diff options
author | unknown <brian@zim.(none)> | 2006-08-15 21:49:26 -0700 |
---|---|---|
committer | unknown <brian@zim.(none)> | 2006-08-15 21:49:26 -0700 |
commit | e1df39a50e75ffdc855ee38aa2d85b091d605ec1 (patch) | |
tree | 6150dee1612f7bbe97f6e20945f53191669ed72f | |
parent | a9922269bca144aef3b691ea2217ae2f42b12f57 (diff) | |
download | mariadb-git-e1df39a50e75ffdc855ee38aa2d85b091d605ec1.tar.gz |
Cheery picked Antony's patch to allow for Window's builds in 5.1
BitKeeper/deleted/.del-bt_compact.c:
Delete: storage/bdb/btree/bt_compact.c
BitKeeper/deleted/.del-bt_compare.c:
Delete: storage/bdb/btree/bt_compare.c
BitKeeper/deleted/.del-bt_conv.c:
Delete: storage/bdb/btree/bt_conv.c
BitKeeper/deleted/.del-bt_curadj.c:
Delete: storage/bdb/btree/bt_curadj.c
BitKeeper/deleted/.del-bt_cursor.c:
Delete: storage/bdb/btree/bt_cursor.c
BitKeeper/deleted/.del-bt_delete.c:
Delete: storage/bdb/btree/bt_delete.c
BitKeeper/deleted/.del-bt_method.c:
Delete: storage/bdb/btree/bt_method.c
BitKeeper/deleted/.del-bt_open.c:
Delete: storage/bdb/btree/bt_open.c
BitKeeper/deleted/.del-bt_put.c:
Delete: storage/bdb/btree/bt_put.c
BitKeeper/deleted/.del-bt_rec.c:
Delete: storage/bdb/btree/bt_rec.c
BitKeeper/deleted/.del-bt_reclaim.c:
Delete: storage/bdb/btree/bt_reclaim.c
BitKeeper/deleted/.del-bt_recno.c:
Delete: storage/bdb/btree/bt_recno.c
BitKeeper/deleted/.del-bt_rsearch.c:
Delete: storage/bdb/btree/bt_rsearch.c
BitKeeper/deleted/.del-bt_search.c:
Delete: storage/bdb/btree/bt_search.c
BitKeeper/deleted/.del-bt_split.c:
Delete: storage/bdb/btree/bt_split.c
BitKeeper/deleted/.del-bt_stat.c:
Delete: storage/bdb/btree/bt_stat.c
BitKeeper/deleted/.del-.IGNORE_ME:
Delete: storage/bdb/build_unix/.IGNORE_ME
BitKeeper/deleted/.del-Berkeley_DB.dsw:
Delete: storage/bdb/build_win32/Berkeley_DB.dsw
BitKeeper/deleted/.del-app_dsp.src:
Delete: storage/bdb/build_win32/app_dsp.src
BitKeeper/deleted/.del-app_dsp.src~dcf703e0c9c72e4a:
Delete: storage/bdb/build_win64/app_dsp.src
BitKeeper/deleted/.del-bt_upgrade.c:
Delete: storage/bdb/btree/bt_upgrade.c
BitKeeper/deleted/.del-bt_verify.c:
Delete: storage/bdb/btree/bt_verify.c
BitKeeper/deleted/.del-btree.src:
Delete: storage/bdb/btree/btree.src
BitKeeper/deleted/.del-db_java_xaj.mak:
Delete: storage/bdb/build_win32/db_java_xaj.mak
BitKeeper/deleted/.del-db_test.src:
Delete: storage/bdb/build_win32/db_test.src
BitKeeper/deleted/.del-dbkill.cpp:
Delete: storage/bdb/build_win32/dbkill.cpp
BitKeeper/deleted/.del-dllmain.c:
Delete: storage/bdb/build_win32/dllmain.c
BitKeeper/deleted/.del-dynamic_dsp.src:
Delete: storage/bdb/build_win32/dynamic_dsp.src
BitKeeper/deleted/.del-java_dsp.src:
Delete: storage/bdb/build_win32/java_dsp.src
BitKeeper/deleted/.del-libdb_tcl.def:
Delete: storage/bdb/build_win32/libdb_tcl.def
BitKeeper/deleted/.del-libdbrc.src:
Delete: storage/bdb/build_win32/libdbrc.src
BitKeeper/deleted/.del-small_dsp.src:
Delete: storage/bdb/build_win32/small_dsp.src
BitKeeper/deleted/.del-srcfile_dsp.src:
Delete: storage/bdb/build_win32/srcfile_dsp.src
BitKeeper/deleted/.del-static_dsp.src:
Delete: storage/bdb/build_win32/static_dsp.src
BitKeeper/deleted/.del-tcl_dsp.src:
Delete: storage/bdb/build_win32/tcl_dsp.src
BitKeeper/deleted/.del-db_test.src~2521827764f86c53:
Delete: storage/bdb/build_win64/db_test.src
BitKeeper/deleted/.del-dynamic_dsp.src~95360632a65b4e62:
Delete: storage/bdb/build_win64/dynamic_dsp.src
BitKeeper/deleted/.del-ex_repquote.src:
Delete: storage/bdb/build_win64/ex_repquote.src
BitKeeper/deleted/.del-getcwd.c:
Delete: storage/bdb/clib/getcwd.c
BitKeeper/deleted/.del-getopt.c:
Delete: storage/bdb/clib/getopt.c
BitKeeper/deleted/.del-java_dsp.src~e42f32427327f5b5:
Delete: storage/bdb/build_win64/java_dsp.src
BitKeeper/deleted/.del-libdbrc.src~d22fea70774c5e98:
Delete: storage/bdb/build_win64/libdbrc.src
BitKeeper/deleted/.del-memcmp.c:
Delete: storage/bdb/clib/memcmp.c
BitKeeper/deleted/.del-memmove.c:
Delete: storage/bdb/clib/memmove.c
BitKeeper/deleted/.del-raise.c:
Delete: storage/bdb/clib/raise.c
BitKeeper/deleted/.del-small_dsp.src~96bb604dd8041058:
Delete: storage/bdb/build_win64/small_dsp.src
BitKeeper/deleted/.del-snprintf.c:
Delete: storage/bdb/clib/snprintf.c
BitKeeper/deleted/.del-srcfile_dsp.src~45382c1414b89bb1:
Delete: storage/bdb/build_win64/srcfile_dsp.src
BitKeeper/deleted/.del-static_dsp.src~3f1945d094870d53:
Delete: storage/bdb/build_win64/static_dsp.src
BitKeeper/deleted/.del-strcasecmp.c:
Delete: storage/bdb/clib/strcasecmp.c
BitKeeper/deleted/.del-strdup.c:
Delete: storage/bdb/clib/strdup.c
BitKeeper/deleted/.del-strerror.c:
Delete: storage/bdb/clib/strerror.c
BitKeeper/deleted/.del-strtol.c:
Delete: storage/bdb/clib/strtol.c
BitKeeper/deleted/.del-tcl_dsp.src~7fd8c5914db07070:
Delete: storage/bdb/build_win64/tcl_dsp.src
BitKeeper/deleted/.del-aes_method.c:
Delete: storage/bdb/crypto/aes_method.c
BitKeeper/deleted/.del-crypto.c:
Delete: storage/bdb/crypto/crypto.c
BitKeeper/deleted/.del-crypto.html:
Delete: storage/bdb/crypto/crypto.html
BitKeeper/deleted/.del-crypto_stub.c:
Delete: storage/bdb/common/crypto_stub.c
BitKeeper/deleted/.del-db_byteorder.c:
Delete: storage/bdb/common/db_byteorder.c
BitKeeper/deleted/.del-db_clock.c:
Delete: storage/bdb/common/db_clock.c
BitKeeper/deleted/.del-db_err.c:
Delete: storage/bdb/common/db_err.c
BitKeeper/deleted/.del-db_getlong.c:
Delete: storage/bdb/common/db_getlong.c
BitKeeper/deleted/.del-db_idspace.c:
Delete: storage/bdb/common/db_idspace.c
BitKeeper/deleted/.del-db_log2.c:
Delete: storage/bdb/common/db_log2.c
BitKeeper/deleted/.del-mt19937db.c:
Delete: storage/bdb/crypto/mersenne/mt19937db.c
BitKeeper/deleted/.del-rijndael-alg-fst.c:
Delete: storage/bdb/crypto/rijndael/rijndael-alg-fst.c
BitKeeper/deleted/.del-rijndael-alg-fst.h:
Delete: storage/bdb/crypto/rijndael/rijndael-alg-fst.h
BitKeeper/deleted/.del-strtoul.c:
Delete: storage/bdb/clib/strtoul.c
BitKeeper/deleted/.del-util_arg.c:
Delete: storage/bdb/common/util_arg.c
BitKeeper/deleted/.del-util_cache.c:
Delete: storage/bdb/common/util_cache.c
BitKeeper/deleted/.del-util_log.c:
Delete: storage/bdb/common/util_log.c
BitKeeper/deleted/.del-util_sig.c:
Delete: storage/bdb/common/util_sig.c
BitKeeper/deleted/.del-vsnprintf.c:
Delete: storage/bdb/clib/vsnprintf.c
BitKeeper/deleted/.del-crdel.src:
Delete: storage/bdb/db/crdel.src
BitKeeper/deleted/.del-crdel_rec.c:
Delete: storage/bdb/db/crdel_rec.c
BitKeeper/deleted/.del-cxx_db.cpp:
Delete: storage/bdb/cxx/cxx_db.cpp
BitKeeper/deleted/.del-cxx_dbc.cpp:
Delete: storage/bdb/cxx/cxx_dbc.cpp
BitKeeper/deleted/.del-cxx_dbt.cpp:
Delete: storage/bdb/cxx/cxx_dbt.cpp
BitKeeper/deleted/.del-cxx_env.cpp:
Delete: storage/bdb/cxx/cxx_env.cpp
BitKeeper/deleted/.del-cxx_except.cpp:
Delete: storage/bdb/cxx/cxx_except.cpp
BitKeeper/deleted/.del-cxx_lock.cpp:
Delete: storage/bdb/cxx/cxx_lock.cpp
BitKeeper/deleted/.del-cxx_logc.cpp:
Delete: storage/bdb/cxx/cxx_logc.cpp
BitKeeper/deleted/.del-cxx_mpool.cpp:
Delete: storage/bdb/cxx/cxx_mpool.cpp
BitKeeper/deleted/.del-cxx_multi.cpp:
Delete: storage/bdb/cxx/cxx_multi.cpp
BitKeeper/deleted/.del-cxx_seq.cpp:
Delete: storage/bdb/cxx/cxx_seq.cpp
BitKeeper/deleted/.del-cxx_txn.cpp:
Delete: storage/bdb/cxx/cxx_txn.cpp
BitKeeper/deleted/.del-db.c:
Delete: storage/bdb/db/db.c
BitKeeper/deleted/.del-rijndael-api-fst.c:
Delete: storage/bdb/crypto/rijndael/rijndael-api-fst.c
BitKeeper/deleted/.del-rijndael-api-fst.h:
Delete: storage/bdb/crypto/rijndael/rijndael-api-fst.h
BitKeeper/deleted/.del-db.src:
Delete: storage/bdb/db/db.src
BitKeeper/deleted/.del-db_am.c:
Delete: storage/bdb/db/db_am.c
BitKeeper/deleted/.del-db_cam.c:
Delete: storage/bdb/db/db_cam.c
BitKeeper/deleted/.del-db_conv.c:
Delete: storage/bdb/db/db_conv.c
BitKeeper/deleted/.del-db_dispatch.c:
Delete: storage/bdb/db/db_dispatch.c
BitKeeper/deleted/.del-db_dup.c:
Delete: storage/bdb/db/db_dup.c
BitKeeper/deleted/.del-db_iface.c:
Delete: storage/bdb/db/db_iface.c
BitKeeper/deleted/.del-db_join.c:
Delete: storage/bdb/db/db_join.c
BitKeeper/deleted/.del-db_meta.c:
Delete: storage/bdb/db/db_meta.c
BitKeeper/deleted/.del-db_method.c:
Delete: storage/bdb/db/db_method.c
BitKeeper/deleted/.del-db_open.c:
Delete: storage/bdb/db/db_open.c
BitKeeper/deleted/.del-db_overflow.c:
Delete: storage/bdb/db/db_overflow.c
BitKeeper/deleted/.del-db_ovfl_vrfy.c:
Delete: storage/bdb/db/db_ovfl_vrfy.c
BitKeeper/deleted/.del-db_pr.c:
Delete: storage/bdb/db/db_pr.c
BitKeeper/deleted/.del-db_rec.c:
Delete: storage/bdb/db/db_rec.c
BitKeeper/deleted/.del-db_reclaim.c:
Delete: storage/bdb/db/db_reclaim.c
BitKeeper/deleted/.del-db_remove.c:
Delete: storage/bdb/db/db_remove.c
BitKeeper/deleted/.del-db_rename.c:
Delete: storage/bdb/db/db_rename.c
BitKeeper/deleted/.del-db_ret.c:
Delete: storage/bdb/db/db_ret.c
BitKeeper/deleted/.del-db185.c:
Delete: storage/bdb/db185/db185.c
BitKeeper/deleted/.del-db185_int.in:
Delete: storage/bdb/db185/db185_int.in
BitKeeper/deleted/.del-db_archive.c:
Delete: storage/bdb/db_archive/db_archive.c
BitKeeper/deleted/.del-db_checkpoint.c:
Delete: storage/bdb/db_checkpoint/db_checkpoint.c
BitKeeper/deleted/.del-db_deadlock.c:
Delete: storage/bdb/db_deadlock/db_deadlock.c
BitKeeper/deleted/.del-db_dump.c:
Delete: storage/bdb/db_dump/db_dump.c
BitKeeper/deleted/.del-db_dump185.c:
Delete: storage/bdb/db_dump185/db_dump185.c
BitKeeper/deleted/.del-db_hotbackup.c:
Delete: storage/bdb/db_hotbackup/db_hotbackup.c
BitKeeper/deleted/.del-db_load.c:
Delete: storage/bdb/db_load/db_load.c
BitKeeper/deleted/.del-db_setid.c:
Delete: storage/bdb/db/db_setid.c
BitKeeper/deleted/.del-db_setlsn.c:
Delete: storage/bdb/db/db_setlsn.c
BitKeeper/deleted/.del-db_stati.c:
Delete: storage/bdb/db/db_stati.c
BitKeeper/deleted/.del-db_truncate.c:
Delete: storage/bdb/db/db_truncate.c
BitKeeper/deleted/.del-db_upg.c:
Delete: storage/bdb/db/db_upg.c
BitKeeper/deleted/.del-db_upg_opd.c:
Delete: storage/bdb/db/db_upg_opd.c
BitKeeper/deleted/.del-db_vrfy.c:
Delete: storage/bdb/db/db_vrfy.c
BitKeeper/deleted/.del-db_vrfy_stub.c:
Delete: storage/bdb/db/db_vrfy_stub.c
BitKeeper/deleted/.del-db_vrfyutil.c:
Delete: storage/bdb/db/db_vrfyutil.c
BitKeeper/deleted/.del-README:
Delete: storage/bdb/db_printlog/README
BitKeeper/deleted/.del-btree.h:
Delete: storage/bdb/dbinc/btree.h
BitKeeper/deleted/.del-commit.awk:
Delete: storage/bdb/db_printlog/commit.awk
BitKeeper/deleted/.del-count.awk:
Delete: storage/bdb/db_printlog/count.awk
BitKeeper/deleted/.del-db_printlog.c:
Delete: storage/bdb/db_printlog/db_printlog.c
BitKeeper/deleted/.del-db_recover.c:
Delete: storage/bdb/db_recover/db_recover.c
BitKeeper/deleted/.del-db_stat.c:
Delete: storage/bdb/db_stat/db_stat.c
BitKeeper/deleted/.del-db_upgrade.c:
Delete: storage/bdb/db_upgrade/db_upgrade.c
BitKeeper/deleted/.del-db_verify.c:
Delete: storage/bdb/db_verify/db_verify.c
BitKeeper/deleted/.del-dbname.awk:
Delete: storage/bdb/db_printlog/dbname.awk
BitKeeper/deleted/.del-dd.sh:
Delete: storage/bdb/db_stat/dd.sh
BitKeeper/deleted/.del-fileid.awk:
Delete: storage/bdb/db_printlog/fileid.awk
BitKeeper/deleted/.del-logstat.awk:
Delete: storage/bdb/db_printlog/logstat.awk
BitKeeper/deleted/.del-pgno.awk:
Delete: storage/bdb/db_printlog/pgno.awk
BitKeeper/deleted/.del-range.awk:
Delete: storage/bdb/db_printlog/range.awk
BitKeeper/deleted/.del-rectype.awk:
Delete: storage/bdb/db_printlog/rectype.awk
BitKeeper/deleted/.del-status.awk:
Delete: storage/bdb/db_printlog/status.awk
BitKeeper/deleted/.del-txn.awk:
Delete: storage/bdb/db_printlog/txn.awk
BitKeeper/deleted/.del-crypto.h:
Delete: storage/bdb/dbinc/crypto.h
BitKeeper/deleted/.del-cxx_common.h:
Delete: storage/bdb/dbinc/cxx_common.h
BitKeeper/deleted/.del-cxx_except.h:
Delete: storage/bdb/dbinc/cxx_except.h
BitKeeper/deleted/.del-cxx_int.h:
Delete: storage/bdb/dbinc/cxx_int.h
BitKeeper/deleted/.del-db.in:
Delete: storage/bdb/dbinc/db.in
BitKeeper/deleted/.del-db_185.in:
Delete: storage/bdb/dbinc/db_185.in
BitKeeper/deleted/.del-db_am.h:
Delete: storage/bdb/dbinc/db_am.h
BitKeeper/deleted/.del-db_cxx.in:
Delete: storage/bdb/dbinc/db_cxx.in
BitKeeper/deleted/.del-db_dispatch.h:
Delete: storage/bdb/dbinc/db_dispatch.h
BitKeeper/deleted/.del-db_int.in:
Delete: storage/bdb/dbinc/db_int.in
BitKeeper/deleted/.del-db_join.h:
Delete: storage/bdb/dbinc/db_join.h
BitKeeper/deleted/.del-db_page.h:
Delete: storage/bdb/dbinc/db_page.h
BitKeeper/deleted/.del-db_server_int.h:
Delete: storage/bdb/dbinc/db_server_int.h
BitKeeper/deleted/.del-db_shash.h:
Delete: storage/bdb/dbinc/db_shash.h
BitKeeper/deleted/.del-db_swap.h:
Delete: storage/bdb/dbinc/db_swap.h
BitKeeper/deleted/.del-db_upgrade.h:
Delete: storage/bdb/dbinc/db_upgrade.h
BitKeeper/deleted/.del-db_verify.h:
Delete: storage/bdb/dbinc/db_verify.h
BitKeeper/deleted/.del-debug.h:
Delete: storage/bdb/dbinc/debug.h
BitKeeper/deleted/.del-fop.h:
Delete: storage/bdb/dbinc/fop.h
BitKeeper/deleted/.del-globals.h:
Delete: storage/bdb/dbinc/globals.h
BitKeeper/deleted/.del-hash.h:
Delete: storage/bdb/dbinc/hash.h
BitKeeper/deleted/.del-hmac.h:
Delete: storage/bdb/dbinc/hmac.h
BitKeeper/deleted/.del-lock.h:
Delete: storage/bdb/dbinc/lock.h
BitKeeper/deleted/.del-log.h:
Delete: storage/bdb/dbinc/log.h
BitKeeper/deleted/.del-mp.h:
Delete: storage/bdb/dbinc/mp.h
BitKeeper/deleted/.del-mutex.h:
Delete: storage/bdb/dbinc/mutex.h
BitKeeper/deleted/.del-mutex_int.h:
Delete: storage/bdb/dbinc/mutex_int.h
BitKeeper/deleted/.del-os.h:
Delete: storage/bdb/dbinc/os.h
BitKeeper/deleted/.del-qam.h:
Delete: storage/bdb/dbinc/qam.h
BitKeeper/deleted/.del-queue.h:
Delete: storage/bdb/dbinc/queue.h
BitKeeper/deleted/.del-region.h:
Delete: storage/bdb/dbinc/region.h
BitKeeper/deleted/.del-rep.h:
Delete: storage/bdb/dbinc/rep.h
BitKeeper/deleted/.del-shqueue.h:
Delete: storage/bdb/dbinc/shqueue.h
BitKeeper/deleted/.del-tcl_db.h:
Delete: storage/bdb/dbinc/tcl_db.h
BitKeeper/deleted/.del-txn.h:
Delete: storage/bdb/dbinc/txn.h
BitKeeper/deleted/.del-xa.h:
Delete: storage/bdb/dbinc/xa.h
BitKeeper/deleted/.del-.empty:
Delete: storage/bdb/dbinc_auto/.empty
BitKeeper/deleted/.del-Makefile.in~c0ea38ee72675ab4:
Delete: storage/bdb/dist/Makefile.in
BitKeeper/deleted/.del-RELEASE:
Delete: storage/bdb/dist/RELEASE
BitKeeper/deleted/.del-buildrel:
Delete: storage/bdb/dist/buildrel
BitKeeper/deleted/.del-config.guess:
Delete: storage/bdb/dist/config.guess
BitKeeper/deleted/.del-config.sub:
Delete: storage/bdb/dist/config.sub
BitKeeper/deleted/.del-configure.ac:
Delete: storage/bdb/dist/configure.ac
BitKeeper/deleted/.del-db.ecd.in:
Delete: storage/bdb/dist/db.ecd.in
BitKeeper/deleted/.del-db.spec.in:
Delete: storage/bdb/dist/db.spec.in
BitKeeper/deleted/.del-dbm.c:
Delete: storage/bdb/dbm/dbm.c
BitKeeper/deleted/.del-dbreg.c:
Delete: storage/bdb/dbreg/dbreg.c
BitKeeper/deleted/.del-dbreg.src:
Delete: storage/bdb/dbreg/dbreg.src
BitKeeper/deleted/.del-dbreg_rec.c:
Delete: storage/bdb/dbreg/dbreg_rec.c
BitKeeper/deleted/.del-dbreg_stat.c:
Delete: storage/bdb/dbreg/dbreg_stat.c
BitKeeper/deleted/.del-dbreg_util.c:
Delete: storage/bdb/dbreg/dbreg_util.c
BitKeeper/deleted/.del-gen_inc.awk:
Delete: storage/bdb/dist/gen_inc.awk
BitKeeper/deleted/.del-gen_rec.awk:
Delete: storage/bdb/dist/gen_rec.awk
BitKeeper/deleted/.del-gen_rpc.awk:
Delete: storage/bdb/dist/gen_rpc.awk
BitKeeper/deleted/.del-install-sh:
Delete: storage/bdb/dist/install-sh
BitKeeper/deleted/.del-ltmain.sh:
Delete: storage/bdb/dist/ltmain.sh
BitKeeper/deleted/.del-pubdef.in:
Delete: storage/bdb/dist/pubdef.in
BitKeeper/deleted/.del-s_all:
Delete: storage/bdb/dist/s_all
BitKeeper/deleted/.del-s_config:
Delete: storage/bdb/dist/s_config
BitKeeper/deleted/.del-s_crypto:
Delete: storage/bdb/dist/s_crypto
BitKeeper/deleted/.del-s_dir:
Delete: storage/bdb/dist/s_dir
BitKeeper/deleted/.del-s_include:
Delete: storage/bdb/dist/s_include
BitKeeper/deleted/.del-s_java_const:
Delete: storage/bdb/dist/s_java_const
BitKeeper/deleted/.del-s_java_stat:
Delete: storage/bdb/dist/s_java_stat
BitKeeper/deleted/.del-s_java_swig:
Delete: storage/bdb/dist/s_java_swig
BitKeeper/deleted/.del-s_javah:
Delete: storage/bdb/dist/s_javah
BitKeeper/deleted/.del-s_java:
Delete: storage/bdb/dist/s_java
BitKeeper/deleted/.del-s_je2db:
Delete: storage/bdb/dist/s_je2db
BitKeeper/deleted/.del-s_perm:
Delete: storage/bdb/dist/s_perm
BitKeeper/deleted/.del-s_readme:
Delete: storage/bdb/dist/s_readme
BitKeeper/deleted/.del-s_recover:
Delete: storage/bdb/dist/s_recover
BitKeeper/deleted/.del-s_rpc:
Delete: storage/bdb/dist/s_rpc
BitKeeper/deleted/.del-s_symlink:
Delete: storage/bdb/dist/s_symlink
BitKeeper/deleted/.del-config.ac:
Delete: storage/bdb/dist/aclocal/config.ac
BitKeeper/deleted/.del-cxx.ac:
Delete: storage/bdb/dist/aclocal/cxx.ac
BitKeeper/deleted/.del-gcc.ac:
Delete: storage/bdb/dist/aclocal/gcc.ac
BitKeeper/deleted/.del-libtool.ac:
Delete: storage/bdb/dist/aclocal/libtool.ac
BitKeeper/deleted/.del-mutex.ac:
Delete: storage/bdb/dist/aclocal/mutex.ac
BitKeeper/deleted/.del-options.ac:
Delete: storage/bdb/dist/aclocal/options.ac
BitKeeper/deleted/.del-programs.ac:
Delete: storage/bdb/dist/aclocal/programs.ac
BitKeeper/deleted/.del-s_tags:
Delete: storage/bdb/dist/s_tags
BitKeeper/deleted/.del-s_test:
Delete: storage/bdb/dist/s_test
BitKeeper/deleted/.del-s_vxworks:
Delete: storage/bdb/dist/s_vxworks
BitKeeper/deleted/.del-s_win32_dsp:
Delete: storage/bdb/dist/s_win32_dsp
BitKeeper/deleted/.del-s_win32:
Delete: storage/bdb/dist/s_win32
BitKeeper/deleted/.del-s_winmsi:
Delete: storage/bdb/dist/s_winmsi
BitKeeper/deleted/.del-srcfiles.in:
Delete: storage/bdb/dist/srcfiles.in
BitKeeper/deleted/.del-vx_buildcd:
Delete: storage/bdb/dist/vx_buildcd
BitKeeper/deleted/.del-vx_config.in:
Delete: storage/bdb/dist/vx_config.in
BitKeeper/deleted/.del-win_config.in:
Delete: storage/bdb/dist/win_config.in
BitKeeper/deleted/.del-win_db.in:
Delete: storage/bdb/dist/win_db.in
BitKeeper/deleted/.del-win_exports.in:
Delete: storage/bdb/dist/win_exports.in
BitKeeper/deleted/.del-ac_check_class.ac:
Delete: storage/bdb/dist/aclocal_java/ac_check_class.ac
BitKeeper/deleted/.del-ac_check_classpath.ac:
Delete: storage/bdb/dist/aclocal_java/ac_check_classpath.ac
BitKeeper/deleted/.del-ac_check_junit.ac:
Delete: storage/bdb/dist/aclocal_java/ac_check_junit.ac
BitKeeper/deleted/.del-ac_check_rqrd_class.ac:
Delete: storage/bdb/dist/aclocal_java/ac_check_rqrd_class.ac
BitKeeper/deleted/.del-ac_java_options.ac:
Delete: storage/bdb/dist/aclocal_java/ac_java_options.ac
BitKeeper/deleted/.del-ac_jni_include_dirs.ac:
Delete: storage/bdb/dist/aclocal_java/ac_jni_include_dirs.ac
BitKeeper/deleted/.del-ac_prog_jar.ac:
Delete: storage/bdb/dist/aclocal_java/ac_prog_jar.ac
BitKeeper/deleted/.del-ac_prog_java.ac:
Delete: storage/bdb/dist/aclocal_java/ac_prog_java.ac
BitKeeper/deleted/.del-ac_prog_java_works.ac:
Delete: storage/bdb/dist/aclocal_java/ac_prog_java_works.ac
BitKeeper/deleted/.del-ac_prog_javac.ac:
Delete: storage/bdb/dist/aclocal_java/ac_prog_javac.ac
BitKeeper/deleted/.del-ac_prog_javac_works.ac:
Delete: storage/bdb/dist/aclocal_java/ac_prog_javac_works.ac
BitKeeper/deleted/.del-ac_prog_javadoc.ac:
Delete: storage/bdb/dist/aclocal_java/ac_prog_javadoc.ac
BitKeeper/deleted/.del-ac_prog_javah.ac:
Delete: storage/bdb/dist/aclocal_java/ac_prog_javah.ac
BitKeeper/deleted/.del-rpc.ac:
Delete: storage/bdb/dist/aclocal/rpc.ac
BitKeeper/deleted/.del-sequence.ac:
Delete: storage/bdb/dist/aclocal/sequence.ac
BitKeeper/deleted/.del-sosuffix.ac:
Delete: storage/bdb/dist/aclocal/sosuffix.ac
BitKeeper/deleted/.del-tcl.ac:
Delete: storage/bdb/dist/aclocal/tcl.ac
BitKeeper/deleted/.del-types.ac:
Delete: storage/bdb/dist/aclocal/types.ac
BitKeeper/deleted/.del-BerkeleyDB.wpj:
Delete: storage/bdb/dist/vx_2.0/BerkeleyDB.wpj
BitKeeper/deleted/.del-BerkeleyDB.wpj~320150f7956cd770:
Delete: storage/bdb/dist/vx_2.2/BerkeleyDB.wpj
BitKeeper/deleted/.del-BerkeleyDBsmall.wpj:
Delete: storage/bdb/dist/vx_2.0/BerkeleyDBsmall.wpj
BitKeeper/deleted/.del-BerkeleyDBsmall.wpj~4c4d7f40dbf1664d:
Delete: storage/bdb/dist/vx_2.2/BerkeleyDBsmall.wpj
BitKeeper/deleted/.del-Makefile.custom:
Delete: storage/bdb/dist/vx_3.1/Makefile.custom
BitKeeper/deleted/.del-ac_try_compile_java.ac:
Delete: storage/bdb/dist/aclocal_java/ac_try_compile_java.ac
BitKeeper/deleted/.del-ac_try_run_javac.ac:
Delete: storage/bdb/dist/aclocal_java/ac_try_run_javac.ac
BitKeeper/deleted/.del-cdf.1:
Delete: storage/bdb/dist/vx_3.1/cdf.1
BitKeeper/deleted/.del-cdf.2:
Delete: storage/bdb/dist/vx_3.1/cdf.2
BitKeeper/deleted/.del-cdf.3:
Delete: storage/bdb/dist/vx_3.1/cdf.3
BitKeeper/deleted/.del-component.cdf:
Delete: storage/bdb/dist/vx_3.1/component.cdf
BitKeeper/deleted/.del-component.wpj:
Delete: storage/bdb/dist/vx_3.1/component.wpj
BitKeeper/deleted/.del-rec_ctemp:
Delete: storage/bdb/dist/template/rec_ctemp
BitKeeper/deleted/.del-rec_rep:
Delete: storage/bdb/dist/template/rec_rep
BitKeeper/deleted/.del-wpj.1:
Delete: storage/bdb/dist/vx_3.1/wpj.1
BitKeeper/deleted/.del-wpj.2:
Delete: storage/bdb/dist/vx_3.1/wpj.2
BitKeeper/deleted/.del-wpj.in:
Delete: storage/bdb/dist/vx_2.0/wpj.in
BitKeeper/deleted/.del-wpj.in~cd8fd754cedb37b2:
Delete: storage/bdb/dist/vx_2.2/wpj.in
BitKeeper/deleted/.del-CONFIG.in:
Delete: storage/bdb/dist/vx_setup/CONFIG.in
BitKeeper/deleted/.del-LICENSE.TXT:
Delete: storage/bdb/dist/vx_setup/LICENSE.TXT
BitKeeper/deleted/.del-MESSAGES.TCL:
Delete: storage/bdb/dist/vx_setup/MESSAGES.TCL
BitKeeper/deleted/.del-README.in:
Delete: storage/bdb/dist/vx_setup/README.in
BitKeeper/deleted/.del-SETUP.BMP:
Delete: storage/bdb/dist/vx_setup/SETUP.BMP
BitKeeper/deleted/.del-dbcorewix.in:
Delete: storage/bdb/dist/winmsi/dbcorewix.in
BitKeeper/deleted/.del-dbvarsbat.in:
Delete: storage/bdb/dist/winmsi/dbvarsbat.in
BitKeeper/deleted/.del-dbwix.m4:
Delete: storage/bdb/dist/winmsi/dbwix.m4
BitKeeper/deleted/.del-environment.in:
Delete: storage/bdb/dist/winmsi/environment.in
BitKeeper/deleted/.del-features.in:
Delete: storage/bdb/dist/winmsi/features.in
BitKeeper/deleted/.del-files.in:
Delete: storage/bdb/dist/winmsi/files.in
BitKeeper/deleted/.del-links.in:
Delete: storage/bdb/dist/winmsi/links.in
BitKeeper/deleted/.del-s_winmsi.fcn:
Delete: storage/bdb/dist/winmsi/s_winmsi.fcn
BitKeeper/deleted/.del-vx_allfile.in:
Delete: storage/bdb/dist/vx_setup/vx_allfile.in
BitKeeper/deleted/.del-vx_demofile.in:
Delete: storage/bdb/dist/vx_setup/vx_demofile.in
BitKeeper/deleted/.del-vx_setup.in:
Delete: storage/bdb/dist/vx_setup/vx_setup.in
BitKeeper/deleted/.del-wpj.3:
Delete: storage/bdb/dist/vx_3.1/wpj.3
BitKeeper/deleted/.del-wpj.4:
Delete: storage/bdb/dist/vx_3.1/wpj.4
BitKeeper/deleted/.del-wpj.5:
Delete: storage/bdb/dist/vx_3.1/wpj.5
BitKeeper/deleted/.del-caticon.ibd:
Delete: storage/bdb/dist/winmsi/images/caticon.ibd
BitKeeper/deleted/.del-db_salloc.c:
Delete: storage/bdb/env/db_salloc.c
BitKeeper/deleted/.del-db_shash.c:
Delete: storage/bdb/env/db_shash.c
BitKeeper/deleted/.del-env_failchk.c:
Delete: storage/bdb/env/env_failchk.c
BitKeeper/deleted/.del-env_file.c:
Delete: storage/bdb/env/env_file.c
BitKeeper/deleted/.del-env_method.c.b:
Delete: storage/bdb/env/env_method.c.b
BitKeeper/deleted/.del-env_method.c:
Delete: storage/bdb/env/env_method.c
BitKeeper/deleted/.del-env_open.c:
Delete: storage/bdb/env/env_open.c
BitKeeper/deleted/.del-env_recover.c:
Delete: storage/bdb/env/env_recover.c
BitKeeper/deleted/.del-env_region.c:
Delete: storage/bdb/env/env_region.c
BitKeeper/deleted/.del-env_register.c:
Delete: storage/bdb/env/env_register.c
BitKeeper/deleted/.del-env_stat.c:
Delete: storage/bdb/env/env_stat.c
BitKeeper/deleted/.del-fileops.src:
Delete: storage/bdb/fileops/fileops.src
BitKeeper/deleted/.del-foldernew.ibd:
Delete: storage/bdb/dist/winmsi/images/foldernew.ibd
BitKeeper/deleted/.del-folderup.ibd:
Delete: storage/bdb/dist/winmsi/images/folderup.ibd
BitKeeper/deleted/.del-sleepycat.jpg:
Delete: storage/bdb/dist/winmsi/images/sleepycat.jpg
BitKeeper/deleted/.del-topstripe.ibd:
Delete: storage/bdb/dist/winmsi/images/topstripe.ibd
BitKeeper/deleted/.del-webicon.ico:
Delete: storage/bdb/dist/winmsi/images/webicon.ico
BitKeeper/deleted/.del-winbuild.bat:
Delete: storage/bdb/dist/winmsi/winbuild.bat
BitKeeper/deleted/.del-fop_basic.c:
Delete: storage/bdb/fileops/fop_basic.c
BitKeeper/deleted/.del-fop_rec.c:
Delete: storage/bdb/fileops/fop_rec.c
BitKeeper/deleted/.del-fop_util.c:
Delete: storage/bdb/fileops/fop_util.c
BitKeeper/deleted/.del-hash.c:
Delete: storage/bdb/hash/hash.c
BitKeeper/deleted/.del-hash.src:
Delete: storage/bdb/hash/hash.src
BitKeeper/deleted/.del-hash_conv.c:
Delete: storage/bdb/hash/hash_conv.c
BitKeeper/deleted/.del-hash_dup.c:
Delete: storage/bdb/hash/hash_dup.c
BitKeeper/deleted/.del-hash_func.c:
Delete: storage/bdb/hash/hash_func.c
BitKeeper/deleted/.del-hash_meta.c:
Delete: storage/bdb/hash/hash_meta.c
BitKeeper/deleted/.del-hash_method.c:
Delete: storage/bdb/hash/hash_method.c
BitKeeper/deleted/.del-hash_open.c:
Delete: storage/bdb/hash/hash_open.c
BitKeeper/deleted/.del-hash_page.c:
Delete: storage/bdb/hash/hash_page.c
BitKeeper/deleted/.del-hash_rec.c:
Delete: storage/bdb/hash/hash_rec.c
BitKeeper/deleted/.del-hash_reclaim.c:
Delete: storage/bdb/hash/hash_reclaim.c
BitKeeper/deleted/.del-hash_stat.c:
Delete: storage/bdb/hash/hash_stat.c
BitKeeper/deleted/.del-hash_stub.c:
Delete: storage/bdb/hash/hash_stub.c
BitKeeper/deleted/.del-hash_upgrade.c:
Delete: storage/bdb/hash/hash_upgrade.c
BitKeeper/deleted/.del-hash_verify.c:
Delete: storage/bdb/hash/hash_verify.c
BitKeeper/deleted/.del-Design:
Delete: storage/bdb/lock/Design
BitKeeper/deleted/.del-hmac.c:
Delete: storage/bdb/hmac/hmac.c
BitKeeper/deleted/.del-hsearch.c:
Delete: storage/bdb/hsearch/hsearch.c
BitKeeper/deleted/.del-lock.c:
Delete: storage/bdb/lock/lock.c
BitKeeper/deleted/.del-lock_deadlock.c:
Delete: storage/bdb/lock/lock_deadlock.c
BitKeeper/deleted/.del-lock_failchk.c:
Delete: storage/bdb/lock/lock_failchk.c
BitKeeper/deleted/.del-lock_id.c:
Delete: storage/bdb/lock/lock_id.c
BitKeeper/deleted/.del-lock_list.c:
Delete: storage/bdb/lock/lock_list.c
BitKeeper/deleted/.del-lock_method.c:
Delete: storage/bdb/lock/lock_method.c
BitKeeper/deleted/.del-lock_region.c:
Delete: storage/bdb/lock/lock_region.c
BitKeeper/deleted/.del-lock_stat.c:
Delete: storage/bdb/lock/lock_stat.c
BitKeeper/deleted/.del-lock_timer.c:
Delete: storage/bdb/lock/lock_timer.c
BitKeeper/deleted/.del-lock_util.c:
Delete: storage/bdb/lock/lock_util.c
BitKeeper/deleted/.del-log.c:
Delete: storage/bdb/log/log.c
BitKeeper/deleted/.del-log_archive.c:
Delete: storage/bdb/log/log_archive.c
BitKeeper/deleted/.del-log_compare.c:
Delete: storage/bdb/log/log_compare.c
BitKeeper/deleted/.del-log_debug.c:
Delete: storage/bdb/log/log_debug.c
BitKeeper/deleted/.del-log_get.c:
Delete: storage/bdb/log/log_get.c
BitKeeper/deleted/.del-sha1.c:
Delete: storage/bdb/hmac/sha1.c
BitKeeper/deleted/.del-README~cce8f408842aa70c:
Delete: storage/bdb/mutex/README
BitKeeper/deleted/.del-log_method.c:
Delete: storage/bdb/log/log_method.c
BitKeeper/deleted/.del-log_put.c:
Delete: storage/bdb/log/log_put.c
BitKeeper/deleted/.del-log_stat.c:
Delete: storage/bdb/log/log_stat.c
BitKeeper/deleted/.del-mp_alloc.c:
Delete: storage/bdb/mp/mp_alloc.c
BitKeeper/deleted/.del-mp_bh.c:
Delete: storage/bdb/mp/mp_bh.c
BitKeeper/deleted/.del-mp_fget.c:
Delete: storage/bdb/mp/mp_fget.c
BitKeeper/deleted/.del-mp_fmethod.c:
Delete: storage/bdb/mp/mp_fmethod.c
BitKeeper/deleted/.del-mp_fopen.c:
Delete: storage/bdb/mp/mp_fopen.c
BitKeeper/deleted/.del-mp_fput.c:
Delete: storage/bdb/mp/mp_fput.c
BitKeeper/deleted/.del-mp_fset.c:
Delete: storage/bdb/mp/mp_fset.c
BitKeeper/deleted/.del-mp_method.c:
Delete: storage/bdb/mp/mp_method.c
BitKeeper/deleted/.del-mp_region.c:
Delete: storage/bdb/mp/mp_region.c
BitKeeper/deleted/.del-mp_register.c:
Delete: storage/bdb/mp/mp_register.c
BitKeeper/deleted/.del-mp_stat.c:
Delete: storage/bdb/mp/mp_stat.c
BitKeeper/deleted/.del-mp_sync.c:
Delete: storage/bdb/mp/mp_sync.c
BitKeeper/deleted/.del-mp_trickle.c:
Delete: storage/bdb/mp/mp_trickle.c
BitKeeper/deleted/.del-mut_alloc.c:
Delete: storage/bdb/mutex/mut_alloc.c
BitKeeper/deleted/.del-mut_fcntl.c:
Delete: storage/bdb/mutex/mut_fcntl.c
BitKeeper/deleted/.del-mut_method.c:
Delete: storage/bdb/mutex/mut_method.c
BitKeeper/deleted/.del-mut_pthread.c:
Delete: storage/bdb/mutex/mut_pthread.c
BitKeeper/deleted/.del-mut_region.c:
Delete: storage/bdb/mutex/mut_region.c
BitKeeper/deleted/.del-mut_stat.c:
Delete: storage/bdb/mutex/mut_stat.c
BitKeeper/deleted/.del-mut_tas.c:
Delete: storage/bdb/mutex/mut_tas.c
BitKeeper/deleted/.del-mut_win32.c:
Delete: storage/bdb/mutex/mut_win32.c
BitKeeper/deleted/.del-os_abs.c:
Delete: storage/bdb/os/os_abs.c
BitKeeper/deleted/.del-os_alloc.c:
Delete: storage/bdb/os/os_alloc.c
BitKeeper/deleted/.del-os_clock.c:
Delete: storage/bdb/os/os_clock.c
BitKeeper/deleted/.del-os_config.c:
Delete: storage/bdb/os/os_config.c
BitKeeper/deleted/.del-os_dir.c:
Delete: storage/bdb/os/os_dir.c
BitKeeper/deleted/.del-os_errno.c:
Delete: storage/bdb/os/os_errno.c
BitKeeper/deleted/.del-os_fid.c:
Delete: storage/bdb/os/os_fid.c
BitKeeper/deleted/.del-os_flock.c:
Delete: storage/bdb/os/os_flock.c
BitKeeper/deleted/.del-tm.c:
Delete: storage/bdb/mutex/tm.c
BitKeeper/deleted/.del-uts4_cc.s:
Delete: storage/bdb/mutex/uts4_cc.s
BitKeeper/deleted/.del-os_fsync.c:
Delete: storage/bdb/os/os_fsync.c
BitKeeper/deleted/.del-os_handle.c:
Delete: storage/bdb/os/os_handle.c
BitKeeper/deleted/.del-os_id.c:
Delete: storage/bdb/os/os_id.c
BitKeeper/deleted/.del-os_map.c:
Delete: storage/bdb/os/os_map.c
BitKeeper/deleted/.del-os_method.c:
Delete: storage/bdb/os/os_method.c
BitKeeper/deleted/.del-os_mkdir.c:
Delete: storage/bdb/os/os_mkdir.c
BitKeeper/deleted/.del-os_oflags.c:
Delete: storage/bdb/os/os_oflags.c
BitKeeper/deleted/.del-os_open.c:
Delete: storage/bdb/os/os_open.c
BitKeeper/deleted/.del-os_region.c:
Delete: storage/bdb/os/os_region.c
BitKeeper/deleted/.del-os_rename.c:
Delete: storage/bdb/os/os_rename.c
BitKeeper/deleted/.del-os_root.c:
Delete: storage/bdb/os/os_root.c
BitKeeper/deleted/.del-os_rpath.c:
Delete: storage/bdb/os/os_rpath.c
BitKeeper/deleted/.del-os_rw.c:
Delete: storage/bdb/os/os_rw.c
BitKeeper/deleted/.del-os_seek.c:
Delete: storage/bdb/os/os_seek.c
BitKeeper/deleted/.del-os_sleep.c:
Delete: storage/bdb/os/os_sleep.c
BitKeeper/deleted/.del-os_spin.c:
Delete: storage/bdb/os/os_spin.c
BitKeeper/deleted/.del-os_stat.c:
Delete: storage/bdb/os/os_stat.c
BitKeeper/deleted/.del-os_tmpdir.c:
Delete: storage/bdb/os/os_tmpdir.c
BitKeeper/deleted/.del-os_truncate.c:
Delete: storage/bdb/os/os_truncate.c
BitKeeper/deleted/.del-os_abs.c~ad5b599d8bf6549f:
Delete: storage/bdb/os_win32/os_abs.c
BitKeeper/deleted/.del-os_clock.c~2add52eff231a274:
Delete: storage/bdb/os_win32/os_clock.c
BitKeeper/deleted/.del-os_config.c~53e193a5e5e97cfd:
Delete: storage/bdb/os_win32/os_config.c
BitKeeper/deleted/.del-os_dir.c~99fbc266717a871a:
Delete: storage/bdb/os_win32/os_dir.c
BitKeeper/deleted/.del-os_errno.c~44204df07323cffb:
Delete: storage/bdb/os_win32/os_errno.c
BitKeeper/deleted/.del-os_fid.c~8f922f06a0fa5a0:
Delete: storage/bdb/os_win32/os_fid.c
BitKeeper/deleted/.del-os_flock.c~cc35099adbda7408:
Delete: storage/bdb/os_win32/os_flock.c
BitKeeper/deleted/.del-os_fsync.c~eebb7e558dacef1c:
Delete: storage/bdb/os_win32/os_fsync.c
BitKeeper/deleted/.del-os_handle.c~281e6b79ac5147f1:
Delete: storage/bdb/os_win32/os_handle.c
BitKeeper/deleted/.del-os_map.c~e8726a67b9abaa30:
Delete: storage/bdb/os_win32/os_map.c
BitKeeper/deleted/.del-os_open.c~996e9987793f8dbc:
Delete: storage/bdb/os_win32/os_open.c
BitKeeper/deleted/.del-os_rename.c~1c318d0b60c977bd:
Delete: storage/bdb/os_win32/os_rename.c
BitKeeper/deleted/.del-os_rw.c~7ec61bd993fe999f:
Delete: storage/bdb/os_win32/os_rw.c
BitKeeper/deleted/.del-os_seek.c~2b5bef3cccfa60c:
Delete: storage/bdb/os_win32/os_seek.c
BitKeeper/deleted/.del-os_sleep.c~d0512f5626e7c40b:
Delete: storage/bdb/os_win32/os_sleep.c
BitKeeper/deleted/.del-os_spin.c~e2abf23edb5bac39:
Delete: storage/bdb/os_win32/os_spin.c
BitKeeper/deleted/.del-os_stat.c~b7aea1c8fe0bc4c4:
Delete: storage/bdb/os_win32/os_stat.c
BitKeeper/deleted/.del-os_truncate.c~9761b239f54b2d96:
Delete: storage/bdb/os_win32/os_truncate.c
BitKeeper/deleted/.del-os_unlink.c:
Delete: storage/bdb/os/os_unlink.c
BitKeeper/deleted/.del-os_type.c:
Delete: storage/bdb/os_win32/os_type.c
BitKeeper/deleted/.del-os_unlink.c~6dee667279d01609:
Delete: storage/bdb/os_win32/os_unlink.c
BitKeeper/deleted/.del-qam.c:
Delete: storage/bdb/qam/qam.c
BitKeeper/deleted/.del-qam.src:
Delete: storage/bdb/qam/qam.src
BitKeeper/deleted/.del-qam_conv.c:
Delete: storage/bdb/qam/qam_conv.c
BitKeeper/deleted/.del-qam_files.c:
Delete: storage/bdb/qam/qam_files.c
BitKeeper/deleted/.del-qam_method.c:
Delete: storage/bdb/qam/qam_method.c
BitKeeper/deleted/.del-qam_open.c:
Delete: storage/bdb/qam/qam_open.c
BitKeeper/deleted/.del-qam_rec.c:
Delete: storage/bdb/qam/qam_rec.c
BitKeeper/deleted/.del-qam_stat.c:
Delete: storage/bdb/qam/qam_stat.c
BitKeeper/deleted/.del-qam_stub.c:
Delete: storage/bdb/qam/qam_stub.c
BitKeeper/deleted/.del-qam_upgrade.c:
Delete: storage/bdb/qam/qam_upgrade.c
BitKeeper/deleted/.del-qam_verify.c:
Delete: storage/bdb/qam/qam_verify.c
BitKeeper/deleted/.del-rep.src:
Delete: storage/bdb/rep/rep.src
BitKeeper/deleted/.del-rep_backup.c:
Delete: storage/bdb/rep/rep_backup.c
BitKeeper/deleted/.del-rep_elect.c:
Delete: storage/bdb/rep/rep_elect.c
BitKeeper/deleted/.del-rep_log.c:
Delete: storage/bdb/rep/rep_log.c
BitKeeper/deleted/.del-rep_method.c:
Delete: storage/bdb/rep/rep_method.c
BitKeeper/deleted/.del-rep_record.c:
Delete: storage/bdb/rep/rep_record.c
BitKeeper/deleted/.del-rep_region.c:
Delete: storage/bdb/rep/rep_region.c
BitKeeper/deleted/.del-rep_stat.c:
Delete: storage/bdb/rep/rep_stat.c
BitKeeper/deleted/.del-rep_stub.c:
Delete: storage/bdb/rep/rep_stub.c
BitKeeper/deleted/.del-rep_util.c:
Delete: storage/bdb/rep/rep_util.c
BitKeeper/deleted/.del-rep_verify.c:
Delete: storage/bdb/rep/rep_verify.c
BitKeeper/deleted/.del-seq_stat.c:
Delete: storage/bdb/sequence/seq_stat.c
BitKeeper/deleted/.del-sequence.c:
Delete: storage/bdb/sequence/sequence.c
BitKeeper/deleted/.del-txn.c:
Delete: storage/bdb/txn/txn.c
BitKeeper/deleted/.del-txn.src:
Delete: storage/bdb/txn/txn.src
BitKeeper/deleted/.del-txn_chkpt.c:
Delete: storage/bdb/txn/txn_chkpt.c
BitKeeper/deleted/.del-txn_failchk.c:
Delete: storage/bdb/txn/txn_failchk.c
BitKeeper/deleted/.del-txn_method.c:
Delete: storage/bdb/txn/txn_method.c
BitKeeper/deleted/.del-txn_rec.c:
Delete: storage/bdb/txn/txn_rec.c
BitKeeper/deleted/.del-txn_recover.c:
Delete: storage/bdb/txn/txn_recover.c
BitKeeper/deleted/.del-txn_region.c:
Delete: storage/bdb/txn/txn_region.c
BitKeeper/deleted/.del-txn_stat.c:
Delete: storage/bdb/txn/txn_stat.c
BitKeeper/deleted/.del-txn_util.c:
Delete: storage/bdb/txn/txn_util.c
BitKeeper/deleted/.del-xa.c:
Delete: storage/bdb/xa/xa.c
BitKeeper/deleted/.del-xa_db.c:
Delete: storage/bdb/xa/xa_db.c
BitKeeper/deleted/.del-xa_map.c:
Delete: storage/bdb/xa/xa_map.c
sql/field.cc:
Antony's patch
sql/field.h:
Antony's patch
461 files changed, 2 insertions, 178414 deletions
diff --git a/sql/field.cc b/sql/field.cc index e45e1586d89..8ac32f03049 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -6571,7 +6571,7 @@ void Field_varstring::sql_type(String &res) const } -uint Field_varstring::data_length(const char *from) +uint32 Field_varstring::data_length(const char *from) { return length_bytes == 1 ? (uint) (uchar) *ptr : uint2korr(ptr); } diff --git a/sql/field.h b/sql/field.h index 01b5f7bd1f9..fce3b51c04b 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1126,7 +1126,7 @@ public: int key_cmp(const byte *str, uint length); uint packed_col_length(const char *to, uint length); uint max_packed_col_length(uint max_length); - uint data_length(const char *from); + uint32 data_length(const char *from); uint size_of() const { return sizeof(*this); } enum_field_types real_type() const { return MYSQL_TYPE_VARCHAR; } bool has_charset(void) const diff --git a/storage/bdb/btree/bt_compact.c b/storage/bdb/btree/bt_compact.c deleted file mode 100644 index 3cc04b9aa19..00000000000 --- a/storage/bdb/btree/bt_compact.c +++ /dev/null @@ -1,2348 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: bt_compact.c,v 12.34 2005/11/10 21:07:48 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/btree.h" -#include "dbinc/lock.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" -#include "dbinc/txn.h" - -static int __bam_compact_dups __P((DBC *, - PAGE *, u_int32_t, int, DB_COMPACT *, int *)); -static int __bam_compact_int __P((DBC *, - DBT *, DBT *, u_int32_t, int *, DB_COMPACT *, int *)); -static int __bam_csearch __P((DBC *, DBT *, u_int32_t, int)); -static int __bam_merge __P((DBC *, - DBC *, u_int32_t, DBT *, DB_COMPACT *,int *)); -static int __bam_merge_internal __P((DBC *, DBC *, int, DB_COMPACT *, int *)); -static int __bam_merge_pages __P((DBC *, DBC *, DB_COMPACT *)); -static int __bam_merge_records __P((DBC *, DBC*, u_int32_t, DB_COMPACT *)); -static int __bam_truncate_internal_overflow __P((DBC *, PAGE *, DB_COMPACT *)); -static int __bam_truncate_overflow __P((DBC *, - db_pgno_t, db_pgno_t, DB_COMPACT *)); -static int __bam_truncate_page __P((DBC *, PAGE **, int)); -static int __bam_truncate_root_page __P((DBC *, - PAGE *, u_int32_t, DB_COMPACT *)); - -#ifdef HAVE_FTRUNCATE -static int __bam_free_freelist __P((DB *, DB_TXN *)); -static int __bam_savekey __P((DBC *, int, DBT *)); -static int __bam_setup_freelist __P((DB *, struct pglist *, u_int32_t)); -static int __bam_truncate_internal __P((DB *, DB_TXN *, DB_COMPACT *)); -#endif - -#define SAVE_START \ - do { \ - save_data = *c_data; \ - ret = __db_retcopy(dbenv, \ - &save_start, end->data, end->size, \ - &save_start.data, &save_start.ulen); \ - } while (0) - -/* - * Only restore those things that are negated by aborting the - * transaction. We don't restore the number of deadlocks, for example. - */ - -#define RESTORE_START \ - do { \ - c_data->compact_pages_free = \ - save_data.compact_pages_free; \ - c_data->compact_levels = save_data.compact_levels; \ - c_data->compact_truncate = save_data.compact_truncate; \ - ret = __db_retcopy(dbenv, end, \ - save_start.data, save_start.size, \ - &end->data, &end->ulen); \ - } while (0) -/* - * __bam_compact -- compact a btree. - * - * PUBLIC: int __bam_compact __P((DB *, DB_TXN *, - * PUBLIC: DBT *, DBT *, DB_COMPACT *, u_int32_t, DBT *)); - */ -int -__bam_compact(dbp, txn, start, stop, c_data, flags, end) - DB *dbp; - DB_TXN *txn; - DBT *start, *stop; - DB_COMPACT *c_data; - u_int32_t flags; - DBT *end; -{ - DBT current, save_start; - DBC *dbc; - DB_COMPACT save_data; - DB_ENV *dbenv; - db_pgno_t last_pgno; - struct pglist *list; - u_int32_t factor, nelems, truncated; - int deadlock, done, ret, span, t_ret, txn_local; - - dbenv = dbp->dbenv; - - memset(¤t, 0, sizeof(current)); - memset(&save_start, 0, sizeof(save_start)); - dbc = NULL; - deadlock = 0; - done = 0; - factor = 0; - ret = 0; - span = 0; - truncated = 0; - last_pgno = 0; - - /* - * We pass "end" to the internal routine, indicating where - * that routine should begin its work and expecting that it - * will return to us the last key that it processed. - */ - if (end == NULL) - end = ¤t; - if (start != NULL && (ret = __db_retcopy(dbenv, - end, start->data, start->size, &end->data, &end->ulen)) != 0) - return (ret); - - list = NULL; - nelems = 0; - - if (IS_DB_AUTO_COMMIT(dbp, txn)) - txn_local = 1; - else - txn_local = 0; - if (!LF_ISSET(DB_FREE_SPACE | DB_FREELIST_ONLY)) - goto no_free; - if (LF_ISSET(DB_FREELIST_ONLY)) - LF_SET(DB_FREE_SPACE); - -#ifdef HAVE_FTRUNCATE - /* Sort the freelist and set up the in-memory list representation. */ - if (txn_local && (ret = __txn_begin(dbenv, NULL, &txn, 0)) != 0) - goto err; - - if ((ret = __db_free_truncate(dbp, - txn, flags, c_data, &list, &nelems, &last_pgno)) != 0) { - LF_CLR(DB_FREE_SPACE); - goto terr; - } - - /* If the freelist is empty and we are not filling, get out. */ - if (nelems == 0 && LF_ISSET(DB_FREELIST_ONLY)) { - ret = 0; - LF_CLR(DB_FREE_SPACE); - goto terr; - } - if ((ret = __bam_setup_freelist(dbp, list, nelems)) != 0) { - /* Someone else owns the free list. */ - if (ret == EBUSY) - ret = 0; - } - - /* Commit the txn and release the meta page lock. */ -terr: if (txn_local) { - if ((t_ret = __txn_commit(txn, DB_TXN_NOSYNC)) != 0 && ret == 0) - ret = t_ret; - txn = NULL; - } - if (ret != 0) - goto err; - - /* Save the number truncated so far, we will add what we get below. */ - truncated = c_data->compact_pages_truncated; - if (LF_ISSET(DB_FREELIST_ONLY)) - goto done; -#endif - - /* - * We want factor to be the target number of free bytes on each page, - * so we know when to stop adding items to a page. Make sure to - * subtract the page overhead when computing this target. This can - * result in a 1-2% error on the smallest page. - * First figure out how many bytes we should use: - */ -no_free: - factor = dbp->pgsize - SIZEOF_PAGE; - if (c_data->compact_fillpercent != 0) { - factor *= c_data->compact_fillpercent; - factor /= 100; - } - /* Now convert to the number of free bytes to target. */ - factor = (dbp->pgsize - SIZEOF_PAGE) - factor; - - if (c_data->compact_pages == 0) - c_data->compact_pages = DB_MAX_PAGES; - - do { - deadlock = 0; - - SAVE_START; - if (ret != 0) - break; - - if (txn_local) { - if ((ret = __txn_begin(dbenv, NULL, &txn, 0)) != 0) - break; - - if (c_data->compact_timeout != 0 && - (ret = __txn_set_timeout(txn, - c_data->compact_timeout, DB_SET_LOCK_TIMEOUT)) != 0) - goto err; - } - - if ((ret = __db_cursor(dbp, txn, &dbc, 0)) != 0) - goto err; - - if ((ret = __bam_compact_int(dbc, end, stop, factor, - &span, c_data, &done)) == DB_LOCK_DEADLOCK && txn_local) { - /* - * We retry on deadlock. Cancel the statistics - * and reset the start point to before this - * iteration. - */ - deadlock = 1; - c_data->compact_deadlock++; - RESTORE_START; - } - - if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0) - ret = t_ret; - -err: if (txn_local && txn != NULL) { - if (ret == 0 && deadlock == 0) - ret = __txn_commit(txn, DB_TXN_NOSYNC); - else if ((t_ret = __txn_abort(txn)) != 0 && ret == 0) - ret = t_ret; - txn = NULL; - } - } while (ret == 0 && !done); - - if (current.data != NULL) - __os_free(dbenv, current.data); - if (save_start.data != NULL) - __os_free(dbenv, save_start.data); - -#ifdef HAVE_FTRUNCATE - /* - * Finish up truncation work. If there are pages left in the free - * list then search the internal nodes of the tree as we may have - * missed some while walking the leaf nodes. Then calculate how - * many pages we have truncated and release the in-memory free list. - */ -done: if (LF_ISSET(DB_FREE_SPACE)) { - DBMETA *meta; - db_pgno_t pgno; - - pgno = PGNO_BASE_MD; - done = 1; - if (ret == 0 && !LF_ISSET(DB_FREELIST_ONLY) && - (t_ret = __memp_fget(dbp->mpf, &pgno, 0, &meta)) == 0) { - done = meta->free == PGNO_INVALID; - ret = __memp_fput(dbp->mpf, meta, 0); - } - - if (!done) - ret = __bam_truncate_internal(dbp, txn, c_data); - - /* Clean up the free list. */ - if (list != NULL) - __os_free(dbenv, list); - - if ((t_ret = __memp_fget(dbp->mpf, &pgno, 0, &meta)) == 0) { - c_data->compact_pages_truncated = - truncated + last_pgno - meta->last_pgno; - if ((t_ret = - __memp_fput(dbp->mpf, meta, 0)) != 0 && ret == 0) - ret = t_ret; - } else if (ret == 0) - ret = t_ret; - - if ((t_ret = __bam_free_freelist(dbp, txn)) != 0 && ret == 0) - t_ret = ret; - } -#endif - - return (ret); -} - -/* - * __bam_csearch -- isolate search code for bam_compact. - * This routine hides the differences between searching - * a BTREE and a RECNO from the rest of the code. - */ -#define CS_READ 0 /* We are just reading. */ -#define CS_PARENT 1 /* We want the parent too, write lock. */ -#define CS_NEXT 2 /* Get the next page. */ -#define CS_NEXT_WRITE 3 /* Get the next page and write lock. */ -#define CS_DEL 4 /* Get a stack to delete a page. */ -#define CS_START 5 /* Starting level for stack, write lock. */ -#define CS_GETRECNO 0x80 /* Extract record number from start. */ - -static int -__bam_csearch(dbc, start, sflag, level) - DBC *dbc; - DBT *start; - u_int32_t sflag; - int level; -{ - BTREE_CURSOR *cp; - int not_used, ret; - - cp = (BTREE_CURSOR *)dbc->internal; - - if (dbc->dbtype == DB_RECNO) { - /* If GETRECNO is not set the cp->recno is what we want. */ - if (FLD_ISSET(sflag, CS_GETRECNO)) { - if (start == NULL || start->size == 0) - cp->recno = 1; - else if ((ret = - __ram_getno(dbc, start, &cp->recno, 0)) != 0) - return (ret); - FLD_CLR(sflag, CS_GETRECNO); - } - switch (sflag) { - case CS_READ: - sflag = S_READ; - break; - case CS_NEXT: - sflag = S_PARENT | S_READ; - break; - case CS_START: - level = LEAFLEVEL; - /* FALLTHROUGH */ - case CS_DEL: - case CS_NEXT_WRITE: - sflag = S_STACK; - break; - case CS_PARENT: - sflag = S_PARENT | S_WRITE; - break; - default: - return (__db_panic(dbc->dbp->dbenv, EINVAL)); - } - if ((ret = __bam_rsearch(dbc, - &cp->recno, sflag, level, ¬_used)) != 0) - return (ret); - /* Reset the cursor's recno to the beginning of the page. */ - cp->recno -= cp->csp->indx; - } else { - FLD_CLR(sflag, CS_GETRECNO); - switch (sflag) { - case CS_READ: - sflag = S_READ | S_DUPFIRST; - break; - case CS_DEL: - sflag = S_DEL; - break; - case CS_NEXT: - sflag = S_NEXT; - break; - case CS_NEXT_WRITE: - sflag = S_NEXT | S_WRITE; - break; - case CS_START: - sflag = S_START | S_WRITE; - break; - case CS_PARENT: - sflag = S_PARENT | S_WRITE; - break; - default: - return (__db_panic(dbc->dbp->dbenv, EINVAL)); - } - if (start == NULL || start->size == 0) - FLD_SET(sflag, S_MIN); - - if ((ret = __bam_search(dbc, - cp->root, start, sflag, level, NULL, ¬_used)) != 0) - return (ret); - } - - return (0); -} - -/* - * __bam_compact_int -- internal compaction routine. - * Called either with a cursor on the main database - * or a cursor initialized to the root of an off page duplicate - * tree. - */ -static int -__bam_compact_int(dbc, start, stop, factor, spanp, c_data, donep) - DBC *dbc; - DBT *start, *stop; - u_int32_t factor; - int *spanp; - DB_COMPACT *c_data; - int *donep; -{ - BTREE_CURSOR *cp, *ncp; - DB *dbp; - DBC *ndbc; - DB_ENV *dbenv; - DB_LOCK nolock; - EPG *epg; - DB_MPOOLFILE *dbmp; - PAGE *pg, *ppg, *npg; - db_pgno_t npgno; - db_recno_t next_recno; - u_int32_t sflag; - int check_dups, check_trunc, done, level; - int merged, nentry, next_page, pgs_done, ret, t_ret, tdone; -#ifdef DEBUG - DBT trace; - char buf[256]; -#define CTRACE(dbc, location, t, start, f) do { \ - trace.data = t; \ - trace.size = (u_int32_t)strlen(t); \ - DEBUG_LWRITE(dbc, dbc->txn, location, &trace, start, f) \ - } while (0) -#define PTRACE(dbc, location, p, start, f) do { \ - (void)sprintf(buf, "pgno: %lu", (u_long)p); \ - CTRACE(dbc, location, buf, start, f); \ - } while (0) -#else -#define CTRACE(dbc, location, t, start, f) -#define PTRACE(dbc, location, p, start, f) -#endif - - ndbc = NULL; - pg = NULL; - npg = NULL; - done = 0; - tdone = 0; - pgs_done = 0; - next_recno = 0; - next_page = 0; - LOCK_INIT(nolock); - check_trunc = c_data->compact_truncate != PGNO_INVALID; - check_dups = (!F_ISSET(dbc, DBC_OPD) && - F_ISSET(dbc->dbp, DB_AM_DUP)) || check_trunc; - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - dbmp = dbp->mpf; - cp = (BTREE_CURSOR *)dbc->internal; - - /* Search down the tree for the starting point. */ - if ((ret = __bam_csearch(dbc, - start, CS_READ | CS_GETRECNO, LEAFLEVEL)) != 0) { - /* Its not an error to compact an empty db. */ - if (ret == DB_NOTFOUND) - ret = 0; - goto err; - } - - /* - * Get the first leaf page. The loop below will change pg so - * we clear the stack reference so we don't put a a page twice. - */ - pg = cp->csp->page; - cp->csp->page = NULL; - next_recno = cp->recno; -next: /* - * This is the start of the main compaction loop. There are 3 - * parts to the process: - * 1) Walk the leaf pages of the tree looking for a page to - * process. We do this with read locks. Save the - * key from the page and release it. - * 2) Set up a cursor stack which will write lock the page - * and enough of its ancestors to get the job done. - * This could go to the root if we might delete a subtree - * or we have record numbers to update. - * 3) Loop fetching pages after the above page and move enough - * data to fill it. - * We exit the loop if we are at the end of the leaf pages, are - * about to lock a new subtree (we span) or on error. - */ - - /* Walk the pages looking for something to fill up. */ - while ((npgno = NEXT_PGNO(pg)) != PGNO_INVALID) { - c_data->compact_pages_examine++; - PTRACE(dbc, "Next", PGNO(pg), start, 0); - - /* If we have fetched the next page, get the new key. */ - if (next_page == 1 && - dbc->dbtype != DB_RECNO && NUM_ENT(pg) != 0) { - if ((ret = __db_ret(dbp, pg, - 0, start, &start->data, &start->ulen)) != 0) - goto err; - } - next_recno += NUM_ENT(pg); - if (P_FREESPACE(dbp, pg) > factor || - (check_trunc && PGNO(pg) > c_data->compact_truncate)) - break; - /* - * The page does not need more data or to be swapped, - * check to see if we want to look at possible duplicate - * trees or overflow records and the move on to the next page. - */ - cp->recno += NUM_ENT(pg); - next_page = 1; - tdone = pgs_done; - PTRACE(dbc, "Dups", PGNO(pg), start, 0); - if (check_dups && (ret = __bam_compact_dups( - dbc, pg, factor, 0, c_data, &pgs_done)) != 0) - goto err; - npgno = NEXT_PGNO(pg); - if ((ret = __memp_fput(dbmp, pg, 0)) != 0) - goto err; - pg = NULL; - /* - * If we don't do anything we don't need to hold - * the lock on the previous page, so couple always. - */ - if ((ret = __db_lget(dbc, - tdone == pgs_done ? LCK_COUPLE_ALWAYS : LCK_COUPLE, - npgno, DB_LOCK_READ, 0, &cp->csp->lock)) != 0) - goto err; - if ((ret = __memp_fget(dbmp, &npgno, 0, &pg)) != 0) - goto err; - } - - /* - * When we get here we have 3 cases: - * 1) We've reached the end of the leaf linked list and are done. - * 2) A page whose freespace exceeds our target and therefore needs - * to have data added to it. - * 3) A page that doesn't have too much free space but needs to be - * checked for truncation. - * In both cases 2 and 3, we need that page's first key or record - * number. We may already have it, if not get it here. - */ - if ((nentry = NUM_ENT(pg)) != 0) { - next_page = 0; - /* Get a copy of the first recno on the page. */ - if (dbc->dbtype == DB_RECNO) { - if ((ret = __db_retcopy(dbp->dbenv, start, - &cp->recno, sizeof(cp->recno), - &start->data, &start->ulen)) != 0) - goto err; - } else if (start->size == 0 && - (ret = __db_ret(dbp, pg, - 0, start, &start->data, &start->ulen)) != 0) - goto err; - - if (npgno == PGNO_INVALID) { - /* End of the tree, check its duplicates and exit. */ - PTRACE(dbc, "GoDone", PGNO(pg), start, 0); - if (check_dups && (ret = - __bam_compact_dups(dbc, - pg, factor, 0, c_data, &pgs_done)) != 0) - goto err; - c_data->compact_pages_examine++; - done = 1; - goto done; - } - } - - /* Release the page so we don't deadlock getting its parent. */ - BT_STK_CLR(cp); - if ((ret = __LPUT(dbc, cp->csp->lock)) != 0) - goto err; - if ((ret = __memp_fput(dbmp, pg, 0)) != 0) - goto err; - pg = NULL; - - /* - * Setup the cursor stack. There are 3 cases: - * 1) the page is empty and will be deleted: nentry == 0. - * 2) the next page has the same parent: *spanp == 0. - * 3) the next page has a different parent: *spanp == 1. - * - * We now need to search the tree again, getting a write lock - * on the page we are going to merge or delete. We do this by - * searching down the tree and locking as much of the subtree - * above the page as needed. In the case of a delete we will - * find the maximal subtree that can be deleted. In the case - * of merge if the current page and the next page are siblings - * with the same parent then we only need to lock the parent. - * Otherwise *span will be set and we need to search to find the - * lowest common ancestor. Dbc will be set to contain the subtree - * containing the page to be merged or deleted. Ndbc will contain - * the minimal subtree containing that page and its next sibling. - * In all cases for DB_RECNO we simplify things and get the whole - * tree if we need more than a single parent. - */ - - /* Case 1 -- page is empty. */ - if (nentry == 0) { - CTRACE(dbc, "Empty", "", start, 0); - if (next_page == 1) - sflag = CS_NEXT_WRITE; - else - sflag = CS_DEL; - if ((ret = __bam_csearch(dbc, start, sflag, LEAFLEVEL)) != 0) - goto err; - - pg = cp->csp->page; - /* Check to see if the page is still empty. */ - if (NUM_ENT(pg) != 0) - npgno = PGNO(pg); - else { - npgno = NEXT_PGNO(pg); - /* If this is now the root, we are very done. */ - if (PGNO(pg) == cp->root) - done = 1; - else { - if ((ret = __bam_dpages(dbc, 0, 0)) != 0) - goto err; - c_data->compact_pages_free++; - goto next_no_release; - } - } - goto next_page; - } - - /* case 3 -- different parents. */ - if (*spanp) { - CTRACE(dbc, "Span", "", start, 0); - if (ndbc == NULL && (ret = __db_c_dup(dbc, &ndbc, 0)) != 0) - goto err; - ncp = (BTREE_CURSOR *)ndbc->internal; - ncp->recno = next_recno; - /* - * Search the tree looking for the next page after the - * current key. For RECNO get the whole stack. - * For BTREE the return will contain the stack that - * dominates both the current and next pages. - */ - if ((ret = __bam_csearch(ndbc, start, CS_NEXT_WRITE, 0)) != 0) - goto err; - - if (dbc->dbtype == DB_RECNO) { - /* - * The record we are looking for may have moved - * to the previous page. This page should - * be at the beginning of its parent. - * If not, then start over. - */ - if (ncp->csp[-1].indx != 0) { - *spanp = 0; - goto deleted; - } - - } - PTRACE(dbc, "SDups", PGNO(ncp->csp->page), start, 0); - if (check_dups && - (ret = __bam_compact_dups(ndbc, - ncp->csp->page, factor, 1, c_data, &pgs_done)) != 0) - goto err; - - /* - * We need the stacks to be the same height - * so that we can merge parents. - */ - level = LEVEL(ncp->sp->page); - sflag = CS_START; - if ((ret = __bam_csearch(dbc, start, sflag, level)) != 0) - goto err; - pg = cp->csp->page; - *spanp = 0; - - /* - * The page may have emptied while we waited for the lock. - * Reset npgno so we re-get this page when we go back to the - * top. - */ - if (NUM_ENT(pg) == 0) { - npgno = PGNO(pg); - goto next_page; - } - if (check_trunc && PGNO(pg) > c_data->compact_truncate) { - pgs_done++; - /* Get a fresh low numbered page. */ - if ((ret = __bam_truncate_page(dbc, &pg, 1)) != 0) - goto err1; - } - - npgno = NEXT_PGNO(pg); - PTRACE(dbc, "SDups", PGNO(pg), start, 0); - if (check_dups && (ret = - __bam_compact_dups(dbc, pg, - factor, 1, c_data, &pgs_done)) != 0) - goto err1; - - /* - * We may have dropped our locks, check again - * to see if we still need to fill this page and - * we are in a spanning situation. - */ - - if (P_FREESPACE(dbp, pg) <= factor || - cp->csp[-1].indx != NUM_ENT(cp->csp[-1].page) - 1) - goto next_page; - - /* - * Try to move things into a single parent. - */ - merged = 0; - for (epg = cp->sp; epg != cp->csp; epg++) { - if (PGNO(epg->page) == cp->root) - continue; - PTRACE(dbc, "PMerge", PGNO(epg->page), start, 0); - if ((ret = __bam_merge_internal(dbc, - ndbc, LEVEL(epg->page), c_data, &merged)) != 0) - goto err1; - if (merged) - break; - } - - /* If we merged the parent, then we nolonger span. */ - if (merged) { - pgs_done++; - if (cp->csp->page == NULL) - goto deleted; - npgno = PGNO(pg); - goto next_page; - } - PTRACE(dbc, "SMerge", PGNO(cp->csp->page), start, 0); - npgno = NEXT_PGNO(ncp->csp->page); - if ((ret = __bam_merge(dbc, - ndbc, factor, stop, c_data, &done)) != 0) - goto err1; - pgs_done++; - /* - * __bam_merge could have freed our stack if it - * deleted a page possibly collapsing the tree. - */ - if (cp->csp->page == NULL) - goto deleted; - cp->recno += NUM_ENT(pg); - - /* If we did not bump to the next page something did not fit. */ - if (npgno != NEXT_PGNO(pg)) { - npgno = NEXT_PGNO(pg); - goto next_page; - } - } else { - /* Case 2 -- same parents. */ - CTRACE(dbc, "Sib", "", start, 0); - if ((ret = - __bam_csearch(dbc, start, CS_PARENT, LEAFLEVEL)) != 0) - goto err; - - pg = cp->csp->page; - DB_ASSERT(cp->csp - cp->sp == 1); - npgno = PGNO(pg); - - /* We now have a write lock, recheck the page. */ - if ((nentry = NUM_ENT(pg)) == 0) - goto next_page; - - npgno = NEXT_PGNO(pg); - - /* Check duplicate trees, we have a write lock on the page. */ - PTRACE(dbc, "SibDup", PGNO(pg), start, 0); - if (check_dups && (ret = - __bam_compact_dups(dbc, pg, - factor, 1, c_data, &pgs_done)) != 0) - goto err1; - - if (check_trunc && PGNO(pg) > c_data->compact_truncate) { - pgs_done++; - /* Get a fresh low numbered page. */ - if ((ret = __bam_truncate_page(dbc, &pg, 1)) != 0) - goto err1; - } - - /* After re-locking check to see if we still need to fill. */ - if (P_FREESPACE(dbp, pg) <= factor) - goto next_page; - - /* If they have the same parent, just dup the cursor */ - if (ndbc != NULL && (ret = __db_c_close(ndbc)) != 0) - goto err1; - if ((ret = __db_c_dup(dbc, &ndbc, DB_POSITION)) != 0) - goto err1; - ncp = (BTREE_CURSOR *)ndbc->internal; - - /* - * ncp->recno needs to have the recno of the next page. - * Bump it by the number of records on the current page. - */ - ncp->recno += NUM_ENT(pg); - } - - /* Fetch pages until we fill this one. */ - while (!done && npgno != PGNO_INVALID && - P_FREESPACE(dbp, pg) > factor && c_data->compact_pages != 0) { - /* - * If our current position is the last one on a parent - * page, then we are about to merge across different - * internal nodes. Thus, we need to lock higher up - * in the tree. We will exit the routine and commit - * what we have done so far. Set spanp so we know - * we are in this case when we come back. - */ - if (cp->csp[-1].indx == NUM_ENT(cp->csp[-1].page) - 1) { - *spanp = 1; - npgno = PGNO(pg); - next_recno = cp->recno; - goto next_page; - } - - /* Lock and get the next page. */ - if ((ret = __db_lget(dbc, LCK_COUPLE, - npgno, DB_LOCK_WRITE, 0, &ncp->lock)) != 0) - goto err1; - if ((ret = __memp_fget(dbmp, &npgno, 0, &npg)) != 0) - goto err1; - - /* Fix up the next page cursor with its parent node. */ - if ((ret = __memp_fget(dbmp, - &PGNO(cp->csp[-1].page), 0, &ppg)) != 0) - goto err1; - BT_STK_PUSH(dbenv, ncp, ppg, - cp->csp[-1].indx + 1, nolock, DB_LOCK_NG, ret); - if (ret != 0) - goto err1; - - /* Put the page on the stack. */ - BT_STK_ENTER(dbenv, ncp, npg, 0, ncp->lock, DB_LOCK_WRITE, ret); - - LOCK_INIT(ncp->lock); - npg = NULL; - - c_data->compact_pages_examine++; - - PTRACE(dbc, "MDups", PGNO(ncp->csp->page), start, 0); - if (check_dups && (ret = __bam_compact_dups(ndbc, - ncp->csp->page, factor, 1, c_data, &pgs_done)) != 0) - goto err1; - - npgno = NEXT_PGNO(ncp->csp->page); - /* - * Merge the pages. This will either free the next - * page or just update its parent pointer. - */ - PTRACE(dbc, "Merge", PGNO(cp->csp->page), start, 0); - if ((ret = __bam_merge(dbc, - ndbc, factor, stop, c_data, &done)) != 0) - goto err1; - - pgs_done++; - - /* - * __bam_merge could have freed our stack if it - * deleted a page possibly collapsing the tree. - */ - if (cp->csp->page == NULL) - goto deleted; - /* If we did not bump to the next page something did not fit. */ - if (npgno != NEXT_PGNO(pg)) - break; - } - - /* Bottom of the main loop. Move to the next page. */ - npgno = NEXT_PGNO(pg); - cp->recno += NUM_ENT(pg); - next_recno = cp->recno; - -next_page: - if ((ret = __bam_stkrel(dbc, pgs_done == 0 ? STK_NOLOCK : 0)) != 0) - goto err1; - if (ndbc != NULL && - (ret = __bam_stkrel(ndbc, pgs_done == 0 ? STK_NOLOCK : 0)) != 0) - goto err1; - -next_no_release: - pg = NULL; - - if (npgno == PGNO_INVALID || c_data->compact_pages == 0) - done = 1; - if (!done) { - /* - * If we are at the end of this parent commit the - * transaction so we don't tie things up. - */ - if (pgs_done != 0 && *spanp) { -deleted: if (((ret = __bam_stkrel(ndbc, 0)) != 0 || - (ret = __db_c_close(ndbc)) != 0)) - goto err; - *donep = 0; - return (0); - } - - /* Reget the next page to look at. */ - cp->recno = next_recno; - if ((ret = __memp_fget(dbmp, &npgno, 0, &pg)) != 0) - goto err; - next_page = 1; - goto next; - } - -done: - if (0) { - /* We come here if pg is the same as cp->csp->page. */ -err1: pg = NULL; - } -err: if (dbc != NULL && - (t_ret = __bam_stkrel(dbc, STK_CLRDBC)) != 0 && ret == 0) - ret = t_ret; - if (ndbc != NULL) { - if ((t_ret = __bam_stkrel(ndbc, STK_CLRDBC)) != 0 && ret == 0) - ret = t_ret; - else if ((t_ret = __db_c_close(ndbc)) != 0 && ret == 0) - ret = t_ret; - } - - if (pg != NULL && (t_ret = __memp_fput(dbmp, pg, 0) != 0) && ret == 0) - ret = t_ret; - if (npg != NULL && (t_ret = __memp_fput(dbmp, npg, 0) != 0) && ret == 0) - ret = t_ret; - - *donep = done; - - return (ret); -} - -/* - * __bam_merge -- do actual merging of leaf pages. - */ -static int -__bam_merge(dbc, ndbc, factor, stop, c_data, donep) - DBC *dbc, *ndbc; - u_int32_t factor; - DBT *stop; - DB_COMPACT *c_data; - int *donep; -{ - BTREE_CURSOR *cp, *ncp; - BTREE *t; - DB *dbp; - PAGE *pg, *npg; - db_indx_t adj, nent; - db_recno_t recno; - int cmp, ret; - int (*func) __P((DB *, const DBT *, const DBT *)); - - dbp = dbc->dbp; - t = dbp->bt_internal; - cp = (BTREE_CURSOR *)dbc->internal; - ncp = (BTREE_CURSOR *)ndbc->internal; - pg = cp->csp->page; - npg = ncp->csp->page; - - nent = NUM_ENT(npg); - - /* If the page is empty just throw it away. */ - if (nent == 0) - goto free; - adj = TYPE(npg) == P_LBTREE ? P_INDX : O_INDX; - /* Find if the stopping point is on this page. */ - if (stop != NULL && stop->size != 0) { - if (dbc->dbtype == DB_RECNO) { - if ((ret = __ram_getno(dbc, stop, &recno, 0)) != 0) - goto err; - if (ncp->recno > recno) { - *donep = 1; - if (cp->recno > recno) - goto done; - } - } else { - func = TYPE(npg) == P_LBTREE ? - (dbp->dup_compare == NULL ? - __bam_defcmp : dbp->dup_compare) : t->bt_compare; - - if ((ret = __bam_cmp(dbp, - stop, npg, nent - adj, func, &cmp)) != 0) - goto err; - - /* - * If the last record is beyond the stopping - * point we are done after this page. If the - * first record is beyond the stopping point - * don't even bother with this page. - */ - if (cmp <= 0) { - *donep = 1; - if ((ret = __bam_cmp(dbp, - stop, npg, 0, func, &cmp)) != 0) - goto err; - if (cmp <= 0) - goto done; - } - } - } - - /* - * If there is too much data then just move records one at a time. - * Otherwise copy the data space over and fix up the index table. - * If we are on the left most child we will effect our parent's - * index entry so we call merge_records to figure out key sizes. - */ - if ((dbc->dbtype == DB_BTREE && - ncp->csp[-1].indx == 0 && ncp->csp[-1].entries != 1) || - (int)(P_FREESPACE(dbp, pg) - - ((dbp->pgsize - P_OVERHEAD(dbp)) - - P_FREESPACE(dbp, npg))) < (int)factor) - ret = __bam_merge_records(dbc, ndbc, factor, c_data); - else -free: ret = __bam_merge_pages(dbc, ndbc, c_data); - -done: -err: return (ret); -} - -static int -__bam_merge_records(dbc, ndbc, factor, c_data) - DBC *dbc, *ndbc; - u_int32_t factor; - DB_COMPACT *c_data; -{ - BKEYDATA *bk, *tmp_bk; - BINTERNAL *bi; - BTREE *t; - BTREE_CURSOR *cp, *ncp; - DB *dbp; - DBT a, b, data, hdr; - EPG *epg; - PAGE *pg, *npg; - db_indx_t adj, indx, nent, *ninp, pind; - int32_t adjust; - u_int32_t free, nksize, pfree, size; - int first_dup, is_dup, next_dup, n_ok, ret; - size_t (*func) __P((DB *, const DBT *, const DBT *)); - - dbp = dbc->dbp; - t = dbp->bt_internal; - cp = (BTREE_CURSOR *)dbc->internal; - ncp = (BTREE_CURSOR *)ndbc->internal; - pg = cp->csp->page; - npg = ncp->csp->page; - memset(&hdr, 0, sizeof(hdr)); - pind = NUM_ENT(pg); - n_ok = 0; - adjust = 0; - ret = 0; - nent = NUM_ENT(npg); - - DB_ASSERT (nent != 0); - - /* See if we want to swap out this page. */ - if (c_data->compact_truncate != PGNO_INVALID && - PGNO(npg) > c_data->compact_truncate) { - /* Get a fresh low numbered page. */ - if ((ret = __bam_truncate_page(ndbc, &npg, 1)) != 0) - goto err; - } - - ninp = P_INP(dbp, npg); - - /* - * pg is the page that is being filled, it is in the stack in cp. - * npg is the next page, it is in the stack in ncp. - */ - free = P_FREESPACE(dbp, pg); - - adj = TYPE(npg) == P_LBTREE ? P_INDX : O_INDX; - /* - * Loop through the records and find the stopping point. - */ - for (indx = 0; indx < nent; indx += adj) { - bk = GET_BKEYDATA(dbp, npg, indx); - - /* Size of the key. */ - size = BITEM_PSIZE(bk); - - /* Size of the data. */ - if (TYPE(pg) == P_LBTREE) - size += BITEM_PSIZE(GET_BKEYDATA(dbp, npg, indx + 1)); - /* - * If we are at a duplicate set, skip ahead to see and - * get the total size for the group. - */ - n_ok = adj; - if (TYPE(pg) == P_LBTREE && - indx < nent - adj && - ninp[indx] == ninp[indx + adj]) { - do { - /* Size of index for key reference. */ - size += sizeof(db_indx_t); - n_ok++; - /* Size of data item. */ - size += BITEM_PSIZE( - GET_BKEYDATA(dbp, npg, indx + n_ok)); - n_ok++; - } while (indx + n_ok < nent && - ninp[indx] == ninp[indx + n_ok]); - } - /* if the next set will not fit on the page we are done. */ - if (free < size) - break; - - /* - * Otherwise figure out if we are past the goal and if - * adding this set will put us closer to the goal than - * we are now. - */ - if ((free - size) < factor) { - if (free - factor > factor - (free - size)) - indx += n_ok; - break; - } - free -= size; - indx += n_ok - adj; - } - if (indx == 0) - goto done; - if (TYPE(pg) != P_LBTREE) { - if (indx == nent) - return (__bam_merge_pages(dbc, ndbc, c_data)); - goto no_check; - } - /* - * We need to update npg's parent key. Avoid creating a new key - * that will be too big. Get what space will be available on the - * parents. Then if there will not be room for this key, see if - * prefix compression will make it work, if not backup till we - * find something that will. (Needless to say, this is a very - * unlikely event.) If we are deleting this page then we will - * need to propagate the next key to our grand parents, so we - * see if that will fit. - */ - pfree = dbp->pgsize; - for (epg = &ncp->csp[-1]; epg >= ncp->sp; epg--) - if ((free = P_FREESPACE(dbp, epg->page)) < pfree) { - bi = GET_BINTERNAL(dbp, epg->page, epg->indx); - /* Add back in the key we will be deleting. */ - free += BINTERNAL_PSIZE(bi->len); - if (free < pfree) - pfree = free; - if (epg->indx != 0) - break; - } - - /* - * If we are at the end, we will delete this page. We need to - * check the next parent key only if we are the leftmost page and - * will therefore have to propagate the key up the tree. - */ - if (indx == nent) { - if (ncp->csp[-1].indx != 0 || - BINTERNAL_PSIZE(GET_BINTERNAL(dbp, - ncp->csp[-1].page, 1)->len) <= pfree) - return (__bam_merge_pages(dbc, ndbc, c_data)); - indx -= adj; - } - bk = GET_BKEYDATA(dbp, npg, indx); - if (indx != 0 && BINTERNAL_SIZE(bk->len) >= pfree) { - if (F_ISSET(dbc, DBC_OPD)) { - if (dbp->dup_compare == __bam_defcmp) - func = __bam_defpfx; - else - func = NULL; - } else - func = t->bt_prefix; - } else - func = NULL; - - /* Skip to the beginning of a duplicate set. */ - while (indx != 0 && ninp[indx] == ninp[indx - adj]) - indx -= adj; - - while (indx != 0 && BINTERNAL_SIZE(bk->len) >= pfree) { - if (B_TYPE(bk->type) != B_KEYDATA) - goto noprefix; - /* - * Figure out if we can truncate this key. - * Code borrowed from bt_split.c - */ - if (func == NULL) - goto noprefix; - tmp_bk = GET_BKEYDATA(dbp, npg, indx - adj); - if (B_TYPE(tmp_bk->type) != B_KEYDATA) - goto noprefix; - memset(&a, 0, sizeof(a)); - a.size = tmp_bk->len; - a.data = tmp_bk->data; - memset(&b, 0, sizeof(b)); - b.size = bk->len; - b.data = bk->data; - nksize = (u_int32_t)func(dbp, &a, &b); - if (BINTERNAL_PSIZE(nksize) < pfree) - break; -noprefix: - /* Skip to the beginning of a duplicate set. */ - do { - indx -= adj; - } while (indx != 0 && ninp[indx] == ninp[indx - adj]); - - bk = GET_BKEYDATA(dbp, npg, indx); - } - - if (indx == 0) - goto done; - DB_ASSERT(indx <= nent); - - /* Loop through the records and move them from npg to pg. */ -no_check: is_dup = first_dup = next_dup = 0; - do { - bk = GET_BKEYDATA(dbp, npg, 0); - /* Figure out if we are in a duplicate group or not. */ - if ((NUM_ENT(npg) % 2) == 0) { - if (NUM_ENT(npg) > 2 && ninp[0] == ninp[2]) { - if (!is_dup) { - first_dup = 1; - is_dup = 1; - } else - first_dup = 0; - - next_dup = 1; - } else if (next_dup) { - is_dup = 1; - first_dup = 0; - next_dup = 0; - } else - is_dup = 0; - } - - if (is_dup && !first_dup && (pind % 2) == 0) { - /* Duplicate key. */ - if ((ret = __bam_adjindx(dbc, - pg, pind, pind - P_INDX, 1)) != 0) - goto err; - if (!next_dup) - is_dup = 0; - } else switch (B_TYPE(bk->type)) { - case B_KEYDATA: - hdr.data = bk; - hdr.size = SSZA(BKEYDATA, data); - data.size = bk->len; - data.data = bk->data; - if ((ret = __db_pitem(dbc, pg, pind, - BKEYDATA_SIZE(bk->len), &hdr, &data)) != 0) - goto err; - break; - case B_OVERFLOW: - case B_DUPLICATE: - data.size = BOVERFLOW_SIZE; - data.data = bk; - if ((ret = __db_pitem(dbc, pg, pind, - BOVERFLOW_SIZE, &data, NULL)) != 0) - goto err; - break; - default: - __db_err(dbp->dbenv, - "Unknown record format, page %lu, indx 0", - (u_long)PGNO(pg)); - ret = EINVAL; - goto err; - } - pind++; - if (next_dup && (NUM_ENT(npg) % 2) == 0) { - if ((ret = __bam_adjindx(ndbc, - npg, 0, O_INDX, 0)) != 0) - goto err; - } else { - if ((ret = __db_ditem(ndbc, - npg, 0, BITEM_SIZE(bk))) != 0) - goto err; - } - adjust++; - } while (--indx != 0); - - DB_ASSERT(NUM_ENT(npg) != 0); - if ((ret = __memp_fset(dbp->mpf, npg, DB_MPOOL_DIRTY)) != 0) - goto err; - - if (adjust != 0 && - (F_ISSET(cp, C_RECNUM) || F_ISSET(dbc, DBC_OPD))) { - DB_ASSERT(cp->csp - cp->sp == ncp->csp - ncp->sp); - if (TYPE(pg) == P_LBTREE) - adjust /= P_INDX; - if ((ret = __bam_adjust(ndbc, -adjust)) != 0) - goto err; - - if ((ret = __bam_adjust(dbc, adjust)) != 0) - goto err; - } - - /* Update parent with new key. */ - if (ndbc->dbtype == DB_BTREE && - (ret = __bam_pupdate(ndbc, pg)) != 0) - goto err; - if ((ret = __memp_fset(dbp->mpf, pg, DB_MPOOL_DIRTY)) != 0) - goto err; - -done: ret = __bam_stkrel(ndbc, STK_CLRDBC); - -err: return (ret); -} - -static int -__bam_merge_pages(dbc, ndbc, c_data) - DBC *dbc, *ndbc; - DB_COMPACT *c_data; -{ - BTREE_CURSOR *cp, *ncp; - DB *dbp; - DB_MPOOLFILE *dbmp; - DBT data, hdr, ind; - PAGE *pg, *npg; - db_indx_t nent, *ninp, *pinp; - db_pgno_t ppgno; - u_int8_t *bp; - u_int32_t len; - int i, level, ret; - - COMPQUIET(ppgno, PGNO_INVALID); - dbp = dbc->dbp; - dbmp = dbp->mpf; - cp = (BTREE_CURSOR *)dbc->internal; - ncp = (BTREE_CURSOR *)ndbc->internal; - pg = cp->csp->page; - npg = ncp->csp->page; - memset(&hdr, 0, sizeof(hdr)); - nent = NUM_ENT(npg); - - /* If the page is empty just throw it away. */ - if (nent == 0) - goto free; - /* Bulk copy the data to the new page. */ - len = dbp->pgsize - HOFFSET(npg); - if (DBC_LOGGING(dbc)) { - data.data = (u_int8_t *)npg + HOFFSET(npg); - data.size = len; - ind.data = P_INP(dbp, npg); - ind.size = NUM_ENT(npg) * sizeof(db_indx_t); - if ((ret = __bam_merge_log(dbp, - dbc->txn, &LSN(pg), 0, PGNO(pg), - &LSN(pg), PGNO(npg), &LSN(npg), NULL, &data, &ind)) != 0) - goto err; - } else - LSN_NOT_LOGGED(LSN(pg)); - LSN(npg) = LSN(pg); - bp = (u_int8_t *)pg + HOFFSET(pg) - len; - memcpy(bp, (u_int8_t *)npg + HOFFSET(npg), len); - - /* Copy index table offset by what was there already. */ - pinp = P_INP(dbp, pg) + NUM_ENT(pg); - ninp = P_INP(dbp, npg); - for (i = 0; i < NUM_ENT(npg); i++) - *pinp++ = *ninp++ - (dbp->pgsize - HOFFSET(pg)); - HOFFSET(pg) -= len; - NUM_ENT(pg) += i; - - NUM_ENT(npg) = 0; - HOFFSET(npg) += len; - - if (F_ISSET(cp, C_RECNUM) || F_ISSET(dbc, DBC_OPD)) { - DB_ASSERT(cp->csp - cp->sp == ncp->csp - ncp->sp); - if (TYPE(pg) == P_LBTREE) - i /= P_INDX; - if ((ret = __bam_adjust(ndbc, -i)) != 0) - goto err; - - if ((ret = __bam_adjust(dbc, i)) != 0) - goto err; - } - ret = __memp_fset(dbp->mpf, pg, DB_MPOOL_DIRTY); - -free: /* - * __bam_dpages may decide to collapse the tree. - * This can happen if we have the root and there - * are exactly 2 pointers left in it. - * If it can collapse the tree we must free the other - * stack since it will nolonger be valid. This - * must be done before hand because we cannot - * hold a page pinned if it might be truncated. - */ - if (PGNO(ncp->sp->page) == ncp->root && - NUM_ENT(ncp->sp->page) == 2) { - if ((ret = __bam_stkrel(dbc, STK_CLRDBC | STK_PGONLY)) != 0) - goto err; - level = LEVEL(ncp->sp->page); - ppgno = PGNO(ncp->csp[-1].page); - } else - level = 0; - if (c_data->compact_truncate > PGNO(npg)) - c_data->compact_truncate--; - if ((ret = __bam_dpages(ndbc, - 0, ndbc->dbtype == DB_RECNO ? 0 : 1)) != 0) - goto err; - npg = NULL; - c_data->compact_pages_free++; - c_data->compact_pages--; - if (level != 0) { - if ((ret = __memp_fget(dbmp, &ncp->root, 0, &npg)) != 0) - goto err; - if (level == LEVEL(npg)) - level = 0; - if ((ret = __memp_fput(dbmp, npg, 0)) != 0) - goto err; - npg = NULL; - if (level != 0) { - c_data->compact_levels++; - c_data->compact_pages_free++; - if (c_data->compact_truncate > ppgno) - c_data->compact_truncate--; - if (c_data->compact_pages != 0) - c_data->compact_pages--; - } - } - -err: return (ret); -} - -/* - * __bam_merge_internal -- - * Merge internal nodes of the tree. - */ -static int -__bam_merge_internal(dbc, ndbc, level, c_data, merged) - DBC *dbc, *ndbc; - int level; - DB_COMPACT *c_data; - int *merged; -{ - BINTERNAL bi, *bip, *fip; - BTREE_CURSOR *cp, *ncp; - DB_MPOOLFILE *dbmp; - DB *dbp; - DBT data, hdr; - EPG *epg, *save_csp, *nsave_csp; - PAGE *pg, *npg; - RINTERNAL *rk; - db_indx_t indx, pind; - db_pgno_t ppgno; - int32_t trecs; - u_int16_t size; - u_int32_t free, pfree; - int ret; - - COMPQUIET(bip, NULL); - COMPQUIET(ppgno, PGNO_INVALID); - - /* - * ndbc will contain the the dominating parent of the subtree. - * dbc will have the tree containing the left child. - * - * The stacks descend to the leaf level. - * If this is a recno tree then both stacks will start at the root. - */ - dbp = dbc->dbp; - dbmp = dbp->mpf; - cp = (BTREE_CURSOR *)dbc->internal; - ncp = (BTREE_CURSOR *)ndbc->internal; - *merged = 0; - ret = 0; - - /* - * Set the stacks to the level requested. - * Save the old value to restore when we exit. - */ - save_csp = cp->csp; - epg = &cp->csp[-level + 1]; - cp->csp = epg; - pg = epg->page; - pind = NUM_ENT(pg); - - nsave_csp = ncp->csp; - epg = &ncp->csp[-level + 1]; - ncp->csp = epg; - npg = epg->page; - indx = NUM_ENT(npg); - - /* - * The caller may have two stacks that include common ancestors, we - * check here for convenience. - */ - if (npg == pg) - goto done; - - if (TYPE(pg) == P_IBTREE) { - /* - * Check for overflow keys on both pages while we have - * them locked. - */ - if ((ret = - __bam_truncate_internal_overflow(dbc, pg, c_data)) != 0) - goto err; - if ((ret = - __bam_truncate_internal_overflow(dbc, npg, c_data)) != 0) - goto err; - } - - /* - * If we are about to move data off the left most page of an - * internal node we will need to update its parents, make sure there - * will be room for the new key on all the parents in the stack. - * If not, move less data. - */ - fip = NULL; - if (TYPE(pg) == P_IBTREE) { - /* See where we run out of space. */ - free = P_FREESPACE(dbp, pg); - /* - * The leftmost key of an internal page is not accurate. - * Go up the tree to find a non-leftmost parent. - */ - while (--epg >= ncp->sp && epg->indx == 0) - continue; - fip = bip = GET_BINTERNAL(dbp, epg->page, epg->indx); - epg = ncp->csp; - - for (indx = 0;;) { - size = BINTERNAL_PSIZE(bip->len); - if (size > free) - break; - free -= size; - if (++indx >= NUM_ENT(npg)) - break; - bip = GET_BINTERNAL(dbp, npg, indx); - } - - /* See if we are deleting the page and we are not left most. */ - if (indx == NUM_ENT(npg) && epg[-1].indx != 0) - goto fits; - - pfree = dbp->pgsize; - for (epg--; epg >= ncp->sp; epg--) - if ((free = P_FREESPACE(dbp, epg->page)) < pfree) { - bip = GET_BINTERNAL(dbp, epg->page, epg->indx); - /* Add back in the key we will be deleting. */ - free += BINTERNAL_PSIZE(bip->len); - if (free < pfree) - pfree = free; - if (epg->indx != 0) - break; - } - epg = ncp->csp; - - /* If we are at the end of the page we will delete it. */ - if (indx == NUM_ENT(npg)) - bip = - GET_BINTERNAL(dbp, epg[-1].page, epg[-1].indx + 1); - else - bip = GET_BINTERNAL(dbp, npg, indx); - - /* Back up until we have a key that fits. */ - while (indx != 0 && BINTERNAL_PSIZE(bip->len) > pfree) { - indx--; - bip = GET_BINTERNAL(dbp, npg, indx); - } - if (indx == 0) - goto done; - } - -fits: memset(&bi, 0, sizeof(bi)); - memset(&hdr, 0, sizeof(hdr)); - memset(&data, 0, sizeof(data)); - trecs = 0; - - /* - * Copy data between internal nodes till one is full - * or the other is empty. - */ - do { - if (dbc->dbtype == DB_BTREE) { - bip = GET_BINTERNAL(dbp, npg, 0); - size = fip == NULL ? - BINTERNAL_SIZE(bip->len) : - BINTERNAL_SIZE(fip->len); - if (P_FREESPACE(dbp, pg) < size + sizeof(db_indx_t)) - break; - - if (fip == NULL) { - data.size = bip->len; - data.data = bip->data; - } else { - data.size = fip->len; - data.data = fip->data; - } - bi.len = data.size; - B_TSET(bi.type, bip->type, 0); - bi.pgno = bip->pgno; - bi.nrecs = bip->nrecs; - hdr.data = &bi; - hdr.size = SSZA(BINTERNAL, data); - if (F_ISSET(cp, C_RECNUM) || F_ISSET(dbc, DBC_OPD)) - trecs += (int32_t)bip->nrecs; - } else { - rk = GET_RINTERNAL(dbp, npg, 0); - size = RINTERNAL_SIZE; - if (P_FREESPACE(dbp, pg) < size + sizeof(db_indx_t)) - break; - - hdr.data = rk; - hdr.size = size; - trecs += (int32_t)rk->nrecs; - } - if ((ret = __db_pitem(dbc, pg, pind, size, &hdr, &data)) != 0) - goto err; - pind++; - if (fip != NULL) { - /* reset size to be for the record being deleted. */ - size = BINTERNAL_SIZE(bip->len); - fip = NULL; - } - if ((ret = __db_ditem(ndbc, npg, 0, size)) != 0) - goto err; - *merged = 1; - } while (--indx != 0); - - if (c_data->compact_truncate != PGNO_INVALID && - PGNO(pg) > c_data->compact_truncate && cp->csp != cp->sp) { - if ((ret = __bam_truncate_page(dbc, &pg, 1)) != 0) - goto err; - } - - if (NUM_ENT(npg) != 0 && c_data->compact_truncate != PGNO_INVALID && - PGNO(npg) > c_data->compact_truncate && ncp->csp != ncp->sp) { - if ((ret = __bam_truncate_page(ndbc, &npg, 1)) != 0) - goto err; - } - - if (!*merged) - goto done; - - if ((ret = __memp_fset(dbmp, pg, DB_MPOOL_DIRTY)) != 0) - goto err; - if ((ret = __memp_fset(dbmp, npg, DB_MPOOL_DIRTY)) != 0) - goto err; - - if (trecs != 0) { - DB_ASSERT(cp->csp - cp->sp == ncp->csp - ncp->sp); - cp->csp--; - if ((ret = __bam_adjust(dbc, trecs)) != 0) - goto err; - - ncp->csp--; - if ((ret = __bam_adjust(ndbc, -trecs)) != 0) - goto err; - ncp->csp++; - } - cp->csp = save_csp; - - /* - * Either we emptied the page or we need to update its - * parent to reflect the first page we now point to. - * First get rid of the bottom of the stack, - * bam_dpages will clear the stack. We can drop - * the locks on those pages as we have not done - * anything to them. - */ - do { - if ((ret = __memp_fput(dbmp, nsave_csp->page, 0)) != 0) - goto err; - if ((ret = __LPUT(dbc, nsave_csp->lock)) != 0) - goto err; - nsave_csp--; - } while (nsave_csp != ncp->csp); - - if (NUM_ENT(npg) == 0) { - /* - * __bam_dpages may decide to collapse the tree - * so we need to free our other stack. The tree - * will change in hight and our stack will nolonger - * be valid. - */ - if (PGNO(ncp->sp->page) == ncp->root && - NUM_ENT(ncp->sp->page) == 2) { - if ((ret = __bam_stkrel(dbc, STK_CLRDBC)) != 0) - goto err; - level = LEVEL(ncp->sp->page); - ppgno = PGNO(ncp->csp[-1].page); - } else - level = 0; - - if (c_data->compact_truncate > PGNO(npg)) - c_data->compact_truncate--; - ret = __bam_dpages(ndbc, - 0, ndbc->dbtype == DB_RECNO ? 0 : 1); - c_data->compact_pages_free++; - if (ret == 0 && level != 0) { - if ((ret = __memp_fget(dbmp, &ncp->root, 0, &npg)) != 0) - goto err; - if (level == LEVEL(npg)) - level = 0; - if ((ret = __memp_fput(dbmp, npg, 0)) != 0) - goto err; - npg = NULL; - if (level != 0) { - c_data->compact_levels++; - c_data->compact_pages_free++; - if (c_data->compact_truncate > ppgno) - c_data->compact_truncate--; - if (c_data->compact_pages != 0) - c_data->compact_pages--; - } - } - } else - ret = __bam_pupdate(ndbc, npg); - return (ret); - -done: -err: cp->csp = save_csp; - ncp->csp = nsave_csp; - - return (ret); -} - -/* - * __bam_compact_dups -- try to compress off page dup trees. - * We may or may not have a write lock on this page. - */ -static int -__bam_compact_dups(dbc, pg, factor, have_lock, c_data, donep) - DBC *dbc; - PAGE *pg; - u_int32_t factor; - int have_lock; - DB_COMPACT *c_data; - int *donep; -{ - BTREE_CURSOR *cp; - BOVERFLOW *bo; - DB *dbp; - DBC *opd; - DBT start; - DB_MPOOLFILE *dbmp; - PAGE *dpg; - db_indx_t i; - int done, level, ret, span, t_ret; - - span = 0; - ret = 0; - opd = NULL; - - dbp = dbc->dbp; - dbmp = dbp->mpf; - cp = (BTREE_CURSOR *)dbc->internal; - - for (i = 0; i < NUM_ENT(pg); i++) { - bo = GET_BOVERFLOW(dbp, pg, i); - if (B_TYPE(bo->type) == B_KEYDATA) - continue; - c_data->compact_pages_examine++; - if (bo->pgno > c_data->compact_truncate) { - (*donep)++; - if (!have_lock) { - if ((ret = __db_lget(dbc, 0, PGNO(pg), - DB_LOCK_WRITE, 0, &cp->csp->lock)) != 0) - goto err; - have_lock = 1; - } - if ((ret = - __bam_truncate_root_page(dbc, pg, i, c_data)) != 0) - goto err; - /* Just in case it should move. Could it? */ - bo = GET_BOVERFLOW(dbp, pg, i); - } - - if (B_TYPE(bo->type) == B_OVERFLOW) { - if ((ret = __bam_truncate_overflow(dbc, bo->pgno, - have_lock ? PGNO_INVALID : PGNO(pg), c_data)) != 0) - goto err; - (*donep)++; - continue; - } - /* - * Take a peek at the root. If it's a leaf then - * there is no tree here, avoid all the trouble. - */ - if ((ret = __memp_fget(dbmp, &bo->pgno, 0, &dpg)) != 0) - goto err; - - level = dpg->level; - if ((ret = __memp_fput(dbmp, dpg, 0)) != 0) - goto err; - if (level == LEAFLEVEL) - continue; - if ((ret = __db_c_newopd(dbc, bo->pgno, NULL, &opd)) != 0) - return (ret); - if (!have_lock) { - if ((ret = __db_lget(dbc, 0, - PGNO(pg), DB_LOCK_WRITE, 0, &cp->csp->lock)) != 0) - goto err; - have_lock = 1; - } - (*donep)++; - memset(&start, 0, sizeof(start)); - do { - if ((ret = __bam_compact_int(opd, &start, - NULL, factor, &span, c_data, &done)) != 0) - break; - } while (!done); - - if (start.data != NULL) - __os_free(dbp->dbenv, start.data); - - if (ret != 0) - goto err; - - ret = __db_c_close(opd); - opd = NULL; - if (ret != 0) - goto err; - } - -err: if (opd != NULL && (t_ret = __db_c_close(opd)) != 0 && ret == 0) - ret = t_ret; - return (ret); -} - -/* - * __bam_truncate_page -- swap a page with a lower numbered page. - * The cusor has a stack which includes at least the - * immediate parent of this page. - */ -static int -__bam_truncate_page(dbc, pgp, update_parent) - DBC *dbc; - PAGE **pgp; - int update_parent; -{ - BTREE_CURSOR *cp; - DB *dbp; - DBT data, hdr, ind; - DB_LSN lsn; - EPG *epg; - PAGE *newpage; - db_pgno_t newpgno, *pgnop; - int ret; - - dbp = dbc->dbp; - - /* - * We want to free a page that lives in the part of the file that - * can be truncated, so we're going to move it onto a free page - * that is in the part of the file that need not be truncated. - * Since the freelist is ordered now, we can simply call __db_new - * which will grab the first element off the freelist; we know this - * is the lowest numbered free page. - */ - - if ((ret = __db_new(dbc, P_DONTEXTEND | TYPE(*pgp), &newpage)) != 0) - return (ret); - - /* - * If newpage is null then __db_new would have had to allocate - * a new page from the filesystem, so there is no reason - * to continue this action. - */ - if (newpage == NULL) - return (0); - - /* - * It is possible that a higher page is allocated if other threads - * are allocating at the same time, if so, just put it back. - */ - if (PGNO(newpage) > PGNO(*pgp)) { - /* Its unfortunate but you can't just free a new overflow. */ - if (TYPE(newpage) == P_OVERFLOW) - OV_LEN(newpage) = 0; - return (__db_free(dbc, newpage)); - } - - /* Log if necessary. */ - if (DBC_LOGGING(dbc)) { - hdr.data = *pgp; - hdr.size = P_OVERHEAD(dbp); - if (TYPE(*pgp) == P_OVERFLOW) { - data.data = (u_int8_t *)*pgp + P_OVERHEAD(dbp); - data.size = OV_LEN(*pgp); - ind.size = 0; - } else { - data.data = (u_int8_t *)*pgp + HOFFSET(*pgp); - data.size = dbp->pgsize - HOFFSET(*pgp); - ind.data = P_INP(dbp, *pgp); - ind.size = NUM_ENT(*pgp) * sizeof(db_indx_t); - } - if ((ret = __bam_merge_log(dbp, dbc->txn, - &LSN(newpage), 0, PGNO(newpage), &LSN(newpage), - PGNO(*pgp), &LSN(*pgp), &hdr, &data, &ind)) != 0) - goto err; - } else - LSN_NOT_LOGGED(LSN(newpage)); - - newpgno = PGNO(newpage); - lsn = LSN(newpage); - memcpy(newpage, *pgp, dbp->pgsize); - PGNO(newpage) = newpgno; - LSN(newpage) = lsn; - - /* Empty the old page. */ - if (TYPE(*pgp) == P_OVERFLOW) - OV_LEN(*pgp) = 0; - else { - HOFFSET(*pgp) = dbp->pgsize; - NUM_ENT(*pgp) = 0; - } - LSN(*pgp) = lsn; - - if ((ret = __memp_fset(dbp->mpf, newpage, DB_MPOOL_DIRTY)) != 0) - goto err; - - /* Update siblings. */ - switch (TYPE(newpage)) { - case P_OVERFLOW: - case P_LBTREE: - case P_LRECNO: - case P_LDUP: - if (NEXT_PGNO(newpage) == PGNO_INVALID && - PREV_PGNO(newpage) == PGNO_INVALID) - break; - if ((ret = __bam_relink(dbc, *pgp, PGNO(newpage))) != 0) - goto err; - break; - default: - break; - } - cp = (BTREE_CURSOR*)dbc->internal; - - /* - * Now, if we free this page, it will get truncated, when we free - * all the pages after it in the file. - */ - ret = __db_free(dbc, *pgp); - /* db_free always puts the page. */ - *pgp = newpage; - - if (ret != 0) - return (ret); - - if (!update_parent) - goto done; - - /* Update the parent. */ - epg = &cp->csp[-1]; - switch (TYPE(epg->page)) { - case P_IBTREE: - pgnop = &GET_BINTERNAL(dbp, epg->page, epg->indx)->pgno; - break; - case P_IRECNO: - pgnop = &GET_RINTERNAL(dbp, epg->page, epg->indx)->pgno; - break; - default: - pgnop = &GET_BOVERFLOW(dbp, epg->page, epg->indx)->pgno; - break; - } - if (DBC_LOGGING(dbc)) { - if ((ret = __bam_pgno_log(dbp, dbc->txn, &LSN(epg->page), - 0, PGNO(epg->page), &LSN(epg->page), (u_int32_t)epg->indx, - *pgnop, PGNO(newpage))) != 0) - return (ret); - } else - LSN_NOT_LOGGED(LSN(epg->page)); - - *pgnop = PGNO(newpage); - cp->csp->page = newpage; - if ((ret = __memp_fset(dbp->mpf, epg->page, DB_MPOOL_DIRTY)) != 0) - return (ret); - -done: return (0); - -err: (void)__memp_fput(dbp->mpf, newpage, 0); - return (ret); -} - -/* - * __bam_truncate_overflow -- find overflow pages to truncate. - * Walk the pages of an overflow chain and swap out - * high numbered pages. We are passed the first page - * but only deal with the second and subsequent pages. - */ - -static int -__bam_truncate_overflow(dbc, pgno, pg_lock, c_data) - DBC *dbc; - db_pgno_t pgno; - db_pgno_t pg_lock; - DB_COMPACT *c_data; -{ - DB *dbp; - DB_LOCK lock; - PAGE *page; - int ret, t_ret; - - dbp = dbc->dbp; - page = NULL; - LOCK_INIT(lock); - - if ((ret = __memp_fget(dbp->mpf, &pgno, 0, &page)) != 0) - return (ret); - - while ((pgno = NEXT_PGNO(page)) != PGNO_INVALID) { - if ((ret = __memp_fput(dbp->mpf, page, 0)) != 0) - return (ret); - if ((ret = __memp_fget(dbp->mpf, &pgno, 0, &page)) != 0) - return (ret); - if (pgno <= c_data->compact_truncate) - continue; - if (pg_lock != PGNO_INVALID) { - if ((ret = __db_lget(dbc, - 0, pg_lock, DB_LOCK_WRITE, 0, &lock)) != 0) - break; - pg_lock = PGNO_INVALID; - } - if ((ret = __bam_truncate_page(dbc, &page, 0)) != 0) - break; - } - - if (page != NULL && - (t_ret = __memp_fput(dbp->mpf, page, 0)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0) - ret = t_ret; - return (ret); -} - -/* - * __bam_truncate_root_page -- swap a page which is - * the root of an off page dup tree or the head of an overflow. - * The page is reference by the pg/indx passed in. - */ -static int -__bam_truncate_root_page(dbc, pg, indx, c_data) - DBC *dbc; - PAGE *pg; - u_int32_t indx; - DB_COMPACT *c_data; -{ - BINTERNAL *bi; - BOVERFLOW *bo; - DB *dbp; - DBT orig; - PAGE *page; - db_pgno_t newpgno, *pgnop; - int ret, t_ret; - - COMPQUIET(c_data, NULL); - COMPQUIET(bo, NULL); - COMPQUIET(newpgno, PGNO_INVALID); - dbp = dbc->dbp; - page = NULL; - if (TYPE(pg) == P_IBTREE) { - bi = GET_BINTERNAL(dbp, pg, indx); - if (B_TYPE(bi->type) == B_OVERFLOW) { - bo = (BOVERFLOW *)(bi->data); - pgnop = &bo->pgno; - } else - pgnop = &bi->pgno; - } else { - bo = GET_BOVERFLOW(dbp, pg, indx); - pgnop = &bo->pgno; - } - - if ((ret = __memp_fget(dbp->mpf, pgnop, 0, &page)) != 0) - goto err; - - /* - * If this is a multiply reference overflow key, then we will just - * copy it and decrement the reference count. This is part of a - * fix to get rid of multiple references. - */ - if (TYPE(page) == P_OVERFLOW && OV_REF(page) > 1) { - if ((ret = __db_ovref(dbc, bo->pgno, -1)) != 0) - goto err; - memset(&orig, 0, sizeof(orig)); - if ((ret = __db_goff(dbp, &orig, - bo->tlen, bo->pgno, &orig.data, &orig.size)) == 0) - ret = __db_poff(dbc, &orig, &newpgno); - if (orig.data != NULL) - __os_free(dbp->dbenv, orig.data); - if (ret != 0) - goto err; - } else { - if ((ret = __bam_truncate_page(dbc, &page, 0)) != 0) - goto err; - newpgno = PGNO(page); - /* If we could not allocate from the free list, give up.*/ - if (newpgno == *pgnop) - goto err; - } - - /* Update the reference. */ - if (DBC_LOGGING(dbc)) { - if ((ret = __bam_pgno_log(dbp, - dbc->txn, &LSN(pg), 0, PGNO(pg), - &LSN(pg), (u_int32_t)indx, *pgnop, newpgno)) != 0) - goto err; - } else - LSN_NOT_LOGGED(LSN(pg)); - - *pgnop = newpgno; - if ((ret = __memp_fset(dbp->mpf, pg, DB_MPOOL_DIRTY)) != 0) - goto err; - -err: if (page != NULL && (t_ret = - __memp_fput(dbp->mpf, page, DB_MPOOL_DIRTY)) != 0 && ret == 0) - ret = t_ret; - return (ret); -} - -/* - * -- bam_truncate_internal_overflow -- find overflow keys - * on internal pages and if they have high page - * numbers swap them with lower pages and truncate them. - * Note that if there are overflow keys in the internal - * nodes they will get copied adding pages to the database. - */ -static int -__bam_truncate_internal_overflow(dbc, page, c_data) - DBC *dbc; - PAGE *page; - DB_COMPACT *c_data; -{ - BINTERNAL *bi; - BOVERFLOW *bo; - db_indx_t indx; - int ret; - - COMPQUIET(bo, NULL); - ret = 0; - for (indx = 0; indx < NUM_ENT(page); indx++) { - bi = GET_BINTERNAL(dbc->dbp, page, indx); - if (B_TYPE(bi->type) != B_OVERFLOW) - continue; - bo = (BOVERFLOW *)(bi->data); - if (bo->pgno > c_data->compact_truncate && (ret = - __bam_truncate_root_page(dbc, page, indx, c_data)) != 0) - break; - if ((ret = __bam_truncate_overflow( - dbc, bo->pgno, PGNO_INVALID, c_data)) != 0) - break; - } - return (ret); -} - -#ifdef HAVE_FTRUNCATE -/* - * __bam_savekey -- save the key from an internal page. - * We need to save information so that we can - * fetch then next internal node of the tree. This means - * we need the btree key on this current page, or the - * next record number. - */ -static int -__bam_savekey(dbc, next, start) - DBC *dbc; - int next; - DBT *start; -{ - BINTERNAL *bi; - BOVERFLOW *bo; - BTREE_CURSOR *cp; - DB *dbp; - DB_ENV *dbenv; - PAGE *pg; - RINTERNAL *ri; - db_indx_t indx, top; - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - cp = (BTREE_CURSOR *)dbc->internal; - pg = cp->csp->page; - - if (dbc->dbtype == DB_RECNO) { - if (next) - for (indx = 0, top = NUM_ENT(pg); indx != top; indx++) { - ri = GET_RINTERNAL(dbp, pg, indx); - cp->recno += ri->nrecs; - } - return (__db_retcopy(dbenv, start, &cp->recno, - sizeof(cp->recno), &start->data, &start->ulen)); - - } - bi = GET_BINTERNAL(dbp, pg, NUM_ENT(pg) - 1); - if (B_TYPE(bi->type) == B_OVERFLOW) { - bo = (BOVERFLOW *)(bi->data); - return (__db_goff(dbp, start, - bo->tlen, bo->pgno, &start->data, &start->ulen)); - } - return (__db_retcopy(dbenv, - start, bi->data, bi->len, &start->data, &start->ulen)); -} - -/* - * bam_truncate_internal -- - * Find high numbered pages in the internal nodes of a tree and - * swap them. - */ -static int -__bam_truncate_internal(dbp, txn, c_data) - DB *dbp; - DB_TXN *txn; - DB_COMPACT *c_data; -{ - BTREE_CURSOR *cp; - DBC *dbc; - DBT start; - PAGE *pg; - db_pgno_t pgno; - u_int32_t sflag; - int level, local_txn, ret, t_ret; - - dbc = NULL; - memset(&start, 0, sizeof(start)); - - if (IS_DB_AUTO_COMMIT(dbp, txn)) { - local_txn = 1; - txn = NULL; - } else - local_txn = 0; - - level = LEAFLEVEL + 1; - sflag = CS_READ | CS_GETRECNO; - -new_txn: - if (local_txn && (ret = __txn_begin(dbp->dbenv, NULL, &txn, 0)) != 0) - goto err; - - if ((ret = __db_cursor(dbp, txn, &dbc, 0)) != 0) - goto err; - cp = (BTREE_CURSOR *)dbc->internal; - - pgno = PGNO_INVALID; - do { - if ((ret = __bam_csearch(dbc, &start, sflag, level)) != 0) { - /* No more at this level, go up one. */ - if (ret == DB_NOTFOUND) { - level++; - if (start.data != NULL) - __os_free(dbp->dbenv, start.data); - memset(&start, 0, sizeof(start)); - sflag = CS_READ | CS_GETRECNO; - continue; - } - goto err; - } - c_data->compact_pages_examine++; - - pg = cp->csp->page; - pgno = PGNO(pg); - - sflag = CS_NEXT | CS_GETRECNO; - /* Grab info about the page and drop the stack. */ - if (pgno != cp->root && (ret = __bam_savekey(dbc, - pgno <= c_data->compact_truncate, &start)) != 0) - goto err; - - if ((ret = __bam_stkrel(dbc, STK_NOLOCK)) != 0) - goto err; - if (pgno == cp->root) - break; - - if (pgno <= c_data->compact_truncate) - continue; - - /* Reget the page with a write lock, and its parent too. */ - if ((ret = __bam_csearch(dbc, - &start, CS_PARENT | CS_GETRECNO, level)) != 0) - goto err; - pg = cp->csp->page; - pgno = PGNO(pg); - - if (pgno > c_data->compact_truncate) { - if ((ret = __bam_truncate_page(dbc, &pg, 1)) != 0) - goto err; - } - if ((ret = __bam_stkrel(dbc, - pgno > c_data->compact_truncate ? 0 : STK_NOLOCK)) != 0) - goto err; - - /* We are locking subtrees, so drop the write locks asap. */ - if (local_txn && pgno > c_data->compact_truncate) - break; - } while (pgno != cp->root); - - if ((ret = __db_c_close(dbc)) != 0) - goto err; - dbc = NULL; - if (local_txn) { - if ((ret = __txn_commit(txn, DB_TXN_NOSYNC)) != 0) - goto err; - txn = NULL; - } - if (pgno != ((BTREE *)dbp->bt_internal)->bt_root) - goto new_txn; - -err: if (dbc != NULL && (t_ret = __bam_stkrel(dbc, 0)) != 0 && ret == 0) - ret = t_ret; - if (dbc != NULL && (t_ret = __db_c_close(dbc)) != 0 && ret == 0) - ret = t_ret; - if (local_txn && - txn != NULL && (t_ret = __txn_abort(txn)) != 0 && ret == 0) - ret = t_ret; - if (start.data != NULL) - __os_free(dbp->dbenv, start.data); - return (ret); -} - -static int -__bam_setup_freelist(dbp, list, nelems) - DB *dbp; - struct pglist *list; - u_int32_t nelems; -{ - DB_MPOOLFILE *mpf; - db_pgno_t *plist; - int ret; - - mpf = dbp->mpf; - - if ((ret = __memp_alloc_freelist(mpf, nelems, &plist)) != 0) - return (ret); - - while (nelems-- != 0) - *plist++ = list++->pgno; - - return (0); -} - -static int -__bam_free_freelist(dbp, txn) - DB *dbp; - DB_TXN *txn; -{ - DBC *dbc; - DB_LOCK lock; - int ret, t_ret; - - LOCK_INIT(lock); - ret = 0; - - /* - * If we are not in a transaction then we need to get - * a lock on the meta page, otherwise we should already - * have the lock. - */ - - dbc = NULL; - if (IS_DB_AUTO_COMMIT(dbp, txn)) { - /* Get a cursor so we can call __db_lget. */ - if ((ret = __db_cursor(dbp, NULL, &dbc, 0)) != 0) - return (ret); - - if ((ret = __db_lget(dbc, - 0, PGNO_BASE_MD, DB_LOCK_WRITE, 0, &lock)) != 0) - goto err; - } - - __memp_free_freelist(dbp->mpf); - -err: if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0) - ret = t_ret; - - if (dbc != NULL && (t_ret = __db_c_close(dbc)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} -#endif diff --git a/storage/bdb/btree/bt_compare.c b/storage/bdb/btree/bt_compare.c deleted file mode 100644 index 126788f3100..00000000000 --- a/storage/bdb/btree/bt_compare.c +++ /dev/null @@ -1,213 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994, 1995, 1996 - * Keith Bostic. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994, 1995 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Mike Olson. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: bt_compare.c,v 12.1 2005/06/16 20:20:13 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/btree.h" - -/* - * __bam_cmp -- - * Compare a key to a given record. - * - * PUBLIC: int __bam_cmp __P((DB *, const DBT *, PAGE *, - * PUBLIC: u_int32_t, int (*)(DB *, const DBT *, const DBT *), int *)); - */ -int -__bam_cmp(dbp, dbt, h, indx, func, cmpp) - DB *dbp; - const DBT *dbt; - PAGE *h; - u_int32_t indx; - int (*func)__P((DB *, const DBT *, const DBT *)); - int *cmpp; -{ - BINTERNAL *bi; - BKEYDATA *bk; - BOVERFLOW *bo; - DBT pg_dbt; - - /* - * Returns: - * < 0 if dbt is < page record - * = 0 if dbt is = page record - * > 0 if dbt is > page record - * - * !!! - * We do not clear the pg_dbt DBT even though it's likely to contain - * random bits. That should be okay, because the app's comparison - * routine had better not be looking at fields other than data/size. - * We don't clear it because we go through this path a lot and it's - * expensive. - */ - switch (TYPE(h)) { - case P_LBTREE: - case P_LDUP: - case P_LRECNO: - bk = GET_BKEYDATA(dbp, h, indx); - if (B_TYPE(bk->type) == B_OVERFLOW) - bo = (BOVERFLOW *)bk; - else { - pg_dbt.data = bk->data; - pg_dbt.size = bk->len; - *cmpp = func(dbp, dbt, &pg_dbt); - return (0); - } - break; - case P_IBTREE: - /* - * The following code guarantees that the left-most key on an - * internal page at any place in the tree sorts less than any - * user-specified key. The reason is that if we have reached - * this internal page, we know the user key must sort greater - * than the key we're storing for this page in any internal - * pages at levels above us in the tree. It then follows that - * any user-specified key cannot sort less than the first page - * which we reference, and so there's no reason to call the - * comparison routine. While this may save us a comparison - * routine call or two, the real reason for this is because - * we don't maintain a copy of the smallest key in the tree, - * so that we don't have to update all the levels of the tree - * should the application store a new smallest key. And, so, - * we may not have a key to compare, which makes doing the - * comparison difficult and error prone. - */ - if (indx == 0) { - *cmpp = 1; - return (0); - } - - bi = GET_BINTERNAL(dbp, h, indx); - if (B_TYPE(bi->type) == B_OVERFLOW) - bo = (BOVERFLOW *)(bi->data); - else { - pg_dbt.data = bi->data; - pg_dbt.size = bi->len; - *cmpp = func(dbp, dbt, &pg_dbt); - return (0); - } - break; - default: - return (__db_pgfmt(dbp->dbenv, PGNO(h))); - } - - /* - * Overflow. - */ - return (__db_moff(dbp, dbt, - bo->pgno, bo->tlen, func == __bam_defcmp ? NULL : func, cmpp)); -} - -/* - * __bam_defcmp -- - * Default comparison routine. - * - * PUBLIC: int __bam_defcmp __P((DB *, const DBT *, const DBT *)); - */ -int -__bam_defcmp(dbp, a, b) - DB *dbp; - const DBT *a, *b; -{ - size_t len; - u_int8_t *p1, *p2; - - COMPQUIET(dbp, NULL); - - /* - * Returns: - * < 0 if a is < b - * = 0 if a is = b - * > 0 if a is > b - * - * XXX - * If a size_t doesn't fit into a long, or if the difference between - * any two characters doesn't fit into an int, this routine can lose. - * What we need is a signed integral type that's guaranteed to be at - * least as large as a size_t, and there is no such thing. - */ - len = a->size > b->size ? b->size : a->size; - for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2) - if (*p1 != *p2) - return ((long)*p1 - (long)*p2); - return ((long)a->size - (long)b->size); -} - -/* - * __bam_defpfx -- - * Default prefix routine. - * - * PUBLIC: size_t __bam_defpfx __P((DB *, const DBT *, const DBT *)); - */ -size_t -__bam_defpfx(dbp, a, b) - DB *dbp; - const DBT *a, *b; -{ - size_t cnt, len; - u_int8_t *p1, *p2; - - COMPQUIET(dbp, NULL); - - cnt = 1; - len = a->size > b->size ? b->size : a->size; - for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2, ++cnt) - if (*p1 != *p2) - return (cnt); - - /* - * They match up to the smaller of the two sizes. - * Collate the longer after the shorter. - */ - if (a->size < b->size) - return (a->size + 1); - if (b->size < a->size) - return (b->size + 1); - return (b->size); -} diff --git a/storage/bdb/btree/bt_conv.c b/storage/bdb/btree/bt_conv.c deleted file mode 100644 index 74bf823088a..00000000000 --- a/storage/bdb/btree/bt_conv.c +++ /dev/null @@ -1,100 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: bt_conv.c,v 12.2 2005/06/16 20:20:13 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_swap.h" -#include "dbinc/btree.h" - -/* - * __bam_pgin -- - * Convert host-specific page layout from the host-independent format - * stored on disk. - * - * PUBLIC: int __bam_pgin __P((DB_ENV *, DB *, db_pgno_t, void *, DBT *)); - */ -int -__bam_pgin(dbenv, dummydbp, pg, pp, cookie) - DB_ENV *dbenv; - DB *dummydbp; - db_pgno_t pg; - void *pp; - DBT *cookie; -{ - DB_PGINFO *pginfo; - PAGE *h; - - pginfo = (DB_PGINFO *)cookie->data; - if (!F_ISSET(pginfo, DB_AM_SWAP)) - return (0); - - h = pp; - return (TYPE(h) == P_BTREEMETA ? __bam_mswap(pp) : - __db_byteswap(dbenv, dummydbp, pg, pp, pginfo->db_pagesize, 1)); -} - -/* - * __bam_pgout -- - * Convert host-specific page layout to the host-independent format - * stored on disk. - * - * PUBLIC: int __bam_pgout __P((DB_ENV *, DB *, db_pgno_t, void *, DBT *)); - */ -int -__bam_pgout(dbenv, dummydbp, pg, pp, cookie) - DB_ENV *dbenv; - DB *dummydbp; - db_pgno_t pg; - void *pp; - DBT *cookie; -{ - DB_PGINFO *pginfo; - PAGE *h; - - pginfo = (DB_PGINFO *)cookie->data; - if (!F_ISSET(pginfo, DB_AM_SWAP)) - return (0); - - h = pp; - return (TYPE(h) == P_BTREEMETA ? __bam_mswap(pp) : - __db_byteswap(dbenv, dummydbp, pg, pp, pginfo->db_pagesize, 0)); -} - -/* - * __bam_mswap -- - * Swap the bytes on the btree metadata page. - * - * PUBLIC: int __bam_mswap __P((PAGE *)); - */ -int -__bam_mswap(pg) - PAGE *pg; -{ - u_int8_t *p; - - __db_metaswap(pg); - - p = (u_int8_t *)pg + sizeof(DBMETA); - - p += sizeof(u_int32_t); /* unused */ - SWAP32(p); /* minkey */ - SWAP32(p); /* re_len */ - SWAP32(p); /* re_pad */ - SWAP32(p); /* root */ - p += 92 * sizeof(u_int32_t); /* unused */ - SWAP32(p); /* crypto_magic */ - - return (0); -} diff --git a/storage/bdb/btree/bt_curadj.c b/storage/bdb/btree/bt_curadj.c deleted file mode 100644 index e2128666cec..00000000000 --- a/storage/bdb/btree/bt_curadj.c +++ /dev/null @@ -1,590 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: bt_curadj.c,v 12.3 2005/07/20 16:50:45 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/btree.h" - -static int __bam_opd_cursor __P((DB *, DBC *, db_pgno_t, u_int32_t, u_int32_t)); - -/* - * Cursor adjustments are logged if they are for subtransactions. This is - * because it's possible for a subtransaction to adjust cursors which will - * still be active after the subtransaction aborts, and so which must be - * restored to their previous locations. Cursors that can be both affected - * by our cursor adjustments and active after our transaction aborts can - * only be found in our parent transaction -- cursors in other transactions, - * including other child transactions of our parent, must have conflicting - * locker IDs, and so cannot be affected by adjustments in this transaction. - */ - -/* - * __bam_ca_delete -- - * Update the cursors when items are deleted and when already deleted - * items are overwritten. Return the number of relevant cursors found. - * - * PUBLIC: int __bam_ca_delete __P((DB *, db_pgno_t, u_int32_t, int, int *)); - */ -int -__bam_ca_delete(dbp, pgno, indx, delete, countp) - DB *dbp; - db_pgno_t pgno; - u_int32_t indx; - int delete, *countp; -{ - BTREE_CURSOR *cp; - DB *ldbp; - DB_ENV *dbenv; - DBC *dbc; - int count; /* !!!: Has to contain max number of cursors. */ - - dbenv = dbp->dbenv; - - /* - * Adjust the cursors. We have the page write locked, so the - * only other cursors that can be pointing at a page are - * those in the same thread of control. Unfortunately, we don't - * know that they're using the same DB handle, so traverse - * all matching DB handles in the same DB_ENV, then all cursors - * on each matching DB handle. - * - * Each cursor is single-threaded, so we only need to lock the - * list of DBs and then the list of cursors in each DB. - */ - MUTEX_LOCK(dbenv, dbenv->mtx_dblist); - for (count = 0, ldbp = __dblist_get(dbenv, dbp->adj_fileid); - ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid; - ldbp = LIST_NEXT(ldbp, dblistlinks)) { - MUTEX_LOCK(dbenv, dbp->mutex); - for (dbc = TAILQ_FIRST(&ldbp->active_queue); - dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) { - cp = (BTREE_CURSOR *)dbc->internal; - if (cp->pgno == pgno && cp->indx == indx) { - /* - * [#8032] This assert is checking - * for possible race conditions where we - * hold a cursor position without a lock. - * Unfortunately, there are paths in the - * Btree code that do not satisfy these - * conditions. None of them are known to - * be a problem, but this assert should - * be re-activated when the Btree stack - * code is re-written. - DB_ASSERT(!STD_LOCKING(dbc) || - cp->lock_mode != DB_LOCK_NG); - */ - if (delete) - F_SET(cp, C_DELETED); - else - F_CLR(cp, C_DELETED); - ++count; - } - } - MUTEX_UNLOCK(dbenv, dbp->mutex); - } - MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist); - - if (countp != NULL) - *countp = count; - return (0); -} - -/* - * __ram_ca_delete -- - * Return if any relevant cursors found. - * - * PUBLIC: int __ram_ca_delete __P((DB *, db_pgno_t, int *)); - */ -int -__ram_ca_delete(dbp, root_pgno, foundp) - DB *dbp; - db_pgno_t root_pgno; - int *foundp; -{ - DB *ldbp; - DBC *dbc; - DB_ENV *dbenv; - int found; - - found = 0; - dbenv = dbp->dbenv; - - /* - * Review the cursors. See the comment in __bam_ca_delete(). - */ - MUTEX_LOCK(dbenv, dbenv->mtx_dblist); - for (ldbp = __dblist_get(dbenv, dbp->adj_fileid); - found == 0 && ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid; - ldbp = LIST_NEXT(ldbp, dblistlinks)) { - MUTEX_LOCK(dbenv, dbp->mutex); - for (dbc = TAILQ_FIRST(&ldbp->active_queue); - found == 0 && dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) - if (dbc->internal->root == root_pgno) - found = 1; - MUTEX_UNLOCK(dbenv, dbp->mutex); - } - MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist); - - *foundp = found; - return (0); -} - -/* - * __bam_ca_di -- - * Adjust the cursors during a delete or insert. - * - * PUBLIC: int __bam_ca_di __P((DBC *, db_pgno_t, u_int32_t, int)); - */ -int -__bam_ca_di(my_dbc, pgno, indx, adjust) - DBC *my_dbc; - db_pgno_t pgno; - u_int32_t indx; - int adjust; -{ - DB *dbp, *ldbp; - DB_ENV *dbenv; - DB_LSN lsn; - DB_TXN *my_txn; - DBC *dbc; - DBC_INTERNAL *cp; - int found, ret; - - dbp = my_dbc->dbp; - dbenv = dbp->dbenv; - - my_txn = IS_SUBTRANSACTION(my_dbc->txn) ? my_dbc->txn : NULL; - - /* - * Adjust the cursors. See the comment in __bam_ca_delete(). - */ - found = 0; - MUTEX_LOCK(dbenv, dbenv->mtx_dblist); - for (ldbp = __dblist_get(dbenv, dbp->adj_fileid); - ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid; - ldbp = LIST_NEXT(ldbp, dblistlinks)) { - MUTEX_LOCK(dbenv, dbp->mutex); - for (dbc = TAILQ_FIRST(&ldbp->active_queue); - dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) { - if (dbc->dbtype == DB_RECNO) - continue; - cp = dbc->internal; - if (cp->pgno == pgno && cp->indx >= indx) { - /* Cursor indices should never be negative. */ - DB_ASSERT(cp->indx != 0 || adjust > 0); - /* [#8032] - DB_ASSERT(!STD_LOCKING(dbc) || - cp->lock_mode != DB_LOCK_NG); - */ - cp->indx += adjust; - if (my_txn != NULL && dbc->txn != my_txn) - found = 1; - } - } - MUTEX_UNLOCK(dbenv, dbp->mutex); - } - MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist); - - if (found != 0 && DBC_LOGGING(my_dbc)) { - if ((ret = __bam_curadj_log(dbp, my_dbc->txn, &lsn, 0, - DB_CA_DI, pgno, 0, 0, (u_int32_t)adjust, indx, 0)) != 0) - return (ret); - } - - return (0); -} - -/* - * __bam_opd_cursor -- create a new opd cursor. - */ -static int -__bam_opd_cursor(dbp, dbc, first, tpgno, ti) - DB *dbp; - DBC *dbc; - db_pgno_t tpgno; - u_int32_t first, ti; -{ - BTREE_CURSOR *cp, *orig_cp; - DBC *dbc_nopd; - int ret; - - orig_cp = (BTREE_CURSOR *)dbc->internal; - dbc_nopd = NULL; - - /* - * Allocate a new cursor and create the stack. If duplicates - * are sorted, we've just created an off-page duplicate Btree. - * If duplicates aren't sorted, we've just created a Recno tree. - * - * Note that in order to get here at all, there shouldn't be - * an old off-page dup cursor--to augment the checking db_c_newopd - * will do, assert this. - */ - DB_ASSERT(orig_cp->opd == NULL); - if ((ret = __db_c_newopd(dbc, tpgno, orig_cp->opd, &dbc_nopd)) != 0) - return (ret); - - cp = (BTREE_CURSOR *)dbc_nopd->internal; - cp->pgno = tpgno; - cp->indx = ti; - - if (dbp->dup_compare == NULL) { - /* - * Converting to off-page Recno trees is tricky. The - * record number for the cursor is the index + 1 (to - * convert to 1-based record numbers). - */ - cp->recno = ti + 1; - } - - /* - * Transfer the deleted flag from the top-level cursor to the - * created one. - */ - if (F_ISSET(orig_cp, C_DELETED)) { - F_SET(cp, C_DELETED); - F_CLR(orig_cp, C_DELETED); - } - - /* Stack the cursors and reset the initial cursor's index. */ - orig_cp->opd = dbc_nopd; - orig_cp->indx = first; - return (0); -} - -/* - * __bam_ca_dup -- - * Adjust the cursors when moving items from a leaf page to a duplicates - * page. - * - * PUBLIC: int __bam_ca_dup __P((DBC *, - * PUBLIC: u_int32_t, db_pgno_t, u_int32_t, db_pgno_t, u_int32_t)); - */ -int -__bam_ca_dup(my_dbc, first, fpgno, fi, tpgno, ti) - DBC *my_dbc; - db_pgno_t fpgno, tpgno; - u_int32_t first, fi, ti; -{ - BTREE_CURSOR *orig_cp; - DB *dbp, *ldbp; - DBC *dbc; - DB_ENV *dbenv; - DB_LSN lsn; - DB_TXN *my_txn; - int found, ret; - - dbp = my_dbc->dbp; - dbenv = dbp->dbenv; - my_txn = IS_SUBTRANSACTION(my_dbc->txn) ? my_dbc->txn : NULL; - - /* - * Adjust the cursors. See the comment in __bam_ca_delete(). - */ - found = 0; - MUTEX_LOCK(dbenv, dbenv->mtx_dblist); - for (ldbp = __dblist_get(dbenv, dbp->adj_fileid); - ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid; - ldbp = LIST_NEXT(ldbp, dblistlinks)) { -loop: MUTEX_LOCK(dbenv, dbp->mutex); - for (dbc = TAILQ_FIRST(&ldbp->active_queue); - dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) { - /* Find cursors pointing to this record. */ - orig_cp = (BTREE_CURSOR *)dbc->internal; - if (orig_cp->pgno != fpgno || orig_cp->indx != fi) - continue; - - /* - * Since we rescan the list see if this is already - * converted. - */ - if (orig_cp->opd != NULL) - continue; - - MUTEX_UNLOCK(dbenv, dbp->mutex); - /* [#8032] - DB_ASSERT(!STD_LOCKING(dbc) || - orig_cp->lock_mode != DB_LOCK_NG); - */ - if ((ret = __bam_opd_cursor(dbp, - dbc, first, tpgno, ti)) !=0) - return (ret); - if (my_txn != NULL && dbc->txn != my_txn) - found = 1; - /* We released the mutex to get a cursor, start over. */ - goto loop; - } - MUTEX_UNLOCK(dbenv, dbp->mutex); - } - MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist); - - if (found != 0 && DBC_LOGGING(my_dbc)) { - if ((ret = __bam_curadj_log(dbp, my_dbc->txn, - &lsn, 0, DB_CA_DUP, fpgno, tpgno, 0, first, fi, ti)) != 0) - return (ret); - } - return (0); -} - -/* - * __bam_ca_undodup -- - * Adjust the cursors when returning items to a leaf page - * from a duplicate page. - * Called only during undo processing. - * - * PUBLIC: int __bam_ca_undodup __P((DB *, - * PUBLIC: u_int32_t, db_pgno_t, u_int32_t, u_int32_t)); - */ -int -__bam_ca_undodup(dbp, first, fpgno, fi, ti) - DB *dbp; - db_pgno_t fpgno; - u_int32_t first, fi, ti; -{ - BTREE_CURSOR *orig_cp; - DB *ldbp; - DBC *dbc; - DB_ENV *dbenv; - int ret; - - dbenv = dbp->dbenv; - - /* - * Adjust the cursors. See the comment in __bam_ca_delete(). - */ - MUTEX_LOCK(dbenv, dbenv->mtx_dblist); - for (ldbp = __dblist_get(dbenv, dbp->adj_fileid); - ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid; - ldbp = LIST_NEXT(ldbp, dblistlinks)) { -loop: MUTEX_LOCK(dbenv, dbp->mutex); - for (dbc = TAILQ_FIRST(&ldbp->active_queue); - dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) { - orig_cp = (BTREE_CURSOR *)dbc->internal; - - /* - * A note on the orig_cp->opd != NULL requirement here: - * it's possible that there's a cursor that refers to - * the same duplicate set, but which has no opd cursor, - * because it refers to a different item and we took - * care of it while processing a previous record. - */ - if (orig_cp->pgno != fpgno || - orig_cp->indx != first || - orig_cp->opd == NULL || ((BTREE_CURSOR *) - orig_cp->opd->internal)->indx != ti) - continue; - MUTEX_UNLOCK(dbenv, dbp->mutex); - if ((ret = __db_c_close(orig_cp->opd)) != 0) - return (ret); - orig_cp->opd = NULL; - orig_cp->indx = fi; - /* - * We released the mutex to free a cursor, - * start over. - */ - goto loop; - } - MUTEX_UNLOCK(dbenv, dbp->mutex); - } - MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist); - - return (0); -} - -/* - * __bam_ca_rsplit -- - * Adjust the cursors when doing reverse splits. - * - * PUBLIC: int __bam_ca_rsplit __P((DBC *, db_pgno_t, db_pgno_t)); - */ -int -__bam_ca_rsplit(my_dbc, fpgno, tpgno) - DBC* my_dbc; - db_pgno_t fpgno, tpgno; -{ - DB *dbp, *ldbp; - DBC *dbc; - DB_ENV *dbenv; - DB_LSN lsn; - DB_TXN *my_txn; - int found, ret; - - dbp = my_dbc->dbp; - dbenv = dbp->dbenv; - my_txn = IS_SUBTRANSACTION(my_dbc->txn) ? my_dbc->txn : NULL; - - /* - * Adjust the cursors. See the comment in __bam_ca_delete(). - */ - found = 0; - MUTEX_LOCK(dbenv, dbenv->mtx_dblist); - for (ldbp = __dblist_get(dbenv, dbp->adj_fileid); - ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid; - ldbp = LIST_NEXT(ldbp, dblistlinks)) { - MUTEX_LOCK(dbenv, dbp->mutex); - for (dbc = TAILQ_FIRST(&ldbp->active_queue); - dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) { - if (dbc->dbtype == DB_RECNO) - continue; - if (dbc->internal->pgno == fpgno) { - dbc->internal->pgno = tpgno; - /* [#8032] - DB_ASSERT(!STD_LOCKING(dbc) || - dbc->internal->lock_mode != DB_LOCK_NG); - */ - if (my_txn != NULL && dbc->txn != my_txn) - found = 1; - } - } - MUTEX_UNLOCK(dbenv, dbp->mutex); - } - MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist); - - if (found != 0 && DBC_LOGGING(my_dbc)) { - if ((ret = __bam_curadj_log(dbp, my_dbc->txn, - &lsn, 0, DB_CA_RSPLIT, fpgno, tpgno, 0, 0, 0, 0)) != 0) - return (ret); - } - return (0); -} - -/* - * __bam_ca_split -- - * Adjust the cursors when splitting a page. - * - * PUBLIC: int __bam_ca_split __P((DBC *, - * PUBLIC: db_pgno_t, db_pgno_t, db_pgno_t, u_int32_t, int)); - */ -int -__bam_ca_split(my_dbc, ppgno, lpgno, rpgno, split_indx, cleft) - DBC *my_dbc; - db_pgno_t ppgno, lpgno, rpgno; - u_int32_t split_indx; - int cleft; -{ - DB *dbp, *ldbp; - DBC *dbc; - DBC_INTERNAL *cp; - DB_ENV *dbenv; - DB_LSN lsn; - DB_TXN *my_txn; - int found, ret; - - dbp = my_dbc->dbp; - dbenv = dbp->dbenv; - my_txn = IS_SUBTRANSACTION(my_dbc->txn) ? my_dbc->txn : NULL; - - /* - * Adjust the cursors. See the comment in __bam_ca_delete(). - * - * If splitting the page that a cursor was on, the cursor has to be - * adjusted to point to the same record as before the split. Most - * of the time we don't adjust pointers to the left page, because - * we're going to copy its contents back over the original page. If - * the cursor is on the right page, it is decremented by the number of - * records split to the left page. - */ - found = 0; - MUTEX_LOCK(dbenv, dbenv->mtx_dblist); - for (ldbp = __dblist_get(dbenv, dbp->adj_fileid); - ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid; - ldbp = LIST_NEXT(ldbp, dblistlinks)) { - MUTEX_LOCK(dbenv, dbp->mutex); - for (dbc = TAILQ_FIRST(&ldbp->active_queue); - dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) { - if (dbc->dbtype == DB_RECNO) - continue; - cp = dbc->internal; - if (cp->pgno == ppgno) { - /* [#8032] - DB_ASSERT(!STD_LOCKING(dbc) || - cp->lock_mode != DB_LOCK_NG); - */ - if (my_txn != NULL && dbc->txn != my_txn) - found = 1; - if (cp->indx < split_indx) { - if (cleft) - cp->pgno = lpgno; - } else { - cp->pgno = rpgno; - cp->indx -= split_indx; - } - } - } - MUTEX_UNLOCK(dbenv, dbp->mutex); - } - MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist); - - if (found != 0 && DBC_LOGGING(my_dbc)) { - if ((ret = __bam_curadj_log(dbp, - my_dbc->txn, &lsn, 0, DB_CA_SPLIT, ppgno, rpgno, - cleft ? lpgno : PGNO_INVALID, 0, split_indx, 0)) != 0) - return (ret); - } - - return (0); -} - -/* - * __bam_ca_undosplit -- - * Adjust the cursors when undoing a split of a page. - * If we grew a level we will execute this for both the - * left and the right pages. - * Called only during undo processing. - * - * PUBLIC: int __bam_ca_undosplit __P((DB *, - * PUBLIC: db_pgno_t, db_pgno_t, db_pgno_t, u_int32_t)); - */ -int -__bam_ca_undosplit(dbp, frompgno, topgno, lpgno, split_indx) - DB *dbp; - db_pgno_t frompgno, topgno, lpgno; - u_int32_t split_indx; -{ - DB *ldbp; - DBC *dbc; - DB_ENV *dbenv; - DBC_INTERNAL *cp; - - dbenv = dbp->dbenv; - - /* - * Adjust the cursors. See the comment in __bam_ca_delete(). - * - * When backing out a split, we move the cursor back - * to the original offset and bump it by the split_indx. - */ - MUTEX_LOCK(dbenv, dbenv->mtx_dblist); - for (ldbp = __dblist_get(dbenv, dbp->adj_fileid); - ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid; - ldbp = LIST_NEXT(ldbp, dblistlinks)) { - MUTEX_LOCK(dbenv, dbp->mutex); - for (dbc = TAILQ_FIRST(&ldbp->active_queue); - dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) { - if (dbc->dbtype == DB_RECNO) - continue; - cp = dbc->internal; - if (cp->pgno == topgno) { - cp->pgno = frompgno; - cp->indx += split_indx; - } else if (cp->pgno == lpgno) - cp->pgno = frompgno; - } - MUTEX_UNLOCK(dbenv, dbp->mutex); - } - MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist); - - return (0); -} diff --git a/storage/bdb/btree/bt_cursor.c b/storage/bdb/btree/bt_cursor.c deleted file mode 100644 index 808dd7aa873..00000000000 --- a/storage/bdb/btree/bt_cursor.c +++ /dev/null @@ -1,2682 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: bt_cursor.c,v 12.7 2005/08/08 14:27:59 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/btree.h" -#include "dbinc/lock.h" -#include "dbinc/mp.h" - -static int __bam_bulk __P((DBC *, DBT *, u_int32_t)); -static int __bam_c_close __P((DBC *, db_pgno_t, int *)); -static int __bam_c_del __P((DBC *)); -static int __bam_c_destroy __P((DBC *)); -static int __bam_c_get __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *)); -static int __bam_c_getstack __P((DBC *)); -static int __bam_c_next __P((DBC *, int, int)); -static int __bam_c_physdel __P((DBC *)); -static int __bam_c_prev __P((DBC *)); -static int __bam_c_put __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *)); -static int __bam_c_search __P((DBC *, - db_pgno_t, const DBT *, u_int32_t, int *)); -static int __bam_c_writelock __P((DBC *)); -static int __bam_getboth_finddatum __P((DBC *, DBT *, u_int32_t)); -static int __bam_getbothc __P((DBC *, DBT *)); -static int __bam_get_prev __P((DBC *)); -static int __bam_isopd __P((DBC *, db_pgno_t *)); - -/* - * Acquire a new page/lock. If we hold a page/lock, discard the page, and - * lock-couple the lock. - * - * !!! - * We have to handle both where we have a lock to lock-couple and where we - * don't -- we don't duplicate locks when we duplicate cursors if we are - * running in a transaction environment as there's no point if locks are - * never discarded. This means that the cursor may or may not hold a lock. - * In the case where we are descending the tree we always want to unlock - * the held interior page so we use ACQUIRE_COUPLE. - */ -#undef ACQUIRE -#define ACQUIRE(dbc, mode, lpgno, lock, fpgno, pagep, ret) do { \ - DB_MPOOLFILE *__mpf = (dbc)->dbp->mpf; \ - if ((pagep) != NULL) { \ - ret = __memp_fput(__mpf, pagep, 0); \ - pagep = NULL; \ - } else \ - ret = 0; \ - if ((ret) == 0 && STD_LOCKING(dbc)) \ - ret = __db_lget(dbc, LCK_COUPLE, lpgno, mode, 0, &(lock));\ - if ((ret) == 0) \ - ret = __memp_fget(__mpf, &(fpgno), 0, &(pagep)); \ -} while (0) - -/* Acquire a new page/lock for a cursor. */ -#undef ACQUIRE_CUR -#define ACQUIRE_CUR(dbc, mode, p, ret) do { \ - BTREE_CURSOR *__cp = (BTREE_CURSOR *)(dbc)->internal; \ - if (p != __cp->pgno) \ - __cp->pgno = PGNO_INVALID; \ - ACQUIRE(dbc, mode, p, __cp->lock, p, __cp->page, ret); \ - if ((ret) == 0) { \ - __cp->pgno = p; \ - __cp->lock_mode = (mode); \ - } \ -} while (0) - -/* - * Acquire a write lock if we don't already have one. - * - * !!! - * See ACQUIRE macro on why we handle cursors that don't have locks. - */ -#undef ACQUIRE_WRITE_LOCK -#define ACQUIRE_WRITE_LOCK(dbc, ret) do { \ - BTREE_CURSOR *__cp = (BTREE_CURSOR *)(dbc)->internal; \ - ret = 0; \ - if (STD_LOCKING(dbc) && \ - __cp->lock_mode != DB_LOCK_WRITE && \ - ((ret) = __db_lget(dbc, \ - LOCK_ISSET(__cp->lock) ? LCK_COUPLE : 0, \ - __cp->pgno, DB_LOCK_WRITE, 0, &__cp->lock)) == 0) \ - __cp->lock_mode = DB_LOCK_WRITE; \ -} while (0) - -/* Discard the current page/lock for a cursor. */ -#undef DISCARD_CUR -#define DISCARD_CUR(dbc, ret) do { \ - BTREE_CURSOR *__cp = (BTREE_CURSOR *)(dbc)->internal; \ - DB_MPOOLFILE *__mpf = (dbc)->dbp->mpf; \ - int __t_ret; \ - if ((__cp->page) != NULL) { \ - __t_ret = __memp_fput(__mpf, __cp->page, 0); \ - __cp->page = NULL; \ - } else \ - __t_ret = 0; \ - if (__t_ret != 0 && (ret) == 0) \ - ret = __t_ret; \ - __t_ret = __TLPUT((dbc), __cp->lock); \ - if (__t_ret != 0 && (ret) == 0) \ - ret = __t_ret; \ - if ((ret) == 0 && !LOCK_ISSET(__cp->lock)) \ - __cp->lock_mode = DB_LOCK_NG; \ -} while (0) - -/* If on-page item is a deleted record. */ -#undef IS_DELETED -#define IS_DELETED(dbp, page, indx) \ - B_DISSET(GET_BKEYDATA(dbp, page, \ - (indx) + (TYPE(page) == P_LBTREE ? O_INDX : 0))->type) -#undef IS_CUR_DELETED -#define IS_CUR_DELETED(dbc) \ - IS_DELETED((dbc)->dbp, (dbc)->internal->page, (dbc)->internal->indx) - -/* - * Test to see if two cursors could point to duplicates of the same key. - * In the case of off-page duplicates they are they same, as the cursors - * will be in the same off-page duplicate tree. In the case of on-page - * duplicates, the key index offsets must be the same. For the last test, - * as the original cursor may not have a valid page pointer, we use the - * current cursor's. - */ -#undef IS_DUPLICATE -#define IS_DUPLICATE(dbc, i1, i2) \ - (P_INP((dbc)->dbp,((PAGE *)(dbc)->internal->page))[i1] == \ - P_INP((dbc)->dbp,((PAGE *)(dbc)->internal->page))[i2]) -#undef IS_CUR_DUPLICATE -#define IS_CUR_DUPLICATE(dbc, orig_pgno, orig_indx) \ - (F_ISSET(dbc, DBC_OPD) || \ - (orig_pgno == (dbc)->internal->pgno && \ - IS_DUPLICATE(dbc, (dbc)->internal->indx, orig_indx))) - -/* - * __bam_c_init -- - * Initialize the access private portion of a cursor - * - * PUBLIC: int __bam_c_init __P((DBC *, DBTYPE)); - */ -int -__bam_c_init(dbc, dbtype) - DBC *dbc; - DBTYPE dbtype; -{ - DB_ENV *dbenv; - int ret; - - dbenv = dbc->dbp->dbenv; - - /* Allocate/initialize the internal structure. */ - if (dbc->internal == NULL && (ret = - __os_calloc(dbenv, 1, sizeof(BTREE_CURSOR), &dbc->internal)) != 0) - return (ret); - - /* Initialize methods. */ - dbc->c_close = __db_c_close_pp; - dbc->c_count = __db_c_count_pp; - dbc->c_del = __db_c_del_pp; - dbc->c_dup = __db_c_dup_pp; - dbc->c_get = __db_c_get_pp; - dbc->c_pget = __db_c_pget_pp; - dbc->c_put = __db_c_put_pp; - if (dbtype == DB_BTREE) { - dbc->c_am_bulk = __bam_bulk; - dbc->c_am_close = __bam_c_close; - dbc->c_am_del = __bam_c_del; - dbc->c_am_destroy = __bam_c_destroy; - dbc->c_am_get = __bam_c_get; - dbc->c_am_put = __bam_c_put; - dbc->c_am_writelock = __bam_c_writelock; - } else { - dbc->c_am_bulk = __bam_bulk; - dbc->c_am_close = __bam_c_close; - dbc->c_am_del = __ram_c_del; - dbc->c_am_destroy = __bam_c_destroy; - dbc->c_am_get = __ram_c_get; - dbc->c_am_put = __ram_c_put; - dbc->c_am_writelock = __bam_c_writelock; - } - - return (0); -} - -/* - * __bam_c_refresh - * Set things up properly for cursor re-use. - * - * PUBLIC: int __bam_c_refresh __P((DBC *)); - */ -int -__bam_c_refresh(dbc) - DBC *dbc; -{ - BTREE *t; - BTREE_CURSOR *cp; - DB *dbp; - - dbp = dbc->dbp; - t = dbp->bt_internal; - cp = (BTREE_CURSOR *)dbc->internal; - - /* - * If our caller set the root page number, it's because the root was - * known. This is always the case for off page dup cursors. Else, - * pull it out of our internal information. - */ - if (cp->root == PGNO_INVALID) - cp->root = t->bt_root; - - LOCK_INIT(cp->lock); - cp->lock_mode = DB_LOCK_NG; - - if (cp->sp == NULL) { - cp->sp = cp->stack; - cp->esp = cp->stack + sizeof(cp->stack) / sizeof(cp->stack[0]); - } - BT_STK_CLR(cp); - - /* - * The btree leaf page data structures require that two key/data pairs - * (or four items) fit on a page, but other than that there's no fixed - * requirement. The btree off-page duplicates only require two items, - * to be exact, but requiring four for them as well seems reasonable. - * - * Recno uses the btree bt_ovflsize value -- it's close enough. - */ - cp->ovflsize = B_MINKEY_TO_OVFLSIZE( - dbp, F_ISSET(dbc, DBC_OPD) ? 2 : t->bt_minkey, dbp->pgsize); - - cp->recno = RECNO_OOB; - cp->order = INVALID_ORDER; - cp->flags = 0; - - /* Initialize for record numbers. */ - if (F_ISSET(dbc, DBC_OPD) || - dbc->dbtype == DB_RECNO || F_ISSET(dbp, DB_AM_RECNUM)) { - F_SET(cp, C_RECNUM); - - /* - * All btrees that support record numbers, optionally standard - * recno trees, and all off-page duplicate recno trees have - * mutable record numbers. - */ - if ((F_ISSET(dbc, DBC_OPD) && dbc->dbtype == DB_RECNO) || - F_ISSET(dbp, DB_AM_RECNUM | DB_AM_RENUMBER)) - F_SET(cp, C_RENUMBER); - } - - return (0); -} - -/* - * __bam_c_close -- - * Close down the cursor. - */ -static int -__bam_c_close(dbc, root_pgno, rmroot) - DBC *dbc; - db_pgno_t root_pgno; - int *rmroot; -{ - BTREE_CURSOR *cp, *cp_opd, *cp_c; - DB *dbp; - DBC *dbc_opd, *dbc_c; - DB_MPOOLFILE *mpf; - PAGE *h; - int cdb_lock, count, ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - cp = (BTREE_CURSOR *)dbc->internal; - cp_opd = (dbc_opd = cp->opd) == NULL ? - NULL : (BTREE_CURSOR *)dbc_opd->internal; - cdb_lock = ret = 0; - - /* - * There are 3 ways this function is called: - * - * 1. Closing a primary cursor: we get called with a pointer to a - * primary cursor that has a NULL opd field. This happens when - * closing a btree/recno database cursor without an associated - * off-page duplicate tree. - * - * 2. Closing a primary and an off-page duplicate cursor stack: we - * get called with a pointer to the primary cursor which has a - * non-NULL opd field. This happens when closing a btree cursor - * into database with an associated off-page btree/recno duplicate - * tree. (It can't be a primary recno database, recno databases - * don't support duplicates.) - * - * 3. Closing an off-page duplicate cursor stack: we get called with - * a pointer to the off-page duplicate cursor. This happens when - * closing a non-btree database that has an associated off-page - * btree/recno duplicate tree or for a btree database when the - * opd tree is not empty (root_pgno == PGNO_INVALID). - * - * If either the primary or off-page duplicate cursor deleted a btree - * key/data pair, check to see if the item is still referenced by a - * different cursor. If it is, confirm that cursor's delete flag is - * set and leave it to that cursor to do the delete. - * - * NB: The test for == 0 below is correct. Our caller already removed - * our cursor argument from the active queue, we won't find it when we - * search the queue in __bam_ca_delete(). - * NB: It can't be true that both the primary and off-page duplicate - * cursors have deleted a btree key/data pair. Either the primary - * cursor may have deleted an item and there's no off-page duplicate - * cursor, or there's an off-page duplicate cursor and it may have - * deleted an item. - * - * Primary recno databases aren't an issue here. Recno keys are either - * deleted immediately or never deleted, and do not have to be handled - * here. - * - * Off-page duplicate recno databases are an issue here, cases #2 and - * #3 above can both be off-page recno databases. The problem is the - * same as the final problem for off-page duplicate btree databases. - * If we no longer need the off-page duplicate tree, we want to remove - * it. For off-page duplicate btrees, we are done with the tree when - * we delete the last item it contains, i.e., there can be no further - * references to it when it's empty. For off-page duplicate recnos, - * we remove items from the tree as the application calls the remove - * function, so we are done with the tree when we close the last cursor - * that references it. - * - * We optionally take the root page number from our caller. If the - * primary database is a btree, we can get it ourselves because dbc - * is the primary cursor. If the primary database is not a btree, - * the problem is that we may be dealing with a stack of pages. The - * cursor we're using to do the delete points at the bottom of that - * stack and we need the top of the stack. - */ - if (F_ISSET(cp, C_DELETED)) { - dbc_c = dbc; - switch (dbc->dbtype) { - case DB_BTREE: /* Case #1, #3. */ - if ((ret = __bam_ca_delete( - dbp, cp->pgno, cp->indx, 1, &count)) != 0) - goto err; - if (count == 0) - goto lock; - goto done; - case DB_RECNO: - if (!F_ISSET(dbc, DBC_OPD)) /* Case #1. */ - goto done; - /* Case #3. */ - if ((ret = __ram_ca_delete(dbp, cp->root, &count)) != 0) - goto err; - if (count == 0) - goto lock; - goto done; - case DB_HASH: - case DB_QUEUE: - case DB_UNKNOWN: - default: - ret = __db_unknown_type(dbp->dbenv, - "__bam_c_close", dbc->dbtype); - goto err; - } - } - - if (dbc_opd == NULL) - goto done; - - if (F_ISSET(cp_opd, C_DELETED)) { /* Case #2. */ - /* - * We will not have been provided a root page number. Acquire - * one from the primary database. - */ - if ((ret = __memp_fget(mpf, &cp->pgno, 0, &h)) != 0) - goto err; - root_pgno = GET_BOVERFLOW(dbp, h, cp->indx + O_INDX)->pgno; - if ((ret = __memp_fput(mpf, h, 0)) != 0) - goto err; - - dbc_c = dbc_opd; - switch (dbc_opd->dbtype) { - case DB_BTREE: - if ((ret = __bam_ca_delete( - dbp, cp_opd->pgno, cp_opd->indx, 1, &count)) != 0) - goto err; - if (count == 0) - goto lock; - goto done; - case DB_RECNO: - if ((ret = - __ram_ca_delete(dbp, cp_opd->root, &count)) != 0) - goto err; - if (count == 0) - goto lock; - goto done; - case DB_HASH: - case DB_QUEUE: - case DB_UNKNOWN: - default: - ret = __db_unknown_type( - dbp->dbenv, "__bam_c_close", dbc->dbtype); - goto err; - } - } - goto done; - -lock: cp_c = (BTREE_CURSOR *)dbc_c->internal; - - /* - * If this is CDB, upgrade the lock if necessary. While we acquired - * the write lock to logically delete the record, we released it when - * we returned from that call, and so may not be holding a write lock - * at the moment. - */ - if (CDB_LOCKING(dbp->dbenv)) { - if (F_ISSET(dbc, DBC_WRITECURSOR)) { - if ((ret = __lock_get(dbp->dbenv, - dbc->locker, DB_LOCK_UPGRADE, &dbc->lock_dbt, - DB_LOCK_WRITE, &dbc->mylock)) != 0) - goto err; - cdb_lock = 1; - } - goto delete; - } - - /* - * The variable dbc_c has been initialized to reference the cursor in - * which we're going to do the delete. Initialize the cursor's lock - * structures as necessary. - * - * First, we may not need to acquire any locks. If we're in case #3, - * that is, the primary database isn't a btree database, our caller - * is responsible for acquiring any necessary locks before calling us. - */ - if (F_ISSET(dbc, DBC_OPD)) - goto delete; - - /* - * Otherwise, acquire a write lock on the primary database's page. - * - * Lock the primary database page, regardless of whether we're deleting - * an item on a primary database page or an off-page duplicates page. - * - * If the cursor that did the initial logical deletion (and had a write - * lock) is not the same cursor doing the physical deletion (which may - * have only ever had a read lock on the item), we need to upgrade to a - * write lock. The confusion comes as follows: - * - * C1 created, acquires item read lock - * C2 dup C1, create C2, also has item read lock. - * C1 acquire write lock, delete item - * C1 close - * C2 close, needs a write lock to physically delete item. - * - * If we're in a TXN, we know that C2 will be able to acquire the write - * lock, because no locker other than the one shared by C1 and C2 can - * acquire a write lock -- the original write lock C1 acquired was never - * discarded. - * - * If we're not in a TXN, it's nastier. Other cursors might acquire - * read locks on the item after C1 closed, discarding its write lock, - * and such locks would prevent C2 from acquiring a read lock. That's - * OK, though, we'll simply wait until we can acquire a write lock, or - * we'll deadlock. (Which better not happen, since we're not in a TXN.) - * - * There are similar scenarios with dirty reads, where the cursor may - * have downgraded its write lock to a was-write lock. - */ - if (STD_LOCKING(dbc)) - if ((ret = __db_lget(dbc, - LCK_COUPLE, cp->pgno, DB_LOCK_WRITE, 0, &cp->lock)) != 0) - goto err; - -delete: /* - * If the delete occurred in a Btree, we're going to look at the page - * to see if the item has to be physically deleted. Otherwise, we do - * not need the actual page (and it may not even exist, it might have - * been truncated from the file after an allocation aborted). - * - * Delete the on-page physical item referenced by the cursor. - */ - if (dbc_c->dbtype == DB_BTREE) { - if ((ret = __memp_fget(mpf, &cp_c->pgno, 0, &cp_c->page)) != 0) - goto err; - if ((ret = __bam_c_physdel(dbc_c)) != 0) - goto err; - } - - /* - * If we're not working in an off-page duplicate tree, then we're - * done. - */ - if (!F_ISSET(dbc_c, DBC_OPD) || root_pgno == PGNO_INVALID) - goto done; - - /* - * We may have just deleted the last element in the off-page duplicate - * tree, and closed the last cursor in the tree. For an off-page btree - * there are no other cursors in the tree by definition, if the tree is - * empty. For an off-page recno we know we have closed the last cursor - * in the tree because the __ram_ca_delete call above returned 0 only - * in that case. So, if the off-page duplicate tree is empty at this - * point, we want to remove it. - */ - if ((ret = __memp_fget(mpf, &root_pgno, 0, &h)) != 0) - goto err; - if (NUM_ENT(h) == 0) { - DISCARD_CUR(dbc_c, ret); - if (ret != 0) - goto err; - if ((ret = __db_free(dbc, h)) != 0) - goto err; - } else { - if ((ret = __memp_fput(mpf, h, 0)) != 0) - goto err; - goto done; - } - - /* - * When removing the tree, we have to do one of two things. If this is - * case #2, that is, the primary tree is a btree, delete the key that's - * associated with the tree from the btree leaf page. We know we are - * the only reference to it and we already have the correct lock. We - * detect this case because the cursor that was passed to us references - * an off-page duplicate cursor. - * - * If this is case #3, that is, the primary tree isn't a btree, pass - * the information back to our caller, it's their job to do cleanup on - * the primary page. - */ - if (dbc_opd != NULL) { - if ((ret = __memp_fget(mpf, &cp->pgno, 0, &cp->page)) != 0) - goto err; - if ((ret = __bam_c_physdel(dbc)) != 0) - goto err; - } else - *rmroot = 1; -err: -done: /* - * Discard the page references and locks, and confirm that the stack - * has been emptied. - */ - if (dbc_opd != NULL) - DISCARD_CUR(dbc_opd, ret); - DISCARD_CUR(dbc, ret); - - /* Downgrade any CDB lock we acquired. */ - if (cdb_lock) - (void)__lock_downgrade( - dbp->dbenv, &dbc->mylock, DB_LOCK_IWRITE, 0); - - return (ret); -} - -/* - * __bam_c_destroy -- - * Close a single cursor -- internal version. - */ -static int -__bam_c_destroy(dbc) - DBC *dbc; -{ - BTREE_CURSOR *cp; - - cp = (BTREE_CURSOR *)dbc->internal; - - /* Discard the structures. */ - if (cp->sp != cp->stack) - __os_free(dbc->dbp->dbenv, cp->sp); - __os_free(dbc->dbp->dbenv, cp); - - return (0); -} - -/* - * __bam_c_count -- - * Return a count of on and off-page duplicates. - * - * PUBLIC: int __bam_c_count __P((DBC *, db_recno_t *)); - */ -int -__bam_c_count(dbc, recnop) - DBC *dbc; - db_recno_t *recnop; -{ - BTREE_CURSOR *cp; - DB *dbp; - DB_MPOOLFILE *mpf; - db_indx_t indx, top; - db_recno_t recno; - int ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - cp = (BTREE_CURSOR *)dbc->internal; - - /* - * Called with the top-level cursor that may reference an off-page - * duplicates tree. We don't have to acquire any new locks, we have - * to have a read lock to even get here. - */ - if (cp->opd == NULL) { - /* - * On-page duplicates, get the page and count. - */ - if ((ret = __memp_fget(mpf, &cp->pgno, 0, &cp->page)) != 0) - return (ret); - - /* - * Move back to the beginning of the set of duplicates and - * then count forward. - */ - for (indx = cp->indx;; indx -= P_INDX) - if (indx == 0 || - !IS_DUPLICATE(dbc, indx, indx - P_INDX)) - break; - for (recno = 0, - top = NUM_ENT(cp->page) - P_INDX;; indx += P_INDX) { - if (!IS_DELETED(dbp, cp->page, indx)) - ++recno; - if (indx == top || - !IS_DUPLICATE(dbc, indx, indx + P_INDX)) - break; - } - } else { - /* - * Off-page duplicates tree, get the root page of the off-page - * duplicate tree. - */ - if ((ret = __memp_fget( - mpf, &cp->opd->internal->root, 0, &cp->page)) != 0) - return (ret); - - /* - * If the page is an internal page use the page's count as it's - * up-to-date and reflects the status of cursors in the tree. - * If the page is a leaf page for unsorted duplicates, use the - * page's count as cursors don't mark items deleted on the page - * and wait, cursor delete items immediately. - * If the page is a leaf page for sorted duplicates, there may - * be cursors on the page marking deleted items -- count. - */ - if (TYPE(cp->page) == P_LDUP) - for (recno = 0, indx = 0, - top = NUM_ENT(cp->page) - O_INDX;; indx += O_INDX) { - if (!IS_DELETED(dbp, cp->page, indx)) - ++recno; - if (indx == top) - break; - } - else - recno = RE_NREC(cp->page); - } - - *recnop = recno; - - ret = __memp_fput(mpf, cp->page, 0); - cp->page = NULL; - - return (ret); -} - -/* - * __bam_c_del -- - * Delete using a cursor. - */ -static int -__bam_c_del(dbc) - DBC *dbc; -{ - BTREE_CURSOR *cp; - DB *dbp; - DB_MPOOLFILE *mpf; - int count, ret, t_ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - cp = (BTREE_CURSOR *)dbc->internal; - ret = 0; - - /* If the item was already deleted, return failure. */ - if (F_ISSET(cp, C_DELETED)) - return (DB_KEYEMPTY); - - /* - * This code is always called with a page lock but no page. - */ - DB_ASSERT(cp->page == NULL); - - /* - * We don't physically delete the record until the cursor moves, so - * we have to have a long-lived write lock on the page instead of a - * a long-lived read lock. Note, we have to have a read lock to even - * get here. - * - * If we're maintaining record numbers, we lock the entire tree, else - * we lock the single page. - */ - if (F_ISSET(cp, C_RECNUM)) { - if ((ret = __bam_c_getstack(dbc)) != 0) - goto err; - cp->page = cp->csp->page; - } else { - ACQUIRE_CUR(dbc, DB_LOCK_WRITE, cp->pgno, ret); - if (ret != 0) - goto err; - } - - /* Log the change. */ - if (DBC_LOGGING(dbc)) { - if ((ret = __bam_cdel_log(dbp, dbc->txn, &LSN(cp->page), 0, - PGNO(cp->page), &LSN(cp->page), cp->indx)) != 0) - goto err; - } else - LSN_NOT_LOGGED(LSN(cp->page)); - - /* Set the intent-to-delete flag on the page. */ - if (TYPE(cp->page) == P_LBTREE) - B_DSET(GET_BKEYDATA(dbp, cp->page, cp->indx + O_INDX)->type); - else - B_DSET(GET_BKEYDATA(dbp, cp->page, cp->indx)->type); - - /* Mark the page dirty. */ - ret = __memp_fset(mpf, cp->page, DB_MPOOL_DIRTY); - -err: /* - * If we've been successful so far and the tree has record numbers, - * adjust the record counts. Either way, release acquired page(s). - */ - if (F_ISSET(cp, C_RECNUM)) { - if (ret == 0) - ret = __bam_adjust(dbc, -1); - (void)__bam_stkrel(dbc, 0); - } else - if (cp->page != NULL && - (t_ret = __memp_fput(mpf, cp->page, 0)) != 0 && ret == 0) - ret = t_ret; - - cp->page = NULL; - - /* - * Update the cursors last, after all chance of recoverable failure - * is past. - */ - if (ret == 0) - ret = __bam_ca_delete(dbp, cp->pgno, cp->indx, 1, &count); - - return (ret); -} - -/* - * __bam_c_dup -- - * Duplicate a btree cursor, such that the new one holds appropriate - * locks for the position of the original. - * - * PUBLIC: int __bam_c_dup __P((DBC *, DBC *)); - */ -int -__bam_c_dup(orig_dbc, new_dbc) - DBC *orig_dbc, *new_dbc; -{ - BTREE_CURSOR *orig, *new; - int ret; - - orig = (BTREE_CURSOR *)orig_dbc->internal; - new = (BTREE_CURSOR *)new_dbc->internal; - - /* - * If we're holding a lock we need to acquire a copy of it, unless - * we're in a transaction. We don't need to copy any lock we're - * holding inside a transaction because all the locks are retained - * until the transaction commits or aborts. - */ - if (orig_dbc->txn == NULL && LOCK_ISSET(orig->lock)) - if ((ret = __db_lget(new_dbc, - 0, new->pgno, new->lock_mode, 0, &new->lock)) != 0) - return (ret); - - new->ovflsize = orig->ovflsize; - new->recno = orig->recno; - new->flags = orig->flags; - - return (0); -} - -/* - * __bam_c_get -- - * Get using a cursor (btree). - */ -static int -__bam_c_get(dbc, key, data, flags, pgnop) - DBC *dbc; - DBT *key, *data; - u_int32_t flags; - db_pgno_t *pgnop; -{ - BTREE_CURSOR *cp; - DB *dbp; - DB_MPOOLFILE *mpf; - db_pgno_t orig_pgno; - db_indx_t orig_indx; - int exact, newopd, ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - cp = (BTREE_CURSOR *)dbc->internal; - orig_pgno = cp->pgno; - orig_indx = cp->indx; - - newopd = 0; - switch (flags) { - case DB_CURRENT: - /* It's not possible to return a deleted record. */ - if (F_ISSET(cp, C_DELETED)) { - ret = DB_KEYEMPTY; - goto err; - } - - /* - * Acquire the current page. We have at least a read-lock - * already. The caller may have set DB_RMW asking for a - * write lock, but upgrading to a write lock has no better - * chance of succeeding now instead of later, so don't try. - */ - if ((ret = __memp_fget(mpf, &cp->pgno, 0, &cp->page)) != 0) - goto err; - break; - case DB_FIRST: - newopd = 1; - if ((ret = __bam_c_search(dbc, - PGNO_INVALID, NULL, flags, &exact)) != 0) - goto err; - break; - case DB_GET_BOTH: - case DB_GET_BOTH_RANGE: - /* - * There are two ways to get here based on DBcursor->c_get - * with the DB_GET_BOTH/DB_GET_BOTH_RANGE flags set: - * - * 1. Searching a sorted off-page duplicate tree: do a tree - * search. - * - * 2. Searching btree: do a tree search. If it returns a - * reference to off-page duplicate tree, return immediately - * and let our caller deal with it. If the search doesn't - * return a reference to off-page duplicate tree, continue - * with an on-page search. - */ - if (F_ISSET(dbc, DBC_OPD)) { - if ((ret = __bam_c_search( - dbc, PGNO_INVALID, data, flags, &exact)) != 0) - goto err; - if (flags == DB_GET_BOTH) { - if (!exact) { - ret = DB_NOTFOUND; - goto err; - } - break; - } - - /* - * We didn't require an exact match, so the search may - * may have returned an entry past the end of the page, - * or we may be referencing a deleted record. If so, - * move to the next entry. - */ - if ((cp->indx == NUM_ENT(cp->page) || - IS_CUR_DELETED(dbc)) && - (ret = __bam_c_next(dbc, 1, 0)) != 0) - goto err; - } else { - if ((ret = __bam_c_search( - dbc, PGNO_INVALID, key, flags, &exact)) != 0) - return (ret); - if (!exact) { - ret = DB_NOTFOUND; - goto err; - } - - if (pgnop != NULL && __bam_isopd(dbc, pgnop)) { - newopd = 1; - break; - } - if ((ret = - __bam_getboth_finddatum(dbc, data, flags)) != 0) - goto err; - } - break; - case DB_GET_BOTHC: - if ((ret = __bam_getbothc(dbc, data)) != 0) - goto err; - break; - case DB_LAST: - newopd = 1; - if ((ret = __bam_c_search(dbc, - PGNO_INVALID, NULL, flags, &exact)) != 0) - goto err; - break; - case DB_NEXT: - newopd = 1; - if (cp->pgno == PGNO_INVALID) { - if ((ret = __bam_c_search(dbc, - PGNO_INVALID, NULL, DB_FIRST, &exact)) != 0) - goto err; - } else - if ((ret = __bam_c_next(dbc, 1, 0)) != 0) - goto err; - break; - case DB_NEXT_DUP: - if ((ret = __bam_c_next(dbc, 1, 0)) != 0) - goto err; - if (!IS_CUR_DUPLICATE(dbc, orig_pgno, orig_indx)) { - ret = DB_NOTFOUND; - goto err; - } - break; - case DB_NEXT_NODUP: - newopd = 1; - if (cp->pgno == PGNO_INVALID) { - if ((ret = __bam_c_search(dbc, - PGNO_INVALID, NULL, DB_FIRST, &exact)) != 0) - goto err; - } else - do { - if ((ret = __bam_c_next(dbc, 1, 0)) != 0) - goto err; - } while (IS_CUR_DUPLICATE(dbc, orig_pgno, orig_indx)); - break; - case DB_PREV: - newopd = 1; - if (cp->pgno == PGNO_INVALID) { - if ((ret = __bam_c_search(dbc, - PGNO_INVALID, NULL, DB_LAST, &exact)) != 0) - goto err; - } else - if ((ret = __bam_c_prev(dbc)) != 0) - goto err; - break; - case DB_PREV_NODUP: - newopd = 1; - if (cp->pgno == PGNO_INVALID) { - if ((ret = __bam_c_search(dbc, - PGNO_INVALID, NULL, DB_LAST, &exact)) != 0) - goto err; - } else - do { - if ((ret = __bam_c_prev(dbc)) != 0) - goto err; - } while (IS_CUR_DUPLICATE(dbc, orig_pgno, orig_indx)); - break; - case DB_SET: - case DB_SET_RECNO: - newopd = 1; - if ((ret = __bam_c_search(dbc, - PGNO_INVALID, key, flags, &exact)) != 0) - goto err; - break; - case DB_SET_RANGE: - newopd = 1; - if ((ret = __bam_c_search(dbc, - PGNO_INVALID, key, flags, &exact)) != 0) - goto err; - - /* - * As we didn't require an exact match, the search function - * may have returned an entry past the end of the page. Or, - * we may be referencing a deleted record. If so, move to - * the next entry. - */ - if (cp->indx == NUM_ENT(cp->page) || IS_CUR_DELETED(dbc)) - if ((ret = __bam_c_next(dbc, 0, 0)) != 0) - goto err; - break; - default: - ret = __db_unknown_flag(dbp->dbenv, "__bam_c_get", flags); - goto err; - } - - /* - * We may have moved to an off-page duplicate tree. Return that - * information to our caller. - */ - if (newopd && pgnop != NULL) - (void)__bam_isopd(dbc, pgnop); - - /* - * Don't return the key, it was passed to us (this is true even if the - * application defines a compare function returning equality for more - * than one key value, since in that case which actual value we store - * in the database is undefined -- and particularly true in the case of - * duplicates where we only store one key value). - */ - if (flags == DB_GET_BOTH || - flags == DB_GET_BOTH_RANGE || flags == DB_SET) - F_SET(key, DB_DBT_ISSET); - -err: /* - * Regardless of whether we were successful or not, if the cursor - * moved, clear the delete flag, DBcursor->c_get never references - * a deleted key, if it moved at all. - */ - if (F_ISSET(cp, C_DELETED) && - (cp->pgno != orig_pgno || cp->indx != orig_indx)) - F_CLR(cp, C_DELETED); - - return (ret); -} - -static int -__bam_get_prev(dbc) - DBC *dbc; -{ - BTREE_CURSOR *cp; - DBT key, data; - db_pgno_t pgno; - int ret; - - if ((ret = __bam_c_prev(dbc)) != 0) - return (ret); - - if (__bam_isopd(dbc, &pgno)) { - cp = (BTREE_CURSOR *)dbc->internal; - if ((ret = __db_c_newopd(dbc, pgno, cp->opd, &cp->opd)) != 0) - return (ret); - if ((ret = cp->opd->c_am_get(cp->opd, - &key, &data, DB_LAST, NULL)) != 0) - return (ret); - } - - return (0); -} - -/* - * __bam_bulk -- Return bulk data from a btree. - */ -static int -__bam_bulk(dbc, data, flags) - DBC *dbc; - DBT *data; - u_int32_t flags; -{ - BKEYDATA *bk; - BOVERFLOW *bo; - BTREE_CURSOR *cp; - PAGE *pg; - db_indx_t *inp, indx, pg_keyoff; - int32_t *endp, key_off, *offp, *saveoffp; - u_int8_t *dbuf, *dp, *np; - u_int32_t key_size, pagesize, size, space; - int adj, is_key, need_pg, next_key, no_dup, rec_key, ret; - - ret = 0; - key_off = 0; - size = 0; - pagesize = dbc->dbp->pgsize; - cp = (BTREE_CURSOR *)dbc->internal; - - /* - * dp tracks the beginning of the page in the buffer. - * np is the next place to copy things into the buffer. - * dbuf always stays at the beginning of the buffer. - */ - dbuf = data->data; - np = dp = dbuf; - - /* Keep track of space that is left. There is a termination entry */ - space = data->ulen; - space -= sizeof(*offp); - - /* Build the offset/size table from the end up. */ - endp = (int32_t *)((u_int8_t *)dbuf + data->ulen); - endp--; - offp = endp; - - key_size = 0; - - /* - * Distinguish between BTREE and RECNO. - * There are no keys in RECNO. If MULTIPLE_KEY is specified - * then we return the record numbers. - * is_key indicates that multiple btree keys are returned. - * rec_key is set if we are returning record numbers. - * next_key is set if we are going after the next key rather than dup. - */ - if (dbc->dbtype == DB_BTREE) { - is_key = LF_ISSET(DB_MULTIPLE_KEY) ? 1: 0; - rec_key = 0; - next_key = is_key && LF_ISSET(DB_OPFLAGS_MASK) != DB_NEXT_DUP; - adj = 2; - } else { - is_key = 0; - rec_key = LF_ISSET(DB_MULTIPLE_KEY) ? 1 : 0; - next_key = LF_ISSET(DB_OPFLAGS_MASK) != DB_NEXT_DUP; - adj = 1; - } - no_dup = LF_ISSET(DB_OPFLAGS_MASK) == DB_NEXT_NODUP; - -next_pg: - indx = cp->indx; - pg = cp->page; - - inp = P_INP(dbc->dbp, pg); - /* The current page is not yet in the buffer. */ - need_pg = 1; - - /* - * Keep track of the offset of the current key on the page. - * If we are returning keys, set it to 0 first so we force - * the copy of the key to the buffer. - */ - pg_keyoff = 0; - if (is_key == 0) - pg_keyoff = inp[indx]; - - do { - if (IS_DELETED(dbc->dbp, pg, indx)) { - if (dbc->dbtype != DB_RECNO) - continue; - - cp->recno++; - /* - * If we are not returning recnos then we - * need to fill in every slot so the user - * can calculate the record numbers. - */ - if (rec_key != 0) - continue; - - space -= 2 * sizeof(*offp); - /* Check if space as underflowed. */ - if (space > data->ulen) - goto back_up; - - /* Just mark the empty recno slots. */ - *offp-- = 0; - *offp-- = 0; - continue; - } - - /* - * Check to see if we have a new key. - * If so, then see if we need to put the - * key on the page. If its already there - * then we just point to it. - */ - if (is_key && pg_keyoff != inp[indx]) { - bk = GET_BKEYDATA(dbc->dbp, pg, indx); - if (B_TYPE(bk->type) == B_OVERFLOW) { - bo = (BOVERFLOW *)bk; - size = key_size = bo->tlen; - if (key_size > space) - goto get_key_space; - if ((ret = __bam_bulk_overflow(dbc, - bo->tlen, bo->pgno, np)) != 0) - return (ret); - space -= key_size; - key_off = (int32_t)(np - dbuf); - np += key_size; - } else { - if (need_pg) { - dp = np; - size = pagesize - HOFFSET(pg); - if (space < size) { -get_key_space: - /* Nothing added, then error. */ - if (offp == endp) { - data->size = (u_int32_t) - DB_ALIGN(size + - pagesize, 1024); - return - (DB_BUFFER_SMALL); - } - /* - * We need to back up to the - * last record put into the - * buffer so that it is - * CURRENT. - */ - if (indx != 0) - indx -= P_INDX; - else { - if ((ret = - __bam_get_prev( - dbc)) != 0) - return (ret); - indx = cp->indx; - pg = cp->page; - } - break; - } - /* - * Move the data part of the page - * to the buffer. - */ - memcpy(dp, - (u_int8_t *)pg + HOFFSET(pg), size); - need_pg = 0; - space -= size; - np += size; - } - key_size = bk->len; - key_off = (int32_t)((inp[indx] - HOFFSET(pg)) - + (dp - dbuf) + SSZA(BKEYDATA, data)); - pg_keyoff = inp[indx]; - } - } - - /* - * Reserve space for the pointers and sizes. - * Either key/data pair or just for a data item. - */ - space -= (is_key ? 4 : 2) * sizeof(*offp); - if (rec_key) - space -= sizeof(*offp); - - /* Check to see if space has underflowed. */ - if (space > data->ulen) - goto back_up; - - /* - * Determine if the next record is in the - * buffer already or if it needs to be copied in. - * If we have an off page dup, then copy as many - * as will fit into the buffer. - */ - bk = GET_BKEYDATA(dbc->dbp, pg, indx + adj - 1); - if (B_TYPE(bk->type) == B_DUPLICATE) { - bo = (BOVERFLOW *)bk; - if (is_key) { - *offp-- = (int32_t)key_off; - *offp-- = (int32_t)key_size; - } - /* - * We pass the offset of the current key. - * On return we check to see if offp has - * moved to see if any data fit. - */ - saveoffp = offp; - if ((ret = __bam_bulk_duplicates(dbc, bo->pgno, - dbuf, is_key ? offp + P_INDX : NULL, - &offp, &np, &space, no_dup)) != 0) { - if (ret == DB_BUFFER_SMALL) { - size = space; - space = 0; - /* If nothing was added, then error. */ - if (offp == saveoffp) { - offp += 2; - goto back_up; - } - goto get_space; - } - return (ret); - } - } else if (B_TYPE(bk->type) == B_OVERFLOW) { - bo = (BOVERFLOW *)bk; - size = bo->tlen; - if (size > space) - goto back_up; - if ((ret = - __bam_bulk_overflow(dbc, - bo->tlen, bo->pgno, np)) != 0) - return (ret); - space -= size; - if (is_key) { - *offp-- = (int32_t)key_off; - *offp-- = (int32_t)key_size; - } else if (rec_key) - *offp-- = (int32_t)cp->recno; - *offp-- = (int32_t)(np - dbuf); - np += size; - *offp-- = (int32_t)size; - } else { - if (need_pg) { - dp = np; - size = pagesize - HOFFSET(pg); - if (space < size) { -back_up: - /* - * Back up the index so that the - * last record in the buffer is CURRENT - */ - if (indx >= adj) - indx -= adj; - else { - if ((ret = - __bam_get_prev(dbc)) != 0 && - ret != DB_NOTFOUND) - return (ret); - indx = cp->indx; - pg = cp->page; - } - if (dbc->dbtype == DB_RECNO) - cp->recno--; -get_space: - /* - * See if we put anything in the - * buffer or if we are doing a DBP->get - * did we get all of the data. - */ - if (offp >= - (is_key ? &endp[-1] : endp) || - F_ISSET(dbc, DBC_TRANSIENT)) { - data->size = (u_int32_t) - DB_ALIGN(size + - data->ulen - space, 1024); - return (DB_BUFFER_SMALL); - } - break; - } - memcpy(dp, (u_int8_t *)pg + HOFFSET(pg), size); - need_pg = 0; - space -= size; - np += size; - } - /* - * Add the offsets and sizes to the end of the buffer. - * First add the key info then the data info. - */ - if (is_key) { - *offp-- = (int32_t)key_off; - *offp-- = (int32_t)key_size; - } else if (rec_key) - *offp-- = (int32_t)cp->recno; - *offp-- = (int32_t)((inp[indx + adj - 1] - HOFFSET(pg)) - + (dp - dbuf) + SSZA(BKEYDATA, data)); - *offp-- = bk->len; - } - if (dbc->dbtype == DB_RECNO) - cp->recno++; - else if (no_dup) { - while (indx + adj < NUM_ENT(pg) && - pg_keyoff == inp[indx + adj]) - indx += adj; - } - /* - * Stop when we either run off the page or we move to the next key and - * we are not returning multiple keys. - */ - } while ((indx += adj) < NUM_ENT(pg) && - (next_key || pg_keyoff == inp[indx])); - - /* If we are off the page then try to the next page. */ - if (ret == 0 && next_key && indx >= NUM_ENT(pg)) { - cp->indx = indx; - ret = __bam_c_next(dbc, 0, 1); - if (ret == 0) - goto next_pg; - if (ret != DB_NOTFOUND) - return (ret); - } - - /* - * If we did a DBP->get we must error if we did not return - * all the data for the current key because there is - * no way to know if we did not get it all, nor any - * interface to fetch the balance. - */ - - if (ret == 0 && indx < pg->entries && - F_ISSET(dbc, DBC_TRANSIENT) && pg_keyoff == inp[indx]) { - data->size = (data->ulen - space) + size; - return (DB_BUFFER_SMALL); - } - /* - * Must leave the index pointing at the last record fetched. - * If we are not fetching keys, we may have stepped to the - * next key. - */ - if (ret == DB_BUFFER_SMALL || next_key || pg_keyoff == inp[indx]) - cp->indx = indx; - else - cp->indx = indx - P_INDX; - - if (rec_key == 1) - *offp = RECNO_OOB; - else - *offp = -1; - return (0); -} - -/* - * __bam_bulk_overflow -- - * Dump overflow record into the buffer. - * The space requirements have already been checked. - * PUBLIC: int __bam_bulk_overflow - * PUBLIC: __P((DBC *, u_int32_t, db_pgno_t, u_int8_t *)); - */ -int -__bam_bulk_overflow(dbc, len, pgno, dp) - DBC *dbc; - u_int32_t len; - db_pgno_t pgno; - u_int8_t *dp; -{ - DBT dbt; - - memset(&dbt, 0, sizeof(dbt)); - F_SET(&dbt, DB_DBT_USERMEM); - dbt.ulen = len; - dbt.data = (void *)dp; - return (__db_goff(dbc->dbp, &dbt, len, pgno, NULL, NULL)); -} - -/* - * __bam_bulk_duplicates -- - * Put as many off page duplicates as will fit into the buffer. - * This routine will adjust the cursor to reflect the position in - * the overflow tree. - * PUBLIC: int __bam_bulk_duplicates __P((DBC *, - * PUBLIC: db_pgno_t, u_int8_t *, int32_t *, - * PUBLIC: int32_t **, u_int8_t **, u_int32_t *, int)); - */ -int -__bam_bulk_duplicates(dbc, pgno, dbuf, keyoff, offpp, dpp, spacep, no_dup) - DBC *dbc; - db_pgno_t pgno; - u_int8_t *dbuf; - int32_t *keyoff, **offpp; - u_int8_t **dpp; - u_int32_t *spacep; - int no_dup; -{ - DB *dbp; - BKEYDATA *bk; - BOVERFLOW *bo; - BTREE_CURSOR *cp; - DBC *opd; - DBT key, data; - PAGE *pg; - db_indx_t indx, *inp; - int32_t *offp; - u_int32_t pagesize, size, space; - u_int8_t *dp, *np; - int first, need_pg, ret, t_ret; - - ret = 0; - - dbp = dbc->dbp; - cp = (BTREE_CURSOR *)dbc->internal; - opd = cp->opd; - - if (opd == NULL) { - if ((ret = __db_c_newopd(dbc, pgno, NULL, &opd)) != 0) - return (ret); - cp->opd = opd; - if ((ret = opd->c_am_get(opd, - &key, &data, DB_FIRST, NULL)) != 0) - goto close_opd; - } - - pagesize = opd->dbp->pgsize; - cp = (BTREE_CURSOR *)opd->internal; - space = *spacep; - /* Get current offset slot. */ - offp = *offpp; - - /* - * np is the next place to put data. - * dp is the beginning of the current page in the buffer. - */ - np = dp = *dpp; - first = 1; - indx = cp->indx; - - do { - /* Fetch the current record. No initial move. */ - if ((ret = __bam_c_next(opd, 0, 0)) != 0) - break; - pg = cp->page; - indx = cp->indx; - inp = P_INP(dbp, pg); - /* We need to copy the page to the buffer. */ - need_pg = 1; - - do { - if (IS_DELETED(dbp, pg, indx)) - goto contin; - bk = GET_BKEYDATA(dbp, pg, indx); - space -= 2 * sizeof(*offp); - /* Allocate space for key if needed. */ - if (first == 0 && keyoff != NULL) - space -= 2 * sizeof(*offp); - - /* Did space underflow? */ - if (space > *spacep) { - ret = DB_BUFFER_SMALL; - if (first == 1) { - /* Get the absolute value. */ - space = -(int32_t)space; - space = *spacep + space; - if (need_pg) - space += pagesize - HOFFSET(pg); - } - break; - } - if (B_TYPE(bk->type) == B_OVERFLOW) { - bo = (BOVERFLOW *)bk; - size = bo->tlen; - if (size > space) { - ret = DB_BUFFER_SMALL; - space = *spacep + size; - break; - } - if (first == 0 && keyoff != NULL) { - *offp-- = keyoff[0]; - *offp-- = keyoff[-1]; - } - if ((ret = __bam_bulk_overflow(dbc, - bo->tlen, bo->pgno, np)) != 0) - return (ret); - space -= size; - *offp-- = (int32_t)(np - dbuf); - np += size; - } else { - if (need_pg) { - dp = np; - size = pagesize - HOFFSET(pg); - if (space < size) { - ret = DB_BUFFER_SMALL; - /* Return space required. */ - space = *spacep + size; - break; - } - memcpy(dp, - (u_int8_t *)pg + HOFFSET(pg), size); - need_pg = 0; - space -= size; - np += size; - } - if (first == 0 && keyoff != NULL) { - *offp-- = keyoff[0]; - *offp-- = keyoff[-1]; - } - size = bk->len; - *offp-- = (int32_t)((inp[indx] - HOFFSET(pg)) - + (dp - dbuf) + SSZA(BKEYDATA, data)); - } - *offp-- = (int32_t)size; - first = 0; - if (no_dup) - break; -contin: - indx++; - if (opd->dbtype == DB_RECNO) - cp->recno++; - } while (indx < NUM_ENT(pg)); - if (no_dup) - break; - cp->indx = indx; - - } while (ret == 0); - - /* Return the updated information. */ - *spacep = space; - *offpp = offp; - *dpp = np; - - /* - * If we ran out of space back up the pointer. - * If we did not return any dups or reached the end, close the opd. - */ - if (ret == DB_BUFFER_SMALL) { - if (opd->dbtype == DB_RECNO) { - if (--cp->recno == 0) - goto close_opd; - } else if (indx != 0) - cp->indx--; - else { - t_ret = __bam_c_prev(opd); - if (t_ret == DB_NOTFOUND) - goto close_opd; - if (t_ret != 0) - ret = t_ret; - } - } else if (keyoff == NULL && ret == DB_NOTFOUND) { - cp->indx--; - if (opd->dbtype == DB_RECNO) - --cp->recno; - } else if (indx == 0 || ret == DB_NOTFOUND) { -close_opd: - if (ret == DB_NOTFOUND) - ret = 0; - if ((t_ret = __db_c_close(opd)) != 0 && ret == 0) - ret = t_ret; - ((BTREE_CURSOR *)dbc->internal)->opd = NULL; - } - if (ret == DB_NOTFOUND) - ret = 0; - - return (ret); -} - -/* - * __bam_getbothc -- - * Search for a matching data item on a join. - */ -static int -__bam_getbothc(dbc, data) - DBC *dbc; - DBT *data; -{ - BTREE_CURSOR *cp; - DB *dbp; - DB_MPOOLFILE *mpf; - int cmp, exact, ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - cp = (BTREE_CURSOR *)dbc->internal; - - /* - * Acquire the current page. We have at least a read-lock - * already. The caller may have set DB_RMW asking for a - * write lock, but upgrading to a write lock has no better - * chance of succeeding now instead of later, so don't try. - */ - if ((ret = __memp_fget(mpf, &cp->pgno, 0, &cp->page)) != 0) - return (ret); - - /* - * An off-page duplicate cursor. Search the remaining duplicates - * for one which matches (do a normal btree search, then verify - * that the retrieved record is greater than the original one). - */ - if (F_ISSET(dbc, DBC_OPD)) { - /* - * Check to make sure the desired item comes strictly after - * the current position; if it doesn't, return DB_NOTFOUND. - */ - if ((ret = __bam_cmp(dbp, data, cp->page, cp->indx, - dbp->dup_compare == NULL ? __bam_defcmp : dbp->dup_compare, - &cmp)) != 0) - return (ret); - - if (cmp <= 0) - return (DB_NOTFOUND); - - /* Discard the current page, we're going to do a full search. */ - if ((ret = __memp_fput(mpf, cp->page, 0)) != 0) - return (ret); - cp->page = NULL; - - return (__bam_c_search(dbc, - PGNO_INVALID, data, DB_GET_BOTH, &exact)); - } - - /* - * We're doing a DBC->c_get(DB_GET_BOTHC) and we're already searching - * a set of on-page duplicates (either sorted or unsorted). Continue - * a linear search from after the current position. - * - * (Note that we could have just finished a "set" of one duplicate, - * i.e. not a duplicate at all, but the following check will always - * return DB_NOTFOUND in this case, which is the desired behavior.) - */ - if (cp->indx + P_INDX >= NUM_ENT(cp->page) || - !IS_DUPLICATE(dbc, cp->indx, cp->indx + P_INDX)) - return (DB_NOTFOUND); - cp->indx += P_INDX; - - return (__bam_getboth_finddatum(dbc, data, DB_GET_BOTH)); -} - -/* - * __bam_getboth_finddatum -- - * Find a matching on-page data item. - */ -static int -__bam_getboth_finddatum(dbc, data, flags) - DBC *dbc; - DBT *data; - u_int32_t flags; -{ - BTREE_CURSOR *cp; - DB *dbp; - db_indx_t base, lim, top; - int cmp, ret; - - COMPQUIET(cmp, 0); - - dbp = dbc->dbp; - cp = (BTREE_CURSOR *)dbc->internal; - - /* - * Called (sometimes indirectly) from DBC->get to search on-page data - * item(s) for a matching value. If the original flag was DB_GET_BOTH - * or DB_GET_BOTH_RANGE, the cursor is set to the first undeleted data - * item for the key. If the original flag was DB_GET_BOTHC, the cursor - * argument is set to the first data item we can potentially return. - * In both cases, there may or may not be additional duplicate data - * items to search. - * - * If the duplicates are not sorted, do a linear search. - */ - if (dbp->dup_compare == NULL) { - for (;; cp->indx += P_INDX) { - if (!IS_CUR_DELETED(dbc) && - (ret = __bam_cmp(dbp, data, cp->page, - cp->indx + O_INDX, __bam_defcmp, &cmp)) != 0) - return (ret); - if (cmp == 0) - return (0); - - if (cp->indx + P_INDX >= NUM_ENT(cp->page) || - !IS_DUPLICATE(dbc, cp->indx, cp->indx + P_INDX)) - break; - } - return (DB_NOTFOUND); - } - - /* - * If the duplicates are sorted, do a binary search. The reason for - * this is that large pages and small key/data pairs result in large - * numbers of on-page duplicates before they get pushed off-page. - * - * Find the top and bottom of the duplicate set. Binary search - * requires at least two items, don't loop if there's only one. - */ - for (base = top = cp->indx; top < NUM_ENT(cp->page); top += P_INDX) - if (!IS_DUPLICATE(dbc, cp->indx, top)) - break; - if (base == (top - P_INDX)) { - if ((ret = __bam_cmp(dbp, data, - cp->page, cp->indx + O_INDX, dbp->dup_compare, &cmp)) != 0) - return (ret); - return (cmp == 0 || - (cmp < 0 && flags == DB_GET_BOTH_RANGE) ? 0 : DB_NOTFOUND); - } - - for (lim = (top - base) / (db_indx_t)P_INDX; lim != 0; lim >>= 1) { - cp->indx = base + ((lim >> 1) * P_INDX); - if ((ret = __bam_cmp(dbp, data, cp->page, - cp->indx + O_INDX, dbp->dup_compare, &cmp)) != 0) - return (ret); - if (cmp == 0) { - /* - * XXX - * No duplicate duplicates in sorted duplicate sets, - * so there can be only one. - */ - if (!IS_CUR_DELETED(dbc)) - return (0); - break; - } - if (cmp > 0) { - base = cp->indx + P_INDX; - --lim; - } - } - - /* No match found; if we're looking for an exact match, we're done. */ - if (flags == DB_GET_BOTH) - return (DB_NOTFOUND); - - /* - * Base is the smallest index greater than the data item, may be zero - * or a last + O_INDX index, and may be deleted. Find an undeleted - * item. - */ - cp->indx = base; - while (cp->indx < top && IS_CUR_DELETED(dbc)) - cp->indx += P_INDX; - return (cp->indx < top ? 0 : DB_NOTFOUND); -} - -/* - * __bam_c_put -- - * Put using a cursor. - */ -static int -__bam_c_put(dbc, key, data, flags, pgnop) - DBC *dbc; - DBT *key, *data; - u_int32_t flags; - db_pgno_t *pgnop; -{ - BTREE *t; - BTREE_CURSOR *cp; - DB *dbp; - DBT dbt; - DB_MPOOLFILE *mpf; - db_pgno_t root_pgno; - u_int32_t iiop; - int cmp, exact, own, ret, stack; - void *arg; - - dbp = dbc->dbp; - mpf = dbp->mpf; - cp = (BTREE_CURSOR *)dbc->internal; - root_pgno = cp->root; - -split: ret = stack = 0; - switch (flags) { - case DB_CURRENT: - if (F_ISSET(cp, C_DELETED)) - return (DB_NOTFOUND); - /* FALLTHROUGH */ - - case DB_AFTER: - case DB_BEFORE: - iiop = flags; - own = 1; - - /* Acquire the current page with a write lock. */ - ACQUIRE_WRITE_LOCK(dbc, ret); - if (ret != 0) - goto err; - if ((ret = __memp_fget(mpf, &cp->pgno, 0, &cp->page)) != 0) - goto err; - break; - case DB_KEYFIRST: - case DB_KEYLAST: - case DB_NODUPDATA: - own = 0; - /* - * Searching off-page, sorted duplicate tree: do a tree search - * for the correct item; __bam_c_search returns the smallest - * slot greater than the key, use it. - * - * See comment below regarding where we can start the search. - */ - if (F_ISSET(dbc, DBC_OPD)) { - if ((ret = __bam_c_search(dbc, - F_ISSET(cp, C_RECNUM) ? cp->root : root_pgno, - data, flags, &exact)) != 0) - goto err; - stack = 1; - - /* Disallow "sorted" duplicate duplicates. */ - if (exact) { - if (IS_DELETED(dbp, cp->page, cp->indx)) { - iiop = DB_CURRENT; - break; - } - ret = __db_duperr(dbp, flags); - goto err; - } - iiop = DB_BEFORE; - break; - } - - /* - * Searching a btree. - * - * If we've done a split, we can start the search from the - * parent of the split page, which __bam_split returned - * for us in root_pgno, unless we're in a Btree with record - * numbering. In that case, we'll need the true root page - * in order to adjust the record count. - */ - if ((ret = __bam_c_search(dbc, - F_ISSET(cp, C_RECNUM) ? cp->root : root_pgno, key, - flags == DB_KEYFIRST || dbp->dup_compare != NULL ? - DB_KEYFIRST : DB_KEYLAST, &exact)) != 0) - goto err; - stack = 1; - - /* - * If we don't have an exact match, __bam_c_search returned - * the smallest slot greater than the key, use it. - */ - if (!exact) { - iiop = DB_KEYFIRST; - break; - } - - /* - * If duplicates aren't supported, replace the current item. - * (If implementing the DB->put function, our caller already - * checked the DB_NOOVERWRITE flag.) - */ - if (!F_ISSET(dbp, DB_AM_DUP)) { - iiop = DB_CURRENT; - break; - } - - /* - * If we find a matching entry, it may be an off-page duplicate - * tree. Return the page number to our caller, we need a new - * cursor. - */ - if (pgnop != NULL && __bam_isopd(dbc, pgnop)) - goto done; - - /* If the duplicates aren't sorted, move to the right slot. */ - if (dbp->dup_compare == NULL) { - if (flags == DB_KEYFIRST) - iiop = DB_BEFORE; - else - for (;; cp->indx += P_INDX) - if (cp->indx + P_INDX >= - NUM_ENT(cp->page) || - !IS_DUPLICATE(dbc, cp->indx, - cp->indx + P_INDX)) { - iiop = DB_AFTER; - break; - } - break; - } - - /* - * We know that we're looking at the first of a set of sorted - * on-page duplicates. Walk the list to find the right slot. - */ - for (;; cp->indx += P_INDX) { - if ((ret = __bam_cmp(dbp, data, cp->page, - cp->indx + O_INDX, dbp->dup_compare, &cmp)) != 0) - goto err; - if (cmp < 0) { - iiop = DB_BEFORE; - break; - } - - /* Disallow "sorted" duplicate duplicates. */ - if (cmp == 0) { - if (IS_DELETED(dbp, cp->page, cp->indx)) { - iiop = DB_CURRENT; - break; - } - ret = __db_duperr(dbp, flags); - goto err; - } - - if (cp->indx + P_INDX >= NUM_ENT(cp->page) || - P_INP(dbp, ((PAGE *)cp->page))[cp->indx] != - P_INP(dbp, ((PAGE *)cp->page))[cp->indx + P_INDX]) { - iiop = DB_AFTER; - break; - } - } - break; - default: - ret = __db_unknown_flag(dbp->dbenv, "__bam_c_put", flags); - goto err; - } - - switch (ret = __bam_iitem(dbc, key, data, iiop, 0)) { - case 0: - break; - case DB_NEEDSPLIT: - /* - * To split, we need a key for the page. Either use the key - * argument or get a copy of the key from the page. - */ - if (flags == DB_AFTER || - flags == DB_BEFORE || flags == DB_CURRENT) { - memset(&dbt, 0, sizeof(DBT)); - if ((ret = __db_ret(dbp, cp->page, 0, &dbt, - &dbc->my_rkey.data, &dbc->my_rkey.ulen)) != 0) - goto err; - arg = &dbt; - } else - arg = F_ISSET(dbc, DBC_OPD) ? data : key; - - /* - * Discard any locks and pinned pages (the locks are discarded - * even if we're running with transactions, as they lock pages - * that we're sorry we ever acquired). If stack is set and the - * cursor entries are valid, they point to the same entries as - * the stack, don't free them twice. - */ - if (stack) - ret = __bam_stkrel(dbc, STK_CLRDBC | STK_NOLOCK); - else - DISCARD_CUR(dbc, ret); - if (ret != 0) - goto err; - - /* - * SR [#6059] - * If we do not own a lock on the page any more, then clear the - * cursor so we don't point at it. Even if we call __bam_stkrel - * above we still may have entered the routine with the cursor - * positioned to a particular record. This is in the case - * where C_RECNUM is set. - */ - if (own == 0) { - cp->pgno = PGNO_INVALID; - cp->indx = 0; - } - - /* Split the tree. */ - if ((ret = __bam_split(dbc, arg, &root_pgno)) != 0) - return (ret); - - goto split; - default: - goto err; - } - -err: -done: /* - * If we inserted a key into the first or last slot of the tree, - * remember where it was so we can do it more quickly next time. - * If the tree has record numbers, we need a complete stack so - * that we can adjust the record counts, so skipping the tree search - * isn't possible. For subdatabases we need to be careful that the - * page does not move from one db to another, so we track its LSN. - * - * If there are duplicates and we are inserting into the last slot, - * the cursor will point _to_ the last item, not after it, which - * is why we subtract P_INDX below. - */ - - t = dbp->bt_internal; - if (ret == 0 && TYPE(cp->page) == P_LBTREE && - (flags == DB_KEYFIRST || flags == DB_KEYLAST) && - !F_ISSET(cp, C_RECNUM) && - (!F_ISSET(dbp, DB_AM_SUBDB) || - (LOGGING_ON(dbp->dbenv) && !F_ISSET(dbp, DB_AM_NOT_DURABLE))) && - ((NEXT_PGNO(cp->page) == PGNO_INVALID && - cp->indx >= NUM_ENT(cp->page) - P_INDX) || - (PREV_PGNO(cp->page) == PGNO_INVALID && cp->indx == 0))) { - t->bt_lpgno = cp->pgno; - if (F_ISSET(dbp, DB_AM_SUBDB)) - t->bt_llsn = LSN(cp->page); - } else - t->bt_lpgno = PGNO_INVALID; - /* - * Discard any pages pinned in the tree and their locks, except for - * the leaf page. Note, the leaf page participated in any stack we - * acquired, and so we have to adjust the stack as necessary. If - * there was only a single page on the stack, we don't have to free - * further stack pages. - */ - if (stack && BT_STK_POP(cp) != NULL) - (void)__bam_stkrel(dbc, 0); - - /* - * Regardless of whether we were successful or not, clear the delete - * flag. If we're successful, we either moved the cursor or the item - * is no longer deleted. If we're not successful, then we're just a - * copy, no need to have the flag set. - * - * We may have instantiated off-page duplicate cursors during the put, - * so clear the deleted bit from the off-page duplicate cursor as well. - */ - F_CLR(cp, C_DELETED); - if (cp->opd != NULL) { - cp = (BTREE_CURSOR *)cp->opd->internal; - F_CLR(cp, C_DELETED); - } - - return (ret); -} - -/* - * __bam_c_rget -- - * Return the record number for a cursor. - * - * PUBLIC: int __bam_c_rget __P((DBC *, DBT *)); - */ -int -__bam_c_rget(dbc, data) - DBC *dbc; - DBT *data; -{ - BTREE_CURSOR *cp; - DB *dbp; - DBT dbt; - DB_MPOOLFILE *mpf; - db_recno_t recno; - int exact, ret, t_ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - cp = (BTREE_CURSOR *)dbc->internal; - - /* - * Get the page with the current item on it. - * Get a copy of the key. - * Release the page, making sure we don't release it twice. - */ - if ((ret = __memp_fget(mpf, &cp->pgno, 0, &cp->page)) != 0) - return (ret); - memset(&dbt, 0, sizeof(DBT)); - if ((ret = __db_ret(dbp, cp->page, - cp->indx, &dbt, &dbc->my_rkey.data, &dbc->my_rkey.ulen)) != 0) - goto err; - ret = __memp_fput(mpf, cp->page, 0); - cp->page = NULL; - if (ret != 0) - return (ret); - - if ((ret = __bam_search(dbc, PGNO_INVALID, &dbt, - F_ISSET(dbc, DBC_RMW) ? S_FIND_WR : S_FIND, - 1, &recno, &exact)) != 0) - goto err; - - ret = __db_retcopy(dbp->dbenv, data, - &recno, sizeof(recno), &dbc->rdata->data, &dbc->rdata->ulen); - - /* Release the stack. */ -err: if ((t_ret = __bam_stkrel(dbc, 0)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __bam_c_writelock -- - * Upgrade the cursor to a write lock. - */ -static int -__bam_c_writelock(dbc) - DBC *dbc; -{ - BTREE_CURSOR *cp; - int ret; - - cp = (BTREE_CURSOR *)dbc->internal; - - if (cp->lock_mode == DB_LOCK_WRITE) - return (0); - - /* - * When writing to an off-page duplicate tree, we need to have the - * appropriate page in the primary tree locked. The general DBC - * code calls us first with the primary cursor so we can acquire the - * appropriate lock. - */ - ACQUIRE_WRITE_LOCK(dbc, ret); - return (ret); -} - -/* - * __bam_c_next -- - * Move to the next record. - */ -static int -__bam_c_next(dbc, initial_move, deleted_okay) - DBC *dbc; - int initial_move, deleted_okay; -{ - BTREE_CURSOR *cp; - db_indx_t adjust; - db_lockmode_t lock_mode; - db_pgno_t pgno; - int ret; - - cp = (BTREE_CURSOR *)dbc->internal; - ret = 0; - - /* - * We're either moving through a page of duplicates or a btree leaf - * page. - * - * !!! - * This code handles empty pages and pages with only deleted entries. - */ - if (F_ISSET(dbc, DBC_OPD)) { - adjust = O_INDX; - lock_mode = DB_LOCK_NG; - } else { - adjust = dbc->dbtype == DB_BTREE ? P_INDX : O_INDX; - lock_mode = - F_ISSET(dbc, DBC_RMW) ? DB_LOCK_WRITE : DB_LOCK_READ; - } - if (cp->page == NULL) { - ACQUIRE_CUR(dbc, lock_mode, cp->pgno, ret); - if (ret != 0) - return (ret); - } - - if (initial_move) - cp->indx += adjust; - - for (;;) { - /* - * If at the end of the page, move to a subsequent page. - * - * !!! - * Check for >= NUM_ENT. If the original search landed us on - * NUM_ENT, we may have incremented indx before the test. - */ - if (cp->indx >= NUM_ENT(cp->page)) { - if ((pgno - = NEXT_PGNO(cp->page)) == PGNO_INVALID) - return (DB_NOTFOUND); - - ACQUIRE_CUR(dbc, lock_mode, pgno, ret); - if (ret != 0) - return (ret); - cp->indx = 0; - continue; - } - if (!deleted_okay && IS_CUR_DELETED(dbc)) { - cp->indx += adjust; - continue; - } - break; - } - return (0); -} - -/* - * __bam_c_prev -- - * Move to the previous record. - */ -static int -__bam_c_prev(dbc) - DBC *dbc; -{ - BTREE_CURSOR *cp; - db_indx_t adjust; - db_lockmode_t lock_mode; - db_pgno_t pgno; - int ret; - - cp = (BTREE_CURSOR *)dbc->internal; - ret = 0; - - /* - * We're either moving through a page of duplicates or a btree leaf - * page. - * - * !!! - * This code handles empty pages and pages with only deleted entries. - */ - if (F_ISSET(dbc, DBC_OPD)) { - adjust = O_INDX; - lock_mode = DB_LOCK_NG; - } else { - adjust = dbc->dbtype == DB_BTREE ? P_INDX : O_INDX; - lock_mode = - F_ISSET(dbc, DBC_RMW) ? DB_LOCK_WRITE : DB_LOCK_READ; - } - if (cp->page == NULL) { - ACQUIRE_CUR(dbc, lock_mode, cp->pgno, ret); - if (ret != 0) - return (ret); - } - - for (;;) { - /* If at the beginning of the page, move to a previous one. */ - if (cp->indx == 0) { - if ((pgno = - PREV_PGNO(cp->page)) == PGNO_INVALID) - return (DB_NOTFOUND); - - ACQUIRE_CUR(dbc, lock_mode, pgno, ret); - if (ret != 0) - return (ret); - - if ((cp->indx = NUM_ENT(cp->page)) == 0) - continue; - } - - /* Ignore deleted records. */ - cp->indx -= adjust; - if (IS_CUR_DELETED(dbc)) - continue; - - break; - } - return (0); -} - -/* - * __bam_c_search -- - * Move to a specified record. - */ -static int -__bam_c_search(dbc, root_pgno, key, flags, exactp) - DBC *dbc; - db_pgno_t root_pgno; - const DBT *key; - u_int32_t flags; - int *exactp; -{ - BTREE *t; - BTREE_CURSOR *cp; - DB *dbp; - PAGE *h; - db_indx_t indx, *inp; - db_pgno_t bt_lpgno; - db_recno_t recno; - u_int32_t sflags; - int cmp, ret, t_ret; - - dbp = dbc->dbp; - cp = (BTREE_CURSOR *)dbc->internal; - t = dbp->bt_internal; - ret = 0; - - /* - * Find an entry in the database. Discard any lock we currently hold, - * we're going to search the tree. - */ - DISCARD_CUR(dbc, ret); - if (ret != 0) - return (ret); - - switch (flags) { - case DB_FIRST: - sflags = (F_ISSET(dbc, DBC_RMW) ? S_WRITE : S_READ) | S_MIN; - goto search; - case DB_LAST: - sflags = (F_ISSET(dbc, DBC_RMW) ? S_WRITE : S_READ) | S_MAX; - goto search; - case DB_SET_RECNO: - if ((ret = __ram_getno(dbc, key, &recno, 0)) != 0) - return (ret); - sflags = (F_ISSET(dbc, DBC_RMW) ? S_FIND_WR : S_FIND) | S_EXACT; - if ((ret = __bam_rsearch(dbc, &recno, sflags, 1, exactp)) != 0) - return (ret); - break; - case DB_SET: - case DB_GET_BOTH: - sflags = (F_ISSET(dbc, DBC_RMW) ? S_FIND_WR : S_FIND) | S_EXACT; - goto search; - case DB_GET_BOTH_RANGE: - sflags = (F_ISSET(dbc, DBC_RMW) ? S_FIND_WR : S_FIND); - goto search; - case DB_SET_RANGE: - sflags = - (F_ISSET(dbc, DBC_RMW) ? S_WRITE : S_READ) | S_DUPFIRST; - goto search; - case DB_KEYFIRST: - sflags = S_KEYFIRST; - goto fast_search; - case DB_KEYLAST: - case DB_NODUPDATA: - sflags = S_KEYLAST; -fast_search: /* - * If the application has a history of inserting into the first - * or last pages of the database, we check those pages first to - * avoid doing a full search. - */ - if (F_ISSET(dbc, DBC_OPD)) - goto search; - - /* - * !!! - * We do not mutex protect the t->bt_lpgno field, which means - * that it can only be used in an advisory manner. If we find - * page we can use, great. If we don't, we don't care, we do - * it the slow way instead. Regardless, copy it into a local - * variable, otherwise we might acquire a lock for a page and - * then read a different page because it changed underfoot. - */ - bt_lpgno = t->bt_lpgno; - - /* - * If the tree has no history of insertion, do it the slow way. - */ - if (bt_lpgno == PGNO_INVALID) - goto search; - - /* - * Lock and retrieve the page on which we last inserted. - * - * The page may not exist: if a transaction created the page - * and then aborted, the page might have been truncated from - * the end of the file. - */ - h = NULL; - ACQUIRE_CUR(dbc, DB_LOCK_WRITE, bt_lpgno, ret); - if (ret != 0) { - if (ret == DB_PAGE_NOTFOUND) - ret = 0; - goto fast_miss; - } - - h = cp->page; - inp = P_INP(dbp, h); - - /* - * It's okay if the page type isn't right or it's empty, it - * just means that the world changed. - */ - if (TYPE(h) != P_LBTREE || NUM_ENT(h) == 0) - goto fast_miss; - - /* Verify that this page cannot have moved to another db. */ - if (F_ISSET(dbp, DB_AM_SUBDB) && - log_compare(&t->bt_llsn, &LSN(h)) != 0) - goto fast_miss; - /* - * What we do here is test to see if we're at the beginning or - * end of the tree and if the new item sorts before/after the - * first/last page entry. We don't try and catch inserts into - * the middle of the tree (although we could, as long as there - * were two keys on the page and we saved both the index and - * the page number of the last insert). - */ - if (h->next_pgno == PGNO_INVALID) { - indx = NUM_ENT(h) - P_INDX; - if ((ret = __bam_cmp(dbp, - key, h, indx, t->bt_compare, &cmp)) != 0) - return (ret); - - if (cmp < 0) - goto try_begin; - if (cmp > 0) { - indx += P_INDX; - goto fast_hit; - } - - /* - * Found a duplicate. If doing DB_KEYLAST, we're at - * the correct position, otherwise, move to the first - * of the duplicates. If we're looking at off-page - * duplicates, duplicate duplicates aren't permitted, - * so we're done. - */ - if (flags == DB_KEYLAST) - goto fast_hit; - for (; - indx > 0 && inp[indx - P_INDX] == inp[indx]; - indx -= P_INDX) - ; - goto fast_hit; - } -try_begin: if (h->prev_pgno == PGNO_INVALID) { - indx = 0; - if ((ret = __bam_cmp(dbp, - key, h, indx, t->bt_compare, &cmp)) != 0) - return (ret); - - if (cmp > 0) - goto fast_miss; - if (cmp < 0) - goto fast_hit; - - /* - * Found a duplicate. If doing DB_KEYFIRST, we're at - * the correct position, otherwise, move to the last - * of the duplicates. If we're looking at off-page - * duplicates, duplicate duplicates aren't permitted, - * so we're done. - */ - if (flags == DB_KEYFIRST) - goto fast_hit; - for (; - indx < (db_indx_t)(NUM_ENT(h) - P_INDX) && - inp[indx] == inp[indx + P_INDX]; - indx += P_INDX) - ; - goto fast_hit; - } - goto fast_miss; - -fast_hit: /* Set the exact match flag, we may have found a duplicate. */ - *exactp = cmp == 0; - - /* - * Insert the entry in the stack. (Our caller is likely to - * call __bam_stkrel() after our return.) - */ - BT_STK_CLR(cp); - BT_STK_ENTER(dbp->dbenv, - cp, h, indx, cp->lock, cp->lock_mode, ret); - if (ret != 0) - return (ret); - break; - -fast_miss: /* - * This was not the right page, so we do not need to retain - * the lock even in the presence of transactions. - * - * This is also an error path, so ret may have been set. - */ - DISCARD_CUR(dbc, ret); - cp->pgno = PGNO_INVALID; - if ((t_ret = __LPUT(dbc, cp->lock)) != 0 && ret == 0) - ret = t_ret; - if (ret != 0) - return (ret); - -search: if ((ret = __bam_search(dbc, root_pgno, - key, sflags, 1, NULL, exactp)) != 0) - return (ret); - break; - default: - return (__db_unknown_flag(dbp->dbenv, "__bam_c_search", flags)); - } - /* Initialize the cursor from the stack. */ - cp->page = cp->csp->page; - cp->pgno = cp->csp->page->pgno; - cp->indx = cp->csp->indx; - cp->lock = cp->csp->lock; - cp->lock_mode = cp->csp->lock_mode; - - /* If on an empty page or a deleted record, move to the next one. */ - if (flags == DB_FIRST && - (NUM_ENT(cp->page) == 0 || IS_CUR_DELETED(dbc))) - if ((ret = __bam_c_next(dbc, 0, 0)) != 0) - return (ret); - if (flags == DB_LAST && - (NUM_ENT(cp->page) == 0 || IS_CUR_DELETED(dbc))) - if ((ret = __bam_c_prev(dbc)) != 0) - return (ret); - - return (0); -} - -/* - * __bam_c_physdel -- - * Physically remove an item from the page. - */ -static int -__bam_c_physdel(dbc) - DBC *dbc; -{ - BTREE_CURSOR *cp; - DB *dbp; - DBT key; - int delete_page, empty_page, exact, ret; - - dbp = dbc->dbp; - memset(&key, 0, sizeof(DBT)); - cp = (BTREE_CURSOR *)dbc->internal; - delete_page = empty_page = ret = 0; - - /* If the page is going to be emptied, consider deleting it. */ - delete_page = empty_page = - NUM_ENT(cp->page) == (TYPE(cp->page) == P_LBTREE ? 2 : 1); - - /* - * Check if the application turned off reverse splits. Applications - * can't turn off reverse splits in off-page duplicate trees, that - * space will never be reused unless the exact same key is specified. - */ - if (delete_page && - !F_ISSET(dbc, DBC_OPD) && F_ISSET(dbp, DB_AM_REVSPLITOFF)) - delete_page = 0; - - /* - * We never delete the last leaf page. (Not really true -- we delete - * the last leaf page of off-page duplicate trees, but that's handled - * by our caller, not down here.) - */ - if (delete_page && cp->pgno == cp->root) - delete_page = 0; - - /* - * To delete a leaf page other than an empty root page, we need a - * copy of a key from the page. Use the 0th page index since it's - * the last key the page held. - * - * !!! - * Note that because __bam_c_physdel is always called from a cursor - * close, it should be safe to use the cursor's own "my_rkey" memory - * to temporarily hold this key. We shouldn't own any returned-data - * memory of interest--if we do, we're in trouble anyway. - */ - if (delete_page) - if ((ret = __db_ret(dbp, cp->page, - 0, &key, &dbc->my_rkey.data, &dbc->my_rkey.ulen)) != 0) - return (ret); - - /* - * Delete the items. If page isn't empty, we adjust the cursors. - * - * !!! - * The following operations to delete a page may deadlock. The easy - * scenario is if we're deleting an item because we're closing cursors - * because we've already deadlocked and want to call txn->abort. If - * we fail due to deadlock, we'll leave a locked, possibly empty page - * in the tree, which won't be empty long because we'll undo the delete - * when we undo the transaction's modifications. - * - * !!! - * Delete the key item first, otherwise the on-page duplicate checks - * in __bam_ditem() won't work! - */ - if (TYPE(cp->page) == P_LBTREE) { - if ((ret = __bam_ditem(dbc, cp->page, cp->indx)) != 0) - return (ret); - if (!empty_page) - if ((ret = __bam_ca_di(dbc, - PGNO(cp->page), cp->indx, -1)) != 0) - return (ret); - } - if ((ret = __bam_ditem(dbc, cp->page, cp->indx)) != 0) - return (ret); - - /* Clear the deleted flag, the item is gone. */ - F_CLR(cp, C_DELETED); - - if (!empty_page) - if ((ret = __bam_ca_di(dbc, PGNO(cp->page), cp->indx, -1)) != 0) - return (ret); - - /* If we're not going to try and delete the page, we're done. */ - if (!delete_page) - return (0); - - ret = __bam_search(dbc, PGNO_INVALID, &key, S_DEL, 0, NULL, &exact); - - /* - * If everything worked, delete the stack, otherwise, release the - * stack and page locks without further damage. - */ - if (ret == 0) - DISCARD_CUR(dbc, ret); - if (ret == 0) - ret = __bam_dpages(dbc, 1, 0); - else - (void)__bam_stkrel(dbc, 0); - - return (ret); -} - -/* - * __bam_c_getstack -- - * Acquire a full stack for a cursor. - */ -static int -__bam_c_getstack(dbc) - DBC *dbc; -{ - BTREE_CURSOR *cp; - DB *dbp; - DBT dbt; - DB_MPOOLFILE *mpf; - PAGE *h; - int exact, ret, t_ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - cp = (BTREE_CURSOR *)dbc->internal; - - /* - * Get the page with the current item on it. The caller of this - * routine has to already hold a read lock on the page, so there - * is no additional lock to acquire. - */ - if ((ret = __memp_fget(mpf, &cp->pgno, 0, &h)) != 0) - return (ret); - - /* Get a copy of a key from the page. */ - memset(&dbt, 0, sizeof(DBT)); - if ((ret = __db_ret(dbp, - h, 0, &dbt, &dbc->my_rkey.data, &dbc->my_rkey.ulen)) != 0) - goto err; - - /* Get a write-locked stack for the page. */ - exact = 0; - ret = __bam_search(dbc, PGNO_INVALID, - &dbt, S_KEYFIRST, 1, NULL, &exact); - -err: /* Discard the key and the page. */ - if ((t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __bam_isopd -- - * Return if the cursor references an off-page duplicate tree via its - * page number. - */ -static int -__bam_isopd(dbc, pgnop) - DBC *dbc; - db_pgno_t *pgnop; -{ - BOVERFLOW *bo; - - if (TYPE(dbc->internal->page) != P_LBTREE) - return (0); - - bo = GET_BOVERFLOW(dbc->dbp, - dbc->internal->page, dbc->internal->indx + O_INDX); - if (B_TYPE(bo->type) == B_DUPLICATE) { - *pgnop = bo->pgno; - return (1); - } - return (0); -} diff --git a/storage/bdb/btree/bt_delete.c b/storage/bdb/btree/bt_delete.c deleted file mode 100644 index 1e54687453f..00000000000 --- a/storage/bdb/btree/bt_delete.c +++ /dev/null @@ -1,643 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994, 1995, 1996 - * Keith Bostic. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994, 1995 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Mike Olson. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: bt_delete.c,v 12.13 2005/10/20 18:14:59 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/btree.h" -#include "dbinc/lock.h" -#include "dbinc/mp.h" - -/* - * __bam_ditem -- - * Delete one or more entries from a page. - * - * PUBLIC: int __bam_ditem __P((DBC *, PAGE *, u_int32_t)); - */ -int -__bam_ditem(dbc, h, indx) - DBC *dbc; - PAGE *h; - u_int32_t indx; -{ - BINTERNAL *bi; - BKEYDATA *bk; - DB *dbp; - DB_MPOOLFILE *mpf; - u_int32_t nbytes; - int ret; - db_indx_t *inp; - - dbp = dbc->dbp; - mpf = dbp->mpf; - inp = P_INP(dbp, h); - - switch (TYPE(h)) { - case P_IBTREE: - bi = GET_BINTERNAL(dbp, h, indx); - switch (B_TYPE(bi->type)) { - case B_DUPLICATE: - case B_KEYDATA: - nbytes = BINTERNAL_SIZE(bi->len); - break; - case B_OVERFLOW: - nbytes = BINTERNAL_SIZE(bi->len); - if ((ret = - __db_doff(dbc, ((BOVERFLOW *)bi->data)->pgno)) != 0) - return (ret); - break; - default: - return (__db_pgfmt(dbp->dbenv, PGNO(h))); - } - break; - case P_IRECNO: - nbytes = RINTERNAL_SIZE; - break; - case P_LBTREE: - /* - * If it's a duplicate key, discard the index and don't touch - * the actual page item. - * - * !!! - * This works because no data item can have an index matching - * any other index so even if the data item is in a key "slot", - * it won't match any other index. - */ - if ((indx % 2) == 0) { - /* - * Check for a duplicate after us on the page. NOTE: - * we have to delete the key item before deleting the - * data item, otherwise the "indx + P_INDX" calculation - * won't work! - */ - if (indx + P_INDX < (u_int32_t)NUM_ENT(h) && - inp[indx] == inp[indx + P_INDX]) - return (__bam_adjindx(dbc, - h, indx, indx + O_INDX, 0)); - /* - * Check for a duplicate before us on the page. It - * doesn't matter if we delete the key item before or - * after the data item for the purposes of this one. - */ - if (indx > 0 && inp[indx] == inp[indx - P_INDX]) - return (__bam_adjindx(dbc, - h, indx, indx - P_INDX, 0)); - } - /* FALLTHROUGH */ - case P_LDUP: - case P_LRECNO: - bk = GET_BKEYDATA(dbp, h, indx); - switch (B_TYPE(bk->type)) { - case B_DUPLICATE: - nbytes = BOVERFLOW_SIZE; - break; - case B_OVERFLOW: - nbytes = BOVERFLOW_SIZE; - if ((ret = __db_doff( - dbc, (GET_BOVERFLOW(dbp, h, indx))->pgno)) != 0) - return (ret); - break; - case B_KEYDATA: - nbytes = BKEYDATA_SIZE(bk->len); - break; - default: - return (__db_pgfmt(dbp->dbenv, PGNO(h))); - } - break; - default: - return (__db_pgfmt(dbp->dbenv, PGNO(h))); - } - - /* Delete the item and mark the page dirty. */ - if ((ret = __db_ditem(dbc, h, indx, nbytes)) != 0) - return (ret); - if ((ret = __memp_fset(mpf, h, DB_MPOOL_DIRTY)) != 0) - return (ret); - - return (0); -} - -/* - * __bam_adjindx -- - * Adjust an index on the page. - * - * PUBLIC: int __bam_adjindx __P((DBC *, PAGE *, u_int32_t, u_int32_t, int)); - */ -int -__bam_adjindx(dbc, h, indx, indx_copy, is_insert) - DBC *dbc; - PAGE *h; - u_int32_t indx, indx_copy; - int is_insert; -{ - DB *dbp; - DB_MPOOLFILE *mpf; - db_indx_t copy, *inp; - int ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - inp = P_INP(dbp, h); - - /* Log the change. */ - if (DBC_LOGGING(dbc)) { - if ((ret = __bam_adj_log(dbp, dbc->txn, &LSN(h), 0, - PGNO(h), &LSN(h), indx, indx_copy, (u_int32_t)is_insert)) != 0) - return (ret); - } else - LSN_NOT_LOGGED(LSN(h)); - - /* Shuffle the indices and mark the page dirty. */ - if (is_insert) { - copy = inp[indx_copy]; - if (indx != NUM_ENT(h)) - memmove(&inp[indx + O_INDX], &inp[indx], - sizeof(db_indx_t) * (NUM_ENT(h) - indx)); - inp[indx] = copy; - ++NUM_ENT(h); - } else { - --NUM_ENT(h); - if (indx != NUM_ENT(h)) - memmove(&inp[indx], &inp[indx + O_INDX], - sizeof(db_indx_t) * (NUM_ENT(h) - indx)); - } - if ((ret = __memp_fset(mpf, h, DB_MPOOL_DIRTY)) != 0) - return (ret); - - return (0); -} - -/* - * __bam_dpages -- - * Delete a set of locked pages. - * - * PUBLIC: int __bam_dpages __P((DBC *, int, int)); - */ -int -__bam_dpages(dbc, use_top, update) - DBC *dbc; - int use_top; - int update; -{ - BTREE_CURSOR *cp; - BINTERNAL *bi; - DB *dbp; - DBT a, b; - DB_LOCK c_lock, p_lock; - DB_MPOOLFILE *mpf; - EPG *epg, *save_sp, *stack_epg; - PAGE *child, *parent; - db_indx_t nitems; - db_pgno_t pgno, root_pgno; - db_recno_t rcnt; - int done, ret, t_ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - cp = (BTREE_CURSOR *)dbc->internal; - nitems = 0; - pgno = PGNO_INVALID; - - /* - * We have the entire stack of deletable pages locked. - * - * Btree calls us with the first page in the stack is to have a - * single item deleted, and the rest of the pages are to be removed. - * - * Recno always has a stack to the root and __bam_merge operations - * may have unneeded items in the sack. We find the lowest page - * in the stack that has more than one record in it and start there. - */ - ret = 0; - if (use_top) - stack_epg = cp->sp; - else - for (stack_epg = cp->csp; stack_epg > cp->sp; --stack_epg) - if (NUM_ENT(stack_epg->page) > 1) - break; - epg = stack_epg; - /* - * !!! - * There is an interesting deadlock situation here. We have to relink - * the leaf page chain around the leaf page being deleted. Consider - * a cursor walking through the leaf pages, that has the previous page - * read-locked and is waiting on a lock for the page we're deleting. - * It will deadlock here. Before we unlink the subtree, we relink the - * leaf page chain. - */ - if (LEVEL(cp->csp->page) == 1 && - (ret = __bam_relink(dbc, cp->csp->page, PGNO_INVALID)) != 0) - goto discard; - - /* - * Delete the last item that references the underlying pages that are - * to be deleted, and adjust cursors that reference that page. Then, - * save that page's page number and item count and release it. If - * the application isn't retaining locks because it's running without - * transactions, this lets the rest of the tree get back to business - * immediately. - */ - if ((ret = __bam_ditem(dbc, epg->page, epg->indx)) != 0) - goto discard; - if ((ret = __bam_ca_di(dbc, PGNO(epg->page), epg->indx, -1)) != 0) - goto discard; - - if (update && epg->indx == 0) { - save_sp = cp->csp; - cp->csp = epg; - ret = __bam_pupdate(dbc, epg->page); - cp->csp = save_sp; - if (ret != 0) - goto discard; - } - - pgno = PGNO(epg->page); - nitems = NUM_ENT(epg->page); - - ret = __memp_fput(mpf, epg->page, 0); - if ((t_ret = __TLPUT(dbc, epg->lock)) != 0 && ret == 0) - ret = t_ret; - if (ret != 0) - goto err_inc; - - /* Then, discard any pages that we don't care about. */ -discard: for (epg = cp->sp; epg < stack_epg; ++epg) { - if ((t_ret = __memp_fput(mpf, epg->page, 0)) != 0 && ret == 0) - ret = t_ret; - epg->page = NULL; - if ((t_ret = __TLPUT(dbc, epg->lock)) != 0 && ret == 0) - ret = t_ret; - } - if (ret != 0) - goto err; - - /* Free the rest of the pages in the stack. */ - while (++epg <= cp->csp) { - /* - * Delete page entries so they will be restored as part of - * recovery. We don't need to do cursor adjustment here as - * the pages are being emptied by definition and so cannot - * be referenced by a cursor. - */ - if (NUM_ENT(epg->page) != 0) { - DB_ASSERT(LEVEL(epg->page) != 1); - - if ((ret = __bam_ditem(dbc, epg->page, epg->indx)) != 0) - goto err; - /* - * Sheer paranoia: if we find any pages that aren't - * emptied by the delete, someone else added an item - * while we were walking the tree, and we discontinue - * the delete. Shouldn't be possible, but we check - * regardless. - */ - if (NUM_ENT(epg->page) != 0) - goto err; - } - - ret = __db_free(dbc, epg->page); - if (cp->page == epg->page) - cp->page = NULL; - epg->page = NULL; - if ((t_ret = __TLPUT(dbc, epg->lock)) != 0 && ret == 0) - ret = t_ret; - if (ret != 0) - goto err_inc; - } - - if (0) { -err_inc: ++epg; -err: for (; epg <= cp->csp; ++epg) { - if (epg->page != NULL) - (void)__memp_fput(mpf, epg->page, 0); - (void)__TLPUT(dbc, epg->lock); - } - BT_STK_CLR(cp); - return (ret); - } - BT_STK_CLR(cp); - - /* - * If we just deleted the next-to-last item from the root page, the - * tree can collapse one or more levels. While there remains only a - * single item on the root page, write lock the last page referenced - * by the root page and copy it over the root page. - */ - root_pgno = cp->root; - if (pgno != root_pgno || nitems != 1) - return (0); - - for (done = 0; !done;) { - /* Initialize. */ - parent = child = NULL; - LOCK_INIT(p_lock); - LOCK_INIT(c_lock); - - /* Lock the root. */ - pgno = root_pgno; - if ((ret = - __db_lget(dbc, 0, pgno, DB_LOCK_WRITE, 0, &p_lock)) != 0) - goto stop; - if ((ret = __memp_fget(mpf, &pgno, 0, &parent)) != 0) - goto stop; - - if (NUM_ENT(parent) != 1) - goto stop; - - switch (TYPE(parent)) { - case P_IBTREE: - /* - * If this is overflow, then try to delete it. - * The child may or may not still point at it. - */ - bi = GET_BINTERNAL(dbp, parent, 0); - if (B_TYPE(bi->type) == B_OVERFLOW) - if ((ret = __db_doff(dbc, - ((BOVERFLOW *)bi->data)->pgno)) != 0) - goto stop; - pgno = bi->pgno; - break; - case P_IRECNO: - pgno = GET_RINTERNAL(dbp, parent, 0)->pgno; - break; - default: - goto stop; - } - - /* Lock the child page. */ - if ((ret = - __db_lget(dbc, 0, pgno, DB_LOCK_WRITE, 0, &c_lock)) != 0) - goto stop; - if ((ret = __memp_fget(mpf, &pgno, 0, &child)) != 0) - goto stop; - - /* Log the change. */ - if (DBC_LOGGING(dbc)) { - memset(&a, 0, sizeof(a)); - a.data = child; - a.size = dbp->pgsize; - memset(&b, 0, sizeof(b)); - b.data = P_ENTRY(dbp, parent, 0); - b.size = TYPE(parent) == P_IRECNO ? RINTERNAL_SIZE : - BINTERNAL_SIZE(((BINTERNAL *)b.data)->len); - if ((ret = __bam_rsplit_log(dbp, dbc->txn, - &child->lsn, 0, PGNO(child), &a, PGNO(parent), - RE_NREC(parent), &b, &parent->lsn)) != 0) - goto stop; - } else - LSN_NOT_LOGGED(child->lsn); - - /* - * Make the switch. - * - * One fixup -- internal pages below the top level do not store - * a record count, so we have to preserve it if we're not - * converting to a leaf page. Note also that we are about to - * overwrite the parent page, including its LSN. This is OK - * because the log message we wrote describing this update - * stores its LSN on the child page. When the child is copied - * onto the parent, the correct LSN is copied into place. - */ - COMPQUIET(rcnt, 0); - if (F_ISSET(cp, C_RECNUM) && LEVEL(child) > LEAFLEVEL) - rcnt = RE_NREC(parent); - memcpy(parent, child, dbp->pgsize); - PGNO(parent) = root_pgno; - if (F_ISSET(cp, C_RECNUM) && LEVEL(child) > LEAFLEVEL) - RE_NREC_SET(parent, rcnt); - - /* Mark the pages dirty. */ - if ((ret = __memp_fset(mpf, parent, DB_MPOOL_DIRTY)) != 0) - goto stop; - if ((ret = __memp_fset(mpf, child, DB_MPOOL_DIRTY)) != 0) - goto stop; - - /* Adjust the cursors. */ - if ((ret = __bam_ca_rsplit(dbc, PGNO(child), root_pgno)) != 0) - goto stop; - - /* - * Free the page copied onto the root page and discard its - * lock. (The call to __db_free() discards our reference - * to the page.) - */ - if ((ret = __db_free(dbc, child)) != 0) { - child = NULL; - goto stop; - } - child = NULL; - - if (0) { -stop: done = 1; - } - if ((t_ret = __TLPUT(dbc, p_lock)) != 0 && ret == 0) - ret = t_ret; - if (parent != NULL && - (t_ret = __memp_fput(mpf, parent, 0)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = __TLPUT(dbc, c_lock)) != 0 && ret == 0) - ret = t_ret; - if (child != NULL && - (t_ret = __memp_fput(mpf, child, 0)) != 0 && ret == 0) - ret = t_ret; - } - - return (ret); -} - -/* - * __bam_relink -- - * Relink around a deleted page. - * - * PUBLIC: int __bam_relink __P((DBC *, PAGE *, db_pgno_t)); - */ -int -__bam_relink(dbc, pagep, new_pgno) - DBC *dbc; - PAGE *pagep; - db_pgno_t new_pgno; -{ - DB *dbp; - PAGE *np, *pp; - DB_LOCK npl, ppl; - DB_LSN *nlsnp, *plsnp, ret_lsn; - DB_MPOOLFILE *mpf; - int ret, t_ret; - - dbp = dbc->dbp; - np = pp = NULL; - LOCK_INIT(npl); - LOCK_INIT(ppl); - nlsnp = plsnp = NULL; - mpf = dbp->mpf; - ret = 0; - - /* - * Retrieve and lock the one/two pages. For a remove, we may need - * two pages (the before and after). For an add, we only need one - * because, the split took care of the prev. - */ - if (pagep->next_pgno != PGNO_INVALID) { - if ((ret = __db_lget(dbc, - 0, pagep->next_pgno, DB_LOCK_WRITE, 0, &npl)) != 0) - goto err; - if ((ret = __memp_fget(mpf, &pagep->next_pgno, 0, &np)) != 0) { - ret = __db_pgerr(dbp, pagep->next_pgno, ret); - goto err; - } - nlsnp = &np->lsn; - } - if (pagep->prev_pgno != PGNO_INVALID) { - if ((ret = __db_lget(dbc, - 0, pagep->prev_pgno, DB_LOCK_WRITE, 0, &ppl)) != 0) - goto err; - if ((ret = __memp_fget(mpf, &pagep->prev_pgno, 0, &pp)) != 0) { - ret = __db_pgerr(dbp, pagep->prev_pgno, ret); - goto err; - } - plsnp = &pp->lsn; - } - - /* Log the change. */ - if (DBC_LOGGING(dbc)) { - if ((ret = __bam_relink_log(dbp, dbc->txn, &ret_lsn, 0, - pagep->pgno, new_pgno, pagep->prev_pgno, plsnp, - pagep->next_pgno, nlsnp)) != 0) - goto err; - } else - LSN_NOT_LOGGED(ret_lsn); - if (np != NULL) - np->lsn = ret_lsn; - if (pp != NULL) - pp->lsn = ret_lsn; - - /* - * Modify and release the two pages. - */ - if (np != NULL) { - if (new_pgno == PGNO_INVALID) - np->prev_pgno = pagep->prev_pgno; - else - np->prev_pgno = new_pgno; - ret = __memp_fput(mpf, np, DB_MPOOL_DIRTY); - if ((t_ret = __TLPUT(dbc, npl)) != 0 && ret == 0) - ret = t_ret; - if (ret != 0) - goto err; - } - - if (pp != NULL) { - if (new_pgno == PGNO_INVALID) - pp->next_pgno = pagep->next_pgno; - else - pp->next_pgno = new_pgno; - ret = __memp_fput(mpf, pp, DB_MPOOL_DIRTY); - if ((t_ret = __TLPUT(dbc, ppl)) != 0 && ret == 0) - ret = t_ret; - if (ret != 0) - goto err; - } - return (0); - -err: if (np != NULL) - (void)__memp_fput(mpf, np, 0); - (void)__TLPUT(dbc, npl); - if (pp != NULL) - (void)__memp_fput(mpf, pp, 0); - (void)__TLPUT(dbc, ppl); - return (ret); -} - -/* - * __bam_pupdate -- - * Update parent key pointers up the tree. - * - * PUBLIC: int __bam_pupdate __P((DBC *, PAGE *)); - */ -int -__bam_pupdate(dbc, lpg) - DBC *dbc; - PAGE *lpg; -{ - BTREE_CURSOR *cp; - DB_ENV *dbenv; - EPG *epg; - int ret; - - dbenv = dbc->dbp->dbenv; - cp = (BTREE_CURSOR *)dbc->internal; - ret = 0; - - /* - * Update the parents up the tree. __bam_pinsert only looks at the - * left child if is a leaf page, so we don't need to change it. We - * just do a delete and insert; a replace is possible but reusing - * pinsert is better. - */ - for (epg = &cp->csp[-1]; epg >= cp->sp; epg--) { - if ((ret = __bam_ditem(dbc, epg->page, epg->indx)) != 0) - return (ret); - epg->indx--; - if ((ret = __bam_pinsert(dbc, epg, - lpg, epg[1].page, BPI_NORECNUM)) != 0) { - if (ret == DB_NEEDSPLIT) { - /* This should not happen. */ - __db_err(dbenv, - "Not enough room in parent: %s: page %lu", - dbc->dbp->fname, (u_long)PGNO(epg->page)); - ret = __db_panic(dbenv, EINVAL); - } - return (ret); - } - } - return (ret); -} diff --git a/storage/bdb/btree/bt_method.c b/storage/bdb/btree/bt_method.c deleted file mode 100644 index c6bfa869fd1..00000000000 --- a/storage/bdb/btree/bt_method.c +++ /dev/null @@ -1,514 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: bt_method.c,v 12.2 2005/06/16 20:20:16 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/btree.h" -#include "dbinc/qam.h" - -static int __bam_set_bt_minkey __P((DB *, u_int32_t)); -static int __bam_set_bt_prefix - __P((DB *, size_t(*)(DB *, const DBT *, const DBT *))); -static int __ram_get_re_delim __P((DB *, int *)); -static int __ram_set_re_delim __P((DB *, int)); -static int __ram_set_re_len __P((DB *, u_int32_t)); -static int __ram_set_re_pad __P((DB *, int)); -static int __ram_get_re_source __P((DB *, const char **)); -static int __ram_set_re_source __P((DB *, const char *)); - -/* - * __bam_db_create -- - * Btree specific initialization of the DB structure. - * - * PUBLIC: int __bam_db_create __P((DB *)); - */ -int -__bam_db_create(dbp) - DB *dbp; -{ - BTREE *t; - int ret; - - /* Allocate and initialize the private btree structure. */ - if ((ret = __os_calloc(dbp->dbenv, 1, sizeof(BTREE), &t)) != 0) - return (ret); - dbp->bt_internal = t; - - t->bt_minkey = DEFMINKEYPAGE; /* Btree */ - t->bt_compare = __bam_defcmp; - t->bt_prefix = __bam_defpfx; - - dbp->set_bt_compare = __bam_set_bt_compare; - dbp->get_bt_minkey = __bam_get_bt_minkey; - dbp->set_bt_minkey = __bam_set_bt_minkey; - dbp->set_bt_prefix = __bam_set_bt_prefix; - - t->re_pad = ' '; /* Recno */ - t->re_delim = '\n'; - t->re_eof = 1; - - dbp->get_re_delim = __ram_get_re_delim; - dbp->set_re_delim = __ram_set_re_delim; - dbp->get_re_len = __ram_get_re_len; - dbp->set_re_len = __ram_set_re_len; - dbp->get_re_pad = __ram_get_re_pad; - dbp->set_re_pad = __ram_set_re_pad; - dbp->get_re_source = __ram_get_re_source; - dbp->set_re_source = __ram_set_re_source; - - return (0); -} - -/* - * __bam_db_close -- - * Btree specific discard of the DB structure. - * - * PUBLIC: int __bam_db_close __P((DB *)); - */ -int -__bam_db_close(dbp) - DB *dbp; -{ - BTREE *t; - - if ((t = dbp->bt_internal) == NULL) - return (0); - /* Recno */ - /* Close any backing source file descriptor. */ - if (t->re_fp != NULL) - (void)fclose(t->re_fp); - - /* Free any backing source file name. */ - if (t->re_source != NULL) - __os_free(dbp->dbenv, t->re_source); - - __os_free(dbp->dbenv, t); - dbp->bt_internal = NULL; - - return (0); -} - -/* - * __bam_map_flags -- - * Map Btree specific flags from public to the internal values. - * - * PUBLIC: void __bam_map_flags __P((DB *, u_int32_t *, u_int32_t *)); - */ -void -__bam_map_flags(dbp, inflagsp, outflagsp) - DB *dbp; - u_int32_t *inflagsp, *outflagsp; -{ - COMPQUIET(dbp, NULL); - - if (FLD_ISSET(*inflagsp, DB_DUP)) { - FLD_SET(*outflagsp, DB_AM_DUP); - FLD_CLR(*inflagsp, DB_DUP); - } - if (FLD_ISSET(*inflagsp, DB_DUPSORT)) { - FLD_SET(*outflagsp, DB_AM_DUP | DB_AM_DUPSORT); - FLD_CLR(*inflagsp, DB_DUPSORT); - } - if (FLD_ISSET(*inflagsp, DB_RECNUM)) { - FLD_SET(*outflagsp, DB_AM_RECNUM); - FLD_CLR(*inflagsp, DB_RECNUM); - } - if (FLD_ISSET(*inflagsp, DB_REVSPLITOFF)) { - FLD_SET(*outflagsp, DB_AM_REVSPLITOFF); - FLD_CLR(*inflagsp, DB_REVSPLITOFF); - } -} - -/* - * __bam_set_flags -- - * Set Btree specific flags. - * - * PUBLIC: int __bam_set_flags __P((DB *, u_int32_t *flagsp)); - */ -int -__bam_set_flags(dbp, flagsp) - DB *dbp; - u_int32_t *flagsp; -{ - u_int32_t flags; - - flags = *flagsp; - if (LF_ISSET(DB_DUP | DB_DUPSORT | DB_RECNUM | DB_REVSPLITOFF)) - DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_flags"); - - /* - * The DB_DUP and DB_DUPSORT flags are shared by the Hash - * and Btree access methods. - */ - if (LF_ISSET(DB_DUP | DB_DUPSORT)) - DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE | DB_OK_HASH); - - if (LF_ISSET(DB_RECNUM | DB_REVSPLITOFF)) - DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE); - - /* DB_DUP/DB_DUPSORT is incompatible with DB_RECNUM. */ - if (LF_ISSET(DB_DUP | DB_DUPSORT) && F_ISSET(dbp, DB_AM_RECNUM)) - goto incompat; - - /* DB_RECNUM is incompatible with DB_DUP/DB_DUPSORT. */ - if (LF_ISSET(DB_RECNUM) && F_ISSET(dbp, DB_AM_DUP)) - goto incompat; - - if (LF_ISSET(DB_DUPSORT) && dbp->dup_compare == NULL) - dbp->dup_compare = __bam_defcmp; - - __bam_map_flags(dbp, flagsp, &dbp->flags); - return (0); - -incompat: - return (__db_ferr(dbp->dbenv, "DB->set_flags", 1)); -} - -/* - * __bam_set_bt_compare -- - * Set the comparison function. - * - * PUBLIC: int __bam_set_bt_compare - * PUBLIC: __P((DB *, int (*)(DB *, const DBT *, const DBT *))); - */ -int -__bam_set_bt_compare(dbp, func) - DB *dbp; - int (*func) __P((DB *, const DBT *, const DBT *)); -{ - BTREE *t; - - DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_bt_compare"); - DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE); - - t = dbp->bt_internal; - - /* - * Can't default the prefix routine if the user supplies a comparison - * routine; shortening the keys can break their comparison algorithm. - */ - t->bt_compare = func; - if (t->bt_prefix == __bam_defpfx) - t->bt_prefix = NULL; - - return (0); -} - -/* - * __db_get_bt_minkey -- - * Get the minimum keys per page. - * - * PUBLIC: int __bam_get_bt_minkey __P((DB *, u_int32_t *)); - */ -int -__bam_get_bt_minkey(dbp, bt_minkeyp) - DB *dbp; - u_int32_t *bt_minkeyp; -{ - BTREE *t; - - DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE); - - t = dbp->bt_internal; - *bt_minkeyp = t->bt_minkey; - return (0); -} - -/* - * __bam_set_bt_minkey -- - * Set the minimum keys per page. - */ -static int -__bam_set_bt_minkey(dbp, bt_minkey) - DB *dbp; - u_int32_t bt_minkey; -{ - BTREE *t; - - DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_bt_minkey"); - DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE); - - t = dbp->bt_internal; - - if (bt_minkey < 2) { - __db_err(dbp->dbenv, "minimum bt_minkey value is 2"); - return (EINVAL); - } - - t->bt_minkey = bt_minkey; - return (0); -} - -/* - * __bam_set_bt_prefix -- - * Set the prefix function. - */ -static int -__bam_set_bt_prefix(dbp, func) - DB *dbp; - size_t (*func) __P((DB *, const DBT *, const DBT *)); -{ - BTREE *t; - - DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_bt_prefix"); - DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE); - - t = dbp->bt_internal; - - t->bt_prefix = func; - return (0); -} - -/* - * __ram_map_flags -- - * Map Recno specific flags from public to the internal values. - * - * PUBLIC: void __ram_map_flags __P((DB *, u_int32_t *, u_int32_t *)); - */ -void -__ram_map_flags(dbp, inflagsp, outflagsp) - DB *dbp; - u_int32_t *inflagsp, *outflagsp; -{ - COMPQUIET(dbp, NULL); - - if (FLD_ISSET(*inflagsp, DB_RENUMBER)) { - FLD_SET(*outflagsp, DB_AM_RENUMBER); - FLD_CLR(*inflagsp, DB_RENUMBER); - } - if (FLD_ISSET(*inflagsp, DB_SNAPSHOT)) { - FLD_SET(*outflagsp, DB_AM_SNAPSHOT); - FLD_CLR(*inflagsp, DB_SNAPSHOT); - } -} - -/* - * __ram_set_flags -- - * Set Recno specific flags. - * - * PUBLIC: int __ram_set_flags __P((DB *, u_int32_t *flagsp)); - */ -int -__ram_set_flags(dbp, flagsp) - DB *dbp; - u_int32_t *flagsp; -{ - u_int32_t flags; - - flags = *flagsp; - if (LF_ISSET(DB_RENUMBER | DB_SNAPSHOT)) { - DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_flags"); - DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO); - } - - __ram_map_flags(dbp, flagsp, &dbp->flags); - return (0); -} - -/* - * __db_get_re_delim -- - * Get the variable-length input record delimiter. - */ -static int -__ram_get_re_delim(dbp, re_delimp) - DB *dbp; - int *re_delimp; -{ - BTREE *t; - - DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO); - t = dbp->bt_internal; - *re_delimp = t->re_delim; - return (0); -} - -/* - * __ram_set_re_delim -- - * Set the variable-length input record delimiter. - */ -static int -__ram_set_re_delim(dbp, re_delim) - DB *dbp; - int re_delim; -{ - BTREE *t; - - DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_re_delim"); - DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO); - - t = dbp->bt_internal; - - t->re_delim = re_delim; - F_SET(dbp, DB_AM_DELIMITER); - - return (0); -} - -/* - * __db_get_re_len -- - * Get the variable-length input record length. - * - * PUBLIC: int __ram_get_re_len __P((DB *, u_int32_t *)); - */ -int -__ram_get_re_len(dbp, re_lenp) - DB *dbp; - u_int32_t *re_lenp; -{ - BTREE *t; - QUEUE *q; - - DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO); - - /* - * This has to work for all access methods, before or after opening the - * database. When the record length is set with __ram_set_re_len, the - * value in both the BTREE and QUEUE structs will be correct. - * Otherwise, this only makes sense after the database in opened, in - * which case we know the type. - */ - if (dbp->type == DB_QUEUE) { - q = dbp->q_internal; - *re_lenp = q->re_len; - } else { - t = dbp->bt_internal; - *re_lenp = t->re_len; - } - - return (0); -} - -/* - * __ram_set_re_len -- - * Set the variable-length input record length. - */ -static int -__ram_set_re_len(dbp, re_len) - DB *dbp; - u_int32_t re_len; -{ - BTREE *t; - QUEUE *q; - - DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_re_len"); - DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO); - - t = dbp->bt_internal; - t->re_len = re_len; - - q = dbp->q_internal; - q->re_len = re_len; - - F_SET(dbp, DB_AM_FIXEDLEN); - - return (0); -} - -/* - * __db_get_re_pad -- - * Get the fixed-length record pad character. - * - * PUBLIC: int __ram_get_re_pad __P((DB *, int *)); - */ -int -__ram_get_re_pad(dbp, re_padp) - DB *dbp; - int *re_padp; -{ - BTREE *t; - QUEUE *q; - - DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO); - - /* - * This has to work for all access methods, before or after opening the - * database. When the record length is set with __ram_set_re_pad, the - * value in both the BTREE and QUEUE structs will be correct. - * Otherwise, this only makes sense after the database in opened, in - * which case we know the type. - */ - if (dbp->type == DB_QUEUE) { - q = dbp->q_internal; - *re_padp = q->re_pad; - } else { - t = dbp->bt_internal; - *re_padp = t->re_pad; - } - - return (0); -} - -/* - * __ram_set_re_pad -- - * Set the fixed-length record pad character. - */ -static int -__ram_set_re_pad(dbp, re_pad) - DB *dbp; - int re_pad; -{ - BTREE *t; - QUEUE *q; - - DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_re_pad"); - DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO); - - t = dbp->bt_internal; - t->re_pad = re_pad; - - q = dbp->q_internal; - q->re_pad = re_pad; - - F_SET(dbp, DB_AM_PAD); - - return (0); -} - -/* - * __db_get_re_source -- - * Get the backing source file name. - */ -static int -__ram_get_re_source(dbp, re_sourcep) - DB *dbp; - const char **re_sourcep; -{ - BTREE *t; - - DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO); - - t = dbp->bt_internal; - *re_sourcep = t->re_source; - return (0); -} - -/* - * __ram_set_re_source -- - * Set the backing source file name. - */ -static int -__ram_set_re_source(dbp, re_source) - DB *dbp; - const char *re_source; -{ - BTREE *t; - - DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_re_source"); - DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO); - - t = dbp->bt_internal; - - return (__os_strdup(dbp->dbenv, re_source, &t->re_source)); -} diff --git a/storage/bdb/btree/bt_open.c b/storage/bdb/btree/bt_open.c deleted file mode 100644 index d1fcaa76597..00000000000 --- a/storage/bdb/btree/bt_open.c +++ /dev/null @@ -1,607 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994, 1995, 1996 - * Keith Bostic. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994, 1995 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Mike Olson. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: bt_open.c,v 12.5 2005/09/28 17:44:17 margo Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/crypto.h" -#include "dbinc/db_page.h" -#include "dbinc/db_swap.h" -#include "dbinc/btree.h" -#include "dbinc/db_shash.h" -#include "dbinc/lock.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" -#include "dbinc/fop.h" - -static void __bam_init_meta __P((DB *, BTMETA *, db_pgno_t, DB_LSN *)); - -/* - * __bam_open -- - * Open a btree. - * - * PUBLIC: int __bam_open __P((DB *, - * PUBLIC: DB_TXN *, const char *, db_pgno_t, u_int32_t)); - */ -int -__bam_open(dbp, txn, name, base_pgno, flags) - DB *dbp; - DB_TXN *txn; - const char *name; - db_pgno_t base_pgno; - u_int32_t flags; -{ - BTREE *t; - - COMPQUIET(name, NULL); - t = dbp->bt_internal; - - /* - * We don't permit the user to specify a prefix routine if they didn't - * also specify a comparison routine, they can't know enough about our - * comparison routine to get it right. - */ - if (t->bt_compare == __bam_defcmp && t->bt_prefix != __bam_defpfx) { - __db_err(dbp->dbenv, -"prefix comparison may not be specified for default comparison routine"); - return (EINVAL); - } - - /* - * Verify that the bt_minkey value specified won't cause the - * calculation of ovflsize to underflow [#2406] for this pagesize. - */ - if (B_MINKEY_TO_OVFLSIZE(dbp, t->bt_minkey, dbp->pgsize) > - B_MINKEY_TO_OVFLSIZE(dbp, DEFMINKEYPAGE, dbp->pgsize)) { - __db_err(dbp->dbenv, - "bt_minkey value of %lu too high for page size of %lu", - (u_long)t->bt_minkey, (u_long)dbp->pgsize); - return (EINVAL); - } - - /* Start up the tree. */ - return (__bam_read_root(dbp, txn, base_pgno, flags)); -} - -/* - * __bam_metachk -- - * - * PUBLIC: int __bam_metachk __P((DB *, const char *, BTMETA *)); - */ -int -__bam_metachk(dbp, name, btm) - DB *dbp; - const char *name; - BTMETA *btm; -{ - DB_ENV *dbenv; - u_int32_t vers; - int ret; - - dbenv = dbp->dbenv; - - /* - * At this point, all we know is that the magic number is for a Btree. - * Check the version, the database may be out of date. - */ - vers = btm->dbmeta.version; - if (F_ISSET(dbp, DB_AM_SWAP)) - M_32_SWAP(vers); - switch (vers) { - case 6: - case 7: - __db_err(dbenv, - "%s: btree version %lu requires a version upgrade", - name, (u_long)vers); - return (DB_OLD_VERSION); - case 8: - case 9: - break; - default: - __db_err(dbenv, - "%s: unsupported btree version: %lu", name, (u_long)vers); - return (EINVAL); - } - - /* Swap the page if we need to. */ - if (F_ISSET(dbp, DB_AM_SWAP) && (ret = __bam_mswap((PAGE *)btm)) != 0) - return (ret); - - /* - * Check application info against metadata info, and set info, flags, - * and type based on metadata info. - */ - if ((ret = - __db_fchk(dbenv, "DB->open", btm->dbmeta.flags, BTM_MASK)) != 0) - return (ret); - - if (F_ISSET(&btm->dbmeta, BTM_RECNO)) { - if (dbp->type == DB_BTREE) - goto wrong_type; - dbp->type = DB_RECNO; - DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO); - } else { - if (dbp->type == DB_RECNO) - goto wrong_type; - dbp->type = DB_BTREE; - DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE); - } - - if (F_ISSET(&btm->dbmeta, BTM_DUP)) - F_SET(dbp, DB_AM_DUP); - else - if (F_ISSET(dbp, DB_AM_DUP)) { - __db_err(dbenv, - "%s: DB_DUP specified to open method but not set in database", - name); - return (EINVAL); - } - - if (F_ISSET(&btm->dbmeta, BTM_RECNUM)) { - if (dbp->type != DB_BTREE) - goto wrong_type; - F_SET(dbp, DB_AM_RECNUM); - - if ((ret = __db_fcchk(dbenv, - "DB->open", dbp->flags, DB_AM_DUP, DB_AM_RECNUM)) != 0) - return (ret); - } else - if (F_ISSET(dbp, DB_AM_RECNUM)) { - __db_err(dbenv, - "%s: DB_RECNUM specified to open method but not set in database", - name); - return (EINVAL); - } - - if (F_ISSET(&btm->dbmeta, BTM_FIXEDLEN)) { - if (dbp->type != DB_RECNO) - goto wrong_type; - F_SET(dbp, DB_AM_FIXEDLEN); - } else - if (F_ISSET(dbp, DB_AM_FIXEDLEN)) { - __db_err(dbenv, - "%s: DB_FIXEDLEN specified to open method but not set in database", - name); - return (EINVAL); - } - - if (F_ISSET(&btm->dbmeta, BTM_RENUMBER)) { - if (dbp->type != DB_RECNO) - goto wrong_type; - F_SET(dbp, DB_AM_RENUMBER); - } else - if (F_ISSET(dbp, DB_AM_RENUMBER)) { - __db_err(dbenv, - "%s: DB_RENUMBER specified to open method but not set in database", - name); - return (EINVAL); - } - - if (F_ISSET(&btm->dbmeta, BTM_SUBDB)) - F_SET(dbp, DB_AM_SUBDB); - else - if (F_ISSET(dbp, DB_AM_SUBDB)) { - __db_err(dbenv, - "%s: multiple databases specified but not supported by file", - name); - return (EINVAL); - } - - if (F_ISSET(&btm->dbmeta, BTM_DUPSORT)) { - if (dbp->dup_compare == NULL) - dbp->dup_compare = __bam_defcmp; - F_SET(dbp, DB_AM_DUPSORT); - } else - if (dbp->dup_compare != NULL) { - __db_err(dbenv, - "%s: duplicate sort specified but not supported in database", - name); - return (EINVAL); - } - - /* Set the page size. */ - dbp->pgsize = btm->dbmeta.pagesize; - - /* Copy the file's ID. */ - memcpy(dbp->fileid, btm->dbmeta.uid, DB_FILE_ID_LEN); - - return (0); - -wrong_type: - if (dbp->type == DB_BTREE) - __db_err(dbenv, - "open method type is Btree, database type is Recno"); - else - __db_err(dbenv, - "open method type is Recno, database type is Btree"); - return (EINVAL); -} - -/* - * __bam_read_root -- - * Read the root page and check a tree. - * - * PUBLIC: int __bam_read_root __P((DB *, DB_TXN *, db_pgno_t, u_int32_t)); - */ -int -__bam_read_root(dbp, txn, base_pgno, flags) - DB *dbp; - DB_TXN *txn; - db_pgno_t base_pgno; - u_int32_t flags; -{ - BTMETA *meta; - BTREE *t; - DBC *dbc; - DB_LOCK metalock; - DB_MPOOLFILE *mpf; - int ret, t_ret; - - COMPQUIET(flags, 0); - meta = NULL; - t = dbp->bt_internal; - LOCK_INIT(metalock); - mpf = dbp->mpf; - ret = 0; - - /* Get a cursor. */ - if ((ret = __db_cursor(dbp, txn, &dbc, 0)) != 0) - return (ret); - - /* Get the metadata page. */ - if ((ret = - __db_lget(dbc, 0, base_pgno, DB_LOCK_READ, 0, &metalock)) != 0) - goto err; - if ((ret = __memp_fget(mpf, &base_pgno, 0, &meta)) != 0) - goto err; - - /* - * If the magic number is set, the tree has been created. Correct - * any fields that may not be right. Note, all of the local flags - * were set by DB->open. - * - * Otherwise, we'd better be in recovery or abort, in which case the - * metadata page will be created/initialized elsewhere. - */ - if (meta->dbmeta.magic == DB_BTREEMAGIC) { - t->bt_minkey = meta->minkey; - t->re_pad = (int)meta->re_pad; - t->re_len = meta->re_len; - - t->bt_meta = base_pgno; - t->bt_root = meta->root; - } else { - DB_ASSERT(IS_RECOVERING(dbp->dbenv) || - F_ISSET(dbp, DB_AM_RECOVER)); - } - - /* - * !!! - * If creating a subdatabase, we've already done an insert when - * we put the subdatabase's entry into the master database, so - * our last-page-inserted value is wrongly initialized for the - * master database, not the subdatabase we're creating. I'm not - * sure where the *right* place to clear this value is, it's not - * intuitively obvious that it belongs here. - */ - t->bt_lpgno = PGNO_INVALID; - -err: /* Put the metadata page back. */ - if (meta != NULL && - (t_ret = __memp_fput(mpf, meta, 0)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0) - ret = t_ret; - - if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0) - ret = t_ret; - return (ret); -} - -/* - * __bam_init_meta -- - * - * Initialize a btree meta-data page. The following fields may need - * to be updated later: last_pgno, root. - */ -static void -__bam_init_meta(dbp, meta, pgno, lsnp) - DB *dbp; - BTMETA *meta; - db_pgno_t pgno; - DB_LSN *lsnp; -{ - BTREE *t; - - memset(meta, 0, sizeof(BTMETA)); - meta->dbmeta.lsn = *lsnp; - meta->dbmeta.pgno = pgno; - meta->dbmeta.magic = DB_BTREEMAGIC; - meta->dbmeta.version = DB_BTREEVERSION; - meta->dbmeta.pagesize = dbp->pgsize; - if (F_ISSET(dbp, DB_AM_CHKSUM)) - FLD_SET(meta->dbmeta.metaflags, DBMETA_CHKSUM); - if (F_ISSET(dbp, DB_AM_ENCRYPT)) { - meta->dbmeta.encrypt_alg = - ((DB_CIPHER *)dbp->dbenv->crypto_handle)->alg; - DB_ASSERT(meta->dbmeta.encrypt_alg != 0); - meta->crypto_magic = meta->dbmeta.magic; - } - meta->dbmeta.type = P_BTREEMETA; - meta->dbmeta.free = PGNO_INVALID; - meta->dbmeta.last_pgno = pgno; - if (F_ISSET(dbp, DB_AM_DUP)) - F_SET(&meta->dbmeta, BTM_DUP); - if (F_ISSET(dbp, DB_AM_FIXEDLEN)) - F_SET(&meta->dbmeta, BTM_FIXEDLEN); - if (F_ISSET(dbp, DB_AM_RECNUM)) - F_SET(&meta->dbmeta, BTM_RECNUM); - if (F_ISSET(dbp, DB_AM_RENUMBER)) - F_SET(&meta->dbmeta, BTM_RENUMBER); - if (F_ISSET(dbp, DB_AM_SUBDB)) - F_SET(&meta->dbmeta, BTM_SUBDB); - if (dbp->dup_compare != NULL) - F_SET(&meta->dbmeta, BTM_DUPSORT); - if (dbp->type == DB_RECNO) - F_SET(&meta->dbmeta, BTM_RECNO); - memcpy(meta->dbmeta.uid, dbp->fileid, DB_FILE_ID_LEN); - - t = dbp->bt_internal; - meta->minkey = t->bt_minkey; - meta->re_len = t->re_len; - meta->re_pad = (u_int32_t)t->re_pad; -} - -/* - * __bam_new_file -- - * Create the necessary pages to begin a new database file. - * - * This code appears more complex than it is because of the two cases (named - * and unnamed). The way to read the code is that for each page being created, - * there are three parts: 1) a "get page" chunk (which either uses malloc'd - * memory or calls __memp_fget), 2) the initialization, and 3) the "put page" - * chunk which either does a fop write or an __memp_fput. - * - * PUBLIC: int __bam_new_file __P((DB *, DB_TXN *, DB_FH *, const char *)); - */ -int -__bam_new_file(dbp, txn, fhp, name) - DB *dbp; - DB_TXN *txn; - DB_FH *fhp; - const char *name; -{ - BTMETA *meta; - DB_ENV *dbenv; - DB_LSN lsn; - DB_MPOOLFILE *mpf; - DB_PGINFO pginfo; - DBT pdbt; - PAGE *root; - db_pgno_t pgno; - int ret, t_ret; - void *buf; - - dbenv = dbp->dbenv; - mpf = dbp->mpf; - root = NULL; - meta = NULL; - buf = NULL; - - if (F_ISSET(dbp, DB_AM_INMEM)) { - /* Build the meta-data page. */ - pgno = PGNO_BASE_MD; - if ((ret = - __memp_fget(mpf, &pgno, DB_MPOOL_CREATE, &meta)) != 0) - return (ret); - LSN_NOT_LOGGED(lsn); - __bam_init_meta(dbp, meta, PGNO_BASE_MD, &lsn); - meta->root = 1; - meta->dbmeta.last_pgno = 1; - if ((ret = - __db_log_page(dbp, txn, &lsn, pgno, (PAGE *)meta)) != 0) - goto err; - ret = __memp_fput(mpf, meta, DB_MPOOL_DIRTY); - meta = NULL; - if (ret != 0) - goto err; - - /* Build the root page. */ - pgno = 1; - if ((ret = - __memp_fget(mpf, &pgno, DB_MPOOL_CREATE, &root)) != 0) - goto err; - P_INIT(root, dbp->pgsize, 1, PGNO_INVALID, PGNO_INVALID, - LEAFLEVEL, dbp->type == DB_RECNO ? P_LRECNO : P_LBTREE); - LSN_NOT_LOGGED(root->lsn); - if ((ret = - __db_log_page(dbp, txn, &root->lsn, pgno, root)) != 0) - goto err; - ret = __memp_fput(mpf, root, DB_MPOOL_DIRTY); - root = NULL; - if (ret != 0) - goto err; - } else { - memset(&pdbt, 0, sizeof(pdbt)); - - /* Build the meta-data page. */ - pginfo.db_pagesize = dbp->pgsize; - pginfo.flags = - F_ISSET(dbp, (DB_AM_CHKSUM | DB_AM_ENCRYPT | DB_AM_SWAP)); - pginfo.type = dbp->type; - pdbt.data = &pginfo; - pdbt.size = sizeof(pginfo); - if ((ret = __os_calloc(dbenv, 1, dbp->pgsize, &buf)) != 0) - return (ret); - meta = (BTMETA *)buf; - LSN_NOT_LOGGED(lsn); - __bam_init_meta(dbp, meta, PGNO_BASE_MD, &lsn); - meta->root = 1; - meta->dbmeta.last_pgno = 1; - if ((ret = __db_pgout(dbenv, PGNO_BASE_MD, meta, &pdbt)) != 0) - goto err; - if ((ret = __fop_write(dbenv, txn, name, DB_APP_DATA, fhp, - dbp->pgsize, 0, 0, buf, dbp->pgsize, 1, F_ISSET( - dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0)) != 0) - goto err; - meta = NULL; - - /* Build the root page. */ -#ifdef DIAGNOSTIC - memset(buf, CLEAR_BYTE, dbp->pgsize); -#endif - root = (PAGE *)buf; - P_INIT(root, dbp->pgsize, 1, PGNO_INVALID, PGNO_INVALID, - LEAFLEVEL, dbp->type == DB_RECNO ? P_LRECNO : P_LBTREE); - LSN_NOT_LOGGED(root->lsn); - if ((ret = __db_pgout(dbenv, root->pgno, root, &pdbt)) != 0) - goto err; - if ((ret = __fop_write(dbenv, txn, name, DB_APP_DATA, fhp, - dbp->pgsize, 1, 0, buf, dbp->pgsize, 1, F_ISSET( - dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0)) != 0) - goto err; - root = NULL; - } - -err: if (buf != NULL) - __os_free(dbenv, buf); - else { - if (meta != NULL && - (t_ret = __memp_fput(mpf, meta, 0)) != 0 && ret == 0) - ret = t_ret; - if (root != NULL && - (t_ret = __memp_fput(mpf, root, 0)) != 0 && ret == 0) - ret = t_ret; - } - return (ret); -} - -/* - * __bam_new_subdb -- - * Create a metadata page and a root page for a new btree. - * - * PUBLIC: int __bam_new_subdb __P((DB *, DB *, DB_TXN *)); - */ -int -__bam_new_subdb(mdbp, dbp, txn) - DB *mdbp, *dbp; - DB_TXN *txn; -{ - BTMETA *meta; - DBC *dbc; - DB_ENV *dbenv; - DB_LOCK metalock; - DB_LSN lsn; - DB_MPOOLFILE *mpf; - PAGE *root; - int ret, t_ret; - - dbenv = mdbp->dbenv; - mpf = mdbp->mpf; - dbc = NULL; - meta = NULL; - root = NULL; - - if ((ret = __db_cursor(mdbp, txn, - &dbc, CDB_LOCKING(dbenv) ? DB_WRITECURSOR : 0)) != 0) - return (ret); - - /* Get, and optionally create the metadata page. */ - if ((ret = __db_lget(dbc, - 0, dbp->meta_pgno, DB_LOCK_WRITE, 0, &metalock)) != 0) - goto err; - if ((ret = - __memp_fget(mpf, &dbp->meta_pgno, DB_MPOOL_CREATE, &meta)) != 0) - goto err; - - /* Build meta-data page. */ - lsn = meta->dbmeta.lsn; - __bam_init_meta(dbp, meta, dbp->meta_pgno, &lsn); - if ((ret = __db_log_page(mdbp, - txn, &meta->dbmeta.lsn, dbp->meta_pgno, (PAGE *)meta)) != 0) - goto err; - - /* Create and initialize a root page. */ - if ((ret = __db_new(dbc, - dbp->type == DB_RECNO ? P_LRECNO : P_LBTREE, &root)) != 0) - goto err; - root->level = LEAFLEVEL; - - if (DBENV_LOGGING(dbenv) && - (ret = __bam_root_log(mdbp, txn, &meta->dbmeta.lsn, 0, - meta->dbmeta.pgno, root->pgno, &meta->dbmeta.lsn)) != 0) - goto err; - - meta->root = root->pgno; - if ((ret = - __db_log_page(mdbp, txn, &root->lsn, root->pgno, root)) != 0) - goto err; - - /* Release the metadata and root pages. */ - if ((ret = __memp_fput(mpf, meta, DB_MPOOL_DIRTY)) != 0) - goto err; - meta = NULL; - if ((ret = __memp_fput(mpf, root, DB_MPOOL_DIRTY)) != 0) - goto err; - root = NULL; -err: - if (meta != NULL) - if ((t_ret = __memp_fput(mpf, meta, 0)) != 0 && ret == 0) - ret = t_ret; - if (root != NULL) - if ((t_ret = __memp_fput(mpf, root, 0)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0) - ret = t_ret; - if (dbc != NULL) - if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0) - ret = t_ret; - return (ret); -} diff --git a/storage/bdb/btree/bt_put.c b/storage/bdb/btree/bt_put.c deleted file mode 100644 index dd56f9d3523..00000000000 --- a/storage/bdb/btree/bt_put.c +++ /dev/null @@ -1,912 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994, 1995, 1996 - * Keith Bostic. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994, 1995 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Mike Olson. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: bt_put.c,v 12.10 2005/10/20 18:57:00 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/btree.h" -#include "dbinc/mp.h" - -static int __bam_build - __P((DBC *, u_int32_t, DBT *, PAGE *, u_int32_t, u_int32_t)); -static int __bam_dup_check __P((DBC *, u_int32_t, - PAGE *, u_int32_t, u_int32_t, db_indx_t *)); -static int __bam_dup_convert __P((DBC *, PAGE *, u_int32_t, u_int32_t)); -static int __bam_ovput - __P((DBC *, u_int32_t, db_pgno_t, PAGE *, u_int32_t, DBT *)); -static u_int32_t - __bam_partsize __P((DB *, u_int32_t, DBT *, PAGE *, u_int32_t)); - -/* - * __bam_iitem -- - * Insert an item into the tree. - * - * PUBLIC: int __bam_iitem __P((DBC *, DBT *, DBT *, u_int32_t, u_int32_t)); - */ -int -__bam_iitem(dbc, key, data, op, flags) - DBC *dbc; - DBT *key, *data; - u_int32_t op, flags; -{ - DB_ENV *dbenv; - BKEYDATA *bk, bk_tmp; - BTREE *t; - BTREE_CURSOR *cp; - DB *dbp; - DBT bk_hdr, tdbt; - DB_MPOOLFILE *mpf; - PAGE *h; - db_indx_t cnt, indx; - u_int32_t data_size, have_bytes, need_bytes, needed, pages, pagespace; - int cmp, bigkey, bigdata, dupadjust, padrec, replace, ret, was_deleted; - - COMPQUIET(bk, NULL); - COMPQUIET(cnt, 0); - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - mpf = dbp->mpf; - cp = (BTREE_CURSOR *)dbc->internal; - t = dbp->bt_internal; - h = cp->page; - indx = cp->indx; - dupadjust = replace = was_deleted = 0; - - /* - * Fixed-length records with partial puts: it's an error to specify - * anything other simple overwrite. - */ - if (F_ISSET(dbp, DB_AM_FIXEDLEN) && - F_ISSET(data, DB_DBT_PARTIAL) && data->size != data->dlen) - return (__db_rec_repl(dbenv, data->size, data->dlen)); - - /* - * Figure out how much space the data will take, including if it's a - * partial record. - * - * Fixed-length records: it's an error to specify a record that's - * longer than the fixed-length, and we never require less than - * the fixed-length record size. - */ - data_size = F_ISSET(data, DB_DBT_PARTIAL) ? - __bam_partsize(dbp, op, data, h, indx) : data->size; - padrec = 0; - if (F_ISSET(dbp, DB_AM_FIXEDLEN)) { - if (data_size > t->re_len) - return (__db_rec_toobig(dbenv, data_size, t->re_len)); - - /* Records that are deleted anyway needn't be padded out. */ - if (!LF_ISSET(BI_DELETED) && data_size < t->re_len) { - padrec = 1; - data_size = t->re_len; - } - } - - /* - * Handle partial puts or short fixed-length records: build the - * real record. - */ - if (padrec || F_ISSET(data, DB_DBT_PARTIAL)) { - tdbt = *data; - if ((ret = - __bam_build(dbc, op, &tdbt, h, indx, data_size)) != 0) - return (ret); - data = &tdbt; - } - - /* - * If the user has specified a duplicate comparison function, return - * an error if DB_CURRENT was specified and the replacement data - * doesn't compare equal to the current data. This stops apps from - * screwing up the duplicate sort order. We have to do this after - * we build the real record so that we're comparing the real items. - */ - if (op == DB_CURRENT && dbp->dup_compare != NULL) { - if ((ret = __bam_cmp(dbp, data, h, - indx + (TYPE(h) == P_LBTREE ? O_INDX : 0), - dbp->dup_compare, &cmp)) != 0) - return (ret); - if (cmp != 0) { - __db_err(dbenv, - "Existing data sorts differently from put data"); - return (EINVAL); - } - } - - /* - * If the key or data item won't fit on a page, we'll have to store - * them on overflow pages. - */ - needed = 0; - bigdata = data_size > cp->ovflsize; - switch (op) { - case DB_KEYFIRST: - /* We're adding a new key and data pair. */ - bigkey = key->size > cp->ovflsize; - if (bigkey) - needed += BOVERFLOW_PSIZE; - else - needed += BKEYDATA_PSIZE(key->size); - if (bigdata) - needed += BOVERFLOW_PSIZE; - else - needed += BKEYDATA_PSIZE(data_size); - break; - case DB_AFTER: - case DB_BEFORE: - case DB_CURRENT: - /* - * We're either overwriting the data item of a key/data pair - * or we're creating a new on-page duplicate and only adding - * a data item. - * - * !!! - * We're not currently correcting for space reclaimed from - * already deleted items, but I don't think it's worth the - * complexity. - */ - bigkey = 0; - if (op == DB_CURRENT) { - bk = GET_BKEYDATA(dbp, h, - indx + (TYPE(h) == P_LBTREE ? O_INDX : 0)); - if (B_TYPE(bk->type) == B_KEYDATA) - have_bytes = BKEYDATA_PSIZE(bk->len); - else - have_bytes = BOVERFLOW_PSIZE; - need_bytes = 0; - } else { - have_bytes = 0; - need_bytes = sizeof(db_indx_t); - } - if (bigdata) - need_bytes += BOVERFLOW_PSIZE; - else - need_bytes += BKEYDATA_PSIZE(data_size); - - if (have_bytes < need_bytes) - needed += need_bytes - have_bytes; - break; - default: - return (__db_unknown_flag(dbenv, "DB->put", op)); - } - - /* Split the page if there's not enough room. */ - if (P_FREESPACE(dbp, h) < needed) - return (DB_NEEDSPLIT); - - /* - * Check to see if we will convert to off page duplicates -- if - * so, we'll need a page. - */ - if (F_ISSET(dbp, DB_AM_DUP) && - TYPE(h) == P_LBTREE && op != DB_KEYFIRST && - P_FREESPACE(dbp, h) - needed <= dbp->pgsize / 2 && - __bam_dup_check(dbc, op, h, indx, needed, &cnt)) { - pages = 1; - dupadjust = 1; - } else - pages = 0; - - /* - * If we are not using transactions and there is a page limit - * set on the file, then figure out if things will fit before - * taking action. - */ - if (dbc->txn == NULL && dbp->mpf->mfp->maxpgno != 0) { - pagespace = P_MAXSPACE(dbp, dbp->pgsize); - if (bigdata) - pages += ((data_size - 1) / pagespace) + 1; - if (bigkey) - pages += ((key->size - 1) / pagespace) + 1; - - if (pages > (dbp->mpf->mfp->maxpgno - dbp->mpf->mfp->last_pgno)) - return (__db_space_err(dbp)); - } - - /* - * The code breaks it up into five cases: - * - * 1. Insert a new key/data pair. - * 2. Append a new data item (a new duplicate). - * 3. Insert a new data item (a new duplicate). - * 4. Delete and re-add the data item (overflow item). - * 5. Overwrite the data item. - */ - switch (op) { - case DB_KEYFIRST: /* 1. Insert a new key/data pair. */ - if (bigkey) { - if ((ret = __bam_ovput(dbc, - B_OVERFLOW, PGNO_INVALID, h, indx, key)) != 0) - return (ret); - } else - if ((ret = __db_pitem(dbc, h, indx, - BKEYDATA_SIZE(key->size), NULL, key)) != 0) - return (ret); - - if ((ret = __bam_ca_di(dbc, PGNO(h), indx, 1)) != 0) - return (ret); - ++indx; - break; - case DB_AFTER: /* 2. Append a new data item. */ - if (TYPE(h) == P_LBTREE) { - /* Copy the key for the duplicate and adjust cursors. */ - if ((ret = - __bam_adjindx(dbc, h, indx + P_INDX, indx, 1)) != 0) - return (ret); - if ((ret = - __bam_ca_di(dbc, PGNO(h), indx + P_INDX, 1)) != 0) - return (ret); - - indx += 3; - - cp->indx += 2; - } else { - ++indx; - cp->indx += 1; - } - break; - case DB_BEFORE: /* 3. Insert a new data item. */ - if (TYPE(h) == P_LBTREE) { - /* Copy the key for the duplicate and adjust cursors. */ - if ((ret = __bam_adjindx(dbc, h, indx, indx, 1)) != 0) - return (ret); - if ((ret = __bam_ca_di(dbc, PGNO(h), indx, 1)) != 0) - return (ret); - - ++indx; - } - break; - case DB_CURRENT: - /* - * Clear the cursor's deleted flag. The problem is that if - * we deadlock or fail while deleting the overflow item or - * replacing the non-overflow item, a subsequent cursor close - * will try and remove the item because the cursor's delete - * flag is set. - */ - if ((ret = __bam_ca_delete(dbp, PGNO(h), indx, 0, NULL)) != 0) - return (ret); - - if (TYPE(h) == P_LBTREE) { - ++indx; - } - - /* - * In a Btree deleted records aren't counted (deleted records - * are counted in a Recno because all accesses are based on - * record number). If it's a Btree and it's a DB_CURRENT - * operation overwriting a previously deleted record, increment - * the record count. - */ - if (TYPE(h) == P_LBTREE || TYPE(h) == P_LDUP) - was_deleted = B_DISSET(bk->type); - - /* - * 4. Delete and re-add the data item. - * - * If we're changing the type of the on-page structure, or we - * are referencing offpage items, we have to delete and then - * re-add the item. We do not do any cursor adjustments here - * because we're going to immediately re-add the item into the - * same slot. - */ - if (bigdata || B_TYPE(bk->type) != B_KEYDATA) { - if ((ret = __bam_ditem(dbc, h, indx)) != 0) - return (ret); - break; - } - - /* 5. Overwrite the data item. */ - replace = 1; - break; - default: - return (__db_unknown_flag(dbenv, "DB->put", op)); - } - - /* Add the data. */ - if (bigdata) { - /* - * We do not have to handle deleted (BI_DELETED) records - * in this case; the actual records should never be created. - */ - DB_ASSERT(!LF_ISSET(BI_DELETED)); - if ((ret = __bam_ovput(dbc, - B_OVERFLOW, PGNO_INVALID, h, indx, data)) != 0) - return (ret); - } else { - if (LF_ISSET(BI_DELETED)) { - B_TSET(bk_tmp.type, B_KEYDATA, 1); - bk_tmp.len = data->size; - bk_hdr.data = &bk_tmp; - bk_hdr.size = SSZA(BKEYDATA, data); - ret = __db_pitem(dbc, h, indx, - BKEYDATA_SIZE(data->size), &bk_hdr, data); - } else if (replace) - ret = __bam_ritem(dbc, h, indx, data); - else - ret = __db_pitem(dbc, h, indx, - BKEYDATA_SIZE(data->size), NULL, data); - if (ret != 0) - return (ret); - } - if ((ret = __memp_fset(mpf, h, DB_MPOOL_DIRTY)) != 0) - return (ret); - - /* - * Re-position the cursors if necessary and reset the current cursor - * to point to the new item. - */ - if (op != DB_CURRENT) { - if ((ret = __bam_ca_di(dbc, PGNO(h), indx, 1)) != 0) - return (ret); - cp->indx = TYPE(h) == P_LBTREE ? indx - O_INDX : indx; - } - - /* - * If we've changed the record count, update the tree. There's no - * need to adjust the count if the operation not performed on the - * current record or when the current record was previously deleted. - */ - if (F_ISSET(cp, C_RECNUM) && (op != DB_CURRENT || was_deleted)) - if ((ret = __bam_adjust(dbc, 1)) != 0) - return (ret); - - /* - * If a Btree leaf page is at least 50% full and we may have added or - * modified a duplicate data item, see if the set of duplicates takes - * up at least 25% of the space on the page. If it does, move it onto - * its own page. - */ - if (dupadjust && - (ret = __bam_dup_convert(dbc, h, indx - O_INDX, cnt)) != 0) - return (ret); - - /* If we've modified a recno file, set the flag. */ - if (dbc->dbtype == DB_RECNO) - t->re_modified = 1; - - return (ret); -} - -/* - * __bam_partsize -- - * Figure out how much space a partial data item is in total. - */ -static u_int32_t -__bam_partsize(dbp, op, data, h, indx) - DB *dbp; - u_int32_t op, indx; - DBT *data; - PAGE *h; -{ - BKEYDATA *bk; - u_int32_t nbytes; - - /* - * If the record doesn't already exist, it's simply the data we're - * provided. - */ - if (op != DB_CURRENT) - return (data->doff + data->size); - - /* - * Otherwise, it's the data provided plus any already existing data - * that we're not replacing. - */ - bk = GET_BKEYDATA(dbp, h, indx + (TYPE(h) == P_LBTREE ? O_INDX : 0)); - nbytes = - B_TYPE(bk->type) == B_OVERFLOW ? ((BOVERFLOW *)bk)->tlen : bk->len; - - return (__db_partsize(nbytes, data)); -} - -/* - * __bam_build -- - * Build the real record for a partial put, or short fixed-length record. - */ -static int -__bam_build(dbc, op, dbt, h, indx, nbytes) - DBC *dbc; - u_int32_t op, indx, nbytes; - DBT *dbt; - PAGE *h; -{ - BKEYDATA *bk, tbk; - BOVERFLOW *bo; - BTREE *t; - DB *dbp; - DBT copy, *rdata; - u_int32_t len, tlen; - u_int8_t *p; - int ret; - - COMPQUIET(bo, NULL); - - dbp = dbc->dbp; - t = dbp->bt_internal; - - /* We use the record data return memory, it's only a short-term use. */ - rdata = &dbc->my_rdata; - if (rdata->ulen < nbytes) { - if ((ret = __os_realloc(dbp->dbenv, - nbytes, &rdata->data)) != 0) { - rdata->ulen = 0; - rdata->data = NULL; - return (ret); - } - rdata->ulen = nbytes; - } - - /* - * We use nul or pad bytes for any part of the record that isn't - * specified; get it over with. - */ - memset(rdata->data, - F_ISSET(dbp, DB_AM_FIXEDLEN) ? t->re_pad : 0, nbytes); - - /* - * In the next clauses, we need to do three things: a) set p to point - * to the place at which to copy the user's data, b) set tlen to the - * total length of the record, not including the bytes contributed by - * the user, and c) copy any valid data from an existing record. If - * it's not a partial put (this code is called for both partial puts - * and fixed-length record padding) or it's a new key, we can cut to - * the chase. - */ - if (!F_ISSET(dbt, DB_DBT_PARTIAL) || op != DB_CURRENT) { - p = (u_int8_t *)rdata->data + dbt->doff; - tlen = dbt->doff; - goto user_copy; - } - - /* Find the current record. */ - if (indx < NUM_ENT(h)) { - bk = GET_BKEYDATA(dbp, h, indx + (TYPE(h) == P_LBTREE ? - O_INDX : 0)); - bo = (BOVERFLOW *)bk; - } else { - bk = &tbk; - B_TSET(bk->type, B_KEYDATA, 0); - bk->len = 0; - } - if (B_TYPE(bk->type) == B_OVERFLOW) { - /* - * In the case of an overflow record, we shift things around - * in the current record rather than allocate a separate copy. - */ - memset(©, 0, sizeof(copy)); - if ((ret = __db_goff(dbp, ©, bo->tlen, - bo->pgno, &rdata->data, &rdata->ulen)) != 0) - return (ret); - - /* Skip any leading data from the original record. */ - tlen = dbt->doff; - p = (u_int8_t *)rdata->data + dbt->doff; - - /* - * Copy in any trailing data from the original record. - * - * If the original record was larger than the original offset - * plus the bytes being deleted, there is trailing data in the - * original record we need to preserve. If we aren't deleting - * the same number of bytes as we're inserting, copy it up or - * down, into place. - * - * Use memmove(), the regions may overlap. - */ - if (bo->tlen > dbt->doff + dbt->dlen) { - len = bo->tlen - (dbt->doff + dbt->dlen); - if (dbt->dlen != dbt->size) - memmove(p + dbt->size, p + dbt->dlen, len); - tlen += len; - } - } else { - /* Copy in any leading data from the original record. */ - memcpy(rdata->data, - bk->data, dbt->doff > bk->len ? bk->len : dbt->doff); - tlen = dbt->doff; - p = (u_int8_t *)rdata->data + dbt->doff; - - /* Copy in any trailing data from the original record. */ - len = dbt->doff + dbt->dlen; - if (bk->len > len) { - memcpy(p + dbt->size, bk->data + len, bk->len - len); - tlen += bk->len - len; - } - } - -user_copy: - /* - * Copy in the application provided data -- p and tlen must have been - * initialized above. - */ - memcpy(p, dbt->data, dbt->size); - tlen += dbt->size; - - /* Set the DBT to reference our new record. */ - rdata->size = F_ISSET(dbp, DB_AM_FIXEDLEN) ? t->re_len : tlen; - rdata->dlen = 0; - rdata->doff = 0; - rdata->flags = 0; - *dbt = *rdata; - return (0); -} - -/* - * __bam_ritem -- - * Replace an item on a page. - * - * PUBLIC: int __bam_ritem __P((DBC *, PAGE *, u_int32_t, DBT *)); - */ -int -__bam_ritem(dbc, h, indx, data) - DBC *dbc; - PAGE *h; - u_int32_t indx; - DBT *data; -{ - BKEYDATA *bk; - DB *dbp; - DBT orig, repl; - db_indx_t cnt, lo, ln, min, off, prefix, suffix; - int32_t nbytes; - int ret; - db_indx_t *inp; - u_int8_t *p, *t; - - dbp = dbc->dbp; - - /* - * Replace a single item onto a page. The logic figuring out where - * to insert and whether it fits is handled in the caller. All we do - * here is manage the page shuffling. - */ - bk = GET_BKEYDATA(dbp, h, indx); - - /* Log the change. */ - if (DBC_LOGGING(dbc)) { - /* - * We might as well check to see if the two data items share - * a common prefix and suffix -- it can save us a lot of log - * message if they're large. - */ - min = data->size < bk->len ? data->size : bk->len; - for (prefix = 0, - p = bk->data, t = data->data; - prefix < min && *p == *t; ++prefix, ++p, ++t) - ; - - min -= prefix; - for (suffix = 0, - p = (u_int8_t *)bk->data + bk->len - 1, - t = (u_int8_t *)data->data + data->size - 1; - suffix < min && *p == *t; ++suffix, --p, --t) - ; - - /* We only log the parts of the keys that have changed. */ - orig.data = (u_int8_t *)bk->data + prefix; - orig.size = bk->len - (prefix + suffix); - repl.data = (u_int8_t *)data->data + prefix; - repl.size = data->size - (prefix + suffix); - if ((ret = __bam_repl_log(dbp, dbc->txn, &LSN(h), 0, PGNO(h), - &LSN(h), (u_int32_t)indx, (u_int32_t)B_DISSET(bk->type), - &orig, &repl, (u_int32_t)prefix, (u_int32_t)suffix)) != 0) - return (ret); - } else - LSN_NOT_LOGGED(LSN(h)); - - /* - * Set references to the first in-use byte on the page and the - * first byte of the item being replaced. - */ - inp = P_INP(dbp, h); - p = (u_int8_t *)h + HOFFSET(h); - t = (u_int8_t *)bk; - - /* - * If the entry is growing in size, shift the beginning of the data - * part of the page down. If the entry is shrinking in size, shift - * the beginning of the data part of the page up. Use memmove(3), - * the regions overlap. - */ - lo = BKEYDATA_SIZE(bk->len); - ln = (db_indx_t)BKEYDATA_SIZE(data->size); - if (lo != ln) { - nbytes = lo - ln; /* Signed difference. */ - if (p == t) /* First index is fast. */ - inp[indx] += nbytes; - else { /* Else, shift the page. */ - memmove(p + nbytes, p, (size_t)(t - p)); - - /* Adjust the indices' offsets. */ - off = inp[indx]; - for (cnt = 0; cnt < NUM_ENT(h); ++cnt) - if (inp[cnt] <= off) - inp[cnt] += nbytes; - } - - /* Clean up the page and adjust the item's reference. */ - HOFFSET(h) += nbytes; - t += nbytes; - } - - /* Copy the new item onto the page. */ - bk = (BKEYDATA *)t; - B_TSET(bk->type, B_KEYDATA, 0); - bk->len = data->size; - memcpy(bk->data, data->data, data->size); - - return (0); -} - -/* - * __bam_dup_check -- - * Check to see if the duplicate set at indx should have its own page. - */ -static int -__bam_dup_check(dbc, op, h, indx, sz, cntp) - DBC *dbc; - u_int32_t op; - PAGE *h; - u_int32_t indx, sz; - db_indx_t *cntp; -{ - BKEYDATA *bk; - DB *dbp; - db_indx_t cnt, first, *inp; - - dbp = dbc->dbp; - inp = P_INP(dbp, h); - - /* - * Count the duplicate records and calculate how much room they're - * using on the page. - */ - while (indx > 0 && inp[indx] == inp[indx - P_INDX]) - indx -= P_INDX; - - /* Count the key once. */ - bk = GET_BKEYDATA(dbp, h, indx); - sz += B_TYPE(bk->type) == B_KEYDATA ? - BKEYDATA_PSIZE(bk->len) : BOVERFLOW_PSIZE; - - /* Sum up all the data items. */ - first = indx; - - /* - * Account for the record being inserted. If we are replacing it, - * don't count it twice. - * - * We execute the loop with first == indx to get the size of the - * first record. - */ - cnt = op == DB_CURRENT ? 0 : 1; - for (first = indx; - indx < NUM_ENT(h) && inp[first] == inp[indx]; - ++cnt, indx += P_INDX) { - bk = GET_BKEYDATA(dbp, h, indx + O_INDX); - sz += B_TYPE(bk->type) == B_KEYDATA ? - BKEYDATA_PSIZE(bk->len) : BOVERFLOW_PSIZE; - } - - /* - * We have to do these checks when the user is replacing the cursor's - * data item -- if the application replaces a duplicate item with a - * larger data item, it can increase the amount of space used by the - * duplicates, requiring this check. But that means we may have done - * this check when it wasn't a duplicate item after all. - */ - if (cnt == 1) - return (0); - - /* - * If this set of duplicates is using more than 25% of the page, move - * them off. The choice of 25% is a WAG, but the value must be small - * enough that we can always split a page without putting duplicates - * on two different pages. - */ - if (sz < dbp->pgsize / 4) - return (0); - - *cntp = cnt; - return (1); -} - -/* - * __bam_dup_convert -- - * Move a set of duplicates off-page and into their own tree. - */ -static int -__bam_dup_convert(dbc, h, indx, cnt) - DBC *dbc; - PAGE *h; - u_int32_t indx, cnt; -{ - BKEYDATA *bk; - DB *dbp; - DBT hdr; - DB_MPOOLFILE *mpf; - PAGE *dp; - db_indx_t cpindx, dindx, first, *inp; - int ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - inp = P_INP(dbp, h); - - /* Move to the beginning of the dup set. */ - while (indx > 0 && inp[indx] == inp[indx - P_INDX]) - indx -= P_INDX; - - /* Get a new page. */ - if ((ret = __db_new(dbc, - dbp->dup_compare == NULL ? P_LRECNO : P_LDUP, &dp)) != 0) - return (ret); - P_INIT(dp, dbp->pgsize, dp->pgno, - PGNO_INVALID, PGNO_INVALID, LEAFLEVEL, TYPE(dp)); - - /* - * Move this set of duplicates off the page. First points to the first - * key of the first duplicate key/data pair, cnt is the number of pairs - * we're dealing with. - */ - memset(&hdr, 0, sizeof(hdr)); - first = indx; - dindx = indx; - cpindx = 0; - do { - /* Move cursors referencing the old entry to the new entry. */ - if ((ret = __bam_ca_dup(dbc, first, - PGNO(h), indx, PGNO(dp), cpindx)) != 0) - goto err; - - /* - * Copy the entry to the new page. If the off-duplicate page - * If the off-duplicate page is a Btree page (i.e. dup_compare - * will be non-NULL, we use Btree pages for sorted dups, - * and Recno pages for unsorted dups), move all entries - * normally, even deleted ones. If it's a Recno page, - * deleted entries are discarded (if the deleted entry is - * overflow, then free up those pages). - */ - bk = GET_BKEYDATA(dbp, h, dindx + 1); - hdr.data = bk; - hdr.size = B_TYPE(bk->type) == B_KEYDATA ? - BKEYDATA_SIZE(bk->len) : BOVERFLOW_SIZE; - if (dbp->dup_compare == NULL && B_DISSET(bk->type)) { - /* - * Unsorted dups, i.e. recno page, and we have - * a deleted entry, don't move it, but if it was - * an overflow entry, we need to free those pages. - */ - if (B_TYPE(bk->type) == B_OVERFLOW && - (ret = __db_doff(dbc, - (GET_BOVERFLOW(dbp, h, dindx + 1))->pgno)) != 0) - goto err; - } else { - if ((ret = __db_pitem( - dbc, dp, cpindx, hdr.size, &hdr, NULL)) != 0) - goto err; - ++cpindx; - } - /* Delete all but the last reference to the key. */ - if (cnt != 1) { - if ((ret = __bam_adjindx(dbc, - h, dindx, first + 1, 0)) != 0) - goto err; - } else - dindx++; - - /* Delete the data item. */ - if ((ret = __db_ditem(dbc, h, dindx, hdr.size)) != 0) - goto err; - indx += P_INDX; - } while (--cnt); - - /* Put in a new data item that points to the duplicates page. */ - if ((ret = __bam_ovput(dbc, - B_DUPLICATE, dp->pgno, h, first + 1, NULL)) != 0) - goto err; - - /* Adjust cursors for all the above movements. */ - if ((ret = __bam_ca_di(dbc, - PGNO(h), first + P_INDX, (int)(first + P_INDX - indx))) != 0) - goto err; - - return (__memp_fput(mpf, dp, DB_MPOOL_DIRTY)); - -err: (void)__memp_fput(mpf, dp, 0); - return (ret); -} - -/* - * __bam_ovput -- - * Build an item for an off-page duplicates page or overflow page and - * insert it on the page. - */ -static int -__bam_ovput(dbc, type, pgno, h, indx, item) - DBC *dbc; - u_int32_t type, indx; - db_pgno_t pgno; - PAGE *h; - DBT *item; -{ - BOVERFLOW bo; - DBT hdr; - int ret; - - UMRW_SET(bo.unused1); - B_TSET(bo.type, type, 0); - UMRW_SET(bo.unused2); - - /* - * If we're creating an overflow item, do so and acquire the page - * number for it. If we're creating an off-page duplicates tree, - * we are giving the page number as an argument. - */ - if (type == B_OVERFLOW) { - if ((ret = __db_poff(dbc, item, &bo.pgno)) != 0) - return (ret); - bo.tlen = item->size; - } else { - bo.pgno = pgno; - bo.tlen = 0; - } - - /* Store the new record on the page. */ - memset(&hdr, 0, sizeof(hdr)); - hdr.data = &bo; - hdr.size = BOVERFLOW_SIZE; - return (__db_pitem(dbc, h, indx, BOVERFLOW_SIZE, &hdr, NULL)); -} diff --git a/storage/bdb/btree/bt_rec.c b/storage/bdb/btree/bt_rec.c deleted file mode 100644 index 3667ee12c58..00000000000 --- a/storage/bdb/btree/bt_rec.c +++ /dev/null @@ -1,1389 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: bt_rec.c,v 12.11 2005/10/20 18:57:01 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/btree.h" -#include "dbinc/lock.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" - -#define IS_BTREE_PAGE(pagep) \ - (TYPE(pagep) == P_IBTREE || \ - TYPE(pagep) == P_LBTREE || TYPE(pagep) == P_LDUP) - -/* - * __bam_split_recover -- - * Recovery function for split. - * - * PUBLIC: int __bam_split_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__bam_split_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __bam_split_args *argp; - DB *file_dbp; - DBC *dbc; - DB_MPOOLFILE *mpf; - PAGE *_lp, *lp, *np, *pp, *_rp, *rp, *sp; - db_pgno_t pgno, root_pgno; - u_int32_t ptype; - int cmp, l_update, p_update, r_update, rc, ret, rootsplit, t_ret; - - COMPQUIET(info, NULL); - REC_PRINT(__bam_split_print); - - mpf = NULL; - _lp = lp = np = pp = _rp = rp = NULL; - sp = NULL; - - REC_INTRO(__bam_split_read, 1, 0); - - /* - * There are two kinds of splits that we have to recover from. The - * first is a root-page split, where the root page is split from a - * leaf page into an internal page and two new leaf pages are created. - * The second is where a page is split into two pages, and a new key - * is inserted into the parent page. - * - * DBTs are not aligned in log records, so we need to copy the page - * so that we can access fields within it throughout this routine. - * Although we could hardcode the unaligned copies in this routine, - * we will be calling into regular btree functions with this page, - * so it's got to be aligned. Copying it into allocated memory is - * the only way to guarantee this. - */ - if ((ret = __os_malloc(dbenv, argp->pg.size, &sp)) != 0) - goto out; - memcpy(sp, argp->pg.data, argp->pg.size); - - pgno = PGNO(sp); - root_pgno = argp->root_pgno; - rootsplit = root_pgno != PGNO_INVALID; - REC_FGET(mpf, argp->left, &lp, right); -right: REC_FGET(mpf, argp->right, &rp, redo); - -redo: if (DB_REDO(op)) { - l_update = r_update = p_update = 0; - /* - * Decide if we need to resplit the page. - * - * If this is a root split, then the root has to exist unless - * we have truncated it due to a future deallocation. - */ - if (rootsplit) { - REC_FGET(mpf, root_pgno, &pp, do_left); - cmp = - log_compare(&LSN(pp), &LSN(argp->pg.data)); - CHECK_LSN(dbenv, op, - cmp, &LSN(pp), &LSN(argp->pg.data)); - p_update = cmp == 0; - } - -do_left: if (lp != NULL) { - cmp = log_compare(&LSN(lp), &argp->llsn); - CHECK_LSN(dbenv, op, cmp, &LSN(lp), &argp->llsn); - if (cmp == 0) - l_update = 1; - } - - if (rp != NULL) { - cmp = log_compare(&LSN(rp), &argp->rlsn); - CHECK_LSN(dbenv, op, cmp, &LSN(rp), &argp->rlsn); - if (cmp == 0) - r_update = 1; - } - - if (!p_update && !l_update && !r_update) - goto check_next; - - /* Allocate and initialize new left/right child pages. */ - if ((ret = __os_malloc(dbenv, file_dbp->pgsize, &_lp)) != 0 || - (ret = __os_malloc(dbenv, file_dbp->pgsize, &_rp)) != 0) - goto out; - if (rootsplit) { - P_INIT(_lp, file_dbp->pgsize, argp->left, - PGNO_INVALID, - ISINTERNAL(sp) ? PGNO_INVALID : argp->right, - LEVEL(sp), TYPE(sp)); - P_INIT(_rp, file_dbp->pgsize, argp->right, - ISINTERNAL(sp) ? PGNO_INVALID : argp->left, - PGNO_INVALID, LEVEL(sp), TYPE(sp)); - } else { - P_INIT(_lp, file_dbp->pgsize, PGNO(sp), - ISINTERNAL(sp) ? PGNO_INVALID : PREV_PGNO(sp), - ISINTERNAL(sp) ? PGNO_INVALID : argp->right, - LEVEL(sp), TYPE(sp)); - P_INIT(_rp, file_dbp->pgsize, argp->right, - ISINTERNAL(sp) ? PGNO_INVALID : sp->pgno, - ISINTERNAL(sp) ? PGNO_INVALID : NEXT_PGNO(sp), - LEVEL(sp), TYPE(sp)); - } - - /* Split the page. */ - if ((ret = __bam_copy(file_dbp, sp, _lp, 0, argp->indx)) != 0 || - (ret = __bam_copy(file_dbp, sp, _rp, argp->indx, - NUM_ENT(sp))) != 0) - goto out; - - if (l_update) { - memcpy(lp, _lp, file_dbp->pgsize); - lp->lsn = *lsnp; - if ((ret = __memp_fput(mpf, lp, DB_MPOOL_DIRTY)) != 0) - goto out; - lp = NULL; - } - - if (r_update) { - memcpy(rp, _rp, file_dbp->pgsize); - rp->lsn = *lsnp; - if ((ret = __memp_fput(mpf, rp, DB_MPOOL_DIRTY)) != 0) - goto out; - rp = NULL; - } - - /* - * If the parent page is wrong, update it. This is of interest - * only if it was a root split, since root splits create parent - * pages. All other splits modify a parent page, but those are - * separately logged and recovered. - */ - if (rootsplit && p_update) { - if (IS_BTREE_PAGE(sp)) { - ptype = P_IBTREE; - rc = argp->opflags & SPL_NRECS ? 1 : 0; - } else { - ptype = P_IRECNO; - rc = 1; - } - - P_INIT(pp, file_dbp->pgsize, root_pgno, - PGNO_INVALID, PGNO_INVALID, _lp->level + 1, ptype); - RE_NREC_SET(pp, rc ? __bam_total(file_dbp, _lp) + - __bam_total(file_dbp, _rp) : 0); - - pp->lsn = *lsnp; - if ((ret = __memp_fput(mpf, pp, DB_MPOOL_DIRTY)) != 0) - goto out; - pp = NULL; - } - -check_next: /* - * Finally, redo the next-page link if necessary. This is of - * interest only if it wasn't a root split -- inserting a new - * page in the tree requires that any following page have its - * previous-page pointer updated to our new page. The next - * page must exist because we're redoing the operation. - */ - if (!rootsplit && argp->npgno != PGNO_INVALID) { - if ((ret = - __memp_fget(mpf, &argp->npgno, 0, &np)) != 0) { - if (ret != DB_PAGE_NOTFOUND -#ifndef HAVE_FTRUNCATE - || DB_REDO(op) -#endif - ) { - ret = __db_pgerr( - file_dbp, argp->npgno, ret); - goto out; - } else - goto done; - } - cmp = log_compare(&LSN(np), &argp->nlsn); - CHECK_LSN(dbenv, op, cmp, &LSN(np), &argp->nlsn); - if (cmp == 0) { - PREV_PGNO(np) = argp->right; - np->lsn = *lsnp; - if ((ret = - __memp_fput(mpf, np, DB_MPOOL_DIRTY)) != 0) - goto out; - np = NULL; - } - } - } else { - /* - * If the split page is wrong, replace its contents with the - * logged page contents. If the page doesn't exist, it means - * that the create of the page never happened, nor did any of - * the adds onto the page that caused the split, and there's - * really no undo-ing to be done. - */ - if ((ret = __memp_fget(mpf, &pgno, 0, &pp)) != 0) { - pp = NULL; - goto lrundo; - } - if (log_compare(lsnp, &LSN(pp)) == 0) { - memcpy(pp, argp->pg.data, argp->pg.size); - if ((ret = __memp_fput(mpf, pp, DB_MPOOL_DIRTY)) != 0) - goto out; - pp = NULL; - } - - /* - * If it's a root split and the left child ever existed, update - * its LSN. (If it's not a root split, we've updated the left - * page already -- it's the same as the split page.) If the - * right child ever existed, root split or not, update its LSN. - * The undo of the page allocation(s) will restore them to the - * free list. - */ -lrundo: if ((rootsplit && lp != NULL) || rp != NULL) { - if (rootsplit && lp != NULL && - log_compare(lsnp, &LSN(lp)) == 0) { - lp->lsn = argp->llsn; - if ((ret = - __memp_fput(mpf, lp, DB_MPOOL_DIRTY)) != 0) - goto out; - lp = NULL; - } - if (rp != NULL && - log_compare(lsnp, &LSN(rp)) == 0) { - rp->lsn = argp->rlsn; - if ((ret = - __memp_fput(mpf, rp, DB_MPOOL_DIRTY)) != 0) - goto out; - rp = NULL; - } - } - - /* - * Finally, undo the next-page link if necessary. This is of - * interest only if it wasn't a root split -- inserting a new - * page in the tree requires that any following page have its - * previous-page pointer updated to our new page. Since it's - * possible that the next-page never existed, we ignore it as - * if there's nothing to undo. - */ - if (!rootsplit && argp->npgno != PGNO_INVALID) { - if ((ret = - __memp_fget(mpf, &argp->npgno, 0, &np)) != 0) { - np = NULL; - goto done; - } - if (log_compare(lsnp, &LSN(np)) == 0) { - PREV_PGNO(np) = argp->left; - np->lsn = argp->nlsn; - if (__memp_fput(mpf, np, DB_MPOOL_DIRTY)) - goto out; - np = NULL; - } - } - } - -done: *lsnp = argp->prev_lsn; - ret = 0; - -out: /* Free any pages that weren't dirtied. */ - if (pp != NULL && (t_ret = __memp_fput(mpf, pp, 0)) != 0 && ret == 0) - ret = t_ret; - if (lp != NULL && (t_ret = __memp_fput(mpf, lp, 0)) != 0 && ret == 0) - ret = t_ret; - if (np != NULL && (t_ret = __memp_fput(mpf, np, 0)) != 0 && ret == 0) - ret = t_ret; - if (rp != NULL && (t_ret = __memp_fput(mpf, rp, 0)) != 0 && ret == 0) - ret = t_ret; - - /* Free any allocated space. */ - if (_lp != NULL) - __os_free(dbenv, _lp); - if (_rp != NULL) - __os_free(dbenv, _rp); - if (sp != NULL) - __os_free(dbenv, sp); - - REC_CLOSE; -} - -/* - * __bam_rsplit_recover -- - * Recovery function for a reverse split. - * - * PUBLIC: int __bam_rsplit_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__bam_rsplit_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __bam_rsplit_args *argp; - DB *file_dbp; - DBC *dbc; - DB_LSN copy_lsn; - DB_MPOOLFILE *mpf; - PAGE *pagep; - db_pgno_t pgno, root_pgno; - db_recno_t rcnt; - int cmp_n, cmp_p, modified, ret; - - pagep = NULL; - COMPQUIET(info, NULL); - REC_PRINT(__bam_rsplit_print); - REC_INTRO(__bam_rsplit_read, 1, 1); - - /* Fix the root page. */ - pgno = root_pgno = argp->root_pgno; - if ((ret = __memp_fget(mpf, &pgno, 0, &pagep)) != 0) { - if (ret != DB_PAGE_NOTFOUND -#ifndef HAVE_FTRUNCATE - || DB_REDO(op) -#endif - ) { - ret = __db_pgerr(file_dbp, pgno, ret); - goto out; - } else - goto do_page; - } - - modified = 0; - cmp_n = log_compare(lsnp, &LSN(pagep)); - cmp_p = log_compare(&LSN(pagep), &argp->rootlsn); - CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->rootlsn); - if (cmp_p == 0 && DB_REDO(op)) { - /* - * Copy the new data to the root page. If it is not now a - * leaf page we need to restore the record number. We could - * try to determine if C_RECNUM was set in the btree, but - * that's not really necessary since the field is not used - * otherwise. - */ - rcnt = RE_NREC(pagep); - memcpy(pagep, argp->pgdbt.data, argp->pgdbt.size); - if (LEVEL(pagep) > LEAFLEVEL) - RE_NREC_SET(pagep, rcnt); - pagep->pgno = root_pgno; - pagep->lsn = *lsnp; - modified = 1; - } else if (cmp_n == 0 && DB_UNDO(op)) { - /* Need to undo update described. */ - P_INIT(pagep, file_dbp->pgsize, root_pgno, - argp->nrec, PGNO_INVALID, pagep->level + 1, - IS_BTREE_PAGE(pagep) ? P_IBTREE : P_IRECNO); - if ((ret = __db_pitem(dbc, pagep, 0, - argp->rootent.size, &argp->rootent, NULL)) != 0) - goto out; - pagep->lsn = argp->rootlsn; - modified = 1; - } - if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0) - goto out; - -do_page: - /* - * Fix the page copied over the root page. It's possible that the - * page never made it to disk, so if we're undo-ing and the page - * doesn't exist, it's okay and there's nothing further to do. - */ - if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) { - if (ret != DB_PAGE_NOTFOUND -#ifndef HAVE_FTRUNCATE - || DB_REDO(op) -#endif - ) { - ret = __db_pgerr(file_dbp, argp->pgno, ret); - goto out; - } else - goto done; - } - modified = 0; - (void)__ua_memcpy(©_lsn, &LSN(argp->pgdbt.data), sizeof(DB_LSN)); - cmp_n = log_compare(lsnp, &LSN(pagep)); - cmp_p = log_compare(&LSN(pagep), ©_lsn); - CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), ©_lsn); - if (cmp_p == 0 && DB_REDO(op)) { - /* Need to redo update described. */ - pagep->lsn = *lsnp; - modified = 1; - } else if (cmp_n == 0 && DB_UNDO(op)) { - /* Need to undo update described. */ - memcpy(pagep, argp->pgdbt.data, argp->pgdbt.size); - modified = 1; - } - if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0) - goto out; - pagep = NULL; - -done: *lsnp = argp->prev_lsn; - ret = 0; - -out: if (pagep != NULL) - (void)__memp_fput(mpf, pagep, 0); - REC_CLOSE; -} - -/* - * __bam_adj_recover -- - * Recovery function for adj. - * - * PUBLIC: int __bam_adj_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__bam_adj_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __bam_adj_args *argp; - DB *file_dbp; - DBC *dbc; - DB_MPOOLFILE *mpf; - PAGE *pagep; - int cmp_n, cmp_p, modified, ret; - - pagep = NULL; - COMPQUIET(info, NULL); - REC_PRINT(__bam_adj_print); - REC_INTRO(__bam_adj_read, 1, 1); - - /* Get the page; if it never existed and we're undoing, we're done. */ - if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) { - if (ret != DB_PAGE_NOTFOUND -#ifndef HAVE_FTRUNCATE - || DB_REDO(op) -#endif - ) { - ret = __db_pgerr(file_dbp, argp->pgno, ret); - goto out; - } else - goto done; - } - - modified = 0; - cmp_n = log_compare(lsnp, &LSN(pagep)); - cmp_p = log_compare(&LSN(pagep), &argp->lsn); - CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->lsn); - if (cmp_p == 0 && DB_REDO(op)) { - /* Need to redo update described. */ - if ((ret = __bam_adjindx(dbc, - pagep, argp->indx, argp->indx_copy, argp->is_insert)) != 0) - goto out; - - LSN(pagep) = *lsnp; - modified = 1; - } else if (cmp_n == 0 && DB_UNDO(op)) { - /* Need to undo update described. */ - if ((ret = __bam_adjindx(dbc, - pagep, argp->indx, argp->indx_copy, !argp->is_insert)) != 0) - goto out; - - LSN(pagep) = argp->lsn; - modified = 1; - } - if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0) - goto out; - pagep = NULL; - -done: *lsnp = argp->prev_lsn; - ret = 0; - -out: if (pagep != NULL) - (void)__memp_fput(mpf, pagep, 0); - REC_CLOSE; -} - -/* - * __bam_cadjust_recover -- - * Recovery function for the adjust of a count change in an internal - * page. - * - * PUBLIC: int __bam_cadjust_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__bam_cadjust_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __bam_cadjust_args *argp; - DB *file_dbp; - DBC *dbc; - DB_MPOOLFILE *mpf; - PAGE *pagep; - int cmp_n, cmp_p, modified, ret; - - pagep = NULL; - COMPQUIET(info, NULL); - REC_PRINT(__bam_cadjust_print); - REC_INTRO(__bam_cadjust_read, 1, 0); - - /* Get the page; if it never existed and we're undoing, we're done. */ - if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) { - if (ret != DB_PAGE_NOTFOUND -#ifndef HAVE_FTRUNCATE - || DB_REDO(op) -#endif - ) { - ret = __db_pgerr(file_dbp, argp->pgno, ret); - goto out; - } else - goto done; - } - - modified = 0; - cmp_n = log_compare(lsnp, &LSN(pagep)); - cmp_p = log_compare(&LSN(pagep), &argp->lsn); - CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->lsn); - if (cmp_p == 0 && DB_REDO(op)) { - /* Need to redo update described. */ - if (IS_BTREE_PAGE(pagep)) { - GET_BINTERNAL(file_dbp, pagep, argp->indx)->nrecs += - argp->adjust; - if (argp->opflags & CAD_UPDATEROOT) - RE_NREC_ADJ(pagep, argp->adjust); - } else { - GET_RINTERNAL(file_dbp, pagep, argp->indx)->nrecs += - argp->adjust; - if (argp->opflags & CAD_UPDATEROOT) - RE_NREC_ADJ(pagep, argp->adjust); - } - - LSN(pagep) = *lsnp; - modified = 1; - } else if (cmp_n == 0 && DB_UNDO(op)) { - /* Need to undo update described. */ - if (IS_BTREE_PAGE(pagep)) { - GET_BINTERNAL(file_dbp, pagep, argp->indx)->nrecs -= - argp->adjust; - if (argp->opflags & CAD_UPDATEROOT) - RE_NREC_ADJ(pagep, -(argp->adjust)); - } else { - GET_RINTERNAL(file_dbp, pagep, argp->indx)->nrecs -= - argp->adjust; - if (argp->opflags & CAD_UPDATEROOT) - RE_NREC_ADJ(pagep, -(argp->adjust)); - } - LSN(pagep) = argp->lsn; - modified = 1; - } - if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0) - goto out; - pagep = NULL; - -done: *lsnp = argp->prev_lsn; - ret = 0; - -out: if (pagep != NULL) - (void)__memp_fput(mpf, pagep, 0); - REC_CLOSE; -} - -/* - * __bam_cdel_recover -- - * Recovery function for the intent-to-delete of a cursor record. - * - * PUBLIC: int __bam_cdel_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__bam_cdel_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __bam_cdel_args *argp; - DB *file_dbp; - DBC *dbc; - DB_MPOOLFILE *mpf; - PAGE *pagep; - u_int32_t indx; - int cmp_n, cmp_p, modified, ret; - - pagep = NULL; - COMPQUIET(info, NULL); - REC_PRINT(__bam_cdel_print); - REC_INTRO(__bam_cdel_read, 1, 0); - - /* Get the page; if it never existed and we're undoing, we're done. */ - if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) { - if (ret != DB_PAGE_NOTFOUND -#ifndef HAVE_FTRUNCATE - || DB_REDO(op) -#endif - ) { - ret = __db_pgerr(file_dbp, argp->pgno, ret); - goto out; - } else - goto done; - } - - modified = 0; - cmp_n = log_compare(lsnp, &LSN(pagep)); - cmp_p = log_compare(&LSN(pagep), &argp->lsn); - CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->lsn); - if (cmp_p == 0 && DB_REDO(op)) { - /* Need to redo update described. */ - indx = argp->indx + (TYPE(pagep) == P_LBTREE ? O_INDX : 0); - B_DSET(GET_BKEYDATA(file_dbp, pagep, indx)->type); - - LSN(pagep) = *lsnp; - modified = 1; - } else if (cmp_n == 0 && DB_UNDO(op)) { - /* Need to undo update described. */ - indx = argp->indx + (TYPE(pagep) == P_LBTREE ? O_INDX : 0); - B_DCLR(GET_BKEYDATA(file_dbp, pagep, indx)->type); - - if ((ret = __bam_ca_delete( - file_dbp, argp->pgno, argp->indx, 0, NULL)) != 0) - goto out; - - LSN(pagep) = argp->lsn; - modified = 1; - } - if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0) - goto out; - pagep = NULL; - -done: *lsnp = argp->prev_lsn; - ret = 0; - -out: if (pagep != NULL) - (void)__memp_fput(mpf, pagep, 0); - REC_CLOSE; -} - -/* - * __bam_repl_recover -- - * Recovery function for page item replacement. - * - * PUBLIC: int __bam_repl_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__bam_repl_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __bam_repl_args *argp; - BKEYDATA *bk; - DB *file_dbp; - DBC *dbc; - DBT dbt; - DB_MPOOLFILE *mpf; - PAGE *pagep; - int cmp_n, cmp_p, modified, ret; - u_int8_t *p; - - pagep = NULL; - COMPQUIET(info, NULL); - REC_PRINT(__bam_repl_print); - REC_INTRO(__bam_repl_read, 1, 1); - - /* Get the page; if it never existed and we're undoing, we're done. */ - if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) { - if (ret != DB_PAGE_NOTFOUND -#ifndef HAVE_FTRUNCATE - || DB_REDO(op) -#endif - ) { - ret = __db_pgerr(file_dbp, argp->pgno, ret); - goto out; - } else - goto done; - } - bk = GET_BKEYDATA(file_dbp, pagep, argp->indx); - - modified = 0; - cmp_n = log_compare(lsnp, &LSN(pagep)); - cmp_p = log_compare(&LSN(pagep), &argp->lsn); - CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->lsn); - if (cmp_p == 0 && DB_REDO(op)) { - /* - * Need to redo update described. - * - * Re-build the replacement item. - */ - memset(&dbt, 0, sizeof(dbt)); - dbt.size = argp->prefix + argp->suffix + argp->repl.size; - if ((ret = __os_malloc(dbenv, dbt.size, &dbt.data)) != 0) - goto out; - p = dbt.data; - memcpy(p, bk->data, argp->prefix); - p += argp->prefix; - memcpy(p, argp->repl.data, argp->repl.size); - p += argp->repl.size; - memcpy(p, bk->data + (bk->len - argp->suffix), argp->suffix); - - ret = __bam_ritem(dbc, pagep, argp->indx, &dbt); - __os_free(dbenv, dbt.data); - if (ret != 0) - goto out; - - LSN(pagep) = *lsnp; - modified = 1; - } else if (cmp_n == 0 && DB_UNDO(op)) { - /* - * Need to undo update described. - * - * Re-build the original item. - */ - memset(&dbt, 0, sizeof(dbt)); - dbt.size = argp->prefix + argp->suffix + argp->orig.size; - if ((ret = __os_malloc(dbenv, dbt.size, &dbt.data)) != 0) - goto out; - p = dbt.data; - memcpy(p, bk->data, argp->prefix); - p += argp->prefix; - memcpy(p, argp->orig.data, argp->orig.size); - p += argp->orig.size; - memcpy(p, bk->data + (bk->len - argp->suffix), argp->suffix); - - ret = __bam_ritem(dbc, pagep, argp->indx, &dbt); - __os_free(dbenv, dbt.data); - if (ret != 0) - goto out; - - /* Reset the deleted flag, if necessary. */ - if (argp->isdeleted) - B_DSET(GET_BKEYDATA(file_dbp, pagep, argp->indx)->type); - - LSN(pagep) = argp->lsn; - modified = 1; - } - if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0) - goto out; - pagep = NULL; - -done: *lsnp = argp->prev_lsn; - ret = 0; - -out: if (pagep != NULL) - (void)__memp_fput(mpf, pagep, 0); - REC_CLOSE; -} - -/* - * __bam_root_recover -- - * Recovery function for setting the root page on the meta-data page. - * - * PUBLIC: int __bam_root_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__bam_root_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __bam_root_args *argp; - BTMETA *meta; - DB *file_dbp; - DBC *dbc; - DB_MPOOLFILE *mpf; - int cmp_n, cmp_p, modified, ret; - - meta = NULL; - COMPQUIET(info, NULL); - REC_PRINT(__bam_root_print); - REC_INTRO(__bam_root_read, 0, 0); - - if ((ret = __memp_fget(mpf, &argp->meta_pgno, 0, &meta)) != 0) { - if (ret != DB_PAGE_NOTFOUND -#ifndef HAVE_FTRUNCATE - || DB_REDO(op) -#endif - ) { - ret = __db_pgerr(file_dbp, argp->meta_pgno, ret); - goto out; - } else - goto done; - } - - modified = 0; - cmp_n = log_compare(lsnp, &LSN(meta)); - cmp_p = log_compare(&LSN(meta), &argp->meta_lsn); - CHECK_LSN(dbenv, op, cmp_p, &LSN(meta), &argp->meta_lsn); - if (cmp_p == 0 && DB_REDO(op)) { - /* Need to redo update described. */ - meta->root = argp->root_pgno; - meta->dbmeta.lsn = *lsnp; - ((BTREE *)file_dbp->bt_internal)->bt_root = meta->root; - modified = 1; - } else if (cmp_n == 0 && DB_UNDO(op)) { - /* Nothing to undo except lsn. */ - meta->dbmeta.lsn = argp->meta_lsn; - modified = 1; - } - if ((ret = __memp_fput(mpf, meta, modified ? DB_MPOOL_DIRTY : 0)) != 0) - goto out; - meta = NULL; - -done: *lsnp = argp->prev_lsn; - ret = 0; - -out: if (meta != NULL) - (void)__memp_fput(mpf, meta, 0); - REC_CLOSE; -} - -/* - * __bam_curadj_recover -- - * Transaction abort function to undo cursor adjustments. - * This should only be triggered by subtransaction aborts. - * - * PUBLIC: int __bam_curadj_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__bam_curadj_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __bam_curadj_args *argp; - DB *file_dbp; - DBC *dbc; - DB_MPOOLFILE *mpf; - int ret; - - COMPQUIET(info, NULL); - COMPQUIET(mpf, NULL); - - REC_PRINT(__bam_curadj_print); - REC_INTRO(__bam_curadj_read, 0, 1); - - ret = 0; - if (op != DB_TXN_ABORT) - goto done; - - switch (argp->mode) { - case DB_CA_DI: - if ((ret = __bam_ca_di(dbc, argp->from_pgno, - argp->from_indx, -(int)argp->first_indx)) != 0) - goto out; - break; - case DB_CA_DUP: - if ((ret = __bam_ca_undodup(file_dbp, argp->first_indx, - argp->from_pgno, argp->from_indx, argp->to_indx)) != 0) - goto out; - break; - - case DB_CA_RSPLIT: - if ((ret = - __bam_ca_rsplit(dbc, argp->to_pgno, argp->from_pgno)) != 0) - goto out; - break; - - case DB_CA_SPLIT: - if ((ret = __bam_ca_undosplit(file_dbp, argp->from_pgno, - argp->to_pgno, argp->left_pgno, argp->from_indx)) != 0) - goto out; - break; - } - -done: *lsnp = argp->prev_lsn; -out: REC_CLOSE; -} - -/* - * __bam_rcuradj_recover -- - * Transaction abort function to undo cursor adjustments in rrecno. - * This should only be triggered by subtransaction aborts. - * - * PUBLIC: int __bam_rcuradj_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__bam_rcuradj_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __bam_rcuradj_args *argp; - BTREE_CURSOR *cp; - DB *file_dbp; - DBC *dbc, *rdbc; - DB_MPOOLFILE *mpf; - int ret, t_ret; - - COMPQUIET(info, NULL); - COMPQUIET(mpf, NULL); - rdbc = NULL; - - REC_PRINT(__bam_rcuradj_print); - REC_INTRO(__bam_rcuradj_read, 0, 1); - - ret = t_ret = 0; - - if (op != DB_TXN_ABORT) - goto done; - - /* - * We don't know whether we're in an offpage dup set, and - * thus don't know whether the dbc REC_INTRO has handed us is - * of a reasonable type. It's certainly unset, so if this is - * an offpage dup set, we don't have an OPD cursor. The - * simplest solution is just to allocate a whole new cursor - * for our use; we're only really using it to hold pass some - * state into __ram_ca, and this way we don't need to make - * this function know anything about how offpage dups work. - */ - if ((ret = __db_cursor_int(file_dbp, - NULL, DB_RECNO, argp->root, 0, DB_LOCK_INVALIDID, &rdbc)) != 0) - goto out; - - cp = (BTREE_CURSOR *)rdbc->internal; - F_SET(cp, C_RENUMBER); - cp->recno = argp->recno; - - switch (argp->mode) { - case CA_DELETE: - /* - * The way to undo a delete is with an insert. Since - * we're undoing it, the delete flag must be set. - */ - F_SET(cp, C_DELETED); - F_SET(cp, C_RENUMBER); /* Just in case. */ - cp->order = argp->order; - (void)__ram_ca(rdbc, CA_ICURRENT); - break; - case CA_IAFTER: - case CA_IBEFORE: - case CA_ICURRENT: - /* - * The way to undo an insert is with a delete. The delete - * flag is unset to start with. - */ - F_CLR(cp, C_DELETED); - cp->order = INVALID_ORDER; - (void)__ram_ca(rdbc, CA_DELETE); - break; - } - -done: *lsnp = argp->prev_lsn; -out: if (rdbc != NULL && (t_ret = __db_c_close(rdbc)) != 0 && ret == 0) - ret = t_ret; - REC_CLOSE; -} - -/* - * __bam_relink_recover -- - * Recovery function for relink. - * - * PUBLIC: int __bam_relink_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__bam_relink_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __bam_relink_args *argp; - DB *file_dbp; - DBC *dbc; - DB_MPOOLFILE *mpf; - PAGE *pagep; - int cmp_n, cmp_p, modified, ret; - - pagep = NULL; - COMPQUIET(info, NULL); - REC_PRINT(__bam_relink_print); - REC_INTRO(__bam_relink_read, 1, 0); - - /* - * There are up to three pages we need to check -- the page, and the - * previous and next pages, if they existed. For a page add operation, - * the current page is the result of a split and is being recovered - * elsewhere, so all we need do is recover the next page. - */ - if ((ret = __memp_fget(mpf, &argp->next, 0, &pagep)) != 0) { - if (ret != DB_PAGE_NOTFOUND -#ifndef HAVE_FTRUNCATE - || DB_REDO(op) -#endif - ) { - ret = __db_pgerr(file_dbp, argp->next, ret); - goto out; - } else - goto prev; - } - - modified = 0; - cmp_n = log_compare(lsnp, &LSN(pagep)); - cmp_p = log_compare(&LSN(pagep), &argp->lsn_next); - CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->lsn_next); - if (cmp_p == 0 && DB_REDO(op)) { - /* Redo the remove or replace. */ - if (argp->new_pgno == PGNO_INVALID) - pagep->prev_pgno = argp->prev; - else - pagep->prev_pgno = argp->new_pgno; - - pagep->lsn = *lsnp; - modified = 1; - } else if (cmp_n == 0 && DB_UNDO(op)) { - /* Undo the remove or replace. */ - pagep->prev_pgno = argp->pgno; - - pagep->lsn = argp->lsn_next; - modified = 1; - } - - if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0) - goto out; - pagep = NULL; - -prev: if ((ret = __memp_fget(mpf, &argp->prev, 0, &pagep)) != 0) { - if (ret != DB_PAGE_NOTFOUND -#ifndef HAVE_FTRUNCATE - || DB_REDO(op) -#endif - ) { - ret = __db_pgerr(file_dbp, argp->prev, ret); - goto out; - } else - goto done; - } - - modified = 0; - cmp_p = log_compare(&LSN(pagep), &argp->lsn_prev); - CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->lsn_prev); - if (cmp_p == 0 && DB_REDO(op)) { - /* Redo the relink. */ - if (argp->new_pgno == PGNO_INVALID) - pagep->next_pgno = argp->next; - else - pagep->next_pgno = argp->new_pgno; - - pagep->lsn = *lsnp; - modified = 1; - } else if (log_compare(lsnp, &LSN(pagep)) == 0 && DB_UNDO(op)) { - /* Undo the relink. */ - pagep->next_pgno = argp->pgno; - pagep->lsn = argp->lsn_prev; - - modified = 1; - } - - if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0) - goto out; - pagep = NULL; - -done: *lsnp = argp->prev_lsn; - ret = 0; - -out: if (pagep != NULL) - (void)__memp_fput(mpf, pagep, 0); - REC_CLOSE; -} - -/* - * __bam_merge_recover -- - * Recovery function for merge. - * - * PUBLIC: int __bam_merge_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__bam_merge_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __bam_merge_args *argp; - BKEYDATA *bk; - DB *file_dbp; - DBC *dbc; - DB_MPOOLFILE *mpf; - PAGE *pagep; - db_indx_t indx, *ninp, *pinp; - u_int32_t size; - u_int8_t *bp; - int cmp_n, cmp_p, i, modified, ret; - - COMPQUIET(info, NULL); - - REC_PRINT(__bam_merge_print); - REC_INTRO(__bam_merge_read, 1, 1); - - if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) { - if (ret != DB_PAGE_NOTFOUND -#ifndef HAVE_FTRUNCATE - || DB_REDO(op) -#endif - ) { - ret = __db_pgerr(file_dbp, argp->pgno, ret); - goto out; - } else - goto next; - } - - modified = 0; - cmp_n = log_compare(lsnp, &LSN(pagep)); - cmp_p = log_compare(&LSN(pagep), &argp->lsn); - CHECK_LSN(file_dbp->dbenv, op, cmp_p, &LSN(pagep), &argp->lsn); - - if (cmp_p == 0 && DB_REDO(op)) { - /* - * If the header is provided the page is empty, copy the - * needed data. - */ - DB_ASSERT(argp->hdr.size == 0 || NUM_ENT(pagep) == 0); - if (argp->hdr.size != 0) { - P_INIT(pagep, file_dbp->pgsize, pagep->pgno, - PREV_PGNO(argp->hdr.data), - NEXT_PGNO(argp->hdr.data), - LEVEL(argp->hdr.data), TYPE(argp->hdr.data)); - } - if (TYPE(pagep) == P_OVERFLOW) { - OV_REF(pagep) = OV_REF(argp->hdr.data); - OV_LEN(pagep) = OV_LEN(argp->hdr.data); - bp = (u_int8_t *) pagep + P_OVERHEAD(file_dbp); - memcpy(bp, argp->data.data, argp->data.size); - } else { - /* Copy the data segment. */ - bp = (u_int8_t *)pagep + - (db_indx_t)(HOFFSET(pagep) - argp->data.size); - memcpy(bp, argp->data.data, argp->data.size); - - /* Copy index table offset past the current entries. */ - pinp = P_INP(file_dbp, pagep) + NUM_ENT(pagep); - ninp = argp->ind.data; - for (i = 0; - i < (int)(argp->ind.size / sizeof(*ninp)); i++) - *pinp++ = *ninp++ - - (file_dbp->pgsize - HOFFSET(pagep)); - HOFFSET(pagep) -= argp->data.size; - NUM_ENT(pagep) += i; - } - pagep->lsn = *lsnp; - modified = 1; - } else if (cmp_n == 0 && !DB_REDO(op)) { - /* - * Since logging is logical at the page level - * we cannot just truncate the data space. Delete - * the proper number of items from the logical end - * of the page. - */ - for (i = 0; i < (int)(argp->ind.size / sizeof(*ninp)); i++) { - indx = NUM_ENT(pagep) - 1; - if (P_INP(file_dbp, pagep)[indx] == - P_INP(file_dbp, pagep)[indx - P_INDX]) { - NUM_ENT(pagep)--; - continue; - } - switch (TYPE(pagep)) { - case P_LBTREE: - case P_LRECNO: - case P_LDUP: - bk = GET_BKEYDATA(file_dbp, pagep, indx); - size = BITEM_SIZE(bk); - break; - - case P_IBTREE: - size = BINTERNAL_SIZE( - GET_BINTERNAL(file_dbp, pagep, indx)->len); - break; - case P_IRECNO: - size = RINTERNAL_SIZE; - break; - - default: - ret = __db_pgfmt(dbenv, PGNO(pagep)); - goto out; - } - if ((ret = - __db_ditem(dbc, pagep, indx, size)) != 0) - goto out; - } - if (argp->ind.size == 0) - HOFFSET(pagep) = file_dbp->pgsize; - pagep->lsn = argp->lsn; - modified = 1; - } - - if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0) - goto out; - -next: if ((ret = __memp_fget(mpf, &argp->npgno, 0, &pagep)) != 0) { - if (ret != DB_PAGE_NOTFOUND -#ifndef HAVE_FTRUNCATE - || DB_REDO(op) -#endif - ) { - ret = __db_pgerr(file_dbp, argp->pgno, ret); - goto out; - } else - goto done; - } - - modified = 0; - cmp_n = log_compare(lsnp, &LSN(pagep)); - cmp_p = log_compare(&LSN(pagep), &argp->nlsn); - CHECK_LSN(file_dbp->dbenv, op, cmp_p, &LSN(pagep), &argp->nlsn); - - if (cmp_p == 0 && DB_REDO(op)) { - /* Need to truncate the page. */ - HOFFSET(pagep) = file_dbp->pgsize; - NUM_ENT(pagep) = 0; - pagep->lsn = *lsnp; - modified = 1; - } else if (cmp_n == 0 && !DB_REDO(op)) { - /* Need to put the data back on the page. */ - if (TYPE(pagep) == P_OVERFLOW) { - OV_REF(pagep) = OV_REF(argp->hdr.data); - OV_LEN(pagep) = OV_LEN(argp->hdr.data); - bp = (u_int8_t *) pagep + P_OVERHEAD(file_dbp); - memcpy(bp, argp->data.data, argp->data.size); - } else { - bp = (u_int8_t *)pagep + - (db_indx_t)(HOFFSET(pagep) - argp->data.size); - memcpy(bp, argp->data.data, argp->data.size); - - /* Copy index table. */ - pinp = P_INP(file_dbp, pagep) + NUM_ENT(pagep); - ninp = argp->ind.data; - for (i = 0; - i < (int)(argp->ind.size / sizeof(*ninp)); i++) - *pinp++ = *ninp++; - HOFFSET(pagep) -= argp->data.size; - NUM_ENT(pagep) = i; - } - pagep->lsn = argp->nlsn; - modified = 1; - } - - if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0) - goto out; -done: - *lsnp = argp->prev_lsn; - ret = 0; - -out: REC_CLOSE; -} - -/* - * __bam_pgno_recover -- - * Recovery function for page number replacment. - * - * PUBLIC: int __bam_pgno_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__bam_pgno_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - BINTERNAL *bi; - __bam_pgno_args *argp; - DB *file_dbp; - DBC *dbc; - DB_MPOOLFILE *mpf; - PAGE *pagep, *npagep; - db_pgno_t *pgnop; - int cmp_n, cmp_p, modified, ret; - - COMPQUIET(info, NULL); - - REC_PRINT(__bam_pgno_print); - REC_INTRO(__bam_pgno_read, 1, 0); - - REC_FGET(mpf, argp->pgno, &pagep, done); - - modified = 0; - cmp_n = log_compare(lsnp, &LSN(pagep)); - cmp_p = log_compare(&LSN(pagep), &argp->lsn); - CHECK_LSN(file_dbp->dbenv, op, cmp_p, &LSN(pagep), &argp->lsn); - - if ((cmp_p == 0 && DB_REDO(op)) || (cmp_n == 0 && !DB_REDO(op))) { - switch (TYPE(pagep)) { - case P_IBTREE: - /* - * An internal record can have both a overflow - * and child pointer. Fetch the page to see - * which it is. - */ - bi = GET_BINTERNAL(file_dbp, pagep, argp->indx); - if (B_TYPE(bi->type) == B_OVERFLOW) { - REC_FGET(mpf, argp->npgno, &npagep, out); - - if (TYPE(npagep) == P_OVERFLOW) - pgnop = - &((BOVERFLOW *)(bi->data))->pgno; - else - pgnop = &bi->pgno; - if ((ret = __memp_fput(mpf, npagep, 0)) != 0) - goto out; - break; - } - pgnop = &bi->pgno; - break; - case P_IRECNO: - pgnop = - &GET_RINTERNAL(file_dbp, pagep, argp->indx)->pgno; - break; - default: - pgnop = - &GET_BOVERFLOW(file_dbp, pagep, argp->indx)->pgno; - break; - } - - if (DB_REDO(op)) { - /* Need to redo update described. */ - *pgnop = argp->npgno; - pagep->lsn = *lsnp; - modified = 1; - } else { - *pgnop = argp->opgno; - pagep->lsn = argp->lsn; - modified = 1; - } - } - - if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0) - goto out; - -done: - *lsnp = argp->prev_lsn; - ret = 0; - -out: REC_CLOSE; -} diff --git a/storage/bdb/btree/bt_reclaim.c b/storage/bdb/btree/bt_reclaim.c deleted file mode 100644 index d7884a79e0c..00000000000 --- a/storage/bdb/btree/bt_reclaim.c +++ /dev/null @@ -1,76 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1998-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: bt_reclaim.c,v 12.2 2005/06/16 20:20:19 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/btree.h" - -/* - * __bam_reclaim -- - * Free a database. - * - * PUBLIC: int __bam_reclaim __P((DB *, DB_TXN *)); - */ -int -__bam_reclaim(dbp, txn) - DB *dbp; - DB_TXN *txn; -{ - DBC *dbc; - int ret, t_ret; - - /* Acquire a cursor. */ - if ((ret = __db_cursor(dbp, txn, &dbc, 0)) != 0) - return (ret); - - /* Walk the tree, freeing pages. */ - ret = __bam_traverse(dbc, - DB_LOCK_WRITE, dbc->internal->root, __db_reclaim_callback, dbc); - - /* Discard the cursor. */ - if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __bam_truncate -- - * Truncate a database. - * - * PUBLIC: int __bam_truncate __P((DBC *, u_int32_t *)); - */ -int -__bam_truncate(dbc, countp) - DBC *dbc; - u_int32_t *countp; -{ - db_trunc_param trunc; - int ret; - - trunc.count = 0; - trunc.dbc = dbc; - - /* Walk the tree, freeing pages. */ - ret = __bam_traverse(dbc, - DB_LOCK_WRITE, dbc->internal->root, __db_truncate_callback, &trunc); - - if (countp != NULL) - *countp = trunc.count; - - return (ret); -} diff --git a/storage/bdb/btree/bt_recno.c b/storage/bdb/btree/bt_recno.c deleted file mode 100644 index a7da96ded4d..00000000000 --- a/storage/bdb/btree/bt_recno.c +++ /dev/null @@ -1,1331 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: bt_recno.c,v 12.6 2005/08/08 14:27:59 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/btree.h" -#include "dbinc/db_shash.h" -#include "dbinc/lock.h" - -static int __ram_add __P((DBC *, db_recno_t *, DBT *, u_int32_t, u_int32_t)); -static int __ram_source __P((DB *)); -static int __ram_sread __P((DBC *, db_recno_t)); -static int __ram_update __P((DBC *, db_recno_t, int)); - -/* - * In recno, there are two meanings to the on-page "deleted" flag. If we're - * re-numbering records, it means the record was implicitly created. We skip - * over implicitly created records if doing a cursor "next" or "prev", and - * return DB_KEYEMPTY if they're explicitly requested.. If not re-numbering - * records, it means that the record was implicitly created, or was deleted. - * We skip over implicitly created or deleted records if doing a cursor "next" - * or "prev", and return DB_KEYEMPTY if they're explicitly requested. - * - * If we're re-numbering records, then we have to detect in the cursor that - * a record was deleted, and adjust the cursor as necessary on the next get. - * If we're not re-numbering records, then we can detect that a record has - * been deleted by looking at the actual on-page record, so we completely - * ignore the cursor's delete flag. This is different from the B+tree code. - * It also maintains whether the cursor references a deleted record in the - * cursor, and it doesn't always check the on-page value. - */ -#define CD_SET(cp) { \ - if (F_ISSET(cp, C_RENUMBER)) \ - F_SET(cp, C_DELETED); \ -} -#define CD_CLR(cp) { \ - if (F_ISSET(cp, C_RENUMBER)) { \ - F_CLR(cp, C_DELETED); \ - cp->order = INVALID_ORDER; \ - } \ -} -#define CD_ISSET(cp) \ - (F_ISSET(cp, C_RENUMBER) && F_ISSET(cp, C_DELETED) ? 1 : 0) - -/* - * Macros for comparing the ordering of two cursors. - * cp1 comes before cp2 iff one of the following holds: - * cp1's recno is less than cp2's recno - * recnos are equal, both deleted, and cp1's order is less than cp2's - * recnos are equal, cp1 deleted, and cp2 not deleted - */ -#define C_LESSTHAN(cp1, cp2) \ - (((cp1)->recno < (cp2)->recno) || \ - (((cp1)->recno == (cp2)->recno) && \ - ((CD_ISSET((cp1)) && CD_ISSET((cp2)) && (cp1)->order < (cp2)->order) || \ - (CD_ISSET((cp1)) && !CD_ISSET((cp2)))))) - -/* - * cp1 is equal to cp2 iff their recnos and delete flags are identical, - * and if the delete flag is set their orders are also identical. - */ -#define C_EQUAL(cp1, cp2) \ - ((cp1)->recno == (cp2)->recno && CD_ISSET((cp1)) == CD_ISSET((cp2)) && \ - (!CD_ISSET((cp1)) || (cp1)->order == (cp2)->order)) - -/* - * Do we need to log the current cursor adjustment? - */ -#define CURADJ_LOG(dbc) \ - (DBC_LOGGING((dbc)) && (dbc)->txn != NULL && (dbc)->txn->parent != NULL) - -/* - * After a search, copy the found page into the cursor, discarding any - * currently held lock. - */ -#define STACK_TO_CURSOR(cp, ret) { \ - int __t_ret; \ - (cp)->page = (cp)->csp->page; \ - (cp)->pgno = (cp)->csp->page->pgno; \ - (cp)->indx = (cp)->csp->indx; \ - if ((__t_ret = __TLPUT(dbc, (cp)->lock)) != 0 && (ret) == 0) \ - ret = __t_ret; \ - (cp)->lock = (cp)->csp->lock; \ - (cp)->lock_mode = (cp)->csp->lock_mode; \ -} - -/* - * __ram_open -- - * Recno open function. - * - * PUBLIC: int __ram_open __P((DB *, - * PUBLIC: DB_TXN *, const char *, db_pgno_t, u_int32_t)); - */ -int -__ram_open(dbp, txn, name, base_pgno, flags) - DB *dbp; - DB_TXN *txn; - const char *name; - db_pgno_t base_pgno; - u_int32_t flags; -{ - BTREE *t; - DBC *dbc; - int ret, t_ret; - - COMPQUIET(name, NULL); - t = dbp->bt_internal; - - /* Start up the tree. */ - if ((ret = __bam_read_root(dbp, txn, base_pgno, flags)) != 0) - return (ret); - - /* - * If the user specified a source tree, open it and map it in. - * - * !!! - * We don't complain if the user specified transactions or threads. - * It's possible to make it work, but you'd better know what you're - * doing! - */ - if (t->re_source != NULL && (ret = __ram_source(dbp)) != 0) - return (ret); - - /* If we're snapshotting an underlying source file, do it now. */ - if (F_ISSET(dbp, DB_AM_SNAPSHOT)) { - /* Allocate a cursor. */ - if ((ret = __db_cursor(dbp, NULL, &dbc, 0)) != 0) - return (ret); - - /* Do the snapshot. */ - if ((ret = __ram_update(dbc, - DB_MAX_RECORDS, 0)) != 0 && ret == DB_NOTFOUND) - ret = 0; - - /* Discard the cursor. */ - if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0) - ret = t_ret; - } - - return (ret); -} - -/* - * __ram_append -- - * Recno append function. - * - * PUBLIC: int __ram_append __P((DBC *, DBT *, DBT *)); - */ -int -__ram_append(dbc, key, data) - DBC *dbc; - DBT *key, *data; -{ - BTREE_CURSOR *cp; - int ret; - - cp = (BTREE_CURSOR *)dbc->internal; - - /* - * Make sure we've read in all of the backing source file. If - * we found the record or it simply didn't exist, add the - * user's record. - */ - ret = __ram_update(dbc, DB_MAX_RECORDS, 0); - if (ret == 0 || ret == DB_NOTFOUND) - ret = __ram_add(dbc, &cp->recno, data, DB_APPEND, 0); - - /* Return the record number. */ - if (ret == 0) - ret = __db_retcopy(dbc->dbp->dbenv, key, &cp->recno, - sizeof(cp->recno), &dbc->rkey->data, &dbc->rkey->ulen); - - return (ret); -} - -/* - * __ram_c_del -- - * Recno cursor->c_del function. - * - * PUBLIC: int __ram_c_del __P((DBC *)); - */ -int -__ram_c_del(dbc) - DBC *dbc; -{ - BKEYDATA bk; - BTREE *t; - BTREE_CURSOR *cp; - DB *dbp; - DB_LSN lsn; - DBT hdr, data; - int exact, ret, stack, t_ret; - - dbp = dbc->dbp; - cp = (BTREE_CURSOR *)dbc->internal; - t = dbp->bt_internal; - stack = 0; - - /* - * The semantics of cursors during delete are as follows: in - * non-renumbering recnos, records are replaced with a marker - * containing a delete flag. If the record referenced by this cursor - * has already been deleted, we will detect that as part of the delete - * operation, and fail. - * - * In renumbering recnos, cursors which represent deleted items - * are flagged with the C_DELETED flag, and it is an error to - * call c_del a second time without an intervening cursor motion. - */ - if (CD_ISSET(cp)) - return (DB_KEYEMPTY); - - /* Search the tree for the key; delete only deletes exact matches. */ - if ((ret = __bam_rsearch(dbc, &cp->recno, S_DELETE, 1, &exact)) != 0) - goto err; - if (!exact) { - ret = DB_NOTFOUND; - goto err; - } - stack = 1; - - /* Copy the page into the cursor. */ - STACK_TO_CURSOR(cp, ret); - if (ret != 0) - goto err; - - /* - * If re-numbering records, the on-page deleted flag can only mean - * that this record was implicitly created. Applications aren't - * permitted to delete records they never created, return an error. - * - * If not re-numbering records, the on-page deleted flag means that - * this record was implicitly created, or, was deleted at some time. - * The former is an error because applications aren't permitted to - * delete records they never created, the latter is an error because - * if the record was "deleted", we could never have found it. - */ - if (B_DISSET(GET_BKEYDATA(dbp, cp->page, cp->indx)->type)) { - ret = DB_KEYEMPTY; - goto err; - } - - if (F_ISSET(cp, C_RENUMBER)) { - /* Delete the item, adjust the counts, adjust the cursors. */ - if ((ret = __bam_ditem(dbc, cp->page, cp->indx)) != 0) - goto err; - if ((ret = __bam_adjust(dbc, -1)) != 0) - goto err; - if (__ram_ca(dbc, CA_DELETE) > 0 && - CURADJ_LOG(dbc) && (ret = __bam_rcuradj_log(dbp, dbc->txn, - &lsn, 0, CA_DELETE, cp->root, cp->recno, cp->order)) != 0) - goto err; - - /* - * If the page is empty, delete it. - * - * We never delete a root page. First, root pages of primary - * databases never go away, recno or otherwise. However, if - * it's the root page of an off-page duplicates database, then - * it can be deleted. We don't delete it here because we have - * no way of telling the primary database page holder (e.g., - * the hash access method) that its page element should cleaned - * up because the underlying tree is gone. So, we keep the page - * around until the last cursor referencing the empty tree is - * are closed, and then clean it up. - */ - if (NUM_ENT(cp->page) == 0 && PGNO(cp->page) != cp->root) { - /* - * We want to delete a single item out of the last page - * that we're not deleting. - */ - ret = __bam_dpages(dbc, 0, 0); - - /* - * Regardless of the return from __bam_dpages, it will - * discard our stack and pinned page. - */ - stack = 0; - cp->page = NULL; - } - } else { - /* Use a delete/put pair to replace the record with a marker. */ - if ((ret = __bam_ditem(dbc, cp->page, cp->indx)) != 0) - goto err; - - B_TSET(bk.type, B_KEYDATA, 1); - bk.len = 0; - memset(&hdr, 0, sizeof(hdr)); - hdr.data = &bk; - hdr.size = SSZA(BKEYDATA, data); - memset(&data, 0, sizeof(data)); - data.data = (void *)""; - data.size = 0; - if ((ret = __db_pitem(dbc, - cp->page, cp->indx, BKEYDATA_SIZE(0), &hdr, &data)) != 0) - goto err; - } - - t->re_modified = 1; - -err: if (stack && (t_ret = __bam_stkrel(dbc, STK_CLRDBC)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __ram_c_get -- - * Recno cursor->c_get function. - * - * PUBLIC: int __ram_c_get - * PUBLIC: __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *)); - */ -int -__ram_c_get(dbc, key, data, flags, pgnop) - DBC *dbc; - DBT *key, *data; - u_int32_t flags; - db_pgno_t *pgnop; -{ - BTREE_CURSOR *cp; - DB *dbp; - int cmp, exact, ret; - - COMPQUIET(pgnop, NULL); - - dbp = dbc->dbp; - cp = (BTREE_CURSOR *)dbc->internal; - - LF_CLR(DB_MULTIPLE|DB_MULTIPLE_KEY); -retry: switch (flags) { - case DB_CURRENT: - /* - * If we're using mutable records and the deleted flag is - * set, the cursor is pointing at a nonexistent record; - * return an error. - */ - if (CD_ISSET(cp)) - return (DB_KEYEMPTY); - break; - case DB_NEXT_DUP: - /* - * If we're not in an off-page dup set, we know there's no - * next duplicate since recnos don't have them. If we - * are in an off-page dup set, the next item assuredly is - * a dup, so we set flags to DB_NEXT and keep going. - */ - if (!F_ISSET(dbc, DBC_OPD)) - return (DB_NOTFOUND); - /* FALLTHROUGH */ - case DB_NEXT_NODUP: - /* - * Recno databases don't have duplicates, set flags to DB_NEXT - * and keep going. - */ - /* FALLTHROUGH */ - case DB_NEXT: - flags = DB_NEXT; - /* - * If record numbers are mutable: if we just deleted a record, - * we have to avoid incrementing the record number so that we - * return the right record by virtue of renumbering the tree. - */ - if (CD_ISSET(cp)) { - /* - * Clear the flag, we've moved off the deleted record. - */ - CD_CLR(cp); - break; - } - - if (cp->recno != RECNO_OOB) { - ++cp->recno; - break; - } - /* FALLTHROUGH */ - case DB_FIRST: - flags = DB_NEXT; - cp->recno = 1; - break; - case DB_PREV_NODUP: - /* - * Recno databases don't have duplicates, set flags to DB_PREV - * and keep going. - */ - /* FALLTHROUGH */ - case DB_PREV: - flags = DB_PREV; - if (cp->recno != RECNO_OOB) { - if (cp->recno == 1) { - ret = DB_NOTFOUND; - goto err; - } - --cp->recno; - break; - } - /* FALLTHROUGH */ - case DB_LAST: - flags = DB_PREV; - if (((ret = __ram_update(dbc, - DB_MAX_RECORDS, 0)) != 0) && ret != DB_NOTFOUND) - goto err; - if ((ret = __bam_nrecs(dbc, &cp->recno)) != 0) - goto err; - if (cp->recno == 0) { - ret = DB_NOTFOUND; - goto err; - } - break; - case DB_GET_BOTHC: - /* - * If we're doing a join and these are offpage dups, - * we want to keep searching forward from after the - * current cursor position. Increment the recno by 1, - * then proceed as for a DB_SET. - * - * Otherwise, we know there are no additional matching - * data, as recnos don't have dups. return DB_NOTFOUND. - */ - if (F_ISSET(dbc, DBC_OPD)) { - cp->recno++; - break; - } - ret = DB_NOTFOUND; - goto err; - /* NOTREACHED */ - case DB_GET_BOTH: - case DB_GET_BOTH_RANGE: - /* - * If we're searching a set of off-page dups, we start - * a new linear search from the first record. Otherwise, - * we compare the single data item associated with the - * requested record for a match. - */ - if (F_ISSET(dbc, DBC_OPD)) { - cp->recno = 1; - break; - } - /* FALLTHROUGH */ - case DB_SET: - case DB_SET_RANGE: - if ((ret = __ram_getno(dbc, key, &cp->recno, 0)) != 0) - goto err; - break; - default: - ret = __db_unknown_flag(dbp->dbenv, "__ram_c_get", flags); - goto err; - } - - /* - * For DB_PREV, DB_LAST, DB_SET and DB_SET_RANGE, we have already - * called __ram_update() to make sure sufficient records have been - * read from the backing source file. Do it now for DB_CURRENT (if - * the current record was deleted we may need more records from the - * backing file for a DB_CURRENT operation), DB_FIRST and DB_NEXT. - * (We don't have to test for flags == DB_FIRST, because the switch - * statement above re-set flags to DB_NEXT in that case.) - */ - if ((flags == DB_NEXT || flags == DB_CURRENT) && ((ret = - __ram_update(dbc, cp->recno, 0)) != 0) && ret != DB_NOTFOUND) - goto err; - - for (;; ++cp->recno) { - /* Search the tree for the record. */ - if ((ret = __bam_rsearch(dbc, &cp->recno, - F_ISSET(dbc, DBC_RMW) ? S_FIND_WR : S_FIND, - 1, &exact)) != 0) - goto err; - if (!exact) { - ret = DB_NOTFOUND; - goto err; - } - - /* Copy the page into the cursor. */ - STACK_TO_CURSOR(cp, ret); - if (ret != 0) - goto err; - - /* - * If re-numbering records, the on-page deleted flag means this - * record was implicitly created. If not re-numbering records, - * the on-page deleted flag means this record was implicitly - * created, or, it was deleted at some time. Regardless, we - * skip such records if doing cursor next/prev operations or - * walking through off-page duplicates, and fail if they were - * requested explicitly by the application. - */ - if (B_DISSET(GET_BKEYDATA(dbp, cp->page, cp->indx)->type)) - switch (flags) { - case DB_NEXT: - case DB_PREV: - (void)__bam_stkrel(dbc, STK_CLRDBC); - goto retry; - case DB_GET_BOTH: - case DB_GET_BOTH_RANGE: - /* - * If we're an OPD tree, we don't care about - * matching a record number on a DB_GET_BOTH - * -- everything belongs to the same tree. A - * normal recno should give up and return - * DB_NOTFOUND if the matching recno is deleted. - */ - if (F_ISSET(dbc, DBC_OPD)) { - (void)__bam_stkrel(dbc, STK_CLRDBC); - continue; - } - ret = DB_NOTFOUND; - goto err; - default: - ret = DB_KEYEMPTY; - goto err; - } - - if (flags == DB_GET_BOTH || - flags == DB_GET_BOTHC || flags == DB_GET_BOTH_RANGE) { - if ((ret = __bam_cmp(dbp, data, - cp->page, cp->indx, __bam_defcmp, &cmp)) != 0) - return (ret); - if (cmp == 0) - break; - if (!F_ISSET(dbc, DBC_OPD)) { - ret = DB_NOTFOUND; - goto err; - } - (void)__bam_stkrel(dbc, STK_CLRDBC); - } else - break; - } - - /* Return the key if the user didn't give us one. */ - if (!F_ISSET(dbc, DBC_OPD)) { - if (flags != DB_GET_BOTH && flags != DB_GET_BOTH_RANGE && - flags != DB_SET && flags != DB_SET_RANGE) - ret = __db_retcopy(dbp->dbenv, - key, &cp->recno, sizeof(cp->recno), - &dbc->rkey->data, &dbc->rkey->ulen); - F_SET(key, DB_DBT_ISSET); - } - - /* The cursor was reset, no further delete adjustment is necessary. */ -err: CD_CLR(cp); - - return (ret); -} - -/* - * __ram_c_put -- - * Recno cursor->c_put function. - * - * PUBLIC: int __ram_c_put __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *)); - */ -int -__ram_c_put(dbc, key, data, flags, pgnop) - DBC *dbc; - DBT *key, *data; - u_int32_t flags; - db_pgno_t *pgnop; -{ - BTREE_CURSOR *cp; - DB *dbp; - DB_LSN lsn; - int exact, nc, ret, t_ret; - u_int32_t iiflags; - void *arg; - - COMPQUIET(pgnop, NULL); - - dbp = dbc->dbp; - cp = (BTREE_CURSOR *)dbc->internal; - - /* - * DB_KEYFIRST and DB_KEYLAST mean different things if they're - * used in an off-page duplicate tree. If we're an off-page - * duplicate tree, they really mean "put at the beginning of the - * tree" and "put at the end of the tree" respectively, so translate - * them to something else. - */ - if (F_ISSET(dbc, DBC_OPD)) - switch (flags) { - case DB_KEYFIRST: - cp->recno = 1; - flags = DB_BEFORE; - break; - case DB_KEYLAST: - if ((ret = __ram_add(dbc, - &cp->recno, data, DB_APPEND, 0)) != 0) - return (ret); - if (CURADJ_LOG(dbc) && - (ret = __bam_rcuradj_log(dbp, dbc->txn, &lsn, 0, - CA_ICURRENT, cp->root, cp->recno, cp->order)) != 0) - return (ret); - return (0); - default: - break; - } - - /* - * Handle normal DB_KEYFIRST/DB_KEYLAST; for a recno, which has - * no duplicates, these are identical and mean "put the given - * datum at the given recno". - * - * Note that the code here used to be in __ram_put; now, we - * go through the access-method-common __db_put function, which - * handles DB_NOOVERWRITE, so we and __ram_add don't have to. - */ - if (flags == DB_KEYFIRST || flags == DB_KEYLAST) { - ret = __ram_getno(dbc, key, &cp->recno, 1); - if (ret == 0 || ret == DB_NOTFOUND) - ret = __ram_add(dbc, &cp->recno, data, 0, 0); - return (ret); - } - - /* - * If we're putting with a cursor that's marked C_DELETED, we need to - * take special care; the cursor doesn't "really" reference the item - * corresponding to its current recno, but instead is "between" that - * record and the current one. Translate the actual insert into - * DB_BEFORE, and let the __ram_ca work out the gory details of what - * should wind up pointing where. - */ - if (CD_ISSET(cp)) - iiflags = DB_BEFORE; - else - iiflags = flags; - -split: if ((ret = __bam_rsearch(dbc, &cp->recno, S_INSERT, 1, &exact)) != 0) - goto err; - /* - * An inexact match is okay; it just means we're one record past the - * end, which is reasonable if we're marked deleted. - */ - DB_ASSERT(exact || CD_ISSET(cp)); - - /* Copy the page into the cursor. */ - STACK_TO_CURSOR(cp, ret); - if (ret != 0) - goto err; - - ret = __bam_iitem(dbc, key, data, iiflags, 0); - t_ret = __bam_stkrel(dbc, STK_CLRDBC); - - if (t_ret != 0 && (ret == 0 || ret == DB_NEEDSPLIT)) - ret = t_ret; - else if (ret == DB_NEEDSPLIT) { - arg = &cp->recno; - if ((ret = __bam_split(dbc, arg, NULL)) != 0) - goto err; - goto split; - } - if (ret != 0) - goto err; - - switch (flags) { /* Adjust the cursors. */ - case DB_AFTER: - nc = __ram_ca(dbc, CA_IAFTER); - - /* - * We only need to adjust this cursor forward if we truly added - * the item after the current recno, rather than remapping it - * to DB_BEFORE. - */ - if (iiflags == DB_AFTER) - ++cp->recno; - - /* Only log if __ram_ca found any relevant cursors. */ - if (nc > 0 && CURADJ_LOG(dbc) && - (ret = __bam_rcuradj_log(dbp, dbc->txn, &lsn, 0, CA_IAFTER, - cp->root, cp->recno, cp->order)) != 0) - goto err; - break; - case DB_BEFORE: - nc = __ram_ca(dbc, CA_IBEFORE); - --cp->recno; - - /* Only log if __ram_ca found any relevant cursors. */ - if (nc > 0 && CURADJ_LOG(dbc) && - (ret = __bam_rcuradj_log(dbp, dbc->txn, &lsn, 0, CA_IBEFORE, - cp->root, cp->recno, cp->order)) != 0) - goto err; - break; - case DB_CURRENT: - /* - * We only need to do an adjustment if we actually - * added an item, which we only would have done if the - * cursor was marked deleted. - * - * Only log if __ram_ca found any relevant cursors. - */ - if (CD_ISSET(cp) && __ram_ca(dbc, CA_ICURRENT) > 0 && - CURADJ_LOG(dbc) && - (ret = __bam_rcuradj_log(dbp, dbc->txn, &lsn, 0, - CA_ICURRENT, cp->root, cp->recno, cp->order)) != 0) - goto err; - break; - default: - break; - } - - /* Return the key if we've created a new record. */ - if (!F_ISSET(dbc, DBC_OPD) && (flags == DB_AFTER || flags == DB_BEFORE)) - ret = __db_retcopy(dbp->dbenv, key, &cp->recno, - sizeof(cp->recno), &dbc->rkey->data, &dbc->rkey->ulen); - - /* The cursor was reset, no further delete adjustment is necessary. */ -err: CD_CLR(cp); - - return (ret); -} - -/* - * __ram_ca -- - * Adjust cursors. Returns the number of relevant cursors. - * - * PUBLIC: int __ram_ca __P((DBC *, ca_recno_arg)); - */ -int -__ram_ca(dbc_arg, op) - DBC *dbc_arg; - ca_recno_arg op; -{ - BTREE_CURSOR *cp, *cp_arg; - DB *dbp, *ldbp; - DB_ENV *dbenv; - DBC *dbc; - db_recno_t recno; - int adjusted, found; - u_int32_t order; - - dbp = dbc_arg->dbp; - dbenv = dbp->dbenv; - cp_arg = (BTREE_CURSOR *)dbc_arg->internal; - recno = cp_arg->recno; - - found = 0; - - /* - * It only makes sense to adjust cursors if we're a renumbering - * recno; we should only be called if this is one. - */ - DB_ASSERT(F_ISSET(cp_arg, C_RENUMBER)); - - MUTEX_LOCK(dbenv, dbenv->mtx_dblist); - /* - * Adjust the cursors. See the comment in __bam_ca_delete(). - */ - /* - * If we're doing a delete, we need to find the highest - * order of any cursor currently pointing at this item, - * so we can assign a higher order to the newly deleted - * cursor. Unfortunately, this requires a second pass through - * the cursor list. - */ - if (op == CA_DELETE) { - order = 1; - for (ldbp = __dblist_get(dbenv, dbp->adj_fileid); - ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid; - ldbp = LIST_NEXT(ldbp, dblistlinks)) { - MUTEX_LOCK(dbenv, dbp->mutex); - for (dbc = TAILQ_FIRST(&ldbp->active_queue); - dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) { - cp = (BTREE_CURSOR *)dbc->internal; - if (cp_arg->root == cp->root && - recno == cp->recno && CD_ISSET(cp) && - order <= cp->order) - order = cp->order + 1; - } - MUTEX_UNLOCK(dbenv, dbp->mutex); - } - } else - order = INVALID_ORDER; - - /* Now go through and do the actual adjustments. */ - for (ldbp = __dblist_get(dbenv, dbp->adj_fileid); - ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid; - ldbp = LIST_NEXT(ldbp, dblistlinks)) { - MUTEX_LOCK(dbenv, dbp->mutex); - for (dbc = TAILQ_FIRST(&ldbp->active_queue); - dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) { - cp = (BTREE_CURSOR *)dbc->internal; - if (cp_arg->root != cp->root) - continue; - ++found; - adjusted = 0; - switch (op) { - case CA_DELETE: - if (recno < cp->recno) { - --cp->recno; - /* - * If the adjustment made them equal, - * we have to merge the orders. - */ - if (recno == cp->recno && CD_ISSET(cp)) - cp->order += order; - } else if (recno == cp->recno && - !CD_ISSET(cp)) { - CD_SET(cp); - cp->order = order; - } - break; - case CA_IBEFORE: - /* - * IBEFORE is just like IAFTER, except that we - * adjust cursors on the current record too. - */ - if (C_EQUAL(cp_arg, cp)) { - ++cp->recno; - adjusted = 1; - } - goto iafter; - case CA_ICURRENT: - - /* - * If the original cursor wasn't deleted, we - * just did a replacement and so there's no - * need to adjust anything--we shouldn't have - * gotten this far. Otherwise, we behave - * much like an IAFTER, except that all - * cursors pointing to the current item get - * marked undeleted and point to the new - * item. - */ - DB_ASSERT(CD_ISSET(cp_arg)); - if (C_EQUAL(cp_arg, cp)) { - CD_CLR(cp); - break; - } - /* FALLTHROUGH */ - case CA_IAFTER: -iafter: if (!adjusted && C_LESSTHAN(cp_arg, cp)) { - ++cp->recno; - adjusted = 1; - } - if (recno == cp->recno && adjusted) - /* - * If we've moved this cursor's recno, - * split its order number--i.e., - * decrement it by enough so that - * the lowest cursor moved has order 1. - * cp_arg->order is the split point, - * so decrement by one less than that. - */ - cp->order -= (cp_arg->order - 1); - break; - } - } - MUTEX_UNLOCK(dbp->dbenv, dbp->mutex); - } - MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist); - - return (found); -} - -/* - * __ram_getno -- - * Check the user's record number, and make sure we've seen it. - * - * PUBLIC: int __ram_getno __P((DBC *, const DBT *, db_recno_t *, int)); - */ -int -__ram_getno(dbc, key, rep, can_create) - DBC *dbc; - const DBT *key; - db_recno_t *rep; - int can_create; -{ - DB *dbp; - db_recno_t recno; - - dbp = dbc->dbp; - - /* Check the user's record number. */ - if ((recno = *(db_recno_t *)key->data) == 0) { - __db_err(dbp->dbenv, "illegal record number of 0"); - return (EINVAL); - } - if (rep != NULL) - *rep = recno; - - /* - * Btree can neither create records nor read them in. Recno can - * do both, see if we can find the record. - */ - return (dbc->dbtype == DB_RECNO ? - __ram_update(dbc, recno, can_create) : 0); -} - -/* - * __ram_update -- - * Ensure the tree has records up to and including the specified one. - */ -static int -__ram_update(dbc, recno, can_create) - DBC *dbc; - db_recno_t recno; - int can_create; -{ - BTREE *t; - DB *dbp; - DBT *rdata; - db_recno_t nrecs; - int ret; - - dbp = dbc->dbp; - t = dbp->bt_internal; - - /* - * If we can't create records and we've read the entire backing input - * file, we're done. - */ - if (!can_create && t->re_eof) - return (0); - - /* - * If we haven't seen this record yet, try to get it from the original - * file. - */ - if ((ret = __bam_nrecs(dbc, &nrecs)) != 0) - return (ret); - if (!t->re_eof && recno > nrecs) { - if ((ret = __ram_sread(dbc, recno)) != 0 && ret != DB_NOTFOUND) - return (ret); - if ((ret = __bam_nrecs(dbc, &nrecs)) != 0) - return (ret); - } - - /* - * If we can create records, create empty ones up to the requested - * record. - */ - if (!can_create || recno <= nrecs + 1) - return (0); - - rdata = &dbc->my_rdata; - rdata->flags = 0; - rdata->size = 0; - - while (recno > ++nrecs) - if ((ret = __ram_add(dbc, - &nrecs, rdata, 0, BI_DELETED)) != 0) - return (ret); - return (0); -} - -/* - * __ram_source -- - * Load information about the backing file. - */ -static int -__ram_source(dbp) - DB *dbp; -{ - BTREE *t; - char *source; - int ret; - - t = dbp->bt_internal; - - /* Find the real name, and swap out the one we had before. */ - if ((ret = __db_appname(dbp->dbenv, - DB_APP_DATA, t->re_source, 0, NULL, &source)) != 0) - return (ret); - __os_free(dbp->dbenv, t->re_source); - t->re_source = source; - - /* - * !!! - * It's possible that the backing source file is read-only. We don't - * much care other than we'll complain if there are any modifications - * when it comes time to write the database back to the source. - */ - if ((t->re_fp = fopen(t->re_source, "r")) == NULL) { - ret = __os_get_errno(); - __db_err(dbp->dbenv, "%s: %s", t->re_source, db_strerror(ret)); - return (ret); - } - - t->re_eof = 0; - return (0); -} - -/* - * __ram_writeback -- - * Rewrite the backing file. - * - * PUBLIC: int __ram_writeback __P((DB *)); - */ -int -__ram_writeback(dbp) - DB *dbp; -{ - BTREE *t; - DB_ENV *dbenv; - DBC *dbc; - DBT key, data; - FILE *fp; - db_recno_t keyno; - int ret, t_ret; - u_int8_t delim, *pad; - - t = dbp->bt_internal; - dbenv = dbp->dbenv; - fp = NULL; - pad = NULL; - - /* If the file wasn't modified, we're done. */ - if (!t->re_modified) - return (0); - - /* If there's no backing source file, we're done. */ - if (t->re_source == NULL) { - t->re_modified = 0; - return (0); - } - - /* - * We step through the records, writing each one out. Use the record - * number and the dbp->get() function, instead of a cursor, so we find - * and write out "deleted" or non-existent records. The DB handle may - * be threaded, so allocate memory as we go. - */ - memset(&key, 0, sizeof(key)); - key.size = sizeof(db_recno_t); - key.data = &keyno; - memset(&data, 0, sizeof(data)); - F_SET(&data, DB_DBT_REALLOC); - - /* Allocate a cursor. */ - if ((ret = __db_cursor(dbp, NULL, &dbc, 0)) != 0) - return (ret); - - /* - * Read any remaining records into the tree. - * - * !!! - * This is why we can't support transactions when applications specify - * backing (re_source) files. At this point we have to read in the - * rest of the records from the file so that we can write all of the - * records back out again, which could modify a page for which we'd - * have to log changes and which we don't have locked. This could be - * partially fixed by taking a snapshot of the entire file during the - * DB->open as DB->open is transaction protected. But, if a checkpoint - * occurs then, the part of the log holding the copy of the file could - * be discarded, and that would make it impossible to recover in the - * face of disaster. This could all probably be fixed, but it would - * require transaction protecting the backing source file. - * - * XXX - * This could be made to work now that we have transactions protecting - * file operations. Margo has specifically asked for the privilege of - * doing this work. - */ - if ((ret = - __ram_update(dbc, DB_MAX_RECORDS, 0)) != 0 && ret != DB_NOTFOUND) - goto err; - - /* - * Close any existing file handle and re-open the file, truncating it. - */ - if (t->re_fp != NULL) { - if (fclose(t->re_fp) != 0) { - ret = __os_get_errno(); - goto err; - } - t->re_fp = NULL; - } - if ((fp = fopen(t->re_source, "w")) == NULL) { - ret = __os_get_errno(); - __db_err(dbenv, "%s: %s", t->re_source, db_strerror(ret)); - goto err; - } - - /* - * We'll need the delimiter if we're doing variable-length records, - * and the pad character if we're doing fixed-length records. - */ - delim = t->re_delim; - for (keyno = 1;; ++keyno) { - switch (ret = __db_get(dbp, NULL, &key, &data, 0)) { - case 0: - if (data.size != 0 && - fwrite(data.data, 1, data.size, fp) != data.size) - goto write_err; - break; - case DB_KEYEMPTY: - if (F_ISSET(dbp, DB_AM_FIXEDLEN)) { - if (pad == NULL) { - if ((ret = __os_malloc( - dbenv, t->re_len, &pad)) != 0) - goto err; - memset(pad, t->re_pad, t->re_len); - } - if (fwrite(pad, 1, t->re_len, fp) != t->re_len) - goto write_err; - } - break; - case DB_NOTFOUND: - ret = 0; - goto done; - default: - goto err; - } - if (!F_ISSET(dbp, DB_AM_FIXEDLEN) && - fwrite(&delim, 1, 1, fp) != 1) { -write_err: ret = __os_get_errno(); - __db_err(dbenv, - "%s: write failed to backing file: %s", - t->re_source, strerror(ret)); - goto err; - } - } - -err: -done: /* Close the file descriptor. */ - if (fp != NULL && fclose(fp) != 0) { - t_ret = __os_get_errno(); - if (ret == 0) - ret = t_ret; - __db_err(dbenv, "%s: %s", t->re_source, db_strerror(t_ret)); - } - - /* Discard the cursor. */ - if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0) - ret = t_ret; - - /* Discard memory allocated to hold the data items. */ - if (data.data != NULL) - __os_ufree(dbenv, data.data); - if (pad != NULL) - __os_free(dbenv, pad); - - if (ret == 0) - t->re_modified = 0; - - return (ret); -} - -/* - * __ram_sread -- - * Read records from a source file. - */ -static int -__ram_sread(dbc, top) - DBC *dbc; - db_recno_t top; -{ - BTREE *t; - DB *dbp; - DBT data, *rdata; - db_recno_t recno; - size_t len; - int ch, ret, was_modified; - - t = dbc->dbp->bt_internal; - dbp = dbc->dbp; - was_modified = t->re_modified; - - if ((ret = __bam_nrecs(dbc, &recno)) != 0) - return (ret); - - /* - * Use the record key return memory, it's only a short-term use. - * The record data return memory is used by __bam_iitem, which - * we'll indirectly call, so use the key so as not to collide. - */ - len = F_ISSET(dbp, DB_AM_FIXEDLEN) ? t->re_len : 256; - rdata = &dbc->my_rkey; - if (rdata->ulen < len) { - if ((ret = __os_realloc( - dbp->dbenv, len, &rdata->data)) != 0) { - rdata->ulen = 0; - rdata->data = NULL; - return (ret); - } - rdata->ulen = (u_int32_t)len; - } - - memset(&data, 0, sizeof(data)); - while (recno < top) { - data.data = rdata->data; - data.size = 0; - if (F_ISSET(dbp, DB_AM_FIXEDLEN)) - for (len = t->re_len; len > 0; --len) { - if ((ch = getc(t->re_fp)) == EOF) { - if (data.size == 0) - goto eof; - break; - } - ((u_int8_t *)data.data)[data.size++] = ch; - } - else - for (;;) { - if ((ch = getc(t->re_fp)) == EOF) { - if (data.size == 0) - goto eof; - break; - } - if (ch == t->re_delim) - break; - - ((u_int8_t *)data.data)[data.size++] = ch; - if (data.size == rdata->ulen) { - if ((ret = __os_realloc(dbp->dbenv, - rdata->ulen *= 2, - &rdata->data)) != 0) { - rdata->ulen = 0; - rdata->data = NULL; - return (ret); - } else - data.data = rdata->data; - } - } - - /* - * Another process may have read this record from the input - * file and stored it into the database already, in which - * case we don't need to repeat that operation. We detect - * this by checking if the last record we've read is greater - * or equal to the number of records in the database. - */ - if (t->re_last >= recno) { - ++recno; - if ((ret = __ram_add(dbc, &recno, &data, 0, 0)) != 0) - goto err; - } - ++t->re_last; - } - - if (0) { -eof: t->re_eof = 1; - ret = DB_NOTFOUND; - } -err: if (!was_modified) - t->re_modified = 0; - - return (ret); -} - -/* - * __ram_add -- - * Add records into the tree. - */ -static int -__ram_add(dbc, recnop, data, flags, bi_flags) - DBC *dbc; - db_recno_t *recnop; - DBT *data; - u_int32_t flags, bi_flags; -{ - BTREE_CURSOR *cp; - int exact, ret, stack, t_ret; - - cp = (BTREE_CURSOR *)dbc->internal; - -retry: /* Find the slot for insertion. */ - if ((ret = __bam_rsearch(dbc, recnop, - S_INSERT | (flags == DB_APPEND ? S_APPEND : 0), 1, &exact)) != 0) - return (ret); - stack = 1; - - /* Copy the page into the cursor. */ - STACK_TO_CURSOR(cp, ret); - if (ret != 0) - goto err; - - /* - * The application may modify the data based on the selected record - * number. - */ - if (flags == DB_APPEND && dbc->dbp->db_append_recno != NULL && - (ret = dbc->dbp->db_append_recno(dbc->dbp, data, *recnop)) != 0) - goto err; - - /* - * Select the arguments for __bam_iitem() and do the insert. If the - * key is an exact match, or we're replacing the data item with a - * new data item, replace the current item. If the key isn't an exact - * match, we're inserting a new key/data pair, before the search - * location. - */ - switch (ret = __bam_iitem(dbc, - NULL, data, exact ? DB_CURRENT : DB_BEFORE, bi_flags)) { - case 0: - /* - * Don't adjust anything. - * - * If we inserted a record, no cursors need adjusting because - * the only new record it's possible to insert is at the very - * end of the tree. The necessary adjustments to the internal - * page counts were made by __bam_iitem(). - * - * If we overwrote a record, no cursors need adjusting because - * future DBcursor->get calls will simply return the underlying - * record (there's no adjustment made for the DB_CURRENT flag - * when a cursor get operation immediately follows a cursor - * delete operation, and the normal adjustment for the DB_NEXT - * flag is still correct). - */ - break; - case DB_NEEDSPLIT: - /* Discard the stack of pages and split the page. */ - (void)__bam_stkrel(dbc, STK_CLRDBC); - stack = 0; - - if ((ret = __bam_split(dbc, recnop, NULL)) != 0) - goto err; - - goto retry; - /* NOTREACHED */ - default: - goto err; - } - -err: if (stack && (t_ret = __bam_stkrel(dbc, STK_CLRDBC)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} diff --git a/storage/bdb/btree/bt_rsearch.c b/storage/bdb/btree/bt_rsearch.c deleted file mode 100644 index 8e93ee213dd..00000000000 --- a/storage/bdb/btree/bt_rsearch.c +++ /dev/null @@ -1,431 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994, 1995, 1996 - * Keith Bostic. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: bt_rsearch.c,v 12.5 2005/08/08 03:37:05 ubell Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/btree.h" -#include "dbinc/db_shash.h" -#include "dbinc/lock.h" -#include "dbinc/mp.h" - -/* - * __bam_rsearch -- - * Search a btree for a record number. - * - * PUBLIC: int __bam_rsearch __P((DBC *, db_recno_t *, u_int32_t, int, int *)); - */ -int -__bam_rsearch(dbc, recnop, flags, stop, exactp) - DBC *dbc; - db_recno_t *recnop; - u_int32_t flags; - int stop, *exactp; -{ - BINTERNAL *bi; - BTREE_CURSOR *cp; - DB *dbp; - DB_LOCK lock; - DB_MPOOLFILE *mpf; - PAGE *h; - RINTERNAL *ri; - db_indx_t adjust, deloffset, indx, top; - db_lockmode_t lock_mode; - db_pgno_t pg; - db_recno_t recno, t_recno, total; - int ret, stack, t_ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - cp = (BTREE_CURSOR *)dbc->internal; - h = NULL; - - BT_STK_CLR(cp); - - /* - * There are several ways we search a btree tree. The flags argument - * specifies if we're acquiring read or write locks and if we are - * locking pairs of pages. In addition, if we're adding or deleting - * an item, we have to lock the entire tree, regardless. See btree.h - * for more details. - * - * If write-locking pages, we need to know whether or not to acquire a - * write lock on a page before getting it. This depends on how deep it - * is in tree, which we don't know until we acquire the root page. So, - * if we need to lock the root page we may have to upgrade it later, - * because we won't get the correct lock initially. - * - * Retrieve the root page. - */ - - if ((ret = __bam_get_root(dbc, cp->root, stop, flags, &stack)) != 0) - return (ret); - lock_mode = cp->csp->lock_mode; - lock = cp->csp->lock; - h = cp->csp->page; - - BT_STK_CLR(cp); - /* - * If appending to the tree, set the record number now -- we have the - * root page locked. - * - * Delete only deletes exact matches, read only returns exact matches. - * Note, this is different from __bam_search(), which returns non-exact - * matches for read. - * - * The record may not exist. We can only return the correct location - * for the record immediately after the last record in the tree, so do - * a fast check now. - */ - total = RE_NREC(h); - if (LF_ISSET(S_APPEND)) { - *exactp = 0; - *recnop = recno = total + 1; - } else { - recno = *recnop; - if (recno <= total) - *exactp = 1; - else { - *exactp = 0; - if (!LF_ISSET(S_PAST_EOF) || recno > total + 1) { - /* - * Keep the page locked for serializability. - * - * XXX - * This leaves the root page locked, which will - * eliminate any concurrency. A possible fix - * would be to lock the last leaf page instead. - */ - ret = __memp_fput(mpf, h, 0); - if ((t_ret = - __TLPUT(dbc, lock)) != 0 && ret == 0) - ret = t_ret; - return (ret == 0 ? DB_NOTFOUND : ret); - } - } - } - - /* - * !!! - * Record numbers in the tree are 0-based, but the recno is - * 1-based. All of the calculations below have to take this - * into account. - */ - for (total = 0;;) { - switch (TYPE(h)) { - case P_LBTREE: - case P_LDUP: - recno -= total; - /* - * There may be logically deleted records on the page. - * If there are enough, the record may not exist. - */ - if (TYPE(h) == P_LBTREE) { - adjust = P_INDX; - deloffset = O_INDX; - } else { - adjust = O_INDX; - deloffset = 0; - } - for (t_recno = 0, indx = 0;; indx += adjust) { - if (indx >= NUM_ENT(h)) { - *exactp = 0; - if (!LF_ISSET(S_PAST_EOF) || - recno > t_recno + 1) { - ret = __memp_fput(mpf, h, 0); - h = NULL; - if ((t_ret = __TLPUT(dbc, - lock)) != 0 && ret == 0) - ret = t_ret; - if (ret == 0) - ret = DB_NOTFOUND; - goto err; - } - } - if (!B_DISSET(GET_BKEYDATA(dbp, h, - indx + deloffset)->type) && - ++t_recno == recno) - break; - } - - /* Correct from 1-based to 0-based for a page offset. */ - BT_STK_ENTER(dbp->dbenv, - cp, h, indx, lock, lock_mode, ret); - if (ret != 0) - goto err; - return (0); - case P_IBTREE: - for (indx = 0, top = NUM_ENT(h);;) { - bi = GET_BINTERNAL(dbp, h, indx); - if (++indx == top || total + bi->nrecs >= recno) - break; - total += bi->nrecs; - } - pg = bi->pgno; - break; - case P_LRECNO: - recno -= total; - - /* Correct from 1-based to 0-based for a page offset. */ - --recno; - BT_STK_ENTER(dbp->dbenv, - cp, h, recno, lock, lock_mode, ret); - if (ret != 0) - goto err; - return (0); - case P_IRECNO: - for (indx = 0, top = NUM_ENT(h);;) { - ri = GET_RINTERNAL(dbp, h, indx); - if (++indx == top || total + ri->nrecs >= recno) - break; - total += ri->nrecs; - } - pg = ri->pgno; - break; - default: - return (__db_pgfmt(dbp->dbenv, h->pgno)); - } - --indx; - - /* Return if this is the lowest page wanted. */ - if (stop == LEVEL(h)) { - BT_STK_ENTER(dbp->dbenv, - cp, h, indx, lock, lock_mode, ret); - if (ret != 0) - goto err; - return (0); - } - if (stack) { - BT_STK_PUSH(dbp->dbenv, - cp, h, indx, lock, lock_mode, ret); - if (ret != 0) - goto err; - h = NULL; - - lock_mode = DB_LOCK_WRITE; - if ((ret = - __db_lget(dbc, 0, pg, lock_mode, 0, &lock)) != 0) - goto err; - } else { - /* - * Decide if we want to return a pointer to the next - * page in the stack. If we do, write lock it and - * never unlock it. - */ - if ((LF_ISSET(S_PARENT) && - (u_int8_t)(stop + 1) >= (u_int8_t)(LEVEL(h) - 1)) || - (LEVEL(h) - 1) == LEAFLEVEL) - stack = 1; - - if ((ret = __memp_fput(mpf, h, 0)) != 0) - goto err; - h = NULL; - - lock_mode = stack && - LF_ISSET(S_WRITE) ? DB_LOCK_WRITE : DB_LOCK_READ; - if ((ret = __db_lget(dbc, - LCK_COUPLE_ALWAYS, pg, lock_mode, 0, &lock)) != 0) { - /* - * If we fail, discard the lock we held. This - * is OK because this only happens when we are - * descending the tree holding read-locks. - */ - (void)__LPUT(dbc, lock); - goto err; - } - } - - if ((ret = __memp_fget(mpf, &pg, 0, &h)) != 0) - goto err; - } - /* NOTREACHED */ - -err: if (h != NULL && (t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0) - ret = t_ret; - - BT_STK_POP(cp); - __bam_stkrel(dbc, 0); - - return (ret); -} - -/* - * __bam_adjust -- - * Adjust the tree after adding or deleting a record. - * - * PUBLIC: int __bam_adjust __P((DBC *, int32_t)); - */ -int -__bam_adjust(dbc, adjust) - DBC *dbc; - int32_t adjust; -{ - BTREE_CURSOR *cp; - DB *dbp; - DB_MPOOLFILE *mpf; - EPG *epg; - PAGE *h; - db_pgno_t root_pgno; - int ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - cp = (BTREE_CURSOR *)dbc->internal; - root_pgno = cp->root; - - /* Update the record counts for the tree. */ - for (epg = cp->sp; epg <= cp->csp; ++epg) { - h = epg->page; - if (TYPE(h) == P_IBTREE || TYPE(h) == P_IRECNO) { - if (DBC_LOGGING(dbc)) { - if ((ret = __bam_cadjust_log(dbp, dbc->txn, - &LSN(h), 0, PGNO(h), &LSN(h), - (u_int32_t)epg->indx, adjust, - PGNO(h) == root_pgno ? - CAD_UPDATEROOT : 0)) != 0) - return (ret); - } else - LSN_NOT_LOGGED(LSN(h)); - - if (TYPE(h) == P_IBTREE) - GET_BINTERNAL(dbp, h, epg->indx)->nrecs += - adjust; - else - GET_RINTERNAL(dbp, h, epg->indx)->nrecs += - adjust; - - if (PGNO(h) == root_pgno) - RE_NREC_ADJ(h, adjust); - - if ((ret = __memp_fset(mpf, h, DB_MPOOL_DIRTY)) != 0) - return (ret); - } - } - return (0); -} - -/* - * __bam_nrecs -- - * Return the number of records in the tree. - * - * PUBLIC: int __bam_nrecs __P((DBC *, db_recno_t *)); - */ -int -__bam_nrecs(dbc, rep) - DBC *dbc; - db_recno_t *rep; -{ - DB *dbp; - DB_LOCK lock; - DB_MPOOLFILE *mpf; - PAGE *h; - db_pgno_t pgno; - int ret, t_ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - - pgno = dbc->internal->root; - if ((ret = __db_lget(dbc, 0, pgno, DB_LOCK_READ, 0, &lock)) != 0) - return (ret); - if ((ret = __memp_fget(mpf, &pgno, 0, &h)) != 0) - return (ret); - - *rep = RE_NREC(h); - - ret = __memp_fput(mpf, h, 0); - if ((t_ret = __TLPUT(dbc, lock)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __bam_total -- - * Return the number of records below a page. - * - * PUBLIC: db_recno_t __bam_total __P((DB *, PAGE *)); - */ -db_recno_t -__bam_total(dbp, h) - DB *dbp; - PAGE *h; -{ - db_recno_t nrecs; - db_indx_t indx, top; - - nrecs = 0; - top = NUM_ENT(h); - - switch (TYPE(h)) { - case P_LBTREE: - /* Check for logically deleted records. */ - for (indx = 0; indx < top; indx += P_INDX) - if (!B_DISSET( - GET_BKEYDATA(dbp, h, indx + O_INDX)->type)) - ++nrecs; - break; - case P_LDUP: - /* Check for logically deleted records. */ - for (indx = 0; indx < top; indx += O_INDX) - if (!B_DISSET(GET_BKEYDATA(dbp, h, indx)->type)) - ++nrecs; - break; - case P_IBTREE: - for (indx = 0; indx < top; indx += O_INDX) - nrecs += GET_BINTERNAL(dbp, h, indx)->nrecs; - break; - case P_LRECNO: - nrecs = NUM_ENT(h); - break; - case P_IRECNO: - for (indx = 0; indx < top; indx += O_INDX) - nrecs += GET_RINTERNAL(dbp, h, indx)->nrecs; - break; - } - - return (nrecs); -} diff --git a/storage/bdb/btree/bt_search.c b/storage/bdb/btree/bt_search.c deleted file mode 100644 index aedd5304a91..00000000000 --- a/storage/bdb/btree/bt_search.c +++ /dev/null @@ -1,706 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994, 1995, 1996 - * Keith Bostic. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994, 1995 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Mike Olson. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: bt_search.c,v 12.17 2005/11/10 21:17:13 ubell Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/btree.h" -#include "dbinc/lock.h" -#include "dbinc/mp.h" - -/* - * __bam_get_root -- - * Fetch the root of a tree and see if we want to keep - * it in the stack. - * - * PUBLIC: int __bam_get_root __P((DBC *, db_pgno_t, int, u_int32_t, int *)); - */ -int -__bam_get_root(dbc, pg, slevel, flags, stack) - DBC *dbc; - db_pgno_t pg; - int slevel; - u_int32_t flags; - int *stack; -{ - BTREE_CURSOR *cp; - DB *dbp; - DB_LOCK lock; - DB_MPOOLFILE *mpf; - PAGE *h; - db_lockmode_t lock_mode; - int ret, t_ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - cp = (BTREE_CURSOR *)dbc->internal; - /* - * If write-locking pages, we need to know whether or not to acquire a - * write lock on a page before getting it. This depends on how deep it - * is in tree, which we don't know until we acquire the root page. So, - * if we need to lock the root page we may have to upgrade it later, - * because we won't get the correct lock initially. - * - * Retrieve the root page. - */ -try_again: - *stack = LF_ISSET(S_STACK) && - (dbc->dbtype == DB_RECNO || F_ISSET(cp, C_RECNUM)); - lock_mode = DB_LOCK_READ; - if (*stack || - LF_ISSET(S_DEL) || (LF_ISSET(S_NEXT) && LF_ISSET(S_WRITE))) - lock_mode = DB_LOCK_WRITE; - if ((ret = __db_lget(dbc, 0, pg, lock_mode, 0, &lock)) != 0) - return (ret); - if ((ret = __memp_fget(mpf, &pg, 0, &h)) != 0) { - /* Did not read it, so we can release the lock */ - (void)__LPUT(dbc, lock); - return (ret); - } - - /* - * Decide if we need to save this page; if we do, write lock it. - * We deliberately don't lock-couple on this call. If the tree - * is tiny, i.e., one page, and two threads are busily updating - * the root page, we're almost guaranteed deadlocks galore, as - * each one gets a read lock and then blocks the other's attempt - * for a write lock. - */ - if (!*stack && - ((LF_ISSET(S_PARENT) && (u_int8_t)(slevel + 1) >= LEVEL(h)) || - (LF_ISSET(S_WRITE) && LEVEL(h) == LEAFLEVEL) || - (LF_ISSET(S_START) && slevel == LEVEL(h)))) { - if (!STD_LOCKING(dbc)) - goto no_relock; - ret = __memp_fput(mpf, h, 0); - if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0) - ret = t_ret; - if (ret != 0) - return (ret); - lock_mode = DB_LOCK_WRITE; - if ((ret = __db_lget(dbc, 0, pg, lock_mode, 0, &lock)) != 0) - return (ret); - if ((ret = __memp_fget(mpf, &pg, 0, &h)) != 0) { - /* Did not read it, so we can release the lock */ - (void)__LPUT(dbc, lock); - return (ret); - } - if (!((LF_ISSET(S_PARENT) && - (u_int8_t)(slevel + 1) >= LEVEL(h)) || - (LF_ISSET(S_WRITE) && LEVEL(h) == LEAFLEVEL) || - (LF_ISSET(S_START) && slevel == LEVEL(h)))) { - /* Someone else split the root, start over. */ - ret = __memp_fput(mpf, h, 0); - if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0) - ret = t_ret; - if (ret != 0) - return (ret); - goto try_again; - } -no_relock: *stack = 1; - } - BT_STK_ENTER(dbp->dbenv, cp, h, 0, lock, lock_mode, ret); - - return (ret); -} - -/* - * __bam_search -- - * Search a btree for a key. - * - * PUBLIC: int __bam_search __P((DBC *, db_pgno_t, - * PUBLIC: const DBT *, u_int32_t, int, db_recno_t *, int *)); - */ -int -__bam_search(dbc, root_pgno, key, flags, slevel, recnop, exactp) - DBC *dbc; - db_pgno_t root_pgno; - const DBT *key; - u_int32_t flags; - int slevel, *exactp; - db_recno_t *recnop; -{ - BTREE *t; - BTREE_CURSOR *cp; - DB *dbp; - DB_LOCK lock; - DB_MPOOLFILE *mpf; - PAGE *h; - db_indx_t base, i, indx, *inp, lim; - db_lockmode_t lock_mode; - db_pgno_t pg; - db_recno_t recno; - int adjust, cmp, deloffset, ret, stack, t_ret; - int (*func) __P((DB *, const DBT *, const DBT *)); - - dbp = dbc->dbp; - mpf = dbp->mpf; - cp = (BTREE_CURSOR *)dbc->internal; - h = NULL; - t = dbp->bt_internal; - recno = 0; - - BT_STK_CLR(cp); - - /* - * There are several ways we search a btree tree. The flags argument - * specifies if we're acquiring read or write locks, if we position - * to the first or last item in a set of duplicates, if we return - * deleted items, and if we are locking pairs of pages. In addition, - * if we're modifying record numbers, we have to lock the entire tree - * regardless. See btree.h for more details. - */ - - if (root_pgno == PGNO_INVALID) - root_pgno = cp->root; - if ((ret = __bam_get_root(dbc, root_pgno, slevel, flags, &stack)) != 0) - return (ret); - lock_mode = cp->csp->lock_mode; - lock = cp->csp->lock; - h = cp->csp->page; - - BT_STK_CLR(cp); - - /* Choose a comparison function. */ - func = F_ISSET(dbc, DBC_OPD) ? - (dbp->dup_compare == NULL ? __bam_defcmp : dbp->dup_compare) : - t->bt_compare; - - for (;;) { - inp = P_INP(dbp, h); - adjust = TYPE(h) == P_LBTREE ? P_INDX : O_INDX; - if (LF_ISSET(S_MIN | S_MAX)) { - if (LF_ISSET(S_MIN) || NUM_ENT(h) == 0) - indx = 0; - else if (TYPE(h) == P_LBTREE) - indx = NUM_ENT(h) - 2; - else - indx = NUM_ENT(h) - 1; - - if (LEVEL(h) == LEAFLEVEL || - (!LF_ISSET(S_START) && LEVEL(h) == slevel)) { - if (LF_ISSET(S_NEXT)) - goto get_next; - goto found; - } - goto next; - } - /* - * Do a binary search on the current page. If we're searching - * a Btree leaf page, we have to walk the indices in groups of - * two. If we're searching an internal page or a off-page dup - * page, they're an index per page item. If we find an exact - * match on a leaf page, we're done. - */ - for (base = 0, - lim = NUM_ENT(h) / (db_indx_t)adjust; lim != 0; lim >>= 1) { - indx = base + ((lim >> 1) * adjust); - if ((ret = - __bam_cmp(dbp, key, h, indx, func, &cmp)) != 0) - goto err; - if (cmp == 0) { - if (LEVEL(h) == LEAFLEVEL || - (!LF_ISSET(S_START) && - LEVEL(h) == slevel)) { - if (LF_ISSET(S_NEXT)) - goto get_next; - goto found; - } - goto next; - } - if (cmp > 0) { - base = indx + adjust; - --lim; - } - } - - /* - * No match found. Base is the smallest index greater than - * key and may be zero or a last + O_INDX index. - * - * If it's a leaf page or the stopping point, - * return base as the "found" value. - * Delete only deletes exact matches. - */ - if (LEVEL(h) == LEAFLEVEL || - (!LF_ISSET(S_START) && LEVEL(h) == slevel)) { - *exactp = 0; - - if (LF_ISSET(S_EXACT)) { - ret = DB_NOTFOUND; - goto err; - } - - if (LF_ISSET(S_STK_ONLY)) { - BT_STK_NUM(dbp->dbenv, cp, h, base, ret); - if ((t_ret = - __LPUT(dbc, lock)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = - __memp_fput(mpf, h, 0)) != 0 && ret == 0) - ret = t_ret; - return (ret); - } - if (LF_ISSET(S_NEXT)) { -get_next: /* - * The caller could have asked for a NEXT - * at the root if the tree recently collapsed. - */ - if (PGNO(h) == root_pgno) { - ret = DB_NOTFOUND; - goto err; - } - /* - * Save the root of the subtree - * and drop the rest of the subtree - * and search down again starting at - * the next child. - */ - if ((ret = __LPUT(dbc, lock)) != 0) - goto err; - if ((ret = __memp_fput(mpf, h, 0)) != 0) - goto err; - h = NULL; - LF_SET(S_MIN); - LF_CLR(S_NEXT); - indx = cp->sp->indx + 1; - if (indx == NUM_ENT(cp->sp->page)) { - ret = DB_NOTFOUND; - cp->csp++; - goto err; - } - h = cp->sp->page; - cp->sp->page = NULL; - lock = cp->sp->lock; - LOCK_INIT(cp->sp->lock); - if ((ret = __bam_stkrel(dbc, STK_NOLOCK)) != 0) - goto err; - stack = 1; - goto next; - } - - /* - * !!! - * Possibly returning a deleted record -- DB_SET_RANGE, - * DB_KEYFIRST and DB_KEYLAST don't require an exact - * match, and we don't want to walk multiple pages here - * to find an undeleted record. This is handled by the - * calling routine. - */ - if (LF_ISSET(S_DEL) && cp->csp == cp->sp) - cp->csp++; - BT_STK_ENTER(dbp->dbenv, - cp, h, base, lock, lock_mode, ret); - if (ret != 0) - goto err; - return (0); - } - - /* - * If it's not a leaf page, record the internal page (which is - * a parent page for the key). Decrement the base by 1 if it's - * non-zero so that if a split later occurs, the inserted page - * will be to the right of the saved page. - */ - indx = base > 0 ? base - O_INDX : base; - - /* - * If we're trying to calculate the record number, sum up - * all the record numbers on this page up to the indx point. - */ -next: if (recnop != NULL) - for (i = 0; i < indx; ++i) - recno += GET_BINTERNAL(dbp, h, i)->nrecs; - - pg = GET_BINTERNAL(dbp, h, indx)->pgno; - - /* See if we are at the level to start stacking. */ - if (LF_ISSET(S_START) && slevel == LEVEL(h)) - stack = 1; - - if (LF_ISSET(S_STK_ONLY)) { - if (slevel == LEVEL(h)) { - BT_STK_NUM(dbp->dbenv, cp, h, indx, ret); - if ((t_ret = - __LPUT(dbc, lock)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = - __memp_fput(mpf, h, 0)) != 0 && ret == 0) - ret = t_ret; - return (ret); - } - BT_STK_NUMPUSH(dbp->dbenv, cp, h, indx, ret); - (void)__memp_fput(mpf, h, 0); - h = NULL; - if ((ret = __db_lget(dbc, - LCK_COUPLE_ALWAYS, pg, lock_mode, 0, &lock)) != 0) { - /* - * Discard our lock and return on failure. This - * is OK because it only happens when descending - * the tree holding read-locks. - */ - (void)__LPUT(dbc, lock); - return (ret); - } - } else if (stack) { - /* Return if this is the lowest page wanted. */ - if (LF_ISSET(S_PARENT) && slevel == LEVEL(h)) { - BT_STK_ENTER(dbp->dbenv, - cp, h, indx, lock, lock_mode, ret); - if (ret != 0) - goto err; - return (0); - } - if (LF_ISSET(S_DEL) && NUM_ENT(h) > 1) { - /* - * There was a page with a singleton pointer - * to a non-empty subtree. - */ - cp->csp--; - if ((ret = __bam_stkrel(dbc, STK_NOLOCK)) != 0) - goto err; - stack = 0; - goto do_del; - } - BT_STK_PUSH(dbp->dbenv, - cp, h, indx, lock, lock_mode, ret); - if (ret != 0) - goto err; - h = NULL; - - lock_mode = DB_LOCK_WRITE; - if ((ret = - __db_lget(dbc, 0, pg, lock_mode, 0, &lock)) != 0) - goto err; - } else { - /* - * Decide if we want to return a reference to the next - * page in the return stack. If so, lock it and never - * unlock it. - */ - if ((LF_ISSET(S_PARENT) && - (u_int8_t)(slevel + 1) >= (LEVEL(h) - 1)) || - (LEVEL(h) - 1) == LEAFLEVEL) - stack = 1; - - /* - * Returning a subtree. See if we have hit the start - * point if so save the parent and set stack. - * Otherwise free the parent and temporarily - * save this one. - * For S_DEL we need to find a page with 1 entry. - * For S_NEXT we want find the minimal subtree - * that contains the key and the next page. - * We save pages as long as we are at the right - * edge of the subtree. When we leave the right - * edge, then drop the subtree. - */ - if (!LF_ISSET(S_DEL | S_NEXT)) { - if ((ret = __memp_fput(mpf, h, 0)) != 0) - goto err; - goto lock_next; - } - - if ((LF_ISSET(S_DEL) && NUM_ENT(h) == 1)) { - stack = 1; - LF_SET(S_WRITE); - /* Push the parent. */ - cp->csp++; - /* Push this node. */ - BT_STK_PUSH(dbp->dbenv, cp, h, - indx, lock, lock_mode, ret); - if (ret != 0) - goto err; - LOCK_INIT(lock); - } else { - /* - * See if we want to save the tree so far. - * If we are looking for the next key, - * then we must save this node if we are - * at the end of the page. If not then - * discard anything we have saved so far. - * For delete only keep one node until - * we find a singleton. - */ -do_del: if (cp->csp->page != NULL) { - if (LF_ISSET(S_NEXT) && - indx == NUM_ENT(h) - 1) - cp->csp++; - else if ((ret = - __bam_stkrel(dbc, STK_NOLOCK)) != 0) - goto err; - } - /* Save this node. */ - BT_STK_ENTER(dbp->dbenv, cp, - h, indx, lock, lock_mode, ret); - if (ret != 0) - goto err; - LOCK_INIT(lock); - } - -lock_next: h = NULL; - - if (stack && LF_ISSET(S_WRITE)) - lock_mode = DB_LOCK_WRITE; - if ((ret = __db_lget(dbc, - LCK_COUPLE_ALWAYS, pg, lock_mode, 0, &lock)) != 0) { - /* - * If we fail, discard the lock we held. This - * is OK because this only happens when we are - * descending the tree holding read-locks. - */ - (void)__LPUT(dbc, lock); - if (LF_ISSET(S_DEL | S_NEXT)) - cp->csp++; - goto err; - } - } - if ((ret = __memp_fget(mpf, &pg, 0, &h)) != 0) - goto err; - } - /* NOTREACHED */ - -found: *exactp = 1; - - /* - * If we got here, we know that we have a Btree leaf or off-page - * duplicates page. If it's a Btree leaf page, we have to handle - * on-page duplicates. - * - * If there are duplicates, go to the first/last one. This is - * safe because we know that we're not going to leave the page, - * all duplicate sets that are not on overflow pages exist on a - * single leaf page. - */ - if (TYPE(h) == P_LBTREE && NUM_ENT(h) > P_INDX) { - if (LF_ISSET(S_DUPLAST)) - while (indx < (db_indx_t)(NUM_ENT(h) - P_INDX) && - inp[indx] == inp[indx + P_INDX]) - indx += P_INDX; - else if (LF_ISSET(S_DUPFIRST)) - while (indx > 0 && - inp[indx] == inp[indx - P_INDX]) - indx -= P_INDX; - } - - /* - * Now check if we are allowed to return deleted items; if not, then - * find the next (or previous) non-deleted duplicate entry. (We do - * not move from the original found key on the basis of the S_DELNO - * flag.) - */ - DB_ASSERT(recnop == NULL || LF_ISSET(S_DELNO)); - if (LF_ISSET(S_DELNO)) { - deloffset = TYPE(h) == P_LBTREE ? O_INDX : 0; - if (LF_ISSET(S_DUPLAST)) - while (B_DISSET(GET_BKEYDATA(dbp, - h, indx + deloffset)->type) && indx > 0 && - inp[indx] == inp[indx - adjust]) - indx -= adjust; - else - while (B_DISSET(GET_BKEYDATA(dbp, - h, indx + deloffset)->type) && - indx < (db_indx_t)(NUM_ENT(h) - adjust) && - inp[indx] == inp[indx + adjust]) - indx += adjust; - - /* - * If we weren't able to find a non-deleted duplicate, return - * DB_NOTFOUND. - */ - if (B_DISSET(GET_BKEYDATA(dbp, h, indx + deloffset)->type)) { - ret = DB_NOTFOUND; - goto err; - } - - /* - * Increment the record counter to point to the found element. - * Ignore any deleted key/data pairs. There doesn't need to - * be any correction for duplicates, as Btree doesn't support - * duplicates and record numbers in the same tree. - */ - if (recnop != NULL) { - DB_ASSERT(TYPE(h) == P_LBTREE); - - for (i = 0; i < indx; i += P_INDX) - if (!B_DISSET( - GET_BKEYDATA(dbp, h, i + O_INDX)->type)) - ++recno; - - /* Correct the number for a 0-base. */ - *recnop = recno + 1; - } - } - - if (LF_ISSET(S_STK_ONLY)) { - BT_STK_NUM(dbp->dbenv, cp, h, indx, ret); - if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0) - ret = t_ret; - } else { - if (LF_ISSET(S_DEL) && cp->csp == cp->sp) - cp->csp++; - BT_STK_ENTER(dbp->dbenv, cp, h, indx, lock, lock_mode, ret); - } - if (ret != 0) - goto err; - - return (0); - -err: if (h != NULL && (t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0) - ret = t_ret; - - /* Keep any not-found page locked for serializability. */ - if ((t_ret = __TLPUT(dbc, lock)) != 0 && ret == 0) - ret = t_ret; - - BT_STK_POP(cp); - __bam_stkrel(dbc, 0); - - return (ret); -} - -/* - * __bam_stkrel -- - * Release all pages currently held in the stack. - * - * PUBLIC: int __bam_stkrel __P((DBC *, u_int32_t)); - */ -int -__bam_stkrel(dbc, flags) - DBC *dbc; - u_int32_t flags; -{ - BTREE_CURSOR *cp; - DB *dbp; - DB_MPOOLFILE *mpf; - EPG *epg; - int ret, t_ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - cp = (BTREE_CURSOR *)dbc->internal; - - /* - * Release inner pages first. - * - * The caller must be sure that setting STK_NOLOCK will not effect - * either serializability or recoverability. - */ - for (ret = 0, epg = cp->sp; epg <= cp->csp; ++epg) { - if (epg->page != NULL) { - if (LF_ISSET(STK_CLRDBC) && cp->page == epg->page) { - cp->page = NULL; - LOCK_INIT(cp->lock); - } - if ((t_ret = - __memp_fput(mpf, epg->page, 0)) != 0 && ret == 0) - ret = t_ret; - /* - * XXX - * Temporary fix for #3243 -- under certain deadlock - * conditions we call here again and re-free the page. - * The correct fix is to never release a stack that - * doesn't hold items. - */ - epg->page = NULL; - } - /* - * We set this if we need to release our pins, - * but are not logically ready to have the pages - * visible. - */ - if (LF_ISSET(STK_PGONLY)) - continue; - if (LF_ISSET(STK_NOLOCK)) { - if ((t_ret = __LPUT(dbc, epg->lock)) != 0 && ret == 0) - ret = t_ret; - } else - if ((t_ret = __TLPUT(dbc, epg->lock)) != 0 && ret == 0) - ret = t_ret; - } - - /* Clear the stack, all pages have been released. */ - if (!LF_ISSET(STK_PGONLY)) - BT_STK_CLR(cp); - - return (ret); -} - -/* - * __bam_stkgrow -- - * Grow the stack. - * - * PUBLIC: int __bam_stkgrow __P((DB_ENV *, BTREE_CURSOR *)); - */ -int -__bam_stkgrow(dbenv, cp) - DB_ENV *dbenv; - BTREE_CURSOR *cp; -{ - EPG *p; - size_t entries; - int ret; - - entries = cp->esp - cp->sp; - - if ((ret = __os_calloc(dbenv, entries * 2, sizeof(EPG), &p)) != 0) - return (ret); - memcpy(p, cp->sp, entries * sizeof(EPG)); - if (cp->sp != cp->stack) - __os_free(dbenv, cp->sp); - cp->sp = p; - cp->csp = p + entries; - cp->esp = p + entries * 2; - return (0); -} diff --git a/storage/bdb/btree/bt_split.c b/storage/bdb/btree/bt_split.c deleted file mode 100644 index fb696ebf768..00000000000 --- a/storage/bdb/btree/bt_split.c +++ /dev/null @@ -1,1194 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994, 1995, 1996 - * Keith Bostic. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994, 1995 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: bt_split.c,v 12.4 2005/06/16 20:20:22 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/lock.h" -#include "dbinc/mp.h" -#include "dbinc/btree.h" - -static int __bam_broot __P((DBC *, PAGE *, PAGE *, PAGE *)); -static int __bam_page __P((DBC *, EPG *, EPG *)); -static int __bam_psplit __P((DBC *, EPG *, PAGE *, PAGE *, db_indx_t *)); -static int __bam_root __P((DBC *, EPG *)); -static int __ram_root __P((DBC *, PAGE *, PAGE *, PAGE *)); - -/* - * __bam_split -- - * Split a page. - * - * PUBLIC: int __bam_split __P((DBC *, void *, db_pgno_t *)); - */ -int -__bam_split(dbc, arg, root_pgnop) - DBC *dbc; - void *arg; - db_pgno_t *root_pgnop; -{ - BTREE_CURSOR *cp; - enum { UP, DOWN } dir; - db_pgno_t root_pgno; - int exact, level, ret; - - cp = (BTREE_CURSOR *)dbc->internal; - root_pgno = cp->root; - - /* - * The locking protocol we use to avoid deadlock to acquire locks by - * walking down the tree, but we do it as lazily as possible, locking - * the root only as a last resort. We expect all stack pages to have - * been discarded before we're called; we discard all short-term locks. - * - * When __bam_split is first called, we know that a leaf page was too - * full for an insert. We don't know what leaf page it was, but we - * have the key/recno that caused the problem. We call XX_search to - * reacquire the leaf page, but this time get both the leaf page and - * its parent, locked. We then split the leaf page and see if the new - * internal key will fit into the parent page. If it will, we're done. - * - * If it won't, we discard our current locks and repeat the process, - * only this time acquiring the parent page and its parent, locked. - * This process repeats until we succeed in the split, splitting the - * root page as the final resort. The entire process then repeats, - * as necessary, until we split a leaf page. - * - * XXX - * A traditional method of speeding this up is to maintain a stack of - * the pages traversed in the original search. You can detect if the - * stack is correct by storing the page's LSN when it was searched and - * comparing that LSN with the current one when it's locked during the - * split. This would be an easy change for this code, but I have no - * numbers that indicate it's worthwhile. - */ - for (dir = UP, level = LEAFLEVEL;; dir == UP ? ++level : --level) { - /* - * Acquire a page and its parent, locked. - */ - if ((ret = (dbc->dbtype == DB_BTREE ? - __bam_search(dbc, PGNO_INVALID, - arg, S_WRPAIR, level, NULL, &exact) : - __bam_rsearch(dbc, - (db_recno_t *)arg, S_WRPAIR, level, &exact))) != 0) - break; - - if (root_pgnop != NULL) - *root_pgnop = cp->csp[0].page->pgno == root_pgno ? - root_pgno : cp->csp[-1].page->pgno; - /* - * Split the page if it still needs it (it's possible another - * thread of control has already split the page). If we are - * guaranteed that two items will fit on the page, the split - * is no longer necessary. - */ - if (2 * B_MAXSIZEONPAGE(cp->ovflsize) - <= (db_indx_t)P_FREESPACE(dbc->dbp, cp->csp[0].page)) { - __bam_stkrel(dbc, STK_NOLOCK); - break; - } - ret = cp->csp[0].page->pgno == root_pgno ? - __bam_root(dbc, &cp->csp[0]) : - __bam_page(dbc, &cp->csp[-1], &cp->csp[0]); - BT_STK_CLR(cp); - - switch (ret) { - case 0: - /* Once we've split the leaf page, we're done. */ - if (level == LEAFLEVEL) - return (0); - - /* Switch directions. */ - if (dir == UP) - dir = DOWN; - break; - case DB_NEEDSPLIT: - /* - * It's possible to fail to split repeatedly, as other - * threads may be modifying the tree, or the page usage - * is sufficiently bad that we don't get enough space - * the first time. - */ - if (dir == DOWN) - dir = UP; - break; - default: - goto err; - } - } - -err: if (root_pgnop != NULL) - *root_pgnop = cp->root; - return (ret); -} - -/* - * __bam_root -- - * Split the root page of a btree. - */ -static int -__bam_root(dbc, cp) - DBC *dbc; - EPG *cp; -{ - DB *dbp; - DBT log_dbt; - DB_LSN log_lsn; - DB_MPOOLFILE *mpf; - PAGE *lp, *rp; - db_indx_t split; - u_int32_t opflags; - int ret, t_ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - lp = rp = NULL; - - /* Yeah, right. */ - if (cp->page->level >= MAXBTREELEVEL) { - __db_err(dbp->dbenv, - "Too many btree levels: %d", cp->page->level); - ret = ENOSPC; - goto err; - } - - /* Create new left and right pages for the split. */ - if ((ret = __db_new(dbc, TYPE(cp->page), &lp)) != 0 || - (ret = __db_new(dbc, TYPE(cp->page), &rp)) != 0) - goto err; - P_INIT(lp, dbp->pgsize, lp->pgno, - PGNO_INVALID, ISINTERNAL(cp->page) ? PGNO_INVALID : rp->pgno, - cp->page->level, TYPE(cp->page)); - P_INIT(rp, dbp->pgsize, rp->pgno, - ISINTERNAL(cp->page) ? PGNO_INVALID : lp->pgno, PGNO_INVALID, - cp->page->level, TYPE(cp->page)); - - /* Split the page. */ - if ((ret = __bam_psplit(dbc, cp, lp, rp, &split)) != 0) - goto err; - - /* Log the change. */ - if (DBC_LOGGING(dbc)) { - memset(&log_dbt, 0, sizeof(log_dbt)); - log_dbt.data = cp->page; - log_dbt.size = dbp->pgsize; - ZERO_LSN(log_lsn); - opflags = F_ISSET( - (BTREE_CURSOR *)dbc->internal, C_RECNUM) ? SPL_NRECS : 0; - if ((ret = __bam_split_log(dbp, - dbc->txn, &LSN(cp->page), 0, PGNO(lp), &LSN(lp), PGNO(rp), - &LSN(rp), (u_int32_t)NUM_ENT(lp), 0, &log_lsn, - dbc->internal->root, &log_dbt, opflags)) != 0) - goto err; - } else - LSN_NOT_LOGGED(LSN(cp->page)); - LSN(lp) = LSN(cp->page); - LSN(rp) = LSN(cp->page); - - /* Clean up the new root page. */ - if ((ret = (dbc->dbtype == DB_RECNO ? - __ram_root(dbc, cp->page, lp, rp) : - __bam_broot(dbc, cp->page, lp, rp))) != 0) - goto err; - - /* Adjust any cursors. */ - ret = __bam_ca_split(dbc, cp->page->pgno, lp->pgno, rp->pgno, split, 1); - - /* Success or error: release pages and locks. */ -err: if ((t_ret = - __memp_fput(mpf, cp->page, DB_MPOOL_DIRTY)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = __TLPUT(dbc, cp->lock)) != 0 && ret == 0) - ret = t_ret; - if (lp != NULL && - (t_ret = __memp_fput(mpf, lp, DB_MPOOL_DIRTY)) != 0 && ret == 0) - ret = t_ret; - if (rp != NULL && - (t_ret = __memp_fput(mpf, rp, DB_MPOOL_DIRTY)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __bam_page -- - * Split the non-root page of a btree. - */ -static int -__bam_page(dbc, pp, cp) - DBC *dbc; - EPG *pp, *cp; -{ - BTREE_CURSOR *bc; - DBT log_dbt; - DB_LSN log_lsn; - DB *dbp; - DB_LOCK rplock, tplock; - DB_MPOOLFILE *mpf; - DB_LSN save_lsn; - PAGE *lp, *rp, *alloc_rp, *tp; - db_indx_t split; - u_int32_t opflags; - int ret, t_ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - alloc_rp = lp = rp = tp = NULL; - LOCK_INIT(rplock); - LOCK_INIT(tplock); - ret = -1; - - /* - * Create a new right page for the split, and fill in everything - * except its LSN and page number. - * - * We malloc space for both the left and right pages, so we don't get - * a new page from the underlying buffer pool until we know the split - * is going to succeed. The reason is that we can't release locks - * acquired during the get-a-new-page process because metadata page - * locks can't be discarded on failure since we may have modified the - * free list. So, if you assume that we're holding a write lock on the - * leaf page which ran out of space and started this split (e.g., we - * have already written records to the page, or we retrieved a record - * from it with the DB_RMW flag set), failing in a split with both a - * leaf page locked and the metadata page locked can potentially lock - * up the tree badly, because we've violated the rule of always locking - * down the tree, and never up. - */ - if ((ret = __os_malloc(dbp->dbenv, dbp->pgsize, &rp)) != 0) - goto err; - P_INIT(rp, dbp->pgsize, 0, - ISINTERNAL(cp->page) ? PGNO_INVALID : PGNO(cp->page), - ISINTERNAL(cp->page) ? PGNO_INVALID : NEXT_PGNO(cp->page), - cp->page->level, TYPE(cp->page)); - - /* - * Create new left page for the split, and fill in everything - * except its LSN and next-page page number. - */ - if ((ret = __os_malloc(dbp->dbenv, dbp->pgsize, &lp)) != 0) - goto err; - P_INIT(lp, dbp->pgsize, PGNO(cp->page), - ISINTERNAL(cp->page) ? PGNO_INVALID : PREV_PGNO(cp->page), - ISINTERNAL(cp->page) ? PGNO_INVALID : 0, - cp->page->level, TYPE(cp->page)); - - /* - * Split right. - * - * Only the indices are sorted on the page, i.e., the key/data pairs - * aren't, so it's simpler to copy the data from the split page onto - * two new pages instead of copying half the data to a new right page - * and compacting the left page in place. Since the left page can't - * change, we swap the original and the allocated left page after the - * split. - */ - if ((ret = __bam_psplit(dbc, cp, lp, rp, &split)) != 0) - goto err; - - /* - * Test to see if we are going to be able to insert the new pages into - * the parent page. The interesting failure here is that the parent - * page can't hold the new keys, and has to be split in turn, in which - * case we want to release all the locks we can. - */ - if ((ret = __bam_pinsert(dbc, pp, lp, rp, BPI_SPACEONLY)) != 0) - goto err; - - /* - * Fix up the previous pointer of any leaf page following the split - * page. - * - * There's interesting deadlock situations here as we try to write-lock - * a page that's not in our direct ancestry. Consider a cursor walking - * backward through the leaf pages, that has our following page locked, - * and is waiting on a lock for the page we're splitting. In that case - * we're going to deadlock here. It's probably OK, stepping backward - * through the tree isn't a common operation. - */ - if (ISLEAF(cp->page) && NEXT_PGNO(cp->page) != PGNO_INVALID) { - if ((ret = __db_lget(dbc, - 0, NEXT_PGNO(cp->page), DB_LOCK_WRITE, 0, &tplock)) != 0) - goto err; - if ((ret = __memp_fget(mpf, &NEXT_PGNO(cp->page), 0, &tp)) != 0) - goto err; - } - - /* - * We've got everything locked down we need, and we know the split - * is going to succeed. Go and get the additional page we'll need. - */ - if ((ret = __db_new(dbc, TYPE(cp->page), &alloc_rp)) != 0) - goto err; - - /* - * Lock the new page. We need to do this for two reasons: first, the - * fast-lookup code might have a reference to this page in bt_lpgno if - * the page was recently deleted from the tree, and that code doesn't - * walk the tree and so won't encounter the parent's page lock. - * Second, a dirty reader could get to this page via the parent or old - * page after the split is done but before the transaction is committed - * or aborted. - */ - if ((ret = __db_lget(dbc, - 0, PGNO(alloc_rp), DB_LOCK_WRITE, 0, &rplock)) != 0) - goto err; - - /* - * Fix up the page numbers we didn't have before. We have to do this - * before calling __bam_pinsert because it may copy a page number onto - * the parent page and it takes the page number from its page argument. - */ - PGNO(rp) = NEXT_PGNO(lp) = PGNO(alloc_rp); - - /* Actually update the parent page. */ - if ((ret = __bam_pinsert(dbc, pp, lp, rp, 0)) != 0) - goto err; - - bc = (BTREE_CURSOR *)dbc->internal; - /* Log the change. */ - if (DBC_LOGGING(dbc)) { - memset(&log_dbt, 0, sizeof(log_dbt)); - log_dbt.data = cp->page; - log_dbt.size = dbp->pgsize; - if (tp == NULL) - ZERO_LSN(log_lsn); - opflags = F_ISSET(bc, C_RECNUM) ? SPL_NRECS : 0; - if ((ret = __bam_split_log(dbp, dbc->txn, &LSN(cp->page), 0, - PGNO(cp->page), &LSN(cp->page), PGNO(alloc_rp), - &LSN(alloc_rp), (u_int32_t)NUM_ENT(lp), - tp == NULL ? 0 : PGNO(tp), - tp == NULL ? &log_lsn : &LSN(tp), - PGNO_INVALID, &log_dbt, opflags)) != 0) - goto err; - - } else - LSN_NOT_LOGGED(LSN(cp->page)); - - /* Update the LSNs for all involved pages. */ - LSN(alloc_rp) = LSN(cp->page); - LSN(lp) = LSN(cp->page); - LSN(rp) = LSN(cp->page); - if (tp != NULL) - LSN(tp) = LSN(cp->page); - - /* - * Copy the left and right pages into place. There are two paths - * through here. Either we are logging and we set the LSNs in the - * logging path. However, if we are not logging, then we do not - * have valid LSNs on lp or rp. The correct LSNs to use are the - * ones on the page we got from __db_new or the one that was - * originally on cp->page. In both cases, we save the LSN from the - * real database page (not a malloc'd one) and reapply it after we - * do the copy. - */ - save_lsn = alloc_rp->lsn; - memcpy(alloc_rp, rp, LOFFSET(dbp, rp)); - memcpy((u_int8_t *)alloc_rp + HOFFSET(rp), - (u_int8_t *)rp + HOFFSET(rp), dbp->pgsize - HOFFSET(rp)); - alloc_rp->lsn = save_lsn; - - save_lsn = cp->page->lsn; - memcpy(cp->page, lp, LOFFSET(dbp, lp)); - memcpy((u_int8_t *)cp->page + HOFFSET(lp), - (u_int8_t *)lp + HOFFSET(lp), dbp->pgsize - HOFFSET(lp)); - cp->page->lsn = save_lsn; - - /* Fix up the next-page link. */ - if (tp != NULL) - PREV_PGNO(tp) = PGNO(rp); - - /* Adjust any cursors. */ - if ((ret = __bam_ca_split(dbc, - PGNO(cp->page), PGNO(cp->page), PGNO(rp), split, 0)) != 0) - goto err; - - __os_free(dbp->dbenv, lp); - __os_free(dbp->dbenv, rp); - - /* - * Success -- write the real pages back to the store. As we never - * acquired any sort of lock on the new page, we release it before - * releasing locks on the pages that reference it. We're finished - * modifying the page so it's not really necessary, but it's neater. - */ - if ((t_ret = - __memp_fput(mpf, alloc_rp, DB_MPOOL_DIRTY)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = __TLPUT(dbc, rplock)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = - __memp_fput(mpf, pp->page, DB_MPOOL_DIRTY)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = __TLPUT(dbc, pp->lock)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = - __memp_fput(mpf, cp->page, DB_MPOOL_DIRTY)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = __TLPUT(dbc, cp->lock)) != 0 && ret == 0) - ret = t_ret; - if (tp != NULL) { - if ((t_ret = - __memp_fput(mpf, tp, DB_MPOOL_DIRTY)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = __TLPUT(dbc, tplock)) != 0 && ret == 0) - ret = t_ret; - } - return (ret); - -err: if (lp != NULL) - __os_free(dbp->dbenv, lp); - if (rp != NULL) - __os_free(dbp->dbenv, rp); - if (alloc_rp != NULL) - (void)__memp_fput(mpf, alloc_rp, 0); - if (tp != NULL) - (void)__memp_fput(mpf, tp, 0); - - /* We never updated the new or next pages, we can release them. */ - (void)__LPUT(dbc, rplock); - (void)__LPUT(dbc, tplock); - - (void)__memp_fput(mpf, pp->page, 0); - if (ret == DB_NEEDSPLIT) - (void)__LPUT(dbc, pp->lock); - else - (void)__TLPUT(dbc, pp->lock); - - (void)__memp_fput(mpf, cp->page, 0); - if (ret == DB_NEEDSPLIT) - (void)__LPUT(dbc, cp->lock); - else - (void)__TLPUT(dbc, cp->lock); - - return (ret); -} - -/* - * __bam_broot -- - * Fix up the btree root page after it has been split. - */ -static int -__bam_broot(dbc, rootp, lp, rp) - DBC *dbc; - PAGE *rootp, *lp, *rp; -{ - BINTERNAL bi, *child_bi; - BKEYDATA *child_bk; - BTREE_CURSOR *cp; - DB *dbp; - DBT hdr, data; - db_pgno_t root_pgno; - int ret; - - dbp = dbc->dbp; - cp = (BTREE_CURSOR *)dbc->internal; - - /* - * If the root page was a leaf page, change it into an internal page. - * We copy the key we split on (but not the key's data, in the case of - * a leaf page) to the new root page. - */ - root_pgno = cp->root; - P_INIT(rootp, dbp->pgsize, - root_pgno, PGNO_INVALID, PGNO_INVALID, lp->level + 1, P_IBTREE); - - memset(&data, 0, sizeof(data)); - memset(&hdr, 0, sizeof(hdr)); - - /* - * The btree comparison code guarantees that the left-most key on any - * internal btree page is never used, so it doesn't need to be filled - * in. Set the record count if necessary. - */ - memset(&bi, 0, sizeof(bi)); - bi.len = 0; - B_TSET(bi.type, B_KEYDATA, 0); - bi.pgno = lp->pgno; - if (F_ISSET(cp, C_RECNUM)) { - bi.nrecs = __bam_total(dbp, lp); - RE_NREC_SET(rootp, bi.nrecs); - } - hdr.data = &bi; - hdr.size = SSZA(BINTERNAL, data); - if ((ret = - __db_pitem(dbc, rootp, 0, BINTERNAL_SIZE(0), &hdr, NULL)) != 0) - return (ret); - - switch (TYPE(rp)) { - case P_IBTREE: - /* Copy the first key of the child page onto the root page. */ - child_bi = GET_BINTERNAL(dbp, rp, 0); - - bi.len = child_bi->len; - B_TSET(bi.type, child_bi->type, 0); - bi.pgno = rp->pgno; - if (F_ISSET(cp, C_RECNUM)) { - bi.nrecs = __bam_total(dbp, rp); - RE_NREC_ADJ(rootp, bi.nrecs); - } - hdr.data = &bi; - hdr.size = SSZA(BINTERNAL, data); - data.data = child_bi->data; - data.size = child_bi->len; - if ((ret = __db_pitem(dbc, rootp, 1, - BINTERNAL_SIZE(child_bi->len), &hdr, &data)) != 0) - return (ret); - - /* Increment the overflow ref count. */ - if (B_TYPE(child_bi->type) == B_OVERFLOW) - if ((ret = __db_ovref(dbc, - ((BOVERFLOW *)(child_bi->data))->pgno, 1)) != 0) - return (ret); - break; - case P_LDUP: - case P_LBTREE: - /* Copy the first key of the child page onto the root page. */ - child_bk = GET_BKEYDATA(dbp, rp, 0); - switch (B_TYPE(child_bk->type)) { - case B_KEYDATA: - bi.len = child_bk->len; - B_TSET(bi.type, child_bk->type, 0); - bi.pgno = rp->pgno; - if (F_ISSET(cp, C_RECNUM)) { - bi.nrecs = __bam_total(dbp, rp); - RE_NREC_ADJ(rootp, bi.nrecs); - } - hdr.data = &bi; - hdr.size = SSZA(BINTERNAL, data); - data.data = child_bk->data; - data.size = child_bk->len; - if ((ret = __db_pitem(dbc, rootp, 1, - BINTERNAL_SIZE(child_bk->len), &hdr, &data)) != 0) - return (ret); - break; - case B_DUPLICATE: - case B_OVERFLOW: - bi.len = BOVERFLOW_SIZE; - B_TSET(bi.type, child_bk->type, 0); - bi.pgno = rp->pgno; - if (F_ISSET(cp, C_RECNUM)) { - bi.nrecs = __bam_total(dbp, rp); - RE_NREC_ADJ(rootp, bi.nrecs); - } - hdr.data = &bi; - hdr.size = SSZA(BINTERNAL, data); - data.data = child_bk; - data.size = BOVERFLOW_SIZE; - if ((ret = __db_pitem(dbc, rootp, 1, - BINTERNAL_SIZE(BOVERFLOW_SIZE), &hdr, &data)) != 0) - return (ret); - - /* Increment the overflow ref count. */ - if (B_TYPE(child_bk->type) == B_OVERFLOW) - if ((ret = __db_ovref(dbc, - ((BOVERFLOW *)child_bk)->pgno, 1)) != 0) - return (ret); - break; - default: - return (__db_pgfmt(dbp->dbenv, rp->pgno)); - } - break; - default: - return (__db_pgfmt(dbp->dbenv, rp->pgno)); - } - return (0); -} - -/* - * __ram_root -- - * Fix up the recno root page after it has been split. - */ -static int -__ram_root(dbc, rootp, lp, rp) - DBC *dbc; - PAGE *rootp, *lp, *rp; -{ - DB *dbp; - DBT hdr; - RINTERNAL ri; - db_pgno_t root_pgno; - int ret; - - dbp = dbc->dbp; - root_pgno = dbc->internal->root; - - /* Initialize the page. */ - P_INIT(rootp, dbp->pgsize, - root_pgno, PGNO_INVALID, PGNO_INVALID, lp->level + 1, P_IRECNO); - - /* Initialize the header. */ - memset(&hdr, 0, sizeof(hdr)); - hdr.data = &ri; - hdr.size = RINTERNAL_SIZE; - - /* Insert the left and right keys, set the header information. */ - ri.pgno = lp->pgno; - ri.nrecs = __bam_total(dbp, lp); - if ((ret = __db_pitem(dbc, rootp, 0, RINTERNAL_SIZE, &hdr, NULL)) != 0) - return (ret); - RE_NREC_SET(rootp, ri.nrecs); - ri.pgno = rp->pgno; - ri.nrecs = __bam_total(dbp, rp); - if ((ret = __db_pitem(dbc, rootp, 1, RINTERNAL_SIZE, &hdr, NULL)) != 0) - return (ret); - RE_NREC_ADJ(rootp, ri.nrecs); - return (0); -} - -/* - * __bam_pinsert -- - * Insert a new key into a parent page, completing the split. - * - * PUBLIC: int __bam_pinsert __P((DBC *, EPG *, PAGE *, PAGE *, int)); - */ -int -__bam_pinsert(dbc, parent, lchild, rchild, flags) - DBC *dbc; - EPG *parent; - PAGE *lchild, *rchild; - int flags; -{ - BINTERNAL bi, *child_bi; - BKEYDATA *child_bk, *tmp_bk; - BTREE *t; - BTREE_CURSOR *cp; - DB *dbp; - DBT a, b, hdr, data; - PAGE *ppage; - RINTERNAL ri; - db_indx_t off; - db_recno_t nrecs; - size_t (*func) __P((DB *, const DBT *, const DBT *)); - u_int32_t n, nbytes, nksize; - int ret; - - dbp = dbc->dbp; - cp = (BTREE_CURSOR *)dbc->internal; - t = dbp->bt_internal; - ppage = parent->page; - - /* If handling record numbers, count records split to the right page. */ - nrecs = F_ISSET(cp, C_RECNUM) && - !LF_ISSET(BPI_SPACEONLY) ? __bam_total(dbp, rchild) : 0; - - /* - * Now we insert the new page's first key into the parent page, which - * completes the split. The parent points to a PAGE and a page index - * offset, where the new key goes ONE AFTER the index, because we split - * to the right. - * - * XXX - * Some btree algorithms replace the key for the old page as well as - * the new page. We don't, as there's no reason to believe that the - * first key on the old page is any better than the key we have, and, - * in the case of a key being placed at index 0 causing the split, the - * key is unavailable. - */ - off = parent->indx + O_INDX; - - /* - * Calculate the space needed on the parent page. - * - * Prefix trees: space hack used when inserting into BINTERNAL pages. - * Retain only what's needed to distinguish between the new entry and - * the LAST entry on the page to its left. If the keys compare equal, - * retain the entire key. We ignore overflow keys, and the entire key - * must be retained for the next-to-leftmost key on the leftmost page - * of each level, or the search will fail. Applicable ONLY to internal - * pages that have leaf pages as children. Further reduction of the - * key between pairs of internal pages loses too much information. - */ - switch (TYPE(rchild)) { - case P_IBTREE: - child_bi = GET_BINTERNAL(dbp, rchild, 0); - nbytes = BINTERNAL_PSIZE(child_bi->len); - - if (P_FREESPACE(dbp, ppage) < nbytes) - return (DB_NEEDSPLIT); - if (LF_ISSET(BPI_SPACEONLY)) - return (0); - - /* Add a new record for the right page. */ - memset(&bi, 0, sizeof(bi)); - bi.len = child_bi->len; - B_TSET(bi.type, child_bi->type, 0); - bi.pgno = rchild->pgno; - bi.nrecs = nrecs; - memset(&hdr, 0, sizeof(hdr)); - hdr.data = &bi; - hdr.size = SSZA(BINTERNAL, data); - memset(&data, 0, sizeof(data)); - data.data = child_bi->data; - data.size = child_bi->len; - if ((ret = __db_pitem(dbc, ppage, off, - BINTERNAL_SIZE(child_bi->len), &hdr, &data)) != 0) - return (ret); - - /* Increment the overflow ref count. */ - if (B_TYPE(child_bi->type) == B_OVERFLOW) - if ((ret = __db_ovref(dbc, - ((BOVERFLOW *)(child_bi->data))->pgno, 1)) != 0) - return (ret); - break; - case P_LDUP: - case P_LBTREE: - child_bk = GET_BKEYDATA(dbp, rchild, 0); - switch (B_TYPE(child_bk->type)) { - case B_KEYDATA: - nbytes = BINTERNAL_PSIZE(child_bk->len); - nksize = child_bk->len; - - /* - * Prefix compression: - * We set t->bt_prefix to NULL if we have a comparison - * callback but no prefix compression callback. But, - * if we're splitting in an off-page duplicates tree, - * we still have to do some checking. If using the - * default off-page duplicates comparison routine we - * can use the default prefix compression callback. If - * not using the default off-page duplicates comparison - * routine, we can't do any kind of prefix compression - * as there's no way for an application to specify a - * prefix compression callback that corresponds to its - * comparison callback. - * - * No prefix compression if we don't have a compression - * function, or the key we'd compress isn't a normal - * key (for example, it references an overflow page). - * - * Generate a parent page key for the right child page - * from a comparison of the last key on the left child - * page and the first key on the right child page. - */ - if (F_ISSET(dbc, DBC_OPD)) { - if (dbp->dup_compare == __bam_defcmp) - func = __bam_defpfx; - else - func = NULL; - } else - func = t->bt_prefix; - if (func == NULL) - goto noprefix; - tmp_bk = GET_BKEYDATA(dbp, lchild, NUM_ENT(lchild) - - (TYPE(lchild) == P_LDUP ? O_INDX : P_INDX)); - if (B_TYPE(tmp_bk->type) != B_KEYDATA) - goto noprefix; - memset(&a, 0, sizeof(a)); - a.size = tmp_bk->len; - a.data = tmp_bk->data; - memset(&b, 0, sizeof(b)); - b.size = child_bk->len; - b.data = child_bk->data; - nksize = (u_int32_t)func(dbp, &a, &b); - if ((n = BINTERNAL_PSIZE(nksize)) < nbytes) - nbytes = n; - else - nksize = child_bk->len; - -noprefix: if (P_FREESPACE(dbp, ppage) < nbytes) - return (DB_NEEDSPLIT); - if (LF_ISSET(BPI_SPACEONLY)) - return (0); - - memset(&bi, 0, sizeof(bi)); - bi.len = nksize; - B_TSET(bi.type, child_bk->type, 0); - bi.pgno = rchild->pgno; - bi.nrecs = nrecs; - memset(&hdr, 0, sizeof(hdr)); - hdr.data = &bi; - hdr.size = SSZA(BINTERNAL, data); - memset(&data, 0, sizeof(data)); - data.data = child_bk->data; - data.size = nksize; - if ((ret = __db_pitem(dbc, ppage, off, - BINTERNAL_SIZE(nksize), &hdr, &data)) != 0) - return (ret); - break; - case B_DUPLICATE: - case B_OVERFLOW: - nbytes = BINTERNAL_PSIZE(BOVERFLOW_SIZE); - - if (P_FREESPACE(dbp, ppage) < nbytes) - return (DB_NEEDSPLIT); - if (LF_ISSET(BPI_SPACEONLY)) - return (0); - - memset(&bi, 0, sizeof(bi)); - bi.len = BOVERFLOW_SIZE; - B_TSET(bi.type, child_bk->type, 0); - bi.pgno = rchild->pgno; - bi.nrecs = nrecs; - memset(&hdr, 0, sizeof(hdr)); - hdr.data = &bi; - hdr.size = SSZA(BINTERNAL, data); - memset(&data, 0, sizeof(data)); - data.data = child_bk; - data.size = BOVERFLOW_SIZE; - if ((ret = __db_pitem(dbc, ppage, off, - BINTERNAL_SIZE(BOVERFLOW_SIZE), &hdr, &data)) != 0) - return (ret); - - /* Increment the overflow ref count. */ - if (B_TYPE(child_bk->type) == B_OVERFLOW) - if ((ret = __db_ovref(dbc, - ((BOVERFLOW *)child_bk)->pgno, 1)) != 0) - return (ret); - break; - default: - return (__db_pgfmt(dbp->dbenv, rchild->pgno)); - } - break; - case P_IRECNO: - case P_LRECNO: - nbytes = RINTERNAL_PSIZE; - - if (P_FREESPACE(dbp, ppage) < nbytes) - return (DB_NEEDSPLIT); - if (LF_ISSET(BPI_SPACEONLY)) - return (0); - - /* Add a new record for the right page. */ - memset(&hdr, 0, sizeof(hdr)); - hdr.data = &ri; - hdr.size = RINTERNAL_SIZE; - ri.pgno = rchild->pgno; - ri.nrecs = nrecs; - if ((ret = __db_pitem(dbc, - ppage, off, RINTERNAL_SIZE, &hdr, NULL)) != 0) - return (ret); - break; - default: - return (__db_pgfmt(dbp->dbenv, rchild->pgno)); - } - - /* - * If a Recno or Btree with record numbers AM page, or an off-page - * duplicates tree, adjust the parent page's left page record count. - */ - if (F_ISSET(cp, C_RECNUM) && !LF_ISSET(BPI_NORECNUM)) { - /* Log the change. */ - if (DBC_LOGGING(dbc)) { - if ((ret = __bam_cadjust_log(dbp, dbc->txn, - &LSN(ppage), 0, PGNO(ppage), &LSN(ppage), - parent->indx, -(int32_t)nrecs, 0)) != 0) - return (ret); - } else - LSN_NOT_LOGGED(LSN(ppage)); - - /* Update the left page count. */ - if (dbc->dbtype == DB_RECNO) - GET_RINTERNAL(dbp, ppage, parent->indx)->nrecs -= nrecs; - else - GET_BINTERNAL(dbp, ppage, parent->indx)->nrecs -= nrecs; - } - - return (0); -} - -/* - * __bam_psplit -- - * Do the real work of splitting the page. - */ -static int -__bam_psplit(dbc, cp, lp, rp, splitret) - DBC *dbc; - EPG *cp; - PAGE *lp, *rp; - db_indx_t *splitret; -{ - DB *dbp; - PAGE *pp; - db_indx_t half, *inp, nbytes, off, splitp, top; - int adjust, cnt, iflag, isbigkey, ret; - - dbp = dbc->dbp; - pp = cp->page; - inp = P_INP(dbp, pp); - adjust = TYPE(pp) == P_LBTREE ? P_INDX : O_INDX; - - /* - * If we're splitting the first (last) page on a level because we're - * inserting (appending) a key to it, it's likely that the data is - * sorted. Moving a single item to the new page is less work and can - * push the fill factor higher than normal. This is trivial when we - * are splitting a new page before the beginning of the tree, all of - * the interesting tests are against values of 0. - * - * Catching appends to the tree is harder. In a simple append, we're - * inserting an item that sorts past the end of the tree; the cursor - * will point past the last element on the page. But, in trees with - * duplicates, the cursor may point to the last entry on the page -- - * in this case, the entry will also be the last element of a duplicate - * set (the last because the search call specified the S_DUPLAST flag). - * The only way to differentiate between an insert immediately before - * the last item in a tree or an append after a duplicate set which is - * also the last item in the tree is to call the comparison function. - * When splitting internal pages during an append, the search code - * guarantees the cursor always points to the largest page item less - * than the new internal entry. To summarize, we want to catch three - * possible index values: - * - * NUM_ENT(page) Btree/Recno leaf insert past end-of-tree - * NUM_ENT(page) - O_INDX Btree or Recno internal insert past EOT - * NUM_ENT(page) - P_INDX Btree leaf insert past EOT after a set - * of duplicates - * - * two of which, (NUM_ENT(page) - O_INDX or P_INDX) might be an insert - * near the end of the tree, and not after the end of the tree at all. - * Do a simple test which might be wrong because calling the comparison - * functions is expensive. Regardless, it's not a big deal if we're - * wrong, we'll do the split the right way next time. - */ - off = 0; - if (NEXT_PGNO(pp) == PGNO_INVALID && cp->indx >= NUM_ENT(pp) - adjust) - off = NUM_ENT(pp) - adjust; - else if (PREV_PGNO(pp) == PGNO_INVALID && cp->indx == 0) - off = adjust; - if (off != 0) - goto sort; - - /* - * Split the data to the left and right pages. Try not to split on - * an overflow key. (Overflow keys on internal pages will slow down - * searches.) Refuse to split in the middle of a set of duplicates. - * - * First, find the optimum place to split. - * - * It's possible to try and split past the last record on the page if - * there's a very large record at the end of the page. Make sure this - * doesn't happen by bounding the check at the next-to-last entry on - * the page. - * - * Note, we try and split half the data present on the page. This is - * because another process may have already split the page and left - * it half empty. We don't try and skip the split -- we don't know - * how much space we're going to need on the page, and we may need up - * to half the page for a big item, so there's no easy test to decide - * if we need to split or not. Besides, if two threads are inserting - * data into the same place in the database, we're probably going to - * need more space soon anyway. - */ - top = NUM_ENT(pp) - adjust; - half = (dbp->pgsize - HOFFSET(pp)) / 2; - for (nbytes = 0, off = 0; off < top && nbytes < half; ++off) - switch (TYPE(pp)) { - case P_IBTREE: - if (B_TYPE( - GET_BINTERNAL(dbp, pp, off)->type) == B_KEYDATA) - nbytes += BINTERNAL_SIZE( - GET_BINTERNAL(dbp, pp, off)->len); - else - nbytes += BINTERNAL_SIZE(BOVERFLOW_SIZE); - break; - case P_LBTREE: - if (B_TYPE(GET_BKEYDATA(dbp, pp, off)->type) == - B_KEYDATA) - nbytes += BKEYDATA_SIZE(GET_BKEYDATA(dbp, - pp, off)->len); - else - nbytes += BOVERFLOW_SIZE; - - ++off; - /* FALLTHROUGH */ - case P_LDUP: - case P_LRECNO: - if (B_TYPE(GET_BKEYDATA(dbp, pp, off)->type) == - B_KEYDATA) - nbytes += BKEYDATA_SIZE(GET_BKEYDATA(dbp, - pp, off)->len); - else - nbytes += BOVERFLOW_SIZE; - break; - case P_IRECNO: - nbytes += RINTERNAL_SIZE; - break; - default: - return (__db_pgfmt(dbp->dbenv, pp->pgno)); - } -sort: splitp = off; - - /* - * Splitp is either at or just past the optimum split point. If the - * tree type is such that we're going to promote a key to an internal - * page, and our current choice is an overflow key, look for something - * close by that's smaller. - */ - switch (TYPE(pp)) { - case P_IBTREE: - iflag = 1; - isbigkey = - B_TYPE(GET_BINTERNAL(dbp, pp, off)->type) != B_KEYDATA; - break; - case P_LBTREE: - case P_LDUP: - iflag = 0; - isbigkey = B_TYPE(GET_BKEYDATA(dbp, pp, off)->type) != - B_KEYDATA; - break; - default: - iflag = isbigkey = 0; - } - if (isbigkey) - for (cnt = 1; cnt <= 3; ++cnt) { - off = splitp + cnt * adjust; - if (off < (db_indx_t)NUM_ENT(pp) && - ((iflag && B_TYPE( - GET_BINTERNAL(dbp, pp,off)->type) == B_KEYDATA) || - B_TYPE(GET_BKEYDATA(dbp, pp, off)->type) == - B_KEYDATA)) { - splitp = off; - break; - } - if (splitp <= (db_indx_t)(cnt * adjust)) - continue; - off = splitp - cnt * adjust; - if (iflag ? B_TYPE( - GET_BINTERNAL(dbp, pp, off)->type) == B_KEYDATA : - B_TYPE(GET_BKEYDATA(dbp, pp, off)->type) == - B_KEYDATA) { - splitp = off; - break; - } - } - - /* - * We can't split in the middle a set of duplicates. We know that - * no duplicate set can take up more than about 25% of the page, - * because that's the point where we push it off onto a duplicate - * page set. So, this loop can't be unbounded. - */ - if (TYPE(pp) == P_LBTREE && - inp[splitp] == inp[splitp - adjust]) - for (cnt = 1;; ++cnt) { - off = splitp + cnt * adjust; - if (off < NUM_ENT(pp) && - inp[splitp] != inp[off]) { - splitp = off; - break; - } - if (splitp <= (db_indx_t)(cnt * adjust)) - continue; - off = splitp - cnt * adjust; - if (inp[splitp] != inp[off]) { - splitp = off + adjust; - break; - } - } - - /* We're going to split at splitp. */ - if ((ret = __bam_copy(dbp, pp, lp, 0, splitp)) != 0) - return (ret); - if ((ret = __bam_copy(dbp, pp, rp, splitp, NUM_ENT(pp))) != 0) - return (ret); - - *splitret = splitp; - return (0); -} - -/* - * __bam_copy -- - * Copy a set of records from one page to another. - * - * PUBLIC: int __bam_copy __P((DB *, PAGE *, PAGE *, u_int32_t, u_int32_t)); - */ -int -__bam_copy(dbp, pp, cp, nxt, stop) - DB *dbp; - PAGE *pp, *cp; - u_int32_t nxt, stop; -{ - db_indx_t *cinp, nbytes, off, *pinp; - - cinp = P_INP(dbp, cp); - pinp = P_INP(dbp, pp); - /* - * Nxt is the offset of the next record to be placed on the target page. - */ - for (off = 0; nxt < stop; ++nxt, ++NUM_ENT(cp), ++off) { - switch (TYPE(pp)) { - case P_IBTREE: - if (B_TYPE( - GET_BINTERNAL(dbp, pp, nxt)->type) == B_KEYDATA) - nbytes = BINTERNAL_SIZE( - GET_BINTERNAL(dbp, pp, nxt)->len); - else - nbytes = BINTERNAL_SIZE(BOVERFLOW_SIZE); - break; - case P_LBTREE: - /* - * If we're on a key and it's a duplicate, just copy - * the offset. - */ - if (off != 0 && (nxt % P_INDX) == 0 && - pinp[nxt] == pinp[nxt - P_INDX]) { - cinp[off] = cinp[off - P_INDX]; - continue; - } - /* FALLTHROUGH */ - case P_LDUP: - case P_LRECNO: - if (B_TYPE(GET_BKEYDATA(dbp, pp, nxt)->type) == - B_KEYDATA) - nbytes = BKEYDATA_SIZE(GET_BKEYDATA(dbp, - pp, nxt)->len); - else - nbytes = BOVERFLOW_SIZE; - break; - case P_IRECNO: - nbytes = RINTERNAL_SIZE; - break; - default: - return (__db_pgfmt(dbp->dbenv, pp->pgno)); - } - cinp[off] = HOFFSET(cp) -= nbytes; - memcpy(P_ENTRY(dbp, cp, off), P_ENTRY(dbp, pp, nxt), nbytes); - } - return (0); -} diff --git a/storage/bdb/btree/bt_stat.c b/storage/bdb/btree/bt_stat.c deleted file mode 100644 index 98e3b9561f7..00000000000 --- a/storage/bdb/btree/bt_stat.c +++ /dev/null @@ -1,638 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: bt_stat.c,v 12.3 2005/06/16 20:20:23 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <ctype.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/btree.h" -#include "dbinc/lock.h" -#include "dbinc/mp.h" - -#ifdef HAVE_STATISTICS -/* - * __bam_stat -- - * Gather/print the btree statistics - * - * PUBLIC: int __bam_stat __P((DBC *, void *, u_int32_t)); - */ -int -__bam_stat(dbc, spp, flags) - DBC *dbc; - void *spp; - u_int32_t flags; -{ - BTMETA *meta; - BTREE *t; - BTREE_CURSOR *cp; - DB *dbp; - DB_BTREE_STAT *sp; - DB_ENV *dbenv; - DB_LOCK lock, metalock; - DB_MPOOLFILE *mpf; - PAGE *h; - db_pgno_t pgno; - int ret, t_ret, write_meta; - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - - meta = NULL; - t = dbp->bt_internal; - sp = NULL; - LOCK_INIT(metalock); - LOCK_INIT(lock); - mpf = dbp->mpf; - h = NULL; - ret = write_meta = 0; - - cp = (BTREE_CURSOR *)dbc->internal; - - /* Allocate and clear the structure. */ - if ((ret = __os_umalloc(dbenv, sizeof(*sp), &sp)) != 0) - goto err; - memset(sp, 0, sizeof(*sp)); - - /* Get the metadata page for the entire database. */ - pgno = PGNO_BASE_MD; - if ((ret = __db_lget(dbc, 0, pgno, DB_LOCK_READ, 0, &metalock)) != 0) - goto err; - if ((ret = __memp_fget(mpf, &pgno, 0, &meta)) != 0) - goto err; - - if (flags == DB_RECORDCOUNT || flags == DB_CACHED_COUNTS) - flags = DB_FAST_STAT; - if (flags == DB_FAST_STAT) - goto meta_only; - - /* Walk the metadata free list, counting pages. */ - for (sp->bt_free = 0, pgno = meta->dbmeta.free; pgno != PGNO_INVALID;) { - ++sp->bt_free; - - if ((ret = __memp_fget(mpf, &pgno, 0, &h)) != 0) - goto err; - - pgno = h->next_pgno; - if ((ret = __memp_fput(mpf, h, 0)) != 0) - goto err; - h = NULL; - } - - /* Get the root page. */ - pgno = cp->root; - if ((ret = __db_lget(dbc, 0, pgno, DB_LOCK_READ, 0, &lock)) != 0) - goto err; - if ((ret = __memp_fget(mpf, &pgno, 0, &h)) != 0) - goto err; - - /* Get the levels from the root page. */ - sp->bt_levels = h->level; - - /* Discard the root page. */ - ret = __memp_fput(mpf, h, 0); - h = NULL; - if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0) - ret = t_ret; - if (ret != 0) - goto err; - - /* Walk the tree. */ - if ((ret = __bam_traverse(dbc, - DB_LOCK_READ, cp->root, __bam_stat_callback, sp)) != 0) - goto err; - - /* - * Get the subdatabase metadata page if it's not the same as the - * one we already have. - */ - write_meta = !F_ISSET(dbp, DB_AM_RDONLY); -meta_only: - if (t->bt_meta != PGNO_BASE_MD || write_meta != 0) { - ret = __memp_fput(mpf, meta, 0); - meta = NULL; - if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0) - ret = t_ret; - if (ret != 0) - goto err; - - if ((ret = __db_lget(dbc, - 0, t->bt_meta, write_meta == 0 ? - DB_LOCK_READ : DB_LOCK_WRITE, 0, &metalock)) != 0) - goto err; - if ((ret = __memp_fget(mpf, &t->bt_meta, 0, &meta)) != 0) - goto err; - } - if (flags == DB_FAST_STAT) { - if (dbp->type == DB_RECNO || - (dbp->type == DB_BTREE && F_ISSET(dbp, DB_AM_RECNUM))) { - if ((ret = __db_lget(dbc, 0, - cp->root, DB_LOCK_READ, 0, &lock)) != 0) - goto err; - if ((ret = __memp_fget(mpf, &cp->root, 0, &h)) != 0) - goto err; - - sp->bt_nkeys = RE_NREC(h); - } else - sp->bt_nkeys = meta->dbmeta.key_count; - - sp->bt_ndata = dbp->type == DB_RECNO ? - sp->bt_nkeys : meta->dbmeta.record_count; - } - - /* Get metadata page statistics. */ - sp->bt_metaflags = meta->dbmeta.flags; - sp->bt_minkey = meta->minkey; - sp->bt_re_len = meta->re_len; - sp->bt_re_pad = meta->re_pad; - sp->bt_pagesize = meta->dbmeta.pagesize; - sp->bt_magic = meta->dbmeta.magic; - sp->bt_version = meta->dbmeta.version; - - if (write_meta != 0) { - meta->dbmeta.key_count = sp->bt_nkeys; - meta->dbmeta.record_count = sp->bt_ndata; - } - - *(DB_BTREE_STAT **)spp = sp; - -err: /* Discard the second page. */ - if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0) - ret = t_ret; - if (h != NULL && (t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0) - ret = t_ret; - - /* Discard the metadata page. */ - if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0) - ret = t_ret; - if (meta != NULL && (t_ret = __memp_fput( - mpf, meta, write_meta == 0 ? 0 : DB_MPOOL_DIRTY)) != 0 && ret == 0) - ret = t_ret; - - if (ret != 0 && sp != NULL) { - __os_ufree(dbenv, sp); - *(DB_BTREE_STAT **)spp = NULL; - } - - return (ret); -} - -/* - * __bam_stat_print -- - * Display btree/recno statistics. - * - * PUBLIC: int __bam_stat_print __P((DBC *, u_int32_t)); - */ -int -__bam_stat_print(dbc, flags) - DBC *dbc; - u_int32_t flags; -{ - static const FN fn[] = { - { BTM_DUP, "duplicates" }, - { BTM_RECNO, "recno" }, - { BTM_RECNUM, "record-numbers" }, - { BTM_FIXEDLEN, "fixed-length" }, - { BTM_RENUMBER, "renumber" }, - { BTM_SUBDB, "multiple-databases" }, - { BTM_DUPSORT, "sorted duplicates" }, - { 0, NULL } - }; - DB *dbp; - DB_BTREE_STAT *sp; - DB_ENV *dbenv; - int lorder, ret; - const char *s; - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - - if ((ret = __bam_stat(dbc, &sp, 0)) != 0) - return (ret); - - if (LF_ISSET(DB_STAT_ALL)) { - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_msg(dbenv, "Default Btree/Recno database information:"); - } - - __db_msg(dbenv, "%lx\tBtree magic number", (u_long)sp->bt_magic); - __db_msg(dbenv, "%lu\tBtree version number", (u_long)sp->bt_version); - - (void)__db_get_lorder(dbp, &lorder); - switch (lorder) { - case 1234: - s = "Little-endian"; - break; - case 4321: - s = "Big-endian"; - break; - default: - s = "Unrecognized byte order"; - break; - } - __db_msg(dbenv, "%s\tByte order", s); - __db_prflags(dbenv, NULL, sp->bt_metaflags, fn, NULL, "\tFlags"); - if (dbp->type == DB_BTREE) - __db_dl(dbenv, "Minimum keys per-page", (u_long)sp->bt_minkey); - if (dbp->type == DB_RECNO) { - __db_dl(dbenv, - "Fixed-length record size", (u_long)sp->bt_re_len); - __db_msg(dbenv, - "%#x\tFixed-length record pad", (u_int)sp->bt_re_pad); - } - __db_dl(dbenv, - "Underlying database page size", (u_long)sp->bt_pagesize); - __db_dl(dbenv, "Number of levels in the tree", (u_long)sp->bt_levels); - __db_dl(dbenv, dbp->type == DB_BTREE ? - "Number of unique keys in the tree" : - "Number of records in the tree", (u_long)sp->bt_nkeys); - __db_dl(dbenv, - "Number of data items in the tree", (u_long)sp->bt_ndata); - - __db_dl(dbenv, - "Number of tree internal pages", (u_long)sp->bt_int_pg); - __db_dl_pct(dbenv, - "Number of bytes free in tree internal pages", - (u_long)sp->bt_int_pgfree, - DB_PCT_PG(sp->bt_int_pgfree, sp->bt_int_pg, sp->bt_pagesize), "ff"); - - __db_dl(dbenv, - "Number of tree leaf pages", (u_long)sp->bt_leaf_pg); - __db_dl_pct(dbenv, "Number of bytes free in tree leaf pages", - (u_long)sp->bt_leaf_pgfree, DB_PCT_PG( - sp->bt_leaf_pgfree, sp->bt_leaf_pg, sp->bt_pagesize), "ff"); - - __db_dl(dbenv, - "Number of tree duplicate pages", (u_long)sp->bt_dup_pg); - __db_dl_pct(dbenv, - "Number of bytes free in tree duplicate pages", - (u_long)sp->bt_dup_pgfree, - DB_PCT_PG(sp->bt_dup_pgfree, sp->bt_dup_pg, sp->bt_pagesize), "ff"); - - __db_dl(dbenv, - "Number of tree overflow pages", (u_long)sp->bt_over_pg); - __db_dl_pct(dbenv, "Number of bytes free in tree overflow pages", - (u_long)sp->bt_over_pgfree, DB_PCT_PG( - sp->bt_over_pgfree, sp->bt_over_pg, sp->bt_pagesize), "ff"); - __db_dl(dbenv, "Number of empty pages", (u_long)sp->bt_empty_pg); - - __db_dl(dbenv, "Number of pages on the free list", (u_long)sp->bt_free); - - __os_ufree(dbenv, sp); - - return (0); -} - -/* - * __bam_stat_callback -- - * Statistics callback. - * - * PUBLIC: int __bam_stat_callback __P((DB *, PAGE *, void *, int *)); - */ -int -__bam_stat_callback(dbp, h, cookie, putp) - DB *dbp; - PAGE *h; - void *cookie; - int *putp; -{ - DB_BTREE_STAT *sp; - db_indx_t indx, *inp, top; - u_int8_t type; - - sp = cookie; - *putp = 0; - top = NUM_ENT(h); - inp = P_INP(dbp, h); - - switch (TYPE(h)) { - case P_IBTREE: - case P_IRECNO: - ++sp->bt_int_pg; - sp->bt_int_pgfree += P_FREESPACE(dbp, h); - break; - case P_LBTREE: - if (top == 0) - ++sp->bt_empty_pg; - - /* Correct for on-page duplicates and deleted items. */ - for (indx = 0; indx < top; indx += P_INDX) { - type = GET_BKEYDATA(dbp, h, indx + O_INDX)->type; - /* Ignore deleted items. */ - if (B_DISSET(type)) - continue; - - /* Ignore duplicate keys. */ - if (indx + P_INDX >= top || - inp[indx] != inp[indx + P_INDX]) - ++sp->bt_nkeys; - - /* Ignore off-page duplicates. */ - if (B_TYPE(type) != B_DUPLICATE) - ++sp->bt_ndata; - } - - ++sp->bt_leaf_pg; - sp->bt_leaf_pgfree += P_FREESPACE(dbp, h); - break; - case P_LRECNO: - if (top == 0) - ++sp->bt_empty_pg; - - /* - * If walking a recno tree, then each of these items is a key. - * Otherwise, we're walking an off-page duplicate set. - */ - if (dbp->type == DB_RECNO) { - /* - * Correct for deleted items in non-renumbering Recno - * databases. - */ - if (F_ISSET(dbp, DB_AM_RENUMBER)) { - sp->bt_nkeys += top; - sp->bt_ndata += top; - } else - for (indx = 0; indx < top; indx += O_INDX) { - type = GET_BKEYDATA(dbp, h, indx)->type; - if (!B_DISSET(type)) { - ++sp->bt_ndata; - ++sp->bt_nkeys; - } - } - - ++sp->bt_leaf_pg; - sp->bt_leaf_pgfree += P_FREESPACE(dbp, h); - } else { - sp->bt_ndata += top; - - ++sp->bt_dup_pg; - sp->bt_dup_pgfree += P_FREESPACE(dbp, h); - } - break; - case P_LDUP: - if (top == 0) - ++sp->bt_empty_pg; - - /* Correct for deleted items. */ - for (indx = 0; indx < top; indx += O_INDX) - if (!B_DISSET(GET_BKEYDATA(dbp, h, indx)->type)) - ++sp->bt_ndata; - - ++sp->bt_dup_pg; - sp->bt_dup_pgfree += P_FREESPACE(dbp, h); - break; - case P_OVERFLOW: - ++sp->bt_over_pg; - sp->bt_over_pgfree += P_OVFLSPACE(dbp, dbp->pgsize, h); - break; - default: - return (__db_pgfmt(dbp->dbenv, h->pgno)); - } - return (0); -} - -/* - * __bam_print_cursor -- - * Display the current internal cursor. - * - * PUBLIC: void __bam_print_cursor __P((DBC *)); - */ -void -__bam_print_cursor(dbc) - DBC *dbc; -{ - static const FN fn[] = { - { C_DELETED, "C_DELETED" }, - { C_RECNUM, "C_RECNUM" }, - { C_RENUMBER, "C_RENUMBER" }, - { 0, NULL } - }; - DB_ENV *dbenv; - BTREE_CURSOR *cp; - - dbenv = dbc->dbp->dbenv; - cp = (BTREE_CURSOR *)dbc->internal; - - STAT_ULONG("Overflow size", cp->ovflsize); - if (dbc->dbtype == DB_RECNO) - STAT_ULONG("Recno", cp->recno); - STAT_ULONG("Order", cp->order); - __db_prflags(dbenv, NULL, cp->flags, fn, NULL, "\tInternal Flags"); -} - -#else /* !HAVE_STATISTICS */ - -int -__bam_stat(dbc, spp, flags) - DBC *dbc; - void *spp; - u_int32_t flags; -{ - COMPQUIET(spp, NULL); - COMPQUIET(flags, 0); - - return (__db_stat_not_built(dbc->dbp->dbenv)); -} - -int -__bam_stat_print(dbc, flags) - DBC *dbc; - u_int32_t flags; -{ - COMPQUIET(flags, 0); - - return (__db_stat_not_built(dbc->dbp->dbenv)); -} -#endif - -/* - * __bam_key_range -- - * Return proportion of keys relative to given key. The numbers are - * slightly skewed due to on page duplicates. - * - * PUBLIC: int __bam_key_range __P((DBC *, DBT *, DB_KEY_RANGE *, u_int32_t)); - */ -int -__bam_key_range(dbc, dbt, kp, flags) - DBC *dbc; - DBT *dbt; - DB_KEY_RANGE *kp; - u_int32_t flags; -{ - BTREE_CURSOR *cp; - EPG *sp; - double factor; - int exact, ret; - - COMPQUIET(flags, 0); - - if ((ret = __bam_search(dbc, PGNO_INVALID, - dbt, S_STK_ONLY, 1, NULL, &exact)) != 0) - return (ret); - - cp = (BTREE_CURSOR *)dbc->internal; - kp->less = kp->greater = 0.0; - - factor = 1.0; - /* Correct the leaf page. */ - cp->csp->entries /= 2; - cp->csp->indx /= 2; - for (sp = cp->sp; sp <= cp->csp; ++sp) { - /* - * At each level we know that pages greater than indx contain - * keys greater than what we are looking for and those less - * than indx are less than. The one pointed to by indx may - * have some less, some greater or even equal. If indx is - * equal to the number of entries, then the key is out of range - * and everything is less. - */ - if (sp->indx == 0) - kp->greater += factor * (sp->entries - 1)/sp->entries; - else if (sp->indx == sp->entries) - kp->less += factor; - else { - kp->less += factor * sp->indx / sp->entries; - kp->greater += factor * - ((sp->entries - sp->indx) - 1) / sp->entries; - } - factor *= 1.0/sp->entries; - } - - /* - * If there was an exact match then assign 1 n'th to the key itself. - * Otherwise that factor belongs to those greater than the key, unless - * the key was out of range. - */ - if (exact) - kp->equal = factor; - else { - if (kp->less != 1) - kp->greater += factor; - kp->equal = 0; - } - - BT_STK_CLR(cp); - - return (0); -} - -/* - * __bam_traverse -- - * Walk a Btree database. - * - * PUBLIC: int __bam_traverse __P((DBC *, db_lockmode_t, - * PUBLIC: db_pgno_t, int (*)(DB *, PAGE *, void *, int *), void *)); - */ -int -__bam_traverse(dbc, mode, root_pgno, callback, cookie) - DBC *dbc; - db_lockmode_t mode; - db_pgno_t root_pgno; - int (*callback)__P((DB *, PAGE *, void *, int *)); - void *cookie; -{ - BINTERNAL *bi; - BKEYDATA *bk; - DB *dbp; - DB_LOCK lock; - DB_MPOOLFILE *mpf; - PAGE *h; - RINTERNAL *ri; - db_indx_t indx, *inp; - int already_put, ret, t_ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - already_put = 0; - - if ((ret = __db_lget(dbc, 0, root_pgno, mode, 0, &lock)) != 0) - return (ret); - if ((ret = __memp_fget(mpf, &root_pgno, 0, &h)) != 0) { - (void)__TLPUT(dbc, lock); - return (ret); - } - - switch (TYPE(h)) { - case P_IBTREE: - for (indx = 0; indx < NUM_ENT(h); indx += O_INDX) { - bi = GET_BINTERNAL(dbp, h, indx); - if (B_TYPE(bi->type) == B_OVERFLOW && - (ret = __db_traverse_big(dbp, - ((BOVERFLOW *)bi->data)->pgno, - callback, cookie)) != 0) - goto err; - if ((ret = __bam_traverse( - dbc, mode, bi->pgno, callback, cookie)) != 0) - goto err; - } - break; - case P_IRECNO: - for (indx = 0; indx < NUM_ENT(h); indx += O_INDX) { - ri = GET_RINTERNAL(dbp, h, indx); - if ((ret = __bam_traverse( - dbc, mode, ri->pgno, callback, cookie)) != 0) - goto err; - } - break; - case P_LBTREE: - inp = P_INP(dbp, h); - for (indx = 0; indx < NUM_ENT(h); indx += P_INDX) { - bk = GET_BKEYDATA(dbp, h, indx); - if (B_TYPE(bk->type) == B_OVERFLOW && - (indx + P_INDX >= NUM_ENT(h) || - inp[indx] != inp[indx + P_INDX])) { - if ((ret = __db_traverse_big(dbp, - GET_BOVERFLOW(dbp, h, indx)->pgno, - callback, cookie)) != 0) - goto err; - } - bk = GET_BKEYDATA(dbp, h, indx + O_INDX); - if (B_TYPE(bk->type) == B_DUPLICATE && - (ret = __bam_traverse(dbc, mode, - GET_BOVERFLOW(dbp, h, indx + O_INDX)->pgno, - callback, cookie)) != 0) - goto err; - if (B_TYPE(bk->type) == B_OVERFLOW && - (ret = __db_traverse_big(dbp, - GET_BOVERFLOW(dbp, h, indx + O_INDX)->pgno, - callback, cookie)) != 0) - goto err; - } - break; - case P_LDUP: - case P_LRECNO: - for (indx = 0; indx < NUM_ENT(h); indx += O_INDX) { - bk = GET_BKEYDATA(dbp, h, indx); - if (B_TYPE(bk->type) == B_OVERFLOW && - (ret = __db_traverse_big(dbp, - GET_BOVERFLOW(dbp, h, indx)->pgno, - callback, cookie)) != 0) - goto err; - } - break; - default: - return (__db_pgfmt(dbp->dbenv, h->pgno)); - } - - ret = callback(dbp, h, cookie, &already_put); - -err: if (!already_put && (t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = __TLPUT(dbc, lock)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} diff --git a/storage/bdb/btree/bt_upgrade.c b/storage/bdb/btree/bt_upgrade.c deleted file mode 100644 index 8ace2864cd3..00000000000 --- a/storage/bdb/btree/bt_upgrade.c +++ /dev/null @@ -1,159 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: bt_upgrade.c,v 12.1 2005/06/16 20:20:23 bostic Exp $ - */ -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_upgrade.h" -#include "dbinc/btree.h" - -/* - * __bam_30_btreemeta -- - * Upgrade the metadata pages from version 6 to version 7. - * - * PUBLIC: int __bam_30_btreemeta __P((DB *, char *, u_int8_t *)); - */ -int -__bam_30_btreemeta(dbp, real_name, buf) - DB *dbp; - char *real_name; - u_int8_t *buf; -{ - BTMETA30 *newmeta; - BTMETA2X *oldmeta; - DB_ENV *dbenv; - int ret; - - dbenv = dbp->dbenv; - - newmeta = (BTMETA30 *)buf; - oldmeta = (BTMETA2X *)buf; - - /* - * Move things from the end up, so we do not overwrite things. - * We are going to create a new uid, so we can move the stuff - * at the end of the structure first, overwriting the uid. - */ - - newmeta->re_pad = oldmeta->re_pad; - newmeta->re_len = oldmeta->re_len; - newmeta->minkey = oldmeta->minkey; - newmeta->maxkey = oldmeta->maxkey; - newmeta->dbmeta.free = oldmeta->free; - newmeta->dbmeta.flags = oldmeta->flags; - newmeta->dbmeta.type = P_BTREEMETA; - - newmeta->dbmeta.version = 7; - /* Replace the unique ID. */ - if ((ret = __os_fileid(dbenv, real_name, 1, buf + 36)) != 0) - return (ret); - - newmeta->root = 1; - - return (0); -} - -/* - * __bam_31_btreemeta -- - * Upgrade the database from version 7 to version 8. - * - * PUBLIC: int __bam_31_btreemeta - * PUBLIC: __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *)); - */ -int -__bam_31_btreemeta(dbp, real_name, flags, fhp, h, dirtyp) - DB *dbp; - char *real_name; - u_int32_t flags; - DB_FH *fhp; - PAGE *h; - int *dirtyp; -{ - BTMETA31 *newmeta; - BTMETA30 *oldmeta; - - COMPQUIET(dbp, NULL); - COMPQUIET(real_name, NULL); - COMPQUIET(fhp, NULL); - - newmeta = (BTMETA31 *)h; - oldmeta = (BTMETA30 *)h; - - /* - * Copy the effected fields down the page. - * The fields may overlap each other so we - * start at the bottom and use memmove. - */ - newmeta->root = oldmeta->root; - newmeta->re_pad = oldmeta->re_pad; - newmeta->re_len = oldmeta->re_len; - newmeta->minkey = oldmeta->minkey; - newmeta->maxkey = oldmeta->maxkey; - memmove(newmeta->dbmeta.uid, - oldmeta->dbmeta.uid, sizeof(oldmeta->dbmeta.uid)); - newmeta->dbmeta.flags = oldmeta->dbmeta.flags; - newmeta->dbmeta.record_count = 0; - newmeta->dbmeta.key_count = 0; - ZERO_LSN(newmeta->dbmeta.unused3); - - /* Set the version number. */ - newmeta->dbmeta.version = 8; - - /* Upgrade the flags. */ - if (LF_ISSET(DB_DUPSORT)) - F_SET(&newmeta->dbmeta, BTM_DUPSORT); - - *dirtyp = 1; - return (0); -} - -/* - * __bam_31_lbtree -- - * Upgrade the database btree leaf pages. - * - * PUBLIC: int __bam_31_lbtree - * PUBLIC: __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *)); - */ -int -__bam_31_lbtree(dbp, real_name, flags, fhp, h, dirtyp) - DB *dbp; - char *real_name; - u_int32_t flags; - DB_FH *fhp; - PAGE *h; - int *dirtyp; -{ - BKEYDATA *bk; - db_pgno_t pgno; - db_indx_t indx; - int ret; - - ret = 0; - for (indx = O_INDX; indx < NUM_ENT(h); indx += P_INDX) { - bk = GET_BKEYDATA(dbp, h, indx); - if (B_TYPE(bk->type) == B_DUPLICATE) { - pgno = GET_BOVERFLOW(dbp, h, indx)->pgno; - if ((ret = __db_31_offdup(dbp, real_name, fhp, - LF_ISSET(DB_DUPSORT) ? 1 : 0, &pgno)) != 0) - break; - if (pgno != GET_BOVERFLOW(dbp, h, indx)->pgno) { - *dirtyp = 1; - GET_BOVERFLOW(dbp, h, indx)->pgno = pgno; - } - } - } - - return (ret); -} diff --git a/storage/bdb/btree/bt_verify.c b/storage/bdb/btree/bt_verify.c deleted file mode 100644 index 055cc46892e..00000000000 --- a/storage/bdb/btree/bt_verify.c +++ /dev/null @@ -1,2469 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: bt_verify.c,v 12.13 2005/11/11 20:27:49 ubell Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/db_verify.h" -#include "dbinc/btree.h" -#include "dbinc/mp.h" - -static int __bam_safe_getdata __P((DB *, PAGE *, u_int32_t, int, DBT *, int *)); -static int __bam_vrfy_inp __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, - db_indx_t *, u_int32_t)); -static int __bam_vrfy_treeorder __P((DB *, db_pgno_t, PAGE *, BINTERNAL *, - BINTERNAL *, int (*)(DB *, const DBT *, const DBT *), u_int32_t)); -static int __ram_vrfy_inp __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, - db_indx_t *, u_int32_t)); - -/* - * __bam_vrfy_meta -- - * Verify the btree-specific part of a metadata page. - * - * PUBLIC: int __bam_vrfy_meta __P((DB *, VRFY_DBINFO *, BTMETA *, - * PUBLIC: db_pgno_t, u_int32_t)); - */ -int -__bam_vrfy_meta(dbp, vdp, meta, pgno, flags) - DB *dbp; - VRFY_DBINFO *vdp; - BTMETA *meta; - db_pgno_t pgno; - u_int32_t flags; -{ - DB_ENV *dbenv; - VRFY_PAGEINFO *pip; - int isbad, t_ret, ret; - db_indx_t ovflsize; - - dbenv = dbp->dbenv; - isbad = 0; - - if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) - return (ret); - - /* - * If VRFY_INCOMPLETE is not set, then we didn't come through - * __db_vrfy_pagezero and didn't incompletely - * check this page--we haven't checked it at all. - * Thus we need to call __db_vrfy_meta and check the common fields. - * - * If VRFY_INCOMPLETE is set, we've already done all the same work - * in __db_vrfy_pagezero, so skip the check. - */ - if (!F_ISSET(pip, VRFY_INCOMPLETE) && - (ret = __db_vrfy_meta(dbp, vdp, &meta->dbmeta, pgno, flags)) != 0) { - if (ret == DB_VERIFY_BAD) - isbad = 1; - else - goto err; - } - - /* bt_minkey: must be >= 2; must produce sensible ovflsize */ - - /* avoid division by zero */ - ovflsize = meta->minkey > 0 ? - B_MINKEY_TO_OVFLSIZE(dbp, meta->minkey, dbp->pgsize) : 0; - - if (meta->minkey < 2 || - ovflsize > B_MINKEY_TO_OVFLSIZE(dbp, DEFMINKEYPAGE, dbp->pgsize)) { - pip->bt_minkey = 0; - isbad = 1; - EPRINT((dbenv, - "Page %lu: nonsensical bt_minkey value %lu on metadata page", - (u_long)pgno, (u_long)meta->minkey)); - } else - pip->bt_minkey = meta->minkey; - - /* re_len: no constraints on this (may be zero or huge--we make rope) */ - pip->re_pad = meta->re_pad; - pip->re_len = meta->re_len; - - /* - * The root must not be current page or 0 and it must be within - * database. If this metadata page is the master meta data page - * of the file, then the root page had better be page 1. - */ - pip->root = 0; - if (meta->root == PGNO_INVALID || - meta->root == pgno || !IS_VALID_PGNO(meta->root) || - (pgno == PGNO_BASE_MD && meta->root != 1)) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: nonsensical root page %lu on metadata page", - (u_long)pgno, (u_long)meta->root)); - } else - pip->root = meta->root; - - /* Flags. */ - if (F_ISSET(&meta->dbmeta, BTM_RENUMBER)) - F_SET(pip, VRFY_IS_RRECNO); - - if (F_ISSET(&meta->dbmeta, BTM_SUBDB)) { - /* - * If this is a master db meta page, it had better not have - * duplicates. - */ - if (F_ISSET(&meta->dbmeta, BTM_DUP) && pgno == PGNO_BASE_MD) { - isbad = 1; - EPRINT((dbenv, -"Page %lu: Btree metadata page has both duplicates and multiple databases", - (u_long)pgno)); - } - F_SET(pip, VRFY_HAS_SUBDBS); - } - - if (F_ISSET(&meta->dbmeta, BTM_DUP)) - F_SET(pip, VRFY_HAS_DUPS); - if (F_ISSET(&meta->dbmeta, BTM_DUPSORT)) - F_SET(pip, VRFY_HAS_DUPSORT); - if (F_ISSET(&meta->dbmeta, BTM_RECNUM)) - F_SET(pip, VRFY_HAS_RECNUMS); - if (F_ISSET(pip, VRFY_HAS_RECNUMS) && F_ISSET(pip, VRFY_HAS_DUPS)) { - EPRINT((dbenv, - "Page %lu: Btree metadata page illegally has both recnums and dups", - (u_long)pgno)); - isbad = 1; - } - - if (F_ISSET(&meta->dbmeta, BTM_RECNO)) { - F_SET(pip, VRFY_IS_RECNO); - dbp->type = DB_RECNO; - } else if (F_ISSET(pip, VRFY_IS_RRECNO)) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: metadata page has renumber flag set but is not recno", - (u_long)pgno)); - } - - if (F_ISSET(pip, VRFY_IS_RECNO) && F_ISSET(pip, VRFY_HAS_DUPS)) { - EPRINT((dbenv, - "Page %lu: recno metadata page specifies duplicates", - (u_long)pgno)); - isbad = 1; - } - - if (F_ISSET(&meta->dbmeta, BTM_FIXEDLEN)) - F_SET(pip, VRFY_IS_FIXEDLEN); - else if (pip->re_len > 0) { - /* - * It's wrong to have an re_len if it's not a fixed-length - * database - */ - isbad = 1; - EPRINT((dbenv, - "Page %lu: re_len of %lu in non-fixed-length database", - (u_long)pgno, (u_long)pip->re_len)); - } - - /* - * We do not check that the rest of the page is 0, because it may - * not be and may still be correct. - */ - -err: if ((t_ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0 && ret == 0) - ret = t_ret; - if (LF_ISSET(DB_SALVAGE) && - (t_ret = __db_salvage_markdone(vdp, pgno)) != 0 && ret == 0) - ret = t_ret; - return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); -} - -/* - * __ram_vrfy_leaf -- - * Verify a recno leaf page. - * - * PUBLIC: int __ram_vrfy_leaf __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, - * PUBLIC: u_int32_t)); - */ -int -__ram_vrfy_leaf(dbp, vdp, h, pgno, flags) - DB *dbp; - VRFY_DBINFO *vdp; - PAGE *h; - db_pgno_t pgno; - u_int32_t flags; -{ - BKEYDATA *bk; - DB_ENV *dbenv; - VRFY_PAGEINFO *pip; - db_indx_t i; - int ret, t_ret, isbad; - u_int32_t re_len_guess, len; - - dbenv = dbp->dbenv; - isbad = 0; - - if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) - return (ret); - - if (TYPE(h) != P_LRECNO) { - /* We should not have been called. */ - TYPE_ERR_PRINT(dbenv, "__ram_vrfy_leaf", pgno, TYPE(h)); - DB_ASSERT(0); - ret = EINVAL; - goto err; - } - - /* - * Verify (and, if relevant, save off) page fields common to - * all PAGEs. - */ - if ((ret = __db_vrfy_datapage(dbp, vdp, h, pgno, flags)) != 0) { - if (ret == DB_VERIFY_BAD) - isbad = 1; - else - goto err; - } - - /* - * Verify inp[]. Return immediately if it returns DB_VERIFY_BAD; - * further checks are dangerous. - */ - if ((ret = __bam_vrfy_inp(dbp, - vdp, h, pgno, &pip->entries, flags)) != 0) - goto err; - - if (F_ISSET(pip, VRFY_HAS_DUPS)) { - EPRINT((dbenv, - "Page %lu: Recno database has dups", (u_long)pgno)); - ret = DB_VERIFY_BAD; - goto err; - } - - /* - * Walk through inp and see if the lengths of all the records are the - * same--if so, this may be a fixed-length database, and we want to - * save off this value. We know inp to be safe if we've gotten this - * far. - */ - re_len_guess = 0; - for (i = 0; i < NUM_ENT(h); i++) { - bk = GET_BKEYDATA(dbp, h, i); - /* KEYEMPTY. Go on. */ - if (B_DISSET(bk->type)) - continue; - if (bk->type == B_OVERFLOW) - len = ((BOVERFLOW *)bk)->tlen; - else if (bk->type == B_KEYDATA) - len = bk->len; - else { - isbad = 1; - EPRINT((dbenv, - "Page %lu: nonsensical type for item %lu", - (u_long)pgno, (u_long)i)); - continue; - } - if (re_len_guess == 0) - re_len_guess = len; - - /* - * Is this item's len the same as the last one's? If not, - * reset to 0 and break--we don't have a single re_len. - * Otherwise, go on to the next item. - */ - if (re_len_guess != len) { - re_len_guess = 0; - break; - } - } - pip->re_len = re_len_guess; - - /* Save off record count. */ - pip->rec_cnt = NUM_ENT(h); - -err: if ((t_ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0 && ret == 0) - ret = t_ret; - return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); -} - -/* - * __bam_vrfy -- - * Verify a btree leaf or internal page. - * - * PUBLIC: int __bam_vrfy __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, - * PUBLIC: u_int32_t)); - */ -int -__bam_vrfy(dbp, vdp, h, pgno, flags) - DB *dbp; - VRFY_DBINFO *vdp; - PAGE *h; - db_pgno_t pgno; - u_int32_t flags; -{ - DB_ENV *dbenv; - VRFY_PAGEINFO *pip; - int ret, t_ret, isbad; - - dbenv = dbp->dbenv; - isbad = 0; - - if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) - return (ret); - - switch (TYPE(h)) { - case P_IBTREE: - case P_IRECNO: - case P_LBTREE: - case P_LDUP: - break; - default: - TYPE_ERR_PRINT(dbenv, "__bam_vrfy", pgno, TYPE(h)); - DB_ASSERT(0); - ret = EINVAL; - goto err; - } - - /* - * Verify (and, if relevant, save off) page fields common to - * all PAGEs. - */ - if ((ret = __db_vrfy_datapage(dbp, vdp, h, pgno, flags)) != 0) { - if (ret == DB_VERIFY_BAD) - isbad = 1; - else - goto err; - } - - /* - * The record count is, on internal pages, stored in an overloaded - * next_pgno field. Save it off; we'll verify it when we check - * overall database structure. We could overload the field - * in VRFY_PAGEINFO, too, but this seems gross, and space - * is not at such a premium. - */ - pip->rec_cnt = RE_NREC(h); - - /* - * Verify inp[]. - */ - if (TYPE(h) == P_IRECNO) { - if ((ret = __ram_vrfy_inp(dbp, - vdp, h, pgno, &pip->entries, flags)) != 0) - goto err; - } else if ((ret = __bam_vrfy_inp(dbp, - vdp, h, pgno, &pip->entries, flags)) != 0) { - if (ret == DB_VERIFY_BAD) - isbad = 1; - else - goto err; - EPRINT((dbenv, - "Page %lu: item order check unsafe: skipping", - (u_long)pgno)); - } else if (!LF_ISSET(DB_NOORDERCHK) && (ret = - __bam_vrfy_itemorder(dbp, vdp, h, pgno, 0, 0, 0, flags)) != 0) { - /* - * We know that the elements of inp are reasonable. - * - * Check that elements fall in the proper order. - */ - if (ret == DB_VERIFY_BAD) - isbad = 1; - else - goto err; - } - -err: if ((t_ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0 && ret == 0) - ret = t_ret; - return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); -} - -/* - * __ram_vrfy_inp -- - * Verify that all entries in a P_IRECNO inp[] array are reasonable, - * and count them. Note that P_LRECNO uses __bam_vrfy_inp; - * P_IRECNOs are a special, and simpler, case, since they have - * RINTERNALs rather than BKEYDATA/BINTERNALs. - */ -static int -__ram_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags) - DB *dbp; - VRFY_DBINFO *vdp; - PAGE *h; - db_pgno_t pgno; - db_indx_t *nentriesp; - u_int32_t flags; -{ - DB_ENV *dbenv; - RINTERNAL *ri; - VRFY_CHILDINFO child; - VRFY_PAGEINFO *pip; - int ret, t_ret, isbad; - u_int32_t himark, i, offset, nentries; - db_indx_t *inp; - u_int8_t *pagelayout, *p; - - dbenv = dbp->dbenv; - isbad = 0; - memset(&child, 0, sizeof(VRFY_CHILDINFO)); - nentries = 0; - pagelayout = NULL; - - if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) - return (ret); - - if (TYPE(h) != P_IRECNO) { - TYPE_ERR_PRINT(dbenv, "__ram_vrfy_inp", pgno, TYPE(h)); - DB_ASSERT(0); - ret = EINVAL; - goto err; - } - - himark = dbp->pgsize; - if ((ret = __os_malloc(dbenv, dbp->pgsize, &pagelayout)) != 0) - goto err; - memset(pagelayout, 0, dbp->pgsize); - inp = P_INP(dbp, h); - for (i = 0; i < NUM_ENT(h); i++) { - if ((u_int8_t *)inp + i >= (u_int8_t *)h + himark) { - EPRINT((dbenv, - "Page %lu: entries listing %lu overlaps data", - (u_long)pgno, (u_long)i)); - ret = DB_VERIFY_BAD; - goto err; - } - offset = inp[i]; - /* - * Check that the item offset is reasonable: it points - * somewhere after the inp array and before the end of the - * page. - */ - if (offset <= (u_int32_t)((u_int8_t *)inp + i - - (u_int8_t *)h) || - offset > (u_int32_t)(dbp->pgsize - RINTERNAL_SIZE)) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: bad offset %lu at index %lu", - (u_long)pgno, (u_long)offset, (u_long)i)); - continue; - } - - /* Update the high-water mark (what HOFFSET should be) */ - if (offset < himark) - himark = offset; - - nentries++; - - /* Make sure this RINTERNAL is not multiply referenced. */ - ri = GET_RINTERNAL(dbp, h, i); - if (pagelayout[offset] == 0) { - pagelayout[offset] = 1; - child.pgno = ri->pgno; - child.type = V_RECNO; - child.nrecs = ri->nrecs; - if ((ret = __db_vrfy_childput(vdp, pgno, &child)) != 0) - goto err; - } else { - EPRINT((dbenv, - "Page %lu: RINTERNAL structure at offset %lu referenced twice", - (u_long)pgno, (u_long)offset)); - isbad = 1; - } - } - - for (p = pagelayout + himark; - p < pagelayout + dbp->pgsize; - p += RINTERNAL_SIZE) - if (*p != 1) { - EPRINT((dbenv, - "Page %lu: gap between items at offset %lu", - (u_long)pgno, (u_long)(p - pagelayout))); - isbad = 1; - } - - if ((db_indx_t)himark != HOFFSET(h)) { - EPRINT((dbenv, - "Page %lu: bad HOFFSET %lu, appears to be %lu", - (u_long)pgno, (u_long)(HOFFSET(h)), (u_long)himark)); - isbad = 1; - } - - *nentriesp = nentries; - -err: if ((t_ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0 && ret == 0) - ret = t_ret; - if (pagelayout != NULL) - __os_free(dbenv, pagelayout); - return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); -} - -typedef enum { VRFY_ITEM_NOTSET=0, VRFY_ITEM_BEGIN, VRFY_ITEM_END } VRFY_ITEM; - -/* - * __bam_vrfy_inp -- - * Verify that all entries in inp[] array are reasonable; - * count them. - */ -static int -__bam_vrfy_inp(dbp, vdp, h, pgno, nentriesp, flags) - DB *dbp; - VRFY_DBINFO *vdp; - PAGE *h; - db_pgno_t pgno; - db_indx_t *nentriesp; - u_int32_t flags; -{ - BKEYDATA *bk; - BOVERFLOW *bo; - DB_ENV *dbenv; - VRFY_CHILDINFO child; - VRFY_ITEM *pagelayout; - VRFY_PAGEINFO *pip; - u_int32_t himark, offset; /* - * These would be db_indx_ts - * but for alignment. - */ - u_int32_t i, endoff, nentries; - int isbad, initem, isdupitem, ret, t_ret; - - dbenv = dbp->dbenv; - isbad = isdupitem = 0; - nentries = 0; - memset(&child, 0, sizeof(VRFY_CHILDINFO)); - if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) - return (ret); - - switch (TYPE(h)) { - case P_IBTREE: - case P_LBTREE: - case P_LDUP: - case P_LRECNO: - break; - default: - /* - * In the salvager, we might call this from a page which - * we merely suspect is a btree page. Otherwise, it - * shouldn't get called--if it is, that's a verifier bug. - */ - if (LF_ISSET(DB_SALVAGE)) - break; - TYPE_ERR_PRINT(dbenv, "__bam_vrfy_inp", pgno, TYPE(h)); - DB_ASSERT(0); - ret = EINVAL; - goto err; - } - - /* - * Loop through inp[], the array of items, until we either - * run out of entries or collide with the data. Keep track - * of h_offset in himark. - * - * For each element in inp[i], make sure it references a region - * that starts after the end of the inp array (as defined by - * NUM_ENT(h)), ends before the beginning of the page, doesn't - * overlap any other regions, and doesn't have a gap between - * it and the region immediately after it. - */ - himark = dbp->pgsize; - if ((ret = __os_calloc( - dbenv, dbp->pgsize, sizeof(pagelayout[0]), &pagelayout)) != 0) - goto err; - for (i = 0; i < NUM_ENT(h); i++) { - switch (ret = __db_vrfy_inpitem(dbp, - h, pgno, i, 1, flags, &himark, &offset)) { - case 0: - break; - case DB_VERIFY_BAD: - isbad = 1; - continue; - case DB_VERIFY_FATAL: - isbad = 1; - goto err; - default: - DB_ASSERT(ret != 0); - break; - } - - /* - * We now have a plausible beginning for the item, and we know - * its length is safe. - * - * Mark the beginning and end in pagelayout so we can make sure - * items have no overlaps or gaps. - */ - bk = GET_BKEYDATA(dbp, h, i); - if (pagelayout[offset] == VRFY_ITEM_NOTSET) - pagelayout[offset] = VRFY_ITEM_BEGIN; - else if (pagelayout[offset] == VRFY_ITEM_BEGIN) { - /* - * Having two inp entries that point at the same patch - * of page is legal if and only if the page is - * a btree leaf and they're onpage duplicate keys-- - * that is, if (i % P_INDX) == 0. - */ - if ((i % P_INDX == 0) && (TYPE(h) == P_LBTREE)) { - /* Flag for later. */ - F_SET(pip, VRFY_HAS_DUPS); - - /* Bump up nentries so we don't undercount. */ - nentries++; - - /* - * We'll check to make sure the end is - * equal, too. - */ - isdupitem = 1; - } else { - isbad = 1; - EPRINT((dbenv, "Page %lu: duplicated item %lu", - (u_long)pgno, (u_long)i)); - } - } - - /* - * Mark the end. Its location varies with the page type - * and the item type. - * - * If the end already has a sign other than 0, do nothing-- - * it's an overlap that we'll catch later. - */ - switch (B_TYPE(bk->type)) { - case B_KEYDATA: - if (TYPE(h) == P_IBTREE) - /* It's a BINTERNAL. */ - endoff = offset + BINTERNAL_SIZE(bk->len) - 1; - else - endoff = offset + BKEYDATA_SIZE(bk->len) - 1; - break; - case B_DUPLICATE: - /* - * Flag that we have dups; we'll check whether - * that's okay during the structure check. - */ - F_SET(pip, VRFY_HAS_DUPS); - /* FALLTHROUGH */ - case B_OVERFLOW: - /* - * Overflow entries on internal pages are stored - * as the _data_ of a BINTERNAL; overflow entries - * on leaf pages are stored as the entire entry. - */ - endoff = offset + - ((TYPE(h) == P_IBTREE) ? - BINTERNAL_SIZE(BOVERFLOW_SIZE) : - BOVERFLOW_SIZE) - 1; - break; - default: - /* - * We'll complain later; for now, just mark - * a minimum. - */ - endoff = offset + BKEYDATA_SIZE(0) - 1; - break; - } - - /* - * If this is an onpage duplicate key we've seen before, - * the end had better coincide too. - */ - if (isdupitem && pagelayout[endoff] != VRFY_ITEM_END) { - EPRINT((dbenv, "Page %lu: duplicated item %lu", - (u_long)pgno, (u_long)i)); - isbad = 1; - } else if (pagelayout[endoff] == VRFY_ITEM_NOTSET) - pagelayout[endoff] = VRFY_ITEM_END; - isdupitem = 0; - - /* - * There should be no deleted items in a quiescent tree, - * except in recno. - */ - if (B_DISSET(bk->type) && TYPE(h) != P_LRECNO) { - isbad = 1; - EPRINT((dbenv, "Page %lu: item %lu marked deleted", - (u_long)pgno, (u_long)i)); - } - - /* - * Check the type and such of bk--make sure it's reasonable - * for the pagetype. - */ - switch (B_TYPE(bk->type)) { - case B_KEYDATA: - /* - * This is a normal, non-overflow BKEYDATA or BINTERNAL. - * The only thing to check is the len, and that's - * already been done. - */ - break; - case B_DUPLICATE: - if (TYPE(h) == P_IBTREE) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: duplicate page referenced by internal btree page at item %lu", - (u_long)pgno, (u_long)i)); - break; - } else if (TYPE(h) == P_LRECNO) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: duplicate page referenced by recno page at item %lu", - (u_long)pgno, (u_long)i)); - break; - } - /* FALLTHROUGH */ - case B_OVERFLOW: - bo = (TYPE(h) == P_IBTREE) ? - (BOVERFLOW *)(((BINTERNAL *)bk)->data) : - (BOVERFLOW *)bk; - - if (B_TYPE(bk->type) == B_OVERFLOW) - /* Make sure tlen is reasonable. */ - if (bo->tlen > dbp->pgsize * vdp->last_pgno) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: impossible tlen %lu, item %lu", - (u_long)pgno, - (u_long)bo->tlen, (u_long)i)); - /* Don't save as a child. */ - break; - } - - if (!IS_VALID_PGNO(bo->pgno) || bo->pgno == pgno || - bo->pgno == PGNO_INVALID) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: offpage item %lu has bad pgno %lu", - (u_long)pgno, (u_long)i, (u_long)bo->pgno)); - /* Don't save as a child. */ - break; - } - - child.pgno = bo->pgno; - child.type = (B_TYPE(bk->type) == B_OVERFLOW ? - V_OVERFLOW : V_DUPLICATE); - child.tlen = bo->tlen; - if ((ret = __db_vrfy_childput(vdp, pgno, &child)) != 0) - goto err; - break; - default: - isbad = 1; - EPRINT((dbenv, "Page %lu: item %lu of invalid type %lu", - (u_long)pgno, (u_long)i, (u_long)B_TYPE(bk->type))); - break; - } - } - - /* - * Now, loop through and make sure the items are contiguous and - * non-overlapping. - */ - initem = 0; - for (i = himark; i < dbp->pgsize; i++) - if (initem == 0) - switch (pagelayout[i]) { - case VRFY_ITEM_NOTSET: - /* May be just for alignment. */ - if (i != DB_ALIGN(i, sizeof(u_int32_t))) - continue; - - isbad = 1; - EPRINT((dbenv, - "Page %lu: gap between items at offset %lu", - (u_long)pgno, (u_long)i)); - /* Find the end of the gap */ - for (; pagelayout[i + 1] == VRFY_ITEM_NOTSET && - (size_t)(i + 1) < dbp->pgsize; i++) - ; - break; - case VRFY_ITEM_BEGIN: - /* We've found an item. Check its alignment. */ - if (i != DB_ALIGN(i, sizeof(u_int32_t))) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: offset %lu unaligned", - (u_long)pgno, (u_long)i)); - } - initem = 1; - nentries++; - break; - case VRFY_ITEM_END: - /* - * We've hit the end of an item even though - * we don't think we're in one; must - * be an overlap. - */ - isbad = 1; - EPRINT((dbenv, - "Page %lu: overlapping items at offset %lu", - (u_long)pgno, (u_long)i)); - break; - } - else - switch (pagelayout[i]) { - case VRFY_ITEM_NOTSET: - /* In the middle of an item somewhere. Okay. */ - break; - case VRFY_ITEM_END: - /* End of an item; switch to out-of-item mode.*/ - initem = 0; - break; - case VRFY_ITEM_BEGIN: - /* - * Hit a second item beginning without an - * end. Overlap. - */ - isbad = 1; - EPRINT((dbenv, - "Page %lu: overlapping items at offset %lu", - (u_long)pgno, (u_long)i)); - break; - } - - __os_free(dbenv, pagelayout); - - /* Verify HOFFSET. */ - if ((db_indx_t)himark != HOFFSET(h)) { - EPRINT((dbenv, "Page %lu: bad HOFFSET %lu, appears to be %lu", - (u_long)pgno, (u_long)HOFFSET(h), (u_long)himark)); - isbad = 1; - } - -err: if (nentriesp != NULL) - *nentriesp = nentries; - - if ((t_ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0 && ret == 0) - ret = t_ret; - - return ((isbad == 1 && ret == 0) ? DB_VERIFY_BAD : ret); -} - -/* - * __bam_vrfy_itemorder -- - * Make sure the items on a page sort correctly. - * - * Assumes that NUM_ENT(h) and inp[0]..inp[NUM_ENT(h) - 1] are - * reasonable; be sure that __bam_vrfy_inp has been called first. - * - * If ovflok is set, it also assumes that overflow page chains - * hanging off the current page have been sanity-checked, and so we - * can use __bam_cmp to verify their ordering. If it is not set, - * and we run into an overflow page, carp and return DB_VERIFY_BAD; - * we shouldn't be called if any exist. - * - * PUBLIC: int __bam_vrfy_itemorder __P((DB *, VRFY_DBINFO *, PAGE *, - * PUBLIC: db_pgno_t, u_int32_t, int, int, u_int32_t)); - */ -int -__bam_vrfy_itemorder(dbp, vdp, h, pgno, nentries, ovflok, hasdups, flags) - DB *dbp; - VRFY_DBINFO *vdp; - PAGE *h; - db_pgno_t pgno; - u_int32_t nentries; - int ovflok, hasdups; - u_int32_t flags; -{ - BINTERNAL *bi; - BKEYDATA *bk; - BOVERFLOW *bo; - BTREE *bt; - DBT dbta, dbtb, dup_1, dup_2, *p1, *p2, *tmp; - DB_ENV *dbenv; - VRFY_PAGEINFO *pip; - db_indx_t i; - int cmp, freedup_1, freedup_2, isbad, ret, t_ret; - int (*dupfunc) __P((DB *, const DBT *, const DBT *)); - int (*func) __P((DB *, const DBT *, const DBT *)); - void *buf1, *buf2, *tmpbuf; - - /* - * We need to work in the ORDERCHKONLY environment where we might - * not have a pip, but we also may need to work in contexts where - * NUM_ENT isn't safe. - */ - if (vdp != NULL) { - if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) - return (ret); - nentries = pip->entries; - } else - pip = NULL; - - dbenv = dbp->dbenv; - ret = isbad = 0; - bo = NULL; /* Shut up compiler. */ - - memset(&dbta, 0, sizeof(DBT)); - F_SET(&dbta, DB_DBT_REALLOC); - - memset(&dbtb, 0, sizeof(DBT)); - F_SET(&dbtb, DB_DBT_REALLOC); - - buf1 = buf2 = NULL; - - DB_ASSERT(!LF_ISSET(DB_NOORDERCHK)); - - dupfunc = (dbp->dup_compare == NULL) ? __bam_defcmp : dbp->dup_compare; - if (TYPE(h) == P_LDUP) - func = dupfunc; - else { - func = __bam_defcmp; - if (dbp->bt_internal != NULL) { - bt = (BTREE *)dbp->bt_internal; - if (bt->bt_compare != NULL) - func = bt->bt_compare; - } - } - - /* - * We alternate our use of dbta and dbtb so that we can walk - * through the page key-by-key without copying a dbt twice. - * p1 is always the dbt for index i - 1, and p2 for index i. - */ - p1 = &dbta; - p2 = &dbtb; - - /* - * Loop through the entries. nentries ought to contain the - * actual count, and so is a safe way to terminate the loop; whether - * we inc. by one or two depends on whether we're a leaf page-- - * on a leaf page, we care only about keys. On internal pages - * and LDUP pages, we want to check the order of all entries. - * - * Note that on IBTREE pages, we start with item 1, since item - * 0 doesn't get looked at by __bam_cmp. - */ - for (i = (TYPE(h) == P_IBTREE) ? 1 : 0; i < nentries; - i += (TYPE(h) == P_LBTREE) ? P_INDX : O_INDX) { - /* - * Put key i-1, now in p2, into p1, by swapping DBTs and bufs. - */ - tmp = p1; - p1 = p2; - p2 = tmp; - tmpbuf = buf1; - buf1 = buf2; - buf2 = tmpbuf; - - /* - * Get key i into p2. - */ - switch (TYPE(h)) { - case P_IBTREE: - bi = GET_BINTERNAL(dbp, h, i); - if (B_TYPE(bi->type) == B_OVERFLOW) { - bo = (BOVERFLOW *)(bi->data); - goto overflow; - } else { - p2->data = bi->data; - p2->size = bi->len; - } - - /* - * The leftmost key on an internal page must be - * len 0, since it's just a placeholder and - * automatically sorts less than all keys. - * - * XXX - * This criterion does not currently hold! - * See todo list item #1686. Meanwhile, it's harmless - * to just not check for it. - */ -#if 0 - if (i == 0 && bi->len != 0) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: lowest key on internal page of nonzero length", - (u_long)pgno)); - } -#endif - break; - case P_LBTREE: - case P_LDUP: - bk = GET_BKEYDATA(dbp, h, i); - if (B_TYPE(bk->type) == B_OVERFLOW) { - bo = (BOVERFLOW *)bk; - goto overflow; - } else { - p2->data = bk->data; - p2->size = bk->len; - } - break; - default: - /* - * This means our caller screwed up and sent us - * an inappropriate page. - */ - TYPE_ERR_PRINT(dbenv, - "__bam_vrfy_itemorder", pgno, TYPE(h)) - DB_ASSERT(0); - ret = EINVAL; - goto err; - } - - if (0) { - /* - * If ovflok != 1, we can't safely go chasing - * overflow pages with the normal routines now; - * they might be unsafe or nonexistent. Mark this - * page as incomplete and return. - * - * Note that we don't need to worry about freeing - * buffers, since they can't have been allocated - * if overflow items are unsafe. - */ -overflow: if (!ovflok) { - F_SET(pip, VRFY_INCOMPLETE); - goto err; - } - - /* - * Overflow items are safe to chase. Do so. - * Fetch the overflow item into p2->data, - * NULLing it or reallocing it as appropriate. - * - * (We set p2->data to buf2 before the call - * so we're sure to realloc if we can and if p2 - * was just pointing at a non-overflow item.) - */ - p2->data = buf2; - if ((ret = __db_goff(dbp, - p2, bo->tlen, bo->pgno, NULL, NULL)) != 0) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: error %lu in fetching overflow item %lu", - (u_long)pgno, (u_long)ret, (u_long)i)); - } - /* In case it got realloc'ed and thus changed. */ - buf2 = p2->data; - } - - /* Compare with the last key. */ - if (p1->data != NULL && p2->data != NULL) { - cmp = func(dbp, p1, p2); - - /* comparison succeeded */ - if (cmp > 0) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: out-of-order key at entry %lu", - (u_long)pgno, (u_long)i)); - /* proceed */ - } else if (cmp == 0) { - /* - * If they compared equally, this - * had better be a (sub)database with dups. - * Mark it so we can check during the - * structure check. - */ - if (pip != NULL) - F_SET(pip, VRFY_HAS_DUPS); - else if (hasdups == 0) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: database with no duplicates has duplicated keys", - (u_long)pgno)); - } - - /* - * If we're a btree leaf, check to see - * if the data items of these on-page dups are - * in sorted order. If not, flag this, so - * that we can make sure during the - * structure checks that the DUPSORT flag - * is unset. - * - * At this point i points to a duplicate key. - * Compare the datum before it (same key) - * to the datum after it, i.e. i-1 to i+1. - */ - if (TYPE(h) == P_LBTREE) { - /* - * Unsafe; continue and we'll pick - * up the bogus nentries later. - */ - if (i + 1 >= (db_indx_t)nentries) - continue; - - /* - * We don't bother with clever memory - * management with on-page dups, - * as it's only really a big win - * in the overflow case, and overflow - * dups are probably (?) rare. - */ - if (((ret = __bam_safe_getdata(dbp, - h, i - 1, ovflok, &dup_1, - &freedup_1)) != 0) || - ((ret = __bam_safe_getdata(dbp, - h, i + 1, ovflok, &dup_2, - &freedup_2)) != 0)) - goto err; - - /* - * If either of the data are NULL, - * it's because they're overflows and - * it's not safe to chase them now. - * Mark an incomplete and return. - */ - if (dup_1.data == NULL || - dup_2.data == NULL) { - DB_ASSERT(!ovflok); - F_SET(pip, VRFY_INCOMPLETE); - goto err; - } - - /* - * If the dups are out of order, - * flag this. It's not an error - * until we do the structure check - * and see whether DUPSORT is set. - */ - if (dupfunc(dbp, &dup_1, &dup_2) > 0) - F_SET(pip, VRFY_DUPS_UNSORTED); - - if (freedup_1) - __os_ufree(dbenv, dup_1.data); - if (freedup_2) - __os_ufree(dbenv, dup_2.data); - } - } - } - } - -err: if (pip != NULL && ((t_ret = - __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0) && ret == 0) - ret = t_ret; - - if (buf1 != NULL) - __os_ufree(dbenv, buf1); - if (buf2 != NULL) - __os_ufree(dbenv, buf2); - - return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); -} - -/* - * __bam_vrfy_structure -- - * Verify the tree structure of a btree database (including the master - * database containing subdbs). - * - * PUBLIC: int __bam_vrfy_structure __P((DB *, VRFY_DBINFO *, db_pgno_t, - * PUBLIC: u_int32_t)); - */ -int -__bam_vrfy_structure(dbp, vdp, meta_pgno, flags) - DB *dbp; - VRFY_DBINFO *vdp; - db_pgno_t meta_pgno; - u_int32_t flags; -{ - DB *pgset; - DB_ENV *dbenv; - VRFY_PAGEINFO *mip, *rip; - db_pgno_t root, p; - int t_ret, ret; - u_int32_t nrecs, level, relen, stflags; - - dbenv = dbp->dbenv; - mip = rip = 0; - pgset = vdp->pgset; - - if ((ret = __db_vrfy_getpageinfo(vdp, meta_pgno, &mip)) != 0) - return (ret); - - if ((ret = __db_vrfy_pgset_get(pgset, meta_pgno, (int *)&p)) != 0) - goto err; - if (p != 0) { - EPRINT((dbenv, - "Page %lu: btree metadata page observed twice", - (u_long)meta_pgno)); - ret = DB_VERIFY_BAD; - goto err; - } - if ((ret = __db_vrfy_pgset_inc(pgset, meta_pgno)) != 0) - goto err; - - root = mip->root; - - if (root == 0) { - EPRINT((dbenv, - "Page %lu: btree metadata page has no root", - (u_long)meta_pgno)); - ret = DB_VERIFY_BAD; - goto err; - } - - if ((ret = __db_vrfy_getpageinfo(vdp, root, &rip)) != 0) - goto err; - - switch (rip->type) { - case P_IBTREE: - case P_LBTREE: - stflags = flags | ST_TOPLEVEL; - if (F_ISSET(mip, VRFY_HAS_DUPS)) - stflags |= ST_DUPOK; - if (F_ISSET(mip, VRFY_HAS_DUPSORT)) - stflags |= ST_DUPSORT; - if (F_ISSET(mip, VRFY_HAS_RECNUMS)) - stflags |= ST_RECNUM; - ret = __bam_vrfy_subtree(dbp, - vdp, root, NULL, NULL, stflags, NULL, NULL, NULL); - break; - case P_IRECNO: - case P_LRECNO: - stflags = flags | ST_RECNUM | ST_IS_RECNO | ST_TOPLEVEL; - if (mip->re_len > 0) - stflags |= ST_RELEN; - if ((ret = __bam_vrfy_subtree(dbp, vdp, - root, NULL, NULL, stflags, &level, &nrecs, &relen)) != 0) - goto err; - /* - * Even if mip->re_len > 0, re_len may come back zero if the - * tree is empty. It should be okay to just skip the check in - * this case, as if there are any non-deleted keys at all, - * that should never happen. - */ - if (mip->re_len > 0 && relen > 0 && mip->re_len != relen) { - EPRINT((dbenv, - "Page %lu: recno database has bad re_len %lu", - (u_long)meta_pgno, (u_long)relen)); - ret = DB_VERIFY_BAD; - goto err; - } - ret = 0; - break; - case P_LDUP: - EPRINT((dbenv, - "Page %lu: duplicate tree referenced from metadata page", - (u_long)meta_pgno)); - ret = DB_VERIFY_BAD; - break; - default: - EPRINT((dbenv, - "Page %lu: btree root of incorrect type %lu on metadata page", - (u_long)meta_pgno, (u_long)rip->type)); - ret = DB_VERIFY_BAD; - break; - } - -err: if (mip != NULL && ((t_ret = - __db_vrfy_putpageinfo(dbenv, vdp, mip)) != 0) && ret == 0) - ret = t_ret; - if (rip != NULL && ((t_ret = - __db_vrfy_putpageinfo(dbenv, vdp, rip)) != 0) && ret == 0) - ret = t_ret; - return (ret); -} - -/* - * __bam_vrfy_subtree-- - * Verify a subtree (or entire) btree with specified root. - * - * Note that this is public because it must be called to verify - * offpage dup trees, including from hash. - * - * PUBLIC: int __bam_vrfy_subtree __P((DB *, VRFY_DBINFO *, db_pgno_t, void *, - * PUBLIC: void *, u_int32_t, u_int32_t *, u_int32_t *, u_int32_t *)); - */ -int -__bam_vrfy_subtree(dbp, vdp, pgno, l, r, flags, levelp, nrecsp, relenp) - DB *dbp; - VRFY_DBINFO *vdp; - db_pgno_t pgno; - void *l, *r; - u_int32_t flags, *levelp, *nrecsp, *relenp; -{ - BINTERNAL *li, *ri, *lp, *rp; - DB *pgset; - DBC *cc; - DB_ENV *dbenv; - DB_MPOOLFILE *mpf; - PAGE *h; - VRFY_CHILDINFO *child; - VRFY_PAGEINFO *pip; - db_indx_t i; - db_pgno_t next_pgno, prev_pgno; - db_recno_t child_nrecs, nrecs; - u_int32_t child_level, child_relen, j, level, relen, stflags; - u_int8_t leaf_type; - int (*func) __P((DB *, const DBT *, const DBT *)); - int isbad, p, ret, t_ret, toplevel; - - dbenv = dbp->dbenv; - mpf = dbp->mpf; - ret = isbad = 0; - nrecs = 0; - h = NULL; - relen = 0; - leaf_type = P_INVALID; - next_pgno = prev_pgno = PGNO_INVALID; - rp = (BINTERNAL *)r; - lp = (BINTERNAL *)l; - - /* Provide feedback on our progress to the application. */ - if (!LF_ISSET(DB_SALVAGE)) - __db_vrfy_struct_feedback(dbp, vdp); - - if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) - return (ret); - - cc = NULL; - level = pip->bt_level; - - toplevel = LF_ISSET(ST_TOPLEVEL) ? 1 : 0; - LF_CLR(ST_TOPLEVEL); - - /* - * If this is the root, initialize the vdp's prev- and next-pgno - * accounting. - * - * For each leaf page we hit, we'll want to make sure that - * vdp->prev_pgno is the same as pip->prev_pgno and vdp->next_pgno is - * our page number. Then, we'll set vdp->next_pgno to pip->next_pgno - * and vdp->prev_pgno to our page number, and the next leaf page in - * line should be able to do the same verification. - */ - if (toplevel) { - /* - * Cache the values stored in the vdp so that if we're an - * auxiliary tree such as an off-page duplicate set, our - * caller's leaf page chain doesn't get lost. - */ - prev_pgno = vdp->prev_pgno; - next_pgno = vdp->next_pgno; - leaf_type = vdp->leaf_type; - vdp->next_pgno = vdp->prev_pgno = PGNO_INVALID; - vdp->leaf_type = P_INVALID; - } - - /* - * We are recursively descending a btree, starting from the root - * and working our way out to the leaves. - * - * There are four cases we need to deal with: - * 1. pgno is a recno leaf page. Any children are overflows. - * 2. pgno is a duplicate leaf page. Any children - * are overflow pages; traverse them, and then return - * level and nrecs. - * 3. pgno is an ordinary leaf page. Check whether dups are - * allowed, and if so, traverse any off-page dups or - * overflows. Then return nrecs and level. - * 4. pgno is a recno internal page. Recursively check any - * child pages, making sure their levels are one lower - * and their nrecs sum to ours. - * 5. pgno is a btree internal page. Same as #4, plus we - * must verify that for each pair of BINTERNAL entries - * N and N+1, the leftmost item on N's child sorts - * greater than N, and the rightmost item on N's child - * sorts less than N+1. - * - * Furthermore, in any sorted page type (P_LDUP, P_LBTREE, P_IBTREE), - * we need to verify the internal sort order is correct if, - * due to overflow items, we were not able to do so earlier. - */ - switch (pip->type) { - case P_LRECNO: - case P_LDUP: - case P_LBTREE: - /* - * Cases 1, 2 and 3. - * - * We're some sort of leaf page; verify - * that our linked list of leaves is consistent. - */ - if (vdp->leaf_type == P_INVALID) { - /* - * First leaf page. Set the type that all its - * successors should be, and verify that our prev_pgno - * is PGNO_INVALID. - */ - vdp->leaf_type = pip->type; - if (pip->prev_pgno != PGNO_INVALID) - goto bad_prev; - } else { - /* - * Successor leaf page. Check our type, the previous - * page's next_pgno, and our prev_pgno. - */ - if (pip->type != vdp->leaf_type) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: unexpected page type %lu found in leaf chain (expected %lu)", - (u_long)pip->pgno, (u_long)pip->type, - (u_long)vdp->leaf_type)); - } - - /* - * Don't do the prev/next_pgno checks if we've lost - * leaf pages due to another corruption. - */ - if (!F_ISSET(vdp, VRFY_LEAFCHAIN_BROKEN)) { - if (pip->pgno != vdp->next_pgno) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: incorrect next_pgno %lu found in leaf chain (should be %lu)", - (u_long)vdp->prev_pgno, - (u_long)vdp->next_pgno, - (u_long)pip->pgno)); - } - if (pip->prev_pgno != vdp->prev_pgno) { -bad_prev: isbad = 1; - EPRINT((dbenv, - "Page %lu: incorrect prev_pgno %lu found in leaf chain (should be %lu)", - (u_long)pip->pgno, - (u_long)pip->prev_pgno, - (u_long)vdp->prev_pgno)); - } - } - } - vdp->prev_pgno = pip->pgno; - vdp->next_pgno = pip->next_pgno; - F_CLR(vdp, VRFY_LEAFCHAIN_BROKEN); - - /* - * Overflow pages are common to all three leaf types; - * traverse the child list, looking for overflows. - */ - if ((ret = __db_vrfy_childcursor(vdp, &cc)) != 0) - goto err; - for (ret = __db_vrfy_ccset(cc, pgno, &child); ret == 0; - ret = __db_vrfy_ccnext(cc, &child)) - if (child->type == V_OVERFLOW && - (ret = __db_vrfy_ovfl_structure(dbp, vdp, - child->pgno, child->tlen, - flags | ST_OVFL_LEAF)) != 0) { - if (ret == DB_VERIFY_BAD) - isbad = 1; - else - goto done; - } - - if ((ret = __db_vrfy_ccclose(cc)) != 0) - goto err; - cc = NULL; - - /* Case 1 */ - if (pip->type == P_LRECNO) { - if (!LF_ISSET(ST_IS_RECNO) && - !(LF_ISSET(ST_DUPOK) && !LF_ISSET(ST_DUPSORT))) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: recno leaf page non-recno tree", - (u_long)pgno)); - goto done; - } - goto leaf; - } else if (LF_ISSET(ST_IS_RECNO)) { - /* - * It's a non-recno leaf. Had better not be a recno - * subtree. - */ - isbad = 1; - EPRINT((dbenv, - "Page %lu: non-recno leaf page in recno tree", - (u_long)pgno)); - goto done; - } - - /* Case 2--no more work. */ - if (pip->type == P_LDUP) - goto leaf; - - /* Case 3 */ - - /* Check if we have any dups. */ - if (F_ISSET(pip, VRFY_HAS_DUPS)) { - /* If dups aren't allowed in this btree, trouble. */ - if (!LF_ISSET(ST_DUPOK)) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: duplicates in non-dup btree", - (u_long)pgno)); - } else { - /* - * We correctly have dups. If any are off-page, - * traverse those btrees recursively. - */ - if ((ret = - __db_vrfy_childcursor(vdp, &cc)) != 0) - goto err; - for (ret = __db_vrfy_ccset(cc, pgno, &child); - ret == 0; - ret = __db_vrfy_ccnext(cc, &child)) { - stflags = flags | ST_RECNUM | ST_DUPSET; - /* Skip any overflow entries. */ - if (child->type == V_DUPLICATE) { - if ((ret = __db_vrfy_duptype( - dbp, vdp, child->pgno, - stflags)) != 0) { - isbad = 1; - /* Next child. */ - continue; - } - if ((ret = __bam_vrfy_subtree( - dbp, vdp, child->pgno, NULL, - NULL, stflags | ST_TOPLEVEL, - NULL, NULL, NULL)) != 0) { - if (ret == - DB_VERIFY_BAD) - isbad = 1; - else - goto err; - } - } - } - - if ((ret = __db_vrfy_ccclose(cc)) != 0) - goto err; - cc = NULL; - - /* - * If VRFY_DUPS_UNSORTED is set, - * ST_DUPSORT had better not be. - */ - if (F_ISSET(pip, VRFY_DUPS_UNSORTED) && - LF_ISSET(ST_DUPSORT)) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: unsorted duplicate set in sorted-dup database", - (u_long)pgno)); - } - } - } - goto leaf; - case P_IBTREE: - case P_IRECNO: - /* We handle these below. */ - break; - default: - /* - * If a P_IBTREE or P_IRECNO contains a reference to an - * invalid page, we'll wind up here; handle it gracefully. - * Note that the code at the "done" label assumes that the - * current page is a btree/recno one of some sort; this - * is not the case here, so we goto err. - * - * If the page is entirely zeroed, its pip->type will be a lie - * (we assumed it was a hash page, as they're allowed to be - * zeroed); handle this case specially. - */ - if (F_ISSET(pip, VRFY_IS_ALLZEROES)) - ZEROPG_ERR_PRINT(dbenv, pgno, "btree or recno page"); - else - EPRINT((dbenv, - "Page %lu: btree or recno page is of inappropriate type %lu", - (u_long)pgno, (u_long)pip->type)); - - /* - * We probably lost a leaf page (or more if this was an - * internal page) from our prev/next_pgno chain. Flag - * that this is expected; we don't want or need to - * spew error messages about erroneous prev/next_pgnos, - * since that's probably not the real problem. - */ - F_SET(vdp, VRFY_LEAFCHAIN_BROKEN); - - ret = DB_VERIFY_BAD; - goto err; - } - - /* - * Cases 4 & 5: This is a btree or recno internal page. For each child, - * recurse, keeping a running count of nrecs and making sure the level - * is always reasonable. - */ - if ((ret = __db_vrfy_childcursor(vdp, &cc)) != 0) - goto err; - for (ret = __db_vrfy_ccset(cc, pgno, &child); ret == 0; - ret = __db_vrfy_ccnext(cc, &child)) - if (child->type == V_RECNO) { - if (pip->type != P_IRECNO) { - TYPE_ERR_PRINT(dbenv, "__bam_vrfy_subtree", - pgno, pip->type); - DB_ASSERT(0); - ret = EINVAL; - goto err; - } - if ((ret = __bam_vrfy_subtree(dbp, vdp, child->pgno, - NULL, NULL, flags, &child_level, &child_nrecs, - &child_relen)) != 0) { - if (ret == DB_VERIFY_BAD) - isbad = 1; - else - goto done; - } - - if (LF_ISSET(ST_RELEN)) { - if (relen == 0) - relen = child_relen; - /* - * child_relen may be zero if the child subtree - * is empty. - */ - else if (child_relen > 0 && - relen != child_relen) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: recno page returned bad re_len %lu", - (u_long)child->pgno, - (u_long)child_relen)); - } - if (relenp) - *relenp = relen; - } - if (LF_ISSET(ST_RECNUM)) { - if (child->nrecs != child_nrecs) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: record count incorrect: actual %lu, in record %lu", - (u_long)child->pgno, - (u_long)child_nrecs, - (u_long)child->nrecs)); - } - nrecs += child_nrecs; - } - if (isbad == 0 && level != child_level + 1) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: recno level incorrect: got %lu, expected %lu", - (u_long)child->pgno, (u_long)child_level, - (u_long)(level - 1))); - } - } else if (child->type == V_OVERFLOW) { - /* - * It is possible for one internal page to reference - * a single overflow page twice, if all the items - * in the subtree referenced by slot 0 are deleted, - * then a similar number of items are put back - * before the key that formerly had been in slot 1. - * - * (Btree doesn't look at the key in slot 0, so the - * fact that the key formerly at slot 1 is the "wrong" - * parent of the stuff in the slot 0 subtree isn't - * really incorrect.) - * - * __db_vrfy_ovfl_structure is designed to be - * efficiently called multiple times for multiple - * references; call it here as many times as is - * appropriate. - */ - - /* Otherwise, __db_vrfy_childput would be broken. */ - DB_ASSERT(child->refcnt >= 1); - - /* - * An overflow referenced more than twice here - * shouldn't happen. - */ - if (child->refcnt > 2) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: overflow page %lu referenced more than twice from internal page", - (u_long)pgno, (u_long)child->pgno)); - } else - for (j = 0; j < child->refcnt; j++) - if ((ret = __db_vrfy_ovfl_structure(dbp, - vdp, child->pgno, child->tlen, - flags)) != 0) { - if (ret == DB_VERIFY_BAD) - isbad = 1; - else - goto done; - } - } - - if ((ret = __db_vrfy_ccclose(cc)) != 0) - goto err; - cc = NULL; - - /* We're done with case 4. */ - if (pip->type == P_IRECNO) - goto done; - - /* - * Case 5. Btree internal pages. - * As described above, we need to iterate through all the - * items on the page and make sure that our children sort appropriately - * with respect to them. - * - * For each entry, li will be the "left-hand" key for the entry - * itself, which must sort lower than all entries on its child; - * ri will be the key to its right, which must sort greater. - */ - if (h == NULL && (ret = __memp_fget(mpf, &pgno, 0, &h)) != 0) - goto err; - for (i = 0; i < pip->entries; i += O_INDX) { - li = GET_BINTERNAL(dbp, h, i); - ri = (i + O_INDX < pip->entries) ? - GET_BINTERNAL(dbp, h, i + O_INDX) : rp; - - /* - * The leftmost key is forcibly sorted less than all entries, - * so don't bother passing it. - */ - if ((ret = __bam_vrfy_subtree(dbp, vdp, li->pgno, - i == 0 ? NULL : li, ri, flags, &child_level, - &child_nrecs, NULL)) != 0) { - if (ret == DB_VERIFY_BAD) - isbad = 1; - else - goto done; - } - - if (LF_ISSET(ST_RECNUM)) { - /* - * Keep a running tally on the actual record count so - * we can return it to our parent (if we have one) or - * compare it to the NRECS field if we're a root page. - */ - nrecs += child_nrecs; - - /* - * Make sure the actual record count of the child - * is equal to the value in the BINTERNAL structure. - */ - if (li->nrecs != child_nrecs) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: item %lu has incorrect record count of %lu, should be %lu", - (u_long)pgno, (u_long)i, (u_long)li->nrecs, - (u_long)child_nrecs)); - } - } - - if (level != child_level + 1) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: Btree level incorrect: got %lu, expected %lu", - (u_long)li->pgno, - (u_long)child_level, (u_long)(level - 1))); - } - } - - if (0) { -leaf: level = LEAFLEVEL; - if (LF_ISSET(ST_RECNUM)) - nrecs = pip->rec_cnt; - - /* XXX - * We should verify that the record count on a leaf page - * is the sum of the number of keys and the number of - * records in its off-page dups. This requires looking - * at the page again, however, and it may all be changing - * soon, so for now we don't bother. - */ - - if (LF_ISSET(ST_RELEN) && relenp) - *relenp = pip->re_len; - } -done: if (F_ISSET(pip, VRFY_INCOMPLETE) && isbad == 0 && ret == 0) { - /* - * During the page-by-page pass, item order verification was - * not finished due to the presence of overflow items. If - * isbad == 0, though, it's now safe to do so, as we've - * traversed any child overflow pages. Do it. - */ - if (h == NULL && (ret = __memp_fget(mpf, &pgno, 0, &h)) != 0) - goto err; - if ((ret = __bam_vrfy_itemorder(dbp, - vdp, h, pgno, 0, 1, 0, flags)) != 0) - goto err; - F_CLR(pip, VRFY_INCOMPLETE); - } - - /* - * It's possible to get to this point with a page that has no - * items, but without having detected any sort of failure yet. - * Having zero items is legal if it's a leaf--it may be the - * root page in an empty tree, or the tree may have been - * modified with the DB_REVSPLITOFF flag set (there's no way - * to tell from what's on disk). For an internal page, - * though, having no items is a problem (all internal pages - * must have children). - */ - if (isbad == 0 && ret == 0) { - if (h == NULL && (ret = __memp_fget(mpf, &pgno, 0, &h)) != 0) - goto err; - - if (NUM_ENT(h) == 0 && ISINTERNAL(h)) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: internal page is empty and should not be", - (u_long)pgno)); - goto err; - } - } - - /* - * Our parent has sent us BINTERNAL pointers to parent records - * so that we can verify our place with respect to them. If it's - * appropriate--we have a default sort function--verify this. - */ - if (isbad == 0 && ret == 0 && !LF_ISSET(DB_NOORDERCHK) && lp != NULL) { - if (h == NULL && (ret = __memp_fget(mpf, &pgno, 0, &h)) != 0) - goto err; - - /* - * __bam_vrfy_treeorder needs to know what comparison function - * to use. If ST_DUPSET is set, we're in a duplicate tree - * and we use the duplicate comparison function; otherwise, - * use the btree one. If unset, use the default, of course. - */ - func = LF_ISSET(ST_DUPSET) ? dbp->dup_compare : - ((BTREE *)dbp->bt_internal)->bt_compare; - if (func == NULL) - func = __bam_defcmp; - - if ((ret = __bam_vrfy_treeorder( - dbp, pgno, h, lp, rp, func, flags)) != 0) { - if (ret == DB_VERIFY_BAD) - isbad = 1; - else - goto err; - } - } - - /* - * This is guaranteed to succeed for leaf pages, but no harm done. - * - * Internal pages below the top level do not store their own - * record numbers, so we skip them. - */ - if (LF_ISSET(ST_RECNUM) && nrecs != pip->rec_cnt && toplevel) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: bad record count: has %lu records, claims %lu", - (u_long)pgno, (u_long)nrecs, (u_long)pip->rec_cnt)); - } - - if (levelp) - *levelp = level; - if (nrecsp) - *nrecsp = nrecs; - - pgset = vdp->pgset; - if ((ret = __db_vrfy_pgset_get(pgset, pgno, &p)) != 0) - goto err; - if (p != 0) { - isbad = 1; - EPRINT((dbenv, "Page %lu: linked twice", (u_long)pgno)); - } else if ((ret = __db_vrfy_pgset_inc(pgset, pgno)) != 0) - goto err; - - if (toplevel) - /* - * The last page's next_pgno in the leaf chain should have been - * PGNO_INVALID. - */ - if (vdp->next_pgno != PGNO_INVALID) { - isbad = 1; - EPRINT((dbenv, "Page %lu: unterminated leaf chain", - (u_long)vdp->prev_pgno)); - } - -err: if (toplevel) { - /* Restore our caller's settings. */ - vdp->next_pgno = next_pgno; - vdp->prev_pgno = prev_pgno; - vdp->leaf_type = leaf_type; - } - - if (h != NULL && (t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0 && ret == 0) - ret = t_ret; - if (cc != NULL && ((t_ret = __db_vrfy_ccclose(cc)) != 0) && ret == 0) - ret = t_ret; - return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); -} - -/* - * __bam_vrfy_treeorder -- - * Verify that the lowest key on a page sorts greater than the - * BINTERNAL which points to it (lp), and the highest key - * sorts less than the BINTERNAL above that (rp). - * - * If lp is NULL, this means that it was the leftmost key on the - * parent, which (regardless of sort function) sorts less than - * all keys. No need to check it. - * - * If rp is NULL, lp was the highest key on the parent, so there's - * no higher key we must sort less than. - */ -static int -__bam_vrfy_treeorder(dbp, pgno, h, lp, rp, func, flags) - DB *dbp; - db_pgno_t pgno; - PAGE *h; - BINTERNAL *lp, *rp; - int (*func) __P((DB *, const DBT *, const DBT *)); - u_int32_t flags; -{ - BOVERFLOW *bo; - DB_ENV *dbenv; - DBT dbt; - db_indx_t last; - int ret, cmp; - - dbenv = dbp->dbenv; - memset(&dbt, 0, sizeof(DBT)); - F_SET(&dbt, DB_DBT_MALLOC); - ret = 0; - - /* - * Empty pages are sorted correctly by definition. We check - * to see whether they ought to be empty elsewhere; leaf - * pages legally may be. - */ - if (NUM_ENT(h) == 0) - return (0); - - switch (TYPE(h)) { - case P_IBTREE: - case P_LDUP: - last = NUM_ENT(h) - O_INDX; - break; - case P_LBTREE: - last = NUM_ENT(h) - P_INDX; - break; - default: - TYPE_ERR_PRINT(dbenv, "__bam_vrfy_treeorder", pgno, TYPE(h)); - DB_ASSERT(0); - return (EINVAL); - } - - /* - * The key on page h, the child page, is more likely to be - * an overflow page, so we pass its offset, rather than lp/rp's, - * into __bam_cmp. This will take advantage of __db_moff. - */ - - /* - * Skip first-item check if we're an internal page--the first - * entry on an internal page is treated specially by __bam_cmp, - * so what's on the page shouldn't matter. (Plus, since we're passing - * our page and item 0 as to __bam_cmp, we'll sort before our - * parent and falsely report a failure.) - */ - if (lp != NULL && TYPE(h) != P_IBTREE) { - if (lp->type == B_KEYDATA) { - dbt.data = lp->data; - dbt.size = lp->len; - } else if (lp->type == B_OVERFLOW) { - bo = (BOVERFLOW *)lp->data; - if ((ret = __db_goff(dbp, &dbt, bo->tlen, bo->pgno, - NULL, NULL)) != 0) - return (ret); - } else { - DB_ASSERT(0); - EPRINT((dbenv, - "Page %lu: unknown type for internal record", - (u_long)PGNO(h))); - return (EINVAL); - } - - /* On error, fall through, free if needed, and return. */ - if ((ret = __bam_cmp(dbp, &dbt, h, 0, func, &cmp)) == 0) { - if (cmp > 0) { - EPRINT((dbenv, - "Page %lu: first item on page sorted greater than parent entry", - (u_long)PGNO(h))); - ret = DB_VERIFY_BAD; - } - } else - EPRINT((dbenv, - "Page %lu: first item on page had comparison error", - (u_long)PGNO(h))); - - if (dbt.data != lp->data) - __os_ufree(dbenv, dbt.data); - if (ret != 0) - return (ret); - } - - if (rp != NULL) { - if (rp->type == B_KEYDATA) { - dbt.data = rp->data; - dbt.size = rp->len; - } else if (rp->type == B_OVERFLOW) { - bo = (BOVERFLOW *)rp->data; - if ((ret = __db_goff(dbp, &dbt, bo->tlen, bo->pgno, - NULL, NULL)) != 0) - return (ret); - } else { - DB_ASSERT(0); - EPRINT((dbenv, - "Page %lu: unknown type for internal record", - (u_long)PGNO(h))); - return (EINVAL); - } - - /* On error, fall through, free if needed, and return. */ - if ((ret = __bam_cmp(dbp, &dbt, h, last, func, &cmp)) == 0) { - if (cmp < 0) { - EPRINT((dbenv, - "Page %lu: last item on page sorted greater than parent entry", - (u_long)PGNO(h))); - ret = DB_VERIFY_BAD; - } - } else - EPRINT((dbenv, - "Page %lu: last item on page had comparison error", - (u_long)PGNO(h))); - - if (dbt.data != rp->data) - __os_ufree(dbenv, dbt.data); - } - - return (ret); -} - -/* - * __bam_salvage -- - * Safely dump out anything that looks like a key on an alleged - * btree leaf page. - * - * PUBLIC: int __bam_salvage __P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t, - * PUBLIC: PAGE *, void *, int (*)(void *, const void *), DBT *, - * PUBLIC: u_int32_t)); - */ -int -__bam_salvage(dbp, vdp, pgno, pgtype, h, handle, callback, key, flags) - DB *dbp; - VRFY_DBINFO *vdp; - db_pgno_t pgno; - u_int32_t pgtype; - PAGE *h; - void *handle; - int (*callback) __P((void *, const void *)); - DBT *key; - u_int32_t flags; -{ - BKEYDATA *bk; - BOVERFLOW *bo; - DBT dbt, unknown_key, unknown_data; - DB_ENV *dbenv; - VRFY_ITEM *pgmap; - db_indx_t i, last, beg, end, *inp; - u_int32_t himark; - void *ovflbuf; - int ret, t_ret, t2_ret; - - dbenv = dbp->dbenv; - ovflbuf = pgmap = NULL; - inp = P_INP(dbp, h); - - memset(&dbt, 0, sizeof(DBT)); - dbt.flags = DB_DBT_REALLOC; - - memset(&unknown_key, 0, sizeof(DBT)); - unknown_key.size = (u_int32_t)strlen("UNKNOWN_KEY"); - unknown_key.data = "UNKNOWN_KEY"; - memset(&unknown_data, 0, sizeof(DBT)); - unknown_data.size = (u_int32_t)strlen("UNKNOWN_DATA"); - unknown_data.data = "UNKNOWN_DATA"; - - /* - * Allocate a buffer for overflow items. Start at one page; - * __db_safe_goff will realloc as needed. - */ - if ((ret = __os_malloc(dbenv, dbp->pgsize, &ovflbuf)) != 0) - goto err; - - if (LF_ISSET(DB_AGGRESSIVE) && (ret = - __os_calloc(dbenv, dbp->pgsize, sizeof(pgmap[0]), &pgmap)) != 0) - goto err; - - /* - * Loop through the inp array, spitting out key/data pairs. - * - * If we're salvaging normally, loop from 0 through NUM_ENT(h). If - * we're being aggressive, loop until we hit the end of the page -- - * NUM_ENT() may be bogus. - */ - himark = dbp->pgsize; - for (i = 0, last = UINT16_MAX;; i += O_INDX) { - /* If we're not aggressive, break when we hit NUM_ENT(h). */ - if (!LF_ISSET(DB_AGGRESSIVE) && i >= NUM_ENT(h)) - break; - - /* Verify the current item. */ - t_ret = - __db_vrfy_inpitem(dbp, h, pgno, i, 1, flags, &himark, NULL); - - if (t_ret != 0) { - /* - * If this is a btree leaf and we've printed out a key - * but not its associated data item, fix this imbalance - * by printing an "UNKNOWN_DATA". - */ - if (pgtype == P_LBTREE && i % P_INDX == 1 && - last == i - 1 && (t2_ret = __db_vrfy_prdbt( - &unknown_data, - 0, " ", handle, callback, 0, vdp)) != 0) { - if (ret == 0) - ret = t2_ret; - goto err; - } - - /* - * Don't return DB_VERIFY_FATAL; it's private and means - * only that we can't go on with this page, not with - * the whole database. It's not even an error if we've - * run into it after NUM_ENT(h). - */ - if (t_ret == DB_VERIFY_FATAL) { - if (i < NUM_ENT(h) && ret == 0) - ret = DB_VERIFY_BAD; - break; - } - continue; - } - - /* - * If this returned 0, it's safe to print or (carefully) - * try to fetch. - * - * We only print deleted items if DB_AGGRESSIVE is set. - */ - bk = GET_BKEYDATA(dbp, h, i); - if (!LF_ISSET(DB_AGGRESSIVE) && B_DISSET(bk->type)) - continue; - - /* - * If this is a btree leaf and we're about to print out a data - * item for which we didn't print out a key, fix this imbalance - * by printing an "UNKNOWN_KEY". - */ - if (pgtype == P_LBTREE && i % P_INDX == 1 && - last != i - 1 && (t_ret = __db_vrfy_prdbt( - &unknown_key, 0, " ", handle, callback, 0, vdp)) != 0) { - if (ret == 0) - ret = t_ret; - goto err; - } - last = i; - - /* - * We're going to go try to print the next item. If key is - * non-NULL, we're a dup page, so we've got to print the key - * first, unless SA_SKIPFIRSTKEY is set and we're on the first - * entry. - */ - if (key != NULL && (i != 0 || !LF_ISSET(SA_SKIPFIRSTKEY))) - if ((t_ret = __db_vrfy_prdbt(key, - 0, " ", handle, callback, 0, vdp)) != 0) { - if (ret == 0) - ret = t_ret; - goto err; - } - - beg = inp[i]; - switch (B_TYPE(bk->type)) { - case B_DUPLICATE: - end = beg + BOVERFLOW_SIZE - 1; - /* - * If we're not on a normal btree leaf page, there - * shouldn't be off-page dup sets. Something's - * confused; just drop it, and the code to pick up - * unlinked offpage dup sets will print it out - * with key "UNKNOWN" later. - */ - if (pgtype != P_LBTREE) - break; - - bo = (BOVERFLOW *)bk; - - /* - * If the page number is unreasonable, or if this is - * supposed to be a key item, output "UNKNOWN_KEY" -- - * the best we can do is run into the data items in - * the unlinked offpage dup pass. - */ - if (!IS_VALID_PGNO(bo->pgno) || (i % P_INDX == 0)) { - /* Not much to do on failure. */ - if ((t_ret = __db_vrfy_prdbt(&unknown_key, - 0, " ", handle, callback, 0, vdp)) != 0) { - if (ret == 0) - ret = t_ret; - goto err; - } - break; - } - - /* Don't stop on error. */ - if ((t_ret = __db_salvage_duptree(dbp, - vdp, bo->pgno, &dbt, handle, callback, - flags | SA_SKIPFIRSTKEY)) != 0 && ret == 0) - ret = t_ret; - - break; - case B_KEYDATA: - end = (db_indx_t)DB_ALIGN( - beg + bk->len, sizeof(u_int32_t)) - 1; - dbt.data = bk->data; - dbt.size = bk->len; - if ((t_ret = __db_vrfy_prdbt(&dbt, - 0, " ", handle, callback, 0, vdp)) != 0) { - if (ret == 0) - ret = t_ret; - goto err; - } - break; - case B_OVERFLOW: - end = beg + BOVERFLOW_SIZE - 1; - bo = (BOVERFLOW *)bk; - - /* Don't stop on error. */ - if ((t_ret = __db_safe_goff(dbp, vdp, - bo->pgno, &dbt, &ovflbuf, flags)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = __db_vrfy_prdbt( - t_ret == 0 ? &dbt : &unknown_key, - 0, " ", handle, callback, 0, vdp)) != 0 && ret == 0) - ret = t_ret; - break; - default: - /* - * We should never get here; __db_vrfy_inpitem should - * not be returning 0 if bk->type is unrecognizable. - */ - DB_ASSERT(0); - if (ret == 0) - ret = EINVAL; - goto err; - } - - /* - * If we're being aggressive, mark the beginning and end of - * the item; we'll come back and print whatever "junk" is in - * the gaps in case we had any bogus inp elements and thereby - * missed stuff. - */ - if (LF_ISSET(DB_AGGRESSIVE)) { - pgmap[beg] = VRFY_ITEM_BEGIN; - pgmap[end] = VRFY_ITEM_END; - } - } - -err: if (pgmap != NULL) - __os_free(dbenv, pgmap); - if (ovflbuf != NULL) - __os_free(dbenv, ovflbuf); - - /* Mark this page as done. */ - if ((t_ret = __db_salvage_markdone(vdp, pgno)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __bam_salvage_walkdupint -- - * Walk a known-good btree or recno internal page which is part of - * a dup tree, calling __db_salvage_duptree on each child page. - * - * PUBLIC: int __bam_salvage_walkdupint __P((DB *, VRFY_DBINFO *, PAGE *, - * PUBLIC: DBT *, void *, int (*)(void *, const void *), u_int32_t)); - */ -int -__bam_salvage_walkdupint(dbp, vdp, h, key, handle, callback, flags) - DB *dbp; - VRFY_DBINFO *vdp; - PAGE *h; - DBT *key; - void *handle; - int (*callback) __P((void *, const void *)); - u_int32_t flags; -{ - RINTERNAL *ri; - BINTERNAL *bi; - int ret, t_ret; - db_indx_t i; - - ret = 0; - for (i = 0; i < NUM_ENT(h); i++) { - switch (TYPE(h)) { - case P_IBTREE: - bi = GET_BINTERNAL(dbp, h, i); - if ((t_ret = __db_salvage_duptree(dbp, - vdp, bi->pgno, key, handle, callback, flags)) != 0) - ret = t_ret; - break; - case P_IRECNO: - ri = GET_RINTERNAL(dbp, h, i); - if ((t_ret = __db_salvage_duptree(dbp, - vdp, ri->pgno, key, handle, callback, flags)) != 0) - ret = t_ret; - break; - default: - __db_err(dbp->dbenv, - "__bam_salvage_walkdupint called on non-int. page"); - DB_ASSERT(0); - return (EINVAL); - } - /* Pass SA_SKIPFIRSTKEY, if set, on to the 0th child only. */ - flags &= ~LF_ISSET(SA_SKIPFIRSTKEY); - } - - return (ret); -} - -/* - * __bam_meta2pgset -- - * Given a known-good meta page, return in pgsetp a 0-terminated list of - * db_pgno_t's corresponding to the pages in the btree. - * - * We do this by a somewhat sleazy method, to avoid having to traverse the - * btree structure neatly: we walk down the left side to the very - * first leaf page, then we mark all the pages in the chain of - * NEXT_PGNOs (being wary of cycles and invalid ones), then we - * consolidate our scratch array into a nice list, and return. This - * avoids the memory management hassles of recursion and the - * trouble of walking internal pages--they just don't matter, except - * for the left branch. - * - * PUBLIC: int __bam_meta2pgset __P((DB *, VRFY_DBINFO *, BTMETA *, - * PUBLIC: u_int32_t, DB *)); - */ -int -__bam_meta2pgset(dbp, vdp, btmeta, flags, pgset) - DB *dbp; - VRFY_DBINFO *vdp; - BTMETA *btmeta; - u_int32_t flags; - DB *pgset; -{ - BINTERNAL *bi; - DB_MPOOLFILE *mpf; - PAGE *h; - RINTERNAL *ri; - db_pgno_t current, p; - int err_ret, ret; - - mpf = dbp->mpf; - h = NULL; - ret = err_ret = 0; - DB_ASSERT(pgset != NULL); - for (current = btmeta->root;;) { - if (!IS_VALID_PGNO(current) || current == PGNO(btmeta)) { - err_ret = DB_VERIFY_BAD; - goto err; - } - if ((ret = __memp_fget(mpf, ¤t, 0, &h)) != 0) { - err_ret = ret; - goto err; - } - - switch (TYPE(h)) { - case P_IBTREE: - case P_IRECNO: - if ((ret = __bam_vrfy(dbp, - vdp, h, current, flags | DB_NOORDERCHK)) != 0) { - err_ret = ret; - goto err; - } - if (TYPE(h) == P_IBTREE) { - bi = GET_BINTERNAL(dbp, h, 0); - current = bi->pgno; - } else { /* P_IRECNO */ - ri = GET_RINTERNAL(dbp, h, 0); - current = ri->pgno; - } - break; - case P_LBTREE: - case P_LRECNO: - goto traverse; - default: - err_ret = DB_VERIFY_BAD; - goto err; - } - - if ((ret = __memp_fput(mpf, h, 0)) != 0) - err_ret = ret; - h = NULL; - } - - /* - * At this point, current is the pgno of leaf page h, the 0th in the - * tree we're concerned with. - */ -traverse: - while (IS_VALID_PGNO(current) && current != PGNO_INVALID) { - if (h == NULL && - (ret = __memp_fget(mpf, ¤t, 0, &h)) != 0) { - err_ret = ret; - break; - } - - if ((ret = __db_vrfy_pgset_get(pgset, current, (int *)&p)) != 0) - goto err; - - if (p != 0) { - /* - * We've found a cycle. Return success anyway-- - * our caller may as well use however much of - * the pgset we've come up with. - */ - break; - } - if ((ret = __db_vrfy_pgset_inc(pgset, current)) != 0) - goto err; - - current = NEXT_PGNO(h); - if ((ret = __memp_fput(mpf, h, 0)) != 0) - err_ret = ret; - h = NULL; - } - -err: if (h != NULL) - (void)__memp_fput(mpf, h, 0); - - return (ret == 0 ? err_ret : ret); -} - -/* - * __bam_safe_getdata -- - * - * Utility function for __bam_vrfy_itemorder. Safely gets the datum at - * index i, page h, and sticks it in DBT dbt. If ovflok is 1 and i's an - * overflow item, we do a safe_goff to get the item and signal that we need - * to free dbt->data; if ovflok is 0, we leaves the DBT zeroed. - */ -static int -__bam_safe_getdata(dbp, h, i, ovflok, dbt, freedbtp) - DB *dbp; - PAGE *h; - u_int32_t i; - int ovflok; - DBT *dbt; - int *freedbtp; -{ - BKEYDATA *bk; - BOVERFLOW *bo; - - memset(dbt, 0, sizeof(DBT)); - *freedbtp = 0; - - bk = GET_BKEYDATA(dbp, h, i); - if (B_TYPE(bk->type) == B_OVERFLOW) { - if (!ovflok) - return (0); - - bo = (BOVERFLOW *)bk; - F_SET(dbt, DB_DBT_MALLOC); - - *freedbtp = 1; - return (__db_goff(dbp, dbt, bo->tlen, bo->pgno, NULL, NULL)); - } else { - dbt->data = bk->data; - dbt->size = bk->len; - } - - return (0); -} diff --git a/storage/bdb/btree/btree.src b/storage/bdb/btree/btree.src deleted file mode 100644 index 1827cffcc53..00000000000 --- a/storage/bdb/btree/btree.src +++ /dev/null @@ -1,252 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: btree.src,v 12.3 2005/08/08 03:37:05 ubell Exp $ - */ - -PREFIX __bam -DBPRIVATE - -INCLUDE #ifndef NO_SYSTEM_INCLUDES -INCLUDE #include <sys/types.h> -INCLUDE -INCLUDE #include <ctype.h> -INCLUDE #include <string.h> -INCLUDE #endif -INCLUDE -INCLUDE #include "db_int.h" -INCLUDE #include "dbinc/crypto.h" -INCLUDE #include "dbinc/db_page.h" -INCLUDE #include "dbinc/db_dispatch.h" -INCLUDE #include "dbinc/db_am.h" -INCLUDE #include "dbinc/btree.h" -INCLUDE #include "dbinc/log.h" -INCLUDE #include "dbinc/txn.h" -INCLUDE - -/* - * BTREE-split: used to log a page split. - * - * left: the page number for the low-order contents. - * llsn: the left page's original LSN. - * right: the page number for the high-order contents. - * rlsn: the right page's original LSN. - * indx: the number of entries that went to the left page. - * npgno: the next page number - * nlsn: the next page's original LSN (or 0 if no next page). - * root_pgno: the root page number - * pg: the split page's contents before the split. - * opflags: SPL_NRECS: if splitting a tree that maintains a record count. - */ -BEGIN split 62 -DB fileid int32_t ld -ARG left db_pgno_t lu -POINTER llsn DB_LSN * lu -ARG right db_pgno_t lu -POINTER rlsn DB_LSN * lu -ARG indx u_int32_t lu -ARG npgno db_pgno_t lu -POINTER nlsn DB_LSN * lu -ARG root_pgno db_pgno_t lu -PGDBT pg DBT s -ARG opflags u_int32_t lu -END - -/* - * BTREE-rsplit: used to log a reverse-split - * - * pgno: the page number of the page copied over the root. - * pgdbt: the page being copied on the root page. - * root_pgno: the root page number. - * nrec: the tree's record count. - * rootent: last entry on the root page. - * rootlsn: the root page's original lsn. - */ -BEGIN rsplit 63 -DB fileid int32_t ld -ARG pgno db_pgno_t lu -PGDBT pgdbt DBT s -ARG root_pgno db_pgno_t lu -ARG nrec db_pgno_t lu -DBT rootent DBT s -POINTER rootlsn DB_LSN * lu -END - -/* - * BTREE-adj: used to log the adjustment of an index. - * - * pgno: the page modified. - * lsn: the page's original lsn. - * indx: the index adjusted. - * indx_copy: the index to copy if inserting. - * is_insert: 0 if a delete, 1 if an insert. - */ -BEGIN adj 55 -DB fileid int32_t ld -ARG pgno db_pgno_t lu -POINTER lsn DB_LSN * lu -ARG indx u_int32_t lu -ARG indx_copy u_int32_t lu -ARG is_insert u_int32_t lu -END - -/* - * BTREE-cadjust: used to adjust the count change in an internal page. - * - * pgno: the page modified. - * lsn: the page's original lsn. - * indx: the index to be adjusted. - * adjust: the signed adjustment. - * opflags: CAD_UPDATEROOT: if root page count was adjusted. - */ -BEGIN cadjust 56 -DB fileid int32_t ld -ARG pgno db_pgno_t lu -POINTER lsn DB_LSN * lu -ARG indx u_int32_t lu -ARG adjust int32_t ld -ARG opflags u_int32_t lu -END - -/* - * BTREE-cdel: used to log the intent-to-delete of a cursor record. - * - * pgno: the page modified. - * lsn: the page's original lsn. - * indx: the index to be deleted. - */ -BEGIN cdel 57 -DB fileid int32_t ld -ARG pgno db_pgno_t lu -POINTER lsn DB_LSN * lu -ARG indx u_int32_t lu -END - -/* - * BTREE-repl: used to log the replacement of an item. - * - * pgno: the page modified. - * lsn: the page's original lsn. - * indx: the index to be replaced. - * isdeleted: set if the record was previously deleted. - * orig: the original data. - * repl: the replacement data. - * prefix: the prefix of the replacement that matches the original. - * suffix: the suffix of the replacement that matches the original. - */ -BEGIN repl 58 -DB fileid int32_t ld -ARG pgno db_pgno_t lu -POINTER lsn DB_LSN * lu -ARG indx u_int32_t lu -ARG isdeleted u_int32_t lu -DBT orig DBT s -DBT repl DBT s -ARG prefix u_int32_t lu -ARG suffix u_int32_t lu -END - -/* - * BTREE-root: log the assignment of a root btree page. - */ -BEGIN root 59 -DB fileid int32_t ld -ARG meta_pgno db_pgno_t lu -ARG root_pgno db_pgno_t lu -POINTER meta_lsn DB_LSN * lu -END - -/* - * BTREE-curadj: undo cursor adjustments on txn abort. - * Should only be processed during DB_TXN_ABORT. - * NOTE: the first_indx field gets used to hold - * signed index adjustment in one case. - * care should be taken if its size is changed. - */ -BEGIN curadj 64 -/* Fileid of db affected. */ -DB fileid int32_t ld -/* Which adjustment. */ -ARG mode db_ca_mode ld -/* Page entry is from. */ -ARG from_pgno db_pgno_t lu -/* Page entry went to. */ -ARG to_pgno db_pgno_t lu -/* Left page of root split. */ -ARG left_pgno db_pgno_t lu -/* First index of dup set. Also used as adjustment. */ -ARG first_indx u_int32_t lu -/* Index entry is from. */ -ARG from_indx u_int32_t lu -/* Index where entry went. */ -ARG to_indx u_int32_t lu -END - -/* - * BTREE-rcuradj: undo cursor adjustments on txn abort in - * renumbering recno trees. - * Should only be processed during DB_TXN_ABORT. - */ -BEGIN rcuradj 65 -/* Fileid of db affected. */ -DB fileid int32_t ld -/* Which adjustment. */ -ARG mode ca_recno_arg ld -/* Root page number. */ -ARG root db_pgno_t ld -/* Recno of the adjustment. */ -ARG recno db_recno_t ld -/* Order number of the adjustment. */ -ARG order u_int32_t ld -END - -/* - * BTREE-relink -- Handles relinking around a deleted leaf page. - * - */ -BEGIN relink 147 -/* Fileid of db affected. */ -DB fileid int32_t ld -/* The page being removed. */ -ARG pgno db_pgno_t lu -/* The new page number, if any. */ -ARG new_pgno db_pgno_t lu -/* The previous page. */ -ARG prev db_pgno_t lu -/* The previous page's original lsn. */ -POINTER lsn_prev DB_LSN * lu -/* The next page. */ -ARG next db_pgno_t lu -/* The previous page's original lsn. */ -POINTER lsn_next DB_LSN * lu -END - -/* - * BTREE-merge -- Handles merging of pages during a compaction. - */ -BEGIN merge 148 -DB fileid int32_t ld -ARG pgno db_pgno_t lu -POINTER lsn DB_LSN * lu -ARG npgno db_pgno_t lu -POINTER nlsn DB_LSN * lu -DBT hdr DBT s -DBT data DBT s -DBT ind DBT s -END - -/* - * BTREE-pgno -- Handles replacing a page number in the record - * refernece on pgno by indx. - */ -BEGIN pgno 149 -DB fileid int32_t ld -ARG pgno db_pgno_t lu -POINTER lsn DB_LSN * lu -ARG indx u_int32_t lu -ARG opgno db_pgno_t lu -ARG npgno db_pgno_t lu -END diff --git a/storage/bdb/build_unix/.IGNORE_ME b/storage/bdb/build_unix/.IGNORE_ME deleted file mode 100644 index 558fd496f0c..00000000000 --- a/storage/bdb/build_unix/.IGNORE_ME +++ /dev/null @@ -1,3 +0,0 @@ -Some combinations of the gzip and tar archive exploders found -on Linux systems ignore directories that don't have any files -(other than symbolic links) in them. So, here's a file. diff --git a/storage/bdb/build_win32/Berkeley_DB.dsw b/storage/bdb/build_win32/Berkeley_DB.dsw deleted file mode 100644 index 91440869b83..00000000000 --- a/storage/bdb/build_win32/Berkeley_DB.dsw +++ /dev/null @@ -1,782 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "build_all"=.\build_all.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_archive - End Project Dependency - Begin Project Dependency - Project_Dep_Name db_checkpoint - End Project Dependency - Begin Project Dependency - Project_Dep_Name db_deadlock - End Project Dependency - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency - Begin Project Dependency - Project_Dep_Name db_dump - End Project Dependency - Begin Project Dependency - Project_Dep_Name db_hotbackup - End Project Dependency - Begin Project Dependency - Project_Dep_Name db_load - End Project Dependency - Begin Project Dependency - Project_Dep_Name db_printlog - End Project Dependency - Begin Project Dependency - Project_Dep_Name db_recover - End Project Dependency - Begin Project Dependency - Project_Dep_Name db_stat - End Project Dependency - Begin Project Dependency - Project_Dep_Name db_upgrade - End Project Dependency - Begin Project Dependency - Project_Dep_Name db_verify - End Project Dependency - Begin Project Dependency - Project_Dep_Name db_static - End Project Dependency - Begin Project Dependency - Project_Dep_Name ex_access - End Project Dependency - Begin Project Dependency - Project_Dep_Name ex_btrec - End Project Dependency - Begin Project Dependency - Project_Dep_Name ex_env - End Project Dependency - Begin Project Dependency - Project_Dep_Name ex_lock - End Project Dependency - Begin Project Dependency - Project_Dep_Name ex_mpool - End Project Dependency - Begin Project Dependency - Project_Dep_Name ex_sequence - End Project Dependency - Begin Project Dependency - Project_Dep_Name ex_tpcb - End Project Dependency - Begin Project Dependency - Project_Dep_Name example_database_load - End Project Dependency - Begin Project Dependency - Project_Dep_Name example_database_read - End Project Dependency - Begin Project Dependency - Project_Dep_Name excxx_access - End Project Dependency - Begin Project Dependency - Project_Dep_Name excxx_btrec - End Project Dependency - Begin Project Dependency - Project_Dep_Name excxx_env - End Project Dependency - Begin Project Dependency - Project_Dep_Name excxx_lock - End Project Dependency - Begin Project Dependency - Project_Dep_Name excxx_mpool - End Project Dependency - Begin Project Dependency - Project_Dep_Name excxx_sequence - End Project Dependency - Begin Project Dependency - Project_Dep_Name excxx_tpcb - End Project Dependency - Begin Project Dependency - Project_Dep_Name excxx_example_database_load - End Project Dependency - Begin Project Dependency - Project_Dep_Name excxx_example_database_read - End Project Dependency - Begin Project Dependency - Project_Dep_Name ex_repquote - End Project Dependency - Begin Project Dependency - Project_Dep_Name ex_txnguide - End Project Dependency - Begin Project Dependency - Project_Dep_Name ex_txnguide_inmem - End Project Dependency - Begin Project Dependency - Project_Dep_Name excxx_txnguide - End Project Dependency - Begin Project Dependency - Project_Dep_Name excxx_txnguide_inmem - End Project Dependency -}}} - -############################################################################### - -Project: "db_archive"=.\db_archive.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "db_checkpoint"=.\db_checkpoint.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "db_deadlock"=.\db_deadlock.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "db_dll"=.\db_dll.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Project: "db_dump"=.\db_dump.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "db_hotbackup"=.\db_hotbackup.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "db_java"=.\db_java.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "db_load"=.\db_load.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "db_printlog"=.\db_printlog.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "db_recover"=.\db_recover.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "db_small"=.\db_small.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Project: "db_stat"=.\db_stat.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "db_static"=.\db_static.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Project: "db_tcl"=.\db_tcl.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "db_test"=.\db_test.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name build_all - End Project Dependency - Begin Project Dependency - Project_Dep_Name db_tcl - End Project Dependency -}}} - -############################################################################### - -Project: "db_upgrade"=.\db_upgrade.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "db_verify"=.\db_verify.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "ex_access"=.\ex_access.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "ex_btrec"=.\ex_btrec.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "ex_csvcode"=.\ex_csvcode.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "ex_csvload"=.\ex_csvload.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency - Begin Project Dependency - Project_Dep_Name ex_csvcode - End Project Dependency -}}} - -############################################################################### - -Project: "ex_csvquery"=.\ex_csvquery.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency - Begin Project Dependency - Project_Dep_Name ex_csvcode - End Project Dependency -}}} - -############################################################################### - -Project: "ex_env"=.\ex_env.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "ex_lock"=.\ex_lock.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "ex_mpool"=.\ex_mpool.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "ex_repquote"=.\ex_repquote.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "ex_sequence"=.\ex_sequence.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "ex_tpcb"=.\ex_tpcb.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "ex_txnguide"=.\ex_txnguide.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "ex_txnguide_inmem"=.\ex_txnguide_inmem.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "example_database_load"=.\example_database_load.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "example_database_read"=.\example_database_read.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "excxx_access"=.\excxx_access.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "excxx_btrec"=.\excxx_btrec.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "excxx_env"=.\excxx_env.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "excxx_example_database_load"=.\excxx_example_database_load.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "excxx_example_database_read"=.\excxx_example_database_read.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "excxx_lock"=.\excxx_lock.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "excxx_mpool"=.\excxx_mpool.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "excxx_sequence"=.\excxx_sequence.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "excxx_tpcb"=.\excxx_tpcb.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "excxx_txnguide"=.\excxx_txnguide.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Project: "excxx_txnguide_inmem"=.\excxx_txnguide_inmem.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name db_dll - End Project Dependency -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/storage/bdb/build_win32/app_dsp.src b/storage/bdb/build_win32/app_dsp.src deleted file mode 100644 index e8644c71299..00000000000 --- a/storage/bdb/build_win32/app_dsp.src +++ /dev/null @@ -1,261 +0,0 @@ -# Microsoft Developer Studio Project File - Name="@project_name@" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=@project_name@ - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "@project_name@.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "@project_name@.mak" CFG="@project_name@ - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "@project_name@ - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "@project_name@ - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE "@project_name@ - Win32 ASCII Debug" (based on "Win32 (x86) Console Application") -!MESSAGE "@project_name@ - Win32 ASCII Release" (based on "Win32 (x86) Console Application") -!MESSAGE "@project_name@ - Win64 Debug AMD64" (based on "Win32 (x86) Console Application") -!MESSAGE "@project_name@ - Win64 Release AMD64" (based on "Win32 (x86) Console Application") -!MESSAGE "@project_name@ - Win64 Debug IA64" (based on "Win32 (x86) Console Application") -!MESSAGE "@project_name@ - Win64 Release IA64" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "@project_name@ - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "@bin_rel_dest@" -# PROP BASE Intermediate_Dir "Release/@project_name@" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "@bin_rel_dest@" -# PROP Intermediate_Dir "Release/@project_name@" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" @extra_cppflags@ /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" @extra_cppflags@ /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 @release_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib @release_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt" /libpath:"@lib_rel_dest@" -@POST_BUILD@ - -!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "@bin_debug_dest@" -# PROP BASE Intermediate_Dir "Debug/@project_name@" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "@bin_debug_dest@" -# PROP Intermediate_Dir "Debug/@project_name@" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" @extra_cppflags@ /FD /c -# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" @extra_cppflags@ /FD /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 @debug_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib @debug_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no /libpath:"@lib_debug_dest@" -@POST_BUILD@ - -!ELSEIF "$(CFG)" == "@project_name@ - Win32 ASCII Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "@bin_debug_dest@_ASCII" -# PROP BASE Intermediate_Dir "Debug_ASCII/@project_name@" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "@bin_debug_dest@_ASCII" -# PROP Intermediate_Dir "Debug_ASCII/@project_name@" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" @extra_cppflags@ /FD /c -# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" @extra_cppflags@ /FD /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib @debug_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no -# ADD LINK32 libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib @debug_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"libcmtd" /fixed:no /libpath:"@lib_debug_dest@_ASCII" -@POST_BUILD@ - -!ELSEIF "$(CFG)" == "@project_name@ - Win32 ASCII Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "@bin_rel_dest@_ASCII" -# PROP BASE Intermediate_Dir "Release_ASCII/@project_name@" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "@bin_rel_dest@_ASCII" -# PROP Intermediate_Dir "Release_ASCII/@project_name@" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" @extra_cppflags@ /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" @extra_cppflags@ /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib @release_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt" -# ADD LINK32 libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib @release_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libcmt" /libpath:"@lib_rel_dest@_ASCII" -@POST_BUILD@ - -!ELSEIF "$(CFG)" == "@project_name@ - Win64 Debug AMD64" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "@bin_debug_dest@_AMD64" -# PROP BASE Intermediate_Dir "Debug_AMD64/@project_name@" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "@bin_debug_dest@_AMD64" -# PROP Intermediate_Dir "Debug_AMD64/@project_name@" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MDd /W3 /EHsc /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" @extra_cppflags@ /Wp64 /FD /c -# ADD CPP /nologo /MDd /W3 /EHsc /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" @extra_cppflags@ /Wp64 /FD /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib @debug_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /debug /machine:AMD64 /nodefaultlib:"libcmtd" /fixed:no -# ADD LINK32 libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib @debug_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /debug /machine:AMD64 /nodefaultlib:"libcmtd" /fixed:no /libpath:"@lib_debug_dest@_AMD64" -@POST_BUILD@ - -!ELSEIF "$(CFG)" == "@project_name@ - Win64 Release AMD64" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "@bin_rel_dest@_AMD64" -# PROP BASE Intermediate_Dir "Release_AMD64/@project_name@" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "@bin_rel_dest@_AMD64" -# PROP Intermediate_Dir "Release_AMD64/@project_name@" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MD /W3 /EHsc /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" @extra_cppflags@ /Wp64 /FD /c -# ADD CPP /nologo /MD /W3 /EHsc /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" @extra_cppflags@ /Wp64 /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib @release_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /machine:AMD64 /nodefaultlib:"libcmt" -# ADD LINK32 libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib @release_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /machine:AMD64 /nodefaultlib:"libcmt" /libpath:"@lib_rel_dest@_AMD64" -@POST_BUILD@ - -!ELSEIF "$(CFG)" == "@project_name@ - Win64 Debug IA64" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "@bin_debug_dest@_IA64" -# PROP BASE Intermediate_Dir "Debug_IA64/@project_name@" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "@bin_debug_dest@_IA64" -# PROP Intermediate_Dir "Debug_IA64/@project_name@" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MDd /W3 /EHsc /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" @extra_cppflags@ /Wp64 /FD /c -# ADD CPP /nologo /MDd /W3 /EHsc /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" @extra_cppflags@ /Wp64 /FD /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib @debug_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /debug /machine:IA64 /nodefaultlib:"libcmtd" /fixed:no -# ADD LINK32 libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib @debug_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /debug /machine:IA64 /nodefaultlib:"libcmtd" /fixed:no /libpath:"@lib_debug_dest@_IA64" -@POST_BUILD@ - -!ELSEIF "$(CFG)" == "@project_name@ - Win64 Release IA64" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "@bin_rel_dest@_IA64" -# PROP BASE Intermediate_Dir "Release_IA64/@project_name@" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "@bin_rel_dest@_IA64" -# PROP Intermediate_Dir "Release_IA64/@project_name@" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MD /W3 /EHsc /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" @extra_cppflags@ /Wp64 /FD /c -# ADD CPP /nologo /MD /W3 /EHsc /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" @extra_cppflags@ /Wp64 /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib @release_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /machine:IA64 /nodefaultlib:"libcmt" -# ADD LINK32 libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib @release_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:console /machine:IA64 /nodefaultlib:"libcmt" /libpath:"@lib_rel_dest@_IA64" -@POST_BUILD@ - -!ENDIF - -# Begin Target - -# Name "@project_name@ - Win32 Release" -# Name "@project_name@ - Win32 Debug" -# Name "@project_name@ - Win32 ASCII Debug" -# Name "@project_name@ - Win32 ASCII Release" -# Name "@project_name@ - Win64 Debug AMD64" -# Name "@project_name@ - Win64 Release AMD64" -# Name "@project_name@ - Win64 Debug IA64" -# Name "@project_name@ - Win64 Release IA64" -@SOURCE_FILES@ -# Begin Source File - -SOURCE=..\clib\getopt.c -# End Source File -# End Target -# End Project diff --git a/storage/bdb/build_win32/db_java_xaj.mak b/storage/bdb/build_win32/db_java_xaj.mak deleted file mode 100644 index c2dbc920d17..00000000000 --- a/storage/bdb/build_win32/db_java_xaj.mak +++ /dev/null @@ -1,21 +0,0 @@ -JAVA_XADIR=../java/src/com/sleepycat/db/xa
-
-JAVA_XASRCS=\
- $(JAVA_XADIR)/DbXAResource.java \
- $(JAVA_XADIR)/DbXid.java
-
-Release/dbxa.jar : $(JAVA_XASRCS)
- @echo compiling Berkeley DB XA classes
- @javac -g -d ./Release/classes -classpath "$(CLASSPATH);./Release/classes" $(JAVA_XASRCS)
- @echo creating jar file
- @cd .\Release\classes
- @jar cf ../dbxa.jar com\sleepycat\db\xa\*.class
- @echo Java XA build finished
-
-Debug/dbxa.jar : $(JAVA_XASRCS)
- @echo compiling Berkeley DB XA classes
- @javac -g -d ./Debug/classes -classpath "$(CLASSPATH);./Debug/classes" $(JAVA_XASRCS)
- @echo creating jar file
- @cd .\Debug\classes
- @jar cf ../dbxa.jar com\sleepycat\db\xa\*.class
- @echo Java XA build finished
diff --git a/storage/bdb/build_win32/db_test.src b/storage/bdb/build_win32/db_test.src deleted file mode 100644 index 38e7fcd9b40..00000000000 --- a/storage/bdb/build_win32/db_test.src +++ /dev/null @@ -1,97 +0,0 @@ -# Microsoft Developer Studio Project File - Name="@project_name@" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=@project_name@ - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "@project_name@.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "@project_name@.mak" CFG="@project_name@ - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "@project_name@ - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "@project_name@ - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "@project_name@ - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 Release/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib /nologo /subsystem:console /machine:I386
-# Begin Special Build Tool
-SOURCE="$(InputPath)"
-PostBuild_Desc=Copy built executable files.
-PostBuild_Cmds=copy Release\*.exe .
-# End Special Build Tool
-
-!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 Debug/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /out:"Debug/dbkill.exe" /fixed:no
-# Begin Special Build Tool
-SOURCE="$(InputPath)"
-PostBuild_Desc=Copy built executable files.
-PostBuild_Cmds=copy Debug\*.exe .
-# End Special Build Tool
-
-!ENDIF
-
-# Begin Target
-
-# Name "@project_name@ - Win32 Release"
-# Name "@project_name@ - Win32 Debug"
-@SOURCE_FILES@
-# End Target
-# End Project
diff --git a/storage/bdb/build_win32/dbkill.cpp b/storage/bdb/build_win32/dbkill.cpp deleted file mode 100644 index 7a7082188f6..00000000000 --- a/storage/bdb/build_win32/dbkill.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: dbkill.cpp,v 12.1 2005/06/16 20:20:43 bostic Exp $ - */ -/* - * Kill - - * Simulate Unix kill on Windows/NT and Windows/9X. - * This good enough to support the Berkeley DB test suite, - * but may be missing some favorite features. - * - * Would have used MKS kill, but it didn't seem to work well - * on Win/9X. Cygnus kill works within the Gnu/Cygnus environment - * (where processes are given small pids, with presumably a translation - * table between small pids and actual process handles), but our test - * environment, via Tcl, does not use the Cygnus environment. - * - * Compile this and install it as c:/tools/kill.exe (or as indicated - * by build_win32/include.tcl ). - */ - -#include <windows.h> -#include <stdio.h> -#include <stdlib.h> -#include <limits.h> - -/* - * Like atol, with specified base. Would use stdlib, but - * strtol("0xFFFF1234", NULL, 16) returns 0x7FFFFFFF and - * strtol("4294712487", NULL, 16) returns 0x7FFFFFFF w/ VC++ - */ -long -myatol(char *s, int base) -{ - long result = 0; - char ch; - int sign = 1; /* + */ - if (base == 0) - base = 10; - if (base != 10 && base != 16) - return LONG_MAX; - while ((ch = *s++) != '\0') { - if (ch == '-') { - sign = -sign; - } - else if (ch >= '0' && ch <= '9') { - result = result * base + (ch - '0'); - } - else if (ch == 'x' || ch == 'X') { - /* Allow leading 0x..., and switch to base 16 */ - base = 16; - } - else if (base == 16 && ch >= 'a' && ch <= 'f') { - result = result * base + (ch - 'a' + 10); - } - else if (base == 16 && ch >= 'A' && ch <= 'F') { - result = result * base + (ch - 'A' + 10); - } - else { - if (sign > 1) - return LONG_MAX; - else - return LONG_MIN; - } - } - return sign * result; -} - -void -usage_exit() -{ - fprintf(stderr, "Usage: kill [ -sig ] pid\n"); - fprintf(stderr, " for win32, sig must be or 0, 15 (TERM)\n"); - exit(EXIT_FAILURE); -} - -int -main(int argc, char **argv) -{ - HANDLE hProcess ; - DWORD accessflag; - long pid; - int sig = 15; - - if (argc > 2) { - if (argv[1][0] != '-') - usage_exit(); - - if (strcmp(argv[1], "-TERM") == 0) - sig = 15; - else { - /* currently sig is more or less ignored, - * we only care if it is zero or not - */ - sig = atoi(&argv[1][1]); - if (sig < 0) - usage_exit(); - } - argc--; - argv++; - } - if (argc < 2) - usage_exit(); - - pid = myatol(argv[1], 10); - /*printf("pid = %ld (0x%lx) (command line %s)\n", pid, pid, argv[1]);*/ - if (pid == LONG_MAX || pid == LONG_MIN) - usage_exit(); - - if (sig == 0) - accessflag = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ; - else - accessflag = STANDARD_RIGHTS_REQUIRED | PROCESS_TERMINATE; - hProcess = OpenProcess(accessflag, FALSE, pid); - if (hProcess == NULL) { - fprintf(stderr, "dbkill: %s: no such process\n", argv[1]); - exit(EXIT_FAILURE); - } - if (sig == 0) - exit(EXIT_SUCCESS); - if (!TerminateProcess(hProcess, 99)) { - DWORD err = GetLastError(); - fprintf(stderr, - "dbkill: cannot kill process: error %d (0x%lx)\n", err, err); - exit(EXIT_FAILURE); - } - return EXIT_SUCCESS; -} diff --git a/storage/bdb/build_win32/dllmain.c b/storage/bdb/build_win32/dllmain.c deleted file mode 100644 index 70c2e849d66..00000000000 --- a/storage/bdb/build_win32/dllmain.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * -------------------------------------------------------------------------- - * Copyright (C) 1997 Netscape Communications Corporation - * -------------------------------------------------------------------------- - * - * dllmain.c - * - * $Id: dllmain.c,v 1.3 2000/10/26 21:58:48 bostic Exp $ - */ - -#define WIN32_LEAN_AND_MEAN -#include <windows.h> - -static int ProcessesAttached = 0; -static HINSTANCE Instance; /* Global library instance handle. */ - -/* - * The following declaration is for the VC++ DLL entry point. - */ - -BOOL APIENTRY DllMain (HINSTANCE hInst, - DWORD reason, LPVOID reserved); - -/* - *---------------------------------------------------------------------- - * - * DllEntryPoint -- - * - * This wrapper function is used by Borland to invoke the - * initialization code for Tcl. It simply calls the DllMain - * routine. - * - * Results: - * See DllMain. - * - * Side effects: - * See DllMain. - * - *---------------------------------------------------------------------- - */ - -BOOL APIENTRY -DllEntryPoint(hInst, reason, reserved) - HINSTANCE hInst; /* Library instance handle. */ - DWORD reason; /* Reason this function is being called. */ - LPVOID reserved; /* Not used. */ -{ - return DllMain(hInst, reason, reserved); -} - -/* - *---------------------------------------------------------------------- - * - * DllMain -- - * - * This routine is called by the VC++ C run time library init - * code, or the DllEntryPoint routine. It is responsible for - * initializing various dynamically loaded libraries. - * - * Results: - * TRUE on sucess, FALSE on failure. - * - * Side effects: - * Establishes 32-to-16 bit thunk and initializes sockets library. - * - *---------------------------------------------------------------------- - */ -BOOL APIENTRY -DllMain(hInst, reason, reserved) - HINSTANCE hInst; /* Library instance handle. */ - DWORD reason; /* Reason this function is being called. */ - LPVOID reserved; /* Not used. */ -{ - switch (reason) { - case DLL_PROCESS_ATTACH: - - /* - * Registration of UT need to be done only once for first - * attaching process. At that time set the tclWin32s flag - * to indicate if the DLL is executing under Win32s or not. - */ - - if (ProcessesAttached++) { - return FALSE; /* Not the first initialization. */ - } - - Instance = hInst; - return TRUE; - - case DLL_PROCESS_DETACH: - - ProcessesAttached--; - break; - } - - return TRUE; -} diff --git a/storage/bdb/build_win32/dynamic_dsp.src b/storage/bdb/build_win32/dynamic_dsp.src deleted file mode 100644 index 641ef221369..00000000000 --- a/storage/bdb/build_win32/dynamic_dsp.src +++ /dev/null @@ -1,281 +0,0 @@ -# Microsoft Developer Studio Project File - Name="@project_name@" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=@project_name@ - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "@project_name@.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "@project_name@.mak" CFG="@project_name@ - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "@project_name@ - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "@project_name@ - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "@project_name@ - Win32 ASCII Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "@project_name@ - Win32 ASCII Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "@project_name@ - Win64 Debug AMD64" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "@project_name@ - Win64 Release AMD64" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "@project_name@ - Win64 Debug IA64" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "@project_name@ - Win64 Release IA64" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "@project_name@ - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "@lib_rel_dest@" -# PROP BASE Intermediate_Dir "Release/@project_name@" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "@lib_rel_dest@" -# PROP Intermediate_Dir "Release/@project_name@" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /Ob2 /I "." /I ".." /D "UNICODE" /D "_UNICODE" /D "DB_CREATE_DLL" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" @extra_cppflags@ /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 @release_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /dll /machine:I386 -# ADD LINK32 @release_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x13000000" /subsystem:windows /dll /machine:I386 /out:"@bin_rel_dest@/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.dll" /libpath:"$(OUTDIR)" -@POST_BUILD@ - -!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "@lib_debug_dest@" -# PROP BASE Intermediate_Dir "Debug/@project_name@" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "@lib_debug_dest@" -# PROP Intermediate_Dir "Debug/@project_name@" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c -# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "UNICODE" /D "_UNICODE" /D "DB_CREATE_DLL" /D "DIAGNOSTIC" /D "CONFIG_TEST" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" @extra_cppflags@ /FD /c -# SUBTRACT CPP /Fr -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 @debug_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 @debug_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x13000000" /subsystem:windows /dll /export:__db_assert /pdb:none /debug /machine:I386 /out:"@bin_debug_dest@/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.dll" /fixed:no /libpath:"$(OUTDIR)" -@POST_BUILD@ - -!ELSEIF "$(CFG)" == "@project_name@ - Win32 ASCII Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "@lib_debug_dest@_ASCII" -# PROP BASE Intermediate_Dir "Debug_ASCII/@project_name@" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "@lib_debug_dest@_ASCII" -# PROP Intermediate_Dir "Debug_ASCII/@project_name@" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "DB_CREATE_DLL" /D "DIAGNOSTIC" /D "CONFIG_TEST" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" @extra_cppflags@ /FD /c -# SUBTRACT BASE CPP /Fr -# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "DB_CREATE_DLL" /D "DIAGNOSTIC" /D "CONFIG_TEST" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" @extra_cppflags@ /FD /c -# SUBTRACT CPP /Fr -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 @debug_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x13000000" /subsystem:windows /dll /pdb:none /debug /machine:I386 /out:"@bin_debug_dest@_ASCII/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.dll" /fixed:no -# ADD LINK32 @debug_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x13000000" /subsystem:windows /dll /export:__db_assert /pdb:none /debug /machine:I386 /out:"@bin_debug_dest@_ASCII/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.dll" /fixed:no /libpath:"$(OUTDIR)" -@POST_BUILD@ - -!ELSEIF "$(CFG)" == "@project_name@ - Win32 ASCII Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "@lib_rel_dest@_ASCII" -# PROP BASE Intermediate_Dir "Release_ASCII/@project_name@" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "@lib_rel_dest@_ASCII" -# PROP Intermediate_Dir "Release_ASCII/@project_name@" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MD /W3 /GX /O2 /Ob2 /I "." /I ".." /D "DB_CREATE_DLL" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" @extra_cppflags@ /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /Ob2 /I "." /I ".." /D "DB_CREATE_DLL" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" @extra_cppflags@ /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 @release_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x13000000" /subsystem:windows /dll /machine:I386 /out:"@bin_rel_dest@_ASCII/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.dll" -# ADD LINK32 @release_libs@ kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x13000000" /subsystem:windows /dll /machine:I386 /out:"@bin_rel_dest@_ASCII/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.dll" /libpath:"$(OUTDIR)" -@POST_BUILD@ - -!ELSEIF "$(CFG)" == "@project_name@ - Win64 Debug AMD64" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "@lib_debug_dest@_AMD64" -# PROP BASE Intermediate_Dir "Debug_AMD64/@project_name@" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "@lib_debug_dest@_AMD64" -# PROP Intermediate_Dir "Debug_AMD64/@project_name@" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MDd /W3 /EHsc /Z7 /Od /I "." /I ".." /D "UNICODE" /D "_UNICODE" /D "DB_CREATE_DLL" /D "DIAGNOSTIC" /D "CONFIG_TEST" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" @extra_cppflags@ /FD /c -# SUBTRACT BASE CPP /Fr -# ADD CPP /nologo /MDd /W3 /EHsc /Z7 /Od /I "." /I ".." /D "UNICODE" /D "_UNICODE" /D "DB_CREATE_DLL" /D "DIAGNOSTIC" /D "CONFIG_TEST" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" @extra_cppflags@ /FD /Wp64 /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 @debug_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x13000000" /subsystem:windows /dll /debug /machine:AMD64 /out:"@bin_debug_dest@_AMD64/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.dll" /fixed:no -# ADD LINK32 @debug_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x13000000" /subsystem:windows /dll /export:__db_assert /debug /machine:AMD64 /out:"@bin_debug_dest@_AMD64/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.dll" /fixed:no /libpath:"$(OUTDIR)" -@POST_BUILD@ - -!ELSEIF "$(CFG)" == "@project_name@ - Win64 Release AMD64" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "@lib_rel_dest@_AMD64" -# PROP BASE Intermediate_Dir "Release_AMD64/@project_name@" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "@lib_rel_dest@_AMD64" -# PROP Intermediate_Dir "Release_AMD64/@project_name@" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MD /W3 /EHsc /O2 /Ob2 /I "." /I ".." /D "UNICODE" /D "_UNICODE" /D "DB_CREATE_DLL" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" @extra_cppflags@ /Wp64 /FD /c -# ADD CPP /nologo /MD /W3 /EHsc /O2 /Ob2 /I "." /I ".." /D "UNICODE" /D "_UNICODE" /D "DB_CREATE_DLL" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" @extra_cppflags@ /Wp64 /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 @release_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x13000000" /subsystem:windows /dll /machine:AMD64 /out:"@bin_rel_dest@_AMD64/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.dll" -# ADD LINK32 @release_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x13000000" /subsystem:windows /dll /machine:AMD64 /out:"@bin_rel_dest@_AMD64/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.dll" /libpath:"$(OUTDIR)" -@POST_BUILD@ - -!ELSEIF "$(CFG)" == "@project_name@ - Win64 Debug IA64" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "@lib_debug_dest@_IA64" -# PROP BASE Intermediate_Dir "Debug_IA64/@project_name@" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "@lib_debug_dest@_IA64" -# PROP Intermediate_Dir "Debug_IA64/@project_name@" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MDd /W3 /EHsc /Z7 /Od /I "." /I ".." /D "UNICODE" /D "_UNICODE" /D "DB_CREATE_DLL" /D "DIAGNOSTIC" /D "CONFIG_TEST" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" @extra_cppflags@ /Wp64 /FD /c -# SUBTRACT BASE CPP /Fr -# ADD CPP /nologo /MDd /W3 /EHsc /Z7 /Od /I "." /I ".." /D "UNICODE" /D "_UNICODE" /D "DB_CREATE_DLL" /D "DIAGNOSTIC" /D "CONFIG_TEST" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" @extra_cppflags@ /Wp64 /FD /c -# SUBTRACT CPP /Fr -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 @debug_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x13000000" /subsystem:windows /dll /debug /machine:IA64 /out:"@bin_debug_dest@_IA64/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.dll" /fixed:no -# ADD LINK32 @debug_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x13000000" /subsystem:windows /dll /export:__db_assert /debug /machine:IA64 /out:"@bin_debug_dest@_IA64/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.dll" /fixed:no /libpath:"$(OUTDIR)" -@POST_BUILD@ - -!ELSEIF "$(CFG)" == "@project_name@ - Win64 Release IA64" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "@lib_rel_dest@_IA64" -# PROP BASE Intermediate_Dir "Release_IA64/@project_name@" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "@lib_rel_dest@_IA64" -# PROP Intermediate_Dir "Release_IA64/@project_name@" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MD /W3 /EHsc /O2 /Ob2 /I "." /I ".." /D "UNICODE" /D "_UNICODE" /D "DB_CREATE_DLL" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" @extra_cppflags@ /Wp64 /FD /c -# ADD CPP /nologo /MD /W3 /EHsc /O2 /Ob2 /I "." /I ".." /D "UNICODE" /D "_UNICODE" /D "DB_CREATE_DLL" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" @extra_cppflags@ /Wp64 /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 @release_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x13000000" /subsystem:windows /dll /machine:IA64 /out:"@bin_rel_dest@_IA64/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.dll" -# ADD LINK32 @release_libs@ bufferoverflowU.lib kernel32.lib user32.lib advapi32.lib shell32.lib /nologo /base:"0x13000000" /subsystem:windows /dll /machine:IA64 /out:"@bin_rel_dest@_IA64/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.dll" /libpath:"$(OUTDIR)" -@POST_BUILD@ - -!ENDIF - -# Begin Target - -# Name "@project_name@ - Win32 Release" -# Name "@project_name@ - Win32 Debug" -# Name "@project_name@ - Win32 ASCII Debug" -# Name "@project_name@ - Win32 ASCII Release" -# Name "@project_name@ - Win64 Debug AMD64" -# Name "@project_name@ - Win64 Release AMD64" -# Name "@project_name@ - Win64 Debug IA64" -# Name "@project_name@ - Win64 Release IA64" -@SOURCE_FILES@ - -# End Target -# End Project diff --git a/storage/bdb/build_win32/java_dsp.src b/storage/bdb/build_win32/java_dsp.src deleted file mode 100644 index c06cb2b3544..00000000000 --- a/storage/bdb/build_win32/java_dsp.src +++ /dev/null @@ -1,129 +0,0 @@ -# Microsoft Developer Studio Project File - Name="@project_name@" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=@project_name@ - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "@project_name@.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "@project_name@.mak" CFG="@project_name@ - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "@project_name@ - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "@project_name@ - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "@project_name@ - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "DB_CREATE_DLL" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 -# ADD LINK32 Release/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib /nologo /base:"0x13000000" /subsystem:windows /dll /machine:I386 /out:"Release/libdb_java@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.dll" -# Begin Custom Build - Compiling java files using javac -ProjDir=. -InputPath=.\Release\libdb_java@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.dll -SOURCE="$(InputPath)" - -"force_compilation.txt" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - echo compiling Berkeley DB classes - mkdir "$(OUTDIR)\classes" - javac -O -d "$(OUTDIR)\classes" -classpath "$(OUTDIR)/classes" ..\java\src\com\sleepycat\db\*.java ..\java\src\com\sleepycat\db\internal\*.java ..\java\src\com\sleepycat\bind\*.java ..\java\src\com\sleepycat\bind\serial\*.java ..\java\src\com\sleepycat\bind\tuple\*.java ..\java\src\com\sleepycat\collections\*.java ..\java\src\com\sleepycat\compat\*.java ..\java\src\com\sleepycat\util\*.java - echo compiling examples - mkdir "$(OUTDIR)\classes.ex" - javac -O -d "$(OUTDIR)\classes.ex" -classpath "$(OUTDIR)\classes;$(OUTDIR)\classes.ex" ..\examples_java\src\com\sleepycat\examples\db\*.java ..\examples_java\src\com\sleepycat\examples\db\GettingStarted\*.java ..\examples_java\src\com\sleepycat\examples\collections\access\*.java ..\examples_java\src\com\sleepycat\examples\collections\hello\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\basic\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\entity\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\tuple\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\sentity\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\marshal\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\factory\*.java - echo creating jar files - jar cf "$(OUTDIR)\db.jar" -C "$(OUTDIR)\classes" . - jar cf "$(OUTDIR)\dbexamples.jar" -C "$(OUTDIR)\classes.ex" . - echo Java build finished - -# End Custom Build - -!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 2 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "DB_CREATE_DLL" /D "_WINDLL" /D "_AFXDLL" /YX"config.h" /FD /c -# SUBTRACT CPP /Fr -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 Debug/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib /nologo /base:"0x13000000" /subsystem:windows /dll /pdb:none /debug /machine:I386 /out:"Debug/libdb_java@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.dll" /fixed:no -# Begin Custom Build - Compiling java files using javac -ProjDir=. -InputPath=.\Debug\libdb_java@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.dll -SOURCE="$(InputPath)" - -"force_compilation.txt" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - echo compiling Berkeley DB classes - mkdir "$(OUTDIR)\classes" - javac -g -d "$(OUTDIR)\classes" -classpath "$(OUTDIR)/classes" ..\java\src\com\sleepycat\db\*.java ..\java\src\com\sleepycat\db\internal\*.java ..\java\src\com\sleepycat\bind\*.java ..\java\src\com\sleepycat\bind\serial\*.java ..\java\src\com\sleepycat\bind\tuple\*.java ..\java\src\com\sleepycat\collections\*.java ..\java\src\com\sleepycat\compat\*.java ..\java\src\com\sleepycat\util\*.java - echo compiling examples - mkdir "$(OUTDIR)\classes.ex" - javac -g -d "$(OUTDIR)\classes.ex" -classpath "$(OUTDIR)\classes;$(OUTDIR)\classes.ex" ..\examples_java\src\com\sleepycat\examples\db\*.java ..\examples_java\src\com\sleepycat\examples\db\GettingStarted\*.java ..\examples_java\src\com\sleepycat\examples\collections\access\*.java ..\examples_java\src\com\sleepycat\examples\collections\hello\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\basic\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\entity\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\tuple\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\sentity\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\marshal\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\factory\*.java - echo creating jar files - jar cf "$(OUTDIR)\db.jar" -C "$(OUTDIR)\classes" . - jar cf "$(OUTDIR)\dbexamples.jar" -C "$(OUTDIR)\classes.ex" . - echo Java build finished - -# End Custom Build - -!ENDIF - -# Begin Target - -# Name "@project_name@ - Win32 Release" -# Name "@project_name@ - Win32 Debug" -@SOURCE_FILES@ -# End Target -# End Project diff --git a/storage/bdb/build_win32/libdb_tcl.def b/storage/bdb/build_win32/libdb_tcl.def deleted file mode 100644 index 01a89e44dff..00000000000 --- a/storage/bdb/build_win32/libdb_tcl.def +++ /dev/null @@ -1,7 +0,0 @@ -; $Id: libdb_tcl.def,v 12.0 2004/11/17 03:48:15 bostic Exp $ - -DESCRIPTION 'Berkeley DB TCL interface Library' -EXPORTS - Db_tcl_Init - _NameToPtr - diff --git a/storage/bdb/build_win32/libdbrc.src b/storage/bdb/build_win32/libdbrc.src deleted file mode 100644 index ec5ba9b3c6c..00000000000 --- a/storage/bdb/build_win32/libdbrc.src +++ /dev/null @@ -1,33 +0,0 @@ -1 VERSIONINFO - FILEVERSION %MAJOR%,0,%MINOR%,%PATCH% - PRODUCTVERSION %MAJOR%,0,%MINOR%,%PATCH% - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x4L - FILETYPE 0x2L - FILESUBTYPE 0x0L - -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "CompanyName", "Sleepycat Software\0" - VALUE "FileDescription", "Berkeley DB %MAJOR%.%MINOR% DLL\0" - VALUE "FileVersion", "%MAJOR%.%MINOR%.%PATCH%\0" - VALUE "InternalName", "libdb%MAJOR%%MINOR%.dll\0" - VALUE "LegalCopyright", "Copyright © Sleepycat Software Inc. 1997-2005\0" - VALUE "OriginalFilename", "libdb%MAJOR%%MINOR%.dll\0" - VALUE "ProductName", "Sleepycat Software libdb\0" - VALUE "ProductVersion", "%MAJOR%.%MINOR%.%PATCH%\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END diff --git a/storage/bdb/build_win32/small_dsp.src b/storage/bdb/build_win32/small_dsp.src deleted file mode 100644 index a54160f6b2a..00000000000 --- a/storage/bdb/build_win32/small_dsp.src +++ /dev/null @@ -1,85 +0,0 @@ -# Microsoft Developer Studio Project File - Name="@project_name@" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Static Library" 0x0104 - -CFG=@project_name@ - Win32 Debug Static -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "@project_name@.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "@project_name@.mak" CFG="@project_name@ - Win32 Debug Static" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "@project_name@ - Win32 Release Static" (based on "Win32 (x86) Static Library") -!MESSAGE "@project_name@ - Win32 Debug Static" (based on "Win32 (x86) Static Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "@project_name@ - Win32 Release Static" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release_small" -# PROP BASE Intermediate_Dir "Release_small" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release_small" -# PROP Intermediate_Dir "Release_small" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "HAVE_SMALLBUILD" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX"config.h" /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "HAVE_SMALLBUILD" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX"config.h" /FD /c -# ADD BASE RSC /l 0xc09 -# ADD RSC /l 0xc09 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo /out:"Release_small/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@s.lib" -# ADD LIB32 /nologo /out:"Release_small/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@s.lib" - -!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug Static" - -# PROP BASE Use_MFC 1 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug_small" -# PROP BASE Intermediate_Dir "Debug_small" -# PROP BASE Target_Dir "" -# PROP Use_MFC 1 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug_small" -# PROP Intermediate_Dir "Debug_small" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "HAVE_SMALLBUILD" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX"config.h" /FD /c -# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "HAVE_SMALLBUILD" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX"config.h" /FD /c -# ADD BASE RSC /l 0xc09 -# ADD RSC /l 0xc09 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo /out:"Debug_small/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@sd.lib" -# ADD LIB32 /nologo /out:"Debug_small/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@sd.lib" - -!ENDIF - -# Begin Target - -# Name "@project_name@ - Win32 Release Static" -# Name "@project_name@ - Win32 Debug Static" -@SOURCE_FILES@ -# End Target -# End Project diff --git a/storage/bdb/build_win32/srcfile_dsp.src b/storage/bdb/build_win32/srcfile_dsp.src deleted file mode 100644 index 572350e6356..00000000000 --- a/storage/bdb/build_win32/srcfile_dsp.src +++ /dev/null @@ -1,4 +0,0 @@ -# Begin Source File - -SOURCE=@srcdir@\@srcfile@ -# End Source File diff --git a/storage/bdb/build_win32/static_dsp.src b/storage/bdb/build_win32/static_dsp.src deleted file mode 100644 index 84c3d298792..00000000000 --- a/storage/bdb/build_win32/static_dsp.src +++ /dev/null @@ -1,235 +0,0 @@ -# Microsoft Developer Studio Project File - Name="@project_name@" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Static Library" 0x0104 - -CFG=@project_name@ - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "@project_name@.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "@project_name@.mak" CFG="@project_name@ - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "@project_name@ - Win32 Release" (based on "Win32 (x86) Static Library") -!MESSAGE "@project_name@ - Win32 Debug" (based on "Win32 (x86) Static Library") -!MESSAGE "@project_name@ - Win32 ASCII Release" (based on "Win32 (x86) Static Library") -!MESSAGE "@project_name@ - Win32 ASCII Debug" (based on "Win32 (x86) Static Library") -!MESSAGE "@project_name@ - Win64 Debug AMD64" (based on "Win32 (x86) Static Library") -!MESSAGE "@project_name@ - Win64 Release AMD64" (based on "Win32 (x86) Static Library") -!MESSAGE "@project_name@ - Win64 Debug IA64" (based on "Win32 (x86) Static Library") -!MESSAGE "@project_name@ - Win64 Release IA64" (based on "Win32 (x86) Static Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "@project_name@ - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "@lib_rel_dest@" -# PROP BASE Intermediate_Dir "Release/@project_name@" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "@lib_rel_dest@" -# PROP Intermediate_Dir "Release/@project_name@" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" @extra_cppflags@ /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" @extra_cppflags@ /FD /c -# ADD BASE RSC /l 0xc09 -# ADD RSC /l 0xc09 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo /out:"@lib_rel_dest@/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@s.lib" -# ADD LIB32 /nologo /out:"@lib_rel_dest@/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@s.lib" - -!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "@lib_debug_dest@" -# PROP BASE Intermediate_Dir "Debug/@project_name@" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "@lib_debug_dest@" -# PROP Intermediate_Dir "Debug/@project_name@" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "DIAGNOSTIC" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" @extra_cppflags@ /FD /c -# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "DIAGNOSTIC" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" @extra_cppflags@ /FD /c -# ADD BASE RSC /l 0xc09 -# ADD RSC /l 0xc09 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo /out:"@lib_debug_dest@/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@sd.lib" -# ADD LIB32 /nologo /out:"@lib_debug_dest@/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@sd.lib" - -!ELSEIF "$(CFG)" == "@project_name@ - Win32 ASCII Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "@lib_rel_dest@_ASCII" -# PROP BASE Intermediate_Dir "Release_ASCII/@project_name@" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "@lib_rel_dest@_ASCII" -# PROP Intermediate_Dir "Release_ASCII/@project_name@" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" @extra_cppflags@ /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" @extra_cppflags@ /FD /c -# ADD BASE RSC /l 0xc09 -# ADD RSC /l 0xc09 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo /out:"@lib_rel_dest@_ASCII/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@s.lib" -# ADD LIB32 /nologo /out:"@lib_rel_dest@_ASCII/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@s.lib" - -!ELSEIF "$(CFG)" == "@project_name@ - Win32 ASCII Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "@lib_debug_dest@_ASCII" -# PROP BASE Intermediate_Dir "Debug_ASCII/@project_name@" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "@lib_debug_dest@_ASCII" -# PROP Intermediate_Dir "Debug_ASCII/@project_name@" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "DIAGNOSTIC" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" @extra_cppflags@ /FD /c -# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "DIAGNOSTIC" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" @extra_cppflags@ /FD /c -# ADD BASE RSC /l 0xc09 -# ADD RSC /l 0xc09 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo /out:"@lib_debug_dest@_ASCII/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@sd.lib" -# ADD LIB32 /nologo /out:"@lib_debug_dest@_ASCII/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@sd.lib" - -!ELSEIF "$(CFG)" == "@project_name@ - Win64 Debug AMD64" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "@lib_debug_dest@_AMD64" -# PROP BASE Intermediate_Dir "Debug/@project_name@" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "@lib_debug_dest@_AMD64" -# PROP Intermediate_Dir "Debug_AMD64/@project_name@" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MDd /W3 /EHsc /Z7 /Od /I "." /I ".." /D "DIAGNOSTIC" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" @extra_cppflags@ /Wp64 /FD /c -# ADD CPP /nologo /MDd /W3 /EHsc /Z7 /Od /I "." /I ".." /D "DIAGNOSTIC" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" @extra_cppflags@ /Wp64 /FD /Wp64 /c -# ADD BASE RSC /l 0xc09 -# ADD RSC /l 0xc09 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo /out:"@lib_debug_dest@_AMD64/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@sd.lib" -# ADD LIB32 /nologo /out:"@lib_debug_dest@_AMD64/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@sd.lib" - -!ELSEIF "$(CFG)" == "@project_name@ - Win64 Release AMD64" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "@lib_rel_dest@_AMD64" -# PROP BASE Intermediate_Dir "Release_AMD64/@project_name@" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "@lib_rel_dest@_AMD64" -# PROP Intermediate_Dir "Release_AMD64/@project_name@" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MD /W3 /EHsc /O2 /I "." /I ".." /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" @extra_cppflags@ /Wp64 /FD /c -# ADD CPP /nologo /MD /W3 /EHsc /O2 /I "." /I ".." /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" @extra_cppflags@ /Wp64 /FD /c -# ADD BASE RSC /l 0xc09 -# ADD RSC /l 0xc09 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo /out:"@lib_rel_dest@_AMD64/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@s.lib" -# ADD LIB32 /nologo /out:"@lib_rel_dest@_AMD64/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@s.lib" - -!ELSEIF "$(CFG)" == "@project_name@ - Win64 Debug IA64" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "@lib_debug_dest@_IA64" -# PROP BASE Intermediate_Dir "Debug_IA64/@project_name@" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "@lib_debug_dest@_IA64" -# PROP Intermediate_Dir "Debug_IA64/@project_name@" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MDd /W3 /EHsc /Z7 /Od /I "." /I ".." /D "DIAGNOSTIC" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" @extra_cppflags@ /Wp64 /FD /c -# ADD CPP /nologo /MDd /W3 /EHsc /Z7 /Od /I "." /I ".." /D "DIAGNOSTIC" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" @extra_cppflags@ /Wp64 /FD /c -# ADD BASE RSC /l 0xc09 -# ADD RSC /l 0xc09 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo /out:"@lib_debug_dest@_IA64/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@sd.lib" -# ADD LIB32 /nologo /out:"@lib_debug_dest@_IA64/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@sd.lib" - -!ELSEIF "$(CFG)" == "@project_name@ - Win64 Release IA64" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "@lib_rel_dest@_IA64" -# PROP BASE Intermediate_Dir "Release_IA64/@project_name@" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "@lib_rel_dest@_IA64" -# PROP Intermediate_Dir "Release_IA64/@project_name@" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MD /W3 /EHsc /O2 /I "." /I ".." /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" @extra_cppflags@ /Wp64 /FD /c -# ADD CPP /nologo /MD /W3 /EHsc /O2 /I "." /I ".." /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" @extra_cppflags@ /Wp64 /FD /c -# ADD BASE RSC /l 0xc09 -# ADD RSC /l 0xc09 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo /out:"@lib_rel_dest@_IA64/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@s.lib" -# ADD LIB32 /nologo /out:"@lib_rel_dest@_IA64/libdb@lib_suffix@@DB_VERSION_MAJOR@@DB_VERSION_MINOR@s.lib" - -!ENDIF - -# Begin Target - -# Name "@project_name@ - Win32 Release" -# Name "@project_name@ - Win32 Debug" -# Name "@project_name@ - Win32 ASCII Release" -# Name "@project_name@ - Win32 ASCII Debug" -# Name "@project_name@ - Win64 Debug AMD64" -# Name "@project_name@ - Win64 Release AMD64" -# Name "@project_name@ - Win64 Debug IA64" -# Name "@project_name@ - Win64 Release IA64" -@SOURCE_FILES@ -# End Target -# End Project diff --git a/storage/bdb/build_win32/tcl_dsp.src b/storage/bdb/build_win32/tcl_dsp.src deleted file mode 100644 index fc7b2177e00..00000000000 --- a/storage/bdb/build_win32/tcl_dsp.src +++ /dev/null @@ -1,93 +0,0 @@ -# Microsoft Developer Studio Project File - Name="@project_name@" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=@project_name@ - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "@project_name@.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "@project_name@.mak" CFG="@project_name@ - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "@project_name@ - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "@project_name@ - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "@project_name@ - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /Ob2 /I "." /I ".." /D "DB_TCL_SUPPORT" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "DB_CREATE_DLL" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 -# ADD LINK32 Release/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib tcl84.lib /nologo /base:"0x13000000" /subsystem:windows /dll /machine:I386 /out:"Release/libdb_tcl@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.dll" - -!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 2 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "DB_TCL_SUPPORT" /D "CONFIG_TEST" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "DB_CREATE_DLL" /D "_WINDLL" /D "_AFXDLL" /YX"config.h" /FD /c -# SUBTRACT CPP /Fr -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 Debug/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib tcl84g.lib /nologo /base:"0x13000000" /subsystem:windows /dll /pdb:none /debug /machine:I386 /out:"Debug/libdb_tcl@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.dll" /fixed:no - -!ENDIF - -# Begin Target - -# Name "@project_name@ - Win32 Release" -# Name "@project_name@ - Win32 Debug" -@SOURCE_FILES@ -# End Target -# End Project diff --git a/storage/bdb/build_win64/app_dsp.src b/storage/bdb/build_win64/app_dsp.src deleted file mode 100644 index 4218e010b8a..00000000000 --- a/storage/bdb/build_win64/app_dsp.src +++ /dev/null @@ -1,145 +0,0 @@ -# Microsoft Developer Studio Project File - Name="@project_name@" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=@project_name@ - Win32 Debug Static -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "@project_name@.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "@project_name@.mak" CFG="@project_name@ - Win32 Debug Static" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "@project_name@ - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "@project_name@ - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE "@project_name@ - Win32 Release Static" (based on "Win32 (x86) Console Application") -!MESSAGE "@project_name@ - Win32 Debug Static" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "@project_name@ - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /machine:IA64 -# ADD LINK32 Release/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib /nologo /subsystem:console /machine:IA64 /nodefaultlib:"libcmt" - -!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:IA64 /pdbtype:sept -# ADD LINK32 Debug/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib /nologo /subsystem:console /debug /machine:IA64 /nodefaultlib:"libcmtd" /fixed:no - -!ELSEIF "$(CFG)" == "@project_name@ - Win32 Release Static" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release_static" -# PROP Intermediate_Dir "Release_static" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 Release_static/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib /nologo /subsystem:console /machine:IA64 -# ADD LINK32 Release_static/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@s.lib /nologo /subsystem:console /machine:IA64 - -!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug Static" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug_static" -# PROP Intermediate_Dir "Debug_static" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 Debug_static/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:IA64 /fixed:no -# ADD LINK32 Debug_static/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@sd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:IA64 /fixed:no - -!ENDIF - -# Begin Target - -# Name "@project_name@ - Win32 Release" -# Name "@project_name@ - Win32 Debug" -# Name "@project_name@ - Win32 Release Static" -# Name "@project_name@ - Win32 Debug Static" -@SOURCE_FILES@ -# Begin Source File - -SOURCE=..\clib\getopt.c -# End Source File -# End Target -# End Project diff --git a/storage/bdb/build_win64/db_test.src b/storage/bdb/build_win64/db_test.src deleted file mode 100644 index 2628128bbcf..00000000000 --- a/storage/bdb/build_win64/db_test.src +++ /dev/null @@ -1,97 +0,0 @@ -# Microsoft Developer Studio Project File - Name="@project_name@" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=@project_name@ - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "@project_name@.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "@project_name@.mak" CFG="@project_name@ - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "@project_name@ - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "@project_name@ - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "@project_name@ - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /machine:IA64 -# ADD LINK32 Release/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib /nologo /subsystem:console /machine:IA64 -# Begin Special Build Tool -SOURCE="$(InputPath)" -PostBuild_Desc=Copy built executable files. -PostBuild_Cmds=copy Release\*.exe . -# End Special Build Tool - -!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:IA64 /pdbtype:sept -# ADD LINK32 Debug/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:IA64 /out:"Debug/dbkill.exe" /fixed:no -# Begin Special Build Tool -SOURCE="$(InputPath)" -PostBuild_Desc=Copy built executable files. -PostBuild_Cmds=copy Debug\*.exe . -# End Special Build Tool - -!ENDIF - -# Begin Target - -# Name "@project_name@ - Win32 Release" -# Name "@project_name@ - Win32 Debug" -@SOURCE_FILES@ -# End Target -# End Project diff --git a/storage/bdb/build_win64/dynamic_dsp.src b/storage/bdb/build_win64/dynamic_dsp.src deleted file mode 100644 index 176ca0fb5ae..00000000000 --- a/storage/bdb/build_win64/dynamic_dsp.src +++ /dev/null @@ -1,93 +0,0 @@ -# Microsoft Developer Studio Project File - Name="@project_name@" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=@project_name@ - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "@project_name@.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "@project_name@.mak" CFG="@project_name@ - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "@project_name@ - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "@project_name@ - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "@project_name@ - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /Ob2 /I "." /I ".." /D "DB_CREATE_DLL" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /machine:IA64 -# ADD LINK32 /nologo /base:"0x13000000" /subsystem:windows /dll /machine:IA64 /out:"Release/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.dll" - -!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 2 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "DB_CREATE_DLL" /D "CONFIG_TEST" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX"config.h" /FD /c -# SUBTRACT CPP /Fr -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /debug /machine:IA64 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /base:"0x13000000" /subsystem:windows /dll /debug /machine:IA64 /out:"Debug/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.dll" /fixed:no - -!ENDIF - -# Begin Target - -# Name "@project_name@ - Win32 Release" -# Name "@project_name@ - Win32 Debug" -@SOURCE_FILES@ -# End Target -# End Project diff --git a/storage/bdb/build_win64/ex_repquote.src b/storage/bdb/build_win64/ex_repquote.src deleted file mode 100644 index 02352f8216b..00000000000 --- a/storage/bdb/build_win64/ex_repquote.src +++ /dev/null @@ -1,145 +0,0 @@ -# Microsoft Developer Studio Project File - Name="@project_name@" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=@project_name@ - Win32 Debug Static -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "@project_name@.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "@project_name@.mak" CFG="@project_name@ - Win32 Debug Static" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "@project_name@ - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "@project_name@ - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE "@project_name@ - Win32 Release Static" (based on "Win32 (x86) Console Application") -!MESSAGE "@project_name@ - Win32 Debug Static" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "@project_name@ - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /machine:IA64 -# ADD LINK32 Release/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib ws2_32.lib /nologo /subsystem:console /machine:IA64 /nodefaultlib:"libcmt" - -!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:IA64 /pdbtype:sept -# ADD LINK32 Debug/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib ws2_32.lib /nologo /subsystem:console /debug /machine:IA64 /nodefaultlib:"libcmtd" /fixed:no - -!ELSEIF "$(CFG)" == "@project_name@ - Win32 Release Static" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release_static" -# PROP Intermediate_Dir "Release_static" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MD /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 Release_static/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib ws2_32.lib /nologo /subsystem:console /machine:IA64 -# ADD LINK32 Release_static/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@s.lib ws2_32.lib /nologo /subsystem:console /machine:IA64 - -!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug Static" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug_static" -# PROP Intermediate_Dir "Debug_static" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 Debug_static/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:IA64 /fixed:no -# ADD LINK32 Debug_static/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@sd.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:console /debug /machine:IA64 /fixed:no - -!ENDIF - -# Begin Target - -# Name "@project_name@ - Win32 Release" -# Name "@project_name@ - Win32 Debug" -# Name "@project_name@ - Win32 Release Static" -# Name "@project_name@ - Win32 Debug Static" -@SOURCE_FILES@ -# Begin Source File - -SOURCE=..\clib\getopt.c -# End Source File -# End Target -# End Project diff --git a/storage/bdb/build_win64/java_dsp.src b/storage/bdb/build_win64/java_dsp.src deleted file mode 100644 index 954dad7d80c..00000000000 --- a/storage/bdb/build_win64/java_dsp.src +++ /dev/null @@ -1,129 +0,0 @@ -# Microsoft Developer Studio Project File - Name="@project_name@" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=@project_name@ - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "@project_name@.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "@project_name@.mak" CFG="@project_name@ - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "@project_name@ - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "@project_name@ - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "@project_name@ - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /Ob2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "DB_CREATE_DLL" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /machine:IA64 -# ADD LINK32 Release/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib /nologo /base:"0x13000000" /subsystem:windows /dll /machine:IA64 /out:"Release/libdb_java@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.dll" -# Begin Custom Build - Compiling java files using javac -ProjDir=. -InputPath=.\Release\libdb_java@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.dll -SOURCE="$(InputPath)" - -"force_compilation.txt" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - echo compiling Berkeley DB classes - mkdir "$(OUTDIR)\classes" - javac -O -d "$(OUTDIR)\classes" -classpath "$(OUTDIR)/classes" ..\java\src\com\sleepycat\db\*.java ..\java\src\com\sleepycat\db\internal\*.java ..\java\src\com\sleepycat\bind\*.java ..\java\src\com\sleepycat\bind\serial\*.java ..\java\src\com\sleepycat\bind\tuple\*.java ..\java\src\com\sleepycat\collections\*.java ..\java\src\com\sleepycat\compat\*.java ..\java\src\com\sleepycat\util\*.java - echo compiling examples - mkdir "$(OUTDIR)\classes.ex" - javac -O -d "$(OUTDIR)\classes.ex" -classpath "$(OUTDIR)\classes;$(OUTDIR)\classes.ex" ..\examples_java\src\com\sleepycat\examples\db\*.java ..\examples_java\src\com\sleepycat\examples\db\GettingStarted\*.java ..\examples_java\src\com\sleepycat\examples\collections\access\*.java ..\examples_java\src\com\sleepycat\examples\collections\hello\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\basic\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\entity\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\tuple\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\sentity\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\marshal\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\factory\*.java - echo creating jar files - jar cf "$(OUTDIR)\db.jar" -C "$(OUTDIR)\classes" . - jar cf "$(OUTDIR)\dbexamples.jar" -C "$(OUTDIR)\classes.ex" . - echo Java build finished - -# End Custom Build - -!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 2 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "DB_CREATE_DLL" /D "_WINDLL" /D "_AFXDLL" /YX"config.h" /FD /c -# SUBTRACT CPP /Fr -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /debug /machine:IA64 /pdbtype:sept -# ADD LINK32 Debug/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib /nologo /base:"0x13000000" /subsystem:windows /dll /debug /machine:IA64 /out:"Debug/libdb_java@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.dll" /fixed:no -# Begin Custom Build - Compiling java files using javac -ProjDir=. -InputPath=.\Debug\libdb_java@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.dll -SOURCE="$(InputPath)" - -"force_compilation.txt" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - echo compiling Berkeley DB classes - mkdir "$(OUTDIR)\classes" - javac -g -d "$(OUTDIR)\classes" -classpath "$(OUTDIR)/classes" ..\java\src\com\sleepycat\db\*.java ..\java\src\com\sleepycat\db\internal\*.java ..\java\src\com\sleepycat\bind\*.java ..\java\src\com\sleepycat\bind\serial\*.java ..\java\src\com\sleepycat\bind\tuple\*.java ..\java\src\com\sleepycat\collections\*.java ..\java\src\com\sleepycat\compat\*.java ..\java\src\com\sleepycat\util\*.java - echo compiling examples - mkdir "$(OUTDIR)\classes.ex" - javac -g -d "$(OUTDIR)\classes.ex" -classpath "$(OUTDIR)\classes;$(OUTDIR)\classes.ex" ..\examples_java\src\com\sleepycat\examples\db\*.java ..\examples_java\src\com\sleepycat\examples\db\GettingStarted\*.java ..\examples_java\src\com\sleepycat\examples\collections\access\*.java ..\examples_java\src\com\sleepycat\examples\collections\hello\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\basic\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\entity\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\tuple\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\sentity\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\marshal\*.java ..\examples_java\src\com\sleepycat\examples\collections\ship\factory\*.java - echo creating jar files - jar cf "$(OUTDIR)\db.jar" -C "$(OUTDIR)\classes" . - jar cf "$(OUTDIR)\dbexamples.jar" -C "$(OUTDIR)\classes.ex" . - echo Java build finished - -# End Custom Build - -!ENDIF - -# Begin Target - -# Name "@project_name@ - Win32 Release" -# Name "@project_name@ - Win32 Debug" -@SOURCE_FILES@ -# End Target -# End Project diff --git a/storage/bdb/build_win64/libdbrc.src b/storage/bdb/build_win64/libdbrc.src deleted file mode 100644 index 4c644ea9f4f..00000000000 --- a/storage/bdb/build_win64/libdbrc.src +++ /dev/null @@ -1,33 +0,0 @@ -1 VERSIONINFO - FILEVERSION %MAJOR%,0,%MINOR%,%PATCH% - PRODUCTVERSION %MAJOR%,0,%MINOR%,%PATCH% - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x4L - FILETYPE 0x2L - FILESUBTYPE 0x0L - -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "CompanyName", "Sleepycat Software\0" - VALUE "FileDescription", "Berkeley DB 3.0 DLL\0" - VALUE "FileVersion", "%MAJOR%.%MINOR%.%PATCH%\0" - VALUE "InternalName", "libdb.dll\0" - VALUE "LegalCopyright", "Copyright © Sleepycat Software Inc. 1997-2004\0" - VALUE "OriginalFilename", "libdb.dll\0" - VALUE "ProductName", "Sleepycat Software libdb\0" - VALUE "ProductVersion", "%MAJOR%.%MINOR%.%PATCH%\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END diff --git a/storage/bdb/build_win64/small_dsp.src b/storage/bdb/build_win64/small_dsp.src deleted file mode 100644 index a54160f6b2a..00000000000 --- a/storage/bdb/build_win64/small_dsp.src +++ /dev/null @@ -1,85 +0,0 @@ -# Microsoft Developer Studio Project File - Name="@project_name@" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Static Library" 0x0104 - -CFG=@project_name@ - Win32 Debug Static -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "@project_name@.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "@project_name@.mak" CFG="@project_name@ - Win32 Debug Static" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "@project_name@ - Win32 Release Static" (based on "Win32 (x86) Static Library") -!MESSAGE "@project_name@ - Win32 Debug Static" (based on "Win32 (x86) Static Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "@project_name@ - Win32 Release Static" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release_small" -# PROP BASE Intermediate_Dir "Release_small" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release_small" -# PROP Intermediate_Dir "Release_small" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "HAVE_SMALLBUILD" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX"config.h" /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "HAVE_SMALLBUILD" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX"config.h" /FD /c -# ADD BASE RSC /l 0xc09 -# ADD RSC /l 0xc09 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo /out:"Release_small/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@s.lib" -# ADD LIB32 /nologo /out:"Release_small/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@s.lib" - -!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug Static" - -# PROP BASE Use_MFC 1 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug_small" -# PROP BASE Intermediate_Dir "Debug_small" -# PROP BASE Target_Dir "" -# PROP Use_MFC 1 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug_small" -# PROP Intermediate_Dir "Debug_small" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "HAVE_SMALLBUILD" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX"config.h" /FD /c -# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "HAVE_SMALLBUILD" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX"config.h" /FD /c -# ADD BASE RSC /l 0xc09 -# ADD RSC /l 0xc09 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo /out:"Debug_small/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@sd.lib" -# ADD LIB32 /nologo /out:"Debug_small/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@sd.lib" - -!ENDIF - -# Begin Target - -# Name "@project_name@ - Win32 Release Static" -# Name "@project_name@ - Win32 Debug Static" -@SOURCE_FILES@ -# End Target -# End Project diff --git a/storage/bdb/build_win64/srcfile_dsp.src b/storage/bdb/build_win64/srcfile_dsp.src deleted file mode 100644 index 572350e6356..00000000000 --- a/storage/bdb/build_win64/srcfile_dsp.src +++ /dev/null @@ -1,4 +0,0 @@ -# Begin Source File - -SOURCE=@srcdir@\@srcfile@ -# End Source File diff --git a/storage/bdb/build_win64/static_dsp.src b/storage/bdb/build_win64/static_dsp.src deleted file mode 100644 index 411e8df8d07..00000000000 --- a/storage/bdb/build_win64/static_dsp.src +++ /dev/null @@ -1,85 +0,0 @@ -# Microsoft Developer Studio Project File - Name="@project_name@" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Static Library" 0x0104 - -CFG=@project_name@ - Win32 Debug Static -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "@project_name@.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "@project_name@.mak" CFG="@project_name@ - Win32 Debug Static" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "@project_name@ - Win32 Release Static" (based on "Win32 (x86) Static Library") -!MESSAGE "@project_name@ - Win32 Debug Static" (based on "Win32 (x86) Static Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "@project_name@ - Win32 Release Static" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release_static" -# PROP BASE Intermediate_Dir "Release_static" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release_static" -# PROP Intermediate_Dir "Release_static" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX"config.h" /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "." /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX"config.h" /FD /c -# ADD BASE RSC /l 0xc09 -# ADD RSC /l 0xc09 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo /out:"Release/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@s.lib" -# ADD LIB32 /nologo /out:"Release_static/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@s.lib" - -!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug Static" - -# PROP BASE Use_MFC 1 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug_static" -# PROP BASE Intermediate_Dir "Debug_static" -# PROP BASE Target_Dir "" -# PROP Use_MFC 1 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug_static" -# PROP Intermediate_Dir "Debug_static" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "CONFIG_TEST" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX"config.h" /FD /c -# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "." /I ".." /D "CONFIG_TEST" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX"config.h" /FD /c -# ADD BASE RSC /l 0xc09 -# ADD RSC /l 0xc09 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo /out:"Debug/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@sd.lib" -# ADD LIB32 /nologo /out:"Debug_static/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@sd.lib" - -!ENDIF - -# Begin Target - -# Name "@project_name@ - Win32 Release Static" -# Name "@project_name@ - Win32 Debug Static" -@SOURCE_FILES@ -# End Target -# End Project diff --git a/storage/bdb/build_win64/tcl_dsp.src b/storage/bdb/build_win64/tcl_dsp.src deleted file mode 100644 index 57bb6f21303..00000000000 --- a/storage/bdb/build_win64/tcl_dsp.src +++ /dev/null @@ -1,93 +0,0 @@ -# Microsoft Developer Studio Project File - Name="@project_name@" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=@project_name@ - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "@project_name@.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "@project_name@.mak" CFG="@project_name@ - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "@project_name@ - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "@project_name@ - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "@project_name@ - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /Ob2 /I "." /I ".." /D "DB_TCL_SUPPORT" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "DB_CREATE_DLL" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /machine:IA64 -# ADD LINK32 Release/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib tcl84.lib /nologo /base:"0x13000000" /subsystem:windows /dll /machine:IA64 /out:"Release/libdb_tcl@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.dll" - -!ELSEIF "$(CFG)" == "@project_name@ - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 2 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /I "." /I ".." /D "DB_TCL_SUPPORT" /D "CONFIG_TEST" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "DB_CREATE_DLL" /D "_WINDLL" /D "_AFXDLL" /YX"config.h" /FD /c -# SUBTRACT CPP /Fr -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /debug /machine:IA64 /pdbtype:sept -# ADD LINK32 Debug/libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib tcl84g.lib /nologo /base:"0x13000000" /subsystem:windows /dll /debug /machine:IA64 /out:"Debug/libdb_tcl@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.dll" /fixed:no - -!ENDIF - -# Begin Target - -# Name "@project_name@ - Win32 Release" -# Name "@project_name@ - Win32 Debug" -@SOURCE_FILES@ -# End Target -# End Project diff --git a/storage/bdb/clib/getcwd.c b/storage/bdb/clib/getcwd.c deleted file mode 100644 index 367950640c9..00000000000 --- a/storage/bdb/clib/getcwd.c +++ /dev/null @@ -1,270 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1989, 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: getcwd.c,v 12.1 2005/06/16 20:20:48 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#include <sys/stat.h> - -#if HAVE_DIRENT_H -# include <dirent.h> -# define NAMLEN(dirent) strlen((dirent)->d_name) -#else -# define dirent direct -# define NAMLEN(dirent) (dirent)->d_namlen -# if HAVE_SYS_NDIR_H -# include <sys/ndir.h> -# endif -# if HAVE_SYS_DIR_H -# include <sys/dir.h> -# endif -# if HAVE_NDIR_H -# include <ndir.h> -# endif -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#endif - -#include "db_int.h" - -#define ISDOT(dp) \ - (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \ - (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) - -#ifndef dirfd -#define dirfd(dirp) ((dirp)->dd_fd) -#endif - -/* - * getcwd -- - * Get the current working directory. - * - * PUBLIC: #ifndef HAVE_GETCWD - * PUBLIC: char *getcwd __P((char *, size_t)); - * PUBLIC: #endif - */ -char * -getcwd(pt, size) - char *pt; - size_t size; -{ - register struct dirent *dp; - register DIR *dir; - register dev_t dev; - register ino_t ino; - register int first; - register char *bpt, *bup; - struct stat s; - dev_t root_dev; - ino_t root_ino; - size_t ptsize, upsize; - int ret, save_errno; - char *ept, *eup, *up; - - /* - * If no buffer specified by the user, allocate one as necessary. - * If a buffer is specified, the size has to be non-zero. The path - * is built from the end of the buffer backwards. - */ - if (pt) { - ptsize = 0; - if (!size) { - __os_set_errno(EINVAL); - return (NULL); - } - if (size == 1) { - __os_set_errno(ERANGE); - return (NULL); - } - ept = pt + size; - } else { - if ((ret = - __os_malloc(NULL, ptsize = 1024 - 4, &pt)) != 0) { - __os_set_errno(ret); - return (NULL); - } - ept = pt + ptsize; - } - bpt = ept - 1; - *bpt = '\0'; - - /* - * Allocate bytes (1024 - malloc space) for the string of "../"'s. - * Should always be enough (it's 340 levels). If it's not, allocate - * as necessary. Special case the first stat, it's ".", not "..". - */ - if ((ret = __os_malloc(NULL, upsize = 1024 - 4, &up)) != 0) - goto err; - eup = up + 1024; - bup = up; - up[0] = '.'; - up[1] = '\0'; - - /* Save root values, so know when to stop. */ - if (stat("/", &s)) - goto err; - root_dev = s.st_dev; - root_ino = s.st_ino; - - __os_set_errno(0); /* XXX readdir has no error return. */ - - for (first = 1;; first = 0) { - /* Stat the current level. */ - if (lstat(up, &s)) - goto err; - - /* Save current node values. */ - ino = s.st_ino; - dev = s.st_dev; - - /* Check for reaching root. */ - if (root_dev == dev && root_ino == ino) { - *--bpt = PATH_SEPARATOR[0]; - /* - * It's unclear that it's a requirement to copy the - * path to the beginning of the buffer, but it's always - * been that way and stuff would probably break. - */ - bcopy(bpt, pt, ept - bpt); - __os_free(NULL, up); - return (pt); - } - - /* - * Build pointer to the parent directory, allocating memory - * as necessary. Max length is 3 for "../", the largest - * possible component name, plus a trailing NULL. - */ - if (bup + 3 + MAXNAMLEN + 1 >= eup) { - if (__os_realloc(NULL, upsize *= 2, &up) != 0) - goto err; - bup = up; - eup = up + upsize; - } - *bup++ = '.'; - *bup++ = '.'; - *bup = '\0'; - - /* Open and stat parent directory. */ - if (!(dir = opendir(up)) || fstat(dirfd(dir), &s)) - goto err; - - /* Add trailing slash for next directory. */ - *bup++ = PATH_SEPARATOR[0]; - - /* - * If it's a mount point, have to stat each element because - * the inode number in the directory is for the entry in the - * parent directory, not the inode number of the mounted file. - */ - save_errno = 0; - if (s.st_dev == dev) { - for (;;) { - if (!(dp = readdir(dir))) - goto notfound; - if (dp->d_fileno == ino) - break; - } - } else - for (;;) { - if (!(dp = readdir(dir))) - goto notfound; - if (ISDOT(dp)) - continue; - bcopy(dp->d_name, bup, dp->d_namlen + 1); - - /* Save the first error for later. */ - if (lstat(up, &s)) { - if (save_errno == 0) - save_errno = __os_get_errno(); - __os_set_errno(0); - continue; - } - if (s.st_dev == dev && s.st_ino == ino) - break; - } - - /* - * Check for length of the current name, preceding slash, - * leading slash. - */ - if (bpt - pt < dp->d_namlen + (first ? 1 : 2)) { - size_t len, off; - - if (!ptsize) { - __os_set_errno(ERANGE); - goto err; - } - off = bpt - pt; - len = ept - bpt; - if (__os_realloc(NULL, ptsize *= 2, &pt) != 0) - goto err; - bpt = pt + off; - ept = pt + ptsize; - bcopy(bpt, ept - len, len); - bpt = ept - len; - } - if (!first) - *--bpt = PATH_SEPARATOR[0]; - bpt -= dp->d_namlen; - bcopy(dp->d_name, bpt, dp->d_namlen); - (void)closedir(dir); - - /* Truncate any file name. */ - *bup = '\0'; - } - -notfound: - /* - * If readdir set errno, use it, not any saved error; otherwise, - * didn't find the current directory in its parent directory, set - * errno to ENOENT. - */ - if (__os_get_errno_ret_zero() == 0) - __os_set_errno(save_errno == 0 ? ENOENT : save_errno); - /* FALLTHROUGH */ -err: - if (ptsize) - __os_free(NULL, pt); - __os_free(NULL, up); - return (NULL); -} diff --git a/storage/bdb/clib/getopt.c b/storage/bdb/clib/getopt.c deleted file mode 100644 index 54bfed16362..00000000000 --- a/storage/bdb/clib/getopt.c +++ /dev/null @@ -1,152 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1987, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: getopt.c,v 12.1 2005/06/16 20:20:48 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#endif - -#include "db_int.h" - -int __db_getopt_reset; /* global reset for VxWorks. */ - -int opterr = 1, /* if error message should be printed */ - optind = 1, /* index into parent argv vector */ - optopt, /* character checked for validity */ - optreset; /* reset getopt */ -char *optarg; /* argument associated with option */ - -#undef BADCH -#define BADCH (int)'?' -#undef BADARG -#define BADARG (int)':' -#undef EMSG -#define EMSG "" - -/* - * getopt -- - * Parse argc/argv argument vector. - * - * PUBLIC: #ifndef HAVE_GETOPT - * PUBLIC: int getopt __P((int, char * const *, const char *)); - * PUBLIC: #endif - */ -int -getopt(nargc, nargv, ostr) - int nargc; - char * const *nargv; - const char *ostr; -{ - static char *progname; - static char *place = EMSG; /* option letter processing */ - char *oli; /* option letter list index */ - - /* - * VxWorks needs to be able to repeatedly call getopt from multiple - * programs within its global name space. - */ - if (__db_getopt_reset) { - __db_getopt_reset = 0; - - opterr = optind = 1; - optopt = optreset = 0; - optarg = NULL; - progname = NULL; - place = EMSG; - } - if (!progname) { - if ((progname = __db_rpath(*nargv)) == NULL) - progname = *nargv; - else - ++progname; - } - - if (optreset || !*place) { /* update scanning pointer */ - optreset = 0; - if (optind >= nargc || *(place = nargv[optind]) != '-') { - place = EMSG; - return (EOF); - } - if (place[1] && *++place == '-') { /* found "--" */ - ++optind; - place = EMSG; - return (EOF); - } - } /* option letter okay? */ - if ((optopt = (int)*place++) == (int)':' || - !(oli = strchr(ostr, optopt))) { - /* - * if the user didn't specify '-' as an option, - * assume it means EOF. - */ - if (optopt == (int)'-') - return (EOF); - if (!*place) - ++optind; - if (opterr && *ostr != ':') - (void)fprintf(stderr, - "%s: illegal option -- %c\n", progname, optopt); - return (BADCH); - } - if (*++oli != ':') { /* don't need argument */ - optarg = NULL; - if (!*place) - ++optind; - } - else { /* need an argument */ - if (*place) /* no white space */ - optarg = place; - else if (nargc <= ++optind) { /* no arg */ - place = EMSG; - if (*ostr == ':') - return (BADARG); - if (opterr) - (void)fprintf(stderr, - "%s: option requires an argument -- %c\n", - progname, optopt); - return (BADCH); - } - else /* white space */ - optarg = nargv[optind]; - place = EMSG; - ++optind; - } - return (optopt); /* dump back option letter */ -} diff --git a/storage/bdb/clib/memcmp.c b/storage/bdb/clib/memcmp.c deleted file mode 100644 index e7400c1c40b..00000000000 --- a/storage/bdb/clib/memcmp.c +++ /dev/null @@ -1,65 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: memcmp.c,v 12.1 2005/06/16 20:20:48 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - -/* - * memcmp -- - * - * PUBLIC: #ifndef HAVE_MEMCMP - * PUBLIC: int memcmp __P((const void *, const void *, size_t)); - * PUBLIC: #endif - */ -int -memcmp(s1, s2, n) - char *s1, *s2; - size_t n; -{ - if (n != 0) { - unsigned char *p1 = (unsigned char *)s1, - *p2 = (unsigned char *)s2; - do { - if (*p1++ != *p2++) - return (*--p1 - *--p2); - } while (--n != 0); - } - return (0); -} diff --git a/storage/bdb/clib/memmove.c b/storage/bdb/clib/memmove.c deleted file mode 100644 index d2a505b1f35..00000000000 --- a/storage/bdb/clib/memmove.c +++ /dev/null @@ -1,153 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: memmove.c,v 12.1 2005/06/16 20:20:49 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - -/* - * sizeof(word) MUST BE A POWER OF TWO - * SO THAT wmask BELOW IS ALL ONES - */ -typedef int word; /* "word" used for optimal copy speed */ - -#undef wsize -#define wsize sizeof(word) -#undef wmask -#define wmask (wsize - 1) - -/* - * Copy a block of memory, handling overlap. - * This is the routine that actually implements - * (the portable versions of) bcopy, memcpy, and memmove. - */ -#ifdef MEMCOPY -/* - * PUBLIC: #ifndef HAVE_MEMCPY - * PUBLIC: void *memcpy __P((void *, const void *, size_t)); - * PUBLIC: #endif - */ -void * -memcpy(dst0, src0, length) -#else -#ifdef MEMMOVE -/* - * PUBLIC: #ifndef HAVE_MEMMOVE - * PUBLIC: void *memmove __P((void *, const void *, size_t)); - * PUBLIC: #endif - */ -void * -memmove(dst0, src0, length) -#else -void -bcopy(src0, dst0, length) -#endif -#endif - void *dst0; - const void *src0; - register size_t length; -{ - register char *dst = dst0; - register const char *src = src0; - register size_t t; - - if (length == 0 || dst == src) /* nothing to do */ - goto done; - - /* - * Macros: loop-t-times; and loop-t-times, t>0 - */ -#undef TLOOP -#define TLOOP(s) if (t) TLOOP1(s) -#undef TLOOP1 -#define TLOOP1(s) do { s; } while (--t) - - if ((unsigned long)dst < (unsigned long)src) { - /* - * Copy forward. - */ - t = (int)src; /* only need low bits */ - if ((t | (int)dst) & wmask) { - /* - * Try to align operands. This cannot be done - * unless the low bits match. - */ - if ((t ^ (int)dst) & wmask || length < wsize) - t = length; - else - t = wsize - (t & wmask); - length -= t; - TLOOP1(*dst++ = *src++); - } - /* - * Copy whole words, then mop up any trailing bytes. - */ - t = length / wsize; - TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize); - t = length & wmask; - TLOOP(*dst++ = *src++); - } else { - /* - * Copy backwards. Otherwise essentially the same. - * Alignment works as before, except that it takes - * (t&wmask) bytes to align, not wsize-(t&wmask). - */ - src += length; - dst += length; - t = (int)src; - if ((t | (int)dst) & wmask) { - if ((t ^ (int)dst) & wmask || length <= wsize) - t = length; - else - t &= wmask; - length -= t; - TLOOP1(*--dst = *--src); - } - t = length / wsize; - TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src); - t = length & wmask; - TLOOP(*--dst = *--src); - } -done: -#if defined(MEMCOPY) || defined(MEMMOVE) - return (dst0); -#else - return; -#endif -} diff --git a/storage/bdb/clib/raise.c b/storage/bdb/clib/raise.c deleted file mode 100644 index 043a2007162..00000000000 --- a/storage/bdb/clib/raise.c +++ /dev/null @@ -1,30 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: raise.c,v 12.2 2005/06/16 20:20:50 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <signal.h> -#include <unistd.h> -#endif - -/* - * raise -- - * Send a signal to the current process. - * - * PUBLIC: #ifndef HAVE_RAISE - * PUBLIC: int raise __P((int)); - * PUBLIC: #endif - */ -int -raise(s) - int s; -{ - return (kill(getpid(), s)); -} diff --git a/storage/bdb/clib/snprintf.c b/storage/bdb/clib/snprintf.c deleted file mode 100644 index 4fa4540b9d2..00000000000 --- a/storage/bdb/clib/snprintf.c +++ /dev/null @@ -1,159 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: snprintf.c,v 12.1 2005/06/16 20:20:50 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> /* Declare STDERR_FILENO. */ -#endif - -#include "db_int.h" - -#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) -static void sprintf_overflow __P((void)); -static int sprintf_retcharpnt __P((void)); -#endif - -/* - * snprintf -- - * Bounded version of sprintf. - * - * PUBLIC: #ifndef HAVE_SNPRINTF - * PUBLIC: int snprintf __P((char *, size_t, const char *, ...)); - * PUBLIC: #endif - */ -#ifndef HAVE_SNPRINTF -int -#ifdef STDC_HEADERS -snprintf(char *str, size_t n, const char *fmt, ...) -#else -snprintf(str, n, fmt, va_alist) - char *str; - size_t n; - const char *fmt; - va_dcl -#endif -{ - static int ret_charpnt = -1; - va_list ap; - size_t len; - - if (ret_charpnt == -1) - ret_charpnt = sprintf_retcharpnt(); - -#ifdef STDC_HEADERS - va_start(ap, fmt); -#else - va_start(ap); -#endif - len = (size_t)vsprintf(str, fmt, ap); - if (ret_charpnt) - len = strlen(str); - - va_end(ap); - - if (len >= n) { - sprintf_overflow(); - /* NOTREACHED */ - } - return ((int)len); -} -#endif - -/* - * vsnprintf -- - * Bounded version of vsprintf. - * - * PUBLIC: #ifndef HAVE_VSNPRINTF - * PUBLIC: int vsnprintf __P((char *, size_t, const char *, va_list)); - * PUBLIC: #endif - */ -#ifndef HAVE_VSNPRINTF -int -vsnprintf(str, n, fmt, ap) - char *str; - size_t n; - const char *fmt; - va_list ap; -{ - static int ret_charpnt = -1; - size_t len; - - if (ret_charpnt == -1) - ret_charpnt = sprintf_retcharpnt(); - - len = (size_t)vsprintf(str, fmt, ap); - if (ret_charpnt) - len = strlen(str); - - if (len >= n) { - sprintf_overflow(); - /* NOTREACHED */ - } - return ((int)len); -} -#endif - -#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) -static void -sprintf_overflow() -{ - /* - * !!! - * We're potentially manipulating strings handed us by the application, - * and on systems without a real snprintf() the sprintf() calls could - * have overflowed the buffer. We can't do anything about it now, but - * we don't want to return control to the application, we might have - * overwritten the stack with a Trojan horse. We're not trying to do - * anything recoverable here because systems without snprintf support - * are pretty rare anymore. - */ -#define OVERFLOW_ERROR "internal buffer overflow, process ended\n" -#ifndef STDERR_FILENO -#define STDERR_FILENO 2 -#endif - (void)write(STDERR_FILENO, OVERFLOW_ERROR, sizeof(OVERFLOW_ERROR) - 1); - - /* Be polite. */ - exit(1); - - /* But firm. */ - abort(); - - /* NOTREACHED */ -} - -static int -sprintf_retcharpnt() -{ - int ret_charpnt; - char buf[10]; - - /* - * Some old versions of sprintf return a pointer to the first argument - * instead of a character count. Assume the return value of snprintf, - * vsprintf, etc. will be the same as sprintf, and check the easy one. - * - * We do this test at run-time because it's not a test we can do in a - * cross-compilation environment. - */ - - ret_charpnt = - (int)sprintf(buf, "123") != 3 || - (int)sprintf(buf, "123456789") != 9 || - (int)sprintf(buf, "1234") != 4; - - return (ret_charpnt); -} -#endif diff --git a/storage/bdb/clib/strcasecmp.c b/storage/bdb/clib/strcasecmp.c deleted file mode 100644 index b83daa3ccab..00000000000 --- a/storage/bdb/clib/strcasecmp.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 1987, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: strcasecmp.c,v 12.0 2004/11/17 03:43:15 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <string.h> -#endif - -/* - * This array is designed for mapping upper and lower case letter - * together for a case independent comparison. The mappings are - * based upon ascii character sequences. - */ -static const unsigned char charmap[] = { - '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', - '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', - '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', - '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', - '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', - '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', - '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', - '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', - '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', - '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', - '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', - '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', - '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', - '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', - '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', - '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177', - '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207', - '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217', - '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227', - '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237', - '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247', - '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257', - '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267', - '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277', - '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307', - '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317', - '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327', - '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337', - '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347', - '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357', - '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367', - '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377' -}; - -/* - * strcasecmp -- - * Do strcmp(3) in a case-insensitive manner. - * - * PUBLIC: #ifndef HAVE_STRCASECMP - * PUBLIC: int strcasecmp __P((const char *, const char *)); - * PUBLIC: #endif - */ -int -strcasecmp(s1, s2) - const char *s1, *s2; -{ - register const unsigned char *cm = charmap, - *us1 = (const unsigned char *)s1, - *us2 = (const unsigned char *)s2; - - while (cm[*us1] == cm[*us2++]) - if (*us1++ == '\0') - return (0); - return (cm[*us1] - cm[*--us2]); -} - -/* - * strncasecmp -- - * Do strncmp(3) in a case-insensitive manner. - * - * PUBLIC: #ifndef HAVE_STRCASECMP - * PUBLIC: int strncasecmp __P((const char *, const char *, size_t)); - * PUBLIC: #endif - */ -int -strncasecmp(s1, s2, n) - const char *s1, *s2; - register size_t n; -{ - if (n != 0) { - register const unsigned char *cm = charmap, - *us1 = (const unsigned char *)s1, - *us2 = (const unsigned char *)s2; - - do { - if (cm[*us1] != cm[*us2++]) - return (cm[*us1] - cm[*--us2]); - if (*us1++ == '\0') - break; - } while (--n != 0); - } - return (0); -} diff --git a/storage/bdb/clib/strdup.c b/storage/bdb/clib/strdup.c deleted file mode 100644 index e679f5a6ccd..00000000000 --- a/storage/bdb/clib/strdup.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: strdup.c,v 12.0 2004/11/17 03:43:15 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stddef.h> -#include <stdlib.h> -#include <string.h> -#endif - -/* - * strdup -- - * - * PUBLIC: #ifndef HAVE_STRDUP - * PUBLIC: char *strdup __P((const char *)); - * PUBLIC: #endif - */ -char * -strdup(str) - const char *str; -{ - size_t len; - char *copy; - - len = strlen(str) + 1; - if (!(copy = malloc((u_int)len))) - return (NULL); - memcpy(copy, str, len); - return (copy); -} diff --git a/storage/bdb/clib/strerror.c b/storage/bdb/clib/strerror.c deleted file mode 100644 index db0d71ccc5f..00000000000 --- a/storage/bdb/clib/strerror.c +++ /dev/null @@ -1,75 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: strerror.c,v 12.1 2005/06/16 20:20:51 bostic Exp $ - */ - -#include "db_config.h" - -/* - * strerror -- - * Return the string associated with an errno. - * - * PUBLIC: #ifndef HAVE_STRERROR - * PUBLIC: char *strerror __P((int)); - * PUBLIC: #endif - */ -char * -strerror(num) - int num; -{ - extern int sys_nerr; - extern char *sys_errlist[]; -#undef UPREFIX -#define UPREFIX "Unknown error: " - static char ebuf[40] = UPREFIX; /* 64-bit number + slop */ - int errnum; - char *p, *t, tmp[40]; - - errnum = num; /* convert to unsigned */ - if (errnum < sys_nerr) - return(sys_errlist[errnum]); - - /* Do this by hand, so we don't include stdio(3). */ - t = tmp; - do { - *t++ = "0123456789"[errnum % 10]; - } while (errnum /= 10); - for (p = ebuf + sizeof(UPREFIX) - 1;;) { - *p++ = *--t; - if (t <= tmp) - break; - } - return(ebuf); -} diff --git a/storage/bdb/clib/strtol.c b/storage/bdb/clib/strtol.c deleted file mode 100644 index 88b17bd3e9f..00000000000 --- a/storage/bdb/clib/strtol.c +++ /dev/null @@ -1,144 +0,0 @@ -/*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: strtol.c,v 12.0 2004/11/17 03:43:15 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <limits.h> -#include <ctype.h> -#include <errno.h> -#include <stdlib.h> -#include <stdio.h> -#endif - -/* - * Convert a string to a long integer. - * - * Assumes that the upper and lower case - * alphabets and digits are each contiguous. - */ -long -strtol(nptr, endptr, base) - const char * nptr; - char ** endptr; - int base; -{ - const char *s; - unsigned long acc; - char c; - unsigned long cutoff; - int neg, any, cutlim; - - /* - * Skip white space and pick up leading +/- sign if any. - * If base is 0, allow 0x for hex and 0 for octal, else - * assume decimal; if base is already 16, allow 0x. - */ - s = nptr; - do { - c = *s++; - } while (isspace((unsigned char)c)); - if (c == '-') { - neg = 1; - c = *s++; - } else { - neg = 0; - if (c == '+') - c = *s++; - } - if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X')) { - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) - base = c == '0' ? 8 : 10; - acc = any = 0; - if (base < 2 || base > 36) - goto noconv; - - /* - * Compute the cutoff value between legal numbers and illegal - * numbers. That is the largest legal value, divided by the - * base. An input number that is greater than this value, if - * followed by a legal input character, is too big. One that - * is equal to this value may be valid or not; the limit - * between valid and invalid numbers is then based on the last - * digit. For instance, if the range for longs is - * [-2147483648..2147483647] and the input base is 10, - * cutoff will be set to 214748364 and cutlim to either - * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated - * a value > 214748364, or equal but the next digit is > 7 (or 8), - * the number is too big, and we will return a range error. - * - * Set 'any' if any `digits' consumed; make it negative to indicate - * overflow. - */ - cutoff = neg ? (unsigned long)-(LONG_MIN + LONG_MAX) + LONG_MAX - : LONG_MAX; - cutlim = cutoff % base; - cutoff /= base; - for ( ; ; c = *s++) { - if (c >= '0' && c <= '9') - c -= '0'; - else if (c >= 'A' && c <= 'Z') - c -= 'A' - 10; - else if (c >= 'a' && c <= 'z') - c -= 'a' - 10; - else - break; - if (c >= base) - break; - if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) - any = -1; - else { - any = 1; - acc *= base; - acc += c; - } - } - if (any < 0) { - acc = neg ? LONG_MIN : LONG_MAX; - errno = ERANGE; - } else if (!any) { -noconv: - errno = EINVAL; - } else if (neg) - acc = -acc; - if (endptr != NULL) - *endptr = (char *)(any ? s - 1 : nptr); - return (acc); -} diff --git a/storage/bdb/clib/strtoul.c b/storage/bdb/clib/strtoul.c deleted file mode 100644 index 14eacb89f3f..00000000000 --- a/storage/bdb/clib/strtoul.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: strtoul.c,v 12.0 2004/11/17 03:43:15 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <limits.h> -#include <ctype.h> -#include <errno.h> -#include <stdlib.h> -#include <stdio.h> -#endif - -/* - * Convert a string to an unsigned long integer. - * - * Assumes that the upper and lower case - * alphabets and digits are each contiguous. - */ -unsigned long -strtoul(nptr, endptr, base) - const char * nptr; - char ** endptr; - int base; -{ - const char *s; - unsigned long acc; - char c; - unsigned long cutoff; - int neg, any, cutlim; - - /* - * See strtol for comments as to the logic used. - */ - s = nptr; - do { - c = *s++; - } while (isspace((unsigned char)c)); - if (c == '-') { - neg = 1; - c = *s++; - } else { - neg = 0; - if (c == '+') - c = *s++; - } - if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X')) { - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) - base = c == '0' ? 8 : 10; - acc = any = 0; - if (base < 2 || base > 36) - goto noconv; - - cutoff = ULONG_MAX / base; - cutlim = ULONG_MAX % base; - for ( ; ; c = *s++) { - if (c >= '0' && c <= '9') - c -= '0'; - else if (c >= 'A' && c <= 'Z') - c -= 'A' - 10; - else if (c >= 'a' && c <= 'z') - c -= 'a' - 10; - else - break; - if (c >= base) - break; - if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) - any = -1; - else { - any = 1; - acc *= base; - acc += c; - } - } - if (any < 0) { - acc = ULONG_MAX; - errno = ERANGE; - } else if (!any) { -noconv: - errno = EINVAL; - } else if (neg) - acc = -acc; - if (endptr != NULL) - *endptr = (char *)(any ? s - 1 : nptr); - return (acc); -} diff --git a/storage/bdb/clib/vsnprintf.c b/storage/bdb/clib/vsnprintf.c deleted file mode 100644 index 4ffea8cb0ad..00000000000 --- a/storage/bdb/clib/vsnprintf.c +++ /dev/null @@ -1,47 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2002 - * Sleepycat Software. All rights reserved. - */ - -#include "db_config.h" - -#ifndef lint -static const char revid[] = "$Id: vsnprintf.c,v 11.7 2002/01/11 15:51:29 bostic Exp $"; -#endif /* not lint */ - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stdio.h> -#endif - -#include "db_int.h" - -/* - * vsnprintf -- - * Bounded version of vsprintf. - * - * PUBLIC: #ifndef HAVE_VSNPRINTF - * PUBLIC: int vsnprintf __P((char *, size_t, const char *, va_list)); - * PUBLIC: #endif - */ -#ifndef HAVE_VSNPRINTF -int -vsnprintf(str, n, fmt, ap) - char *str; - size_t n; - const char *fmt; - va_list ap; -{ - COMPQUIET(n, 0); - -#ifdef SPRINTF_RET_CHARPNT - (void)vsprintf(str, fmt, ap); - return (strlen(str)); -#else - return (vsprintf(str, fmt, ap)); -#endif -} -#endif diff --git a/storage/bdb/common/crypto_stub.c b/storage/bdb/common/crypto_stub.c deleted file mode 100644 index e335b61f99a..00000000000 --- a/storage/bdb/common/crypto_stub.c +++ /dev/null @@ -1,45 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: crypto_stub.c,v 12.2 2005/07/20 16:50:55 bostic Exp $ - */ - -#include "db_config.h" - -#include "db_int.h" - -/* - * __crypto_region_init -- - * Initialize crypto. - * - * - * !!! - * We don't put this stub file in the crypto/ directory of the distribution - * because that entire directory is removed for non-crypto distributions. - * - * PUBLIC: int __crypto_region_init __P((DB_ENV *)); - */ -int -__crypto_region_init(dbenv) - DB_ENV *dbenv; -{ - REGENV *renv; - REGINFO *infop; - int ret; - - infop = dbenv->reginfo; - renv = infop->primary; - MUTEX_LOCK(dbenv, renv->mtx_regenv); - ret = !(renv->cipher_off == INVALID_ROFF); - MUTEX_UNLOCK(dbenv, renv->mtx_regenv); - - if (ret == 0) - return (0); - - __db_err(dbenv, -"Encrypted environment: library build did not include cryptography support"); - return (DB_OPNOTSUP); -} diff --git a/storage/bdb/common/db_byteorder.c b/storage/bdb/common/db_byteorder.c deleted file mode 100644 index 60b1d293e41..00000000000 --- a/storage/bdb/common/db_byteorder.c +++ /dev/null @@ -1,72 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_byteorder.c,v 12.1 2005/06/16 20:20:52 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - -#include "db_int.h" - -/* - * __db_isbigendian -- - * Return 1 if big-endian (Motorola and Sparc), not little-endian - * (Intel and Vax). We do this work at run-time, rather than at - * configuration time so cross-compilation and general embedded - * system support is simpler. - * - * PUBLIC: int __db_isbigendian __P((void)); - */ -int -__db_isbigendian() -{ - union { /* From Harbison & Steele. */ - long l; - char c[sizeof(long)]; - } u; - - u.l = 1; - return (u.c[sizeof(long) - 1] == 1); -} - -/* - * __db_byteorder -- - * Return if we need to do byte swapping, checking for illegal - * values. - * - * PUBLIC: int __db_byteorder __P((DB_ENV *, int)); - */ -int -__db_byteorder(dbenv, lorder) - DB_ENV *dbenv; - int lorder; -{ - int is_bigendian; - - is_bigendian = __db_isbigendian(); - - switch (lorder) { - case 0: - break; - case 1234: - if (is_bigendian) - return (DB_SWAPBYTES); - break; - case 4321: - if (!is_bigendian) - return (DB_SWAPBYTES); - break; - default: - __db_err(dbenv, - "unsupported byte order, only big and little-endian supported"); - return (EINVAL); - } - return (0); -} diff --git a/storage/bdb/common/db_clock.c b/storage/bdb/common/db_clock.c deleted file mode 100644 index d53b1961ada..00000000000 --- a/storage/bdb/common/db_clock.c +++ /dev/null @@ -1,30 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_clock.c,v 1.2 2005/08/08 14:39:52 bostic Exp $ - */ - -#include "db_config.h" -#include "db_int.h" - -/* - * __db_difftime -- - * - * Compute the difference in seconds and microseconds of two timers. - * - * PUBLIC: void __db_difftime __P((u_int32_t, u_int32_t, u_int32_t, u_int32_t, - * PUBLIC: u_int32_t *, u_int32_t *)); - */ -void -__db_difftime(ssec, esec, susec, eusec, secp, usecp) - u_int32_t ssec, esec, susec, eusec, *secp, *usecp; -{ - if ((*secp = esec - ssec) != 0 && eusec < susec) { - (*secp)--; - eusec += 1000000; - } - *usecp = eusec - susec; -} diff --git a/storage/bdb/common/db_err.c b/storage/bdb/common/db_err.c deleted file mode 100644 index fd9fa89a46a..00000000000 --- a/storage/bdb/common/db_err.c +++ /dev/null @@ -1,840 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_err.c,v 12.19 2005/10/19 19:06:29 sue Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stdlib.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_am.h" -#include "dbinc/db_shash.h" -#include "dbinc/lock.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" -#include "dbinc/txn.h" - -static void __db_msgcall __P((const DB_ENV *, const char *, va_list)); -static void __db_msgfile __P((const DB_ENV *, const char *, va_list)); - -/* - * __db_fchk -- - * General flags checking routine. - * - * PUBLIC: int __db_fchk __P((DB_ENV *, const char *, u_int32_t, u_int32_t)); - */ -int -__db_fchk(dbenv, name, flags, ok_flags) - DB_ENV *dbenv; - const char *name; - u_int32_t flags, ok_flags; -{ - return (LF_ISSET(~ok_flags) ? __db_ferr(dbenv, name, 0) : 0); -} - -/* - * __db_fcchk -- - * General combination flags checking routine. - * - * PUBLIC: int __db_fcchk - * PUBLIC: __P((DB_ENV *, const char *, u_int32_t, u_int32_t, u_int32_t)); - */ -int -__db_fcchk(dbenv, name, flags, flag1, flag2) - DB_ENV *dbenv; - const char *name; - u_int32_t flags, flag1, flag2; -{ - return (LF_ISSET(flag1) && - LF_ISSET(flag2) ? __db_ferr(dbenv, name, 1) : 0); -} - -/* - * __db_ferr -- - * Common flag errors. - * - * PUBLIC: int __db_ferr __P((const DB_ENV *, const char *, int)); - */ -int -__db_ferr(dbenv, name, iscombo) - const DB_ENV *dbenv; - const char *name; - int iscombo; -{ - __db_err(dbenv, "illegal flag %sspecified to %s", - iscombo ? "combination " : "", name); - return (EINVAL); -} - -/* - * __db_fnl -- - * Common flag-needs-locking message. - * - * PUBLIC: int __db_fnl __P((const DB_ENV *, const char *)); - */ -int -__db_fnl(dbenv, name) - const DB_ENV *dbenv; - const char *name; -{ - __db_err(dbenv, - "%s: DB_READ_COMMITTED, DB_READ_UNCOMMITTED and DB_RMW require locking", - name); - return (EINVAL); -} - -/* - * __db_pgerr -- - * Error when unable to retrieve a specified page. - * - * PUBLIC: int __db_pgerr __P((DB *, db_pgno_t, int)); - */ -int -__db_pgerr(dbp, pgno, errval) - DB *dbp; - db_pgno_t pgno; - int errval; -{ - /* - * Three things are certain: - * Death, taxes, and lost data. - * Guess which has occurred. - */ - __db_err(dbp->dbenv, - "unable to create/retrieve page %lu", (u_long)pgno); - return (__db_panic(dbp->dbenv, errval)); -} - -/* - * __db_pgfmt -- - * Error when a page has the wrong format. - * - * PUBLIC: int __db_pgfmt __P((DB_ENV *, db_pgno_t)); - */ -int -__db_pgfmt(dbenv, pgno) - DB_ENV *dbenv; - db_pgno_t pgno; -{ - __db_err(dbenv, "page %lu: illegal page type or format", (u_long)pgno); - return (__db_panic(dbenv, EINVAL)); -} - -#ifdef DIAGNOSTIC -/* - * __db_assert -- - * Error when an assertion fails. Only checked if #DIAGNOSTIC defined. - * - * PUBLIC: #ifdef DIAGNOSTIC - * PUBLIC: void __db_assert __P((const char *, const char *, int)); - * PUBLIC: #endif - */ -void -__db_assert(failedexpr, file, line) - const char *failedexpr, *file; - int line; -{ - (void)fprintf(stderr, - "__db_assert: \"%s\" failed: file \"%s\", line %d\n", - failedexpr, file, line); - (void)fflush(stderr); - - /* We want a stack trace of how this could possibly happen. */ - abort(); - - /* NOTREACHED */ -} -#endif - -/* - * __db_panic_msg -- - * Just report that someone else paniced. - * - * PUBLIC: int __db_panic_msg __P((DB_ENV *)); - */ -int -__db_panic_msg(dbenv) - DB_ENV *dbenv; -{ - __db_err(dbenv, "PANIC: fatal region error detected; run recovery"); - - if (dbenv->db_paniccall != NULL) - dbenv->db_paniccall(dbenv, DB_RUNRECOVERY); - - return (DB_RUNRECOVERY); -} - -/* - * __db_panic -- - * Lock out the tree due to unrecoverable error. - * - * PUBLIC: int __db_panic __P((DB_ENV *, int)); - */ -int -__db_panic(dbenv, errval) - DB_ENV *dbenv; - int errval; -{ - if (dbenv != NULL) { - __db_panic_set(dbenv, 1); - - __db_err(dbenv, "PANIC: %s", db_strerror(errval)); - - if (dbenv->db_paniccall != NULL) - dbenv->db_paniccall(dbenv, errval); - } - -#if defined(DIAGNOSTIC) && !defined(CONFIG_TEST) - /* - * We want a stack trace of how this could possibly happen. - * - * Don't drop core if it's the test suite -- it's reasonable for the - * test suite to check to make sure that DB_RUNRECOVERY is returned - * under certain conditions. - */ - abort(); -#endif - - /* - * Chaos reigns within. - * Reflect, repent, and reboot. - * Order shall return. - */ - return (DB_RUNRECOVERY); -} - -/* - * __db_panic_set -- - * Set/clear unrecoverable error. - * - * PUBLIC: void __db_panic_set __P((DB_ENV *, int)); - */ -void -__db_panic_set(dbenv, on) - DB_ENV *dbenv; - int on; -{ - if (dbenv != NULL && dbenv->reginfo != NULL) - ((REGENV *) - ((REGINFO *)dbenv->reginfo)->primary)->panic = on ? 1 : 0; -} - -/* - * db_strerror -- - * ANSI C strerror(3) for DB. - * - * EXTERN: char *db_strerror __P((int)); - */ -char * -db_strerror(error) - int error; -{ - char *p; - - if (error == 0) - return ("Successful return: 0"); - if (error > 0) { - if ((p = strerror(error)) != NULL) - return (p); - goto unknown_err; - } - - /* - * !!! - * The Tcl API requires that some of these return strings be compared - * against strings stored in application scripts. So, any of these - * errors that do not invariably result in a Tcl exception may not be - * altered. - */ - switch (error) { - case DB_BUFFER_SMALL: - return - ("DB_BUFFER_SMALL: User memory too small for return value"); - case DB_DONOTINDEX: - return ("DB_DONOTINDEX: Secondary index callback returns null"); - case DB_KEYEMPTY: - return ("DB_KEYEMPTY: Non-existent key/data pair"); - case DB_KEYEXIST: - return ("DB_KEYEXIST: Key/data pair already exists"); - case DB_LOCK_DEADLOCK: - return - ("DB_LOCK_DEADLOCK: Locker killed to resolve a deadlock"); - case DB_LOCK_NOTGRANTED: - return ("DB_LOCK_NOTGRANTED: Lock not granted"); - case DB_LOG_BUFFER_FULL: - return ("DB_LOG_BUFFER_FULL: In-memory log buffer is full"); - case DB_NOSERVER: - return ("DB_NOSERVER: Fatal error, no RPC server"); - case DB_NOSERVER_HOME: - return ("DB_NOSERVER_HOME: Home unrecognized at server"); - case DB_NOSERVER_ID: - return ("DB_NOSERVER_ID: Identifier unrecognized at server"); - case DB_NOTFOUND: - return ("DB_NOTFOUND: No matching key/data pair found"); - case DB_OLD_VERSION: - return ("DB_OLDVERSION: Database requires a version upgrade"); - case DB_PAGE_NOTFOUND: - return ("DB_PAGE_NOTFOUND: Requested page not found"); - case DB_REP_DUPMASTER: - return ("DB_REP_DUPMASTER: A second master site appeared"); - case DB_REP_HANDLE_DEAD: - return ("DB_REP_HANDLE_DEAD: Handle is no longer valid"); - case DB_REP_HOLDELECTION: - return ("DB_REP_HOLDELECTION: Need to hold an election"); - case DB_REP_IGNORE: - return ("DB_REP_IGNORE: Replication record ignored"); - case DB_REP_ISPERM: - return ("DB_REP_ISPERM: Permanent record written"); - case DB_REP_JOIN_FAILURE: - return - ("DB_REP_JOIN_FAILURE: Unable to join replication group"); - case DB_REP_LOCKOUT: - return - ("DB_REP_LOCKOUT: Waiting for replication recovery to complete"); - case DB_REP_NEWMASTER: - return ("DB_REP_NEWMASTER: A new master has declared itself"); - case DB_REP_NEWSITE: - return ("DB_REP_NEWSITE: A new site has entered the system"); - case DB_REP_NOTPERM: - return ("DB_REP_NOTPERM: Permanent log record not written"); - case DB_REP_STARTUPDONE: - return - ("DB_REP_STARTUPDONE: Client completed startup synchronization."); - case DB_REP_UNAVAIL: - return ("DB_REP_UNAVAIL: Unable to elect a master"); - case DB_RUNRECOVERY: - return ("DB_RUNRECOVERY: Fatal error, run database recovery"); - case DB_SECONDARY_BAD: - return - ("DB_SECONDARY_BAD: Secondary index inconsistent with primary"); - case DB_VERIFY_BAD: - return ("DB_VERIFY_BAD: Database verification failed"); - case DB_VERSION_MISMATCH: - return - ("DB_VERSION_MISMATCH: Database environment version mismatch"); - default: - break; - } - -unknown_err: { - /* - * !!! - * Room for a 64-bit number + slop. This buffer is only used - * if we're given an unknown error, which should never happen. - * Note, however, we're no longer thread-safe if it does. - */ - static char ebuf[40]; - - (void)snprintf(ebuf, sizeof(ebuf), "Unknown error: %d", error); - return (ebuf); - } -} - -/* - * __db_err -- - * Standard DB error routine. The same as errx, except we don't write - * to stderr if no output mechanism was specified. - * - * PUBLIC: void __db_err __P((const DB_ENV *, const char *, ...)) - * PUBLIC: __attribute__ ((__format__ (__printf__, 2, 3))); - */ -void -#ifdef STDC_HEADERS -__db_err(const DB_ENV *dbenv, const char *fmt, ...) -#else -__db_err(dbenv, fmt, va_alist) - const DB_ENV *dbenv; - const char *fmt; - va_dcl -#endif -{ - DB_REAL_ERR(dbenv, 0, 0, 0, fmt); -} - -/* - * __db_errcall -- - * Do the error message work for callback functions. - * - * PUBLIC: void __db_errcall - * PUBLIC: __P((const DB_ENV *, int, int, const char *, va_list)); - */ -void -__db_errcall(dbenv, error, error_set, fmt, ap) - const DB_ENV *dbenv; - int error, error_set; - const char *fmt; - va_list ap; -{ - char *p; - char buf[2048]; /* !!!: END OF THE STACK DON'T TRUST SPRINTF. */ - - p = buf; - if (fmt != NULL) - p += vsnprintf(buf, sizeof(buf), fmt, ap); - if (error_set) - p += snprintf(p, - sizeof(buf) - (size_t)(p - buf), ": %s", - db_strerror(error)); - - dbenv->db_errcall(dbenv, dbenv->db_errpfx, buf); -} - -/* - * __db_errfile -- - * Do the error message work for FILE *s. - * - * PUBLIC: void __db_errfile - * PUBLIC: __P((const DB_ENV *, int, int, const char *, va_list)); - */ -void -__db_errfile(dbenv, error, error_set, fmt, ap) - const DB_ENV *dbenv; - int error, error_set; - const char *fmt; - va_list ap; -{ - FILE *fp; - - fp = dbenv == NULL || - dbenv->db_errfile == NULL ? stderr : dbenv->db_errfile; - - if (dbenv != NULL && dbenv->db_errpfx != NULL) - (void)fprintf(fp, "%s: ", dbenv->db_errpfx); - if (fmt != NULL) { - (void)vfprintf(fp, fmt, ap); - if (error_set) - (void)fprintf(fp, ": "); - } - if (error_set) - (void)fprintf(fp, "%s", db_strerror(error)); - (void)fprintf(fp, "\n"); - (void)fflush(fp); -} - -/* - * __db_msgadd -- - * Aggregate a set of strings into a buffer for the callback API. - * - * PUBLIC: void __db_msgadd __P((DB_ENV *, DB_MSGBUF *, const char *, ...)) - * PUBLIC: __attribute__ ((__format__ (__printf__, 3, 4))); - */ -void -#ifdef STDC_HEADERS -__db_msgadd(DB_ENV *dbenv, DB_MSGBUF *mbp, const char *fmt, ...) -#else -__db_msgadd(dbenv, mbp, fmt, va_alist) - DB_ENV *dbenv; - DB_MSGBUF *mbp; - const char *fmt; - va_dcl -#endif -{ - va_list ap; - size_t len, olen; - char buf[2048]; /* !!!: END OF THE STACK DON'T TRUST SPRINTF. */ - -#ifdef STDC_HEADERS - va_start(ap, fmt); -#else - va_start(ap); -#endif - len = (size_t)vsnprintf(buf, sizeof(buf), fmt, ap); - - va_end(ap); - - /* - * There's a heap buffer in the DB_ENV handle we use to aggregate the - * message chunks. We maintain a pointer to the buffer, the next slot - * to be filled in in the buffer, and a total buffer length. - */ - olen = (size_t)(mbp->cur - mbp->buf); - if (olen + len >= mbp->len) { - if (__os_realloc(dbenv, mbp->len + len + 256, &mbp->buf)) - return; - mbp->len += (len + 256); - mbp->cur = mbp->buf + olen; - } - - memcpy(mbp->cur, buf, len + 1); - mbp->cur += len; -} - -/* - * __db_msg -- - * Standard DB stat message routine. - * - * PUBLIC: void __db_msg __P((const DB_ENV *, const char *, ...)) - * PUBLIC: __attribute__ ((__format__ (__printf__, 2, 3))); - */ -void -#ifdef STDC_HEADERS -__db_msg(const DB_ENV *dbenv, const char *fmt, ...) -#else -__db_msg(dbenv, fmt, va_alist) - const DB_ENV *dbenv; - const char *fmt; - va_dcl -#endif -{ - DB_REAL_MSG(dbenv, fmt); -} - -/* - * __db_msgcall -- - * Do the message work for callback functions. - */ -static void -__db_msgcall(dbenv, fmt, ap) - const DB_ENV *dbenv; - const char *fmt; - va_list ap; -{ - char buf[2048]; /* !!!: END OF THE STACK DON'T TRUST SPRINTF. */ - - (void)vsnprintf(buf, sizeof(buf), fmt, ap); - - dbenv->db_msgcall(dbenv, buf); -} - -/* - * __db_msgfile -- - * Do the message work for FILE *s. - */ -static void -__db_msgfile(dbenv, fmt, ap) - const DB_ENV *dbenv; - const char *fmt; - va_list ap; -{ - FILE *fp; - - fp = dbenv == NULL || - dbenv->db_msgfile == NULL ? stdout : dbenv->db_msgfile; - (void)vfprintf(fp, fmt, ap); - - (void)fprintf(fp, "\n"); - (void)fflush(fp); -} - -/* - * __db_unknown_flag -- report internal error - * - * PUBLIC: int __db_unknown_flag __P((DB_ENV *, char *, u_int32_t)); - */ -int -__db_unknown_flag(dbenv, routine, flag) - DB_ENV *dbenv; - char *routine; - u_int32_t flag; -{ - __db_err(dbenv, "%s: Unknown flag: %#x", routine, (u_int)flag); - DB_ASSERT(0); - return (EINVAL); -} - -/* - * __db_unknown_type -- report internal error - * - * PUBLIC: int __db_unknown_type __P((DB_ENV *, char *, DBTYPE)); - */ -int -__db_unknown_type(dbenv, routine, type) - DB_ENV *dbenv; - char *routine; - DBTYPE type; -{ - __db_err(dbenv, - "%s: Unexpected DB type: %s", routine, __db_dbtype_to_string(type)); - - DB_ASSERT(0); - return (EINVAL); -} - -/* - * __db_check_txn -- - * Check for common transaction errors. - * - * PUBLIC: int __db_check_txn __P((DB *, DB_TXN *, u_int32_t, int)); - */ -int -__db_check_txn(dbp, txn, assoc_lid, read_op) - DB *dbp; - DB_TXN *txn; - u_int32_t assoc_lid; - int read_op; -{ - DB_ENV *dbenv; - int isp, ret; - - dbenv = dbp->dbenv; - - /* - * If we are in recovery or aborting a transaction, then we - * don't need to enforce the rules about dbp's not allowing - * transactional operations in non-transactional dbps and - * vica-versa. This happens all the time as the dbp during - * an abort may be transactional, but we undo operations - * outside a transaction since we're aborting. - */ - if (IS_RECOVERING(dbenv) || F_ISSET(dbp, DB_AM_RECOVER)) - return (0); - - /* - * Check for common transaction errors: - * an operation on a handle whose open commit hasn't completed. - * a transaction handle in a non-transactional environment - * a transaction handle for a non-transactional database - */ - if (txn == NULL) { - if (dbp->cur_lid >= TXN_MINIMUM) - goto open_err; - } else { - if (!TXN_ON(dbenv)) - return (__db_not_txn_env(dbenv)); - - if (!F_ISSET(dbp, DB_AM_TXN)) { - __db_err(dbenv, - "Transaction specified for a DB handle opened outside a transaction"); - return (EINVAL); - } - - if (F_ISSET(txn, TXN_DEADLOCK)) { - __db_err(dbenv, - "Previous deadlock return not resolved"); - return (EINVAL); - } - if (dbp->cur_lid >= TXN_MINIMUM && dbp->cur_lid != txn->txnid) { - if ((ret = __lock_locker_is_parent(dbenv, - dbp->cur_lid, txn->txnid, &isp)) != 0) - return (ret); - if (!isp) - goto open_err; - } - } - - /* - * If dbp->associate_lid is not DB_LOCK_INVALIDID, that means we're in - * the middle of a DB->associate with DB_CREATE (i.e., a secondary index - * creation). - * - * In addition to the usual transaction rules, we need to lock out - * non-transactional updates that aren't part of the associate (and - * thus are using some other locker ID). - * - * Transactional updates should simply block; from the time we - * decide to build the secondary until commit, we'll hold a write - * lock on all of its pages, so it should be safe to attempt to update - * the secondary in another transaction (presumably by updating the - * primary). - */ - if (!read_op && dbp->associate_lid != DB_LOCK_INVALIDID && - txn != NULL && dbp->associate_lid != assoc_lid) { - __db_err(dbenv, - "Operation forbidden while secondary index is being created"); - return (EINVAL); - } - - /* - * Check the txn and dbp are from the same env. - */ - if (txn != NULL && dbenv != txn->mgrp->dbenv) { - __db_err(dbenv, - "Transaction and database from different environments"); - return (EINVAL); - } - - return (0); -open_err: - __db_err(dbenv, - "Transaction that opened the DB handle is still active"); - return (EINVAL); -} - -/* - * __db_not_txn_env -- - * DB handle must be in an environment that supports transactions. - * - * PUBLIC: int __db_not_txn_env __P((DB_ENV *)); - */ -int -__db_not_txn_env(dbenv) - DB_ENV *dbenv; -{ - __db_err(dbenv, "DB environment not configured for transactions"); - return (EINVAL); -} - -/* - * __db_rec_toobig -- - * Fixed record length exceeded error message. - * - * PUBLIC: int __db_rec_toobig __P((DB_ENV *, u_int32_t, u_int32_t)); - */ -int -__db_rec_toobig(dbenv, data_len, fixed_rec_len) - DB_ENV *dbenv; - u_int32_t data_len, fixed_rec_len; -{ - __db_err(dbenv, "%s: length of %lu larger than database's value of %lu", - "Record length error", (u_long)data_len, (u_long)fixed_rec_len); - return (EINVAL); -} - -/* - * __db_rec_repl -- - * Fixed record replacement length error message. - * - * PUBLIC: int __db_rec_repl __P((DB_ENV *, u_int32_t, u_int32_t)); - */ -int -__db_rec_repl(dbenv, data_size, data_dlen) - DB_ENV *dbenv; - u_int32_t data_size, data_dlen; -{ - __db_err(dbenv, - "%s: replacement length %lu differs from replaced length %lu", - "Record length error", (u_long)data_size, (u_long)data_dlen); - return (EINVAL); -} - -#if defined(DIAGNOSTIC) || defined(DEBUG_ROP) || defined(DEBUG_WOP) -/* - * __dbc_logging -- - * In DIAGNOSTIC mode, check for bad replication combinations. - * - * PUBLIC: int __dbc_logging __P((DBC *)); - */ -int -__dbc_logging(dbc) - DBC *dbc; -{ - DB_ENV *dbenv; - DB_REP *db_rep; - int ret; - - dbenv = dbc->dbp->dbenv; - db_rep = dbenv->rep_handle; - - ret = LOGGING_ON(dbenv) && - !F_ISSET(dbc, DBC_RECOVER) && !IS_REP_CLIENT(dbenv); - - /* - * If we're not using replication or running recovery, return. - */ - if (db_rep == NULL || F_ISSET(dbc, DBC_RECOVER)) - return (ret); - -#ifndef DEBUG_ROP - /* - * Only check when DEBUG_ROP is not configured. People often do - * non-transactional reads, and debug_rop is going to write - * a log record. - */ - { - REP *rep; - - rep = db_rep->region; - - /* - * If we're a client and not running recovery or internally, error. - */ - if (IS_REP_CLIENT(dbenv) && !F_ISSET(dbc->dbp, DB_AM_CL_WRITER)) { - __db_err(dbenv, "Dbc_logging: Client update"); - goto err; - } - if (IS_REP_MASTER(dbenv) && dbc->txn == NULL) { - __db_err(dbenv, "Dbc_logging: Master non-txn update"); - goto err; - } - if (0) { -err: __db_err(dbenv, "Rep: flags 0x%lx msg_th %lu, start_th %d", - (u_long)rep->flags, (u_long)rep->msg_th, rep->start_th); - __db_err(dbenv, "Rep: handle %lu, opcnt %lu, in_rec %d", - (u_long)rep->handle_cnt, (u_long)rep->op_cnt, - rep->in_recovery); - abort(); - } - } -#endif - return (ret); -} -#endif - -/* - * __db_check_lsn -- - * Display the log sequence error message. - * - * PUBLIC: int __db_check_lsn __P((DB_ENV *, DB_LSN *, DB_LSN *)); - */ -int -__db_check_lsn(dbenv, lsn, prev) - DB_ENV *dbenv; - DB_LSN *lsn, *prev; -{ - __db_err(dbenv, - "Log sequence error: page LSN %lu %lu; previous LSN %lu %lu", - (u_long)(lsn)->file, (u_long)(lsn)->offset, - (u_long)(prev)->file, (u_long)(prev)->offset); - return (EINVAL); -} - -/* - * __db_rdonly -- - * Common readonly message. - * PUBLIC: int __db_rdonly __P((const DB_ENV *, const char *)); - */ -int -__db_rdonly(dbenv, name) - const DB_ENV *dbenv; - const char *name; -{ - __db_err(dbenv, "%s: attempt to modify a read-only database", name); - return (EACCES); -} - -/* - * __db_space_err -- - * Common out of space message. - * PUBLIC: int __db_space_err __P((const DB *)); - */ -int -__db_space_err(dbp) - const DB *dbp; -{ - __db_err(dbp->dbenv, - "%s: file limited to %lu pages", - dbp->fname, (u_long)dbp->mpf->mfp->maxpgno); - return (ENOSPC); -} - -/* - * __db_failed -- - * Common failed thread message. - * - * PUBLIC: int __db_failed __P((const DB_ENV *, - * PUBLIC: const char *, pid_t, db_threadid_t)); - */ -int -__db_failed(dbenv, msg, pid, tid) - const DB_ENV *dbenv; - const char *msg; - pid_t pid; - db_threadid_t tid; -{ - char buf[DB_THREADID_STRLEN]; - - __db_err(dbenv, "Thread/process %s failed: %s", - dbenv->thread_id_string((DB_ENV*)dbenv, pid, tid, buf), msg); - return (DB_RUNRECOVERY); -} diff --git a/storage/bdb/common/db_getlong.c b/storage/bdb/common/db_getlong.c deleted file mode 100644 index 3d0183c602c..00000000000 --- a/storage/bdb/common/db_getlong.c +++ /dev/null @@ -1,146 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_getlong.c,v 12.1 2005/06/16 20:20:53 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <limits.h> -#include <stdlib.h> -#include <string.h> -#endif - -#include "db_int.h" - -/* - * __db_getlong -- - * Return a long value inside of basic parameters. - * - * PUBLIC: int __db_getlong - * PUBLIC: __P((DB_ENV *, const char *, char *, long, long, long *)); - */ -int -__db_getlong(dbenv, progname, p, min, max, storep) - DB_ENV *dbenv; - const char *progname; - char *p; - long min, max, *storep; -{ - long val; - char *end; - - __os_set_errno(0); - val = strtol(p, &end, 10); - if ((val == LONG_MIN || val == LONG_MAX) && - __os_get_errno() == ERANGE) { - if (dbenv == NULL) - fprintf(stderr, - "%s: %s: %s\n", progname, p, strerror(ERANGE)); - else - dbenv->err(dbenv, ERANGE, "%s", p); - return (1); - } - if (p[0] == '\0' || (end[0] != '\0' && end[0] != '\n')) { - if (dbenv == NULL) - fprintf(stderr, - "%s: %s: Invalid numeric argument\n", progname, p); - else - dbenv->errx(dbenv, "%s: Invalid numeric argument", p); - return (1); - } - if (val < min) { - if (dbenv == NULL) - fprintf(stderr, - "%s: %s: Less than minimum value (%ld)\n", - progname, p, min); - else - dbenv->errx(dbenv, - "%s: Less than minimum value (%ld)", p, min); - return (1); - } - if (val > max) { - if (dbenv == NULL) - fprintf(stderr, - "%s: %s: Greater than maximum value (%ld)\n", - progname, p, max); - else - dbenv->errx(dbenv, - "%s: Greater than maximum value (%ld)", p, max); - return (1); - } - *storep = val; - return (0); -} - -/* - * __db_getulong -- - * Return an unsigned long value inside of basic parameters. - * - * PUBLIC: int __db_getulong - * PUBLIC: __P((DB_ENV *, const char *, char *, u_long, u_long, u_long *)); - */ -int -__db_getulong(dbenv, progname, p, min, max, storep) - DB_ENV *dbenv; - const char *progname; - char *p; - u_long min, max, *storep; -{ - u_long val; - char *end; - - __os_set_errno(0); - val = strtoul(p, &end, 10); - if (val == ULONG_MAX && __os_get_errno() == ERANGE) { - if (dbenv == NULL) - fprintf(stderr, - "%s: %s: %s\n", progname, p, strerror(ERANGE)); - else - dbenv->err(dbenv, ERANGE, "%s", p); - return (1); - } - if (p[0] == '\0' || (end[0] != '\0' && end[0] != '\n')) { - if (dbenv == NULL) - fprintf(stderr, - "%s: %s: Invalid numeric argument\n", progname, p); - else - dbenv->errx(dbenv, "%s: Invalid numeric argument", p); - return (1); - } - if (val < min) { - if (dbenv == NULL) - fprintf(stderr, - "%s: %s: Less than minimum value (%lu)\n", - progname, p, min); - else - dbenv->errx(dbenv, - "%s: Less than minimum value (%lu)", p, min); - return (1); - } - - /* - * We allow a 0 to substitute as a max value for ULONG_MAX because - * 1) accepting only a 0 value is unlikely to be necessary, and 2) - * we don't want callers to have to use ULONG_MAX explicitly, as it - * may not exist on all platforms. - */ - if (max != 0 && val > max) { - if (dbenv == NULL) - fprintf(stderr, - "%s: %s: Greater than maximum value (%lu)\n", - progname, p, max); - else - dbenv->errx(dbenv, - "%s: Greater than maximum value (%lu)", p, max); - return (1); - } - *storep = val; - return (0); -} diff --git a/storage/bdb/common/db_idspace.c b/storage/bdb/common/db_idspace.c deleted file mode 100644 index 3932a49ea2e..00000000000 --- a/storage/bdb/common/db_idspace.c +++ /dev/null @@ -1,92 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2001-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_idspace.c,v 12.1 2005/06/16 20:20:53 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stdlib.h> -#endif - -#include "db_int.h" - -static int __db_idcmp __P((const void *, const void *)); - -static int -__db_idcmp(a, b) - const void *a; - const void *b; -{ - u_int32_t i, j; - - i = *(u_int32_t *)a; - j = *(u_int32_t *)b; - - if (i < j) - return (-1); - else if (i > j) - return (1); - else - return (0); -} - -/* - * __db_idspace -- - * - * On input, minp and maxp contain the minimum and maximum valid values for - * the name space and on return, they contain the minimum and maximum ids - * available (by finding the biggest gap). The minimum can be an inuse - * value, but the maximum cannot be. - * - * PUBLIC: void __db_idspace __P((u_int32_t *, int, u_int32_t *, u_int32_t *)); - */ -void -__db_idspace(inuse, n, minp, maxp) - u_int32_t *inuse; - int n; - u_int32_t *minp, *maxp; -{ - int i, low; - u_int32_t gap, t; - - /* A single locker ID is a special case. */ - if (n == 1) { - /* - * If the single item in use is the last one in the range, - * then we've got to perform wrap which means that we set - * the min to the minimum ID, which is what we came in with, - * so we don't do anything. - */ - if (inuse[0] != *maxp) - *minp = inuse[0]; - *maxp = inuse[0] - 1; - return; - } - - gap = 0; - low = 0; - qsort(inuse, (size_t)n, sizeof(u_int32_t), __db_idcmp); - for (i = 0; i < n - 1; i++) - if ((t = (inuse[i + 1] - inuse[i])) > gap) { - gap = t; - low = i; - } - - /* Check for largest gap at the end of the space. */ - if ((*maxp - inuse[n - 1]) + (inuse[0] - *minp) > gap) { - /* Do same check as we do in the n == 1 case. */ - if (inuse[n - 1] != *maxp) - *minp = inuse[n - 1]; - *maxp = inuse[0] - 1; - } else { - *minp = inuse[low]; - *maxp = inuse[low + 1] - 1; - } -} diff --git a/storage/bdb/common/db_log2.c b/storage/bdb/common/db_log2.c deleted file mode 100644 index 455340640e9..00000000000 --- a/storage/bdb/common/db_log2.c +++ /dev/null @@ -1,62 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1995, 1996 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Margo Seltzer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: db_log2.c,v 12.1 2005/06/16 20:20:53 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - -#include "db_int.h" - -/* - * PUBLIC: u_int32_t __db_log2 __P((u_int32_t)); - */ -u_int32_t -__db_log2(num) - u_int32_t num; -{ - u_int32_t i, limit; - - limit = 1; - for (i = 0; limit < num; limit = limit << 1) - ++i; - return (i); -} diff --git a/storage/bdb/common/util_arg.c b/storage/bdb/common/util_arg.c deleted file mode 100644 index 017fda6c312..00000000000 --- a/storage/bdb/common/util_arg.c +++ /dev/null @@ -1,124 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2001-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: util_arg.c,v 12.1 2005/06/16 20:20:53 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - -#include "db_int.h" - -static char *__db_strsep __P((char **, const char *)); - -/* - * __db_util_arg -- - * Convert a string into an argc/argv pair. - * - * PUBLIC: int __db_util_arg __P((char *, char *, int *, char ***)); - */ -int -__db_util_arg(arg0, str, argcp, argvp) - char *arg0, *str, ***argvp; - int *argcp; -{ - int n, ret; - char **ap, **argv; - -#define MAXARGS 25 - if ((ret = - __os_malloc(NULL, (MAXARGS + 1) * sizeof(char **), &argv)) != 0) - return (ret); - - ap = argv; - *ap++ = arg0; - for (n = 1; (*ap = __db_strsep(&str, " \t")) != NULL;) - if (**ap != '\0') { - ++ap; - if (++n == MAXARGS) - break; - } - *ap = NULL; - - *argcp = ap - argv; - *argvp = argv; - - return (0); -} - -/*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -/* - * Get next token from string *stringp, where tokens are possibly-empty - * strings separated by characters from delim. - * - * Writes NULs into the string at *stringp to end tokens. - * delim need not remain constant from call to call. - * On return, *stringp points past the last NUL written (if there might - * be further tokens), or is NULL (if there are definitely no more tokens). - * - * If *stringp is NULL, strsep returns NULL. - */ -static char * -__db_strsep(stringp, delim) - char **stringp; - const char *delim; -{ - const char *spanp; - int c, sc; - char *s, *tok; - - if ((s = *stringp) == NULL) - return (NULL); - for (tok = s;;) { - c = *s++; - spanp = delim; - do { - if ((sc = *spanp++) == c) { - if (c == 0) - s = NULL; - else - s[-1] = 0; - *stringp = s; - return (tok); - } - } while (sc != 0); - } - /* NOTREACHED */ -} diff --git a/storage/bdb/common/util_cache.c b/storage/bdb/common/util_cache.c deleted file mode 100644 index 34ff5ff008f..00000000000 --- a/storage/bdb/common/util_cache.c +++ /dev/null @@ -1,56 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2000-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: util_cache.c,v 12.1 2005/06/16 20:20:54 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stdlib.h> - -#include <string.h> -#endif - -#include "db_int.h" - -/* - * __db_util_cache -- - * Compute if we have enough cache. - * - * PUBLIC: int __db_util_cache __P((DB *, u_int32_t *, int *)); - */ -int -__db_util_cache(dbp, cachep, resizep) - DB *dbp; - u_int32_t *cachep; - int *resizep; -{ - u_int32_t pgsize; - int ret; - - /* Get the current page size. */ - if ((ret = dbp->get_pagesize(dbp, &pgsize)) != 0) - return (ret); - - /* - * The current cache size is in cachep. If it's insufficient, set the - * the memory referenced by resizep to 1 and set cachep to the minimum - * size needed. - * - * Make sure our current cache is big enough. We want at least - * DB_MINPAGECACHE pages in the cache. - */ - if ((*cachep / pgsize) < DB_MINPAGECACHE) { - *resizep = 1; - *cachep = pgsize * DB_MINPAGECACHE; - } else - *resizep = 0; - - return (0); -} diff --git a/storage/bdb/common/util_log.c b/storage/bdb/common/util_log.c deleted file mode 100644 index 5c46d6b2d4c..00000000000 --- a/storage/bdb/common/util_log.c +++ /dev/null @@ -1,63 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2000-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: util_log.c,v 12.4 2005/10/12 17:47:17 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stdlib.h> -#if TIME_WITH_SYS_TIME -#include <sys/time.h> -#include <time.h> -#else -#if HAVE_SYS_TIME_H -#include <sys/time.h> -#else -#include <time.h> -#endif -#endif - -#include <string.h> -#endif - -#include "db_int.h" - -/* - * __db_util_logset -- - * Log that we're running. - * - * PUBLIC: int __db_util_logset __P((const char *, char *)); - */ -int -__db_util_logset(progname, fname) - const char *progname; - char *fname; -{ - pid_t pid; - db_threadid_t tid; - FILE *fp; - time_t now; - - if ((fp = fopen(fname, "w")) == NULL) - goto err; - - (void)time(&now); - - __os_id(NULL, &pid, &tid); - fprintf(fp, "%s: %lu %s", progname, (u_long)pid, ctime(&now)); - - if (fclose(fp) == EOF) - goto err; - - return (0); - -err: fprintf(stderr, "%s: %s: %s\n", progname, fname, strerror(errno)); - return (1); -} diff --git a/storage/bdb/common/util_sig.c b/storage/bdb/common/util_sig.c deleted file mode 100644 index 3561173166f..00000000000 --- a/storage/bdb/common/util_sig.c +++ /dev/null @@ -1,84 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2000-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: util_sig.c,v 12.1 2005/06/16 20:20:55 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <signal.h> -#endif - -#include "db_int.h" - -static int interrupt; -static void onint __P((int)); - -/* - * onint -- - * Interrupt signal handler. - */ -static void -onint(signo) - int signo; -{ - if ((interrupt = signo) == 0) - interrupt = SIGINT; -} - -/* - * __db_util_siginit -- - * - * PUBLIC: void __db_util_siginit __P((void)); - */ -void -__db_util_siginit() -{ - /* - * Initialize the set of signals for which we want to clean up. - * Generally, we try not to leave the shared regions locked if - * we can. - */ -#ifdef SIGHUP - (void)signal(SIGHUP, onint); -#endif - (void)signal(SIGINT, onint); -#ifdef SIGPIPE - (void)signal(SIGPIPE, onint); -#endif - (void)signal(SIGTERM, onint); -} - -/* - * __db_util_interrupted -- - * Return if interrupted. - * - * PUBLIC: int __db_util_interrupted __P((void)); - */ -int -__db_util_interrupted() -{ - return (interrupt != 0); -} - -/* - * __db_util_sigresend -- - * - * PUBLIC: void __db_util_sigresend __P((void)); - */ -void -__db_util_sigresend() -{ - /* Resend any caught signal. */ - if (interrupt != 0) { - (void)signal(interrupt, SIG_DFL); - (void)raise(interrupt); - /* NOTREACHED */ - } -} diff --git a/storage/bdb/crypto/aes_method.c b/storage/bdb/crypto/aes_method.c deleted file mode 100644 index f77616f3c35..00000000000 --- a/storage/bdb/crypto/aes_method.c +++ /dev/null @@ -1,273 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2001-2005 - * Sleepycat Software. All rights reserved. - * - * Some parts of this code originally written by Adam Stubblefield, - * -- astubble@rice.edu. - * - * $Id: aes_method.c,v 12.1 2005/06/16 20:20:55 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/crypto.h" -#include "dbinc/hmac.h" - -static void __aes_err __P((DB_ENV *, int)); -static int __aes_derivekeys __P((DB_ENV *, DB_CIPHER *, u_int8_t *, size_t)); - -/* - * __aes_setup -- - * Setup AES functions. - * - * PUBLIC: int __aes_setup __P((DB_ENV *, DB_CIPHER *)); - */ -int -__aes_setup(dbenv, db_cipher) - DB_ENV *dbenv; - DB_CIPHER *db_cipher; -{ - AES_CIPHER *aes_cipher; - int ret; - - db_cipher->adj_size = __aes_adj_size; - db_cipher->close = __aes_close; - db_cipher->decrypt = __aes_decrypt; - db_cipher->encrypt = __aes_encrypt; - db_cipher->init = __aes_init; - if ((ret = __os_calloc(dbenv, 1, sizeof(AES_CIPHER), &aes_cipher)) != 0) - return (ret); - db_cipher->data = aes_cipher; - return (0); -} - -/* - * __aes_adj_size -- - * Given a size, return an addition amount needed to meet the - * "chunk" needs of the algorithm. - * - * PUBLIC: u_int __aes_adj_size __P((size_t)); - */ -u_int -__aes_adj_size(len) - size_t len; -{ - if (len % DB_AES_CHUNK == 0) - return (0); - return (DB_AES_CHUNK - (u_int)(len % DB_AES_CHUNK)); -} - -/* - * __aes_close -- - * Destroy the AES encryption instantiation. - * - * PUBLIC: int __aes_close __P((DB_ENV *, void *)); - */ -int -__aes_close(dbenv, data) - DB_ENV *dbenv; - void *data; -{ - __os_free(dbenv, data); - return (0); -} - -/* - * __aes_decrypt -- - * Decrypt data with AES. - * - * PUBLIC: int __aes_decrypt __P((DB_ENV *, void *, void *, - * PUBLIC: u_int8_t *, size_t)); - */ -int -__aes_decrypt(dbenv, aes_data, iv, cipher, cipher_len) - DB_ENV *dbenv; - void *aes_data; - void *iv; - u_int8_t *cipher; - size_t cipher_len; -{ - AES_CIPHER *aes; - cipherInstance c; - int ret; - - aes = (AES_CIPHER *)aes_data; - if (iv == NULL || cipher == NULL) - return (EINVAL); - if ((cipher_len % DB_AES_CHUNK) != 0) - return (EINVAL); - /* - * Initialize the cipher - */ - if ((ret = __db_cipherInit(&c, MODE_CBC, iv)) < 0) { - __aes_err(dbenv, ret); - return (EAGAIN); - } - - /* Do the decryption */ - if ((ret = __db_blockDecrypt(&c, &aes->decrypt_ki, cipher, - cipher_len * 8, cipher)) < 0) { - __aes_err(dbenv, ret); - return (EAGAIN); - } - return (0); -} - -/* - * __aes_encrypt -- - * Encrypt data with AES. - * - * PUBLIC: int __aes_encrypt __P((DB_ENV *, void *, void *, - * PUBLIC: u_int8_t *, size_t)); - */ -int -__aes_encrypt(dbenv, aes_data, iv, data, data_len) - DB_ENV *dbenv; - void *aes_data; - void *iv; - u_int8_t *data; - size_t data_len; -{ - AES_CIPHER *aes; - cipherInstance c; - u_int32_t tmp_iv[DB_IV_BYTES/4]; - int ret; - - aes = (AES_CIPHER *)aes_data; - if (aes == NULL || data == NULL) - return (EINVAL); - if ((data_len % DB_AES_CHUNK) != 0) - return (EINVAL); - /* - * Generate the IV here. We store it in a tmp IV because - * the IV might be stored within the data we are encrypting - * and so we will copy it over to the given location after - * encryption is done. - * We don't do this outside of there because some encryption - * algorithms someone might add may not use IV's and we always - * want on here. - */ - if ((ret = __db_generate_iv(dbenv, tmp_iv)) != 0) - return (ret); - - /* - * Initialize the cipher - */ - if ((ret = __db_cipherInit(&c, MODE_CBC, (char *)tmp_iv)) < 0) { - __aes_err(dbenv, ret); - return (EAGAIN); - } - - /* Do the encryption */ - if ((ret = __db_blockEncrypt(&c, &aes->encrypt_ki, data, data_len * 8, - data)) < 0) { - __aes_err(dbenv, ret); - return (EAGAIN); - } - memcpy(iv, tmp_iv, DB_IV_BYTES); - return (0); -} - -/* - * __aes_init -- - * Initialize the AES encryption instantiation. - * - * PUBLIC: int __aes_init __P((DB_ENV *, DB_CIPHER *)); - */ -int -__aes_init(dbenv, db_cipher) - DB_ENV *dbenv; - DB_CIPHER *db_cipher; -{ - return (__aes_derivekeys(dbenv, db_cipher, (u_int8_t *)dbenv->passwd, - dbenv->passwd_len)); -} - -static int -__aes_derivekeys(dbenv, db_cipher, passwd, plen) - DB_ENV *dbenv; - DB_CIPHER *db_cipher; - u_int8_t *passwd; - size_t plen; -{ - SHA1_CTX ctx; - AES_CIPHER *aes; - int ret; - u_int32_t temp[DB_MAC_KEY/4]; - - if (passwd == NULL) - return (EINVAL); - - aes = (AES_CIPHER *)db_cipher->data; - - /* Derive the crypto keys */ - __db_SHA1Init(&ctx); - __db_SHA1Update(&ctx, passwd, plen); - __db_SHA1Update(&ctx, (u_int8_t *)DB_ENC_MAGIC, strlen(DB_ENC_MAGIC)); - __db_SHA1Update(&ctx, passwd, plen); - __db_SHA1Final((u_int8_t *)temp, &ctx); - - if ((ret = __db_makeKey(&aes->encrypt_ki, DIR_ENCRYPT, - DB_AES_KEYLEN, (char *)temp)) != TRUE) { - __aes_err(dbenv, ret); - return (EAGAIN); - } - if ((ret = __db_makeKey(&aes->decrypt_ki, DIR_DECRYPT, - DB_AES_KEYLEN, (char *)temp)) != TRUE) { - __aes_err(dbenv, ret); - return (EAGAIN); - } - return (0); -} - -/* - * __aes_err -- - * Handle AES-specific errors. Codes and messages derived from - * rijndael/rijndael-api-fst.h. - */ -static void -__aes_err(dbenv, err) - DB_ENV *dbenv; - int err; -{ - char *errstr; - - switch (err) { - case BAD_KEY_DIR: - errstr = "AES key direction is invalid"; - break; - case BAD_KEY_MAT: - errstr = "AES key material not of correct length"; - break; - case BAD_KEY_INSTANCE: - errstr = "AES key passwd not valid"; - break; - case BAD_CIPHER_MODE: - errstr = "AES cipher in wrong state (not initialized)"; - break; - case BAD_BLOCK_LENGTH: - errstr = "AES bad block length"; - break; - case BAD_CIPHER_INSTANCE: - errstr = "AES cipher instance is invalid"; - break; - case BAD_DATA: - errstr = "AES data contents are invalid"; - break; - case BAD_OTHER: - errstr = "AES unknown error"; - break; - default: - errstr = "AES error unrecognized"; - break; - } - __db_err(dbenv, errstr); - return; -} diff --git a/storage/bdb/crypto/crypto.c b/storage/bdb/crypto/crypto.c deleted file mode 100644 index 63dea986fe6..00000000000 --- a/storage/bdb/crypto/crypto.c +++ /dev/null @@ -1,394 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * Some parts of this code originally written by Adam Stubblefield - * -- astubble@rice.edu - * - * $Id: crypto.c,v 12.5 2005/07/20 16:50:56 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/crypto.h" - -/* - * __crypto_region_init -- - * Initialize crypto. - */ -int -__crypto_region_init(dbenv) - DB_ENV *dbenv; -{ - REGENV *renv; - REGINFO *infop; - CIPHER *cipher; - DB_CIPHER *db_cipher; - char *sh_passwd; - int ret; - - db_cipher = dbenv->crypto_handle; - - ret = 0; - infop = dbenv->reginfo; - renv = infop->primary; - if (renv->cipher_off == INVALID_ROFF) { - if (!CRYPTO_ON(dbenv)) - return (0); - if (!F_ISSET(infop, REGION_CREATE)) { - __db_err(dbenv, - "Joining non-encrypted environment with encryption key"); - return (EINVAL); - } - if (F_ISSET(db_cipher, CIPHER_ANY)) { - __db_err(dbenv, "Encryption algorithm not supplied"); - return (EINVAL); - } - /* - * Must create the shared information. We need: Shared cipher - * information that contains the passwd. After we copy the - * passwd, we smash and free the one in the dbenv. - */ - if ((ret = - __db_shalloc(infop, sizeof(CIPHER), 0, &cipher)) != 0) - return (ret); - memset(cipher, 0, sizeof(*cipher)); - if ((ret = __db_shalloc( - infop, dbenv->passwd_len, 0, &sh_passwd)) != 0) { - __db_shalloc_free(infop, cipher); - return (ret); - } - memset(sh_passwd, 0, dbenv->passwd_len); - cipher->passwd = R_OFFSET(infop, sh_passwd); - cipher->passwd_len = dbenv->passwd_len; - cipher->flags = db_cipher->alg; - memcpy(sh_passwd, dbenv->passwd, cipher->passwd_len); - renv->cipher_off = R_OFFSET(infop, cipher); - } else { - if (!CRYPTO_ON(dbenv)) { - __db_err(dbenv, - "Encrypted environment: no encryption key supplied"); - return (EINVAL); - } - cipher = R_ADDR(infop, renv->cipher_off); - sh_passwd = R_ADDR(infop, cipher->passwd); - if ((cipher->passwd_len != dbenv->passwd_len) || - memcmp(dbenv->passwd, sh_passwd, cipher->passwd_len) != 0) { - __db_err(dbenv, "Invalid password"); - return (EPERM); - } - if (!F_ISSET(db_cipher, CIPHER_ANY) && - db_cipher->alg != cipher->flags) { - __db_err(dbenv, - "Environment encrypted using a different algorithm"); - return (EINVAL); - } - if (F_ISSET(db_cipher, CIPHER_ANY)) - /* - * We have CIPHER_ANY and we are joining the existing - * env. Setup our cipher structure for whatever - * algorithm this env has. - */ - if ((ret = __crypto_algsetup(dbenv, db_cipher, - cipher->flags, 0)) != 0) - return (ret); - } - ret = db_cipher->init(dbenv, db_cipher); - - /* - * On success, no matter if we allocated it or are using the already - * existing one, we are done with the passwd in the dbenv. We smash - * N-1 bytes so that we don't overwrite the nul. - */ - memset(dbenv->passwd, 0xff, dbenv->passwd_len-1); - __os_free(dbenv, dbenv->passwd); - dbenv->passwd = NULL; - dbenv->passwd_len = 0; - - return (ret); -} - -/* - * __crypto_dbenv_close -- - * Crypto-specific destruction of DB_ENV structure. - * - * PUBLIC: int __crypto_dbenv_close __P((DB_ENV *)); - */ -int -__crypto_dbenv_close(dbenv) - DB_ENV *dbenv; -{ - DB_CIPHER *db_cipher; - int ret; - - ret = 0; - db_cipher = dbenv->crypto_handle; - if (dbenv->passwd != NULL) { - memset(dbenv->passwd, 0xff, dbenv->passwd_len-1); - __os_free(dbenv, dbenv->passwd); - dbenv->passwd = NULL; - } - if (!CRYPTO_ON(dbenv)) - return (0); - if (!F_ISSET(db_cipher, CIPHER_ANY)) - ret = db_cipher->close(dbenv, db_cipher->data); - __os_free(dbenv, db_cipher); - return (ret); -} - -/* - * __crypto_region_destroy -- - * Destroy any system resources allocated in the primary region. - * - * PUBLIC: int __crypto_region_destroy __P((DB_ENV *)); - */ -int -__crypto_region_destroy(dbenv) - DB_ENV *dbenv; -{ - CIPHER *cipher; - REGENV *renv; - REGINFO *infop; - - infop = dbenv->reginfo; - renv = infop->primary; - if (renv->cipher_off != INVALID_ROFF) { - cipher = R_ADDR(infop, renv->cipher_off); - __db_shalloc_free(infop, R_ADDR(infop, cipher->passwd)); - __db_shalloc_free(infop, cipher); - } - return (0); -} - -/* - * __crypto_algsetup -- - * Given a db_cipher structure and a valid algorithm flag, call - * the specific algorithm setup function. - * - * PUBLIC: int __crypto_algsetup __P((DB_ENV *, DB_CIPHER *, u_int32_t, int)); - */ -int -__crypto_algsetup(dbenv, db_cipher, alg, do_init) - DB_ENV *dbenv; - DB_CIPHER *db_cipher; - u_int32_t alg; - int do_init; -{ - int ret; - - ret = 0; - if (!CRYPTO_ON(dbenv)) { - __db_err(dbenv, "No cipher structure given"); - return (EINVAL); - } - F_CLR(db_cipher, CIPHER_ANY); - switch (alg) { - case CIPHER_AES: - db_cipher->alg = CIPHER_AES; - ret = __aes_setup(dbenv, db_cipher); - break; - default: - __db_panic(dbenv, EINVAL); - /* NOTREACHED */ - } - if (do_init) - ret = db_cipher->init(dbenv, db_cipher); - return (ret); -} - -/* - * __crypto_decrypt_meta -- - * Perform decryption on a metapage if needed. - * - * PUBLIC: int __crypto_decrypt_meta __P((DB_ENV *, DB *, u_int8_t *, int)); - */ -int -__crypto_decrypt_meta(dbenv, dbp, mbuf, do_metachk) - DB_ENV *dbenv; - DB *dbp; - u_int8_t *mbuf; - int do_metachk; -{ - DB_CIPHER *db_cipher; - DB dummydb; - DBMETA *meta; - size_t pg_off; - int ret; - u_int8_t *iv; - - /* - * If we weren't given a dbp, we just want to decrypt the page on - * behalf of some internal subsystem, not on behalf of a user with - * a dbp. Therefore, set up a dummy dbp so that the call to - * P_OVERHEAD below works. - */ - if (dbp == NULL) { - memset(&dummydb, 0, sizeof(DB)); - dbp = &dummydb; - } - - ret = 0; - meta = (DBMETA *)mbuf; - - /* - * !!! - * We used an "unused" field in the meta-data page to flag whether or - * not the database is encrypted. Unfortunately, that unused field - * was used in Berkeley DB releases before 3.0 (for example, 2.7.7). - * It would have been OK, except encryption doesn't follow the usual - * rules of "upgrade before doing anything else", we check encryption - * before checking for old versions of the database. - * - * We don't have to check Btree databases -- before 3.0, the field of - * interest was the bt_maxkey field (which was never supported and has - * since been removed). - * - * Ugly check to jump out if this format is older than what we support. - * It assumes no encrypted page will have an unencrypted magic number, - * but that seems relatively safe. [#10920] - */ - if (meta->magic == DB_HASHMAGIC && meta->version <= 5) - return (0); - - /* - * Meta-pages may be encrypted for DBMETASIZE bytes. If we have a - * non-zero IV (that is written after encryption) then we decrypt (or - * error if the user isn't set up for security). We guarantee that - * the IV space on non-encrypted pages will be zero and a zero-IV is - * illegal for encryption. Therefore any non-zero IV means an - * encrypted database. This basically checks the passwd on the file - * if we cannot find a good magic number. We walk through all the - * algorithms we know about attempting to decrypt (and possibly - * byteswap). - * - * !!! - * All method meta pages have the IV and checksum at the exact same - * location, but not in DBMETA, use BTMETA. - */ - if (meta->encrypt_alg != 0) { - db_cipher = (DB_CIPHER *)dbenv->crypto_handle; - if (!F_ISSET(dbp, DB_AM_ENCRYPT)) { - if (!CRYPTO_ON(dbenv)) { - __db_err(dbenv, - "Encrypted database: no encryption flag specified"); - return (EINVAL); - } - /* - * User has a correct, secure env, but has encountered - * a database in that env that is secure, but user - * didn't dbp->set_flags. Since it is existing, use - * encryption if it is that way already. - */ - F_SET(dbp, DB_AM_ENCRYPT|DB_AM_CHKSUM); - } - /* - * This was checked in set_flags when DB_AM_ENCRYPT was set. - * So it better still be true here. - */ - DB_ASSERT(CRYPTO_ON(dbenv)); - if (!F_ISSET(db_cipher, CIPHER_ANY) && - meta->encrypt_alg != db_cipher->alg) { - __db_err(dbenv, - "Database encrypted using a different algorithm"); - return (EINVAL); - } - DB_ASSERT(F_ISSET(dbp, DB_AM_CHKSUM)); - iv = ((BTMETA *)mbuf)->iv; - /* - * For ALL pages, we do not encrypt the beginning of the page - * that contains overhead information. This is true of meta - * and all other pages. - */ - pg_off = P_OVERHEAD(dbp); -alg_retry: - /* - * If they asked for a specific algorithm, then - * use it. Otherwise walk through those we know. - */ - if (!F_ISSET(db_cipher, CIPHER_ANY)) { - if (do_metachk && (ret = db_cipher->decrypt(dbenv, - db_cipher->data, iv, mbuf + pg_off, - DBMETASIZE - pg_off))) - return (ret); - if (((BTMETA *)meta)->crypto_magic != - meta->magic) { - __db_err(dbenv, "Invalid password"); - return (EINVAL); - } - /* - * Success here. The algorithm asked for and the one - * on the file match. We've just decrypted the meta - * page and checked the magic numbers. They match, - * indicating the password is right. All is right - * with the world. - */ - return (0); - } - /* - * If we get here, CIPHER_ANY must be set. - */ - ret = __crypto_algsetup(dbenv, db_cipher, meta->encrypt_alg, 1); - goto alg_retry; - } else if (F_ISSET(dbp, DB_AM_ENCRYPT)) { - /* - * They gave us a passwd, but the database is not encrypted. - * This is an error. We do NOT want to silently allow them - * to write data in the clear when the user set up and expects - * encrypted data. - * - * This covers at least the following scenario. - * 1. User creates and sets up an encrypted database. - * 2. Attacker cannot read the actual data in the database - * because it is encrypted, but can remove/replace the file - * with an empty, unencrypted database file. - * 3. User sets encryption and we get to this code now. - * If we allowed the file to be used in the clear since - * it is that way on disk, the user would unsuspectingly - * write sensitive data in the clear. - * 4. Attacker reads data that user thought was encrypted. - * - * Therefore, asking for encryption with a database that - * was not encrypted is an error. - */ - __db_err(dbenv, - "Unencrypted database with a supplied encryption key"); - return (EINVAL); - } - return (ret); -} - -/* - * __crypto_set_passwd -- - * Get the password from the shared region; and set it in a new - * environment handle. Use this to duplicate environment handles. - * - * PUBLIC: int __crypto_set_passwd __P((DB_ENV *, DB_ENV *)); - */ -int -__crypto_set_passwd(dbenv_src, dbenv_dest) - DB_ENV *dbenv_src, *dbenv_dest; -{ - CIPHER *cipher; - REGENV *renv; - REGINFO *infop; - char *sh_passwd; - int ret; - - ret = 0; - infop = dbenv_src->reginfo; - renv = infop->primary; - - DB_ASSERT(CRYPTO_ON(dbenv_src)); - - cipher = R_ADDR(infop, renv->cipher_off); - sh_passwd = R_ADDR(infop, cipher->passwd); - return (__env_set_encrypt(dbenv_dest, sh_passwd, DB_ENCRYPT_AES)); -} diff --git a/storage/bdb/crypto/crypto.html b/storage/bdb/crypto/crypto.html deleted file mode 100644 index 7d2804b43b4..00000000000 --- a/storage/bdb/crypto/crypto.html +++ /dev/null @@ -1,639 +0,0 @@ -<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> - <meta name="GENERATOR" content="Mozilla/4.76 [en] (X11; U; FreeBSD 4.3-RELEASE i386) [Netscape]"> -</head> -<body> - -<center> -<h1> - Security Interface for Berkeley DB</h1></center> - -<center><i>Susan LoVerso</i> -<br><i>sue@sleepycat.com</i> -<br><i>Rev 1.6</i> -<br><i>2002 Feb 26</i></center> - -<p>We provide an interface allowing secure access to Berkeley DB. -Our goal is to allow users to have encrypted secure databases. In -this document, the term <i>ciphering</i> means the act of encryption or -decryption. They are equal but opposite actions and the same issues -apply to both just in the opposite direction. -<h3> -Requirements</h3> -The overriding requirement is to provide a simple mechanism to allow users -to have a secure database. A secure database means that all of the -pages of a database will be encrypted, and all of the log files will be -encrypted. -<p>Falling out from this work will be a simple mechanism to allow users -to request that we checksum their data for additional error detection (without -encryption/decryption). -<p>We expect that data in process memory or stored in shared memory, potentially -backed by disk, is not encrypted or secure. -<h2> -<a NAME="DB Modifications"></a>DB Method Interface Modifications</h2> -With a logging environment, all database changes are recorded in the log -files. Therefore, users requiring secure databases in such environments -also require secure log files. -<p>A prior thought had been to allow different passwords on the environment -and the databases within. However, such a scheme, then requires that -the password be logged in order for recovery to be able to restore the -database. Therefore, any application having the password for the -log could get the password for any databases by reading the log. -So having a different password on a database does not gain any additional -security and it makes certain things harder and more complex. Some -of those more complex things include the need to handle database and env -passwords differently since they'd need to be stored and accessed from -different places. Also resolving the issue of how <i>db_checkpoint</i> -or <i>db_sync</i>, which flush database pages to disk, would find the passwords -of various databases without any dbps was unsolved. The feature didn't -gain anything and caused significant pain. Therefore the decision -is that there will be a single password protecting an environment and all -the logs and some databases within that environment. We do allow -users to have a secure environment and clear databases. Users that -want secure databases within a secure environment must set a flag. -<p>Users wishing to enable encryption on a database in a secure environment -or enable just checksumming on their database pages will use new flags -to <a href="../docs/api_c/db_set_flags.html">DB->set_flags()</a>. -Providing ciphering over an entire environment is accomplished by adding -a single environment method: <a href="../docs/api_c/env_set_encrypt.html">DBENV->set_encrypt()</a>. -Providing encryption for a database (not part of an environment) is accomplished -by adding a new database method: <a href="../docs/api_c/db_set_encrypt.html">DB->set_encrypt()</a>. -<p>Both of the <i>set_encrypt</i> methods must be called before their respective -<i>open</i> calls. The environment method must be before the environment -open because we must know about security before there is any possibility -of writing any log records out. The database method must be before -the database open in order to read the root page. The planned interfaces -for these methods are: -<pre>DBENV->set_encrypt(DBENV *dbenv, /* DB_ENV structure */ - char *passwd /* Password */ - u_int32_t flags); /* Flags */</pre> - -<pre>DB->set_encrypt(DB *dbp, /* DB structure */ - char *passwd /* Password */ - u_int32_t flags); /* Flags */</pre> -The flags accepted by these functions are: -<pre>#define DB_ENCRYPT_AES 0x00000001 /* Use the AES encryption algorithm */</pre> -Passwords are NULL-terminated strings. NULL or zero length strings -are illegal. These flags enable the checksumming and encryption using -the particular algorithms we have chosen for this implementation. -The flags are named such that there is a logical naming pattern if additional -checksum or encryption algorithms are used. If a user gives a flag of zero, -it will behave in a manner similar to DB_UNKNOWN. It will be illegal if -they are creating the environment or database, as an algorithm must be -specified. If they are joining an existing environment or opening an existing -database, they will use whatever algorithm is in force at the time. -Using DB_ENCRYPT_AES automatically implies SHA1 checksumming. -<p>These functions will perform several initialization steps. We -will allocate crypto_handle for our env handle and set up our function -pointers. We will allocate space and copy the password into our env -handle password area. Similar to <i>DB->set_cachesize</i>, calling -<i>DB->set_encrypt</i> -will actually reflect back into the local environment created by DB. -<p>Lastly, we will add a new flag, DB_OVERWRITE, to the <a href="../docs/api_c/env_remove.html">DBENV->remove</a> -method. The purpose of this flag is to force all of the memory used -by the shared regions to be overwritten before removal. We will use -<i>rm_overwrite</i>, -a function that overwrites and syncs a file 3 times with varying bit patterns -to really remove a file. Additionally, this flag will force a sync -of the overwritten regions to disk, if the regions are backed by the file -system. That way there is no residual information left in the clear -in memory or freed disk blocks. Although we expect that this flag -will be used by customers using security, primarily, its action is not -dependent on passwords or a secure setup, and so can be used by anyone. -<h4> -Initialization of the Environment</h4> -The setup of the security subsystem will be similar to replication initialization -since it is a sort of subsystem, but it does not have its own region. -When the environment handle is created via <i>db_env_create</i>, we initialize -our <i>set_encrypt</i> method to be the RPC or local version. Therefore -the <i>DB_ENV</i> structure needs a new pointer: -<pre> void *crypto_handle; /* Security handle */</pre> -The crypto handle will really point to a new <i>__db_cipher</i> structure -that will contain a set of functions and a pointer to the in-memory information -needed by the specific encryption algorithm. It will look like: -<pre>typedef struct __db_cipher { - int (*init)__P((...)); /* Alg-specific initialization function */ - int (*encrypt)__P((...)); /* Alg-specific encryption algorithm */ - int (*decrypt)__P((...)); /* Alg-specific decryption function */ - void *data; /* Pointer to alg-specific information (AES_CIPHER) */ - u_int32_t flags; /* Cipher flags */ -} DB_CIPHER;</pre> - -<pre>#define DB_MAC_KEY 20 /* Size of the MAC key */ -typedef struct __aes_cipher { - keyInstance encrypt_ki; /* Encrypt keyInstance temp. */ - keyInstance decrypt_ki; /* Decrypt keyInstance temp. */ - u_int8_t mac_key[DB_MAC_KEY]; /* MAC key */ - u_int32_t flags; /* AES-specific flags */ -} AES_CIPHER;</pre> -It should be noted that none of these structures have their own mutex. -We hold the environment region locked while we are creating this, but once -this is set up, it is read-only forever. -<p>During <a href="../docs/api_c/env_set_encrypt.html">dbenv->set_encrypt</a>, -we set the encryption, decryption and checksumming methods to the appropriate -functions based on the flags. This function will allocate us a crypto -handle that we store in the <i>DB_ENV</i> structure just like all the -other subsystems. For now, only AES ciphering functions and SHA1 -checksumming functions are supported. Also we will copy the password -into the <i>DB_ENV</i> structure. We ultimately need to keep the -password in the environment's shared memory region or compare this one -against the one that is there, if we are joining an existing environment, -but we do not have it yet because open has not yet been called. We -will allocate a structure that will be used in initialization and set up -the function pointers to point to the algorithm-specific functions. -<p>In the <i>__env_open</i> path, in <i>__db_e_attach</i>, if we -are creating the region and the <i>dbenv->passwd</i> field is set, we need -to use the length of the password in the initial computation of the environment's -size. This guarantees sufficient space for storing the password in -shared memory. Then we will call a new function to initialize the -security region, <i>__crypto_region_init</i> in <i>__env_open</i>. -If we are the creator, we will allocate space in the shared region to store -the password and copy the password into that space. Or, if we are -not the creator we will compare the password stored in the dbenv with the -one in shared memory. Additionally, we will compare the ciphering -algorithm to the one stored in the shared region.We'll smash the dbenv -password and free it. If they do not match, we return an error. -If we are the creator we store the offset into the REGENV structure. -Then <i>__crypto_region_init </i> will call the initialization function -set up earlier based on the ciphering algorithm specified. For now -we will call <i>__aes_init</i>. Additionally this function will allocate -and set up the per-process state vector for this encryption's IVs. -See <a href="#Generating the Initialization Vector">Generating the Initialization -Vector</a> for a detailed description of the IV and state vector. -<p>In the AES-specific initialization function, <i>__aes_init</i>, -we will initialize it by calling -<i>__aes_derivekeys</i> in order to fill -in the keyInstance and mac_key fields in that structure. The REGENV -structure will have one additional item -<pre> roff_t passwd_off; /* Offset of passwd */</pre> - -<h4> -Initializing a Database</h4> -During <a href="../docs/api_c/db_set_encrypt.html">db->set_encrypt</a>, -we set the encryption, decryption and checksumming methods to the appropriate -functions based on the flags. Basically, we test that we are not -in an existing environment and we haven't called open. Then we just -call through the environment handle to set the password. -<p>Also, we will need to add a flag in the database meta-data page that -indicates that the database is encrypted and what its algorithm is. -This will be used when the meta-page is read after reopening a file. We -need this information on the meta-page in order to detect a user opening -a secure database without a password. I propose using the first unused1 -byte (renaming it too) in the meta page for this purpose. -<p>All pages will not be encrypted for the first 64 bytes of data. -Database meta-pages will be encrypted on the first 512 bytes only. -All meta-page types will have an IV and checksum added within the first -512 bytes as well as a crypto magic number. This will expand the -size of the meta-page from 256 bytes to 512 bytes. The page in/out routines, -<i>__db_pgin</i> and <i>__db_pgout</i> know the page type of the page and -will apply the 512 bytes ciphering to meta pages. In <i>__db_pgout</i>, -if we have a crypto handle in our (private) environment, we will apply -ciphering to either the entire page, or the first 512 bytes if it is a -meta-page. In <i>__db_pgin</i>, we will decrypt if the page we have -a crypto handle. -<p>When multiple processes share a database, all must use the same password -as the database creator. Using an existing database requires several conditions -to be true. First, if the creator of the database did not create -with security, then opening later with security is an error. Second, -if the creator did create it with security, then opening later without -security is an error. Third, we need to be able to test and check -that when another process opens a secure database that the password they -provided is the same as the one in use by the creator. -<p>When reading the meta-page, in <i>__db_file_setup</i>, we do not go -through the paging functions, but directly read via <i>__os_read</i>. -It is at this point that we will determine if the user is configured correctly. -If the meta-page we read has an IV and checksum, they better have a crypto -handle. If they have a crypto handle, then the meta-page must have -an IV and checksum. If both of those are true, we test the password. -We compare the unencrypted magic number to the newly-decrypted crypto magic -number and if they are not the same, then we report that the user gave -us a bad password. -<p>On a mostly unrelated topic, even when we go to very large pagesizes, -the meta information will still be within a disk sector. So, after -talking it over with Keith and Margo, we determined that unencrypted meta-pages -still will not need a checksum. -<h3> -Encryption and Checksum Routines</h3> -These routines are provided to us by Adam Stubblefield at Rice University -(astubble@rice.edu). The functional interfaces are: -<pre>__aes_derivekeys(DB_ENV *dbenv, /* dbenv */ - u_int8_t *passwd, /* Password */ - size_t passwd_len, /* Length of passwd */ - u_int8_t *mac_key, /* 20 byte array to store MAC key */ - keyInstance *encrypt_key, /* Encryption key of passwd */ - keyInstance *decrypt_key); /* Decryption key of passwd */</pre> -This is the only function requiring the textual user password. From -the password, this function generates a key used in the checksum function, -<i>__db_chksum</i>. -It also fills in <i>keyInstance</i> structures which are then used in the -encryption and decryption routines. The keyInstance structures must -already be allocated. These will be stored in the AES_CIPHER structure. -<pre> __db_chksum(u_int8_t *data, /* Data to checksum */ - size_t data_len, /* Length of data */ - u_int8_t *mac_key, /* 20 byte array from __db_derive_keys */ - u_int8_t *checksum); /* 20 byte array to store checksum */</pre> -This function generates a checksum on the data given. This function -will do double-duty for users that simply want error detection on their -pages. When users are using encryption, the <i>mac_key </i>will contain -the 20-byte key set up in <i>__aes_derivekeys</i>. If they just want -checksumming, then <i>mac_key</i> will be NULL. According to Adam, -we can safely use the first N-bytes of the checksum. So for seeding -the generator for initialization vectors, we'll hash the time and then -send in the first 4 bytes for the seed. I believe we can probably -do the same thing for checksumming log records. We can only use 4 -bytes for the checksum in the non-secure case. So when we want to -verify the log checksum we can compute the mac but just compare the first -4 bytes to the one we read. All locations where we generate or check -log record checksums that currently call <i>__ham_func4</i> will now call -<i>__db_chksum</i>. -I believe there are 5 such locations, -<i>__log_put, __log_putr, __log_newfile, -__log_rep_put -</i>and<i> __txn_force_abort.</i> -<pre>__aes_encrypt(DB_ENV *dbenv, /* dbenv */ - keyInstance *key, /* Password key instance from __db_derive_keys */ - u_int8_t *iv, /* Initialization vector */ - u_int8_t *data, /* Data to encrypt */ - size_t data_len); /* Length of data to encrypt - 16 byte multiple */</pre> -This is the function to encrypt data. It will be called to encrypt -pages and log records. The <i>key</i> instance is initialized in -<i>__aes_derivekeys</i>. -The initialization vector, <i>iv</i>, is the 16 byte random value set up -by the Mersenne Twister pseudo-random generator. Lastly, we pass -in a pointer to the <i>data</i> to encrypt and its length in <i>data_len</i>. -The <i>data_len</i> must be a multiple of 16 bytes. The encryption is done -in-place so that when the encryption code returns our encrypted data is -in the same location as the original data. -<pre>__aes_decrypt(DB_ENV *dbenv, /* dbenv */ - keyInstance *key, /* Password key instance from __db_derive_keys */ - u_int8_t *iv, /* Initialization vector */ - u_int8_t *data, /* Data to decrypt */ - size_t data_len); /* Length of data to decrypt - 16 byte multiple */</pre> -This is the function to decrypt the data. It is exactly the same -as the encryption function except for the action it performs. All -of the args and issues are the same. It also decrypts in place. -<h3> -<a NAME="Generating the Initialization Vector"></a>Generating the Initialization -Vector</h3> -Internally, we need to provide a unique initialization vector (IV) of 16 -bytes every time we encrypt any data with the same password. For -the IV we are planning on using mt19937, the Mersenne Twister, a random -number generator that has a period of 2**19937-1. This package can be found -at <a href="http://www.math.keio.ac.jp/~matumoto/emt.html">http://www.math.keio.ac.jp/~matumoto/emt.html</a>. -Tests show that although it repeats a single integer every once in a while, -that after several million iterations, it doesn't repeat any 4 integers -that we'd be stuffing into our 16-byte IV. We plan on seeding this -generator with the time (tv_sec) hashed through SHA1 when we create the -environment. This package uses a global state vector that contains -624 unsigned long integers. We do not allow a 16-byte IV of zero. -It is simpler just to reject any 4-byte value of 0 and if we get one, just -call the generator again and get a different number. We need to detect -holes in files and if we read an IV of zero that is a simple indication -that we need to check for an entire page of zero. The IVs are stored -on the page after encryption and are not encrypted themselves so it is -not possible for an entire encrypted page to be read as all zeroes, unless -it was a hole in a file. See <a href="#Holes in Files">Holes in Files</a> -for more details. -<p>We will not be holding any locks when we need to generate our IV but -we need to protect access to the state vector and the index. Calls -to the MT code will come while encrypting some data in <i>__aes_encrypt.</i> -The MT code will assume that all necessary locks are held in the caller. -We will have per-process state vectors that are set up when a process begins. -That way we minimize the contention and only multi-threaded processes need -acquire locks for the IV. We will have the state vector in the environment -handle in heap memory, as well as the index and there will be a mutex protecting -it for threaded access. This will be added to the <i>DB_ENV</i> -structure: -<pre> DB_MUTEX *mt_mutexp; /* Mersenne Twister mutex */ - int *mti; /* MT index */ - u_long *mt; /* MT state vector */</pre> -This portion of the environment will be initialized at the end of _<i>_dbenv_open</i>, -right after we initialize the other mutex for the <i>dblist</i>. When we -allocate the space, we will generate our initial state vector. If we are -multi-threaded we'll allocate and initialize our mutex also. -<p>We need to make changes to the MT code to make it work in our namespace -and to take a pointer to the location of the state vector and -the index. There will be a wrapper function <i>__db_generate_iv</i> -that DB will call and it will call the appropriate MT function. I -am also going to change the default seed to use a hashed time instead of -a hard coded value. I have looked at other implementations of the -MT code available on the web site. The C++ version does a hash on -the current time. I will modify our MT code to seed with the hashed -time as well. That way the code to seed is contained within the MT -code and we can just write the wrapper to get an IV. We will not -be changing the core computational code of MT. -<h2> -DB Internal Issues</h2> - -<h4> -When do we Cipher?</h4> -All of the page ciphering is done in the <i>__db_pgin/__db_pgout</i> functions. -We will encrypt after the method-specific function on page-out and decrypt -before the method-specfic function on page-in. We do not hold any -locks when entering these functions. We determine that we need to -cipher based on the existence of the encryption flag in the dbp. -<p>For ciphering log records, the encryption will be done as the first -thing (or a new wrapper) in <i>__log_put. </i>See <a href="#Log Record Encryption">Log -Record Encryption</a> for those details. -<br> -<h4> -Page Changes</h4> -The checksum and IV values will be stored prior to the first index of the -page. We have a new P_INP macro that replaces use of inp[X] in the -code. This macro takes a dbp as an argument and determines where -our first index is based on whether we have DB_AM_CHKSUM and DB_AM_ENCRYPT -set. If neither is set, then our first index is where it always was. - If just checksumming is set, then we reserve a 4-byte checksum. -If encryption is set, then we reserve 36 bytes for our checksum/IV as well -as some space to get proper alignment to encrypt on a 16-byte boundary. -<p>Since several paging macros use inp[X] in them, those macros must now -take a dbp. There are a lot of changes to make all the necessary -paging macros take a dbp, although these changes are trivial in nature. -<p>Also, there is a new function <i>__db_chk_meta</i> to perform checksumming -and decryption checking on meta pages specifically. This function -is where we check that the database algorithm matches what the user gave -(or if they set DB_CIPHER_ANY then we set it), and other encryption related -testing for bad combinations of what is in the file versus what is in the -user structures. -<h4> -Verification</h4> -The verification code will also need to be updated to deal with secure -pages. Basically when the verification code reads in the meta page -it will call <i>__db_chk_meta</i> to perform any checksumming and decryption. -<h4> -<a NAME="Holes in Files"></a>Holes in Files</h4> -Holes in files will be dealt with rather simply. We need to be able -to distinguish reading a hole in a file from an encrypted page that happened -to encrypt to all zero's. If we read a hole in a file, we do not -want to send that empty page through the decryption routine. This -can be determined simply without incurring the performance penalty of comparing -every byte on a page on every read until we get a non-zero byte. -<br>The __db_pgin function is only given an invalid page P_INVALID in this -case. So, if the page type, which is always unencrypted, is -P_INVALID, then we do not perform any checksum verification or decryption. -<h4> -Errors and Recovery</h4> -Dealing with a checksum error is tricky. Ultimately, if a checksum -error occurs it is extremely likely that the user must do catastrophic -recovery. There is no other failure return other than DB_RUNRECOVERY -for indicating that the user should run catastrophic recovery. We -do not want to add a new error return for applications to check because -a lot of applications already look for and deal with DB_RUNRECOVERY as -an error condition and we want to fit ourselves into that application model. -We already indicate to the user that when they get that error, then they -need to run recovery. If recovery fails, then they need to run catastrophic -recovery. We need to get ourselves to the point where users will -run catastrophic recovery. -<p>If we get a checksum error, then we need to log a message stating a -checksum error occurred on page N. In <i>__db_pgin</i>, we can check -if logging is on in the environment. If so, we want to log the message. -<p>When the application gets the DB_RUNRECOVERY error, they'll have to -shut down their application and run recovery. When the recovery encounters -the record indicating checksum failure, then normal recovery will fail -and the user will have to perform catastrophic recovery. When catastrophic -recovery encounters that record, it will simply ignore it. -<h4> -<a NAME="Log Record Encryption"></a>Log Record Encryption</h4> -Log records will be ciphered. It might make sense to wrap <i>__log_put</i> -to encrypt the DBT we send down. The <i>__log_put </i>function is -where the checksum is computed before acquiring the region lock. -But also this function is where we call <i>__rep_send_message</i> to send -the DBT to the replication clients. Therefore, we need the DBT to -be encrypted prior to there. We also need it encrypted before checksumming. -I think <i>__log_put </i>will become <i>__log_put_internal</i>, and the -new <i>__log_put</i> will encrypt if needed and then call <i>__log_put_internal -</i>(the -function formerly known as <i>__log_put</i>). Log records are kept -in a shared memory region buffer prior to going out to disk. Records -in the buffer will be encrypted. No locks are held at the time we -will need to encrypt. -<p>On reading the log, via log cursors, the log code stores log records -in the log buffer. Records in that buffer will be encrypted, so decryption -will occur no matter whether we are returning records from the buffer or -if we are returning log records directly from the disk. Current checksum -checking is done in -<i>__log_get_c_int.</i> Decryption will be done -after the checksum is checked. -<p>There are currently two nasty issues with encrypted log records. -The first is that <i>__txn_force_abort</i> overwrites a commit record in -the log buffer with an abort record. Well, our log buffer will be -encrypted. Therefore, <i>__txn_force_abort</i> is going to need to -do encryption of its new record. This can be accomplished by sending -in the dbenv handle to the function. It is available to us in <i>__log_flush_commit</i> -and we can just pass it in. I don't like putting log encryption in -the txn code, but the layering violation is already there. -<p>The second issue is that the encryption code requires data that is a -multiple of 16 bytes and log record lengths are variable. We will -need to pad log records to meet the requirement. Since the callers -of <i>__log_put</i> set up the given DBT it is a logical place to pad if -necessary. We will modify the gen_rec.awk script to have all of the generated -logging functions pad for us if we have a crypto handle. This padding will -also expand the size of log files. Anyone calling <i>log_put</i> and using -security from the application will have to pad on their own or it will -return an error. -<p>When ciphering the log file, we will need a different header than the -current one. The current header only has space for a 4 byte checksum. -Our secure header will need space for the 16 byte IV and 20 byte checksum. -This will blow up our log files when running securely since every single -log record header will now consume 32 additional bytes. I believe -that the log header does not need to be encrypted. It contains an -offset, a length and our IV and checksum. Our IV and checksum are -never encrypted. I don't believe there to be any risk in having the -offset and length in the clear. -<p>I would prefer not to have two types of log headers that are incompatible -with each other. It is not acceptable to increase the log headers -of all users from 12 bytes to 44 bytes. Such a change would also -make log files incompatible with earlier releases. Worse even, is -that the <i>cksum</i> field of the header is in between the offset and -len. It would be really convenient if we could have just made a bigger -cksum portion without affecting the location of the other fields. -Oh well. Most customers will not be using encryption and we won't -make them pay the price of the expanded header. Keith indicates that -the log file format is changing with the next release so I will move the -cksum field so it can at least be overlaid. -<p>One method around this would be to have a single internal header that -contains all the information both mechanisms need, but when we write out -the header we choose which pieces to write. By appending the security -information to the end of the existing structure, and adding a size field, -we can modify a few places to use the size field to write out only the -current first 12 bytes, or the entire security header needed. -<h4> -Replication</h4> -Replication clients are going to need to start all of their individual -environment handles with the same password. The log records are going -to be sent to the clients decrypted and the clients will have to encrypt -them on their way to the client log files. We cannot send encrypted -log records to clients. The reason is that the checksum and IV are -stored in the log header and the master only sends the log record itself -to the client. Therefore, the client has no way to decrypt a log -record from the master. Therefore, anyone wanting to use truly secure -replication is going to have to have a secure transport mechanism. -By not encrypting records, clients can theoretically have different passwords -and DB won't care. -<p>On the master side we must copy the DBT sent in. We encrypt the -original and send to clients the clear record. On the client side, -support for encryption is added into <i>__log_rep_put</i>. -<h4> -Sharing the Environment</h4> -When multiple processes join the environment, all must use the same password -as the creator. -<p>Joining an existing environment requires several conditions to be true. -First, if the creator of the environment did not create with security, -then joining later with security is an error. Second, if the creator -did create it with security, then joining later without security is an -error. Third, we need to be able to test and check that when another -process joins a secure environment that the password they provided is the -same as the one in use by the creator. -<p>The first two scenarios should be fairly trivial to determine, if we -aren't creating the environment, we can compare what is there with what -we have. In the third case, the <i>__crypto_region_init</i> function -will see that the environment region has a valid passwd_off and we'll then -compare that password to the one we have in our dbenv handle. In -any case we'll smash the dbenv handle's passwd and free that memory before -returning whether we have a password match or not. -<p>We need to store the passwords themselves in the region because multiple -calls to the <i>__aes_derivekeys </i>function with the same password yields -different keyInstance contents. Therefore we don't have any way to -check passwords other than retaining and comparing the actual passwords. -<h4> -Other APIs</h4> -All of the other APIs will need interface enhancements to support the new -security methods. The Java and C++ interfaces will likely be done -by Michael Cahill and Sue will implement the Tcl and RPC changes. -Tcl will need the changes for testing purposes but the interface should -be public, not test-only. RPC should fully support security. -The biggest risk that I can see is that the client will send the password -to the server in the clear. Anyone sniffing the wires or running -tcpdump or other packet grabbing code could grab that. Someone really -interested in using security over RPC probably ought to add authentication -and other measures to the RPC server as well. -<h4> -<a NAME="Utilities"></a>Utilities</h4> -All should take a -P flag to specify a password for the environment or -password. Those that take an env and a database might need something -more to distinguish between env passwds and db passwds. Here is what we -do for each utility: -<ul> -<li> -berkeley_db_svc - Needs -P after each -h specified.</li> - -<li> -db_archive - Needs -P if the env is encrypted.</li> - -<li> -db_checkpoint - Needs -P if the env is encrypted.</li> - -<li> -db_deadlock - No changes</li> - -<li> -db_dump - Needs -P if the env or database is encrypted.</li> - -<li> -db_load - Needs -P if the env or database is encrypted.</li> - -<li> -db_printlog - Needs -P if the env is encrypted.</li> - -<li> -db_recover - Needs -P if the env is encrypted.</li> - -<li> -db_stat - Needs -P if the env or database is encrypted.</li> - -<li> -db_upgrade - Needs -P if the env or database is encrypted.</li> - -<li> -db_verify - Needs -P if the env or database is encrypted.</li> -</ul> - -<h2> -Testing</h2> -All testing should be able to be accomplished via Tcl. The following -tests (and probably others I haven't thought of yet) should be performed: -<ul> -<li> -Basic functionality - basically a test001 but encrypted without an env</li> - -<li> -Basic functionality, w/ env - like the previous test but with an env.</li> - -<li> -Basic functionality, multiple processes - like first test, but make sure -others can correctly join.</li> - -<li> -Basic functionality, mult. processes - like above test, but initialize/close -environment/database first so that the next test processes are all joiners -of an existing env, but creator no longer exists and the shared region -must be opened.</li> - -<li> -Recovery test - Run recovery over an encrypted environment.</li> - -<li> -Subdb test - Run with subdbs that are encrypted.</li> - -<li> -Utility test - Verify the new options to all the utilities.</li> - -<li> -Error handling - Test the basic setup errors for both env's and databases -with multiple processes. They are:</li> - -<ol> -<li> -Attempt to set a NULL or zero-length passwd.</li> - -<li> -Create Env w/ security and attempt to create database w/ its own password.</li> - -<li> -Env/DB creates with security. Proc2 joins without - should get an -error.</li> - -<li> -Env/DB creates without security. Proc2 joins with - should get an -error.</li> - -<li> -Env/DB creates with security. Proc2 joins with different password -- should get an error.</li> - -<li> -Env/DB creates with security. Closes. Proc2 reopens with different -password - should get an error.</li> - -<li> -Env/DB creates with security. Closes. Tcl overwrites a page -of the database with garbage. Proc2 reopens with the correct password. -Code should detect checksum error.</li> - -<li> -Env/DB creates with security. Open a 2nd identical DB with a different -password. Put the exact same data into both databases. Close. -Overwrite the identical page of DB1 with the one from DB2. Reopen -the database with correct DB1 password. Code should detect an encryption -error on that page.</li> -</ol> -</ul> - -<h2> -Risks</h2> -There are several holes in this design. It is important to document -them clearly. -<p>The first is that all of the pages are stored in memory and possibly -the file system in the clear. The password is stored in the shared -data regions in the clear. Therefore if an attacker can read the -process memory, they can do whatever they want. If the attacker can -read system memory or swap they can access the data as well. Since -everything in the shared data regions (with the exception of the buffered -log) will be in the clear, it is important to realize that file backed -regions will be written in the clear, including the portion of the regions -containing passwords. We recommend to users that they use system -memory instead of file backed shared memory. -</body> -</html> diff --git a/storage/bdb/crypto/mersenne/mt19937db.c b/storage/bdb/crypto/mersenne/mt19937db.c deleted file mode 100644 index 1dad5f6ad12..00000000000 --- a/storage/bdb/crypto/mersenne/mt19937db.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * $Id: mt19937db.c,v 12.1 2005/07/20 16:50:57 bostic Exp $ - */ -#include "db_config.h" - -#include "db_int.h" -#include "dbinc/crypto.h" -#include "dbinc/hmac.h" - -/* A C-program for MT19937: Integer version (1999/10/28) */ -/* genrand() generates one pseudorandom unsigned integer (32bit) */ -/* which is uniformly distributed among 0 to 2^32-1 for each */ -/* call. sgenrand(seed) sets initial values to the working area */ -/* of 624 words. Before genrand(), sgenrand(seed) must be */ -/* called once. (seed is any 32-bit integer.) */ -/* Coded by Takuji Nishimura, considering the suggestions by */ -/* Topher Cooper and Marc Rieffel in July-Aug. 1997. */ - -/* This library is free software under the Artistic license: */ -/* see the file COPYING distributed together with this code. */ -/* For the verification of the code, its output sequence file */ -/* mt19937int.out is attached (2001/4/2) */ - -/* Copyright (C) 1997, 1999 Makoto Matsumoto and Takuji Nishimura. */ -/* Any feedback is very welcome. For any question, comments, */ -/* see http://www.math.keio.ac.jp/matumoto/emt.html or email */ -/* matumoto@math.keio.ac.jp */ - -/* REFERENCE */ -/* M. Matsumoto and T. Nishimura, */ -/* "Mersenne Twister: A 623-Dimensionally Equidistributed Uniform */ -/* Pseudo-Random Number Generator", */ -/* ACM Transactions on Modeling and Computer Simulation, */ -/* Vol. 8, No. 1, January 1998, pp 3--30. */ - -/* Period parameters */ -#define N 624 -#define M 397 -#define MATRIX_A 0x9908b0df /* constant vector a */ -#define UPPER_MASK 0x80000000 /* most significant w-r bits */ -#define LOWER_MASK 0x7fffffff /* least significant r bits */ - -/* Tempering parameters */ -#define TEMPERING_MASK_B 0x9d2c5680 -#define TEMPERING_MASK_C 0xefc60000 -#define TEMPERING_SHIFT_U(y) (y >> 11) -#define TEMPERING_SHIFT_S(y) (y << 7) -#define TEMPERING_SHIFT_T(y) (y << 15) -#define TEMPERING_SHIFT_L(y) (y >> 18) - -static void __db_sgenrand __P((unsigned long, unsigned long *, int *)); -#ifdef NOT_USED -static void __db_lsgenrand __P((unsigned long *, unsigned long *, int *)); -#endif -static unsigned long __db_genrand __P((DB_ENV *)); - -/* - * __db_generate_iv -- - * Generate an initialization vector (IV) - * - * PUBLIC: int __db_generate_iv __P((DB_ENV *, u_int32_t *)); - */ -int -__db_generate_iv(dbenv, iv) - DB_ENV *dbenv; - u_int32_t *iv; -{ - int i, n, ret; - - ret = 0; - n = DB_IV_BYTES / sizeof(u_int32_t); - MUTEX_LOCK(dbenv, dbenv->mtx_mt); - if (dbenv->mt == NULL) { - if ((ret = __os_calloc(dbenv, 1, N*sizeof(unsigned long), - &dbenv->mt)) != 0) - return (ret); - /* mti==N+1 means mt[N] is not initialized */ - dbenv->mti = N + 1; - } - for (i = 0; i < n; i++) { - /* - * We do not allow 0. If we get one just try again. - */ - do { - iv[i] = (u_int32_t)__db_genrand(dbenv); - } while (iv[i] == 0); - } - - MUTEX_UNLOCK(dbenv, dbenv->mtx_mt); - return (0); -} - -/* Initializing the array with a seed */ -static void -__db_sgenrand(seed, mt, mtip) - unsigned long seed; - unsigned long mt[]; - int *mtip; -{ - int i; - - DB_ASSERT(seed != 0); - for (i=0;i<N;i++) { - mt[i] = seed & 0xffff0000; - seed = 69069 * seed + 1; - mt[i] |= (seed & 0xffff0000) >> 16; - seed = 69069 * seed + 1; - } - *mtip = N; -} - -#ifdef NOT_USED -/* Initialization by "sgenrand()" is an example. Theoretically, */ -/* there are 2^19937-1 possible states as an intial state. */ -/* This function allows to choose any of 2^19937-1 ones. */ -/* Essential bits in "seed_array[]" is following 19937 bits: */ -/* (seed_array[0]&UPPER_MASK), seed_array[1], ..., seed_array[N-1]. */ -/* (seed_array[0]&LOWER_MASK) is discarded. */ -/* Theoretically, */ -/* (seed_array[0]&UPPER_MASK), seed_array[1], ..., seed_array[N-1] */ -/* can take any values except all zeros. */ -static void -__db_lsgenrand(seed_array, mt, mtip) - unsigned long seed_array[]; - unsigned long mt[]; - int *mtip; - /* the length of seed_array[] must be at least N */ -{ - int i; - - for (i=0;i<N;i++) - mt[i] = seed_array[i]; - *mtip=N; -} -#endif - -static unsigned long -__db_genrand(dbenv) - DB_ENV *dbenv; -{ - unsigned long y; - static unsigned long mag01[2]={0x0, MATRIX_A}; - /* mag01[x] = x * MATRIX_A for x=0,1 */ - u_int32_t secs, seed, usecs; - - /* - * We are called with DB_ENV->mtx_mt locked. - */ - if (dbenv->mti >= N) { /* generate N words at one time */ - int kk; - - if (dbenv->mti == N+1) { /* if sgenrand() has not been called, */ - /* - * Seed the generator with the hashed time. The __db_mac - * function will return 4 bytes if we don't send in a key. - */ - do { - __os_clock(dbenv, &secs, &usecs); - __db_chksum((u_int8_t *)&secs, sizeof(secs), NULL, - (u_int8_t *)&seed); - } while (seed == 0); - __db_sgenrand((long)seed, dbenv->mt, &dbenv->mti); - } - - for (kk=0;kk<N-M;kk++) { - y = (dbenv->mt[kk]&UPPER_MASK)|(dbenv->mt[kk+1]&LOWER_MASK); - dbenv->mt[kk] = dbenv->mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1]; - } - for (;kk<N-1;kk++) { - y = (dbenv->mt[kk]&UPPER_MASK)|(dbenv->mt[kk+1]&LOWER_MASK); - dbenv->mt[kk] = dbenv->mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1]; - } - y = (dbenv->mt[N-1]&UPPER_MASK)|(dbenv->mt[0]&LOWER_MASK); - dbenv->mt[N-1] = dbenv->mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1]; - - dbenv->mti = 0; - } - - y = dbenv->mt[dbenv->mti++]; - y ^= TEMPERING_SHIFT_U(y); - y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B; - y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C; - y ^= TEMPERING_SHIFT_L(y); - - return y; -} diff --git a/storage/bdb/crypto/rijndael/rijndael-alg-fst.c b/storage/bdb/crypto/rijndael/rijndael-alg-fst.c deleted file mode 100644 index 4a251606d28..00000000000 --- a/storage/bdb/crypto/rijndael/rijndael-alg-fst.c +++ /dev/null @@ -1,1466 +0,0 @@ -/** - * rijndael-alg-fst.c - * - * @version 3.0 (December 2000) - * - * Optimised ANSI C code for the Rijndael cipher (now AES) - * - * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be> - * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be> - * @author Paulo Barreto <paulo.barreto@terra.com.br> - * - * This code is hereby placed in the public domain. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "db_config.h" - -#include "db_int.h" -#include "dbinc/crypto.h" - -#include "crypto/rijndael/rijndael-alg-fst.h" - -/* -Te0[x] = S [x].[02, 01, 01, 03]; -Te1[x] = S [x].[03, 02, 01, 01]; -Te2[x] = S [x].[01, 03, 02, 01]; -Te3[x] = S [x].[01, 01, 03, 02]; -Te4[x] = S [x].[01, 01, 01, 01]; - -Td0[x] = Si[x].[0e, 09, 0d, 0b]; -Td1[x] = Si[x].[0b, 0e, 09, 0d]; -Td2[x] = Si[x].[0d, 0b, 0e, 09]; -Td3[x] = Si[x].[09, 0d, 0b, 0e]; -Td4[x] = Si[x].[01, 01, 01, 01]; -*/ - -static const u32 Te0[256] = { - (u_int)0xc66363a5, (u_int)0xf87c7c84, (u_int)0xee777799, (u_int)0xf67b7b8d, - (u_int)0xfff2f20d, (u_int)0xd66b6bbd, (u_int)0xde6f6fb1, (u_int)0x91c5c554, - (u_int)0x60303050, (u_int)0x02010103, (u_int)0xce6767a9, (u_int)0x562b2b7d, - (u_int)0xe7fefe19, (u_int)0xb5d7d762, (u_int)0x4dababe6, (u_int)0xec76769a, - (u_int)0x8fcaca45, (u_int)0x1f82829d, (u_int)0x89c9c940, (u_int)0xfa7d7d87, - (u_int)0xeffafa15, (u_int)0xb25959eb, (u_int)0x8e4747c9, (u_int)0xfbf0f00b, - (u_int)0x41adadec, (u_int)0xb3d4d467, (u_int)0x5fa2a2fd, (u_int)0x45afafea, - (u_int)0x239c9cbf, (u_int)0x53a4a4f7, (u_int)0xe4727296, (u_int)0x9bc0c05b, - (u_int)0x75b7b7c2, (u_int)0xe1fdfd1c, (u_int)0x3d9393ae, (u_int)0x4c26266a, - (u_int)0x6c36365a, (u_int)0x7e3f3f41, (u_int)0xf5f7f702, (u_int)0x83cccc4f, - (u_int)0x6834345c, (u_int)0x51a5a5f4, (u_int)0xd1e5e534, (u_int)0xf9f1f108, - (u_int)0xe2717193, (u_int)0xabd8d873, (u_int)0x62313153, (u_int)0x2a15153f, - (u_int)0x0804040c, (u_int)0x95c7c752, (u_int)0x46232365, (u_int)0x9dc3c35e, - (u_int)0x30181828, (u_int)0x379696a1, (u_int)0x0a05050f, (u_int)0x2f9a9ab5, - (u_int)0x0e070709, (u_int)0x24121236, (u_int)0x1b80809b, (u_int)0xdfe2e23d, - (u_int)0xcdebeb26, (u_int)0x4e272769, (u_int)0x7fb2b2cd, (u_int)0xea75759f, - (u_int)0x1209091b, (u_int)0x1d83839e, (u_int)0x582c2c74, (u_int)0x341a1a2e, - (u_int)0x361b1b2d, (u_int)0xdc6e6eb2, (u_int)0xb45a5aee, (u_int)0x5ba0a0fb, - (u_int)0xa45252f6, (u_int)0x763b3b4d, (u_int)0xb7d6d661, (u_int)0x7db3b3ce, - (u_int)0x5229297b, (u_int)0xdde3e33e, (u_int)0x5e2f2f71, (u_int)0x13848497, - (u_int)0xa65353f5, (u_int)0xb9d1d168, (u_int)0x00000000, (u_int)0xc1eded2c, - (u_int)0x40202060, (u_int)0xe3fcfc1f, (u_int)0x79b1b1c8, (u_int)0xb65b5bed, - (u_int)0xd46a6abe, (u_int)0x8dcbcb46, (u_int)0x67bebed9, (u_int)0x7239394b, - (u_int)0x944a4ade, (u_int)0x984c4cd4, (u_int)0xb05858e8, (u_int)0x85cfcf4a, - (u_int)0xbbd0d06b, (u_int)0xc5efef2a, (u_int)0x4faaaae5, (u_int)0xedfbfb16, - (u_int)0x864343c5, (u_int)0x9a4d4dd7, (u_int)0x66333355, (u_int)0x11858594, - (u_int)0x8a4545cf, (u_int)0xe9f9f910, (u_int)0x04020206, (u_int)0xfe7f7f81, - (u_int)0xa05050f0, (u_int)0x783c3c44, (u_int)0x259f9fba, (u_int)0x4ba8a8e3, - (u_int)0xa25151f3, (u_int)0x5da3a3fe, (u_int)0x804040c0, (u_int)0x058f8f8a, - (u_int)0x3f9292ad, (u_int)0x219d9dbc, (u_int)0x70383848, (u_int)0xf1f5f504, - (u_int)0x63bcbcdf, (u_int)0x77b6b6c1, (u_int)0xafdada75, (u_int)0x42212163, - (u_int)0x20101030, (u_int)0xe5ffff1a, (u_int)0xfdf3f30e, (u_int)0xbfd2d26d, - (u_int)0x81cdcd4c, (u_int)0x180c0c14, (u_int)0x26131335, (u_int)0xc3ecec2f, - (u_int)0xbe5f5fe1, (u_int)0x359797a2, (u_int)0x884444cc, (u_int)0x2e171739, - (u_int)0x93c4c457, (u_int)0x55a7a7f2, (u_int)0xfc7e7e82, (u_int)0x7a3d3d47, - (u_int)0xc86464ac, (u_int)0xba5d5de7, (u_int)0x3219192b, (u_int)0xe6737395, - (u_int)0xc06060a0, (u_int)0x19818198, (u_int)0x9e4f4fd1, (u_int)0xa3dcdc7f, - (u_int)0x44222266, (u_int)0x542a2a7e, (u_int)0x3b9090ab, (u_int)0x0b888883, - (u_int)0x8c4646ca, (u_int)0xc7eeee29, (u_int)0x6bb8b8d3, (u_int)0x2814143c, - (u_int)0xa7dede79, (u_int)0xbc5e5ee2, (u_int)0x160b0b1d, (u_int)0xaddbdb76, - (u_int)0xdbe0e03b, (u_int)0x64323256, (u_int)0x743a3a4e, (u_int)0x140a0a1e, - (u_int)0x924949db, (u_int)0x0c06060a, (u_int)0x4824246c, (u_int)0xb85c5ce4, - (u_int)0x9fc2c25d, (u_int)0xbdd3d36e, (u_int)0x43acacef, (u_int)0xc46262a6, - (u_int)0x399191a8, (u_int)0x319595a4, (u_int)0xd3e4e437, (u_int)0xf279798b, - (u_int)0xd5e7e732, (u_int)0x8bc8c843, (u_int)0x6e373759, (u_int)0xda6d6db7, - (u_int)0x018d8d8c, (u_int)0xb1d5d564, (u_int)0x9c4e4ed2, (u_int)0x49a9a9e0, - (u_int)0xd86c6cb4, (u_int)0xac5656fa, (u_int)0xf3f4f407, (u_int)0xcfeaea25, - (u_int)0xca6565af, (u_int)0xf47a7a8e, (u_int)0x47aeaee9, (u_int)0x10080818, - (u_int)0x6fbabad5, (u_int)0xf0787888, (u_int)0x4a25256f, (u_int)0x5c2e2e72, - (u_int)0x381c1c24, (u_int)0x57a6a6f1, (u_int)0x73b4b4c7, (u_int)0x97c6c651, - (u_int)0xcbe8e823, (u_int)0xa1dddd7c, (u_int)0xe874749c, (u_int)0x3e1f1f21, - (u_int)0x964b4bdd, (u_int)0x61bdbddc, (u_int)0x0d8b8b86, (u_int)0x0f8a8a85, - (u_int)0xe0707090, (u_int)0x7c3e3e42, (u_int)0x71b5b5c4, (u_int)0xcc6666aa, - (u_int)0x904848d8, (u_int)0x06030305, (u_int)0xf7f6f601, (u_int)0x1c0e0e12, - (u_int)0xc26161a3, (u_int)0x6a35355f, (u_int)0xae5757f9, (u_int)0x69b9b9d0, - (u_int)0x17868691, (u_int)0x99c1c158, (u_int)0x3a1d1d27, (u_int)0x279e9eb9, - (u_int)0xd9e1e138, (u_int)0xebf8f813, (u_int)0x2b9898b3, (u_int)0x22111133, - (u_int)0xd26969bb, (u_int)0xa9d9d970, (u_int)0x078e8e89, (u_int)0x339494a7, - (u_int)0x2d9b9bb6, (u_int)0x3c1e1e22, (u_int)0x15878792, (u_int)0xc9e9e920, - (u_int)0x87cece49, (u_int)0xaa5555ff, (u_int)0x50282878, (u_int)0xa5dfdf7a, - (u_int)0x038c8c8f, (u_int)0x59a1a1f8, (u_int)0x09898980, (u_int)0x1a0d0d17, - (u_int)0x65bfbfda, (u_int)0xd7e6e631, (u_int)0x844242c6, (u_int)0xd06868b8, - (u_int)0x824141c3, (u_int)0x299999b0, (u_int)0x5a2d2d77, (u_int)0x1e0f0f11, - (u_int)0x7bb0b0cb, (u_int)0xa85454fc, (u_int)0x6dbbbbd6, (u_int)0x2c16163a, -}; -static const u32 Te1[256] = { - (u_int)0xa5c66363, (u_int)0x84f87c7c, (u_int)0x99ee7777, (u_int)0x8df67b7b, - (u_int)0x0dfff2f2, (u_int)0xbdd66b6b, (u_int)0xb1de6f6f, (u_int)0x5491c5c5, - (u_int)0x50603030, (u_int)0x03020101, (u_int)0xa9ce6767, (u_int)0x7d562b2b, - (u_int)0x19e7fefe, (u_int)0x62b5d7d7, (u_int)0xe64dabab, (u_int)0x9aec7676, - (u_int)0x458fcaca, (u_int)0x9d1f8282, (u_int)0x4089c9c9, (u_int)0x87fa7d7d, - (u_int)0x15effafa, (u_int)0xebb25959, (u_int)0xc98e4747, (u_int)0x0bfbf0f0, - (u_int)0xec41adad, (u_int)0x67b3d4d4, (u_int)0xfd5fa2a2, (u_int)0xea45afaf, - (u_int)0xbf239c9c, (u_int)0xf753a4a4, (u_int)0x96e47272, (u_int)0x5b9bc0c0, - (u_int)0xc275b7b7, (u_int)0x1ce1fdfd, (u_int)0xae3d9393, (u_int)0x6a4c2626, - (u_int)0x5a6c3636, (u_int)0x417e3f3f, (u_int)0x02f5f7f7, (u_int)0x4f83cccc, - (u_int)0x5c683434, (u_int)0xf451a5a5, (u_int)0x34d1e5e5, (u_int)0x08f9f1f1, - (u_int)0x93e27171, (u_int)0x73abd8d8, (u_int)0x53623131, (u_int)0x3f2a1515, - (u_int)0x0c080404, (u_int)0x5295c7c7, (u_int)0x65462323, (u_int)0x5e9dc3c3, - (u_int)0x28301818, (u_int)0xa1379696, (u_int)0x0f0a0505, (u_int)0xb52f9a9a, - (u_int)0x090e0707, (u_int)0x36241212, (u_int)0x9b1b8080, (u_int)0x3ddfe2e2, - (u_int)0x26cdebeb, (u_int)0x694e2727, (u_int)0xcd7fb2b2, (u_int)0x9fea7575, - (u_int)0x1b120909, (u_int)0x9e1d8383, (u_int)0x74582c2c, (u_int)0x2e341a1a, - (u_int)0x2d361b1b, (u_int)0xb2dc6e6e, (u_int)0xeeb45a5a, (u_int)0xfb5ba0a0, - (u_int)0xf6a45252, (u_int)0x4d763b3b, (u_int)0x61b7d6d6, (u_int)0xce7db3b3, - (u_int)0x7b522929, (u_int)0x3edde3e3, (u_int)0x715e2f2f, (u_int)0x97138484, - (u_int)0xf5a65353, (u_int)0x68b9d1d1, (u_int)0x00000000, (u_int)0x2cc1eded, - (u_int)0x60402020, (u_int)0x1fe3fcfc, (u_int)0xc879b1b1, (u_int)0xedb65b5b, - (u_int)0xbed46a6a, (u_int)0x468dcbcb, (u_int)0xd967bebe, (u_int)0x4b723939, - (u_int)0xde944a4a, (u_int)0xd4984c4c, (u_int)0xe8b05858, (u_int)0x4a85cfcf, - (u_int)0x6bbbd0d0, (u_int)0x2ac5efef, (u_int)0xe54faaaa, (u_int)0x16edfbfb, - (u_int)0xc5864343, (u_int)0xd79a4d4d, (u_int)0x55663333, (u_int)0x94118585, - (u_int)0xcf8a4545, (u_int)0x10e9f9f9, (u_int)0x06040202, (u_int)0x81fe7f7f, - (u_int)0xf0a05050, (u_int)0x44783c3c, (u_int)0xba259f9f, (u_int)0xe34ba8a8, - (u_int)0xf3a25151, (u_int)0xfe5da3a3, (u_int)0xc0804040, (u_int)0x8a058f8f, - (u_int)0xad3f9292, (u_int)0xbc219d9d, (u_int)0x48703838, (u_int)0x04f1f5f5, - (u_int)0xdf63bcbc, (u_int)0xc177b6b6, (u_int)0x75afdada, (u_int)0x63422121, - (u_int)0x30201010, (u_int)0x1ae5ffff, (u_int)0x0efdf3f3, (u_int)0x6dbfd2d2, - (u_int)0x4c81cdcd, (u_int)0x14180c0c, (u_int)0x35261313, (u_int)0x2fc3ecec, - (u_int)0xe1be5f5f, (u_int)0xa2359797, (u_int)0xcc884444, (u_int)0x392e1717, - (u_int)0x5793c4c4, (u_int)0xf255a7a7, (u_int)0x82fc7e7e, (u_int)0x477a3d3d, - (u_int)0xacc86464, (u_int)0xe7ba5d5d, (u_int)0x2b321919, (u_int)0x95e67373, - (u_int)0xa0c06060, (u_int)0x98198181, (u_int)0xd19e4f4f, (u_int)0x7fa3dcdc, - (u_int)0x66442222, (u_int)0x7e542a2a, (u_int)0xab3b9090, (u_int)0x830b8888, - (u_int)0xca8c4646, (u_int)0x29c7eeee, (u_int)0xd36bb8b8, (u_int)0x3c281414, - (u_int)0x79a7dede, (u_int)0xe2bc5e5e, (u_int)0x1d160b0b, (u_int)0x76addbdb, - (u_int)0x3bdbe0e0, (u_int)0x56643232, (u_int)0x4e743a3a, (u_int)0x1e140a0a, - (u_int)0xdb924949, (u_int)0x0a0c0606, (u_int)0x6c482424, (u_int)0xe4b85c5c, - (u_int)0x5d9fc2c2, (u_int)0x6ebdd3d3, (u_int)0xef43acac, (u_int)0xa6c46262, - (u_int)0xa8399191, (u_int)0xa4319595, (u_int)0x37d3e4e4, (u_int)0x8bf27979, - (u_int)0x32d5e7e7, (u_int)0x438bc8c8, (u_int)0x596e3737, (u_int)0xb7da6d6d, - (u_int)0x8c018d8d, (u_int)0x64b1d5d5, (u_int)0xd29c4e4e, (u_int)0xe049a9a9, - (u_int)0xb4d86c6c, (u_int)0xfaac5656, (u_int)0x07f3f4f4, (u_int)0x25cfeaea, - (u_int)0xafca6565, (u_int)0x8ef47a7a, (u_int)0xe947aeae, (u_int)0x18100808, - (u_int)0xd56fbaba, (u_int)0x88f07878, (u_int)0x6f4a2525, (u_int)0x725c2e2e, - (u_int)0x24381c1c, (u_int)0xf157a6a6, (u_int)0xc773b4b4, (u_int)0x5197c6c6, - (u_int)0x23cbe8e8, (u_int)0x7ca1dddd, (u_int)0x9ce87474, (u_int)0x213e1f1f, - (u_int)0xdd964b4b, (u_int)0xdc61bdbd, (u_int)0x860d8b8b, (u_int)0x850f8a8a, - (u_int)0x90e07070, (u_int)0x427c3e3e, (u_int)0xc471b5b5, (u_int)0xaacc6666, - (u_int)0xd8904848, (u_int)0x05060303, (u_int)0x01f7f6f6, (u_int)0x121c0e0e, - (u_int)0xa3c26161, (u_int)0x5f6a3535, (u_int)0xf9ae5757, (u_int)0xd069b9b9, - (u_int)0x91178686, (u_int)0x5899c1c1, (u_int)0x273a1d1d, (u_int)0xb9279e9e, - (u_int)0x38d9e1e1, (u_int)0x13ebf8f8, (u_int)0xb32b9898, (u_int)0x33221111, - (u_int)0xbbd26969, (u_int)0x70a9d9d9, (u_int)0x89078e8e, (u_int)0xa7339494, - (u_int)0xb62d9b9b, (u_int)0x223c1e1e, (u_int)0x92158787, (u_int)0x20c9e9e9, - (u_int)0x4987cece, (u_int)0xffaa5555, (u_int)0x78502828, (u_int)0x7aa5dfdf, - (u_int)0x8f038c8c, (u_int)0xf859a1a1, (u_int)0x80098989, (u_int)0x171a0d0d, - (u_int)0xda65bfbf, (u_int)0x31d7e6e6, (u_int)0xc6844242, (u_int)0xb8d06868, - (u_int)0xc3824141, (u_int)0xb0299999, (u_int)0x775a2d2d, (u_int)0x111e0f0f, - (u_int)0xcb7bb0b0, (u_int)0xfca85454, (u_int)0xd66dbbbb, (u_int)0x3a2c1616, -}; -static const u32 Te2[256] = { - (u_int)0x63a5c663, (u_int)0x7c84f87c, (u_int)0x7799ee77, (u_int)0x7b8df67b, - (u_int)0xf20dfff2, (u_int)0x6bbdd66b, (u_int)0x6fb1de6f, (u_int)0xc55491c5, - (u_int)0x30506030, (u_int)0x01030201, (u_int)0x67a9ce67, (u_int)0x2b7d562b, - (u_int)0xfe19e7fe, (u_int)0xd762b5d7, (u_int)0xabe64dab, (u_int)0x769aec76, - (u_int)0xca458fca, (u_int)0x829d1f82, (u_int)0xc94089c9, (u_int)0x7d87fa7d, - (u_int)0xfa15effa, (u_int)0x59ebb259, (u_int)0x47c98e47, (u_int)0xf00bfbf0, - (u_int)0xadec41ad, (u_int)0xd467b3d4, (u_int)0xa2fd5fa2, (u_int)0xafea45af, - (u_int)0x9cbf239c, (u_int)0xa4f753a4, (u_int)0x7296e472, (u_int)0xc05b9bc0, - (u_int)0xb7c275b7, (u_int)0xfd1ce1fd, (u_int)0x93ae3d93, (u_int)0x266a4c26, - (u_int)0x365a6c36, (u_int)0x3f417e3f, (u_int)0xf702f5f7, (u_int)0xcc4f83cc, - (u_int)0x345c6834, (u_int)0xa5f451a5, (u_int)0xe534d1e5, (u_int)0xf108f9f1, - (u_int)0x7193e271, (u_int)0xd873abd8, (u_int)0x31536231, (u_int)0x153f2a15, - (u_int)0x040c0804, (u_int)0xc75295c7, (u_int)0x23654623, (u_int)0xc35e9dc3, - (u_int)0x18283018, (u_int)0x96a13796, (u_int)0x050f0a05, (u_int)0x9ab52f9a, - (u_int)0x07090e07, (u_int)0x12362412, (u_int)0x809b1b80, (u_int)0xe23ddfe2, - (u_int)0xeb26cdeb, (u_int)0x27694e27, (u_int)0xb2cd7fb2, (u_int)0x759fea75, - (u_int)0x091b1209, (u_int)0x839e1d83, (u_int)0x2c74582c, (u_int)0x1a2e341a, - (u_int)0x1b2d361b, (u_int)0x6eb2dc6e, (u_int)0x5aeeb45a, (u_int)0xa0fb5ba0, - (u_int)0x52f6a452, (u_int)0x3b4d763b, (u_int)0xd661b7d6, (u_int)0xb3ce7db3, - (u_int)0x297b5229, (u_int)0xe33edde3, (u_int)0x2f715e2f, (u_int)0x84971384, - (u_int)0x53f5a653, (u_int)0xd168b9d1, (u_int)0x00000000, (u_int)0xed2cc1ed, - (u_int)0x20604020, (u_int)0xfc1fe3fc, (u_int)0xb1c879b1, (u_int)0x5bedb65b, - (u_int)0x6abed46a, (u_int)0xcb468dcb, (u_int)0xbed967be, (u_int)0x394b7239, - (u_int)0x4ade944a, (u_int)0x4cd4984c, (u_int)0x58e8b058, (u_int)0xcf4a85cf, - (u_int)0xd06bbbd0, (u_int)0xef2ac5ef, (u_int)0xaae54faa, (u_int)0xfb16edfb, - (u_int)0x43c58643, (u_int)0x4dd79a4d, (u_int)0x33556633, (u_int)0x85941185, - (u_int)0x45cf8a45, (u_int)0xf910e9f9, (u_int)0x02060402, (u_int)0x7f81fe7f, - (u_int)0x50f0a050, (u_int)0x3c44783c, (u_int)0x9fba259f, (u_int)0xa8e34ba8, - (u_int)0x51f3a251, (u_int)0xa3fe5da3, (u_int)0x40c08040, (u_int)0x8f8a058f, - (u_int)0x92ad3f92, (u_int)0x9dbc219d, (u_int)0x38487038, (u_int)0xf504f1f5, - (u_int)0xbcdf63bc, (u_int)0xb6c177b6, (u_int)0xda75afda, (u_int)0x21634221, - (u_int)0x10302010, (u_int)0xff1ae5ff, (u_int)0xf30efdf3, (u_int)0xd26dbfd2, - (u_int)0xcd4c81cd, (u_int)0x0c14180c, (u_int)0x13352613, (u_int)0xec2fc3ec, - (u_int)0x5fe1be5f, (u_int)0x97a23597, (u_int)0x44cc8844, (u_int)0x17392e17, - (u_int)0xc45793c4, (u_int)0xa7f255a7, (u_int)0x7e82fc7e, (u_int)0x3d477a3d, - (u_int)0x64acc864, (u_int)0x5de7ba5d, (u_int)0x192b3219, (u_int)0x7395e673, - (u_int)0x60a0c060, (u_int)0x81981981, (u_int)0x4fd19e4f, (u_int)0xdc7fa3dc, - (u_int)0x22664422, (u_int)0x2a7e542a, (u_int)0x90ab3b90, (u_int)0x88830b88, - (u_int)0x46ca8c46, (u_int)0xee29c7ee, (u_int)0xb8d36bb8, (u_int)0x143c2814, - (u_int)0xde79a7de, (u_int)0x5ee2bc5e, (u_int)0x0b1d160b, (u_int)0xdb76addb, - (u_int)0xe03bdbe0, (u_int)0x32566432, (u_int)0x3a4e743a, (u_int)0x0a1e140a, - (u_int)0x49db9249, (u_int)0x060a0c06, (u_int)0x246c4824, (u_int)0x5ce4b85c, - (u_int)0xc25d9fc2, (u_int)0xd36ebdd3, (u_int)0xacef43ac, (u_int)0x62a6c462, - (u_int)0x91a83991, (u_int)0x95a43195, (u_int)0xe437d3e4, (u_int)0x798bf279, - (u_int)0xe732d5e7, (u_int)0xc8438bc8, (u_int)0x37596e37, (u_int)0x6db7da6d, - (u_int)0x8d8c018d, (u_int)0xd564b1d5, (u_int)0x4ed29c4e, (u_int)0xa9e049a9, - (u_int)0x6cb4d86c, (u_int)0x56faac56, (u_int)0xf407f3f4, (u_int)0xea25cfea, - (u_int)0x65afca65, (u_int)0x7a8ef47a, (u_int)0xaee947ae, (u_int)0x08181008, - (u_int)0xbad56fba, (u_int)0x7888f078, (u_int)0x256f4a25, (u_int)0x2e725c2e, - (u_int)0x1c24381c, (u_int)0xa6f157a6, (u_int)0xb4c773b4, (u_int)0xc65197c6, - (u_int)0xe823cbe8, (u_int)0xdd7ca1dd, (u_int)0x749ce874, (u_int)0x1f213e1f, - (u_int)0x4bdd964b, (u_int)0xbddc61bd, (u_int)0x8b860d8b, (u_int)0x8a850f8a, - (u_int)0x7090e070, (u_int)0x3e427c3e, (u_int)0xb5c471b5, (u_int)0x66aacc66, - (u_int)0x48d89048, (u_int)0x03050603, (u_int)0xf601f7f6, (u_int)0x0e121c0e, - (u_int)0x61a3c261, (u_int)0x355f6a35, (u_int)0x57f9ae57, (u_int)0xb9d069b9, - (u_int)0x86911786, (u_int)0xc15899c1, (u_int)0x1d273a1d, (u_int)0x9eb9279e, - (u_int)0xe138d9e1, (u_int)0xf813ebf8, (u_int)0x98b32b98, (u_int)0x11332211, - (u_int)0x69bbd269, (u_int)0xd970a9d9, (u_int)0x8e89078e, (u_int)0x94a73394, - (u_int)0x9bb62d9b, (u_int)0x1e223c1e, (u_int)0x87921587, (u_int)0xe920c9e9, - (u_int)0xce4987ce, (u_int)0x55ffaa55, (u_int)0x28785028, (u_int)0xdf7aa5df, - (u_int)0x8c8f038c, (u_int)0xa1f859a1, (u_int)0x89800989, (u_int)0x0d171a0d, - (u_int)0xbfda65bf, (u_int)0xe631d7e6, (u_int)0x42c68442, (u_int)0x68b8d068, - (u_int)0x41c38241, (u_int)0x99b02999, (u_int)0x2d775a2d, (u_int)0x0f111e0f, - (u_int)0xb0cb7bb0, (u_int)0x54fca854, (u_int)0xbbd66dbb, (u_int)0x163a2c16, -}; -static const u32 Te3[256] = { - - (u_int)0x6363a5c6, (u_int)0x7c7c84f8, (u_int)0x777799ee, (u_int)0x7b7b8df6, - (u_int)0xf2f20dff, (u_int)0x6b6bbdd6, (u_int)0x6f6fb1de, (u_int)0xc5c55491, - (u_int)0x30305060, (u_int)0x01010302, (u_int)0x6767a9ce, (u_int)0x2b2b7d56, - (u_int)0xfefe19e7, (u_int)0xd7d762b5, (u_int)0xababe64d, (u_int)0x76769aec, - (u_int)0xcaca458f, (u_int)0x82829d1f, (u_int)0xc9c94089, (u_int)0x7d7d87fa, - (u_int)0xfafa15ef, (u_int)0x5959ebb2, (u_int)0x4747c98e, (u_int)0xf0f00bfb, - (u_int)0xadadec41, (u_int)0xd4d467b3, (u_int)0xa2a2fd5f, (u_int)0xafafea45, - (u_int)0x9c9cbf23, (u_int)0xa4a4f753, (u_int)0x727296e4, (u_int)0xc0c05b9b, - (u_int)0xb7b7c275, (u_int)0xfdfd1ce1, (u_int)0x9393ae3d, (u_int)0x26266a4c, - (u_int)0x36365a6c, (u_int)0x3f3f417e, (u_int)0xf7f702f5, (u_int)0xcccc4f83, - (u_int)0x34345c68, (u_int)0xa5a5f451, (u_int)0xe5e534d1, (u_int)0xf1f108f9, - (u_int)0x717193e2, (u_int)0xd8d873ab, (u_int)0x31315362, (u_int)0x15153f2a, - (u_int)0x04040c08, (u_int)0xc7c75295, (u_int)0x23236546, (u_int)0xc3c35e9d, - (u_int)0x18182830, (u_int)0x9696a137, (u_int)0x05050f0a, (u_int)0x9a9ab52f, - (u_int)0x0707090e, (u_int)0x12123624, (u_int)0x80809b1b, (u_int)0xe2e23ddf, - (u_int)0xebeb26cd, (u_int)0x2727694e, (u_int)0xb2b2cd7f, (u_int)0x75759fea, - (u_int)0x09091b12, (u_int)0x83839e1d, (u_int)0x2c2c7458, (u_int)0x1a1a2e34, - (u_int)0x1b1b2d36, (u_int)0x6e6eb2dc, (u_int)0x5a5aeeb4, (u_int)0xa0a0fb5b, - (u_int)0x5252f6a4, (u_int)0x3b3b4d76, (u_int)0xd6d661b7, (u_int)0xb3b3ce7d, - (u_int)0x29297b52, (u_int)0xe3e33edd, (u_int)0x2f2f715e, (u_int)0x84849713, - (u_int)0x5353f5a6, (u_int)0xd1d168b9, (u_int)0x00000000, (u_int)0xeded2cc1, - (u_int)0x20206040, (u_int)0xfcfc1fe3, (u_int)0xb1b1c879, (u_int)0x5b5bedb6, - (u_int)0x6a6abed4, (u_int)0xcbcb468d, (u_int)0xbebed967, (u_int)0x39394b72, - (u_int)0x4a4ade94, (u_int)0x4c4cd498, (u_int)0x5858e8b0, (u_int)0xcfcf4a85, - (u_int)0xd0d06bbb, (u_int)0xefef2ac5, (u_int)0xaaaae54f, (u_int)0xfbfb16ed, - (u_int)0x4343c586, (u_int)0x4d4dd79a, (u_int)0x33335566, (u_int)0x85859411, - (u_int)0x4545cf8a, (u_int)0xf9f910e9, (u_int)0x02020604, (u_int)0x7f7f81fe, - (u_int)0x5050f0a0, (u_int)0x3c3c4478, (u_int)0x9f9fba25, (u_int)0xa8a8e34b, - (u_int)0x5151f3a2, (u_int)0xa3a3fe5d, (u_int)0x4040c080, (u_int)0x8f8f8a05, - (u_int)0x9292ad3f, (u_int)0x9d9dbc21, (u_int)0x38384870, (u_int)0xf5f504f1, - (u_int)0xbcbcdf63, (u_int)0xb6b6c177, (u_int)0xdada75af, (u_int)0x21216342, - (u_int)0x10103020, (u_int)0xffff1ae5, (u_int)0xf3f30efd, (u_int)0xd2d26dbf, - (u_int)0xcdcd4c81, (u_int)0x0c0c1418, (u_int)0x13133526, (u_int)0xecec2fc3, - (u_int)0x5f5fe1be, (u_int)0x9797a235, (u_int)0x4444cc88, (u_int)0x1717392e, - (u_int)0xc4c45793, (u_int)0xa7a7f255, (u_int)0x7e7e82fc, (u_int)0x3d3d477a, - (u_int)0x6464acc8, (u_int)0x5d5de7ba, (u_int)0x19192b32, (u_int)0x737395e6, - (u_int)0x6060a0c0, (u_int)0x81819819, (u_int)0x4f4fd19e, (u_int)0xdcdc7fa3, - (u_int)0x22226644, (u_int)0x2a2a7e54, (u_int)0x9090ab3b, (u_int)0x8888830b, - (u_int)0x4646ca8c, (u_int)0xeeee29c7, (u_int)0xb8b8d36b, (u_int)0x14143c28, - (u_int)0xdede79a7, (u_int)0x5e5ee2bc, (u_int)0x0b0b1d16, (u_int)0xdbdb76ad, - (u_int)0xe0e03bdb, (u_int)0x32325664, (u_int)0x3a3a4e74, (u_int)0x0a0a1e14, - (u_int)0x4949db92, (u_int)0x06060a0c, (u_int)0x24246c48, (u_int)0x5c5ce4b8, - (u_int)0xc2c25d9f, (u_int)0xd3d36ebd, (u_int)0xacacef43, (u_int)0x6262a6c4, - (u_int)0x9191a839, (u_int)0x9595a431, (u_int)0xe4e437d3, (u_int)0x79798bf2, - (u_int)0xe7e732d5, (u_int)0xc8c8438b, (u_int)0x3737596e, (u_int)0x6d6db7da, - (u_int)0x8d8d8c01, (u_int)0xd5d564b1, (u_int)0x4e4ed29c, (u_int)0xa9a9e049, - (u_int)0x6c6cb4d8, (u_int)0x5656faac, (u_int)0xf4f407f3, (u_int)0xeaea25cf, - (u_int)0x6565afca, (u_int)0x7a7a8ef4, (u_int)0xaeaee947, (u_int)0x08081810, - (u_int)0xbabad56f, (u_int)0x787888f0, (u_int)0x25256f4a, (u_int)0x2e2e725c, - (u_int)0x1c1c2438, (u_int)0xa6a6f157, (u_int)0xb4b4c773, (u_int)0xc6c65197, - (u_int)0xe8e823cb, (u_int)0xdddd7ca1, (u_int)0x74749ce8, (u_int)0x1f1f213e, - (u_int)0x4b4bdd96, (u_int)0xbdbddc61, (u_int)0x8b8b860d, (u_int)0x8a8a850f, - (u_int)0x707090e0, (u_int)0x3e3e427c, (u_int)0xb5b5c471, (u_int)0x6666aacc, - (u_int)0x4848d890, (u_int)0x03030506, (u_int)0xf6f601f7, (u_int)0x0e0e121c, - (u_int)0x6161a3c2, (u_int)0x35355f6a, (u_int)0x5757f9ae, (u_int)0xb9b9d069, - (u_int)0x86869117, (u_int)0xc1c15899, (u_int)0x1d1d273a, (u_int)0x9e9eb927, - (u_int)0xe1e138d9, (u_int)0xf8f813eb, (u_int)0x9898b32b, (u_int)0x11113322, - (u_int)0x6969bbd2, (u_int)0xd9d970a9, (u_int)0x8e8e8907, (u_int)0x9494a733, - (u_int)0x9b9bb62d, (u_int)0x1e1e223c, (u_int)0x87879215, (u_int)0xe9e920c9, - (u_int)0xcece4987, (u_int)0x5555ffaa, (u_int)0x28287850, (u_int)0xdfdf7aa5, - (u_int)0x8c8c8f03, (u_int)0xa1a1f859, (u_int)0x89898009, (u_int)0x0d0d171a, - (u_int)0xbfbfda65, (u_int)0xe6e631d7, (u_int)0x4242c684, (u_int)0x6868b8d0, - (u_int)0x4141c382, (u_int)0x9999b029, (u_int)0x2d2d775a, (u_int)0x0f0f111e, - (u_int)0xb0b0cb7b, (u_int)0x5454fca8, (u_int)0xbbbbd66d, (u_int)0x16163a2c, -}; -static const u32 Te4[256] = { - (u_int)0x63636363, (u_int)0x7c7c7c7c, (u_int)0x77777777, (u_int)0x7b7b7b7b, - (u_int)0xf2f2f2f2, (u_int)0x6b6b6b6b, (u_int)0x6f6f6f6f, (u_int)0xc5c5c5c5, - (u_int)0x30303030, (u_int)0x01010101, (u_int)0x67676767, (u_int)0x2b2b2b2b, - (u_int)0xfefefefe, (u_int)0xd7d7d7d7, (u_int)0xabababab, (u_int)0x76767676, - (u_int)0xcacacaca, (u_int)0x82828282, (u_int)0xc9c9c9c9, (u_int)0x7d7d7d7d, - (u_int)0xfafafafa, (u_int)0x59595959, (u_int)0x47474747, (u_int)0xf0f0f0f0, - (u_int)0xadadadad, (u_int)0xd4d4d4d4, (u_int)0xa2a2a2a2, (u_int)0xafafafaf, - (u_int)0x9c9c9c9c, (u_int)0xa4a4a4a4, (u_int)0x72727272, (u_int)0xc0c0c0c0, - (u_int)0xb7b7b7b7, (u_int)0xfdfdfdfd, (u_int)0x93939393, (u_int)0x26262626, - (u_int)0x36363636, (u_int)0x3f3f3f3f, (u_int)0xf7f7f7f7, (u_int)0xcccccccc, - (u_int)0x34343434, (u_int)0xa5a5a5a5, (u_int)0xe5e5e5e5, (u_int)0xf1f1f1f1, - (u_int)0x71717171, (u_int)0xd8d8d8d8, (u_int)0x31313131, (u_int)0x15151515, - (u_int)0x04040404, (u_int)0xc7c7c7c7, (u_int)0x23232323, (u_int)0xc3c3c3c3, - (u_int)0x18181818, (u_int)0x96969696, (u_int)0x05050505, (u_int)0x9a9a9a9a, - (u_int)0x07070707, (u_int)0x12121212, (u_int)0x80808080, (u_int)0xe2e2e2e2, - (u_int)0xebebebeb, (u_int)0x27272727, (u_int)0xb2b2b2b2, (u_int)0x75757575, - (u_int)0x09090909, (u_int)0x83838383, (u_int)0x2c2c2c2c, (u_int)0x1a1a1a1a, - (u_int)0x1b1b1b1b, (u_int)0x6e6e6e6e, (u_int)0x5a5a5a5a, (u_int)0xa0a0a0a0, - (u_int)0x52525252, (u_int)0x3b3b3b3b, (u_int)0xd6d6d6d6, (u_int)0xb3b3b3b3, - (u_int)0x29292929, (u_int)0xe3e3e3e3, (u_int)0x2f2f2f2f, (u_int)0x84848484, - (u_int)0x53535353, (u_int)0xd1d1d1d1, (u_int)0x00000000, (u_int)0xedededed, - (u_int)0x20202020, (u_int)0xfcfcfcfc, (u_int)0xb1b1b1b1, (u_int)0x5b5b5b5b, - (u_int)0x6a6a6a6a, (u_int)0xcbcbcbcb, (u_int)0xbebebebe, (u_int)0x39393939, - (u_int)0x4a4a4a4a, (u_int)0x4c4c4c4c, (u_int)0x58585858, (u_int)0xcfcfcfcf, - (u_int)0xd0d0d0d0, (u_int)0xefefefef, (u_int)0xaaaaaaaa, (u_int)0xfbfbfbfb, - (u_int)0x43434343, (u_int)0x4d4d4d4d, (u_int)0x33333333, (u_int)0x85858585, - (u_int)0x45454545, (u_int)0xf9f9f9f9, (u_int)0x02020202, (u_int)0x7f7f7f7f, - (u_int)0x50505050, (u_int)0x3c3c3c3c, (u_int)0x9f9f9f9f, (u_int)0xa8a8a8a8, - (u_int)0x51515151, (u_int)0xa3a3a3a3, (u_int)0x40404040, (u_int)0x8f8f8f8f, - (u_int)0x92929292, (u_int)0x9d9d9d9d, (u_int)0x38383838, (u_int)0xf5f5f5f5, - (u_int)0xbcbcbcbc, (u_int)0xb6b6b6b6, (u_int)0xdadadada, (u_int)0x21212121, - (u_int)0x10101010, (u_int)0xffffffff, (u_int)0xf3f3f3f3, (u_int)0xd2d2d2d2, - (u_int)0xcdcdcdcd, (u_int)0x0c0c0c0c, (u_int)0x13131313, (u_int)0xecececec, - (u_int)0x5f5f5f5f, (u_int)0x97979797, (u_int)0x44444444, (u_int)0x17171717, - (u_int)0xc4c4c4c4, (u_int)0xa7a7a7a7, (u_int)0x7e7e7e7e, (u_int)0x3d3d3d3d, - (u_int)0x64646464, (u_int)0x5d5d5d5d, (u_int)0x19191919, (u_int)0x73737373, - (u_int)0x60606060, (u_int)0x81818181, (u_int)0x4f4f4f4f, (u_int)0xdcdcdcdc, - (u_int)0x22222222, (u_int)0x2a2a2a2a, (u_int)0x90909090, (u_int)0x88888888, - (u_int)0x46464646, (u_int)0xeeeeeeee, (u_int)0xb8b8b8b8, (u_int)0x14141414, - (u_int)0xdededede, (u_int)0x5e5e5e5e, (u_int)0x0b0b0b0b, (u_int)0xdbdbdbdb, - (u_int)0xe0e0e0e0, (u_int)0x32323232, (u_int)0x3a3a3a3a, (u_int)0x0a0a0a0a, - (u_int)0x49494949, (u_int)0x06060606, (u_int)0x24242424, (u_int)0x5c5c5c5c, - (u_int)0xc2c2c2c2, (u_int)0xd3d3d3d3, (u_int)0xacacacac, (u_int)0x62626262, - (u_int)0x91919191, (u_int)0x95959595, (u_int)0xe4e4e4e4, (u_int)0x79797979, - (u_int)0xe7e7e7e7, (u_int)0xc8c8c8c8, (u_int)0x37373737, (u_int)0x6d6d6d6d, - (u_int)0x8d8d8d8d, (u_int)0xd5d5d5d5, (u_int)0x4e4e4e4e, (u_int)0xa9a9a9a9, - (u_int)0x6c6c6c6c, (u_int)0x56565656, (u_int)0xf4f4f4f4, (u_int)0xeaeaeaea, - (u_int)0x65656565, (u_int)0x7a7a7a7a, (u_int)0xaeaeaeae, (u_int)0x08080808, - (u_int)0xbabababa, (u_int)0x78787878, (u_int)0x25252525, (u_int)0x2e2e2e2e, - (u_int)0x1c1c1c1c, (u_int)0xa6a6a6a6, (u_int)0xb4b4b4b4, (u_int)0xc6c6c6c6, - (u_int)0xe8e8e8e8, (u_int)0xdddddddd, (u_int)0x74747474, (u_int)0x1f1f1f1f, - (u_int)0x4b4b4b4b, (u_int)0xbdbdbdbd, (u_int)0x8b8b8b8b, (u_int)0x8a8a8a8a, - (u_int)0x70707070, (u_int)0x3e3e3e3e, (u_int)0xb5b5b5b5, (u_int)0x66666666, - (u_int)0x48484848, (u_int)0x03030303, (u_int)0xf6f6f6f6, (u_int)0x0e0e0e0e, - (u_int)0x61616161, (u_int)0x35353535, (u_int)0x57575757, (u_int)0xb9b9b9b9, - (u_int)0x86868686, (u_int)0xc1c1c1c1, (u_int)0x1d1d1d1d, (u_int)0x9e9e9e9e, - (u_int)0xe1e1e1e1, (u_int)0xf8f8f8f8, (u_int)0x98989898, (u_int)0x11111111, - (u_int)0x69696969, (u_int)0xd9d9d9d9, (u_int)0x8e8e8e8e, (u_int)0x94949494, - (u_int)0x9b9b9b9b, (u_int)0x1e1e1e1e, (u_int)0x87878787, (u_int)0xe9e9e9e9, - (u_int)0xcececece, (u_int)0x55555555, (u_int)0x28282828, (u_int)0xdfdfdfdf, - (u_int)0x8c8c8c8c, (u_int)0xa1a1a1a1, (u_int)0x89898989, (u_int)0x0d0d0d0d, - (u_int)0xbfbfbfbf, (u_int)0xe6e6e6e6, (u_int)0x42424242, (u_int)0x68686868, - (u_int)0x41414141, (u_int)0x99999999, (u_int)0x2d2d2d2d, (u_int)0x0f0f0f0f, - (u_int)0xb0b0b0b0, (u_int)0x54545454, (u_int)0xbbbbbbbb, (u_int)0x16161616, -}; -static const u32 Td0[256] = { - (u_int)0x51f4a750, (u_int)0x7e416553, (u_int)0x1a17a4c3, (u_int)0x3a275e96, - (u_int)0x3bab6bcb, (u_int)0x1f9d45f1, (u_int)0xacfa58ab, (u_int)0x4be30393, - (u_int)0x2030fa55, (u_int)0xad766df6, (u_int)0x88cc7691, (u_int)0xf5024c25, - (u_int)0x4fe5d7fc, (u_int)0xc52acbd7, (u_int)0x26354480, (u_int)0xb562a38f, - (u_int)0xdeb15a49, (u_int)0x25ba1b67, (u_int)0x45ea0e98, (u_int)0x5dfec0e1, - (u_int)0xc32f7502, (u_int)0x814cf012, (u_int)0x8d4697a3, (u_int)0x6bd3f9c6, - (u_int)0x038f5fe7, (u_int)0x15929c95, (u_int)0xbf6d7aeb, (u_int)0x955259da, - (u_int)0xd4be832d, (u_int)0x587421d3, (u_int)0x49e06929, (u_int)0x8ec9c844, - (u_int)0x75c2896a, (u_int)0xf48e7978, (u_int)0x99583e6b, (u_int)0x27b971dd, - (u_int)0xbee14fb6, (u_int)0xf088ad17, (u_int)0xc920ac66, (u_int)0x7dce3ab4, - (u_int)0x63df4a18, (u_int)0xe51a3182, (u_int)0x97513360, (u_int)0x62537f45, - (u_int)0xb16477e0, (u_int)0xbb6bae84, (u_int)0xfe81a01c, (u_int)0xf9082b94, - (u_int)0x70486858, (u_int)0x8f45fd19, (u_int)0x94de6c87, (u_int)0x527bf8b7, - (u_int)0xab73d323, (u_int)0x724b02e2, (u_int)0xe31f8f57, (u_int)0x6655ab2a, - (u_int)0xb2eb2807, (u_int)0x2fb5c203, (u_int)0x86c57b9a, (u_int)0xd33708a5, - (u_int)0x302887f2, (u_int)0x23bfa5b2, (u_int)0x02036aba, (u_int)0xed16825c, - (u_int)0x8acf1c2b, (u_int)0xa779b492, (u_int)0xf307f2f0, (u_int)0x4e69e2a1, - (u_int)0x65daf4cd, (u_int)0x0605bed5, (u_int)0xd134621f, (u_int)0xc4a6fe8a, - (u_int)0x342e539d, (u_int)0xa2f355a0, (u_int)0x058ae132, (u_int)0xa4f6eb75, - (u_int)0x0b83ec39, (u_int)0x4060efaa, (u_int)0x5e719f06, (u_int)0xbd6e1051, - (u_int)0x3e218af9, (u_int)0x96dd063d, (u_int)0xdd3e05ae, (u_int)0x4de6bd46, - (u_int)0x91548db5, (u_int)0x71c45d05, (u_int)0x0406d46f, (u_int)0x605015ff, - (u_int)0x1998fb24, (u_int)0xd6bde997, (u_int)0x894043cc, (u_int)0x67d99e77, - (u_int)0xb0e842bd, (u_int)0x07898b88, (u_int)0xe7195b38, (u_int)0x79c8eedb, - (u_int)0xa17c0a47, (u_int)0x7c420fe9, (u_int)0xf8841ec9, (u_int)0x00000000, - (u_int)0x09808683, (u_int)0x322bed48, (u_int)0x1e1170ac, (u_int)0x6c5a724e, - (u_int)0xfd0efffb, (u_int)0x0f853856, (u_int)0x3daed51e, (u_int)0x362d3927, - (u_int)0x0a0fd964, (u_int)0x685ca621, (u_int)0x9b5b54d1, (u_int)0x24362e3a, - (u_int)0x0c0a67b1, (u_int)0x9357e70f, (u_int)0xb4ee96d2, (u_int)0x1b9b919e, - (u_int)0x80c0c54f, (u_int)0x61dc20a2, (u_int)0x5a774b69, (u_int)0x1c121a16, - (u_int)0xe293ba0a, (u_int)0xc0a02ae5, (u_int)0x3c22e043, (u_int)0x121b171d, - (u_int)0x0e090d0b, (u_int)0xf28bc7ad, (u_int)0x2db6a8b9, (u_int)0x141ea9c8, - (u_int)0x57f11985, (u_int)0xaf75074c, (u_int)0xee99ddbb, (u_int)0xa37f60fd, - (u_int)0xf701269f, (u_int)0x5c72f5bc, (u_int)0x44663bc5, (u_int)0x5bfb7e34, - (u_int)0x8b432976, (u_int)0xcb23c6dc, (u_int)0xb6edfc68, (u_int)0xb8e4f163, - (u_int)0xd731dcca, (u_int)0x42638510, (u_int)0x13972240, (u_int)0x84c61120, - (u_int)0x854a247d, (u_int)0xd2bb3df8, (u_int)0xaef93211, (u_int)0xc729a16d, - (u_int)0x1d9e2f4b, (u_int)0xdcb230f3, (u_int)0x0d8652ec, (u_int)0x77c1e3d0, - (u_int)0x2bb3166c, (u_int)0xa970b999, (u_int)0x119448fa, (u_int)0x47e96422, - (u_int)0xa8fc8cc4, (u_int)0xa0f03f1a, (u_int)0x567d2cd8, (u_int)0x223390ef, - (u_int)0x87494ec7, (u_int)0xd938d1c1, (u_int)0x8ccaa2fe, (u_int)0x98d40b36, - (u_int)0xa6f581cf, (u_int)0xa57ade28, (u_int)0xdab78e26, (u_int)0x3fadbfa4, - (u_int)0x2c3a9de4, (u_int)0x5078920d, (u_int)0x6a5fcc9b, (u_int)0x547e4662, - (u_int)0xf68d13c2, (u_int)0x90d8b8e8, (u_int)0x2e39f75e, (u_int)0x82c3aff5, - (u_int)0x9f5d80be, (u_int)0x69d0937c, (u_int)0x6fd52da9, (u_int)0xcf2512b3, - (u_int)0xc8ac993b, (u_int)0x10187da7, (u_int)0xe89c636e, (u_int)0xdb3bbb7b, - (u_int)0xcd267809, (u_int)0x6e5918f4, (u_int)0xec9ab701, (u_int)0x834f9aa8, - (u_int)0xe6956e65, (u_int)0xaaffe67e, (u_int)0x21bccf08, (u_int)0xef15e8e6, - (u_int)0xbae79bd9, (u_int)0x4a6f36ce, (u_int)0xea9f09d4, (u_int)0x29b07cd6, - (u_int)0x31a4b2af, (u_int)0x2a3f2331, (u_int)0xc6a59430, (u_int)0x35a266c0, - (u_int)0x744ebc37, (u_int)0xfc82caa6, (u_int)0xe090d0b0, (u_int)0x33a7d815, - (u_int)0xf104984a, (u_int)0x41ecdaf7, (u_int)0x7fcd500e, (u_int)0x1791f62f, - (u_int)0x764dd68d, (u_int)0x43efb04d, (u_int)0xccaa4d54, (u_int)0xe49604df, - (u_int)0x9ed1b5e3, (u_int)0x4c6a881b, (u_int)0xc12c1fb8, (u_int)0x4665517f, - (u_int)0x9d5eea04, (u_int)0x018c355d, (u_int)0xfa877473, (u_int)0xfb0b412e, - (u_int)0xb3671d5a, (u_int)0x92dbd252, (u_int)0xe9105633, (u_int)0x6dd64713, - (u_int)0x9ad7618c, (u_int)0x37a10c7a, (u_int)0x59f8148e, (u_int)0xeb133c89, - (u_int)0xcea927ee, (u_int)0xb761c935, (u_int)0xe11ce5ed, (u_int)0x7a47b13c, - (u_int)0x9cd2df59, (u_int)0x55f2733f, (u_int)0x1814ce79, (u_int)0x73c737bf, - (u_int)0x53f7cdea, (u_int)0x5ffdaa5b, (u_int)0xdf3d6f14, (u_int)0x7844db86, - (u_int)0xcaaff381, (u_int)0xb968c43e, (u_int)0x3824342c, (u_int)0xc2a3405f, - (u_int)0x161dc372, (u_int)0xbce2250c, (u_int)0x283c498b, (u_int)0xff0d9541, - (u_int)0x39a80171, (u_int)0x080cb3de, (u_int)0xd8b4e49c, (u_int)0x6456c190, - (u_int)0x7bcb8461, (u_int)0xd532b670, (u_int)0x486c5c74, (u_int)0xd0b85742, -}; -static const u32 Td1[256] = { - (u_int)0x5051f4a7, (u_int)0x537e4165, (u_int)0xc31a17a4, (u_int)0x963a275e, - (u_int)0xcb3bab6b, (u_int)0xf11f9d45, (u_int)0xabacfa58, (u_int)0x934be303, - (u_int)0x552030fa, (u_int)0xf6ad766d, (u_int)0x9188cc76, (u_int)0x25f5024c, - (u_int)0xfc4fe5d7, (u_int)0xd7c52acb, (u_int)0x80263544, (u_int)0x8fb562a3, - (u_int)0x49deb15a, (u_int)0x6725ba1b, (u_int)0x9845ea0e, (u_int)0xe15dfec0, - (u_int)0x02c32f75, (u_int)0x12814cf0, (u_int)0xa38d4697, (u_int)0xc66bd3f9, - (u_int)0xe7038f5f, (u_int)0x9515929c, (u_int)0xebbf6d7a, (u_int)0xda955259, - (u_int)0x2dd4be83, (u_int)0xd3587421, (u_int)0x2949e069, (u_int)0x448ec9c8, - (u_int)0x6a75c289, (u_int)0x78f48e79, (u_int)0x6b99583e, (u_int)0xdd27b971, - (u_int)0xb6bee14f, (u_int)0x17f088ad, (u_int)0x66c920ac, (u_int)0xb47dce3a, - (u_int)0x1863df4a, (u_int)0x82e51a31, (u_int)0x60975133, (u_int)0x4562537f, - (u_int)0xe0b16477, (u_int)0x84bb6bae, (u_int)0x1cfe81a0, (u_int)0x94f9082b, - (u_int)0x58704868, (u_int)0x198f45fd, (u_int)0x8794de6c, (u_int)0xb7527bf8, - (u_int)0x23ab73d3, (u_int)0xe2724b02, (u_int)0x57e31f8f, (u_int)0x2a6655ab, - (u_int)0x07b2eb28, (u_int)0x032fb5c2, (u_int)0x9a86c57b, (u_int)0xa5d33708, - (u_int)0xf2302887, (u_int)0xb223bfa5, (u_int)0xba02036a, (u_int)0x5ced1682, - (u_int)0x2b8acf1c, (u_int)0x92a779b4, (u_int)0xf0f307f2, (u_int)0xa14e69e2, - (u_int)0xcd65daf4, (u_int)0xd50605be, (u_int)0x1fd13462, (u_int)0x8ac4a6fe, - (u_int)0x9d342e53, (u_int)0xa0a2f355, (u_int)0x32058ae1, (u_int)0x75a4f6eb, - (u_int)0x390b83ec, (u_int)0xaa4060ef, (u_int)0x065e719f, (u_int)0x51bd6e10, - (u_int)0xf93e218a, (u_int)0x3d96dd06, (u_int)0xaedd3e05, (u_int)0x464de6bd, - (u_int)0xb591548d, (u_int)0x0571c45d, (u_int)0x6f0406d4, (u_int)0xff605015, - (u_int)0x241998fb, (u_int)0x97d6bde9, (u_int)0xcc894043, (u_int)0x7767d99e, - (u_int)0xbdb0e842, (u_int)0x8807898b, (u_int)0x38e7195b, (u_int)0xdb79c8ee, - (u_int)0x47a17c0a, (u_int)0xe97c420f, (u_int)0xc9f8841e, (u_int)0x00000000, - (u_int)0x83098086, (u_int)0x48322bed, (u_int)0xac1e1170, (u_int)0x4e6c5a72, - (u_int)0xfbfd0eff, (u_int)0x560f8538, (u_int)0x1e3daed5, (u_int)0x27362d39, - (u_int)0x640a0fd9, (u_int)0x21685ca6, (u_int)0xd19b5b54, (u_int)0x3a24362e, - (u_int)0xb10c0a67, (u_int)0x0f9357e7, (u_int)0xd2b4ee96, (u_int)0x9e1b9b91, - (u_int)0x4f80c0c5, (u_int)0xa261dc20, (u_int)0x695a774b, (u_int)0x161c121a, - (u_int)0x0ae293ba, (u_int)0xe5c0a02a, (u_int)0x433c22e0, (u_int)0x1d121b17, - (u_int)0x0b0e090d, (u_int)0xadf28bc7, (u_int)0xb92db6a8, (u_int)0xc8141ea9, - (u_int)0x8557f119, (u_int)0x4caf7507, (u_int)0xbbee99dd, (u_int)0xfda37f60, - (u_int)0x9ff70126, (u_int)0xbc5c72f5, (u_int)0xc544663b, (u_int)0x345bfb7e, - (u_int)0x768b4329, (u_int)0xdccb23c6, (u_int)0x68b6edfc, (u_int)0x63b8e4f1, - (u_int)0xcad731dc, (u_int)0x10426385, (u_int)0x40139722, (u_int)0x2084c611, - (u_int)0x7d854a24, (u_int)0xf8d2bb3d, (u_int)0x11aef932, (u_int)0x6dc729a1, - (u_int)0x4b1d9e2f, (u_int)0xf3dcb230, (u_int)0xec0d8652, (u_int)0xd077c1e3, - (u_int)0x6c2bb316, (u_int)0x99a970b9, (u_int)0xfa119448, (u_int)0x2247e964, - (u_int)0xc4a8fc8c, (u_int)0x1aa0f03f, (u_int)0xd8567d2c, (u_int)0xef223390, - (u_int)0xc787494e, (u_int)0xc1d938d1, (u_int)0xfe8ccaa2, (u_int)0x3698d40b, - (u_int)0xcfa6f581, (u_int)0x28a57ade, (u_int)0x26dab78e, (u_int)0xa43fadbf, - (u_int)0xe42c3a9d, (u_int)0x0d507892, (u_int)0x9b6a5fcc, (u_int)0x62547e46, - (u_int)0xc2f68d13, (u_int)0xe890d8b8, (u_int)0x5e2e39f7, (u_int)0xf582c3af, - (u_int)0xbe9f5d80, (u_int)0x7c69d093, (u_int)0xa96fd52d, (u_int)0xb3cf2512, - (u_int)0x3bc8ac99, (u_int)0xa710187d, (u_int)0x6ee89c63, (u_int)0x7bdb3bbb, - (u_int)0x09cd2678, (u_int)0xf46e5918, (u_int)0x01ec9ab7, (u_int)0xa8834f9a, - (u_int)0x65e6956e, (u_int)0x7eaaffe6, (u_int)0x0821bccf, (u_int)0xe6ef15e8, - (u_int)0xd9bae79b, (u_int)0xce4a6f36, (u_int)0xd4ea9f09, (u_int)0xd629b07c, - (u_int)0xaf31a4b2, (u_int)0x312a3f23, (u_int)0x30c6a594, (u_int)0xc035a266, - (u_int)0x37744ebc, (u_int)0xa6fc82ca, (u_int)0xb0e090d0, (u_int)0x1533a7d8, - (u_int)0x4af10498, (u_int)0xf741ecda, (u_int)0x0e7fcd50, (u_int)0x2f1791f6, - (u_int)0x8d764dd6, (u_int)0x4d43efb0, (u_int)0x54ccaa4d, (u_int)0xdfe49604, - (u_int)0xe39ed1b5, (u_int)0x1b4c6a88, (u_int)0xb8c12c1f, (u_int)0x7f466551, - (u_int)0x049d5eea, (u_int)0x5d018c35, (u_int)0x73fa8774, (u_int)0x2efb0b41, - (u_int)0x5ab3671d, (u_int)0x5292dbd2, (u_int)0x33e91056, (u_int)0x136dd647, - (u_int)0x8c9ad761, (u_int)0x7a37a10c, (u_int)0x8e59f814, (u_int)0x89eb133c, - (u_int)0xeecea927, (u_int)0x35b761c9, (u_int)0xede11ce5, (u_int)0x3c7a47b1, - (u_int)0x599cd2df, (u_int)0x3f55f273, (u_int)0x791814ce, (u_int)0xbf73c737, - (u_int)0xea53f7cd, (u_int)0x5b5ffdaa, (u_int)0x14df3d6f, (u_int)0x867844db, - (u_int)0x81caaff3, (u_int)0x3eb968c4, (u_int)0x2c382434, (u_int)0x5fc2a340, - (u_int)0x72161dc3, (u_int)0x0cbce225, (u_int)0x8b283c49, (u_int)0x41ff0d95, - (u_int)0x7139a801, (u_int)0xde080cb3, (u_int)0x9cd8b4e4, (u_int)0x906456c1, - (u_int)0x617bcb84, (u_int)0x70d532b6, (u_int)0x74486c5c, (u_int)0x42d0b857, -}; -static const u32 Td2[256] = { - (u_int)0xa75051f4, (u_int)0x65537e41, (u_int)0xa4c31a17, (u_int)0x5e963a27, - (u_int)0x6bcb3bab, (u_int)0x45f11f9d, (u_int)0x58abacfa, (u_int)0x03934be3, - (u_int)0xfa552030, (u_int)0x6df6ad76, (u_int)0x769188cc, (u_int)0x4c25f502, - (u_int)0xd7fc4fe5, (u_int)0xcbd7c52a, (u_int)0x44802635, (u_int)0xa38fb562, - (u_int)0x5a49deb1, (u_int)0x1b6725ba, (u_int)0x0e9845ea, (u_int)0xc0e15dfe, - (u_int)0x7502c32f, (u_int)0xf012814c, (u_int)0x97a38d46, (u_int)0xf9c66bd3, - (u_int)0x5fe7038f, (u_int)0x9c951592, (u_int)0x7aebbf6d, (u_int)0x59da9552, - (u_int)0x832dd4be, (u_int)0x21d35874, (u_int)0x692949e0, (u_int)0xc8448ec9, - (u_int)0x896a75c2, (u_int)0x7978f48e, (u_int)0x3e6b9958, (u_int)0x71dd27b9, - (u_int)0x4fb6bee1, (u_int)0xad17f088, (u_int)0xac66c920, (u_int)0x3ab47dce, - (u_int)0x4a1863df, (u_int)0x3182e51a, (u_int)0x33609751, (u_int)0x7f456253, - (u_int)0x77e0b164, (u_int)0xae84bb6b, (u_int)0xa01cfe81, (u_int)0x2b94f908, - (u_int)0x68587048, (u_int)0xfd198f45, (u_int)0x6c8794de, (u_int)0xf8b7527b, - (u_int)0xd323ab73, (u_int)0x02e2724b, (u_int)0x8f57e31f, (u_int)0xab2a6655, - (u_int)0x2807b2eb, (u_int)0xc2032fb5, (u_int)0x7b9a86c5, (u_int)0x08a5d337, - (u_int)0x87f23028, (u_int)0xa5b223bf, (u_int)0x6aba0203, (u_int)0x825ced16, - (u_int)0x1c2b8acf, (u_int)0xb492a779, (u_int)0xf2f0f307, (u_int)0xe2a14e69, - (u_int)0xf4cd65da, (u_int)0xbed50605, (u_int)0x621fd134, (u_int)0xfe8ac4a6, - (u_int)0x539d342e, (u_int)0x55a0a2f3, (u_int)0xe132058a, (u_int)0xeb75a4f6, - (u_int)0xec390b83, (u_int)0xefaa4060, (u_int)0x9f065e71, (u_int)0x1051bd6e, - - (u_int)0x8af93e21, (u_int)0x063d96dd, (u_int)0x05aedd3e, (u_int)0xbd464de6, - (u_int)0x8db59154, (u_int)0x5d0571c4, (u_int)0xd46f0406, (u_int)0x15ff6050, - (u_int)0xfb241998, (u_int)0xe997d6bd, (u_int)0x43cc8940, (u_int)0x9e7767d9, - (u_int)0x42bdb0e8, (u_int)0x8b880789, (u_int)0x5b38e719, (u_int)0xeedb79c8, - (u_int)0x0a47a17c, (u_int)0x0fe97c42, (u_int)0x1ec9f884, (u_int)0x00000000, - (u_int)0x86830980, (u_int)0xed48322b, (u_int)0x70ac1e11, (u_int)0x724e6c5a, - (u_int)0xfffbfd0e, (u_int)0x38560f85, (u_int)0xd51e3dae, (u_int)0x3927362d, - (u_int)0xd9640a0f, (u_int)0xa621685c, (u_int)0x54d19b5b, (u_int)0x2e3a2436, - (u_int)0x67b10c0a, (u_int)0xe70f9357, (u_int)0x96d2b4ee, (u_int)0x919e1b9b, - (u_int)0xc54f80c0, (u_int)0x20a261dc, (u_int)0x4b695a77, (u_int)0x1a161c12, - (u_int)0xba0ae293, (u_int)0x2ae5c0a0, (u_int)0xe0433c22, (u_int)0x171d121b, - (u_int)0x0d0b0e09, (u_int)0xc7adf28b, (u_int)0xa8b92db6, (u_int)0xa9c8141e, - (u_int)0x198557f1, (u_int)0x074caf75, (u_int)0xddbbee99, (u_int)0x60fda37f, - (u_int)0x269ff701, (u_int)0xf5bc5c72, (u_int)0x3bc54466, (u_int)0x7e345bfb, - (u_int)0x29768b43, (u_int)0xc6dccb23, (u_int)0xfc68b6ed, (u_int)0xf163b8e4, - (u_int)0xdccad731, (u_int)0x85104263, (u_int)0x22401397, (u_int)0x112084c6, - (u_int)0x247d854a, (u_int)0x3df8d2bb, (u_int)0x3211aef9, (u_int)0xa16dc729, - (u_int)0x2f4b1d9e, (u_int)0x30f3dcb2, (u_int)0x52ec0d86, (u_int)0xe3d077c1, - (u_int)0x166c2bb3, (u_int)0xb999a970, (u_int)0x48fa1194, (u_int)0x642247e9, - (u_int)0x8cc4a8fc, (u_int)0x3f1aa0f0, (u_int)0x2cd8567d, (u_int)0x90ef2233, - (u_int)0x4ec78749, (u_int)0xd1c1d938, (u_int)0xa2fe8cca, (u_int)0x0b3698d4, - (u_int)0x81cfa6f5, (u_int)0xde28a57a, (u_int)0x8e26dab7, (u_int)0xbfa43fad, - (u_int)0x9de42c3a, (u_int)0x920d5078, (u_int)0xcc9b6a5f, (u_int)0x4662547e, - (u_int)0x13c2f68d, (u_int)0xb8e890d8, (u_int)0xf75e2e39, (u_int)0xaff582c3, - (u_int)0x80be9f5d, (u_int)0x937c69d0, (u_int)0x2da96fd5, (u_int)0x12b3cf25, - (u_int)0x993bc8ac, (u_int)0x7da71018, (u_int)0x636ee89c, (u_int)0xbb7bdb3b, - (u_int)0x7809cd26, (u_int)0x18f46e59, (u_int)0xb701ec9a, (u_int)0x9aa8834f, - (u_int)0x6e65e695, (u_int)0xe67eaaff, (u_int)0xcf0821bc, (u_int)0xe8e6ef15, - (u_int)0x9bd9bae7, (u_int)0x36ce4a6f, (u_int)0x09d4ea9f, (u_int)0x7cd629b0, - (u_int)0xb2af31a4, (u_int)0x23312a3f, (u_int)0x9430c6a5, (u_int)0x66c035a2, - (u_int)0xbc37744e, (u_int)0xcaa6fc82, (u_int)0xd0b0e090, (u_int)0xd81533a7, - (u_int)0x984af104, (u_int)0xdaf741ec, (u_int)0x500e7fcd, (u_int)0xf62f1791, - (u_int)0xd68d764d, (u_int)0xb04d43ef, (u_int)0x4d54ccaa, (u_int)0x04dfe496, - (u_int)0xb5e39ed1, (u_int)0x881b4c6a, (u_int)0x1fb8c12c, (u_int)0x517f4665, - (u_int)0xea049d5e, (u_int)0x355d018c, (u_int)0x7473fa87, (u_int)0x412efb0b, - (u_int)0x1d5ab367, (u_int)0xd25292db, (u_int)0x5633e910, (u_int)0x47136dd6, - (u_int)0x618c9ad7, (u_int)0x0c7a37a1, (u_int)0x148e59f8, (u_int)0x3c89eb13, - (u_int)0x27eecea9, (u_int)0xc935b761, (u_int)0xe5ede11c, (u_int)0xb13c7a47, - (u_int)0xdf599cd2, (u_int)0x733f55f2, (u_int)0xce791814, (u_int)0x37bf73c7, - (u_int)0xcdea53f7, (u_int)0xaa5b5ffd, (u_int)0x6f14df3d, (u_int)0xdb867844, - (u_int)0xf381caaf, (u_int)0xc43eb968, (u_int)0x342c3824, (u_int)0x405fc2a3, - (u_int)0xc372161d, (u_int)0x250cbce2, (u_int)0x498b283c, (u_int)0x9541ff0d, - (u_int)0x017139a8, (u_int)0xb3de080c, (u_int)0xe49cd8b4, (u_int)0xc1906456, - (u_int)0x84617bcb, (u_int)0xb670d532, (u_int)0x5c74486c, (u_int)0x5742d0b8, -}; -static const u32 Td3[256] = { - (u_int)0xf4a75051, (u_int)0x4165537e, (u_int)0x17a4c31a, (u_int)0x275e963a, - (u_int)0xab6bcb3b, (u_int)0x9d45f11f, (u_int)0xfa58abac, (u_int)0xe303934b, - (u_int)0x30fa5520, (u_int)0x766df6ad, (u_int)0xcc769188, (u_int)0x024c25f5, - (u_int)0xe5d7fc4f, (u_int)0x2acbd7c5, (u_int)0x35448026, (u_int)0x62a38fb5, - (u_int)0xb15a49de, (u_int)0xba1b6725, (u_int)0xea0e9845, (u_int)0xfec0e15d, - (u_int)0x2f7502c3, (u_int)0x4cf01281, (u_int)0x4697a38d, (u_int)0xd3f9c66b, - (u_int)0x8f5fe703, (u_int)0x929c9515, (u_int)0x6d7aebbf, (u_int)0x5259da95, - (u_int)0xbe832dd4, (u_int)0x7421d358, (u_int)0xe0692949, (u_int)0xc9c8448e, - (u_int)0xc2896a75, (u_int)0x8e7978f4, (u_int)0x583e6b99, (u_int)0xb971dd27, - (u_int)0xe14fb6be, (u_int)0x88ad17f0, (u_int)0x20ac66c9, (u_int)0xce3ab47d, - (u_int)0xdf4a1863, (u_int)0x1a3182e5, (u_int)0x51336097, (u_int)0x537f4562, - (u_int)0x6477e0b1, (u_int)0x6bae84bb, (u_int)0x81a01cfe, (u_int)0x082b94f9, - (u_int)0x48685870, (u_int)0x45fd198f, (u_int)0xde6c8794, (u_int)0x7bf8b752, - (u_int)0x73d323ab, (u_int)0x4b02e272, (u_int)0x1f8f57e3, (u_int)0x55ab2a66, - (u_int)0xeb2807b2, (u_int)0xb5c2032f, (u_int)0xc57b9a86, (u_int)0x3708a5d3, - (u_int)0x2887f230, (u_int)0xbfa5b223, (u_int)0x036aba02, (u_int)0x16825ced, - (u_int)0xcf1c2b8a, (u_int)0x79b492a7, (u_int)0x07f2f0f3, (u_int)0x69e2a14e, - (u_int)0xdaf4cd65, (u_int)0x05bed506, (u_int)0x34621fd1, (u_int)0xa6fe8ac4, - (u_int)0x2e539d34, (u_int)0xf355a0a2, (u_int)0x8ae13205, (u_int)0xf6eb75a4, - (u_int)0x83ec390b, (u_int)0x60efaa40, (u_int)0x719f065e, (u_int)0x6e1051bd, - (u_int)0x218af93e, (u_int)0xdd063d96, (u_int)0x3e05aedd, (u_int)0xe6bd464d, - (u_int)0x548db591, (u_int)0xc45d0571, (u_int)0x06d46f04, (u_int)0x5015ff60, - (u_int)0x98fb2419, (u_int)0xbde997d6, (u_int)0x4043cc89, (u_int)0xd99e7767, - (u_int)0xe842bdb0, (u_int)0x898b8807, (u_int)0x195b38e7, (u_int)0xc8eedb79, - (u_int)0x7c0a47a1, (u_int)0x420fe97c, (u_int)0x841ec9f8, (u_int)0x00000000, - (u_int)0x80868309, (u_int)0x2bed4832, (u_int)0x1170ac1e, (u_int)0x5a724e6c, - (u_int)0x0efffbfd, (u_int)0x8538560f, (u_int)0xaed51e3d, (u_int)0x2d392736, - (u_int)0x0fd9640a, (u_int)0x5ca62168, (u_int)0x5b54d19b, (u_int)0x362e3a24, - (u_int)0x0a67b10c, (u_int)0x57e70f93, (u_int)0xee96d2b4, (u_int)0x9b919e1b, - (u_int)0xc0c54f80, (u_int)0xdc20a261, (u_int)0x774b695a, (u_int)0x121a161c, - (u_int)0x93ba0ae2, (u_int)0xa02ae5c0, (u_int)0x22e0433c, (u_int)0x1b171d12, - (u_int)0x090d0b0e, (u_int)0x8bc7adf2, (u_int)0xb6a8b92d, (u_int)0x1ea9c814, - (u_int)0xf1198557, (u_int)0x75074caf, (u_int)0x99ddbbee, (u_int)0x7f60fda3, - (u_int)0x01269ff7, (u_int)0x72f5bc5c, (u_int)0x663bc544, (u_int)0xfb7e345b, - (u_int)0x4329768b, (u_int)0x23c6dccb, (u_int)0xedfc68b6, (u_int)0xe4f163b8, - (u_int)0x31dccad7, (u_int)0x63851042, (u_int)0x97224013, (u_int)0xc6112084, - (u_int)0x4a247d85, (u_int)0xbb3df8d2, (u_int)0xf93211ae, (u_int)0x29a16dc7, - (u_int)0x9e2f4b1d, (u_int)0xb230f3dc, (u_int)0x8652ec0d, (u_int)0xc1e3d077, - (u_int)0xb3166c2b, (u_int)0x70b999a9, (u_int)0x9448fa11, (u_int)0xe9642247, - (u_int)0xfc8cc4a8, (u_int)0xf03f1aa0, (u_int)0x7d2cd856, (u_int)0x3390ef22, - (u_int)0x494ec787, (u_int)0x38d1c1d9, (u_int)0xcaa2fe8c, (u_int)0xd40b3698, - (u_int)0xf581cfa6, (u_int)0x7ade28a5, (u_int)0xb78e26da, (u_int)0xadbfa43f, - (u_int)0x3a9de42c, (u_int)0x78920d50, (u_int)0x5fcc9b6a, (u_int)0x7e466254, - (u_int)0x8d13c2f6, (u_int)0xd8b8e890, (u_int)0x39f75e2e, (u_int)0xc3aff582, - (u_int)0x5d80be9f, (u_int)0xd0937c69, (u_int)0xd52da96f, (u_int)0x2512b3cf, - (u_int)0xac993bc8, (u_int)0x187da710, (u_int)0x9c636ee8, (u_int)0x3bbb7bdb, - (u_int)0x267809cd, (u_int)0x5918f46e, (u_int)0x9ab701ec, (u_int)0x4f9aa883, - (u_int)0x956e65e6, (u_int)0xffe67eaa, (u_int)0xbccf0821, (u_int)0x15e8e6ef, - (u_int)0xe79bd9ba, (u_int)0x6f36ce4a, (u_int)0x9f09d4ea, (u_int)0xb07cd629, - (u_int)0xa4b2af31, (u_int)0x3f23312a, (u_int)0xa59430c6, (u_int)0xa266c035, - (u_int)0x4ebc3774, (u_int)0x82caa6fc, (u_int)0x90d0b0e0, (u_int)0xa7d81533, - (u_int)0x04984af1, (u_int)0xecdaf741, (u_int)0xcd500e7f, (u_int)0x91f62f17, - (u_int)0x4dd68d76, (u_int)0xefb04d43, (u_int)0xaa4d54cc, (u_int)0x9604dfe4, - (u_int)0xd1b5e39e, (u_int)0x6a881b4c, (u_int)0x2c1fb8c1, (u_int)0x65517f46, - (u_int)0x5eea049d, (u_int)0x8c355d01, (u_int)0x877473fa, (u_int)0x0b412efb, - (u_int)0x671d5ab3, (u_int)0xdbd25292, (u_int)0x105633e9, (u_int)0xd647136d, - (u_int)0xd7618c9a, (u_int)0xa10c7a37, (u_int)0xf8148e59, (u_int)0x133c89eb, - (u_int)0xa927eece, (u_int)0x61c935b7, (u_int)0x1ce5ede1, (u_int)0x47b13c7a, - (u_int)0xd2df599c, (u_int)0xf2733f55, (u_int)0x14ce7918, (u_int)0xc737bf73, - (u_int)0xf7cdea53, (u_int)0xfdaa5b5f, (u_int)0x3d6f14df, (u_int)0x44db8678, - (u_int)0xaff381ca, (u_int)0x68c43eb9, (u_int)0x24342c38, (u_int)0xa3405fc2, - (u_int)0x1dc37216, (u_int)0xe2250cbc, (u_int)0x3c498b28, (u_int)0x0d9541ff, - (u_int)0xa8017139, (u_int)0x0cb3de08, (u_int)0xb4e49cd8, (u_int)0x56c19064, - (u_int)0xcb84617b, (u_int)0x32b670d5, (u_int)0x6c5c7448, (u_int)0xb85742d0, -}; -static const u32 Td4[256] = { - (u_int)0x52525252, (u_int)0x09090909, (u_int)0x6a6a6a6a, (u_int)0xd5d5d5d5, - (u_int)0x30303030, (u_int)0x36363636, (u_int)0xa5a5a5a5, (u_int)0x38383838, - (u_int)0xbfbfbfbf, (u_int)0x40404040, (u_int)0xa3a3a3a3, (u_int)0x9e9e9e9e, - (u_int)0x81818181, (u_int)0xf3f3f3f3, (u_int)0xd7d7d7d7, (u_int)0xfbfbfbfb, - (u_int)0x7c7c7c7c, (u_int)0xe3e3e3e3, (u_int)0x39393939, (u_int)0x82828282, - (u_int)0x9b9b9b9b, (u_int)0x2f2f2f2f, (u_int)0xffffffff, (u_int)0x87878787, - (u_int)0x34343434, (u_int)0x8e8e8e8e, (u_int)0x43434343, (u_int)0x44444444, - (u_int)0xc4c4c4c4, (u_int)0xdededede, (u_int)0xe9e9e9e9, (u_int)0xcbcbcbcb, - (u_int)0x54545454, (u_int)0x7b7b7b7b, (u_int)0x94949494, (u_int)0x32323232, - (u_int)0xa6a6a6a6, (u_int)0xc2c2c2c2, (u_int)0x23232323, (u_int)0x3d3d3d3d, - (u_int)0xeeeeeeee, (u_int)0x4c4c4c4c, (u_int)0x95959595, (u_int)0x0b0b0b0b, - (u_int)0x42424242, (u_int)0xfafafafa, (u_int)0xc3c3c3c3, (u_int)0x4e4e4e4e, - (u_int)0x08080808, (u_int)0x2e2e2e2e, (u_int)0xa1a1a1a1, (u_int)0x66666666, - (u_int)0x28282828, (u_int)0xd9d9d9d9, (u_int)0x24242424, (u_int)0xb2b2b2b2, - (u_int)0x76767676, (u_int)0x5b5b5b5b, (u_int)0xa2a2a2a2, (u_int)0x49494949, - (u_int)0x6d6d6d6d, (u_int)0x8b8b8b8b, (u_int)0xd1d1d1d1, (u_int)0x25252525, - (u_int)0x72727272, (u_int)0xf8f8f8f8, (u_int)0xf6f6f6f6, (u_int)0x64646464, - (u_int)0x86868686, (u_int)0x68686868, (u_int)0x98989898, (u_int)0x16161616, - (u_int)0xd4d4d4d4, (u_int)0xa4a4a4a4, (u_int)0x5c5c5c5c, (u_int)0xcccccccc, - (u_int)0x5d5d5d5d, (u_int)0x65656565, (u_int)0xb6b6b6b6, (u_int)0x92929292, - (u_int)0x6c6c6c6c, (u_int)0x70707070, (u_int)0x48484848, (u_int)0x50505050, - (u_int)0xfdfdfdfd, (u_int)0xedededed, (u_int)0xb9b9b9b9, (u_int)0xdadadada, - (u_int)0x5e5e5e5e, (u_int)0x15151515, (u_int)0x46464646, (u_int)0x57575757, - (u_int)0xa7a7a7a7, (u_int)0x8d8d8d8d, (u_int)0x9d9d9d9d, (u_int)0x84848484, - (u_int)0x90909090, (u_int)0xd8d8d8d8, (u_int)0xabababab, (u_int)0x00000000, - (u_int)0x8c8c8c8c, (u_int)0xbcbcbcbc, (u_int)0xd3d3d3d3, (u_int)0x0a0a0a0a, - (u_int)0xf7f7f7f7, (u_int)0xe4e4e4e4, (u_int)0x58585858, (u_int)0x05050505, - (u_int)0xb8b8b8b8, (u_int)0xb3b3b3b3, (u_int)0x45454545, (u_int)0x06060606, - (u_int)0xd0d0d0d0, (u_int)0x2c2c2c2c, (u_int)0x1e1e1e1e, (u_int)0x8f8f8f8f, - (u_int)0xcacacaca, (u_int)0x3f3f3f3f, (u_int)0x0f0f0f0f, (u_int)0x02020202, - (u_int)0xc1c1c1c1, (u_int)0xafafafaf, (u_int)0xbdbdbdbd, (u_int)0x03030303, - (u_int)0x01010101, (u_int)0x13131313, (u_int)0x8a8a8a8a, (u_int)0x6b6b6b6b, - (u_int)0x3a3a3a3a, (u_int)0x91919191, (u_int)0x11111111, (u_int)0x41414141, - (u_int)0x4f4f4f4f, (u_int)0x67676767, (u_int)0xdcdcdcdc, (u_int)0xeaeaeaea, - (u_int)0x97979797, (u_int)0xf2f2f2f2, (u_int)0xcfcfcfcf, (u_int)0xcececece, - (u_int)0xf0f0f0f0, (u_int)0xb4b4b4b4, (u_int)0xe6e6e6e6, (u_int)0x73737373, - (u_int)0x96969696, (u_int)0xacacacac, (u_int)0x74747474, (u_int)0x22222222, - (u_int)0xe7e7e7e7, (u_int)0xadadadad, (u_int)0x35353535, (u_int)0x85858585, - (u_int)0xe2e2e2e2, (u_int)0xf9f9f9f9, (u_int)0x37373737, (u_int)0xe8e8e8e8, - (u_int)0x1c1c1c1c, (u_int)0x75757575, (u_int)0xdfdfdfdf, (u_int)0x6e6e6e6e, - (u_int)0x47474747, (u_int)0xf1f1f1f1, (u_int)0x1a1a1a1a, (u_int)0x71717171, - (u_int)0x1d1d1d1d, (u_int)0x29292929, (u_int)0xc5c5c5c5, (u_int)0x89898989, - (u_int)0x6f6f6f6f, (u_int)0xb7b7b7b7, (u_int)0x62626262, (u_int)0x0e0e0e0e, - (u_int)0xaaaaaaaa, (u_int)0x18181818, (u_int)0xbebebebe, (u_int)0x1b1b1b1b, - (u_int)0xfcfcfcfc, (u_int)0x56565656, (u_int)0x3e3e3e3e, (u_int)0x4b4b4b4b, - (u_int)0xc6c6c6c6, (u_int)0xd2d2d2d2, (u_int)0x79797979, (u_int)0x20202020, - (u_int)0x9a9a9a9a, (u_int)0xdbdbdbdb, (u_int)0xc0c0c0c0, (u_int)0xfefefefe, - (u_int)0x78787878, (u_int)0xcdcdcdcd, (u_int)0x5a5a5a5a, (u_int)0xf4f4f4f4, - (u_int)0x1f1f1f1f, (u_int)0xdddddddd, (u_int)0xa8a8a8a8, (u_int)0x33333333, - (u_int)0x88888888, (u_int)0x07070707, (u_int)0xc7c7c7c7, (u_int)0x31313131, - (u_int)0xb1b1b1b1, (u_int)0x12121212, (u_int)0x10101010, (u_int)0x59595959, - (u_int)0x27272727, (u_int)0x80808080, (u_int)0xecececec, (u_int)0x5f5f5f5f, - (u_int)0x60606060, (u_int)0x51515151, (u_int)0x7f7f7f7f, (u_int)0xa9a9a9a9, - (u_int)0x19191919, (u_int)0xb5b5b5b5, (u_int)0x4a4a4a4a, (u_int)0x0d0d0d0d, - (u_int)0x2d2d2d2d, (u_int)0xe5e5e5e5, (u_int)0x7a7a7a7a, (u_int)0x9f9f9f9f, - (u_int)0x93939393, (u_int)0xc9c9c9c9, (u_int)0x9c9c9c9c, (u_int)0xefefefef, - (u_int)0xa0a0a0a0, (u_int)0xe0e0e0e0, (u_int)0x3b3b3b3b, (u_int)0x4d4d4d4d, - (u_int)0xaeaeaeae, (u_int)0x2a2a2a2a, (u_int)0xf5f5f5f5, (u_int)0xb0b0b0b0, - (u_int)0xc8c8c8c8, (u_int)0xebebebeb, (u_int)0xbbbbbbbb, (u_int)0x3c3c3c3c, - (u_int)0x83838383, (u_int)0x53535353, (u_int)0x99999999, (u_int)0x61616161, - (u_int)0x17171717, (u_int)0x2b2b2b2b, (u_int)0x04040404, (u_int)0x7e7e7e7e, - (u_int)0xbabababa, (u_int)0x77777777, (u_int)0xd6d6d6d6, (u_int)0x26262626, - (u_int)0xe1e1e1e1, (u_int)0x69696969, (u_int)0x14141414, (u_int)0x63636363, - (u_int)0x55555555, (u_int)0x21212121, (u_int)0x0c0c0c0c, (u_int)0x7d7d7d7d, -}; -static const u32 rcon[] = { - 0x01000000, 0x02000000, 0x04000000, 0x08000000, - 0x10000000, 0x20000000, 0x40000000, 0x80000000, - 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ -}; - -#define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) - -#ifdef _MSC_VER -#define GETU32(p) SWAP(*((u32 *)(p))) -#define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); } -#else -#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3])) -#define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); } -#endif - -/** - * Expand the cipher key into the encryption key schedule. - * - * @return the number of rounds for the given cipher key size. - */ -/* - * __db_rijndaelKeySetupEnc -- - * - * PUBLIC: int __db_rijndaelKeySetupEnc __P((u32 *, const u8 *, int)); - */ -int -__db_rijndaelKeySetupEnc(rk, cipherKey, keyBits) - u32 *rk; /* rk[4*(Nr + 1)] */ - const u8 *cipherKey; - int keyBits; -{ - int i = 0; - u32 temp; - - rk[0] = GETU32(cipherKey ); - rk[1] = GETU32(cipherKey + 4); - rk[2] = GETU32(cipherKey + 8); - rk[3] = GETU32(cipherKey + 12); - if (keyBits == 128) { - for (;;) { - temp = rk[3]; - rk[4] = rk[0] ^ - (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ - (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ - (Te4[(temp ) & 0xff] & 0x0000ff00) ^ - (Te4[(temp >> 24) ] & 0x000000ff) ^ - rcon[i]; - rk[5] = rk[1] ^ rk[4]; - rk[6] = rk[2] ^ rk[5]; - rk[7] = rk[3] ^ rk[6]; - if (++i == 10) { - return 10; - } - rk += 4; - } - } - rk[4] = GETU32(cipherKey + 16); - rk[5] = GETU32(cipherKey + 20); - if (keyBits == 192) { - for (;;) { - temp = rk[ 5]; - rk[ 6] = rk[ 0] ^ - (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ - (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ - (Te4[(temp ) & 0xff] & 0x0000ff00) ^ - (Te4[(temp >> 24) ] & 0x000000ff) ^ - rcon[i]; - rk[ 7] = rk[ 1] ^ rk[ 6]; - rk[ 8] = rk[ 2] ^ rk[ 7]; - rk[ 9] = rk[ 3] ^ rk[ 8]; - if (++i == 8) { - return 12; - } - rk[10] = rk[ 4] ^ rk[ 9]; - rk[11] = rk[ 5] ^ rk[10]; - rk += 6; - } - } - rk[6] = GETU32(cipherKey + 24); - rk[7] = GETU32(cipherKey + 28); - if (keyBits == 256) { - for (;;) { - temp = rk[ 7]; - rk[ 8] = rk[ 0] ^ - (Te4[(temp >> 16) & 0xff] & 0xff000000) ^ - (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ - (Te4[(temp ) & 0xff] & 0x0000ff00) ^ - (Te4[(temp >> 24) ] & 0x000000ff) ^ - rcon[i]; - rk[ 9] = rk[ 1] ^ rk[ 8]; - rk[10] = rk[ 2] ^ rk[ 9]; - rk[11] = rk[ 3] ^ rk[10]; - if (++i == 7) { - return 14; - } - temp = rk[11]; - rk[12] = rk[ 4] ^ - (Te4[(temp >> 24) ] & 0xff000000) ^ - (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(temp ) & 0xff] & 0x000000ff); - rk[13] = rk[ 5] ^ rk[12]; - rk[14] = rk[ 6] ^ rk[13]; - rk[15] = rk[ 7] ^ rk[14]; - - rk += 8; - } - } - return 0; -} - -/** - * Expand the cipher key into the decryption key schedule. - * - * @return the number of rounds for the given cipher key size. - */ -/* - * __db_rijndaelKeySetupDec -- - * - * PUBLIC: int __db_rijndaelKeySetupDec __P((u32 *, const u8 *, int)); - */ -int -__db_rijndaelKeySetupDec(rk, cipherKey, keyBits) - u32 *rk; /* rk[4*(Nr + 1)] */ - const u8 *cipherKey; - int keyBits; -{ - int Nr, i, j; - u32 temp; - - /* expand the cipher key: */ - Nr = __db_rijndaelKeySetupEnc(rk, cipherKey, keyBits); - /* invert the order of the round keys: */ - for (i = 0, j = 4*Nr; i < j; i += 4, j -= 4) { - temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; - temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; - temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; - temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; - } - /* apply the inverse MixColumn transform to all round keys but the first and the last: */ - for (i = 1; i < Nr; i++) { - rk += 4; - rk[0] = - Td0[Te4[(rk[0] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[0] ) & 0xff] & 0xff]; - rk[1] = - Td0[Te4[(rk[1] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[1] ) & 0xff] & 0xff]; - rk[2] = - Td0[Te4[(rk[2] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[2] ) & 0xff] & 0xff]; - rk[3] = - Td0[Te4[(rk[3] >> 24) ] & 0xff] ^ - Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^ - Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^ - Td3[Te4[(rk[3] ) & 0xff] & 0xff]; - } - return Nr; -} - -/* - * __db_rijndaelEncrypt -- - * - * PUBLIC: void __db_rijndaelEncrypt __P((u32 *, int, const u8 *, u8 *)); - */ -void -__db_rijndaelEncrypt(rk, Nr, pt, ct) - u32 *rk; /* rk[4*(Nr + 1)] */ - int Nr; - const u8 *pt; - u8 *ct; -{ - u32 s0, s1, s2, s3, t0, t1, t2, t3; -#ifndef FULL_UNROLL - int r; -#endif /* ?FULL_UNROLL */ - - /* - * map byte array block to cipher state - * and add initial round key: - */ - s0 = GETU32(pt ) ^ rk[0]; - s1 = GETU32(pt + 4) ^ rk[1]; - s2 = GETU32(pt + 8) ^ rk[2]; - s3 = GETU32(pt + 12) ^ rk[3]; -#ifdef FULL_UNROLL - /* round 1: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7]; - /* round 2: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11]; - /* round 3: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15]; - /* round 4: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19]; - /* round 5: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23]; - /* round 6: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27]; - /* round 7: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31]; - /* round 8: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35]; - /* round 9: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39]; - if (Nr > 10) { - /* round 10: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43]; - /* round 11: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47]; - if (Nr > 12) { - /* round 12: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51]; - /* round 13: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55]; - } - } - rk += Nr << 2; -#else /* !FULL_UNROLL */ - /* - * Nr - 1 full rounds: - */ - r = Nr >> 1; - for (;;) { - t0 = - Te0[(s0 >> 24) ] ^ - Te1[(s1 >> 16) & 0xff] ^ - Te2[(s2 >> 8) & 0xff] ^ - Te3[(s3 ) & 0xff] ^ - rk[4]; - t1 = - Te0[(s1 >> 24) ] ^ - Te1[(s2 >> 16) & 0xff] ^ - Te2[(s3 >> 8) & 0xff] ^ - Te3[(s0 ) & 0xff] ^ - rk[5]; - t2 = - Te0[(s2 >> 24) ] ^ - Te1[(s3 >> 16) & 0xff] ^ - Te2[(s0 >> 8) & 0xff] ^ - Te3[(s1 ) & 0xff] ^ - rk[6]; - t3 = - Te0[(s3 >> 24) ] ^ - Te1[(s0 >> 16) & 0xff] ^ - Te2[(s1 >> 8) & 0xff] ^ - Te3[(s2 ) & 0xff] ^ - rk[7]; - - rk += 8; - if (--r == 0) { - break; - } - - s0 = - Te0[(t0 >> 24) ] ^ - Te1[(t1 >> 16) & 0xff] ^ - Te2[(t2 >> 8) & 0xff] ^ - Te3[(t3 ) & 0xff] ^ - rk[0]; - s1 = - Te0[(t1 >> 24) ] ^ - Te1[(t2 >> 16) & 0xff] ^ - Te2[(t3 >> 8) & 0xff] ^ - Te3[(t0 ) & 0xff] ^ - rk[1]; - s2 = - Te0[(t2 >> 24) ] ^ - Te1[(t3 >> 16) & 0xff] ^ - Te2[(t0 >> 8) & 0xff] ^ - Te3[(t1 ) & 0xff] ^ - rk[2]; - s3 = - Te0[(t3 >> 24) ] ^ - Te1[(t0 >> 16) & 0xff] ^ - Te2[(t1 >> 8) & 0xff] ^ - Te3[(t2 ) & 0xff] ^ - rk[3]; - } -#endif /* ?FULL_UNROLL */ - /* - * apply last round and - * map cipher state to byte array block: - */ - s0 = - (Te4[(t0 >> 24) ] & 0xff000000) ^ - (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t3 ) & 0xff] & 0x000000ff) ^ - rk[0]; - PUTU32(ct , s0); - s1 = - (Te4[(t1 >> 24) ] & 0xff000000) ^ - (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t0 ) & 0xff] & 0x000000ff) ^ - rk[1]; - PUTU32(ct + 4, s1); - s2 = - (Te4[(t2 >> 24) ] & 0xff000000) ^ - (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t1 ) & 0xff] & 0x000000ff) ^ - rk[2]; - PUTU32(ct + 8, s2); - s3 = - (Te4[(t3 >> 24) ] & 0xff000000) ^ - (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(t2 ) & 0xff] & 0x000000ff) ^ - rk[3]; - PUTU32(ct + 12, s3); -} - -/* - * __db_rijndaelDecrypt -- - * - * PUBLIC: void __db_rijndaelDecrypt __P((u32 *, int, const u8 *, u8 *)); - */ -void -__db_rijndaelDecrypt(rk, Nr, ct, pt) - u32 *rk; /* rk[4*(Nr + 1)] */ - int Nr; - const u8 *ct; - u8 *pt; -{ - u32 s0, s1, s2, s3, t0, t1, t2, t3; -#ifndef FULL_UNROLL - int r; -#endif /* ?FULL_UNROLL */ - - /* - * map byte array block to cipher state - * and add initial round key: - */ - s0 = GETU32(ct ) ^ rk[0]; - s1 = GETU32(ct + 4) ^ rk[1]; - s2 = GETU32(ct + 8) ^ rk[2]; - s3 = GETU32(ct + 12) ^ rk[3]; -#ifdef FULL_UNROLL - /* round 1: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7]; - /* round 2: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11]; - /* round 3: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15]; - /* round 4: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19]; - /* round 5: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23]; - /* round 6: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27]; - /* round 7: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31]; - /* round 8: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35]; - /* round 9: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39]; - if (Nr > 10) { - /* round 10: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43]; - /* round 11: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47]; - if (Nr > 12) { - /* round 12: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51]; - /* round 13: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55]; - } - } - rk += Nr << 2; -#else /* !FULL_UNROLL */ - /* - * Nr - 1 full rounds: - */ - r = Nr >> 1; - for (;;) { - t0 = - Td0[(s0 >> 24) ] ^ - Td1[(s3 >> 16) & 0xff] ^ - Td2[(s2 >> 8) & 0xff] ^ - Td3[(s1 ) & 0xff] ^ - rk[4]; - t1 = - Td0[(s1 >> 24) ] ^ - Td1[(s0 >> 16) & 0xff] ^ - Td2[(s3 >> 8) & 0xff] ^ - Td3[(s2 ) & 0xff] ^ - rk[5]; - t2 = - Td0[(s2 >> 24) ] ^ - Td1[(s1 >> 16) & 0xff] ^ - Td2[(s0 >> 8) & 0xff] ^ - Td3[(s3 ) & 0xff] ^ - rk[6]; - t3 = - Td0[(s3 >> 24) ] ^ - Td1[(s2 >> 16) & 0xff] ^ - Td2[(s1 >> 8) & 0xff] ^ - Td3[(s0 ) & 0xff] ^ - rk[7]; - - rk += 8; - if (--r == 0) { - break; - } - - s0 = - Td0[(t0 >> 24) ] ^ - Td1[(t3 >> 16) & 0xff] ^ - Td2[(t2 >> 8) & 0xff] ^ - Td3[(t1 ) & 0xff] ^ - rk[0]; - s1 = - Td0[(t1 >> 24) ] ^ - Td1[(t0 >> 16) & 0xff] ^ - Td2[(t3 >> 8) & 0xff] ^ - Td3[(t2 ) & 0xff] ^ - rk[1]; - s2 = - Td0[(t2 >> 24) ] ^ - Td1[(t1 >> 16) & 0xff] ^ - Td2[(t0 >> 8) & 0xff] ^ - Td3[(t3 ) & 0xff] ^ - rk[2]; - s3 = - Td0[(t3 >> 24) ] ^ - Td1[(t2 >> 16) & 0xff] ^ - Td2[(t1 >> 8) & 0xff] ^ - Td3[(t0 ) & 0xff] ^ - rk[3]; - } -#endif /* ?FULL_UNROLL */ - /* - * apply last round and - * map cipher state to byte array block: - */ - s0 = - (Td4[(t0 >> 24) ] & 0xff000000) ^ - (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t1 ) & 0xff] & 0x000000ff) ^ - rk[0]; - PUTU32(pt , s0); - s1 = - (Td4[(t1 >> 24) ] & 0xff000000) ^ - (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t2 ) & 0xff] & 0x000000ff) ^ - rk[1]; - PUTU32(pt + 4, s1); - s2 = - (Td4[(t2 >> 24) ] & 0xff000000) ^ - (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t3 ) & 0xff] & 0x000000ff) ^ - rk[2]; - PUTU32(pt + 8, s2); - s3 = - (Td4[(t3 >> 24) ] & 0xff000000) ^ - (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(t0 ) & 0xff] & 0x000000ff) ^ - rk[3]; - PUTU32(pt + 12, s3); -} - -#ifdef INTERMEDIATE_VALUE_KAT - -/* - * __db_rijndaelEncryptRound -- - * - * PUBLIC: void __db_rijndaelEncryptRound __P((const u32 *, int, u8 *, int)); - */ -void -__db_rijndaelEncryptRound(rk, Nr, pt, ct) - const u32 *rk; /* rk[4*(Nr + 1)] */ - int Nr; - u8 *block; - int rounds; -{ - int r; - u32 s0, s1, s2, s3, t0, t1, t2, t3; - - /* - * map byte array block to cipher state - * and add initial round key: - */ - s0 = GETU32(block ) ^ rk[0]; - s1 = GETU32(block + 4) ^ rk[1]; - s2 = GETU32(block + 8) ^ rk[2]; - s3 = GETU32(block + 12) ^ rk[3]; - rk += 4; - - /* - * Nr - 1 full rounds: - */ - for (r = (rounds < Nr ? rounds : Nr - 1); r > 0; r--) { - t0 = - Te0[(s0 >> 24) ] ^ - Te1[(s1 >> 16) & 0xff] ^ - Te2[(s2 >> 8) & 0xff] ^ - Te3[(s3 ) & 0xff] ^ - rk[0]; - t1 = - Te0[(s1 >> 24) ] ^ - Te1[(s2 >> 16) & 0xff] ^ - Te2[(s3 >> 8) & 0xff] ^ - Te3[(s0 ) & 0xff] ^ - rk[1]; - t2 = - Te0[(s2 >> 24) ] ^ - Te1[(s3 >> 16) & 0xff] ^ - Te2[(s0 >> 8) & 0xff] ^ - Te3[(s1 ) & 0xff] ^ - rk[2]; - t3 = - Te0[(s3 >> 24) ] ^ - Te1[(s0 >> 16) & 0xff] ^ - Te2[(s1 >> 8) & 0xff] ^ - Te3[(s2 ) & 0xff] ^ - rk[3]; - - s0 = t0; - s1 = t1; - s2 = t2; - s3 = t3; - rk += 4; - - } - - /* - * apply last round and - * map cipher state to byte array block: - */ - if (rounds == Nr) { - t0 = - (Te4[(s0 >> 24) ] & 0xff000000) ^ - (Te4[(s1 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(s2 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(s3 ) & 0xff] & 0x000000ff) ^ - rk[0]; - t1 = - (Te4[(s1 >> 24) ] & 0xff000000) ^ - (Te4[(s2 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(s3 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(s0 ) & 0xff] & 0x000000ff) ^ - rk[1]; - t2 = - (Te4[(s2 >> 24) ] & 0xff000000) ^ - (Te4[(s3 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(s0 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(s1 ) & 0xff] & 0x000000ff) ^ - rk[2]; - t3 = - (Te4[(s3 >> 24) ] & 0xff000000) ^ - (Te4[(s0 >> 16) & 0xff] & 0x00ff0000) ^ - (Te4[(s1 >> 8) & 0xff] & 0x0000ff00) ^ - (Te4[(s2 ) & 0xff] & 0x000000ff) ^ - rk[3]; - - s0 = t0; - s1 = t1; - s2 = t2; - s3 = t3; - } - - PUTU32(block , s0); - PUTU32(block + 4, s1); - PUTU32(block + 8, s2); - PUTU32(block + 12, s3); -} - -/* - * __db_rijndaelDecryptRound -- - * - * PUBLIC: void __db_rijndaelDecryptRound __P((const u32 *, int, u8 *, int)); - */ -void -__db_rijndaelDecryptRound(rk, Nr, pt, ct) - const u32 *rk; /* rk[4*(Nr + 1)] */ - int Nr; - u8 *block; - int rounds; -{ - int r; - u32 s0, s1, s2, s3, t0, t1, t2, t3; - - /* - * map byte array block to cipher state - * and add initial round key: - */ - s0 = GETU32(block ) ^ rk[0]; - s1 = GETU32(block + 4) ^ rk[1]; - s2 = GETU32(block + 8) ^ rk[2]; - s3 = GETU32(block + 12) ^ rk[3]; - rk += 4; - - /* - * Nr - 1 full rounds: - */ - for (r = (rounds < Nr ? rounds : Nr) - 1; r > 0; r--) { - t0 = - Td0[(s0 >> 24) ] ^ - Td1[(s3 >> 16) & 0xff] ^ - Td2[(s2 >> 8) & 0xff] ^ - Td3[(s1 ) & 0xff] ^ - rk[0]; - t1 = - Td0[(s1 >> 24) ] ^ - Td1[(s0 >> 16) & 0xff] ^ - Td2[(s3 >> 8) & 0xff] ^ - Td3[(s2 ) & 0xff] ^ - rk[1]; - t2 = - Td0[(s2 >> 24) ] ^ - Td1[(s1 >> 16) & 0xff] ^ - Td2[(s0 >> 8) & 0xff] ^ - Td3[(s3 ) & 0xff] ^ - rk[2]; - t3 = - Td0[(s3 >> 24) ] ^ - Td1[(s2 >> 16) & 0xff] ^ - Td2[(s1 >> 8) & 0xff] ^ - Td3[(s0 ) & 0xff] ^ - rk[3]; - - s0 = t0; - s1 = t1; - s2 = t2; - s3 = t3; - rk += 4; - - } - - /* - * complete the last round and - * map cipher state to byte array block: - */ - t0 = - (Td4[(s0 >> 24) ] & 0xff000000) ^ - (Td4[(s3 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(s2 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(s1 ) & 0xff] & 0x000000ff); - t1 = - (Td4[(s1 >> 24) ] & 0xff000000) ^ - (Td4[(s0 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(s3 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(s2 ) & 0xff] & 0x000000ff); - t2 = - (Td4[(s2 >> 24) ] & 0xff000000) ^ - (Td4[(s1 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(s0 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(s3 ) & 0xff] & 0x000000ff); - t3 = - (Td4[(s3 >> 24) ] & 0xff000000) ^ - (Td4[(s2 >> 16) & 0xff] & 0x00ff0000) ^ - (Td4[(s1 >> 8) & 0xff] & 0x0000ff00) ^ - (Td4[(s0 ) & 0xff] & 0x000000ff); - - if (rounds == Nr) { - t0 ^= rk[0]; - t1 ^= rk[1]; - t2 ^= rk[2]; - t3 ^= rk[3]; - } - - PUTU32(block , t0); - PUTU32(block + 4, t1); - PUTU32(block + 8, t2); - PUTU32(block + 12, t3); -} - -#endif /* INTERMEDIATE_VALUE_KAT */ diff --git a/storage/bdb/crypto/rijndael/rijndael-alg-fst.h b/storage/bdb/crypto/rijndael/rijndael-alg-fst.h deleted file mode 100644 index 60c01212764..00000000000 --- a/storage/bdb/crypto/rijndael/rijndael-alg-fst.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * $Id: rijndael-alg-fst.h,v 12.0 2004/11/17 03:43:17 bostic Exp $ - */ -/** - * rijndael-alg-fst.h - * - * @version 3.0 (December 2000) - * - * Optimised ANSI C code for the Rijndael cipher (now AES) - * - * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be> - * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be> - * @author Paulo Barreto <paulo.barreto@terra.com.br> - * - * This code is hereby placed in the public domain. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef __RIJNDAEL_ALG_FST_H -#define __RIJNDAEL_ALG_FST_H - -#define MAXKC (256/32) -#define MAXKB (256/8) -#define MAXNR 14 - -typedef u_int8_t u8; -typedef u_int16_t u16; -typedef u_int32_t u32; - -#endif /* __RIJNDAEL_ALG_FST_H */ diff --git a/storage/bdb/crypto/rijndael/rijndael-api-fst.c b/storage/bdb/crypto/rijndael/rijndael-api-fst.c deleted file mode 100644 index 09475370f6b..00000000000 --- a/storage/bdb/crypto/rijndael/rijndael-api-fst.c +++ /dev/null @@ -1,496 +0,0 @@ -/** - * rijndael-api-fst.c - * - * @version 2.9 (December 2000) - * - * Optimised ANSI C code for the Rijndael cipher (now AES) - * - * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be> - * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be> - * @author Paulo Barreto <paulo.barreto@terra.com.br> - * - * This code is hereby placed in the public domain. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Acknowledgements: - * - * We are deeply indebted to the following people for their bug reports, - * fixes, and improvement suggestions to this implementation. Though we - * tried to list all contributions, we apologise in advance for any - * missing reference. - * - * Andrew Bales <Andrew.Bales@Honeywell.com> - * Markus Friedl <markus.friedl@informatik.uni-erlangen.de> - * John Skodon <skodonj@webquill.com> - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/crypto.h" - -#include "crypto/rijndael/rijndael-alg-fst.h" -#include "crypto/rijndael/rijndael-api-fst.h" - -/* - * __db_makeKey -- - * - * PUBLIC: int __db_makeKey __P((keyInstance *, int, int, char *)); - */ -int -__db_makeKey(key, direction, keyLen, keyMaterial) - keyInstance *key; - int direction; - int keyLen; - char *keyMaterial; -{ - u8 cipherKey[MAXKB]; - - if (key == NULL) { - return BAD_KEY_INSTANCE; - } - - if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) { - key->direction = direction; - } else { - return BAD_KEY_DIR; - } - - if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) { - key->keyLen = keyLen; - } else { - return BAD_KEY_MAT; - } - - if (keyMaterial != NULL) { - memcpy(cipherKey, keyMaterial, key->keyLen/8); - } - - if (direction == DIR_ENCRYPT) { - key->Nr = __db_rijndaelKeySetupEnc(key->rk, cipherKey, keyLen); - } else { - key->Nr = __db_rijndaelKeySetupDec(key->rk, cipherKey, keyLen); - } - __db_rijndaelKeySetupEnc(key->ek, cipherKey, keyLen); - return TRUE; -} - -/* - * __db_cipherInit -- - * - * PUBLIC: int __db_cipherInit __P((cipherInstance *, int, char *)); - */ -int -__db_cipherInit(cipher, mode, IV) - cipherInstance *cipher; - int mode; - char *IV; -{ - if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) { - cipher->mode = mode; - } else { - return BAD_CIPHER_MODE; - } - if (IV != NULL) { - memcpy(cipher->IV, IV, MAX_IV_SIZE); - } - return TRUE; -} - -/* - * __db_blockEncrypt -- - * - * PUBLIC: int __db_blockEncrypt __P((cipherInstance *, keyInstance *, u_int8_t *, - * PUBLIC: size_t, u_int8_t *)); - */ -int -__db_blockEncrypt(cipher, key, input, inputLen, outBuffer) - cipherInstance *cipher; - keyInstance *key; - u_int8_t *input; - size_t inputLen; - u_int8_t *outBuffer; -{ - int i, k, t, numBlocks; - u8 block[16], *iv; - u32 tmpiv[4]; - - if (cipher == NULL || - key == NULL || - key->direction == DIR_DECRYPT) { - return BAD_CIPHER_STATE; - } - if (input == NULL || inputLen <= 0) { - return 0; /* nothing to do */ - } - - numBlocks = (int)(inputLen/128); - - switch (cipher->mode) { - case MODE_ECB: - for (i = numBlocks; i > 0; i--) { - __db_rijndaelEncrypt(key->rk, key->Nr, input, outBuffer); - input += 16; - outBuffer += 16; - } - break; - - case MODE_CBC: - iv = cipher->IV; - for (i = numBlocks; i > 0; i--) { - memcpy(tmpiv, iv, MAX_IV_SIZE); - ((u32*)block)[0] = ((u32*)input)[0] ^ tmpiv[0]; - ((u32*)block)[1] = ((u32*)input)[1] ^ tmpiv[1]; - ((u32*)block)[2] = ((u32*)input)[2] ^ tmpiv[2]; - ((u32*)block)[3] = ((u32*)input)[3] ^ tmpiv[3]; - __db_rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); - iv = outBuffer; - input += 16; - outBuffer += 16; - } - break; - - case MODE_CFB1: - iv = cipher->IV; - for (i = numBlocks; i > 0; i--) { - memcpy(outBuffer, input, 16); - for (k = 0; k < 128; k++) { - __db_rijndaelEncrypt(key->ek, key->Nr, iv, block); - outBuffer[k >> 3] ^= (block[0] & (u_int)0x80) >> (k & 7); - for (t = 0; t < 15; t++) { - iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7); - } - iv[15] = (iv[15] << 1) | ((outBuffer[k >> 3] >> (7 - (k & 7))) & 1); - } - outBuffer += 16; - input += 16; - } - break; - - default: - return BAD_CIPHER_STATE; - } - - return 128*numBlocks; -} - -/** - * Encrypt data partitioned in octets, using RFC 2040-like padding. - * - * @param input data to be encrypted (octet sequence) - * @param inputOctets input length in octets (not bits) - * @param outBuffer encrypted output data - * - * @return length in octets (not bits) of the encrypted output buffer. - */ -/* - * __db_padEncrypt -- - * - * PUBLIC: int __db_padEncrypt __P((cipherInstance *, keyInstance *, u_int8_t *, - * PUBLIC: int, u_int8_t *)); - */ -int -__db_padEncrypt(cipher, key, input, inputOctets, outBuffer) - cipherInstance *cipher; - keyInstance *key; - u_int8_t *input; - int inputOctets; - u_int8_t *outBuffer; -{ - int i, numBlocks, padLen; - u8 block[16], *iv; - u32 tmpiv[4]; - - if (cipher == NULL || - key == NULL || - key->direction == DIR_DECRYPT) { - return BAD_CIPHER_STATE; - } - if (input == NULL || inputOctets <= 0) { - return 0; /* nothing to do */ - } - - numBlocks = inputOctets/16; - - switch (cipher->mode) { - case MODE_ECB: - for (i = numBlocks; i > 0; i--) { - __db_rijndaelEncrypt(key->rk, key->Nr, input, outBuffer); - input += 16; - outBuffer += 16; - } - padLen = 16 - (inputOctets - 16*numBlocks); - DB_ASSERT(padLen > 0 && padLen <= 16); - memcpy(block, input, 16 - padLen); - memset(block + 16 - padLen, padLen, padLen); - __db_rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); - break; - - case MODE_CBC: - iv = cipher->IV; - for (i = numBlocks; i > 0; i--) { - memcpy(tmpiv, iv, MAX_IV_SIZE); - ((u32*)block)[0] = ((u32*)input)[0] ^ tmpiv[0]; - ((u32*)block)[1] = ((u32*)input)[1] ^ tmpiv[1]; - ((u32*)block)[2] = ((u32*)input)[2] ^ tmpiv[2]; - ((u32*)block)[3] = ((u32*)input)[3] ^ tmpiv[3]; - __db_rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); - iv = outBuffer; - input += 16; - outBuffer += 16; - } - padLen = 16 - (inputOctets - 16*numBlocks); - DB_ASSERT(padLen > 0 && padLen <= 16); - for (i = 0; i < 16 - padLen; i++) { - block[i] = input[i] ^ iv[i]; - } - for (i = 16 - padLen; i < 16; i++) { - block[i] = (u_int8_t)padLen ^ iv[i]; - } - __db_rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); - break; - - default: - return BAD_CIPHER_STATE; - } - - return 16*(numBlocks + 1); -} - -/* - * __db_blockDecrypt -- - * - * PUBLIC: int __db_blockDecrypt __P((cipherInstance *, keyInstance *, u_int8_t *, - * PUBLIC: size_t, u_int8_t *)); - */ -int -__db_blockDecrypt(cipher, key, input, inputLen, outBuffer) - cipherInstance *cipher; - keyInstance *key; - u_int8_t *input; - size_t inputLen; - u_int8_t *outBuffer; -{ - int i, k, t, numBlocks; - u8 block[16], *iv; - u32 tmpiv[4]; - - if (cipher == NULL || - key == NULL || - (cipher->mode != MODE_CFB1 && key->direction == DIR_ENCRYPT)) { - return BAD_CIPHER_STATE; - } - if (input == NULL || inputLen <= 0) { - return 0; /* nothing to do */ - } - - numBlocks = (int)(inputLen/128); - - switch (cipher->mode) { - case MODE_ECB: - for (i = numBlocks; i > 0; i--) { - __db_rijndaelDecrypt(key->rk, key->Nr, input, outBuffer); - input += 16; - outBuffer += 16; - } - break; - - case MODE_CBC: - memcpy(tmpiv, cipher->IV, MAX_IV_SIZE); - for (i = numBlocks; i > 0; i--) { - __db_rijndaelDecrypt(key->rk, key->Nr, input, block); - ((u32*)block)[0] ^= tmpiv[0]; - ((u32*)block)[1] ^= tmpiv[1]; - ((u32*)block)[2] ^= tmpiv[2]; - ((u32*)block)[3] ^= tmpiv[3]; - memcpy(tmpiv, input, 16); - memcpy(outBuffer, block, 16); - input += 16; - outBuffer += 16; - } - break; - - case MODE_CFB1: - iv = cipher->IV; - for (i = numBlocks; i > 0; i--) { - memcpy(outBuffer, input, 16); - for (k = 0; k < 128; k++) { - __db_rijndaelEncrypt(key->ek, key->Nr, iv, block); - for (t = 0; t < 15; t++) { - iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7); - } - iv[15] = (iv[15] << 1) | ((input[k >> 3] >> (7 - (k & 7))) & 1); - outBuffer[k >> 3] ^= (block[0] & (u_int)0x80) >> (k & 7); - } - outBuffer += 16; - input += 16; - } - break; - - default: - return BAD_CIPHER_STATE; - } - - return 128*numBlocks; -} - -/* - * __db_padDecrypt -- - * - * PUBLIC: int __db_padDecrypt __P((cipherInstance *, keyInstance *, u_int8_t *, - * PUBLIC: int, u_int8_t *)); - */ -int -__db_padDecrypt(cipher, key, input, inputOctets, outBuffer) - cipherInstance *cipher; - keyInstance *key; - u_int8_t *input; - int inputOctets; - u_int8_t *outBuffer; -{ - int i, numBlocks, padLen; - u8 block[16]; - u32 tmpiv[4]; - - if (cipher == NULL || - key == NULL || - key->direction == DIR_ENCRYPT) { - return BAD_CIPHER_STATE; - } - if (input == NULL || inputOctets <= 0) { - return 0; /* nothing to do */ - } - if (inputOctets % 16 != 0) { - return BAD_DATA; - } - - numBlocks = inputOctets/16; - - switch (cipher->mode) { - case MODE_ECB: - /* all blocks but last */ - for (i = numBlocks - 1; i > 0; i--) { - __db_rijndaelDecrypt(key->rk, key->Nr, input, outBuffer); - input += 16; - outBuffer += 16; - } - /* last block */ - __db_rijndaelDecrypt(key->rk, key->Nr, input, block); - padLen = block[15]; - if (padLen >= 16) { - return BAD_DATA; - } - for (i = 16 - padLen; i < 16; i++) { - if (block[i] != padLen) { - return BAD_DATA; - } - } - memcpy(outBuffer, block, 16 - padLen); - break; - - case MODE_CBC: - /* all blocks but last */ - memcpy(tmpiv, cipher->IV, MAX_IV_SIZE); - for (i = numBlocks - 1; i > 0; i--) { - __db_rijndaelDecrypt(key->rk, key->Nr, input, block); - ((u32*)block)[0] ^= tmpiv[0]; - ((u32*)block)[1] ^= tmpiv[1]; - ((u32*)block)[2] ^= tmpiv[2]; - ((u32*)block)[3] ^= tmpiv[3]; - memcpy(tmpiv, input, 16); - memcpy(outBuffer, block, 16); - input += 16; - outBuffer += 16; - } - /* last block */ - __db_rijndaelDecrypt(key->rk, key->Nr, input, block); - ((u32*)block)[0] ^= tmpiv[0]; - ((u32*)block)[1] ^= tmpiv[1]; - ((u32*)block)[2] ^= tmpiv[2]; - ((u32*)block)[3] ^= tmpiv[3]; - padLen = block[15]; - if (padLen <= 0 || padLen > 16) { - return BAD_DATA; - } - for (i = 16 - padLen; i < 16; i++) { - if (block[i] != padLen) { - return BAD_DATA; - } - } - memcpy(outBuffer, block, 16 - padLen); - break; - - default: - return BAD_CIPHER_STATE; - } - - return 16*numBlocks - padLen; -} - -#ifdef INTERMEDIATE_VALUE_KAT -/** - * cipherUpdateRounds: - * - * Encrypts/Decrypts exactly one full block a specified number of rounds. - * Only used in the Intermediate Value Known Answer Test. - * - * Returns: - * TRUE - on success - * BAD_CIPHER_STATE - cipher in bad state (e.g., not initialized) - */ -/* - * __db_cipherUpdateRounds -- - * - * PUBLIC: int __db_cipherUpdateRounds __P((cipherInstance *, keyInstance *, - * PUBLIC: u_int8_t *, int, u_int8_t *, int)); - */ -int -__db_cipherUpdateRounds(cipher, key, input, inputLen, outBuffer, rounds) - cipherInstance *cipher; - keyInstance *key; - u_int8_t *input; - size_t inputLen; - u_int8_t *outBuffer; - int rounds; -{ - u8 block[16]; - - if (cipher == NULL || key == NULL) { - return BAD_CIPHER_STATE; - } - - memcpy(block, input, 16); - - switch (key->direction) { - case DIR_ENCRYPT: - __db_rijndaelEncryptRound(key->rk, key->Nr, block, rounds); - break; - - case DIR_DECRYPT: - __db_rijndaelDecryptRound(key->rk, key->Nr, block, rounds); - break; - - default: - return BAD_KEY_DIR; - } - - memcpy(outBuffer, block, 16); - - return TRUE; -} -#endif /* INTERMEDIATE_VALUE_KAT */ diff --git a/storage/bdb/crypto/rijndael/rijndael-api-fst.h b/storage/bdb/crypto/rijndael/rijndael-api-fst.h deleted file mode 100644 index caf0abc4aa7..00000000000 --- a/storage/bdb/crypto/rijndael/rijndael-api-fst.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * $Id: rijndael-api-fst.h,v 12.0 2004/11/17 03:43:17 bostic Exp $ - */ -/** - * rijndael-api-fst.h - * - * @version 2.9 (December 2000) - * - * Optimised ANSI C code for the Rijndael cipher (now AES) - * - * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be> - * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be> - * @author Paulo Barreto <paulo.barreto@terra.com.br> - * - * This code is hereby placed in the public domain. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Acknowledgements: - * - * We are deeply indebted to the following people for their bug reports, - * fixes, and improvement suggestions to this implementation. Though we - * tried to list all contributions, we apologise in advance for any - * missing reference. - * - * Andrew Bales <Andrew.Bales@Honeywell.com> - * Markus Friedl <markus.friedl@informatik.uni-erlangen.de> - * John Skodon <skodonj@webquill.com> - */ - -#ifndef __RIJNDAEL_API_FST_H -#define __RIJNDAEL_API_FST_H - -#include "crypto/rijndael/rijndael-alg-fst.h" - -/* Generic Defines */ -#define DIR_ENCRYPT 0 /* Are we encrpyting? */ -#define DIR_DECRYPT 1 /* Are we decrpyting? */ -#define MODE_ECB 1 /* Are we ciphering in ECB mode? */ -#define MODE_CBC 2 /* Are we ciphering in CBC mode? */ -#define MODE_CFB1 3 /* Are we ciphering in 1-bit CFB mode? */ -#undef TRUE -#define TRUE 1 -#undef FALSE -#define FALSE 0 -#define BITSPERBLOCK 128 /* Default number of bits in a cipher block */ - -/* Error Codes */ -#define BAD_KEY_DIR -1 /* Key direction is invalid, e.g., unknown value */ -#define BAD_KEY_MAT -2 /* Key material not of correct length */ -#define BAD_KEY_INSTANCE -3 /* Key passed is not valid */ -#define BAD_CIPHER_MODE -4 /* Params struct passed to cipherInit invalid */ -#define BAD_CIPHER_STATE -5 /* Cipher in wrong state (e.g., not initialized) */ -#define BAD_BLOCK_LENGTH -6 -#define BAD_CIPHER_INSTANCE -7 -#define BAD_DATA -8 /* Data contents are invalid, e.g., invalid padding */ -#define BAD_OTHER -9 /* Unknown error */ - -/* Algorithm-specific Defines */ -#define MAX_KEY_SIZE 64 /* # of ASCII char's needed to represent a key */ -#define MAX_IV_SIZE 16 /* # bytes needed to represent an IV */ - -/* Typedefs */ - -/* The structure for key information */ -typedef struct { - u_int8_t direction; /* Key used for encrypting or decrypting? */ - int keyLen; /* Length of the key */ - char keyMaterial[MAX_KEY_SIZE+1]; /* Raw key data in ASCII, e.g., user input or KAT values */ - int Nr; /* key-length-dependent number of rounds */ - u32 rk[4*(MAXNR + 1)]; /* key schedule */ - u32 ek[4*(MAXNR + 1)]; /* CFB1 key schedule (encryption only) */ -} keyInstance; - -/* The structure for cipher information */ -typedef struct { /* changed order of the components */ - u_int8_t mode; /* MODE_ECB, MODE_CBC, or MODE_CFB1 */ - u_int8_t IV[MAX_IV_SIZE]; /* A possible Initialization Vector for ciphering */ -} cipherInstance; - -#endif /* __RIJNDAEL_API_FST_H */ diff --git a/storage/bdb/cxx/cxx_db.cpp b/storage/bdb/cxx/cxx_db.cpp deleted file mode 100644 index 03e07f4d238..00000000000 --- a/storage/bdb/cxx/cxx_db.cpp +++ /dev/null @@ -1,657 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: cxx_db.cpp,v 12.4 2005/10/18 14:25:53 mjc Exp $ - */ - -#include "db_config.h" - -#include <errno.h> -#include <string.h> - -#include "db_cxx.h" -#include "dbinc/cxx_int.h" - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc_auto/db_auto.h" -#include "dbinc_auto/crdel_auto.h" -#include "dbinc/db_dispatch.h" -#include "dbinc_auto/db_ext.h" -#include "dbinc_auto/common_ext.h" - -// Helper macros for simple methods that pass through to the -// underlying C method. It may return an error or raise an exception. -// Note this macro expects that input _argspec is an argument -// list element (e.g., "char *arg") and that _arglist is the arguments -// that should be passed through to the C method (e.g., "(db, arg)") -// -#define DB_METHOD(_name, _argspec, _arglist, _retok) \ -int Db::_name _argspec \ -{ \ - int ret; \ - DB *db = unwrap(this); \ - \ - ret = db->_name _arglist; \ - if (!_retok(ret)) \ - DB_ERROR(env_, "Db::" # _name, ret, error_policy()); \ - return (ret); \ -} - -#define DB_DESTRUCTOR(_name, _argspec, _arglist, _retok) \ -int Db::_name _argspec \ -{ \ - int ret; \ - DB *db = unwrap(this); \ - \ - if (!db) { \ - DB_ERROR(env_, "Db::" # _name, EINVAL, error_policy()); \ - return (EINVAL); \ - } \ - cleanup(); \ - ret = db->_name _arglist; \ - if (!_retok(ret)) \ - DB_ERROR(env_, "Db::" # _name, ret, error_policy()); \ - return (ret); \ -} - -#define DB_METHOD_QUIET(_name, _argspec, _arglist) \ -int Db::_name _argspec \ -{ \ - DB *db = unwrap(this); \ - \ - return (db->_name _arglist); \ -} - -#define DB_METHOD_VOID(_name, _argspec, _arglist) \ -void Db::_name _argspec \ -{ \ - DB *db = unwrap(this); \ - \ - db->_name _arglist; \ -} - -// A truism for the Db object is that there is a valid -// DB handle from the constructor until close(). -// After the close, the DB handle is invalid and -// no operations are permitted on the Db (other than -// destructor). Leaving the Db handle open and not -// doing a close is generally considered an error. -// -// We used to allow Db objects to be closed and reopened. -// This implied always keeping a valid DB object, and -// coordinating the open objects between Db/DbEnv turned -// out to be overly complicated. Now we do not allow this. - -Db::Db(DbEnv *env, u_int32_t flags) -: imp_(0) -, env_(env) -, mpf_(0) -, construct_error_(0) -, flags_(0) -, construct_flags_(flags) -, append_recno_callback_(0) -, associate_callback_(0) -, bt_compare_callback_(0) -, bt_prefix_callback_(0) -, dup_compare_callback_(0) -, feedback_callback_(0) -, h_hash_callback_(0) -{ - if (env_ == 0) - flags_ |= DB_CXX_PRIVATE_ENV; - - if ((construct_error_ = initialize()) != 0) - DB_ERROR(env_, "Db::Db", construct_error_, error_policy()); -} - -// If the DB handle is still open, we close it. This is to make stack -// allocation of Db objects easier so that they are cleaned up in the error -// path. If the environment was closed prior to this, it may cause a trap, but -// an error message is generated during the environment close. Applications -// should call close explicitly in normal (non-exceptional) cases to check the -// return value. -// -Db::~Db() -{ - DB *db; - - db = unwrap(this); - if (db != NULL) { - cleanup(); - (void)db->close(db, 0); - } -} - -// private method to initialize during constructor. -// initialize must create a backing DB object, -// and if that creates a new DB_ENV, it must be tied to a new DbEnv. -// -int Db::initialize() -{ - DB *db; - DB_ENV *cenv = unwrap(env_); - int ret; - u_int32_t cxx_flags; - - cxx_flags = construct_flags_ & DB_CXX_NO_EXCEPTIONS; - - // Create a new underlying DB object. - // We rely on the fact that if a NULL DB_ENV* is given, - // one is allocated by DB. - // - if ((ret = db_create(&db, cenv, - construct_flags_ & ~cxx_flags)) != 0) - return (ret); - - // Associate the DB with this object - imp_ = db; - db->api_internal = this; - - // Create a new DbEnv from a DB_ENV* if it was created locally. - // It is deleted in Db::close(). - // - if ((flags_ & DB_CXX_PRIVATE_ENV) != 0) - env_ = new DbEnv(db->dbenv, cxx_flags); - - // Create a DbMpoolFile from the DB_MPOOLFILE* in the DB handle. - mpf_ = new DbMpoolFile(); - mpf_->imp_ = db->mpf; - - return (0); -} - -// private method to cleanup after destructor or during close. -// If the environment was created by this Db object, we optionally -// delete it, or return it so the caller can delete it after -// last use. -// -void Db::cleanup() -{ - DB *db = unwrap(this); - - if (db != NULL) { - // extra safety - imp_ = 0; - - // we must dispose of the DbEnv object if - // we created it. This will be the case - // if a NULL DbEnv was passed into the constructor. - // The underlying DB_ENV object will be inaccessible - // after the close, so we must clean it up now. - // - if ((flags_ & DB_CXX_PRIVATE_ENV) != 0) { - env_->cleanup(); - delete env_; - env_ = 0; - } - - delete mpf_; - } -} - -// Return a tristate value corresponding to whether we should -// throw exceptions on errors: -// ON_ERROR_RETURN -// ON_ERROR_THROW -// ON_ERROR_UNKNOWN -// -int Db::error_policy() -{ - if (env_ != NULL) - return (env_->error_policy()); - else { - // If the env_ is null, that means that the user - // did not attach an environment, so the correct error - // policy can be deduced from constructor flags - // for this Db. - // - if ((construct_flags_ & DB_CXX_NO_EXCEPTIONS) != 0) { - return (ON_ERROR_RETURN); - } - else { - return (ON_ERROR_THROW); - } - } -} - -DB_DESTRUCTOR(close, (u_int32_t flags), (db, flags), DB_RETOK_STD) -DB_METHOD(compact, (DbTxn *txnid, Dbt *start, Dbt *stop, - DB_COMPACT *c_data, u_int32_t flags, Dbt *end), - (db, unwrap(txnid), start, stop, c_data, flags, end), DB_RETOK_STD) - -// The following cast implies that Dbc can be no larger than DBC -DB_METHOD(cursor, (DbTxn *txnid, Dbc **cursorp, u_int32_t flags), - (db, unwrap(txnid), (DBC **)cursorp, flags), - DB_RETOK_STD) - -DB_METHOD(del, (DbTxn *txnid, Dbt *key, u_int32_t flags), - (db, unwrap(txnid), key, flags), - DB_RETOK_DBDEL) - -void Db::err(int error, const char *format, ...) -{ - DB *db = unwrap(this); - - DB_REAL_ERR(db->dbenv, error, 1, 1, format); -} - -void Db::errx(const char *format, ...) -{ - DB *db = unwrap(this); - - DB_REAL_ERR(db->dbenv, 0, 0, 1, format); -} - -DB_METHOD(fd, (int *fdp), (db, fdp), DB_RETOK_STD) - -int Db::get(DbTxn *txnid, Dbt *key, Dbt *value, u_int32_t flags) -{ - DB *db = unwrap(this); - int ret; - - ret = db->get(db, unwrap(txnid), key, value, flags); - - if (!DB_RETOK_DBGET(ret)) { - if (ret == DB_BUFFER_SMALL) - DB_ERROR_DBT(env_, "Db::get", value, error_policy()); - else - DB_ERROR(env_, "Db::get", ret, error_policy()); - } - - return (ret); -} - -int Db::get_byteswapped(int *isswapped) -{ - DB *db = (DB *)unwrapConst(this); - return (db->get_byteswapped(db, isswapped)); -} - -DbEnv *Db::get_env() -{ - DB *db = (DB *)unwrapConst(this); - DB_ENV *dbenv = db->get_env(db); - return (dbenv != NULL ? DbEnv::get_DbEnv(dbenv) : NULL); -} - -DbMpoolFile *Db::get_mpf() -{ - return (mpf_); -} - -DB_METHOD(get_dbname, (const char **filenamep, const char **dbnamep), - (db, filenamep, dbnamep), DB_RETOK_STD) - -DB_METHOD(get_open_flags, (u_int32_t *flagsp), (db, flagsp), DB_RETOK_STD) - -int Db::get_type(DBTYPE *dbtype) -{ - DB *db = (DB *)unwrapConst(this); - return (db->get_type(db, dbtype)); -} - -// Dbc is a "compatible" subclass of DBC - that is, no virtual functions -// or even extra data members, so these casts, although technically -// non-portable, "should" always be okay. -DB_METHOD(join, (Dbc **curslist, Dbc **cursorp, u_int32_t flags), - (db, (DBC **)curslist, (DBC **)cursorp, flags), DB_RETOK_STD) - -DB_METHOD(key_range, - (DbTxn *txnid, Dbt *key, DB_KEY_RANGE *results, u_int32_t flags), - (db, unwrap(txnid), key, results, flags), DB_RETOK_STD) - -// If an error occurred during the constructor, report it now. -// Otherwise, call the underlying DB->open method. -// -int Db::open(DbTxn *txnid, const char *file, const char *database, - DBTYPE type, u_int32_t flags, int mode) -{ - int ret; - DB *db = unwrap(this); - - if (construct_error_ != 0) - ret = construct_error_; - else - ret = db->open(db, unwrap(txnid), file, database, type, flags, - mode); - - if (!DB_RETOK_STD(ret)) - DB_ERROR(env_, "Db::open", ret, error_policy()); - - return (ret); -} - -int Db::pget(DbTxn *txnid, Dbt *key, Dbt *pkey, Dbt *value, u_int32_t flags) -{ - DB *db = unwrap(this); - int ret; - - ret = db->pget(db, unwrap(txnid), key, pkey, value, flags); - - /* The logic here is identical to Db::get - reuse the macro. */ - if (!DB_RETOK_DBGET(ret)) { - if (ret == DB_BUFFER_SMALL && DB_OVERFLOWED_DBT(value)) - DB_ERROR_DBT(env_, "Db::pget", value, error_policy()); - else - DB_ERROR(env_, "Db::pget", ret, error_policy()); - } - - return (ret); -} - -DB_METHOD(put, (DbTxn *txnid, Dbt *key, Dbt *value, u_int32_t flags), - (db, unwrap(txnid), key, value, flags), DB_RETOK_DBPUT) - -DB_DESTRUCTOR(rename, - (const char *file, const char *database, const char *newname, - u_int32_t flags), - (db, file, database, newname, flags), DB_RETOK_STD) - -DB_DESTRUCTOR(remove, (const char *file, const char *database, u_int32_t flags), - (db, file, database, flags), DB_RETOK_STD) - -DB_METHOD(truncate, (DbTxn *txnid, u_int32_t *countp, u_int32_t flags), - (db, unwrap(txnid), countp, flags), DB_RETOK_STD) - -DB_METHOD(stat, (DbTxn *txnid, void *sp, u_int32_t flags), - (db, unwrap(txnid), sp, flags), DB_RETOK_STD) - -DB_METHOD(stat_print, (u_int32_t flags), (db, flags), DB_RETOK_STD) - -DB_METHOD(sync, (u_int32_t flags), (db, flags), DB_RETOK_STD) - -DB_METHOD(upgrade, - (const char *name, u_int32_t flags), (db, name, flags), DB_RETOK_STD) - -//////////////////////////////////////////////////////////////////////// -// -// callbacks -// -// *_intercept_c are 'glue' functions that must be declared -// as extern "C" so to be typesafe. Using a C++ method, even -// a static class method with 'correct' arguments, will not pass -// the test; some picky compilers do not allow mixing of function -// pointers to 'C' functions with function pointers to C++ functions. -// -// One wart with this scheme is that the *_callback_ method pointer -// must be declared public to be accessible by the C intercept. -// It's possible to accomplish the goal without this, and with -// another public transfer method, but it's just too much overhead. -// These callbacks are supposed to be *fast*. -// -// The DBTs we receive in these callbacks from the C layer may be -// manufactured there, but we want to treat them as a Dbts. -// Technically speaking, these DBTs were not constructed as a Dbts, -// but it should be safe to cast them as such given that Dbt is a -// *very* thin extension of the DBT. That is, Dbt has no additional -// data elements, does not use virtual functions, virtual inheritance, -// multiple inheritance, RTI, or any other language feature that -// causes the structure to grow or be displaced. Although this may -// sound risky, a design goal of C++ is complete structure -// compatibility with C, and has the philosophy 'if you don't use it, -// you shouldn't incur the overhead'. If the C/C++ compilers you're -// using on a given machine do not have matching struct layouts, then -// a lot more things will be broken than just this. -// -// The alternative, creating a Dbt here in the callback, and populating -// it from the DBT, is just too slow and cumbersome to be very useful. - -// These macros avoid a lot of boilerplate code for callbacks - -#define DB_CALLBACK_C_INTERCEPT(_name, _rettype, _cargspec, \ - _return, _cxxargs) \ -extern "C" _rettype _db_##_name##_intercept_c _cargspec \ -{ \ - Db *cxxthis; \ - \ - DB_ASSERT(cthis != NULL); \ - cxxthis = Db::get_Db(cthis); \ - DB_ASSERT(cxxthis != NULL); \ - DB_ASSERT(cxxthis->_name##_callback_ != 0); \ - \ - _return (*cxxthis->_name##_callback_) _cxxargs; \ -} - -#define DB_SET_CALLBACK(_cxxname, _name, _cxxargspec, _cb) \ -int Db::_cxxname _cxxargspec \ -{ \ - DB *cthis = unwrap(this); \ - \ - _name##_callback_ = _cb; \ - return ((*(cthis->_cxxname))(cthis, \ - (_cb) ? _db_##_name##_intercept_c : NULL)); \ -} - -/* associate callback - doesn't quite fit the pattern because of the flags */ -DB_CALLBACK_C_INTERCEPT(associate, - int, (DB *cthis, const DBT *key, const DBT *data, DBT *retval), - return, (cxxthis, Dbt::get_const_Dbt(key), Dbt::get_const_Dbt(data), - Dbt::get_Dbt(retval))) - -int Db::associate(DbTxn *txn, Db *secondary, int (*callback)(Db *, const Dbt *, - const Dbt *, Dbt *), u_int32_t flags) -{ - DB *cthis = unwrap(this); - - /* Since the secondary Db is used as the first argument - * to the callback, we store the C++ callback on it - * rather than on 'this'. - */ - secondary->associate_callback_ = callback; - return ((*(cthis->associate))(cthis, unwrap(txn), unwrap(secondary), - (callback) ? _db_associate_intercept_c : NULL, flags)); -} - -DB_CALLBACK_C_INTERCEPT(feedback, - void, (DB *cthis, int opcode, int pct), - /* no return */ (void), (cxxthis, opcode, pct)) - -DB_SET_CALLBACK(set_feedback, feedback, - (void (*arg)(Db *cxxthis, int opcode, int pct)), arg) - -DB_CALLBACK_C_INTERCEPT(append_recno, - int, (DB *cthis, DBT *data, db_recno_t recno), - return, (cxxthis, Dbt::get_Dbt(data), recno)) - -DB_SET_CALLBACK(set_append_recno, append_recno, - (int (*arg)(Db *cxxthis, Dbt *data, db_recno_t recno)), arg) - -DB_CALLBACK_C_INTERCEPT(bt_compare, - int, (DB *cthis, const DBT *data1, const DBT *data2), - return, - (cxxthis, Dbt::get_const_Dbt(data1), Dbt::get_const_Dbt(data2))) - -DB_SET_CALLBACK(set_bt_compare, bt_compare, - (int (*arg)(Db *cxxthis, const Dbt *data1, const Dbt *data2)), arg) - -DB_CALLBACK_C_INTERCEPT(bt_prefix, - size_t, (DB *cthis, const DBT *data1, const DBT *data2), - return, - (cxxthis, Dbt::get_const_Dbt(data1), Dbt::get_const_Dbt(data2))) - -DB_SET_CALLBACK(set_bt_prefix, bt_prefix, - (size_t (*arg)(Db *cxxthis, const Dbt *data1, const Dbt *data2)), arg) - -DB_CALLBACK_C_INTERCEPT(dup_compare, - int, (DB *cthis, const DBT *data1, const DBT *data2), - return, - (cxxthis, Dbt::get_const_Dbt(data1), Dbt::get_const_Dbt(data2))) - -DB_SET_CALLBACK(set_dup_compare, dup_compare, - (int (*arg)(Db *cxxthis, const Dbt *data1, const Dbt *data2)), arg) - -DB_CALLBACK_C_INTERCEPT(h_hash, - u_int32_t, (DB *cthis, const void *data, u_int32_t len), - return, (cxxthis, data, len)) - -DB_SET_CALLBACK(set_h_hash, h_hash, - (u_int32_t (*arg)(Db *cxxthis, const void *data, u_int32_t len)), arg) - -// This is a 'glue' function declared as extern "C" so it will -// be compatible with picky compilers that do not allow mixing -// of function pointers to 'C' functions with function pointers -// to C++ functions. -// -extern "C" -int _verify_callback_c(void *handle, const void *str_arg) -{ - char *str; - __DB_STD(ostream) *out; - - str = (char *)str_arg; - out = (__DB_STD(ostream) *)handle; - - (*out) << str; - if (out->fail()) - return (EIO); - - return (0); -} - -int Db::verify(const char *name, const char *subdb, - __DB_STD(ostream) *ostr, u_int32_t flags) -{ - DB *db = unwrap(this); - int ret; - - if (!db) - ret = EINVAL; - else { - // after a DB->verify (no matter if success or failure), - // the underlying DB object must not be accessed, - // so we clean up in advance. - // - cleanup(); - - ret = __db_verify_internal(db, name, subdb, ostr, - _verify_callback_c, flags); - } - - if (!DB_RETOK_STD(ret)) - DB_ERROR(env_, "Db::verify", ret, error_policy()); - - return (ret); -} - -DB_METHOD(set_bt_compare, (bt_compare_fcn_type func), - (db, func), DB_RETOK_STD) -DB_METHOD(get_bt_minkey, (u_int32_t *bt_minkeyp), - (db, bt_minkeyp), DB_RETOK_STD) -DB_METHOD(set_bt_minkey, (u_int32_t bt_minkey), - (db, bt_minkey), DB_RETOK_STD) -DB_METHOD(set_bt_prefix, (bt_prefix_fcn_type func), - (db, func), DB_RETOK_STD) -DB_METHOD(set_dup_compare, (dup_compare_fcn_type func), - (db, func), DB_RETOK_STD) -DB_METHOD(get_encrypt_flags, (u_int32_t *flagsp), - (db, flagsp), DB_RETOK_STD) -DB_METHOD(set_encrypt, (const char *passwd, u_int32_t flags), - (db, passwd, flags), DB_RETOK_STD) -DB_METHOD_VOID(get_errfile, (FILE **errfilep), (db, errfilep)) -DB_METHOD_VOID(set_errfile, (FILE *errfile), (db, errfile)) -DB_METHOD_VOID(get_errpfx, (const char **errpfx), (db, errpfx)) -DB_METHOD_VOID(set_errpfx, (const char *errpfx), (db, errpfx)) -DB_METHOD(get_flags, (u_int32_t *flagsp), (db, flagsp), - DB_RETOK_STD) -DB_METHOD(set_flags, (u_int32_t flags), (db, flags), - DB_RETOK_STD) -DB_METHOD(get_h_ffactor, (u_int32_t *h_ffactorp), - (db, h_ffactorp), DB_RETOK_STD) -DB_METHOD(set_h_ffactor, (u_int32_t h_ffactor), - (db, h_ffactor), DB_RETOK_STD) -DB_METHOD(set_h_hash, (h_hash_fcn_type func), - (db, func), DB_RETOK_STD) -DB_METHOD(get_h_nelem, (u_int32_t *h_nelemp), - (db, h_nelemp), DB_RETOK_STD) -DB_METHOD(set_h_nelem, (u_int32_t h_nelem), - (db, h_nelem), DB_RETOK_STD) -DB_METHOD(get_lorder, (int *db_lorderp), (db, db_lorderp), - DB_RETOK_STD) -DB_METHOD(set_lorder, (int db_lorder), (db, db_lorder), - DB_RETOK_STD) -DB_METHOD_VOID(get_msgfile, (FILE **msgfilep), (db, msgfilep)) -DB_METHOD_VOID(set_msgfile, (FILE *msgfile), (db, msgfile)) -DB_METHOD(get_pagesize, (u_int32_t *db_pagesizep), - (db, db_pagesizep), DB_RETOK_STD) -DB_METHOD(set_pagesize, (u_int32_t db_pagesize), - (db, db_pagesize), DB_RETOK_STD) -DB_METHOD(get_re_delim, (int *re_delimp), - (db, re_delimp), DB_RETOK_STD) -DB_METHOD(set_re_delim, (int re_delim), - (db, re_delim), DB_RETOK_STD) -DB_METHOD(get_re_len, (u_int32_t *re_lenp), - (db, re_lenp), DB_RETOK_STD) -DB_METHOD(set_re_len, (u_int32_t re_len), - (db, re_len), DB_RETOK_STD) -DB_METHOD(get_re_pad, (int *re_padp), - (db, re_padp), DB_RETOK_STD) -DB_METHOD(set_re_pad, (int re_pad), - (db, re_pad), DB_RETOK_STD) -DB_METHOD(get_re_source, (const char **re_source), - (db, re_source), DB_RETOK_STD) -DB_METHOD(set_re_source, (const char *re_source), - (db, re_source), DB_RETOK_STD) -DB_METHOD(get_q_extentsize, (u_int32_t *extentsizep), - (db, extentsizep), DB_RETOK_STD) -DB_METHOD(set_q_extentsize, (u_int32_t extentsize), - (db, extentsize), DB_RETOK_STD) - -DB_METHOD_QUIET(set_alloc, (db_malloc_fcn_type malloc_fcn, - db_realloc_fcn_type realloc_fcn, db_free_fcn_type free_fcn), - (db, malloc_fcn, realloc_fcn, free_fcn)) - -void Db::set_errcall(void (*arg)(const DbEnv *, const char *, const char *)) -{ - env_->set_errcall(arg); -} - -void Db::set_msgcall(void (*arg)(const DbEnv *, const char *)) -{ - env_->set_msgcall(arg); -} - -void *Db::get_app_private() const -{ - return unwrapConst(this)->app_private; -} - -void Db::set_app_private(void *value) -{ - unwrap(this)->app_private = value; -} - -DB_METHOD(get_cachesize, (u_int32_t *gbytesp, u_int32_t *bytesp, int *ncachep), - (db, gbytesp, bytesp, ncachep), DB_RETOK_STD) -DB_METHOD(set_cachesize, (u_int32_t gbytes, u_int32_t bytes, int ncache), - (db, gbytes, bytes, ncache), DB_RETOK_STD) - -int Db::set_paniccall(void (*callback)(DbEnv *, int)) -{ - return (env_->set_paniccall(callback)); -} - -__DB_STD(ostream) *Db::get_error_stream() -{ - return env_->get_error_stream(); -} - -void Db::set_error_stream(__DB_STD(ostream) *error_stream) -{ - env_->set_error_stream(error_stream); -} - -__DB_STD(ostream) *Db::get_message_stream() -{ - return env_->get_message_stream(); -} - -void Db::set_message_stream(__DB_STD(ostream) *message_stream) -{ - env_->set_message_stream(message_stream); -} - -DB_METHOD_QUIET(get_transactional, (), (db)) diff --git a/storage/bdb/cxx/cxx_dbc.cpp b/storage/bdb/cxx/cxx_dbc.cpp deleted file mode 100644 index 8f73557222a..00000000000 --- a/storage/bdb/cxx/cxx_dbc.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: cxx_dbc.cpp,v 12.2 2005/09/30 07:38:25 mjc Exp $ - */ - -#include "db_config.h" - -#include <errno.h> -#include <string.h> - -#include "db_cxx.h" -#include "dbinc/cxx_int.h" - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc_auto/db_auto.h" -#include "dbinc_auto/crdel_auto.h" -#include "dbinc/db_dispatch.h" -#include "dbinc_auto/db_ext.h" -#include "dbinc_auto/common_ext.h" - -// Helper macro for simple methods that pass through to the -// underlying C method. It may return an error or raise an exception. -// Note this macro expects that input _argspec is an argument -// list element (e.g., "char *arg") and that _arglist is the arguments -// that should be passed through to the C method (e.g., "(db, arg)") -// -#define DBC_METHOD(_name, _argspec, _arglist, _retok) \ -int Dbc::_name _argspec \ -{ \ - int ret; \ - DBC *dbc = this; \ - \ - ret = dbc->c_##_name _arglist; \ - if (!_retok(ret)) \ - DB_ERROR(DbEnv::get_DbEnv(dbc->dbp->dbenv), \ - "Dbc::" # _name, ret, ON_ERROR_UNKNOWN); \ - return (ret); \ -} - -// It's private, and should never be called, but VC4.0 needs it resolved -// -Dbc::~Dbc() -{ -} - -DBC_METHOD(close, (void), (dbc), DB_RETOK_STD) -DBC_METHOD(count, (db_recno_t *countp, u_int32_t _flags), - (dbc, countp, _flags), DB_RETOK_STD) -DBC_METHOD(del, (u_int32_t _flags), - (dbc, _flags), DB_RETOK_DBCDEL) - -int Dbc::dup(Dbc** cursorp, u_int32_t _flags) -{ - int ret; - DBC *dbc = this; - DBC *new_cursor = 0; - - ret = dbc->c_dup(dbc, &new_cursor, _flags); - - if (DB_RETOK_STD(ret)) - // The following cast implies that Dbc can be no larger than DBC - *cursorp = (Dbc*)new_cursor; - else - DB_ERROR(DbEnv::get_DbEnv(dbc->dbp->dbenv), - "Dbc::dup", ret, ON_ERROR_UNKNOWN); - - return (ret); -} - -int Dbc::get(Dbt* key, Dbt *data, u_int32_t _flags) -{ - int ret; - DBC *dbc = this; - - ret = dbc->c_get(dbc, key, data, _flags); - - if (!DB_RETOK_DBCGET(ret)) { - if (ret == DB_BUFFER_SMALL && DB_OVERFLOWED_DBT(key)) - DB_ERROR_DBT(DbEnv::get_DbEnv(dbc->dbp->dbenv), - "Dbc::get", key, ON_ERROR_UNKNOWN); - else if (ret == DB_BUFFER_SMALL && DB_OVERFLOWED_DBT(data)) - DB_ERROR_DBT(DbEnv::get_DbEnv(dbc->dbp->dbenv), - "Dbc::get", data, ON_ERROR_UNKNOWN); - else - DB_ERROR(DbEnv::get_DbEnv(dbc->dbp->dbenv), - "Dbc::get", ret, ON_ERROR_UNKNOWN); - } - - return (ret); -} - -int Dbc::pget(Dbt* key, Dbt *pkey, Dbt *data, u_int32_t _flags) -{ - int ret; - DBC *dbc = this; - - ret = dbc->c_pget(dbc, key, pkey, data, _flags); - - /* Logic is the same as for Dbc::get - reusing macro. */ - if (!DB_RETOK_DBCGET(ret)) { - if (ret == DB_BUFFER_SMALL && DB_OVERFLOWED_DBT(key)) - DB_ERROR_DBT(DbEnv::get_DbEnv(dbc->dbp->dbenv), - "Dbc::pget", key, ON_ERROR_UNKNOWN); - else if (ret == DB_BUFFER_SMALL && DB_OVERFLOWED_DBT(data)) - DB_ERROR_DBT(DbEnv::get_DbEnv(dbc->dbp->dbenv), - "Dbc::pget", data, ON_ERROR_UNKNOWN); - else - DB_ERROR(DbEnv::get_DbEnv(dbc->dbp->dbenv), - "Dbc::pget", ret, ON_ERROR_UNKNOWN); - } - - return (ret); -} - -DBC_METHOD(put, (Dbt* key, Dbt *data, u_int32_t _flags), - (dbc, key, data, _flags), DB_RETOK_DBCPUT) diff --git a/storage/bdb/cxx/cxx_dbt.cpp b/storage/bdb/cxx/cxx_dbt.cpp deleted file mode 100644 index 8062c255be5..00000000000 --- a/storage/bdb/cxx/cxx_dbt.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: cxx_dbt.cpp,v 12.1 2005/06/16 20:20:58 bostic Exp $ - */ - -#include "db_config.h" - -#include <errno.h> -#include <string.h> - -#include "db_cxx.h" -#include "dbinc/cxx_int.h" - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc_auto/db_auto.h" -#include "dbinc_auto/crdel_auto.h" -#include "dbinc/db_dispatch.h" -#include "dbinc_auto/db_ext.h" -#include "dbinc_auto/common_ext.h" - -Dbt::Dbt() -{ - DBT *dbt = this; - memset(dbt, 0, sizeof(DBT)); -} - -Dbt::Dbt(void *data_arg, u_int32_t size_arg) -{ - DBT *dbt = this; - memset(dbt, 0, sizeof(DBT)); - set_data(data_arg); - set_size(size_arg); -} - -Dbt::~Dbt() -{ -} - -Dbt::Dbt(const Dbt &that) -{ - const DBT *from = &that; - DBT *to = this; - memcpy(to, from, sizeof(DBT)); -} - -Dbt &Dbt::operator = (const Dbt &that) -{ - if (this != &that) { - const DBT *from = &that; - DBT *to = this; - memcpy(to, from, sizeof(DBT)); - } - return (*this); -} diff --git a/storage/bdb/cxx/cxx_env.cpp b/storage/bdb/cxx/cxx_env.cpp deleted file mode 100644 index 62bbb0de381..00000000000 --- a/storage/bdb/cxx/cxx_env.cpp +++ /dev/null @@ -1,1054 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: cxx_env.cpp,v 12.14 2005/10/18 14:49:27 mjc Exp $ - */ - -#include "db_config.h" - -#include <errno.h> -#include <stdio.h> // needed for set_error_stream -#include <string.h> - -#include "db_cxx.h" -#include "dbinc/cxx_int.h" - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_am.h" -#include "dbinc/log.h" -#include "dbinc_auto/common_ext.h" -#include "dbinc_auto/log_ext.h" - -#ifdef HAVE_CXX_STDHEADERS -using std::cerr; -#endif - -// Helper macros for simple methods that pass through to the -// underlying C method. They may return an error or raise an exception. -// These macros expect that input _argspec is an argument -// list element (e.g., "char *arg") and that _arglist is the arguments -// that should be passed through to the C method (e.g., "(dbenv, arg)") -// -#define DBENV_METHOD_ERR(_name, _argspec, _arglist, _on_err) \ -int DbEnv::_name _argspec \ -{ \ - DB_ENV *dbenv = unwrap(this); \ - int ret; \ - \ - if ((ret = dbenv->_name _arglist) != 0) { \ - _on_err; \ - } \ - return (ret); \ -} - -#define DBENV_METHOD(_name, _argspec, _arglist) \ - DBENV_METHOD_ERR(_name, _argspec, _arglist, \ - DB_ERROR(this, "DbEnv::" # _name, ret, error_policy())) - -#define DBENV_METHOD_QUIET(_name, _argspec, _arglist) \ -int DbEnv::_name _argspec \ -{ \ - DB_ENV *dbenv = unwrap(this); \ - \ - return (dbenv->_name _arglist); \ -} - -#define DBENV_METHOD_VOID(_name, _argspec, _arglist) \ -void DbEnv::_name _argspec \ -{ \ - DB_ENV *dbenv = unwrap(this); \ - \ - dbenv->_name _arglist; \ -} - -// The reason for a static variable is that some structures -// (like Dbts) have no connection to any Db or DbEnv, so when -// errors occur in their methods, we must have some reasonable -// way to determine whether to throw or return errors. -// -// This variable is taken from flags whenever a DbEnv is constructed. -// Normally there is only one DbEnv per program, and even if not, -// there is typically a single policy of throwing or returning. -// -static int last_known_error_policy = ON_ERROR_UNKNOWN; - -// These 'glue' function are declared as extern "C" so they will -// be compatible with picky compilers that do not allow mixing -// of function pointers to 'C' functions with function pointers -// to C++ functions. -// -extern "C" -void _feedback_intercept_c(DB_ENV *env, int opcode, int pct) -{ - DbEnv::_feedback_intercept(env, opcode, pct); -} - -extern "C" -void _paniccall_intercept_c(DB_ENV *env, int errval) -{ - DbEnv::_paniccall_intercept(env, errval); -} - -extern "C" -void _stream_error_function_c(const DB_ENV *env, - const char *prefix, const char *message) -{ - DbEnv::_stream_error_function(env, prefix, message); -} - -extern "C" -void _stream_message_function_c(const DB_ENV *env, const char *message) -{ - DbEnv::_stream_message_function(env, message); -} - -extern "C" -int _app_dispatch_intercept_c(DB_ENV *env, DBT *dbt, DB_LSN *lsn, db_recops op) -{ - return (DbEnv::_app_dispatch_intercept(env, dbt, lsn, op)); -} - -extern "C" -int _rep_send_intercept_c(DB_ENV *env, const DBT *cntrl, const DBT *data, - const DB_LSN *lsn, int id, u_int32_t flags) -{ - return (DbEnv::_rep_send_intercept(env, - cntrl, data, lsn, id, flags)); -} - -extern "C" -int _isalive_intercept_c(DB_ENV *env, pid_t pid, db_threadid_t thrid) -{ - return (DbEnv::_isalive_intercept(env, pid, thrid)); -} - -extern "C" -void _thread_id_intercept_c(DB_ENV *env, pid_t *pidp, db_threadid_t *thridp) -{ - DbEnv::_thread_id_intercept(env, pidp, thridp); -} - -extern "C" -char *_thread_id_string_intercept_c(DB_ENV *env, pid_t pid, - db_threadid_t thrid, char *buf) -{ - return (DbEnv::_thread_id_string_intercept(env, pid, thrid, buf)); -} - -void DbEnv::_feedback_intercept(DB_ENV *env, int opcode, int pct) -{ - DbEnv *cxxenv = DbEnv::get_DbEnv(env); - if (cxxenv == 0) { - DB_ERROR(0, - "DbEnv::feedback_callback", EINVAL, ON_ERROR_UNKNOWN); - return; - } - if (cxxenv->feedback_callback_ == 0) { - DB_ERROR(DbEnv::get_DbEnv(env), - "DbEnv::feedback_callback", EINVAL, cxxenv->error_policy()); - return; - } - (*cxxenv->feedback_callback_)(cxxenv, opcode, pct); -} - -void DbEnv::_paniccall_intercept(DB_ENV *env, int errval) -{ - DbEnv *cxxenv = DbEnv::get_DbEnv(env); - if (cxxenv == 0) { - DB_ERROR(0, - "DbEnv::paniccall_callback", EINVAL, ON_ERROR_UNKNOWN); - return; - } - if (cxxenv->paniccall_callback_ == 0) { - DB_ERROR(cxxenv, "DbEnv::paniccall_callback", EINVAL, - cxxenv->error_policy()); - return; - } - (*cxxenv->paniccall_callback_)(cxxenv, errval); -} - -int DbEnv::_app_dispatch_intercept(DB_ENV *env, DBT *dbt, DB_LSN *lsn, - db_recops op) -{ - DbEnv *cxxenv = DbEnv::get_DbEnv(env); - if (cxxenv == 0) { - DB_ERROR(DbEnv::get_DbEnv(env), - "DbEnv::app_dispatch_callback", EINVAL, ON_ERROR_UNKNOWN); - return (EINVAL); - } - if (cxxenv->app_dispatch_callback_ == 0) { - DB_ERROR(DbEnv::get_DbEnv(env), - "DbEnv::app_dispatch_callback", EINVAL, - cxxenv->error_policy()); - return (EINVAL); - } - Dbt *cxxdbt = (Dbt *)dbt; - DbLsn *cxxlsn = (DbLsn *)lsn; - return ((*cxxenv->app_dispatch_callback_)(cxxenv, cxxdbt, cxxlsn, op)); -} - -int DbEnv::_isalive_intercept(DB_ENV *env, pid_t pid, db_threadid_t thrid) -{ - DbEnv *cxxenv = DbEnv::get_DbEnv(env); - if (cxxenv == 0) { - DB_ERROR(DbEnv::get_DbEnv(env), - "DbEnv::isalive_callback", EINVAL, ON_ERROR_UNKNOWN); - return (0); - } - return ((*cxxenv->isalive_callback_)(cxxenv, pid, thrid)); -} - -int DbEnv::_rep_send_intercept(DB_ENV *env, const DBT *cntrl, const DBT *data, - const DB_LSN *lsn, int id, u_int32_t flags) -{ - DbEnv *cxxenv = DbEnv::get_DbEnv(env); - if (cxxenv == 0) { - DB_ERROR(DbEnv::get_DbEnv(env), - "DbEnv::rep_send_callback", EINVAL, ON_ERROR_UNKNOWN); - return (EINVAL); - } - const Dbt *cxxcntrl = (const Dbt *)cntrl; - const DbLsn *cxxlsn = (const DbLsn *)lsn; - Dbt *cxxdata = (Dbt *)data; - return ((*cxxenv->rep_send_callback_)(cxxenv, - cxxcntrl, cxxdata, cxxlsn, id, flags)); -} - -void DbEnv::_thread_id_intercept(DB_ENV *env, pid_t *pidp, db_threadid_t *thridp) -{ - DbEnv *cxxenv = DbEnv::get_DbEnv(env); - if (cxxenv == 0) { - DB_ERROR(DbEnv::get_DbEnv(env), - "DbEnv::thread_id_callback", EINVAL, ON_ERROR_UNKNOWN); - } else - cxxenv->thread_id_callback_(cxxenv, pidp, thridp); -} - -char *DbEnv::_thread_id_string_intercept(DB_ENV *env, pid_t pid, - db_threadid_t thrid, char *buf) -{ - DbEnv *cxxenv = DbEnv::get_DbEnv(env); - if (cxxenv == 0) { - DB_ERROR(DbEnv::get_DbEnv(env), - "DbEnv::thread_id_string_callback", EINVAL, ON_ERROR_UNKNOWN); - return (NULL); - } - return (cxxenv->thread_id_string_callback_(cxxenv, pid, thrid, buf)); -} - -// A truism for the DbEnv object is that there is a valid -// DB_ENV handle from the constructor until close(). -// After the close, the DB_ENV handle is invalid and -// no operations are permitted on the DbEnv (other than -// destructor). Leaving the DbEnv handle open and not -// doing a close is generally considered an error. -// -// We used to allow DbEnv objects to be closed and reopened. -// This implied always keeping a valid DB_ENV object, and -// coordinating the open objects between Db/DbEnv turned -// out to be overly complicated. Now we do not allow this. - -DbEnv::DbEnv(u_int32_t flags) -: imp_(0) -, construct_error_(0) -, construct_flags_(flags) -, error_stream_(0) -, message_stream_(0) -, app_dispatch_callback_(0) -, feedback_callback_(0) -, paniccall_callback_(0) -, rep_send_callback_(0) -{ - if ((construct_error_ = initialize(0)) != 0) - DB_ERROR(this, "DbEnv::DbEnv", construct_error_, - error_policy()); -} - -DbEnv::DbEnv(DB_ENV *env, u_int32_t flags) -: imp_(0) -, construct_error_(0) -, construct_flags_(flags) -, error_stream_(0) -, message_stream_(0) -, app_dispatch_callback_(0) -, feedback_callback_(0) -, paniccall_callback_(0) -, rep_send_callback_(0) -{ - if ((construct_error_ = initialize(env)) != 0) - DB_ERROR(this, "DbEnv::DbEnv", construct_error_, - error_policy()); -} - -// If the DB_ENV handle is still open, we close it. This is to make stack -// allocation of DbEnv objects easier so that they are cleaned up in the error -// path. Note that the C layer catches cases where handles are open in the -// environment at close time and reports an error. Applications should call -// close explicitly in normal (non-exceptional) cases to check the return -// value. -// -DbEnv::~DbEnv() -{ - DB_ENV *env = unwrap(this); - - if (env != NULL) { - cleanup(); - (void)env->close(env, 0); - } -} - -// called by destructors before the DB_ENV is destroyed. -void DbEnv::cleanup() -{ - DB_ENV *env = unwrap(this); - - if (env != NULL) { - env->api1_internal = 0; - imp_ = 0; - } -} - -int DbEnv::close(u_int32_t flags) -{ - int ret; - DB_ENV *env = unwrap(this); - - // after a close (no matter if success or failure), - // the underlying DB_ENV object must not be accessed, - // so we clean up in advance. - // - cleanup(); - - // It's safe to throw an error after the close, - // since our error mechanism does not peer into - // the DB* structures. - // - if ((ret = env->close(env, flags)) != 0) - DB_ERROR(this, "DbEnv::close", ret, error_policy()); - - return (ret); -} - -DBENV_METHOD(dbremove, - (DbTxn *txn, const char *name, const char *subdb, u_int32_t flags), - (dbenv, unwrap(txn), name, subdb, flags)) -DBENV_METHOD(dbrename, (DbTxn *txn, const char *name, const char *subdb, - const char *newname, u_int32_t flags), - (dbenv, unwrap(txn), name, subdb, newname, flags)) - -void DbEnv::err(int error, const char *format, ...) -{ - DB_ENV *env = unwrap(this); - - DB_REAL_ERR(env, error, 1, 1, format); -} - -// Return a tristate value corresponding to whether we should -// throw exceptions on errors: -// ON_ERROR_RETURN -// ON_ERROR_THROW -// ON_ERROR_UNKNOWN -// -int DbEnv::error_policy() -{ - if ((construct_flags_ & DB_CXX_NO_EXCEPTIONS) != 0) { - return (ON_ERROR_RETURN); - } - else { - return (ON_ERROR_THROW); - } -} - -void DbEnv::errx(const char *format, ...) -{ - DB_ENV *env = unwrap(this); - - DB_REAL_ERR(env, 0, 0, 1, format); -} - -void *DbEnv::get_app_private() const -{ - return unwrapConst(this)->app_private; -} - -DBENV_METHOD(failchk, (u_int32_t flags), (dbenv, flags)) -DBENV_METHOD(fileid_reset, (const char *file, u_int32_t flags), - (dbenv, file, flags)) -DBENV_METHOD(get_home, (const char **homep), (dbenv, homep)) -DBENV_METHOD(get_open_flags, (u_int32_t *flagsp), (dbenv, flagsp)) -DBENV_METHOD(get_data_dirs, (const char ***dirspp), (dbenv, dirspp)) - -bool DbEnv::is_bigendian() -{ - return unwrap(this)->is_bigendian() ? true : false; -} - -DBENV_METHOD(set_thread_count, (u_int32_t count), (dbenv, count)) - -// used internally during constructor -// to associate an existing DB_ENV with this DbEnv, -// or create a new one. -// -int DbEnv::initialize(DB_ENV *env) -{ - int ret; - - last_known_error_policy = error_policy(); - - if (env == 0) { - // Create a new DB_ENV environment. - if ((ret = ::db_env_create(&env, - construct_flags_ & ~DB_CXX_NO_EXCEPTIONS)) != 0) - return (ret); - } - imp_ = env; - env->api1_internal = this; // for DB_ENV* to DbEnv* conversion - return (0); -} - -// lock methods -DBENV_METHOD(lock_detect, (u_int32_t flags, u_int32_t atype, int *aborted), - (dbenv, flags, atype, aborted)) -DBENV_METHOD_ERR(lock_get, - (u_int32_t locker, u_int32_t flags, const Dbt *obj, - db_lockmode_t lock_mode, DbLock *lock), - (dbenv, locker, flags, obj, lock_mode, &lock->lock_), - DbEnv::runtime_error_lock_get(this, "DbEnv::lock_get", ret, - DB_LOCK_GET, lock_mode, obj, *lock, - -1, error_policy())) -DBENV_METHOD(lock_id, (u_int32_t *idp), (dbenv, idp)) -DBENV_METHOD(lock_id_free, (u_int32_t id), (dbenv, id)) -DBENV_METHOD(lock_put, (DbLock *lock), (dbenv, &lock->lock_)) -DBENV_METHOD(lock_stat, (DB_LOCK_STAT **statp, u_int32_t flags), - (dbenv, statp, flags)) -DBENV_METHOD(lock_stat_print, (u_int32_t flags), (dbenv, flags)) -DBENV_METHOD_ERR(lock_vec, - (u_int32_t locker, u_int32_t flags, DB_LOCKREQ list[], - int nlist, DB_LOCKREQ **elist_returned), - (dbenv, locker, flags, list, nlist, elist_returned), - DbEnv::runtime_error_lock_get(this, "DbEnv::lock_vec", ret, - (*elist_returned)->op, (*elist_returned)->mode, - Dbt::get_Dbt((*elist_returned)->obj), DbLock((*elist_returned)->lock), - (*elist_returned) - list, error_policy())) -// log methods -DBENV_METHOD(log_archive, (char **list[], u_int32_t flags), - (dbenv, list, flags)) - -int DbEnv::log_compare(const DbLsn *lsn0, const DbLsn *lsn1) -{ - return (::log_compare(lsn0, lsn1)); -} - -// The following cast implies that DbLogc can be no larger than DB_LOGC -DBENV_METHOD(log_cursor, (DbLogc **cursorp, u_int32_t flags), - (dbenv, (DB_LOGC **)cursorp, flags)) -DBENV_METHOD(log_file, (DbLsn *lsn, char *namep, size_t len), - (dbenv, lsn, namep, len)) -DBENV_METHOD(log_flush, (const DbLsn *lsn), (dbenv, lsn)) -DBENV_METHOD(log_put, (DbLsn *lsn, const Dbt *data, u_int32_t flags), - (dbenv, lsn, data, flags)) - -int DbEnv::log_printf(DbTxn *txn, const char *fmt, ...) -{ - DB_ENV *env = unwrap(this); - va_list ap; - int ret; - - va_start(ap, fmt); - ret = __log_printf_pp(env, unwrap(txn), fmt, ap); - va_end(ap); - - return (ret); -} - -DBENV_METHOD(log_stat, (DB_LOG_STAT **spp, u_int32_t flags), - (dbenv, spp, flags)) -DBENV_METHOD(log_stat_print, (u_int32_t flags), (dbenv, flags)) - -DBENV_METHOD(lsn_reset, (const char *file, u_int32_t flags), - (dbenv, file, flags)) - -int DbEnv::memp_fcreate(DbMpoolFile **dbmfp, u_int32_t flags) -{ - DB_ENV *env = unwrap(this); - int ret; - DB_MPOOLFILE *mpf; - - if (env == NULL) - ret = EINVAL; - else - ret = env->memp_fcreate(env, &mpf, flags); - - if (DB_RETOK_STD(ret)) { - *dbmfp = new DbMpoolFile(); - (*dbmfp)->imp_ = mpf; - } else - DB_ERROR(this, "DbMpoolFile::f_create", ret, ON_ERROR_UNKNOWN); - - return (ret); -} - -DBENV_METHOD(memp_register, - (int ftype, pgin_fcn_type pgin_fcn, pgout_fcn_type pgout_fcn), - (dbenv, ftype, pgin_fcn, pgout_fcn)) - -// memory pool methods -DBENV_METHOD(memp_stat, - (DB_MPOOL_STAT **gsp, DB_MPOOL_FSTAT ***fsp, u_int32_t flags), - (dbenv, gsp, fsp, flags)) -DBENV_METHOD(memp_stat_print, (u_int32_t flags), (dbenv, flags)) -DBENV_METHOD(memp_sync, (DbLsn *sn), (dbenv, sn)) -DBENV_METHOD(memp_trickle, (int pct, int *nwrotep), (dbenv, pct, nwrotep)) - -// If an error occurred during the constructor, report it now. -// Otherwise, call the underlying DB->open method. -// -int DbEnv::open(const char *db_home, u_int32_t flags, int mode) -{ - int ret; - DB_ENV *env = unwrap(this); - - if (construct_error_ != 0) - ret = construct_error_; - else - ret = env->open(env, db_home, flags, mode); - - if (!DB_RETOK_STD(ret)) - DB_ERROR(this, "DbEnv::open", ret, error_policy()); - - return (ret); -} - -int DbEnv::remove(const char *db_home, u_int32_t flags) -{ - int ret; - DB_ENV *env = unwrap(this); - - // after a remove (no matter if success or failure), - // the underlying DB_ENV object must not be accessed, - // so we clean up in advance. - // - cleanup(); - - if ((ret = env->remove(env, db_home, flags)) != 0) - DB_ERROR(this, "DbEnv::remove", ret, error_policy()); - - return (ret); -} - -// Report an error associated with the DbEnv. -// error_policy is one of: -// ON_ERROR_THROW throw an error -// ON_ERROR_RETURN do nothing here, the caller will return an error -// ON_ERROR_UNKNOWN defer the policy to policy saved in DbEnv::DbEnv -// -void DbEnv::runtime_error(DbEnv *env, - const char *caller, int error, int error_policy) -{ - if (error_policy == ON_ERROR_UNKNOWN) - error_policy = last_known_error_policy; - if (error_policy == ON_ERROR_THROW) { - // Creating and throwing the object in two separate - // statements seems to be necessary for HP compilers. - switch (error) { - case DB_LOCK_DEADLOCK: - { - DbDeadlockException dl_except(caller); - dl_except.set_env(env); - throw dl_except; - } - break; - case DB_RUNRECOVERY: - { - DbRunRecoveryException rr_except(caller); - rr_except.set_env(env); - throw rr_except; - } - break; - case DB_LOCK_NOTGRANTED: - { - DbLockNotGrantedException lng_except(caller); - lng_except.set_env(env); - throw lng_except; - } - break; - case DB_REP_HANDLE_DEAD: - { - DbRepHandleDeadException dl_except(caller); - dl_except.set_env(env); - throw dl_except; - } - default: - { - DbException except(caller, error); - except.set_env(env); - throw except; - } - break; - } - } -} - -// Like DbEnv::runtime_error, but issue a DbMemoryException -// based on the fact that this Dbt is not large enough. -void DbEnv::runtime_error_dbt(DbEnv *env, - const char *caller, Dbt *dbt, int error_policy) -{ - if (error_policy == ON_ERROR_UNKNOWN) - error_policy = last_known_error_policy; - if (error_policy == ON_ERROR_THROW) { - // Creating and throwing the object in two separate - // statements seems to be necessary for HP compilers. - DbMemoryException except(caller, dbt); - except.set_env(env); - throw except; - } -} - -// Like DbEnv::runtime_error, but issue a DbLockNotGrantedException, -// or a regular runtime error. -// call regular runtime_error if it -void DbEnv::runtime_error_lock_get(DbEnv *env, - const char *caller, int error, - db_lockop_t op, db_lockmode_t mode, const Dbt *obj, - DbLock lock, int index, int error_policy) -{ - if (error != DB_LOCK_NOTGRANTED) { - runtime_error(env, caller, error, error_policy); - return; - } - - if (error_policy == ON_ERROR_UNKNOWN) - error_policy = last_known_error_policy; - if (error_policy == ON_ERROR_THROW) { - // Creating and throwing the object in two separate - // statements seems to be necessary for HP compilers. - DbLockNotGrantedException except(caller, op, mode, - obj, lock, index); - except.set_env(env); - throw except; - } -} - -void DbEnv::_stream_error_function( - const DB_ENV *env, const char *prefix, const char *message) -{ - const DbEnv *cxxenv = DbEnv::get_const_DbEnv(env); - if (cxxenv == 0) { - DB_ERROR(0, - "DbEnv::stream_error", EINVAL, ON_ERROR_UNKNOWN); - return; - } - - if (cxxenv->error_callback_) - cxxenv->error_callback_(cxxenv, prefix, message); - else if (cxxenv->error_stream_) { - // HP compilers need the extra casts, we don't know why. - if (prefix) { - (*cxxenv->error_stream_) << prefix; - (*cxxenv->error_stream_) << (const char *)": "; - } - if (message) - (*cxxenv->error_stream_) << (const char *)message; - (*cxxenv->error_stream_) << (const char *)"\n"; - } -} - -void DbEnv::_stream_message_function(const DB_ENV *env, const char *message) -{ - const DbEnv *cxxenv = DbEnv::get_const_DbEnv(env); - if (cxxenv == 0) { - DB_ERROR(0, - "DbEnv::stream_message", EINVAL, ON_ERROR_UNKNOWN); - return; - } - - if (cxxenv->message_callback_) - cxxenv->message_callback_(cxxenv, message); - else if (cxxenv->message_stream_) { - // HP compilers need the extra casts, we don't know why. - (*cxxenv->message_stream_) << (const char *)message; - (*cxxenv->message_stream_) << (const char *)"\n"; - } -} - -// static method -char *DbEnv::strerror(int error) -{ - return (db_strerror(error)); -} - -// We keep these alphabetical by field name, -// for comparison with Java's list. -// -DBENV_METHOD(set_data_dir, (const char *dir), (dbenv, dir)) -DBENV_METHOD(get_encrypt_flags, (u_int32_t *flagsp), - (dbenv, flagsp)) -DBENV_METHOD(set_encrypt, (const char *passwd, u_int32_t flags), - (dbenv, passwd, flags)) -DBENV_METHOD_VOID(get_errfile, (FILE **errfilep), (dbenv, errfilep)) -DBENV_METHOD_VOID(set_errfile, (FILE *errfile), (dbenv, errfile)) -DBENV_METHOD_VOID(get_errpfx, (const char **errpfxp), (dbenv, errpfxp)) -DBENV_METHOD_VOID(set_errpfx, (const char *errpfx), (dbenv, errpfx)) -DBENV_METHOD(set_intermediate_dir, (int mode, u_int32_t flags), - (dbenv, mode, flags)) -DBENV_METHOD(get_lg_bsize, (u_int32_t *bsizep), (dbenv, bsizep)) -DBENV_METHOD(set_lg_bsize, (u_int32_t bsize), (dbenv, bsize)) -DBENV_METHOD(get_lg_dir, (const char **dirp), (dbenv, dirp)) -DBENV_METHOD(set_lg_dir, (const char *dir), (dbenv, dir)) -DBENV_METHOD(get_lg_filemode, (int *modep), (dbenv, modep)) -DBENV_METHOD(set_lg_filemode, (int mode), (dbenv, mode)) -DBENV_METHOD(get_lg_max, (u_int32_t *maxp), (dbenv, maxp)) -DBENV_METHOD(set_lg_max, (u_int32_t max), (dbenv, max)) -DBENV_METHOD(get_lg_regionmax, (u_int32_t *regionmaxp), (dbenv, regionmaxp)) -DBENV_METHOD(set_lg_regionmax, (u_int32_t regionmax), (dbenv, regionmax)) -DBENV_METHOD(get_lk_conflicts, (const u_int8_t **lk_conflictsp, int *lk_maxp), - (dbenv, lk_conflictsp, lk_maxp)) -DBENV_METHOD(set_lk_conflicts, (u_int8_t *lk_conflicts, int lk_max), - (dbenv, lk_conflicts, lk_max)) -DBENV_METHOD(get_lk_detect, (u_int32_t *detectp), (dbenv, detectp)) -DBENV_METHOD(set_lk_detect, (u_int32_t detect), (dbenv, detect)) -DBENV_METHOD(set_lk_max, (u_int32_t max), (dbenv, max)) -DBENV_METHOD(get_lk_max_lockers, (u_int32_t *max_lockersp), - (dbenv, max_lockersp)) -DBENV_METHOD(set_lk_max_lockers, (u_int32_t max_lockers), (dbenv, max_lockers)) -DBENV_METHOD(get_lk_max_locks, (u_int32_t *max_locksp), (dbenv, max_locksp)) -DBENV_METHOD(set_lk_max_locks, (u_int32_t max_locks), (dbenv, max_locks)) -DBENV_METHOD(get_lk_max_objects, (u_int32_t *max_objectsp), - (dbenv, max_objectsp)) -DBENV_METHOD(set_lk_max_objects, (u_int32_t max_objects), (dbenv, max_objects)) -DBENV_METHOD(get_mp_max_openfd, (int *maxopenfdp), (dbenv, maxopenfdp)) -DBENV_METHOD(set_mp_max_openfd, (int maxopenfd), (dbenv, maxopenfd)) -DBENV_METHOD(get_mp_max_write, (int *maxwritep, int *maxwrite_sleepp), (dbenv, maxwritep, maxwrite_sleepp)) -DBENV_METHOD(set_mp_max_write, (int maxwrite, int maxwrite_sleep), (dbenv, maxwrite, maxwrite_sleep)) -DBENV_METHOD(get_mp_mmapsize, (size_t *mmapsizep), (dbenv, mmapsizep)) -DBENV_METHOD(set_mp_mmapsize, (size_t mmapsize), (dbenv, mmapsize)) -DBENV_METHOD_VOID(get_msgfile, (FILE **msgfilep), (dbenv, msgfilep)) -DBENV_METHOD_VOID(set_msgfile, (FILE *msgfile), (dbenv, msgfile)) -DBENV_METHOD(get_tmp_dir, (const char **tmp_dirp), (dbenv, tmp_dirp)) -DBENV_METHOD(set_tmp_dir, (const char *tmp_dir), (dbenv, tmp_dir)) -DBENV_METHOD(get_tx_max, (u_int32_t *tx_maxp), (dbenv, tx_maxp)) -DBENV_METHOD(set_tx_max, (u_int32_t tx_max), (dbenv, tx_max)) - -DBENV_METHOD(stat_print, (u_int32_t flags), (dbenv, flags)) - -DBENV_METHOD_QUIET(set_alloc, - (db_malloc_fcn_type malloc_fcn, db_realloc_fcn_type realloc_fcn, - db_free_fcn_type free_fcn), - (dbenv, malloc_fcn, realloc_fcn, free_fcn)) - -void DbEnv::set_app_private(void *value) -{ - unwrap(this)->app_private = value; -} - -DBENV_METHOD(get_cachesize, - (u_int32_t *gbytesp, u_int32_t *bytesp, int *ncachep), - (dbenv, gbytesp, bytesp, ncachep)) -DBENV_METHOD(set_cachesize, - (u_int32_t gbytes, u_int32_t bytes, int ncache), - (dbenv, gbytes, bytes, ncache)) - -void DbEnv::set_errcall(void (*arg)(const DbEnv *, const char *, const char *)) -{ - DB_ENV *dbenv = unwrap(this); - - error_callback_ = arg; - error_stream_ = 0; - - dbenv->set_errcall(dbenv, (arg == 0) ? 0 : - _stream_error_function_c); -} - -__DB_STD(ostream) *DbEnv::get_error_stream() -{ - return (error_stream_); -} - -void DbEnv::set_error_stream(__DB_STD(ostream) *stream) -{ - DB_ENV *dbenv = unwrap(this); - - error_stream_ = stream; - error_callback_ = 0; - - dbenv->set_errcall(dbenv, (stream == 0) ? 0 : - _stream_error_function_c); -} - -int DbEnv::set_feedback(void (*arg)(DbEnv *, int, int)) -{ - DB_ENV *dbenv = unwrap(this); - - feedback_callback_ = arg; - - return (dbenv->set_feedback(dbenv, - arg == 0 ? 0 : _feedback_intercept_c)); -} - -DBENV_METHOD(get_flags, (u_int32_t *flagsp), (dbenv, flagsp)) -DBENV_METHOD(set_flags, (u_int32_t flags, int onoff), (dbenv, flags, onoff)) - -void DbEnv::set_msgcall(void (*arg)(const DbEnv *, const char *)) -{ - DB_ENV *dbenv = unwrap(this); - - message_callback_ = arg; - message_stream_ = 0; - - dbenv->set_msgcall(dbenv, (arg == 0) ? 0 : - _stream_message_function_c); -} - -__DB_STD(ostream) *DbEnv::get_message_stream() -{ - return (message_stream_); -} - -void DbEnv::set_message_stream(__DB_STD(ostream) *stream) -{ - DB_ENV *dbenv = unwrap(this); - - message_stream_ = stream; - message_callback_ = 0; - - dbenv->set_msgcall(dbenv, (stream == 0) ? 0 : - _stream_message_function_c); -} - -int DbEnv::set_paniccall(void (*arg)(DbEnv *, int)) -{ - DB_ENV *dbenv = unwrap(this); - - paniccall_callback_ = arg; - - return (dbenv->set_paniccall(dbenv, - arg == 0 ? 0 : _paniccall_intercept_c)); -} - -DBENV_METHOD(set_rpc_server, - (void *cl, char *host, long tsec, long ssec, u_int32_t flags), - (dbenv, cl, host, tsec, ssec, flags)) -DBENV_METHOD(get_shm_key, (long *shm_keyp), (dbenv, shm_keyp)) -DBENV_METHOD(set_shm_key, (long shm_key), (dbenv, shm_key)) - -int DbEnv::set_app_dispatch - (int (*arg)(DbEnv *, Dbt *, DbLsn *, db_recops)) -{ - DB_ENV *dbenv = unwrap(this); - int ret; - - app_dispatch_callback_ = arg; - if ((ret = dbenv->set_app_dispatch(dbenv, - arg == 0 ? 0 : _app_dispatch_intercept_c)) != 0) - DB_ERROR(this, "DbEnv::set_app_dispatch", ret, error_policy()); - - return (ret); -} - -int DbEnv::set_isalive - (int (*arg)(DbEnv *, pid_t, db_threadid_t)) -{ - DB_ENV *dbenv = unwrap(this); - int ret; - - isalive_callback_ = arg; - if ((ret = dbenv->set_isalive(dbenv, - arg == 0 ? 0 : _isalive_intercept_c)) != 0) - DB_ERROR(this, "DbEnv::set_isalive", ret, error_policy()); - - return (ret); -} - -DBENV_METHOD(get_tx_timestamp, (time_t *timestamp), (dbenv, timestamp)) -DBENV_METHOD(set_tx_timestamp, (time_t *timestamp), (dbenv, timestamp)) -DBENV_METHOD(get_verbose, (u_int32_t which, int *onoffp), - (dbenv, which, onoffp)) -DBENV_METHOD(set_verbose, (u_int32_t which, int onoff), (dbenv, which, onoff)) - -DBENV_METHOD(mutex_alloc, - (u_int32_t flags, db_mutex_t *mutexp), (dbenv, flags, mutexp)) -DBENV_METHOD(mutex_free, (db_mutex_t mutex), (dbenv, mutex)) -DBENV_METHOD(mutex_get_align, (u_int32_t *argp), (dbenv, argp)) -DBENV_METHOD(mutex_get_increment, (u_int32_t *argp), (dbenv, argp)) -DBENV_METHOD(mutex_get_max, (u_int32_t *argp), (dbenv, argp)) -DBENV_METHOD(mutex_get_tas_spins, (u_int32_t *argp), (dbenv, argp)) -DBENV_METHOD(mutex_lock, (db_mutex_t mutex), (dbenv, mutex)) -DBENV_METHOD(mutex_set_align, (u_int32_t arg), (dbenv, arg)) -DBENV_METHOD(mutex_set_increment, (u_int32_t arg), (dbenv, arg)) -DBENV_METHOD(mutex_set_max, (u_int32_t arg), (dbenv, arg)) -DBENV_METHOD(mutex_set_tas_spins, (u_int32_t arg), (dbenv, arg)) -DBENV_METHOD(mutex_stat, - (DB_MUTEX_STAT **statp, u_int32_t flags), (dbenv, statp, flags)) -DBENV_METHOD(mutex_stat_print, (u_int32_t flags), (dbenv, flags)) -DBENV_METHOD(mutex_unlock, (db_mutex_t mutex), (dbenv, mutex)) - -int DbEnv::set_thread_id(void (*arg)(DbEnv *, pid_t *, db_threadid_t *)) -{ - DB_ENV *dbenv = unwrap(this); - int ret; - - thread_id_callback_ = arg; - if ((ret = dbenv->set_thread_id(dbenv, - arg == 0 ? 0 : _thread_id_intercept_c)) != 0) - DB_ERROR(this, "DbEnv::set_thread_id", ret, error_policy()); - - return (ret); -} - -int DbEnv::set_thread_id_string( - char *(*arg)(DbEnv *, pid_t, db_threadid_t, char *)) -{ - DB_ENV *dbenv = unwrap(this); - int ret; - - thread_id_string_callback_ = arg; - if ((ret = dbenv->set_thread_id_string(dbenv, - arg == 0 ? 0 : _thread_id_string_intercept_c)) != 0) - DB_ERROR(this, "DbEnv::set_thread_id_string", ret, - error_policy()); - - return (ret); -} - -int DbEnv::txn_begin(DbTxn *pid, DbTxn **tid, u_int32_t flags) -{ - DB_ENV *env = unwrap(this); - DB_TXN *txn; - int ret; - - ret = env->txn_begin(env, unwrap(pid), &txn, flags); - if (DB_RETOK_STD(ret)) - *tid = new DbTxn(txn); - else - DB_ERROR(this, "DbEnv::txn_begin", ret, error_policy()); - - return (ret); -} - -DBENV_METHOD(txn_checkpoint, (u_int32_t kbyte, u_int32_t min, u_int32_t flags), - (dbenv, kbyte, min, flags)) - -int DbEnv::txn_recover(DbPreplist *preplist, long count, - long *retp, u_int32_t flags) -{ - DB_ENV *dbenv = unwrap(this); - DB_PREPLIST *c_preplist; - long i; - int ret; - - /* - * We need to allocate some local storage for the - * returned preplist, and that requires us to do - * our own argument validation. - */ - if (count <= 0) - ret = EINVAL; - else - ret = __os_malloc(dbenv, sizeof(DB_PREPLIST) * count, - &c_preplist); - - if (ret != 0) { - DB_ERROR(this, "DbEnv::txn_recover", ret, error_policy()); - return (ret); - } - - if ((ret = - dbenv->txn_recover(dbenv, c_preplist, count, retp, flags)) != 0) { - __os_free(dbenv, c_preplist); - DB_ERROR(this, "DbEnv::txn_recover", ret, error_policy()); - return (ret); - } - - for (i = 0; i < *retp; i++) { - preplist[i].txn = new DbTxn(); - preplist[i].txn->imp_ = c_preplist[i].txn; - memcpy(preplist[i].gid, c_preplist[i].gid, - sizeof(preplist[i].gid)); - } - - __os_free(dbenv, c_preplist); - - return (0); -} - -DBENV_METHOD(txn_stat, (DB_TXN_STAT **statp, u_int32_t flags), - (dbenv, statp, flags)) -DBENV_METHOD(txn_stat_print, (u_int32_t flags), (dbenv, flags)) - -int DbEnv::set_rep_transport(int myid, - int (*arg)(DbEnv *, const Dbt *, const Dbt *, const DbLsn *, int, u_int32_t)) -{ - DB_ENV *dbenv = unwrap(this); - int ret; - - rep_send_callback_ = arg; - if ((ret = dbenv->set_rep_transport(dbenv, myid, - arg == 0 ? 0 : _rep_send_intercept_c)) != 0) - DB_ERROR(this, "DbEnv::set_rep_transport", ret, error_policy()); - - return (ret); -} - -DBENV_METHOD(rep_elect, - (int nsites, - int nvotes, int priority, u_int32_t timeout, int *eidp, u_int32_t flags), - (dbenv, nsites, nvotes, priority, timeout, eidp, flags)) -DBENV_METHOD(rep_flush, (), (dbenv)) -DBENV_METHOD(rep_get_config, (u_int32_t which, int *onoffp), - (dbenv, which, onoffp)) -DBENV_METHOD(set_rep_request, (u_int32_t min, u_int32_t max), (dbenv, min, max)) - -int DbEnv::rep_process_message(Dbt *control, - Dbt *rec, int *idp, DbLsn *ret_lsnp) -{ - DB_ENV *dbenv = unwrap(this); - int ret; - - ret = dbenv->rep_process_message(dbenv, control, rec, idp, ret_lsnp); - if (!DB_RETOK_REPPMSG(ret)) - DB_ERROR(this, "DbEnv::rep_process_message", ret, - error_policy()); - - return (ret); -} - -DBENV_METHOD(rep_set_config, - (u_int32_t which, int onoff), (dbenv, which, onoff)) -DBENV_METHOD(rep_start, - (Dbt *cookie, u_int32_t flags), - (dbenv, (DBT *)cookie, flags)) - -DBENV_METHOD(rep_stat, (DB_REP_STAT **statp, u_int32_t flags), - (dbenv, statp, flags)) -DBENV_METHOD(rep_stat_print, (u_int32_t flags), (dbenv, flags)) -DBENV_METHOD(rep_sync, (u_int32_t flags), (dbenv, flags)) - -DBENV_METHOD(get_rep_limit, (u_int32_t *gbytesp, u_int32_t *bytesp), - (dbenv, gbytesp, bytesp)) -DBENV_METHOD(set_rep_limit, (u_int32_t gbytes, u_int32_t bytes), - (dbenv, gbytes, bytes)) - -DBENV_METHOD(get_timeout, - (db_timeout_t *timeoutp, u_int32_t flags), - (dbenv, timeoutp, flags)) -DBENV_METHOD(set_timeout, - (db_timeout_t timeout, u_int32_t flags), - (dbenv, timeout, flags)) - -// static method -char *DbEnv::version(int *major, int *minor, int *patch) -{ - return (db_version(major, minor, patch)); -} - -// static method -DbEnv *DbEnv::wrap_DB_ENV(DB_ENV *dbenv) -{ - DbEnv *wrapped_env = get_DbEnv(dbenv); - return (wrapped_env != NULL) ? wrapped_env : new DbEnv(dbenv, 0); -} diff --git a/storage/bdb/cxx/cxx_except.cpp b/storage/bdb/cxx/cxx_except.cpp deleted file mode 100644 index b0bf7c0690e..00000000000 --- a/storage/bdb/cxx/cxx_except.cpp +++ /dev/null @@ -1,354 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: cxx_except.cpp,v 12.2 2005/10/14 12:20:04 mjc Exp $ - */ - -#include "db_config.h" - -#include <string.h> -#include <errno.h> - -#include "db_cxx.h" -#include "dbinc/cxx_int.h" - -// Note: would not be needed if we can inherit from exception -// It does not appear to be possible to inherit from exception -// with the current Microsoft library (VC5.0). -// -static char *dupString(const char *s) -{ - char *r = new char[strlen(s)+1]; - strcpy(r, s); - return (r); -} - -//////////////////////////////////////////////////////////////////////// -// // -// DbException // -// // -//////////////////////////////////////////////////////////////////////// - -DbException::~DbException() throw() -{ - delete [] what_; -} - -DbException::DbException(int err) -: err_(err) -, env_(0) -{ - describe(0, 0); -} - -DbException::DbException(const char *description) -: err_(0) -, env_(0) -{ - describe(0, description); -} - -DbException::DbException(const char *description, int err) -: err_(err) -, env_(0) -{ - describe(0, description); -} - -DbException::DbException(const char *prefix, const char *description, int err) -: err_(err) -, env_(0) -{ - describe(prefix, description); -} - -DbException::DbException(const DbException &that) -: __DB_STD(exception)() -, what_(dupString(that.what_)) -, err_(that.err_) -, env_(0) -{ -} - -DbException &DbException::operator = (const DbException &that) -{ - if (this != &that) { - err_ = that.err_; - delete [] what_; - what_ = dupString(that.what_); - } - return (*this); -} - -void DbException::describe(const char *prefix, const char *description) -{ - char msgbuf[1024], *p, *end; - - p = msgbuf; - end = msgbuf + sizeof(msgbuf) - 1; - - if (prefix != NULL) { - strncpy(p, prefix, (p < end) ? end - p: 0); - p += strlen(prefix); - strncpy(p, ": ", (p < end) ? end - p: 0); - p += 2; - } - if (description != NULL) { - strncpy(p, description, (p < end) ? end - p: 0); - p += strlen(description); - if (err_ != 0) { - strncpy(p, ": ", (p < end) ? end - p: 0); - p += 2; - } - } - if (err_ != 0) { - strncpy(p, db_strerror(err_), (p < end) ? end - p: 0); - p += strlen(db_strerror(err_)); - } - - /* - * If the result was too long, the buffer will not be null-terminated, - * so we need to fix that here before duplicating it. - */ - if (p >= end) - *end = '\0'; - - what_ = dupString(msgbuf); -} - -int DbException::get_errno() const -{ - return (err_); -} - -const char *DbException::what() const throw() -{ - return (what_); -} - -DbEnv *DbException::get_env() const -{ - return env_; -} - -void DbException::set_env(DbEnv *env) -{ - env_= env; -} - -//////////////////////////////////////////////////////////////////////// -// // -// DbMemoryException // -// // -//////////////////////////////////////////////////////////////////////// - -static const char *memory_err_desc = "Dbt not large enough for available data"; -DbMemoryException::~DbMemoryException() throw() -{ -} - -DbMemoryException::DbMemoryException(Dbt *dbt) -: DbException(memory_err_desc, ENOMEM) -, dbt_(dbt) -{ -} - -DbMemoryException::DbMemoryException(const char *prefix, Dbt *dbt) -: DbException(prefix, memory_err_desc, ENOMEM) -, dbt_(dbt) -{ -} - -DbMemoryException::DbMemoryException(const DbMemoryException &that) -: DbException(that) -, dbt_(that.dbt_) -{ -} - -DbMemoryException -&DbMemoryException::operator =(const DbMemoryException &that) -{ - if (this != &that) { - DbException::operator=(that); - dbt_ = that.dbt_; - } - return (*this); -} - -Dbt *DbMemoryException::get_dbt() const -{ - return (dbt_); -} - -//////////////////////////////////////////////////////////////////////// -// // -// DbDeadlockException // -// // -//////////////////////////////////////////////////////////////////////// - -DbDeadlockException::~DbDeadlockException() throw() -{ -} - -DbDeadlockException::DbDeadlockException(const char *description) -: DbException(description, DB_LOCK_DEADLOCK) -{ -} - -DbDeadlockException::DbDeadlockException(const DbDeadlockException &that) -: DbException(that) -{ -} - -DbDeadlockException -&DbDeadlockException::operator =(const DbDeadlockException &that) -{ - if (this != &that) - DbException::operator=(that); - return (*this); -} - -//////////////////////////////////////////////////////////////////////// -// // -// DbLockNotGrantedException // -// // -//////////////////////////////////////////////////////////////////////// - -DbLockNotGrantedException::~DbLockNotGrantedException() throw() -{ - delete lock_; -} - -DbLockNotGrantedException::DbLockNotGrantedException(const char *prefix, - db_lockop_t op, db_lockmode_t mode, const Dbt *obj, const DbLock lock, - int index) -: DbException(prefix, DbEnv::strerror(DB_LOCK_NOTGRANTED), - DB_LOCK_NOTGRANTED) -, op_(op) -, mode_(mode) -, obj_(obj) -, lock_(new DbLock(lock)) -, index_(index) -{ -} - -DbLockNotGrantedException::DbLockNotGrantedException(const char *description) -: DbException(description, DB_LOCK_NOTGRANTED) -, op_(DB_LOCK_GET) -, mode_(DB_LOCK_NG) -, obj_(NULL) -, lock_(NULL) -, index_(0) -{ -} - -DbLockNotGrantedException::DbLockNotGrantedException - (const DbLockNotGrantedException &that) -: DbException(that) -{ - op_ = that.op_; - mode_ = that.mode_; - obj_ = that.obj_; - lock_ = (that.lock_ != NULL) ? new DbLock(*that.lock_) : NULL; - index_ = that.index_; -} - -DbLockNotGrantedException -&DbLockNotGrantedException::operator =(const DbLockNotGrantedException &that) -{ - if (this != &that) { - DbException::operator=(that); - op_ = that.op_; - mode_ = that.mode_; - obj_ = that.obj_; - lock_ = (that.lock_ != NULL) ? new DbLock(*that.lock_) : NULL; - index_ = that.index_; - } - return (*this); -} - -db_lockop_t DbLockNotGrantedException::get_op() const -{ - return op_; -} - -db_lockmode_t DbLockNotGrantedException::get_mode() const -{ - return mode_; -} - -const Dbt* DbLockNotGrantedException::get_obj() const -{ - return obj_; -} - -DbLock* DbLockNotGrantedException::get_lock() const -{ - return lock_; -} - -int DbLockNotGrantedException::get_index() const -{ - return index_; -} - -//////////////////////////////////////////////////////////////////////// -// // -// DbRepHandleDeadException // -// // -//////////////////////////////////////////////////////////////////////// - -DbRepHandleDeadException::~DbRepHandleDeadException() throw() -{ -} - -DbRepHandleDeadException::DbRepHandleDeadException(const char *description) -: DbException(description, DB_REP_HANDLE_DEAD) -{ -} - -DbRepHandleDeadException::DbRepHandleDeadException - (const DbRepHandleDeadException &that) -: DbException(that) -{ -} - -DbRepHandleDeadException -&DbRepHandleDeadException::operator =(const DbRepHandleDeadException &that) -{ - if (this != &that) - DbException::operator=(that); - return (*this); -} - -//////////////////////////////////////////////////////////////////////// -// // -// DbRunRecoveryException // -// // -//////////////////////////////////////////////////////////////////////// - -DbRunRecoveryException::~DbRunRecoveryException() throw() -{ -} - -DbRunRecoveryException::DbRunRecoveryException(const char *description) -: DbException(description, DB_RUNRECOVERY) -{ -} - -DbRunRecoveryException::DbRunRecoveryException - (const DbRunRecoveryException &that) -: DbException(that) -{ -} - -DbRunRecoveryException -&DbRunRecoveryException::operator =(const DbRunRecoveryException &that) -{ - if (this != &that) - DbException::operator=(that); - return (*this); -} diff --git a/storage/bdb/cxx/cxx_lock.cpp b/storage/bdb/cxx/cxx_lock.cpp deleted file mode 100644 index 47f27ae3504..00000000000 --- a/storage/bdb/cxx/cxx_lock.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: cxx_lock.cpp,v 12.1 2005/06/16 20:20:59 bostic Exp $ - */ - -#include "db_config.h" - -#include <errno.h> -#include <string.h> - -#include "db_cxx.h" -#include "dbinc/cxx_int.h" - -//////////////////////////////////////////////////////////////////////// -// // -// DbLock // -// // -//////////////////////////////////////////////////////////////////////// - -DbLock::DbLock(DB_LOCK value) -: lock_(value) -{ -} - -DbLock::DbLock() -{ - memset(&lock_, 0, sizeof(DB_LOCK)); -} - -DbLock::DbLock(const DbLock &that) -: lock_(that.lock_) -{ -} - -DbLock &DbLock::operator = (const DbLock &that) -{ - lock_ = that.lock_; - return (*this); -} diff --git a/storage/bdb/cxx/cxx_logc.cpp b/storage/bdb/cxx/cxx_logc.cpp deleted file mode 100644 index 63d7fd9fe17..00000000000 --- a/storage/bdb/cxx/cxx_logc.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: cxx_logc.cpp,v 12.1 2005/06/16 20:21:00 bostic Exp $ - */ - -#include "db_config.h" - -#include <errno.h> -#include <string.h> - -#include "db_cxx.h" -#include "dbinc/cxx_int.h" - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc_auto/db_auto.h" -#include "dbinc_auto/crdel_auto.h" -#include "dbinc/db_dispatch.h" -#include "dbinc_auto/db_ext.h" -#include "dbinc_auto/common_ext.h" - -// It's private, and should never be called, -// but some compilers need it resolved -// -DbLogc::~DbLogc() -{ -} - -// The name _flags prevents a name clash with __db_log_cursor::flags -int DbLogc::close(u_int32_t _flags) -{ - DB_LOGC *logc = this; - int ret; - DbEnv *dbenv2 = DbEnv::get_DbEnv(logc->dbenv); - - ret = logc->close(logc, _flags); - - if (!DB_RETOK_STD(ret)) - DB_ERROR(dbenv2, "DbLogc::close", ret, ON_ERROR_UNKNOWN); - - return (ret); -} - -// The name _flags prevents a name clash with __db_log_cursor::flags -int DbLogc::get(DbLsn *lsn, Dbt *data, u_int32_t _flags) -{ - DB_LOGC *logc = this; - int ret; - - ret = logc->get(logc, lsn, data, _flags); - - if (!DB_RETOK_LGGET(ret)) { - if (ret == DB_BUFFER_SMALL) - DB_ERROR_DBT(DbEnv::get_DbEnv(logc->dbenv), - "DbLogc::get", data, ON_ERROR_UNKNOWN); - else - DB_ERROR(DbEnv::get_DbEnv(logc->dbenv), - "DbLogc::get", ret, ON_ERROR_UNKNOWN); - } - - return (ret); -} diff --git a/storage/bdb/cxx/cxx_mpool.cpp b/storage/bdb/cxx/cxx_mpool.cpp deleted file mode 100644 index 475a18b3e3f..00000000000 --- a/storage/bdb/cxx/cxx_mpool.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: cxx_mpool.cpp,v 12.1 2005/06/16 20:21:02 bostic Exp $ - */ - -#include "db_config.h" - -#include <errno.h> - -#include "db_cxx.h" -#include "dbinc/cxx_int.h" - -#include "db_int.h" - -// Helper macros for simple methods that pass through to the -// underlying C method. It may return an error or raise an exception. -// Note this macro expects that input _argspec is an argument -// list element (e.g., "char *arg") and that _arglist is the arguments -// that should be passed through to the C method (e.g., "(mpf, arg)") -// -#define DB_MPOOLFILE_METHOD(_name, _argspec, _arglist, _retok) \ -int DbMpoolFile::_name _argspec \ -{ \ - int ret; \ - DB_MPOOLFILE *mpf = unwrap(this); \ - \ - if (mpf == NULL) \ - ret = EINVAL; \ - else \ - ret = mpf->_name _arglist; \ - if (!_retok(ret)) \ - DB_ERROR(DbEnv::get_DbEnv(mpf->dbenv), \ - "DbMpoolFile::"#_name, ret, ON_ERROR_UNKNOWN); \ - return (ret); \ -} - -#define DB_MPOOLFILE_METHOD_VOID(_name, _argspec, _arglist) \ -void DbMpoolFile::_name _argspec \ -{ \ - DB_MPOOLFILE *mpf = unwrap(this); \ - \ - mpf->_name _arglist; \ -} - -//////////////////////////////////////////////////////////////////////// -// // -// DbMpoolFile // -// // -//////////////////////////////////////////////////////////////////////// - -DbMpoolFile::DbMpoolFile() -: imp_(0) -{ -} - -DbMpoolFile::~DbMpoolFile() -{ -} - -int DbMpoolFile::close(u_int32_t flags) -{ - DB_MPOOLFILE *mpf = unwrap(this); - int ret; - DbEnv *dbenv = DbEnv::get_DbEnv(mpf->dbenv); - - if (mpf == NULL) - ret = EINVAL; - else - ret = mpf->close(mpf, flags); - - imp_ = 0; // extra safety - - // This may seem weird, but is legal as long as we don't access - // any data before returning. - delete this; - - if (!DB_RETOK_STD(ret)) - DB_ERROR(dbenv, "DbMpoolFile::close", ret, ON_ERROR_UNKNOWN); - - return (ret); -} - -DB_MPOOLFILE_METHOD(get, (db_pgno_t *pgnoaddr, u_int32_t flags, void *pagep), - (mpf, pgnoaddr, flags, pagep), DB_RETOK_MPGET) -DB_MPOOLFILE_METHOD(open, - (const char *file, u_int32_t flags, int mode, size_t pagesize), - (mpf, file, flags, mode, pagesize), DB_RETOK_STD) -DB_MPOOLFILE_METHOD(put, (void *pgaddr, u_int32_t flags), - (mpf, pgaddr, flags), DB_RETOK_STD) -DB_MPOOLFILE_METHOD(set, (void *pgaddr, u_int32_t flags), - (mpf, pgaddr, flags), DB_RETOK_STD) -DB_MPOOLFILE_METHOD(get_clear_len, (u_int32_t *lenp), - (mpf, lenp), DB_RETOK_STD) -DB_MPOOLFILE_METHOD(set_clear_len, (u_int32_t len), - (mpf, len), DB_RETOK_STD) -DB_MPOOLFILE_METHOD(get_fileid, (u_int8_t *fileid), - (mpf, fileid), DB_RETOK_STD) -DB_MPOOLFILE_METHOD(set_fileid, (u_int8_t *fileid), - (mpf, fileid), DB_RETOK_STD) -DB_MPOOLFILE_METHOD(get_flags, (u_int32_t *flagsp), - (mpf, flagsp), DB_RETOK_STD) -DB_MPOOLFILE_METHOD(set_flags, (u_int32_t flags, int onoff), - (mpf, flags, onoff), DB_RETOK_STD) -DB_MPOOLFILE_METHOD(get_ftype, (int *ftypep), - (mpf, ftypep), DB_RETOK_STD) -DB_MPOOLFILE_METHOD(set_ftype, (int ftype), - (mpf, ftype), DB_RETOK_STD) -DB_MPOOLFILE_METHOD(get_lsn_offset, (int32_t *offsetp), - (mpf, offsetp), DB_RETOK_STD) -DB_MPOOLFILE_METHOD(set_lsn_offset, (int32_t offset), - (mpf, offset), DB_RETOK_STD) -DB_MPOOLFILE_METHOD(get_maxsize, (u_int32_t *gbytesp, u_int32_t *bytesp), - (mpf, gbytesp, bytesp), DB_RETOK_STD) -DB_MPOOLFILE_METHOD(set_maxsize, (u_int32_t gbytes, u_int32_t bytes), - (mpf, gbytes, bytes), DB_RETOK_STD) -DB_MPOOLFILE_METHOD(get_pgcookie, (DBT *dbt), - (mpf, dbt), DB_RETOK_STD) -DB_MPOOLFILE_METHOD(set_pgcookie, (DBT *dbt), - (mpf, dbt), DB_RETOK_STD) -DB_MPOOLFILE_METHOD(get_priority, (DB_CACHE_PRIORITY *priorityp), - (mpf, priorityp), DB_RETOK_STD) -DB_MPOOLFILE_METHOD(set_priority, (DB_CACHE_PRIORITY priority), - (mpf, priority), DB_RETOK_STD) -DB_MPOOLFILE_METHOD(sync, (), - (mpf), DB_RETOK_STD) diff --git a/storage/bdb/cxx/cxx_multi.cpp b/storage/bdb/cxx/cxx_multi.cpp deleted file mode 100644 index ca80bbafbc4..00000000000 --- a/storage/bdb/cxx/cxx_multi.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: cxx_multi.cpp,v 12.3 2005/09/30 07:40:20 mjc Exp $ - */ - -#include "db_config.h" - -#include "db_cxx.h" - -DbMultipleIterator::DbMultipleIterator(const Dbt &dbt) - : data_((u_int8_t*)dbt.get_data()), - p_((u_int32_t*)(data_ + dbt.get_size() - sizeof(u_int32_t))) -{ -} - -bool DbMultipleDataIterator::next(Dbt &data) -{ - if (*p_ == (u_int32_t)-1) { - data.set_data(0); - data.set_size(0); - p_ = 0; - } else { - data.set_data(data_ + *p_--); - data.set_size(*p_--); - if (data.get_size() == 0 && data.get_data() == data_) - data.set_data(0); - } - return (p_ != 0); -} - -bool DbMultipleKeyDataIterator::next(Dbt &key, Dbt &data) -{ - if (*p_ == (u_int32_t)-1) { - key.set_data(0); - key.set_size(0); - data.set_data(0); - data.set_size(0); - p_ = 0; - } else { - key.set_data(data_ + *p_--); - key.set_size(*p_--); - data.set_data(data_ + *p_--); - data.set_size(*p_--); - } - return (p_ != 0); -} - -bool DbMultipleRecnoDataIterator::next(db_recno_t &recno, Dbt &data) -{ - if (*p_ == (u_int32_t)0) { - recno = 0; - data.set_data(0); - data.set_size(0); - p_ = 0; - } else { - recno = *p_--; - data.set_data(data_ + *p_--); - data.set_size(*p_--); - } - return (p_ != 0); -} diff --git a/storage/bdb/cxx/cxx_seq.cpp b/storage/bdb/cxx/cxx_seq.cpp deleted file mode 100644 index ed8997f0340..00000000000 --- a/storage/bdb/cxx/cxx_seq.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: cxx_seq.cpp,v 12.2 2005/10/13 20:49:47 bostic Exp $ - */ - -#include "db_config.h" - -#include <errno.h> -#include <string.h> - -#include "db_cxx.h" -#include "dbinc/cxx_int.h" - -#include "db_int.h" - -// Helper macro for simple methods that pass through to the -// underlying C method. It may return an error or raise an exception. -// Note this macro expects that input _argspec is an argument -// list element (e.g., "char *arg") and that _arglist is the arguments -// that should be passed through to the C method (e.g., "(db, arg)") -// -#define DBSEQ_METHOD(_name, _argspec, _arglist, _destructor) \ -int DbSequence::_name _argspec \ -{ \ - int ret; \ - DB_SEQUENCE *seq = unwrap(this); \ - DbEnv *dbenv = DbEnv::get_DbEnv(seq->seq_dbp->dbenv); \ - \ - ret = seq->_name _arglist; \ - if (_destructor) \ - imp_ = 0; \ - if (!DB_RETOK_STD(ret)) \ - DB_ERROR(dbenv, \ - "DbSequence::" # _name, ret, ON_ERROR_UNKNOWN); \ - return (ret); \ -} - -DbSequence::DbSequence(Db *db, u_int32_t flags) -: imp_(0) -{ - DB_SEQUENCE *seq; - int ret; - - if ((ret = db_sequence_create(&seq, unwrap(db), flags)) != 0) - DB_ERROR(db->get_env(), "DbSequence::DbSequence", ret, - ON_ERROR_UNKNOWN); - else { - imp_ = seq; - seq->api_internal = this; - } -} - -DbSequence::DbSequence(DB_SEQUENCE *seq) -: imp_(seq) -{ - seq->api_internal = this; -} - -DbSequence::~DbSequence() -{ - DB_SEQUENCE *seq; - - seq = unwrap(this); - if (seq != NULL) - (void)seq->close(seq, 0); -} - -DBSEQ_METHOD(open, (DbTxn *txnid, Dbt *key, u_int32_t flags), - (seq, unwrap(txnid), key, flags), 0) -DBSEQ_METHOD(initial_value, (db_seq_t value), (seq, value), 0) -DBSEQ_METHOD(close, (u_int32_t flags), (seq, flags), 1) -DBSEQ_METHOD(remove, (DbTxn *txnid, u_int32_t flags), - (seq, unwrap(txnid), flags), 1) -DBSEQ_METHOD(stat, (DB_SEQUENCE_STAT **sp, u_int32_t flags), - (seq, sp, flags), 0) -DBSEQ_METHOD(stat_print, (u_int32_t flags), (seq, flags), 0) - -DBSEQ_METHOD(get, - (DbTxn *txnid, int32_t delta, db_seq_t *retp, u_int32_t flags), - (seq, unwrap(txnid), delta, retp, flags), 0) -DBSEQ_METHOD(get_cachesize, (int32_t *sizep), (seq, sizep), 0) -DBSEQ_METHOD(set_cachesize, (int32_t size), (seq, size), 0) -DBSEQ_METHOD(get_flags, (u_int32_t *flagsp), (seq, flagsp), 0) -DBSEQ_METHOD(set_flags, (u_int32_t flags), (seq, flags), 0) -DBSEQ_METHOD(get_range, (db_seq_t *minp, db_seq_t *maxp), (seq, minp, maxp), 0) -DBSEQ_METHOD(set_range, (db_seq_t min, db_seq_t max), (seq, min, max), 0) - -Db *DbSequence::get_db() -{ - DB_SEQUENCE *seq = unwrap(this); - DB *db; - (void)seq->get_db(seq, &db); - return Db::get_Db(db); -} - -Dbt *DbSequence::get_key() -{ - DB_SEQUENCE *seq = unwrap(this); - memset(&key_, 0, sizeof (DBT)); - (void)seq->get_key(seq, &key_); - return Dbt::get_Dbt(&key_); -} - -// static method -DbSequence *DbSequence::wrap_DB_SEQUENCE(DB_SEQUENCE *seq) -{ - DbSequence *wrapped_seq = get_DbSequence(seq); - return (wrapped_seq != NULL) ? wrapped_seq : new DbSequence(seq); -} diff --git a/storage/bdb/cxx/cxx_txn.cpp b/storage/bdb/cxx/cxx_txn.cpp deleted file mode 100644 index 64ee3b9fff5..00000000000 --- a/storage/bdb/cxx/cxx_txn.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: cxx_txn.cpp,v 12.2 2005/06/16 20:21:03 bostic Exp $ - */ - -#include "db_config.h" - -#include <errno.h> - -#include "db_cxx.h" -#include "dbinc/cxx_int.h" - -#include "db_int.h" -#include "dbinc/txn.h" - -// Helper macro for simple methods that pass through to the -// underlying C method. It may return an error or raise an exception. -// Note this macro expects that input _argspec is an argument -// list element (e.g., "char *arg") and that _arglist is the arguments -// that should be passed through to the C method (e.g., "(db, arg)") -// -#define DBTXN_METHOD(_name, _delete, _argspec, _arglist) \ -int DbTxn::_name _argspec \ -{ \ - int ret; \ - DB_TXN *txn = unwrap(this); \ - DbEnv *dbenv = DbEnv::get_DbEnv(txn->mgrp->dbenv); \ - \ - ret = txn->_name _arglist; \ - /* Weird, but safe if we don't access this again. */ \ - if (_delete) \ - delete this; \ - if (!DB_RETOK_STD(ret)) \ - DB_ERROR(dbenv, "DbTxn::" # _name, ret, ON_ERROR_UNKNOWN); \ - return (ret); \ -} - -// private constructor, never called but needed by some C++ linkers -DbTxn::DbTxn() -: imp_(0) -{ -} - -DbTxn::DbTxn(DB_TXN *txn) -: imp_(txn) -{ - txn->api_internal = this; -} - -DbTxn::~DbTxn() -{ -} - -DBTXN_METHOD(abort, 1, (), (txn)) -DBTXN_METHOD(commit, 1, (u_int32_t flags), (txn, flags)) -DBTXN_METHOD(discard, 1, (u_int32_t flags), (txn, flags)) - -u_int32_t DbTxn::id() -{ - DB_TXN *txn; - - txn = unwrap(this); - return (txn->id(txn)); // no error -} - -DBTXN_METHOD(get_name, 0, (const char **namep), (txn, namep)) -DBTXN_METHOD(prepare, 0, (u_int8_t *gid), (txn, gid)) -DBTXN_METHOD(set_name, 0, (const char *name), (txn, name)) -DBTXN_METHOD(set_timeout, 0, (db_timeout_t timeout, u_int32_t flags), - (txn, timeout, flags)) - -// static method -DbTxn *DbTxn::wrap_DB_TXN(DB_TXN *txn) -{ - DbTxn *wrapped_txn = get_DbTxn(txn); - return (wrapped_txn != NULL) ? wrapped_txn : new DbTxn(txn); -} diff --git a/storage/bdb/db/crdel.src b/storage/bdb/db/crdel.src deleted file mode 100644 index ba03fea9312..00000000000 --- a/storage/bdb/db/crdel.src +++ /dev/null @@ -1,80 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: crdel.src,v 12.2 2005/09/28 17:44:18 margo Exp $ - */ - -PREFIX __crdel -DBPRIVATE - -INCLUDE #ifndef NO_SYSTEM_INCLUDES -INCLUDE #include <sys/types.h> -INCLUDE -INCLUDE #include <ctype.h> -INCLUDE #include <string.h> -INCLUDE #endif -INCLUDE -INCLUDE #include "db_int.h" -INCLUDE #include "dbinc/crypto.h" -INCLUDE #include "dbinc/db_page.h" -INCLUDE #include "dbinc/db_dispatch.h" -INCLUDE #include "dbinc/db_am.h" -INCLUDE #include "dbinc/log.h" -INCLUDE #include "dbinc/txn.h" -INCLUDE - -/* - * Metasub: log the creation of a subdatabase meta data page. - * - * fileid: identifies the file being acted upon. - * pgno: page number on which to write this meta-data page - * page: the actual meta-data page - * lsn: lsn of the page. - */ -BEGIN metasub 142 -DB fileid int32_t ld -ARG pgno db_pgno_t lu -PGDBT page DBT s -POINTER lsn DB_LSN * lu -END - -/* - * Inmem_create: Log the creation of an in-memory database. - * - * name: Name of the database - * fid: File id of the database - */ -BEGIN inmem_create 138 -ARG fileid int32_t ld -DBT name DBT s -DBT fid DBT s -ARG pgsize u_int32_t lu -END - -/* - * Inmem_rename: Log the renaming of an in-memory only database. - * - * oldname: database's starting name - * newname: database's ending name - * fid: fileid - */ -BEGIN inmem_rename 139 -DBT oldname DBT s -DBT newname DBT s -DBT fid DBT s -END - -/* - * Inmem_remove: Log the removal of an in-memory only database. - * - * name: database's ending name - * fid: fileid - */ -BEGIN inmem_remove 140 -DBT name DBT s -DBT fid DBT s -END - diff --git a/storage/bdb/db/crdel_rec.c b/storage/bdb/db/crdel_rec.c deleted file mode 100644 index a94c6cbbc1f..00000000000 --- a/storage/bdb/db/crdel_rec.c +++ /dev/null @@ -1,294 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: crdel_rec.c,v 12.6 2005/10/20 18:57:04 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/fop.h" -#include "dbinc/hash.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" -#include "dbinc/txn.h" - -/* - * __crdel_metasub_recover -- - * Recovery function for metasub. - * - * PUBLIC: int __crdel_metasub_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__crdel_metasub_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __crdel_metasub_args *argp; - DB *file_dbp; - DBC *dbc; - DB_MPOOLFILE *mpf; - PAGE *pagep; - int cmp_p, modified, ret; - - pagep = NULL; - COMPQUIET(info, NULL); - REC_PRINT(__crdel_metasub_print); - REC_INTRO(__crdel_metasub_read, 0, 0); - - if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) { - /* If this is an in-memory file, this might be OK. */ - if (F_ISSET(file_dbp, DB_AM_INMEM) && (ret = __memp_fget(mpf, - &argp->pgno, DB_MPOOL_CREATE, &pagep)) == 0) - LSN_NOT_LOGGED(LSN(pagep)); - else { - *lsnp = argp->prev_lsn; - ret = 0; - goto out; - } - } - - modified = 0; - cmp_p = log_compare(&LSN(pagep), &argp->lsn); - CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->lsn); - - if (cmp_p == 0 && DB_REDO(op)) { - memcpy(pagep, argp->page.data, argp->page.size); - LSN(pagep) = *lsnp; - modified = 1; - - /* - * If this was an in-memory database and we are re-creating - * and this is the meta-data page, then we need to set up a - * bunch of fields in the dbo as well. - */ - if (F_ISSET(file_dbp, DB_AM_INMEM) && - argp->pgno == PGNO_BASE_MD && - (ret = __db_meta_setup(file_dbp->dbenv, - file_dbp, file_dbp->dname, (DBMETA *)pagep, 0, 1)) != 0) - goto out; - } else if (DB_UNDO(op)) { - /* - * We want to undo this page creation. The page creation - * happened in two parts. First, we called __bam_new which - * was logged separately. Then we wrote the meta-data onto - * the page. So long as we restore the LSN, then the recovery - * for __bam_new will do everything else. - * - * Don't bother checking the lsn on the page. If we are - * rolling back the next thing is that this page will get - * freed. Opening the subdb will have reinitialized the - * page, but not the lsn. - */ - LSN(pagep) = argp->lsn; - modified = 1; - } - if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0) - goto out; - pagep = NULL; - -done: *lsnp = argp->prev_lsn; - ret = 0; - -out: if (pagep != NULL) - (void)__memp_fput(mpf, pagep, 0); - REC_CLOSE; -} - -/* - * __crdel_inmem_create_recover -- - * Recovery function for inmem_create. - * - * PUBLIC: int __crdel_inmem_create_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__crdel_inmem_create_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - DB *dbp; - __crdel_inmem_create_args *argp; - int do_close, ret, t_ret; - - COMPQUIET(info, NULL); - dbp = NULL; - do_close = 0; - REC_PRINT(__crdel_inmem_create_print); - REC_NOOP_INTRO(__crdel_inmem_create_read); - - /* First, see if the DB handle already exists. */ - if (argp->fileid == DB_LOGFILEID_INVALID) { - if (DB_REDO(op)) - ret = ENOENT; - else - ret = 0; - } else - ret = __dbreg_id_to_db_int(dbenv, - argp->txnid, &dbp, argp->fileid, 0, 0); - - if (DB_REDO(op)) { - /* - * If the dbreg failed, that means that we're creating a - * tmp file. - */ - if (ret != 0) { - if ((ret = db_create(&dbp, dbenv, 0)) != 0) - goto out; - - F_SET(dbp, DB_AM_RECOVER | DB_AM_INMEM); - memcpy(dbp->fileid, argp->fid.data, DB_FILE_ID_LEN); - if (((ret = __os_strdup(dbenv, - argp->name.data, &dbp->dname)) != 0)) - goto out; - - /* - * This DBP is never going to be entered into the - * dbentry table, so if we leave it open here, - * then we're going to lose it. - */ - do_close = 1; - } - - /* Now, set the fileid. */ - memcpy(dbp->fileid, argp->fid.data, argp->fid.size); - if ((ret = __memp_set_fileid(dbp->mpf, dbp->fileid)) != 0) - goto out; - dbp->preserve_fid = 1; - MAKE_INMEM(dbp); - if ((ret = __db_dbenv_setup(dbp, - NULL, NULL, argp->name.data, TXN_INVALID, 0)) != 0) - goto out; - ret = __db_dbenv_mpool(dbp, argp->name.data, 0); - - if (ret == ENOENT) { - dbp->pgsize = argp->pgsize; - if ((ret = __db_dbenv_mpool(dbp, - argp->name.data, DB_CREATE)) != 0) - goto out; - } else if (ret != 0) - goto out; - } - - if (DB_UNDO(op)) { - if (ret == 0) - ret = __memp_nameop(dbenv, argp->fid.data, NULL, - (const char *)argp->name.data, NULL, 1); - - if (ret == ENOENT || ret == DB_DELETED) - ret = 0; - else - goto out; - } - - *lsnp = argp->prev_lsn; - -out: if (dbp != NULL) { - t_ret = 0; - if (DB_UNDO(op)) - t_ret = __db_refresh(dbp, NULL, DB_NOSYNC, NULL, 0); - else if (do_close || ret != 0) - t_ret = __db_close(dbp, NULL, DB_NOSYNC); - if (t_ret != 0 && ret == 0) - ret = t_ret; - } - REC_NOOP_CLOSE; -} - -/* - * __crdel_inmem_rename_recover -- - * Recovery function for inmem_rename. - * - * PUBLIC: int __crdel_inmem_rename_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__crdel_inmem_rename_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __crdel_inmem_rename_args *argp; - u_int8_t *fileid; - int ret; - - COMPQUIET(info, NULL); - REC_PRINT(__crdel_inmem_rename_print); - REC_NOOP_INTRO(__crdel_inmem_rename_read); - fileid = argp->fid.data; - - /* Void out errors because the files may or may not still exist. */ - if (DB_REDO(op)) - (void)__memp_nameop(dbenv, fileid, - (const char *)argp->newname.data, - (const char *)argp->oldname.data, - (const char *)argp->newname.data, 1); - - if (DB_UNDO(op)) - (void)__memp_nameop(dbenv, fileid, - (const char *)argp->oldname.data, - (const char *)argp->newname.data, - (const char *)argp->oldname.data, 1); - - *lsnp = argp->prev_lsn; - ret = 0; - - REC_NOOP_CLOSE; -} - -/* - * __crdel_inmem_remove_recover -- - * Recovery function for inmem_remove. - * - * PUBLIC: int __crdel_inmem_remove_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__crdel_inmem_remove_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __crdel_inmem_remove_args *argp; - int ret; - - COMPQUIET(info, NULL); - REC_PRINT(__crdel_inmem_remove_print); - REC_NOOP_INTRO(__crdel_inmem_remove_read); - - /* - * Since removes are delayed; there is no undo for a remove; only redo. - * The remove may fail, which is OK. - */ - if (DB_REDO(op)) { - (void)__memp_nameop(dbenv, - argp->fid.data, NULL, argp->name.data, NULL, 1); - } - - *lsnp = argp->prev_lsn; - ret = 0; - - REC_NOOP_CLOSE; -} diff --git a/storage/bdb/db/db.c b/storage/bdb/db/db.c deleted file mode 100644 index 432919133a2..00000000000 --- a/storage/bdb/db/db.c +++ /dev/null @@ -1,1509 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994, 1995, 1996 - * Keith Bostic. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994, 1995 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: db.c,v 12.22 2005/11/12 17:41:44 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/db_swap.h" -#include "dbinc/btree.h" -#include "dbinc/fop.h" -#include "dbinc/hash.h" -#include "dbinc/lock.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" -#include "dbinc/qam.h" -#include "dbinc/txn.h" - -static int __db_disassociate __P((DB *)); - -#ifdef CONFIG_TEST -static void __db_makecopy __P((DB_ENV *, const char *, const char *)); -static int __db_testdocopy __P((DB_ENV *, const char *)); -static int __qam_testdocopy __P((DB *, const char *)); -#endif - -/* - * DB.C -- - * This file contains the utility functions for the DBP layer. - */ - -/* - * __db_master_open -- - * Open up a handle on a master database. - * - * PUBLIC: int __db_master_open __P((DB *, - * PUBLIC: DB_TXN *, const char *, u_int32_t, int, DB **)); - */ -int -__db_master_open(subdbp, txn, name, flags, mode, dbpp) - DB *subdbp; - DB_TXN *txn; - const char *name; - u_int32_t flags; - int mode; - DB **dbpp; -{ - DB *dbp; - int ret; - - *dbpp = NULL; - - /* Open up a handle on the main database. */ - if ((ret = db_create(&dbp, subdbp->dbenv, 0)) != 0) - return (ret); - - /* - * It's always a btree. - * Run in the transaction we've created. - * Set the pagesize in case we're creating a new database. - * Flag that we're creating a database with subdatabases. - */ - dbp->pgsize = subdbp->pgsize; - F_SET(dbp, DB_AM_SUBDB); - F_SET(dbp, F_ISSET(subdbp, - DB_AM_RECOVER | DB_AM_SWAP | - DB_AM_ENCRYPT | DB_AM_CHKSUM | DB_AM_NOT_DURABLE)); - - /* - * If there was a subdb specified, then we only want to apply - * DB_EXCL to the subdb, not the actual file. We only got here - * because there was a subdb specified. - */ - LF_CLR(DB_EXCL); - LF_SET(DB_RDWRMASTER); - if ((ret = __db_open(dbp, - txn, name, NULL, DB_BTREE, flags, mode, PGNO_BASE_MD)) != 0) - goto err; - - /* - * Verify that pagesize is the same on both. The items in dbp were now - * initialized from the meta page. The items in dbp were set in - * __db_dbopen when we either read or created the master file. Other - * items such as checksum and encryption are checked when we read the - * meta-page. So we do not check those here. However, if the - * meta-page caused checksumming to be turned on and it wasn't already, - * set it here. - */ - if (F_ISSET(dbp, DB_AM_CHKSUM)) - F_SET(subdbp, DB_AM_CHKSUM); - if (subdbp->pgsize != 0 && dbp->pgsize != subdbp->pgsize) { - ret = EINVAL; - __db_err(dbp->dbenv, - "Different pagesize specified on existent file"); - goto err; - } -err: - if (ret != 0 && !F_ISSET(dbp, DB_AM_DISCARD)) - (void)__db_close(dbp, txn, 0); - else - *dbpp = dbp; - return (ret); -} - -/* - * __db_master_update -- - * Add/Open/Remove a subdatabase from a master database. - * - * PUBLIC: int __db_master_update __P((DB *, DB *, DB_TXN *, const char *, - * PUBLIC: DBTYPE, mu_action, const char *, u_int32_t)); - */ -int -__db_master_update(mdbp, sdbp, txn, subdb, type, action, newname, flags) - DB *mdbp, *sdbp; - DB_TXN *txn; - const char *subdb; - DBTYPE type; - mu_action action; - const char *newname; - u_int32_t flags; -{ - DB_ENV *dbenv; - DBC *dbc, *ndbc; - DBT key, data, ndata; - PAGE *p, *r; - db_pgno_t t_pgno; - int modify, ret, t_ret; - - dbenv = mdbp->dbenv; - dbc = ndbc = NULL; - p = NULL; - - memset(&key, 0, sizeof(key)); - memset(&data, 0, sizeof(data)); - - /* Might we modify the master database? If so, we'll need to lock. */ - modify = (action != MU_OPEN || LF_ISSET(DB_CREATE)) ? 1 : 0; - - /* - * Open up a cursor. If this is CDB and we're creating the database, - * make it an update cursor. - */ - if ((ret = __db_cursor(mdbp, txn, &dbc, - (CDB_LOCKING(dbenv) && modify) ? DB_WRITECURSOR : 0)) != 0) - goto err; - - /* - * Point the cursor at the record. - * - * If we're removing or potentially creating an entry, lock the page - * with DB_RMW. - * - * We do multiple cursor operations with the cursor in some cases and - * subsequently access the data DBT information. Set DB_DBT_MALLOC so - * we don't risk modification of the data between our uses of it. - * - * !!! - * We don't include the name's nul termination in the database. - */ - key.data = (void *)subdb; - key.size = (u_int32_t)strlen(subdb); - F_SET(&data, DB_DBT_MALLOC); - - ret = __db_c_get(dbc, &key, &data, - DB_SET | ((STD_LOCKING(dbc) && modify) ? DB_RMW : 0)); - - /* - * What we do next--whether or not we found a record for the - * specified subdatabase--depends on what the specified action is. - * Handle ret appropriately as the first statement of each case. - */ - switch (action) { - case MU_REMOVE: - /* - * We should have found something if we're removing it. Note - * that in the common case where the DB we're asking to remove - * doesn't exist, we won't get this far; __db_subdb_remove - * will already have returned an error from __db_open. - */ - if (ret != 0) - goto err; - - /* - * Delete the subdatabase entry first; if this fails, - * we don't want to touch the actual subdb pages. - */ - if ((ret = __db_c_del(dbc, 0)) != 0) - goto err; - - /* - * We're handling actual data, not on-page meta-data, - * so it hasn't been converted to/from opposite - * endian architectures. Do it explicitly, now. - */ - memcpy(&sdbp->meta_pgno, data.data, sizeof(db_pgno_t)); - DB_NTOHL(&sdbp->meta_pgno); - if ((ret = - __memp_fget(mdbp->mpf, &sdbp->meta_pgno, 0, &p)) != 0) - goto err; - - /* Free the root on the master db if it was created. */ - if (TYPE(p) == P_BTREEMETA && - ((BTMETA *)p)->root != PGNO_INVALID) { - if ((ret = __memp_fget(mdbp->mpf, - &((BTMETA *)p)->root, 0, &r)) != 0) - goto err; - - /* Free and put the page. */ - if ((ret = __db_free(dbc, r)) != 0) { - r = NULL; - goto err; - } - } - /* Free and put the page. */ - if ((ret = __db_free(dbc, p)) != 0) { - p = NULL; - goto err; - } - p = NULL; - break; - case MU_RENAME: - /* We should have found something if we're renaming it. */ - if (ret != 0) - goto err; - - /* - * Before we rename, we need to make sure we're not - * overwriting another subdatabase, or else this operation - * won't be undoable. Open a second cursor and check - * for the existence of newname; it shouldn't appear under - * us since we hold the metadata lock. - */ - if ((ret = __db_cursor(mdbp, txn, &ndbc, 0)) != 0) - goto err; - key.data = (void *)newname; - key.size = (u_int32_t)strlen(newname); - - /* - * We don't actually care what the meta page of the potentially- - * overwritten DB is; we just care about existence. - */ - memset(&ndata, 0, sizeof(ndata)); - F_SET(&ndata, DB_DBT_USERMEM | DB_DBT_PARTIAL); - - if ((ret = __db_c_get(ndbc, &key, &ndata, DB_SET)) == 0) { - /* A subdb called newname exists. Bail. */ - ret = EEXIST; - __db_err(dbenv, "rename: database %s exists", newname); - goto err; - } else if (ret != DB_NOTFOUND) - goto err; - - /* - * Now do the put first; we don't want to lose our - * sole reference to the subdb. Use the second cursor - * so that the first one continues to point to the old record. - */ - if ((ret = __db_c_put(ndbc, &key, &data, DB_KEYFIRST)) != 0) - goto err; - if ((ret = __db_c_del(dbc, 0)) != 0) { - /* - * If the delete fails, try to delete the record - * we just put, in case we're not txn-protected. - */ - (void)__db_c_del(ndbc, 0); - goto err; - } - - break; - case MU_OPEN: - /* - * Get the subdatabase information. If it already exists, - * copy out the page number and we're done. - */ - switch (ret) { - case 0: - if (LF_ISSET(DB_CREATE) && LF_ISSET(DB_EXCL)) { - ret = EEXIST; - goto err; - } - memcpy(&sdbp->meta_pgno, data.data, sizeof(db_pgno_t)); - DB_NTOHL(&sdbp->meta_pgno); - goto done; - case DB_NOTFOUND: - if (LF_ISSET(DB_CREATE)) - break; - /* - * No db_err, it is reasonable to remove a - * nonexistent db. - */ - ret = ENOENT; - goto err; - default: - goto err; - } - - /* Create a subdatabase. */ - if ((ret = __db_new(dbc, - type == DB_HASH ? P_HASHMETA : P_BTREEMETA, &p)) != 0) - goto err; - sdbp->meta_pgno = PGNO(p); - - /* - * XXX - * We're handling actual data, not on-page meta-data, so it - * hasn't been converted to/from opposite endian architectures. - * Do it explicitly, now. - */ - t_pgno = PGNO(p); - DB_HTONL(&t_pgno); - memset(&ndata, 0, sizeof(ndata)); - ndata.data = &t_pgno; - ndata.size = sizeof(db_pgno_t); - if ((ret = __db_c_put(dbc, &key, &ndata, DB_KEYLAST)) != 0) - goto err; - F_SET(sdbp, DB_AM_CREATED); - break; - } - -err: -done: /* - * If we allocated a page: if we're successful, mark the page dirty - * and return it to the cache, otherwise, discard/free it. - */ - if (p != NULL) { - if (ret == 0) { - if ((t_ret = - __memp_fput(mdbp->mpf, p, DB_MPOOL_DIRTY)) != 0) - ret = t_ret; - } else - (void)__memp_fput(mdbp->mpf, p, 0); - } - - /* Discard the cursor(s) and data. */ - if (data.data != NULL) - __os_ufree(dbenv, data.data); - if (dbc != NULL && (t_ret = __db_c_close(dbc)) != 0 && ret == 0) - ret = t_ret; - if (ndbc != NULL && (t_ret = __db_c_close(ndbc)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __db_dbenv_setup -- - * Set up the underlying environment during a db_open. - * - * PUBLIC: int __db_dbenv_setup __P((DB *, - * PUBLIC: DB_TXN *, const char *, const char *, u_int32_t, u_int32_t)); - */ -int -__db_dbenv_setup(dbp, txn, fname, dname, id, flags) - DB *dbp; - DB_TXN *txn; - const char *fname, *dname; - u_int32_t id, flags; -{ - DB *ldbp; - DB_ENV *dbenv; - u_int32_t maxid; - int ret; - - dbenv = dbp->dbenv; - - /* If we don't yet have an environment, it's time to create it. */ - if (!F_ISSET(dbenv, DB_ENV_OPEN_CALLED)) { - /* Make sure we have at least DB_MINCACHE pages in our cache. */ - if (dbenv->mp_gbytes == 0 && - dbenv->mp_bytes < dbp->pgsize * DB_MINPAGECACHE && - (ret = __memp_set_cachesize( - dbenv, 0, dbp->pgsize * DB_MINPAGECACHE, 0)) != 0) - return (ret); - - if ((ret = __env_open(dbenv, NULL, DB_CREATE | - DB_INIT_MPOOL | DB_PRIVATE | LF_ISSET(DB_THREAD), 0)) != 0) - return (ret); - } - - /* Join the underlying cache. */ - if ((!F_ISSET(dbp, DB_AM_INMEM) || dname == NULL) && - (ret = __db_dbenv_mpool(dbp, fname, flags)) != 0) - return (ret); - - /* We may need a per-thread mutex. */ - if (LF_ISSET(DB_THREAD) && (ret = __mutex_alloc( - dbenv, MTX_DB_HANDLE, DB_MUTEX_THREAD, &dbp->mutex)) != 0) - return (ret); - - /* - * Set up a bookkeeping entry for this database in the log region, - * if such a region exists. Note that even if we're in recovery - * or a replication client, where we won't log registries, we'll - * still need an FNAME struct, so LOGGING_ON is the correct macro. - */ - if (LOGGING_ON(dbenv) && dbp->log_filename == NULL && - (ret = __dbreg_setup(dbp, - F_ISSET(dbp, DB_AM_INMEM) ? dname : fname, id)) != 0) - return (ret); - - /* - * If we're actively logging and our caller isn't a recovery function - * that already did so, then assign this dbp a log fileid. - */ - if (DBENV_LOGGING(dbenv) && !F_ISSET(dbp, DB_AM_RECOVER) && -#if !defined(DEBUG_ROP) - !F_ISSET(dbp, DB_AM_RDONLY) && -#endif - (ret = __dbreg_new_id(dbp, txn)) != 0) - return (ret); - - /* - * Insert ourselves into the DB_ENV's dblist. We allocate a - * unique ID to each {fileid, meta page number} pair, and to - * each temporary file (since they all have a zero fileid). - * This ID gives us something to use to tell which DB handles - * go with which databases in all the cursor adjustment - * routines, where we don't want to do a lot of ugly and - * expensive memcmps. - */ - MUTEX_LOCK(dbenv, dbenv->mtx_dblist); - for (maxid = 0, ldbp = LIST_FIRST(&dbenv->dblist); - ldbp != NULL; ldbp = LIST_NEXT(ldbp, dblistlinks)) { - if (!F_ISSET(dbp, DB_AM_INMEM)) { - if (memcmp(ldbp->fileid, dbp->fileid, DB_FILE_ID_LEN) - == 0 && ldbp->meta_pgno == dbp->meta_pgno) - break; - } else if (dname != NULL) { - if (F_ISSET(ldbp, DB_AM_INMEM) && - strcmp(ldbp->dname, dname) == 0) - break; - } - if (ldbp->adj_fileid > maxid) - maxid = ldbp->adj_fileid; - } - - /* - * If ldbp is NULL, we didn't find a match, or we weren't - * really looking because fname is NULL. Assign the dbp an - * adj_fileid one higher than the largest we found, and - * insert it at the head of the master dbp list. - * - * If ldbp is not NULL, it is a match for our dbp. Give dbp - * the same ID that ldbp has, and add it after ldbp so they're - * together in the list. - */ - if (ldbp == NULL) { - dbp->adj_fileid = maxid + 1; - LIST_INSERT_HEAD(&dbenv->dblist, dbp, dblistlinks); - } else { - dbp->adj_fileid = ldbp->adj_fileid; - LIST_INSERT_AFTER(ldbp, dbp, dblistlinks); - } - MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist); - - return (0); -} - -/* - * __db_dbenv_mpool -- - * Set up the underlying environment cache during a db_open. - * - * PUBLIC: int __db_dbenv_mpool __P((DB *, const char *, u_int32_t)); - */ -int -__db_dbenv_mpool(dbp, fname, flags) - DB *dbp; - const char *fname; - u_int32_t flags; -{ - DB_ENV *dbenv; - DBT pgcookie; - DB_MPOOLFILE *mpf; - DB_PGINFO pginfo; - int fidset, ftype, ret; - int32_t lsn_off; - u_int8_t nullfid[DB_FILE_ID_LEN]; - u_int32_t clear_len; - - COMPQUIET(mpf, NULL); - - dbenv = dbp->dbenv; - lsn_off = 0; - - /* It's possible that this database is already open. */ - if (F_ISSET(dbp, DB_AM_OPEN_CALLED)) - return (0); - - /* - * If we need to pre- or post-process a file's pages on I/O, set the - * file type. If it's a hash file, always call the pgin and pgout - * routines. This means that hash files can never be mapped into - * process memory. If it's a btree file and requires swapping, we - * need to page the file in and out. This has to be right -- we can't - * mmap files that are being paged in and out. - */ - switch (dbp->type) { - case DB_BTREE: - case DB_RECNO: - ftype = F_ISSET(dbp, DB_AM_SWAP | DB_AM_ENCRYPT | DB_AM_CHKSUM) - ? DB_FTYPE_SET : DB_FTYPE_NOTSET; - clear_len = CRYPTO_ON(dbenv) ? - (dbp->pgsize != 0 ? dbp->pgsize : DB_CLEARLEN_NOTSET) : - DB_PAGE_DB_LEN; - break; - case DB_HASH: - ftype = DB_FTYPE_SET; - clear_len = CRYPTO_ON(dbenv) ? - (dbp->pgsize != 0 ? dbp->pgsize : DB_CLEARLEN_NOTSET) : - DB_PAGE_DB_LEN; - break; - case DB_QUEUE: - ftype = F_ISSET(dbp, - DB_AM_SWAP | DB_AM_ENCRYPT | DB_AM_CHKSUM) ? - DB_FTYPE_SET : DB_FTYPE_NOTSET; - - /* - * If we came in here without a pagesize set, then we need - * to mark the in-memory handle as having clear_len not - * set, because we don't really know the clear length or - * the page size yet (since the file doesn't yet exist). - */ - clear_len = dbp->pgsize != 0 ? dbp->pgsize : DB_CLEARLEN_NOTSET; - break; - case DB_UNKNOWN: - /* - * If we're running in the verifier, our database might - * be corrupt and we might not know its type--but we may - * still want to be able to verify and salvage. - * - * If we can't identify the type, it's not going to be safe - * to call __db_pgin--we pretty much have to give up all - * hope of salvaging cross-endianness. Proceed anyway; - * at worst, the database will just appear more corrupt - * than it actually is, but at best, we may be able - * to salvage some data even with no metadata page. - */ - if (F_ISSET(dbp, DB_AM_VERIFYING)) { - ftype = DB_FTYPE_NOTSET; - clear_len = DB_PAGE_DB_LEN; - break; - } - - /* - * This might be an in-memory file and we won't know its - * file type until after we open it and read the meta-data - * page. - */ - if (F_ISSET(dbp, DB_AM_INMEM)) { - clear_len = DB_CLEARLEN_NOTSET; - ftype = DB_FTYPE_NOTSET; - lsn_off = DB_LSN_OFF_NOTSET; - break; - } - /* FALLTHROUGH */ - default: - return (__db_unknown_type(dbenv, "DB->open", dbp->type)); - } - - mpf = dbp->mpf; - - memset(nullfid, 0, DB_FILE_ID_LEN); - fidset = memcmp(nullfid, dbp->fileid, DB_FILE_ID_LEN); - if (fidset) - (void)__memp_set_fileid(mpf, dbp->fileid); - - (void)__memp_set_clear_len(mpf, clear_len); - (void)__memp_set_ftype(mpf, ftype); - (void)__memp_set_lsn_offset(mpf, lsn_off); - - pginfo.db_pagesize = dbp->pgsize; - pginfo.flags = - F_ISSET(dbp, (DB_AM_CHKSUM | DB_AM_ENCRYPT | DB_AM_SWAP)); - pginfo.type = dbp->type; - pgcookie.data = &pginfo; - pgcookie.size = sizeof(DB_PGINFO); - (void)__memp_set_pgcookie(mpf, &pgcookie); - - if ((ret = __memp_fopen(mpf, NULL, fname, - LF_ISSET(DB_CREATE | DB_DURABLE_UNKNOWN | - DB_NOMMAP | DB_ODDFILESIZE | DB_RDONLY | DB_TRUNCATE) | - (F_ISSET(dbenv, DB_ENV_DIRECT_DB) ? DB_DIRECT : 0) | - (F_ISSET(dbp, DB_AM_NOT_DURABLE) ? DB_TXN_NOT_DURABLE : 0), - 0, dbp->pgsize)) != 0) { - /* - * The open didn't work; we need to reset the mpf, - * retaining the in-memory semantics (if any). - */ - (void)__memp_fclose(dbp->mpf, 0); - (void)__memp_fcreate(dbenv, &dbp->mpf); - if (F_ISSET(dbp, DB_AM_INMEM)) - MAKE_INMEM(dbp); - return (ret); - } - - /* - * Set the open flag. We use it to mean that the dbp has gone - * through mpf setup, including dbreg_register. Also, below, - * the underlying access method open functions may want to do - * things like acquire cursors, so the open flag has to be set - * before calling them. - */ - F_SET(dbp, DB_AM_OPEN_CALLED); - if (!fidset && fname != NULL) { - (void)__memp_get_fileid(dbp->mpf, dbp->fileid); - dbp->preserve_fid = 1; - } - - return (0); -} - -/* - * __db_close -- - * DB->close method. - * - * PUBLIC: int __db_close __P((DB *, DB_TXN *, u_int32_t)); - */ -int -__db_close(dbp, txn, flags) - DB *dbp; - DB_TXN *txn; - u_int32_t flags; -{ - DB_ENV *dbenv; - int db_ref, deferred_close, ret, t_ret; - - dbenv = dbp->dbenv; - deferred_close = ret = 0; - - /* - * Validate arguments, but as a DB handle destructor, we can't fail. - * - * Check for consistent transaction usage -- ignore errors. Only - * internal callers specify transactions, so it's a serious problem - * if we get error messages. - */ - if (txn != NULL) - (void)__db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 0); - - /* Refresh the structure and close any underlying resources. */ - ret = __db_refresh(dbp, txn, flags, &deferred_close, 0); - - /* - * If we've deferred the close because the logging of the close failed, - * return our failure right away without destroying the handle. - */ - if (deferred_close) - return (ret); - - /* !!! - * This code has an apparent race between the moment we read and - * decrement dbenv->db_ref and the moment we check whether it's 0. - * However, if the environment is DBLOCAL, the user shouldn't have a - * reference to the dbenv handle anyway; the only way we can get - * multiple dbps sharing a local dbenv is if we open them internally - * during something like a subdatabase open. If any such thing is - * going on while the user is closing the original dbp with a local - * dbenv, someone's already badly screwed up, so there's no reason - * to bother engineering around this possibility. - */ - MUTEX_LOCK(dbenv, dbenv->mtx_dblist); - db_ref = --dbenv->db_ref; - MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist); - if (F_ISSET(dbenv, DB_ENV_DBLOCAL) && db_ref == 0 && - (t_ret = __env_close(dbenv, 0)) != 0 && ret == 0) - ret = t_ret; - - /* Free the database handle. */ - memset(dbp, CLEAR_BYTE, sizeof(*dbp)); - __os_free(dbenv, dbp); - - return (ret); -} - -/* - * __db_refresh -- - * Refresh the DB structure, releasing any allocated resources. - * This does most of the work of closing files now because refresh - * is what is used during abort processing (since we can't destroy - * the actual handle) and during abort processing, we may have a - * fully opened handle. - * - * PUBLIC: int __db_refresh __P((DB *, DB_TXN *, u_int32_t, int *, int)); - */ -int -__db_refresh(dbp, txn, flags, deferred_closep, reuse) - DB *dbp; - DB_TXN *txn; - u_int32_t flags; - int *deferred_closep, reuse; -{ - DB *sdbp; - DBC *dbc; - DB_ENV *dbenv; - DB_LOCKREQ lreq; - REGENV *renv; - REGINFO *infop; - u_int32_t save_flags; - int resync, ret, t_ret; - - ret = 0; - - dbenv = dbp->dbenv; - infop = dbenv->reginfo; - if (infop != NULL) - renv = infop->primary; - else - renv = NULL; - - /* If never opened, or not currently open, it's easy. */ - if (!F_ISSET(dbp, DB_AM_OPEN_CALLED)) - goto never_opened; - - /* - * If we have any secondary indices, disassociate them from us. - * We don't bother with the mutex here; it only protects some - * of the ops that will make us core-dump mid-close anyway, and - * if you're trying to do something with a secondary *while* you're - * closing the primary, you deserve what you get. The disassociation - * is mostly done just so we can close primaries and secondaries in - * any order--but within one thread of control. - */ - for (sdbp = LIST_FIRST(&dbp->s_secondaries); - sdbp != NULL; sdbp = LIST_NEXT(sdbp, s_links)) { - LIST_REMOVE(sdbp, s_links); - if ((t_ret = __db_disassociate(sdbp)) != 0 && ret == 0) - ret = t_ret; - } - - /* - * Sync the underlying access method. Do before closing the cursors - * because DB->sync allocates cursors in order to write Recno backing - * source text files. - * - * Sync is slow on some systems, notably Solaris filesystems where the - * entire buffer cache is searched. If we're in recovery, don't flush - * the file, it's not necessary. - */ - if (!LF_ISSET(DB_NOSYNC) && - !F_ISSET(dbp, DB_AM_DISCARD | DB_AM_RECOVER) && - (t_ret = __db_sync(dbp)) != 0 && ret == 0) - ret = t_ret; - - /* - * Go through the active cursors and call the cursor recycle routine, - * which resolves pending operations and moves the cursors onto the - * free list. Then, walk the free list and call the cursor destroy - * routine. Note that any failure on a close is considered "really - * bad" and we just break out of the loop and force forward. - */ - resync = TAILQ_FIRST(&dbp->active_queue) == NULL ? 0 : 1; - while ((dbc = TAILQ_FIRST(&dbp->active_queue)) != NULL) - if ((t_ret = __db_c_close(dbc)) != 0) { - if (ret == 0) - ret = t_ret; - break; - } - - while ((dbc = TAILQ_FIRST(&dbp->free_queue)) != NULL) - if ((t_ret = __db_c_destroy(dbc)) != 0) { - if (ret == 0) - ret = t_ret; - break; - } - - /* - * Close any outstanding join cursors. Join cursors destroy themselves - * on close and have no separate destroy routine. We don't have to set - * the resync flag here, because join cursors aren't write cursors. - */ - while ((dbc = TAILQ_FIRST(&dbp->join_queue)) != NULL) - if ((t_ret = __db_join_close(dbc)) != 0) { - if (ret == 0) - ret = t_ret; - break; - } - - /* - * Sync the memory pool, even though we've already called DB->sync, - * because closing cursors can dirty pages by deleting items they - * referenced. - * - * Sync is slow on some systems, notably Solaris filesystems where the - * entire buffer cache is searched. If we're in recovery, don't flush - * the file, it's not necessary. - */ - if (resync && !LF_ISSET(DB_NOSYNC) && - !F_ISSET(dbp, DB_AM_DISCARD | DB_AM_RECOVER) && - (t_ret = __memp_fsync(dbp->mpf)) != 0 && ret == 0) - ret = t_ret; - -never_opened: - /* - * At this point, we haven't done anything to render the DB - * handle unusable, at least by a transaction abort. Take the - * opportunity now to log the file close. If this log fails - * and we're in a transaction, we have to bail out of the attempted - * close; we'll need a dbp in order to successfully abort the - * transaction, and we can't conjure a new one up because we haven't - * gotten out the dbreg_register record that represents the close. - * In this case, we put off actually closing the dbp until we've - * performed the abort. - */ - if (!reuse && LOGGING_ON(dbp->dbenv)) { - /* - * Discard the log file id, if any. We want to log the close - * if and only if this is not a recovery dbp or a client dbp, - * or a dead dbp handle. - */ - DB_ASSERT(renv != NULL); - if (F_ISSET(dbp, DB_AM_RECOVER) || IS_REP_CLIENT(dbenv) || - dbp->timestamp != renv->rep_timestamp) - t_ret = __dbreg_revoke_id(dbp, 0, DB_LOGFILEID_INVALID); - else { - if ((t_ret = __dbreg_close_id(dbp, - txn, DBREG_CLOSE)) != 0 && txn != NULL) { - /* - * We're in a txn and the attempt to log the - * close failed; let the txn subsystem know - * that we need to destroy this dbp once we're - * done with the abort, then bail from the - * close. - * - * Note that if the attempt to put off the - * close -also- fails--which it won't unless - * we're out of heap memory--we're really - * screwed. Panic. - */ - if ((ret = - __txn_closeevent(dbenv, txn, dbp)) != 0) - return (__db_panic(dbenv, ret)); - if (deferred_closep != NULL) - *deferred_closep = 1; - return (t_ret); - } - /* - * If dbreg_close_id failed and we were not in a - * transaction, then we need to finish this close - * because the caller can't do anything with the - * handle after we return an error. We rely on - * dbreg_close_id to mark the entry in some manner - * so that we do not do a clean shutdown of this - * environment. If shutdown isn't clean, then the - * application *must* run recovery and that will - * generate the RCLOSE record. - */ - } - - if (ret == 0) - ret = t_ret; - - /* Discard the log FNAME. */ - if ((t_ret = __dbreg_teardown(dbp)) != 0 && ret == 0) - ret = t_ret; - } - - /* Close any handle we've been holding since the open. */ - if (dbp->saved_open_fhp != NULL && - (t_ret = __os_closehandle(dbenv, dbp->saved_open_fhp)) != 0 && - ret == 0) - ret = t_ret; - - /* - * Remove this DB handle from the DB_ENV's dblist, if it's been added. - * - * Close our reference to the underlying cache while locked, we don't - * want to race with a thread searching for our underlying cache link - * while opening a DB handle. - */ - MUTEX_LOCK(dbenv, dbenv->mtx_dblist); - if (!reuse && dbp->dblistlinks.le_prev != NULL) { - LIST_REMOVE(dbp, dblistlinks); - dbp->dblistlinks.le_prev = NULL; - } - - /* Close the memory pool file handle. */ - if (dbp->mpf != NULL) { - if ((t_ret = __memp_fclose(dbp->mpf, - F_ISSET(dbp, DB_AM_DISCARD) ? DB_MPOOL_DISCARD : 0)) != 0 && - ret == 0) - ret = t_ret; - dbp->mpf = NULL; - if (reuse && - (t_ret = __memp_fcreate(dbenv, &dbp->mpf)) != 0 && - ret == 0) - ret = t_ret; - } - - MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist); - - /* - * Call the access specific close function. - * - * We do this here rather than in __db_close as we need to do this when - * aborting an open so that file descriptors are closed and abort of - * renames can succeed on platforms that lock open files (such as - * Windows). In particular, we need to ensure that all the extents - * associated with a queue are closed so that queue renames can be - * aborted. - * - * It is also important that we do this before releasing the handle - * lock, because dbremove and dbrename assume that once they have the - * handle lock, it is safe to modify the underlying file(s). - * - * !!! - * Because of where these functions are called in the DB handle close - * process, these routines can't do anything that would dirty pages or - * otherwise affect closing down the database. Specifically, we can't - * abort and recover any of the information they control. - */ - if ((t_ret = __bam_db_close(dbp)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = __ham_db_close(dbp)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = __qam_db_close(dbp, dbp->flags)) != 0 && ret == 0) - ret = t_ret; - - /* - * !!! - * At this point, the access-method specific information has been - * freed. From now on, we can use the dbp, but not touch any - * access-method specific data. - */ - - if (!reuse && dbp->lid != DB_LOCK_INVALIDID) { - /* We may have pending trade operations on this dbp. */ - if (txn != NULL) - __txn_remlock(dbenv, txn, &dbp->handle_lock, dbp->lid); - - /* We may be holding the handle lock; release it. */ - lreq.op = DB_LOCK_PUT_ALL; - lreq.obj = NULL; - if ((t_ret = __lock_vec(dbenv, - dbp->lid, 0, &lreq, 1, NULL)) != 0 && ret == 0) - ret = t_ret; - - if ((t_ret = __lock_id_free(dbenv, dbp->lid)) != 0 && ret == 0) - ret = t_ret; - dbp->lid = DB_LOCK_INVALIDID; - LOCK_INIT(dbp->handle_lock); - } - - /* - * If this is a temporary file (un-named in-memory file), then - * discard the locker ID allocated as the fileid. - */ - if (LOCKING_ON(dbenv) && - F_ISSET(dbp, DB_AM_INMEM) && !dbp->preserve_fid && - *(u_int32_t *)dbp->fileid != DB_LOCK_INVALIDID && - (t_ret = __lock_id_free(dbenv, *(u_int32_t *)dbp->fileid)) != 0 && - ret == 0) - ret = t_ret; - - if (reuse) { - /* - * If we are reusing this dbp, then we're done now. Re-init - * the handle, preserving important flags, and then return. - * This code is borrowed from __db_init, which does more - * than we can do here. - */ - save_flags = F_ISSET(dbp, DB_AM_INMEM | DB_AM_TXN); - - /* - * XXX If this is an XA handle, we'll want to specify - * DB_XA_CREATE. - */ - if ((ret = __bam_db_create(dbp)) != 0) - return (ret); - if ((ret = __ham_db_create(dbp)) != 0) - return (ret); - if ((ret = __qam_db_create(dbp)) != 0) - return (ret); - - /* Restore flags */ - dbp->flags = dbp->orig_flags | save_flags; - - if (FLD_ISSET(save_flags, DB_AM_INMEM)) { - /* - * If this is inmem, then it may have a fileid - * even if it was never opened, and we need to - * clear out that fileid. - */ - memset(dbp->fileid, 0, sizeof(dbp->fileid)); - MAKE_INMEM(dbp); - } - return (ret); - } - - dbp->type = DB_UNKNOWN; - - /* Discard the thread mutex. */ - if ((t_ret = __mutex_free(dbenv, &dbp->mutex)) != 0 && ret == 0) - ret = t_ret; - - /* Discard any memory allocated for the file and database names. */ - if (dbp->fname != NULL) { - __os_free(dbp->dbenv, dbp->fname); - dbp->fname = NULL; - } - if (dbp->dname != NULL) { - __os_free(dbp->dbenv, dbp->dname); - dbp->dname = NULL; - } - - /* Discard any memory used to store returned data. */ - if (dbp->my_rskey.data != NULL) - __os_free(dbp->dbenv, dbp->my_rskey.data); - if (dbp->my_rkey.data != NULL) - __os_free(dbp->dbenv, dbp->my_rkey.data); - if (dbp->my_rdata.data != NULL) - __os_free(dbp->dbenv, dbp->my_rdata.data); - - /* For safety's sake; we may refresh twice. */ - memset(&dbp->my_rskey, 0, sizeof(DBT)); - memset(&dbp->my_rkey, 0, sizeof(DBT)); - memset(&dbp->my_rdata, 0, sizeof(DBT)); - - /* Clear out fields that normally get set during open. */ - memset(dbp->fileid, 0, sizeof(dbp->fileid)); - dbp->adj_fileid = 0; - dbp->meta_pgno = 0; - dbp->cur_lid = DB_LOCK_INVALIDID; - dbp->associate_lid = DB_LOCK_INVALIDID; - dbp->cl_id = 0; - dbp->open_flags = 0; - - /* - * If we are being refreshed with a txn specified, then we need - * to make sure that we clear out the lock handle field, because - * releasing all the locks for this transaction will release this - * lock and we don't want close to stumble upon this handle and - * try to close it. - */ - if (txn != NULL) - LOCK_INIT(dbp->handle_lock); - - /* Reset flags to whatever the user configured. */ - dbp->flags = dbp->orig_flags; - - return (ret); -} - -/* - * __db_log_page - * Log a meta-data or root page during a subdatabase create operation. - * - * PUBLIC: int __db_log_page __P((DB *, DB_TXN *, DB_LSN *, db_pgno_t, PAGE *)); - */ -int -__db_log_page(dbp, txn, lsn, pgno, page) - DB *dbp; - DB_TXN *txn; - DB_LSN *lsn; - db_pgno_t pgno; - PAGE *page; -{ - DBT page_dbt; - DB_LSN new_lsn; - int ret; - - if (!LOGGING_ON(dbp->dbenv) || txn == NULL) - return (0); - - memset(&page_dbt, 0, sizeof(page_dbt)); - page_dbt.size = dbp->pgsize; - page_dbt.data = page; - - ret = __crdel_metasub_log(dbp, txn, &new_lsn, 0, pgno, &page_dbt, lsn); - - if (ret == 0) - page->lsn = new_lsn; - return (ret); -} - -/* - * __db_backup_name - * Create the backup file name for a given file. - * - * PUBLIC: int __db_backup_name __P((DB_ENV *, - * PUBLIC: const char *, DB_TXN *, char **)); - */ -#undef BACKUP_PREFIX -#define BACKUP_PREFIX "__db" - -#undef MAX_LSN_TO_TEXT -#define MAX_LSN_TO_TEXT 17 - -int -__db_backup_name(dbenv, name, txn, backup) - DB_ENV *dbenv; - const char *name; - DB_TXN *txn; - char **backup; -{ - DB_LSN lsn; - size_t len; - int ret; - char *p, *retp; - - /* - * Part of the name may be a full path, so we need to make sure that - * we allocate enough space for it, even in the case where we don't - * use the entire filename for the backup name. - */ - len = strlen(name) + strlen(BACKUP_PREFIX) + 1 + MAX_LSN_TO_TEXT; - if ((ret = __os_malloc(dbenv, len, &retp)) != 0) - return (ret); - - /* - * Create the name. Backup file names are in one of three forms: - * - * In a transactional env: __db.LSN(8).LSN(8) - * and - * In VXWORKS (where we want 8.3 support) - * and - * in any other non-transactional env: __db.FILENAME - * - * If the transaction doesn't have a current LSN, we write a dummy - * log record to force it, so we ensure all tmp names are unique. - * - * In addition, the name passed may contain an env-relative path. - * In that case, put the __db. in the right place (in the last - * component of the pathname). - * - * There are four cases here: - * 1. simple path w/out transaction - * 2. simple path + transaction - * 3. multi-component path w/out transaction - * 4. multi-component path + transaction - */ - p = __db_rpath(name); - if (txn == NULL) { -#ifdef HAVE_VXWORKS - { int i, n; - /* On VxWorks we must support 8.3 names. */ - if (p == NULL) /* Case 1. */ - n = snprintf(retp, - len, "%s%.4s.tmp", BACKUP_PREFIX, name); - else /* Case 3. */ - n = snprintf(retp, len, "%.*s%s%.4s.tmp", - (int)(p - name) + 1, name, BACKUP_PREFIX, p + 1); - - /* - * Overwrite "." in the characters copied from the name. - * If we backup 8 characters from the end, we're guaranteed - * to a) include the four bytes we copied from the name - * and b) not run off the beginning of the string. - */ - for (i = 0, p = (retp + n) - 8; i < 4; p++, i++) - if (*p == '.') - *p = '_'; - } -#else - if (p == NULL) /* Case 1. */ - snprintf(retp, len, "%s.%s", BACKUP_PREFIX, name); - else /* Case 3. */ - snprintf(retp, len, "%.*s%s.%s", - (int)(p - name) + 1, name, BACKUP_PREFIX, p + 1); -#endif - } else { - lsn = ((TXN_DETAIL *)txn->td)->last_lsn; - if (IS_ZERO_LSN(lsn)) { - /* - * Write dummy log record. The two choices for dummy - * log records are __db_noop_log and __db_debug_log; - * unfortunately __db_noop_log requires a valid dbp, - * and we aren't guaranteed to be able to pass one in - * here. - */ - if ((ret = __db_debug_log(dbenv, - txn, &lsn, 0, NULL, 0, NULL, NULL, 0)) != 0) { - __os_free(dbenv, retp); - return (ret); - } - } - - if (p == NULL) /* Case 2. */ - snprintf(retp, len, - "%s.%x.%x", BACKUP_PREFIX, lsn.file, lsn.offset); - else /* Case 4. */ - snprintf(retp, len, "%.*s%x.%x", - (int)(p - name) + 1, name, lsn.file, lsn.offset); - } - - *backup = retp; - return (0); -} - -/* - * __dblist_get -- - * Get the first element of dbenv->dblist with - * dbp->adj_fileid matching adjid. - * - * PUBLIC: DB *__dblist_get __P((DB_ENV *, u_int32_t)); - */ -DB * -__dblist_get(dbenv, adjid) - DB_ENV *dbenv; - u_int32_t adjid; -{ - DB *dbp; - - for (dbp = LIST_FIRST(&dbenv->dblist); - dbp != NULL && dbp->adj_fileid != adjid; - dbp = LIST_NEXT(dbp, dblistlinks)) - ; - - return (dbp); -} - -/* - * __db_disassociate -- - * Destroy the association between a given secondary and its primary. - */ -static int -__db_disassociate(sdbp) - DB *sdbp; -{ - DBC *dbc; - int ret, t_ret; - - ret = 0; - - sdbp->s_callback = NULL; - sdbp->s_primary = NULL; - sdbp->get = sdbp->stored_get; - sdbp->close = sdbp->stored_close; - - /* - * Complain, but proceed, if we have any active cursors. (We're in - * the middle of a close, so there's really no turning back.) - */ - if (sdbp->s_refcnt != 1 || - TAILQ_FIRST(&sdbp->active_queue) != NULL || - TAILQ_FIRST(&sdbp->join_queue) != NULL) { - __db_err(sdbp->dbenv, - "Closing a primary DB while a secondary DB has active cursors is unsafe"); - ret = EINVAL; - } - sdbp->s_refcnt = 0; - - while ((dbc = TAILQ_FIRST(&sdbp->free_queue)) != NULL) - if ((t_ret = __db_c_destroy(dbc)) != 0 && ret == 0) - ret = t_ret; - - F_CLR(sdbp, DB_AM_SECONDARY); - return (ret); -} - -#ifdef CONFIG_TEST -/* - * __db_testcopy - * Create a copy of all backup files and our "main" DB. - * - * PUBLIC: #ifdef CONFIG_TEST - * PUBLIC: int __db_testcopy __P((DB_ENV *, DB *, const char *)); - * PUBLIC: #endif - */ -int -__db_testcopy(dbenv, dbp, name) - DB_ENV *dbenv; - DB *dbp; - const char *name; -{ - DB_MPOOL *dbmp; - DB_MPOOLFILE *mpf; - - DB_ASSERT(dbp != NULL || name != NULL); - - if (name == NULL) { - dbmp = dbenv->mp_handle; - mpf = dbp->mpf; - name = R_ADDR(dbmp->reginfo, mpf->mfp->path_off); - } - - if (dbp != NULL && dbp->type == DB_QUEUE) - return (__qam_testdocopy(dbp, name)); - else - return (__db_testdocopy(dbenv, name)); -} - -static int -__qam_testdocopy(dbp, name) - DB *dbp; - const char *name; -{ - QUEUE_FILELIST *filelist, *fp; - char buf[256], *dir; - int ret; - - filelist = NULL; - if ((ret = __db_testdocopy(dbp->dbenv, name)) != 0) - return (ret); - if (dbp->mpf != NULL && - (ret = __qam_gen_filelist(dbp, &filelist)) != 0) - return (ret); - - if (filelist == NULL) - return (0); - dir = ((QUEUE *)dbp->q_internal)->dir; - for (fp = filelist; fp->mpf != NULL; fp++) { - snprintf(buf, sizeof(buf), - QUEUE_EXTENT, dir, PATH_SEPARATOR[0], name, fp->id); - if ((ret = __db_testdocopy(dbp->dbenv, buf)) != 0) - return (ret); - } - - __os_free(dbp->dbenv, filelist); - return (0); -} - -/* - * __db_testdocopy - * Create a copy of all backup files and our "main" DB. - * - */ -static int -__db_testdocopy(dbenv, name) - DB_ENV *dbenv; - const char *name; -{ - size_t len; - int dircnt, i, ret; - char *backup, *copy, *dir, **namesp, *p, *real_name; - - dircnt = 0; - copy = backup = NULL; - namesp = NULL; - - /* Get the real backing file name. */ - if ((ret = __db_appname(dbenv, - DB_APP_DATA, name, 0, NULL, &real_name)) != 0) - return (ret); - - /* - * Maximum size of file, including adding a ".afterop". - */ - len = strlen(real_name) + - strlen(BACKUP_PREFIX) + 1 + MAX_LSN_TO_TEXT + 9; - - if ((ret = __os_malloc(dbenv, len, ©)) != 0) - goto err; - - if ((ret = __os_malloc(dbenv, len, &backup)) != 0) - goto err; - - /* - * First copy the file itself. - */ - snprintf(copy, len, "%s.afterop", real_name); - __db_makecopy(dbenv, real_name, copy); - - if ((ret = __os_strdup(dbenv, real_name, &dir)) != 0) - goto err; - __os_free(dbenv, real_name); - real_name = NULL; - - /* - * Create the name. Backup file names are of the form: - * - * __db.name.0x[lsn-file].0x[lsn-offset] - * - * which guarantees uniqueness. We want to look for the - * backup name, followed by a '.0x' (so that if they have - * files named, say, 'a' and 'abc' we won't match 'abc' when - * looking for 'a'. - */ - snprintf(backup, len, "%s.%s.0x", BACKUP_PREFIX, name); - - /* - * We need the directory path to do the __os_dirlist. - */ - p = __db_rpath(dir); - if (p != NULL) - *p = '\0'; - ret = __os_dirlist(dbenv, dir, &namesp, &dircnt); -#if DIAGNOSTIC - /* - * XXX - * To get the memory guard code to work because it uses strlen and we - * just moved the end of the string somewhere sooner. This causes the - * guard code to fail because it looks at one byte past the end of the - * string. - */ - *p = '/'; -#endif - __os_free(dbenv, dir); - if (ret != 0) - goto err; - for (i = 0; i < dircnt; i++) { - /* - * Need to check if it is a backup file for this. - * No idea what namesp[i] may be or how long, so - * must use strncmp and not memcmp. We don't want - * to use strcmp either because we are only matching - * the first part of the real file's name. We don't - * know its LSN's. - */ - if (strncmp(namesp[i], backup, strlen(backup)) == 0) { - if ((ret = __db_appname(dbenv, DB_APP_DATA, - namesp[i], 0, NULL, &real_name)) != 0) - goto err; - - /* - * This should not happen. Check that old - * .afterop files aren't around. - * If so, just move on. - */ - if (strstr(real_name, ".afterop") != NULL) { - __os_free(dbenv, real_name); - real_name = NULL; - continue; - } - snprintf(copy, len, "%s.afterop", real_name); - __db_makecopy(dbenv, real_name, copy); - __os_free(dbenv, real_name); - real_name = NULL; - } - } - -err: if (backup != NULL) - __os_free(dbenv, backup); - if (copy != NULL) - __os_free(dbenv, copy); - if (namesp != NULL) - __os_dirfree(dbenv, namesp, dircnt); - if (real_name != NULL) - __os_free(dbenv, real_name); - return (ret); -} - -static void -__db_makecopy(dbenv, src, dest) - DB_ENV *dbenv; - const char *src, *dest; -{ - DB_FH *rfhp, *wfhp; - size_t rcnt, wcnt; - char *buf; - - rfhp = wfhp = NULL; - - if (__os_malloc(dbenv, 1024, &buf) != 0) - return; - - if (__os_open(dbenv, - src, DB_OSO_RDONLY, __db_omode(OWNER_RW), &rfhp) != 0) - goto err; - if (__os_open(dbenv, dest, - DB_OSO_CREATE | DB_OSO_TRUNC, __db_omode(OWNER_RW), &wfhp) != 0) - goto err; - - for (;;) - if (__os_read(dbenv, rfhp, buf, 1024, &rcnt) < 0 || rcnt == 0 || - __os_write(dbenv, wfhp, buf, rcnt, &wcnt) < 0) - break; - -err: if (buf != NULL) - __os_free(dbenv, buf); - if (rfhp != NULL) - (void)__os_closehandle(dbenv, rfhp); - if (wfhp != NULL) - (void)__os_closehandle(dbenv, wfhp); -} -#endif diff --git a/storage/bdb/db/db.src b/storage/bdb/db/db.src deleted file mode 100644 index 21fe754a3f7..00000000000 --- a/storage/bdb/db/db.src +++ /dev/null @@ -1,259 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db.src,v 12.2 2005/08/08 03:37:06 ubell Exp $ - */ - -PREFIX __db -DBPRIVATE - -INCLUDE #ifndef NO_SYSTEM_INCLUDES -INCLUDE #include <sys/types.h> -INCLUDE -INCLUDE #include <ctype.h> -INCLUDE #include <string.h> -INCLUDE #endif -INCLUDE -INCLUDE #include "db_int.h" -INCLUDE #include "dbinc/crypto.h" -INCLUDE #include "dbinc/db_page.h" -INCLUDE #include "dbinc/db_dispatch.h" -INCLUDE #include "dbinc/db_am.h" -INCLUDE #include "dbinc/log.h" -INCLUDE #include "dbinc/txn.h" -INCLUDE - -/* - * addrem -- Add or remove an entry from a duplicate page. - * - * opcode: identifies if this is an add or delete. - * fileid: file identifier of the file being modified. - * pgno: duplicate page number. - * indx: location at which to insert or delete. - * nbytes: number of bytes added/removed to/from the page. - * hdr: header for the data item. - * dbt: data that is deleted or is to be added. - * pagelsn: former lsn of the page. - * - * If the hdr was NULL then, the dbt is a regular B_KEYDATA. - * If the dbt was NULL then the hdr is a complete item to be - * pasted on the page. - */ -BEGIN addrem 41 -ARG opcode u_int32_t lu -DB fileid int32_t ld -ARG pgno db_pgno_t lu -ARG indx u_int32_t lu -ARG nbytes u_int32_t lu -PGDBT hdr DBT s -DBT dbt DBT s -POINTER pagelsn DB_LSN * lu -END - -/* - * big -- Handles addition and deletion of big key/data items. - * - * opcode: identifies get/put. - * fileid: file identifier of the file being modified. - * pgno: page onto which data is being added/removed. - * prev_pgno: the page before the one we are logging. - * next_pgno: the page after the one we are logging. - * dbt: data being written onto the page. - * pagelsn: former lsn of the orig_page. - * prevlsn: former lsn of the prev_pgno. - * nextlsn: former lsn of the next_pgno. This is not currently used, but - * may be used later if we actually do overwrites of big key/ - * data items in place. - */ -BEGIN big 43 -ARG opcode u_int32_t lu -DB fileid int32_t ld -ARG pgno db_pgno_t lu -ARG prev_pgno db_pgno_t lu -ARG next_pgno db_pgno_t lu -DBT dbt DBT s -POINTER pagelsn DB_LSN * lu -POINTER prevlsn DB_LSN * lu -POINTER nextlsn DB_LSN * lu -END - -/* - * ovref -- Handles increment/decrement of overflow page reference count. - * - * fileid: identifies the file being modified. - * pgno: page number whose ref count is being incremented/decremented. - * adjust: the adjustment being made. - * lsn: the page's original lsn. - */ -BEGIN ovref 44 -DB fileid int32_t ld -ARG pgno db_pgno_t lu -ARG adjust int32_t ld -POINTER lsn DB_LSN * lu -END - -/* - * Debug -- log an operation upon entering an access method. - * op: Operation (cursor, c_close, c_get, c_put, c_del, - * get, put, delete). - * fileid: identifies the file being acted upon. - * key: key paramater - * data: data parameter - * flags: flags parameter - */ -BEGIN debug 47 -DBT op DBT s -ARG fileid int32_t ld -DBT key DBT s -DBT data DBT s -ARG arg_flags u_int32_t lu -END - -/* - * noop -- do nothing, but get an LSN. - */ -BEGIN noop 48 -DB fileid int32_t ld -ARG pgno db_pgno_t lu -POINTER prevlsn DB_LSN * lu -END - -/* - * pg_alloc: used to record allocating a new page. - * - * meta_lsn: the meta-data page's original lsn. - * meta_pgno the meta-data page number. - * page_lsn: the allocated page's original lsn. - * pgno: the page allocated. - * ptype: the type of the page allocated. - * next: the next page on the free list. - * last_pgno: the last page in the file after this op. - */ -BEGIN pg_alloc 49 -DB fileid int32_t ld -POINTER meta_lsn DB_LSN * lu -ARG meta_pgno db_pgno_t lu -POINTER page_lsn DB_LSN * lu -ARG pgno db_pgno_t lu -ARG ptype u_int32_t lu -ARG next db_pgno_t lu -ARG last_pgno db_pgno_t lu -END - -/* - * pg_free: used to record freeing a page. - * - * pgno: the page being freed. - * meta_lsn: the meta-data page's original lsn. - * meta_pgno: the meta-data page number. - * header: the header from the free'd page. - * next: the previous next pointer on the metadata page. - * last_pgno: the last page in the file before this op. - */ -BEGIN pg_free 50 -DB fileid int32_t ld -ARG pgno db_pgno_t lu -POINTER meta_lsn DB_LSN * lu -ARG meta_pgno db_pgno_t lu -PGDBT header DBT s -ARG next db_pgno_t lu -ARG last_pgno db_pgno_t lu -END - -/* - * cksum -- - * This log record is written when we're unable to checksum a page, - * before returning DB_RUNRECOVERY. This log record causes normal - * recovery to itself return DB_RUNRECOVERY, as only catastrophic - * recovery can fix things. - */ -BEGIN cksum 51 -END - -/* - * pg_freedata: used to record freeing a page with data on it. - * - * pgno: the page being freed. - * meta_lsn: the meta-data page's original lsn. - * meta_pgno: the meta-data page number. - * header: the header and index entries from the free'd page. - * data: the data from the free'd page. - * next: the previous next pointer on the metadata page. - * last_pgno: the last page in the file before this op. - */ -BEGIN pg_freedata 52 -DB fileid int32_t ld -ARG pgno db_pgno_t lu -POINTER meta_lsn DB_LSN * lu -ARG meta_pgno db_pgno_t lu -PGDBT header DBT s -ARG next db_pgno_t lu -ARG last_pgno db_pgno_t lu -PGDBT data DBT s -END - -/* - * pg_prepare: used to record an aborted page in a prepared transaction. - * - * pgno: the page being freed. - */ -BEGIN pg_prepare 53 -DB fileid int32_t ld -ARG pgno db_pgno_t lu -END - -/* - * pg_new: used to record a new page put on the free list. - * - * pgno: the page being freed. - * meta_lsn: the meta-data page's original lsn. - * meta_pgno: the meta-data page number. - * header: the header from the free'd page. - * next: the previous next pointer on the metadata page. - */ -BEGIN pg_new 54 -DB fileid int32_t ld -ARG pgno db_pgno_t lu -POINTER meta_lsn DB_LSN * lu -ARG meta_pgno db_pgno_t lu -PGDBT header DBT s -ARG next db_pgno_t lu -END - -/* - * pg_init: used to reinitialize a page during truncate. - * - * pgno: the page being initialized. - * header: the header from the page. - * data: data that used to be on the page. - */ -BEGIN pg_init 60 -DB fileid int32_t ld -ARG pgno db_pgno_t lu -PGDBT header DBT s -PGDBT data DBT s -END - -/* - * pg_sort: sort the free list - * - * meta: meta page number - * meta_lsn: lsn on meta page. - * last_free: page number of new last free page. - * last_lsn; lsn of last free page. - * last_pgno: current last page number. - * list: list of pages and lsns to sort. - */ -BEGIN pg_sort 61 -DB fileid int32_t ld -ARG meta db_pgno_t lu -POINTER meta_lsn DB_LSN * lu -ARG last_free db_pgno_t lu -POINTER last_lsn DB_LSN * lu -ARG last_pgno db_pgno_t lu -DBT list DBT s -END - diff --git a/storage/bdb/db/db_am.c b/storage/bdb/db/db_am.c deleted file mode 100644 index 966f5f07123..00000000000 --- a/storage/bdb/db/db_am.c +++ /dev/null @@ -1,904 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1998-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_am.c,v 12.12 2005/11/01 00:44:09 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/btree.h" -#include "dbinc/hash.h" -#include "dbinc/lock.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" -#include "dbinc/qam.h" - -static int __db_append_primary __P((DBC *, DBT *, DBT *)); -static int __db_secondary_get __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); - -/* - * __db_cursor_int -- - * Internal routine to create a cursor. - * - * PUBLIC: int __db_cursor_int - * PUBLIC: __P((DB *, DB_TXN *, DBTYPE, db_pgno_t, int, u_int32_t, DBC **)); - */ -int -__db_cursor_int(dbp, txn, dbtype, root, is_opd, lockerid, dbcp) - DB *dbp; - DB_TXN *txn; - DBTYPE dbtype; - db_pgno_t root; - int is_opd; - u_int32_t lockerid; - DBC **dbcp; -{ - DBC *dbc; - DBC_INTERNAL *cp; - DB_ENV *dbenv; - db_threadid_t tid; - int allocated, ret; - pid_t pid; - - dbenv = dbp->dbenv; - allocated = 0; - - /* - * If dbcp is non-NULL it is assumed to point to an area to initialize - * as a cursor. - * - * Take one from the free list if it's available. Take only the - * right type. With off page dups we may have different kinds - * of cursors on the queue for a single database. - */ - MUTEX_LOCK(dbenv, dbp->mutex); - for (dbc = TAILQ_FIRST(&dbp->free_queue); - dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) - if (dbtype == dbc->dbtype) { - TAILQ_REMOVE(&dbp->free_queue, dbc, links); - F_CLR(dbc, ~DBC_OWN_LID); - break; - } - MUTEX_UNLOCK(dbenv, dbp->mutex); - - if (dbc == NULL) { - if ((ret = __os_calloc(dbenv, 1, sizeof(DBC), &dbc)) != 0) - return (ret); - allocated = 1; - dbc->flags = 0; - - dbc->dbp = dbp; - - /* Set up locking information. */ - if (LOCKING_ON(dbenv)) { - /* - * If we are not threaded, we share a locker ID among - * all cursors opened in the environment handle, - * allocating one if this is the first cursor. - * - * This relies on the fact that non-threaded DB handles - * always have non-threaded environment handles, since - * we set DB_THREAD on DB handles created with threaded - * environment handles. - */ - if (!DB_IS_THREADED(dbp)) { - if (dbp->dbenv->env_lref == NULL && - (ret = __lock_id(dbenv, NULL, - (DB_LOCKER **)&dbp->dbenv->env_lref)) != 0) - goto err; - dbc->lref = dbp->dbenv->env_lref; - } else { - if ((ret = __lock_id(dbenv, NULL, - (DB_LOCKER **)&dbc->lref)) != 0) - goto err; - F_SET(dbc, DBC_OWN_LID); - } - - /* - * In CDB, secondary indices should share a lock file - * ID with the primary; otherwise we're susceptible - * to deadlocks. We also use __db_cursor_int rather - * than __db_cursor to create secondary update cursors - * in c_put and c_del; these won't acquire a new lock. - * - * !!! - * Since this is in the one-time cursor allocation - * code, we need to be sure to destroy, not just - * close, all cursors in the secondary when we - * associate. - */ - if (CDB_LOCKING(dbenv) && - F_ISSET(dbp, DB_AM_SECONDARY)) - memcpy(dbc->lock.fileid, - dbp->s_primary->fileid, DB_FILE_ID_LEN); - else - memcpy(dbc->lock.fileid, - dbp->fileid, DB_FILE_ID_LEN); - - if (CDB_LOCKING(dbenv)) { - if (F_ISSET(dbenv, DB_ENV_CDB_ALLDB)) { - /* - * If we are doing a single lock per - * environment, set up the global - * lock object just like we do to - * single thread creates. - */ - DB_ASSERT(sizeof(db_pgno_t) == - sizeof(u_int32_t)); - dbc->lock_dbt.size = sizeof(u_int32_t); - dbc->lock_dbt.data = &dbc->lock.pgno; - dbc->lock.pgno = 0; - } else { - dbc->lock_dbt.size = DB_FILE_ID_LEN; - dbc->lock_dbt.data = dbc->lock.fileid; - } - } else { - dbc->lock.type = DB_PAGE_LOCK; - dbc->lock_dbt.size = sizeof(dbc->lock); - dbc->lock_dbt.data = &dbc->lock; - } - } - /* Init the DBC internal structure. */ - switch (dbtype) { - case DB_BTREE: - case DB_RECNO: - if ((ret = __bam_c_init(dbc, dbtype)) != 0) - goto err; - break; - case DB_HASH: - if ((ret = __ham_c_init(dbc)) != 0) - goto err; - break; - case DB_QUEUE: - if ((ret = __qam_c_init(dbc)) != 0) - goto err; - break; - case DB_UNKNOWN: - default: - ret = __db_unknown_type(dbenv, "DB->cursor", dbtype); - goto err; - } - - cp = dbc->internal; - } - - /* Refresh the DBC structure. */ - dbc->dbtype = dbtype; - RESET_RET_MEM(dbc); - - if ((dbc->txn = txn) != NULL) - dbc->locker = txn->txnid; - else if (LOCKING_ON(dbenv)) { - /* - * There are certain cases in which we want to create a - * new cursor with a particular locker ID that is known - * to be the same as (and thus not conflict with) an - * open cursor. - * - * The most obvious case is cursor duplication; when we - * call DBC->c_dup or __db_c_idup, we want to use the original - * cursor's locker ID. - * - * Another case is when updating secondary indices. Standard - * CDB locking would mean that we might block ourself: we need - * to open an update cursor in the secondary while an update - * cursor in the primary is open, and when the secondary and - * primary are subdatabases or we're using env-wide locking, - * this is disastrous. - * - * In these cases, our caller will pass a nonzero locker - * ID into this function. Use this locker ID instead of - * the default as the locker ID for our new cursor. - */ - if (lockerid != DB_LOCK_INVALIDID) - dbc->locker = lockerid; - else { - /* - * If we are threaded then we need to set the - * proper thread id into the locker. - */ - if (DB_IS_THREADED(dbp)) { - dbenv->thread_id(dbenv, &pid, &tid); - __lock_set_thread_id( - (DB_LOCKER *)dbc->lref, pid, tid); - } - dbc->locker = ((DB_LOCKER *)dbc->lref)->id; - } - } - - /* - * These fields change when we are used as a secondary index, so - * if the DB is a secondary, make sure they're set properly just - * in case we opened some cursors before we were associated. - * - * __db_c_get is used by all access methods, so this should be safe. - */ - if (F_ISSET(dbp, DB_AM_SECONDARY)) - dbc->c_get = __db_c_secondary_get_pp; - - if (is_opd) - F_SET(dbc, DBC_OPD); - if (F_ISSET(dbp, DB_AM_RECOVER)) - F_SET(dbc, DBC_RECOVER); - if (F_ISSET(dbp, DB_AM_COMPENSATE)) - F_SET(dbc, DBC_COMPENSATE); - - /* Refresh the DBC internal structure. */ - cp = dbc->internal; - cp->opd = NULL; - - cp->indx = 0; - cp->page = NULL; - cp->pgno = PGNO_INVALID; - cp->root = root; - - switch (dbtype) { - case DB_BTREE: - case DB_RECNO: - if ((ret = __bam_c_refresh(dbc)) != 0) - goto err; - break; - case DB_HASH: - case DB_QUEUE: - break; - case DB_UNKNOWN: - default: - ret = __db_unknown_type(dbenv, "DB->cursor", dbp->type); - goto err; - } - - /* - * The transaction keeps track of how many cursors were opened within - * it to catch application errors where the cursor isn't closed when - * the transaction is resolved. - */ - if (txn != NULL) - ++txn->cursors; - - MUTEX_LOCK(dbenv, dbp->mutex); - TAILQ_INSERT_TAIL(&dbp->active_queue, dbc, links); - F_SET(dbc, DBC_ACTIVE); - MUTEX_UNLOCK(dbenv, dbp->mutex); - - *dbcp = dbc; - return (0); - -err: if (allocated) - __os_free(dbenv, dbc); - return (ret); -} - -/* - * __db_put -- - * Store a key/data pair. - * - * PUBLIC: int __db_put __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); - */ -int -__db_put(dbp, txn, key, data, flags) - DB *dbp; - DB_TXN *txn; - DBT *key, *data; - u_int32_t flags; -{ - DBC *dbc; - DBT tdata; - DB_ENV *dbenv; - int ret, t_ret; - - dbenv = dbp->dbenv; - - if ((ret = __db_cursor(dbp, txn, &dbc, DB_WRITELOCK)) != 0) - return (ret); - - DEBUG_LWRITE(dbc, txn, "DB->put", key, data, flags); - - SET_RET_MEM(dbc, dbp); - - /* - * See the comment in __db_get(). - * - * Note that the c_get in the DB_NOOVERWRITE case is safe to - * do with this flag set; if it errors in any way other than - * DB_NOTFOUND, we're going to close the cursor without doing - * anything else, and if it returns DB_NOTFOUND then it's safe - * to do a c_put(DB_KEYLAST) even if an access method moved the - * cursor, since that's not position-dependent. - */ - F_SET(dbc, DBC_TRANSIENT); - - switch (flags) { - case DB_APPEND: - /* - * If there is an append callback, the value stored in - * data->data may be replaced and then freed. To avoid - * passing a freed pointer back to the user, just operate - * on a copy of the data DBT. - */ - tdata = *data; - - /* - * Append isn't a normal put operation; call the appropriate - * access method's append function. - */ - switch (dbp->type) { - case DB_QUEUE: - if ((ret = __qam_append(dbc, key, &tdata)) != 0) - goto err; - break; - case DB_RECNO: - if ((ret = __ram_append(dbc, key, &tdata)) != 0) - goto err; - break; - case DB_BTREE: - case DB_HASH: - case DB_UNKNOWN: - default: - /* The interface should prevent this. */ - DB_ASSERT( - dbp->type == DB_QUEUE || dbp->type == DB_RECNO); - - ret = __db_ferr(dbenv, "DB->put", 0); - goto err; - } - - /* - * Secondary indices: since we've returned zero from - * an append function, we've just put a record, and done - * so outside __db_c_put. We know we're not a secondary-- - * the interface prevents puts on them--but we may be a - * primary. If so, update our secondary indices - * appropriately. - */ - DB_ASSERT(!F_ISSET(dbp, DB_AM_SECONDARY)); - - if (LIST_FIRST(&dbp->s_secondaries) != NULL) - ret = __db_append_primary(dbc, key, &tdata); - - /* - * The append callback, if one exists, may have allocated - * a new tdata.data buffer. If so, free it. - */ - FREE_IF_NEEDED(dbp, &tdata); - - /* No need for a cursor put; we're done. */ - goto done; - case DB_NOOVERWRITE: - flags = 0; - /* - * Set DB_DBT_USERMEM, this might be a threaded application and - * the flags checking will catch us. We don't want the actual - * data, so request a partial of length 0. - */ - memset(&tdata, 0, sizeof(tdata)); - F_SET(&tdata, DB_DBT_USERMEM | DB_DBT_PARTIAL); - - /* - * If we're doing page-level locking, set the read-modify-write - * flag, we're going to overwrite immediately. - */ - if ((ret = __db_c_get(dbc, key, &tdata, - DB_SET | (STD_LOCKING(dbc) ? DB_RMW : 0))) == 0) - ret = DB_KEYEXIST; - else if (ret == DB_NOTFOUND || ret == DB_KEYEMPTY) - ret = 0; - break; - default: - /* Fall through to normal cursor put. */ - break; - } - - if (ret == 0) - ret = __db_c_put(dbc, - key, data, flags == 0 ? DB_KEYLAST : flags); - -err: -done: /* Close the cursor. */ - if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __db_del -- - * Delete the items referenced by a key. - * - * PUBLIC: int __db_del __P((DB *, DB_TXN *, DBT *, u_int32_t)); - */ -int -__db_del(dbp, txn, key, flags) - DB *dbp; - DB_TXN *txn; - DBT *key; - u_int32_t flags; -{ - DBC *dbc; - DBT data, lkey; - u_int32_t f_init, f_next; - int ret, t_ret; - - /* Allocate a cursor. */ - if ((ret = __db_cursor(dbp, txn, &dbc, DB_WRITELOCK)) != 0) - goto err; - - DEBUG_LWRITE(dbc, txn, "DB->del", key, NULL, flags); - COMPQUIET(flags, 0); - - /* - * Walk a cursor through the key/data pairs, deleting as we go. Set - * the DB_DBT_USERMEM flag, as this might be a threaded application - * and the flags checking will catch us. We don't actually want the - * keys or data, so request a partial of length 0. - */ - memset(&lkey, 0, sizeof(lkey)); - F_SET(&lkey, DB_DBT_USERMEM | DB_DBT_PARTIAL); - memset(&data, 0, sizeof(data)); - F_SET(&data, DB_DBT_USERMEM | DB_DBT_PARTIAL); - - /* - * If locking (and we haven't already acquired CDB locks), set the - * read-modify-write flag. - */ - f_init = DB_SET; - f_next = DB_NEXT_DUP; - if (STD_LOCKING(dbc)) { - f_init |= DB_RMW; - f_next |= DB_RMW; - } - - /* - * Optimize the simple cases. For all AMs if we don't have secondaries - * and are not a secondary and there are no dups then we can avoid a - * bunch of overhead. For queue we don't need to fetch the record since - * we delete by direct calculation from the record number. - * - * Hash permits an optimization in DB->del: since on-page duplicates are - * stored in a single HKEYDATA structure, it's possible to delete an - * entire set of them at once, and as the HKEYDATA has to be rebuilt - * and re-put each time it changes, this is much faster than deleting - * the duplicates one by one. Thus, if not pointing at an off-page - * duplicate set, and we're not using secondary indices (in which case - * we'd have to examine the items one by one anyway), let hash do this - * "quick delete". - * - * !!! - * Note that this is the only application-executed delete call in - * Berkeley DB that does not go through the __db_c_del function. - * If anything other than the delete itself (like a secondary index - * update) has to happen there in a particular situation, the - * conditions here should be modified not to use these optimizations. - * The ordinary AM-independent alternative will work just fine; - * it'll just be slower. - */ - if (!F_ISSET(dbp, DB_AM_SECONDARY) && - LIST_FIRST(&dbp->s_secondaries) == NULL) { - -#ifdef HAVE_QUEUE - if (dbp->type == DB_QUEUE) { - ret = __qam_delete(dbc, key); - goto done; - } -#endif - - /* Fetch the first record. */ - if ((ret = __db_c_get(dbc, key, &data, f_init)) != 0) - goto err; - -#ifdef HAVE_HASH - if (dbp->type == DB_HASH && dbc->internal->opd == NULL) { - ret = __ham_quick_delete(dbc); - goto done; - } -#endif - - if ((dbp->type == DB_BTREE || dbp->type == DB_RECNO) && - !F_ISSET(dbp, DB_AM_DUP)) { - ret = dbc->c_am_del(dbc); - goto done; - } - } else if ((ret = __db_c_get(dbc, key, &data, f_init)) != 0) - goto err; - - /* Walk through the set of key/data pairs, deleting as we go. */ - for (;;) { - if ((ret = __db_c_del(dbc, 0)) != 0) - break; - if ((ret = __db_c_get(dbc, &lkey, &data, f_next)) != 0) { - if (ret == DB_NOTFOUND) - ret = 0; - break; - } - } - -done: -err: /* Discard the cursor. */ - if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __db_sync -- - * Flush the database cache. - * - * PUBLIC: int __db_sync __P((DB *)); - */ -int -__db_sync(dbp) - DB *dbp; -{ - int ret, t_ret; - - ret = 0; - - /* If the database was read-only, we're done. */ - if (F_ISSET(dbp, DB_AM_RDONLY)) - return (0); - - /* If it's a Recno tree, write the backing source text file. */ - if (dbp->type == DB_RECNO) - ret = __ram_writeback(dbp); - - /* If the database was never backed by a database file, we're done. */ - if (F_ISSET(dbp, DB_AM_INMEM)) - return (ret); - - if (dbp->type == DB_QUEUE) - ret = __qam_sync(dbp); - else - /* Flush any dirty pages from the cache to the backing file. */ - if ((t_ret = __memp_fsync(dbp->mpf)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __db_associate -- - * Associate another database as a secondary index to this one. - * - * PUBLIC: int __db_associate __P((DB *, DB_TXN *, DB *, - * PUBLIC: int (*)(DB *, const DBT *, const DBT *, DBT *), u_int32_t)); - */ -int -__db_associate(dbp, txn, sdbp, callback, flags) - DB *dbp, *sdbp; - DB_TXN *txn; - int (*callback) __P((DB *, const DBT *, const DBT *, DBT *)); - u_int32_t flags; -{ - DB_ENV *dbenv; - DBC *pdbc, *sdbc; - DBT skey, key, data; - int build, ret, t_ret; - - dbenv = dbp->dbenv; - pdbc = sdbc = NULL; - ret = 0; - - /* - * Check to see if the secondary is empty -- and thus if we should - * build it -- before we link it in and risk making it show up in other - * threads. Do this first so that the databases remain unassociated on - * error. - */ - build = 0; - if (LF_ISSET(DB_CREATE)) { - if ((ret = __db_cursor(sdbp, txn, &sdbc, 0)) != 0) - goto err; - - /* - * We don't care about key or data; we're just doing - * an existence check. - */ - memset(&key, 0, sizeof(DBT)); - memset(&data, 0, sizeof(DBT)); - F_SET(&key, DB_DBT_PARTIAL | DB_DBT_USERMEM); - F_SET(&data, DB_DBT_PARTIAL | DB_DBT_USERMEM); - if ((ret = __db_c_get(sdbc, &key, &data, - (STD_LOCKING(sdbc) ? DB_RMW : 0) | - DB_FIRST)) == DB_NOTFOUND) { - build = 1; - ret = 0; - } - - if ((t_ret = __db_c_close(sdbc)) != 0 && ret == 0) - ret = t_ret; - - /* Reset for later error check. */ - sdbc = NULL; - - if (ret != 0) - goto err; - } - - /* - * Set up the database handle as a secondary. - */ - sdbp->s_callback = callback; - sdbp->s_primary = dbp; - - sdbp->stored_get = sdbp->get; - sdbp->get = __db_secondary_get; - - sdbp->stored_close = sdbp->close; - sdbp->close = __db_secondary_close_pp; - - F_SET(sdbp, DB_AM_SECONDARY); - - if (LF_ISSET(DB_IMMUTABLE_KEY)) - FLD_SET(sdbp->s_assoc_flags, DB_ASSOC_IMMUTABLE_KEY); - - /* - * Add the secondary to the list on the primary. Do it here - * so that we see any updates that occur while we're walking - * the primary. - */ - MUTEX_LOCK(dbenv, dbp->mutex); - - /* See __db_s_next for an explanation of secondary refcounting. */ - DB_ASSERT(sdbp->s_refcnt == 0); - sdbp->s_refcnt = 1; - LIST_INSERT_HEAD(&dbp->s_secondaries, sdbp, s_links); - MUTEX_UNLOCK(dbenv, dbp->mutex); - - if (build) { - /* - * We loop through the primary, putting each item we - * find into the new secondary. - * - * If we're using CDB, opening these two cursors puts us - * in a bit of a locking tangle: CDB locks are done on the - * primary, so that we stay deadlock-free, but that means - * that updating the secondary while we have a read cursor - * open on the primary will self-block. To get around this, - * we force the primary cursor to use the same locker ID - * as the secondary, so they won't conflict. This should - * be harmless even if we're not using CDB. - */ - if ((ret = __db_cursor(sdbp, txn, &sdbc, - CDB_LOCKING(sdbp->dbenv) ? DB_WRITECURSOR : 0)) != 0) - goto err; - if ((ret = __db_cursor_int(dbp, - txn, dbp->type, PGNO_INVALID, 0, sdbc->locker, &pdbc)) != 0) - goto err; - - /* Lock out other threads, now that we have a locker ID. */ - dbp->associate_lid = sdbc->locker; - - memset(&key, 0, sizeof(DBT)); - memset(&data, 0, sizeof(DBT)); - while ((ret = __db_c_get(pdbc, &key, &data, DB_NEXT)) == 0) { - memset(&skey, 0, sizeof(DBT)); - if ((ret = callback(sdbp, &key, &data, &skey)) != 0) { - if (ret == DB_DONOTINDEX) - continue; - goto err; - } - SWAP_IF_NEEDED(dbp, sdbp, &key); - if ((ret = __db_c_put(sdbc, - &skey, &key, DB_UPDATE_SECONDARY)) != 0) { - FREE_IF_NEEDED(sdbp, &skey); - goto err; - } - SWAP_IF_NEEDED(dbp, sdbp, &key); - - FREE_IF_NEEDED(sdbp, &skey); - } - if (ret == DB_NOTFOUND) - ret = 0; - } - -err: if (sdbc != NULL && (t_ret = __db_c_close(sdbc)) != 0 && ret == 0) - ret = t_ret; - - if (pdbc != NULL && (t_ret = __db_c_close(pdbc)) != 0 && ret == 0) - ret = t_ret; - - dbp->associate_lid = DB_LOCK_INVALIDID; - - return (ret); -} - -/* - * __db_secondary_get -- - * This wrapper function for DB->pget() is the DB->get() function - * on a database which has been made into a secondary index. - */ -static int -__db_secondary_get(sdbp, txn, skey, data, flags) - DB *sdbp; - DB_TXN *txn; - DBT *skey, *data; - u_int32_t flags; -{ - - DB_ASSERT(F_ISSET(sdbp, DB_AM_SECONDARY)); - return (__db_pget_pp(sdbp, txn, skey, NULL, data, flags)); -} - -/* - * __db_secondary_close -- - * Wrapper function for DB->close() which we use on secondaries to - * manage refcounting and make sure we don't close them underneath - * a primary that is updating. - * - * PUBLIC: int __db_secondary_close __P((DB *, u_int32_t)); - */ -int -__db_secondary_close(sdbp, flags) - DB *sdbp; - u_int32_t flags; -{ - DB *primary; - int doclose; - - doclose = 0; - primary = sdbp->s_primary; - - MUTEX_LOCK(primary->dbenv, primary->mutex); - /* - * Check the refcount--if it was at 1 when we were called, no - * thread is currently updating this secondary through the primary, - * so it's safe to close it for real. - * - * If it's not safe to do the close now, we do nothing; the - * database will actually be closed when the refcount is decremented, - * which can happen in either __db_s_next or __db_s_done. - */ - DB_ASSERT(sdbp->s_refcnt != 0); - if (--sdbp->s_refcnt == 0) { - LIST_REMOVE(sdbp, s_links); - /* We don't want to call close while the mutex is held. */ - doclose = 1; - } - MUTEX_UNLOCK(primary->dbenv, primary->mutex); - - /* - * sdbp->close is this function; call the real one explicitly if - * need be. - */ - return (doclose ? __db_close(sdbp, NULL, flags) : 0); -} - -/* - * __db_append_primary -- - * Perform the secondary index updates necessary to put(DB_APPEND) - * a record to a primary database. - */ -static int -__db_append_primary(dbc, key, data) - DBC *dbc; - DBT *key, *data; -{ - DB *dbp, *sdbp; - DBC *sdbc, *pdbc; - DBT oldpkey, pkey, pdata, skey; - int cmp, ret, t_ret; - - dbp = dbc->dbp; - sdbp = NULL; - ret = 0; - - /* - * Worrying about partial appends seems a little like worrying - * about Linear A character encodings. But we support those - * too if your application understands them. - */ - pdbc = NULL; - if (F_ISSET(data, DB_DBT_PARTIAL) || F_ISSET(key, DB_DBT_PARTIAL)) { - /* - * The dbc we were passed is all set to pass things - * back to the user; we can't safely do a call on it. - * Dup the cursor, grab the real data item (we don't - * care what the key is--we've been passed it directly), - * and use that instead of the data DBT we were passed. - * - * Note that we can get away with this simple get because - * an appended item is by definition new, and the - * correctly-constructed full data item from this partial - * put is on the page waiting for us. - */ - if ((ret = __db_c_idup(dbc, &pdbc, DB_POSITION)) != 0) - return (ret); - memset(&pkey, 0, sizeof(DBT)); - memset(&pdata, 0, sizeof(DBT)); - - if ((ret = __db_c_get(pdbc, &pkey, &pdata, DB_CURRENT)) != 0) - goto err; - - key = &pkey; - data = &pdata; - } - - /* - * Loop through the secondary indices, putting a new item in - * each that points to the appended item. - * - * This is much like the loop in "step 3" in __db_c_put, so - * I'm not commenting heavily here; it was unclean to excerpt - * just that section into a common function, but the basic - * overview is the same here. - */ - if ((ret = __db_s_first(dbp, &sdbp)) != 0) - goto err; - for (; sdbp != NULL && ret == 0; ret = __db_s_next(&sdbp)) { - memset(&skey, 0, sizeof(DBT)); - if ((ret = sdbp->s_callback(sdbp, key, data, &skey)) != 0) { - if (ret == DB_DONOTINDEX) - continue; - goto err; - } - - if ((ret = __db_cursor_int(sdbp, dbc->txn, sdbp->type, - PGNO_INVALID, 0, dbc->locker, &sdbc)) != 0) { - FREE_IF_NEEDED(sdbp, &skey); - goto err; - } - if (CDB_LOCKING(sdbp->dbenv)) { - DB_ASSERT(sdbc->mylock.off == LOCK_INVALID); - F_SET(sdbc, DBC_WRITER); - } - - /* - * Since we know we have a new primary key, it can't be a - * duplicate duplicate in the secondary. It can be a - * duplicate in a secondary that doesn't support duplicates, - * however, so we need to be careful to avoid an overwrite - * (which would corrupt our index). - */ - if (!F_ISSET(sdbp, DB_AM_DUP)) { - memset(&oldpkey, 0, sizeof(DBT)); - F_SET(&oldpkey, DB_DBT_MALLOC); - ret = __db_c_get(sdbc, &skey, &oldpkey, - DB_SET | (STD_LOCKING(dbc) ? DB_RMW : 0)); - if (ret == 0) { - cmp = __bam_defcmp(sdbp, &oldpkey, key); - /* - * XXX - * This needs to use the right free function - * as soon as this is possible. - */ - __os_ufree(sdbp->dbenv, - oldpkey.data); - if (cmp != 0) { - __db_err(sdbp->dbenv, "%s%s", - "Append results in a non-unique secondary key in", - " an index not configured to support duplicates"); - ret = EINVAL; - goto err1; - } - } else if (ret != DB_NOTFOUND && ret != DB_KEYEMPTY) - goto err1; - } - - ret = __db_c_put(sdbc, &skey, key, DB_UPDATE_SECONDARY); - -err1: FREE_IF_NEEDED(sdbp, &skey); - - if ((t_ret = __db_c_close(sdbc)) != 0 && ret == 0) - ret = t_ret; - if (ret != 0) - goto err; - } - -err: if (pdbc != NULL && (t_ret = __db_c_close(pdbc)) != 0 && ret == 0) - ret = t_ret; - if (sdbp != NULL && (t_ret = __db_s_done(sdbp)) != 0 && ret == 0) - ret = t_ret; - return (ret); -} diff --git a/storage/bdb/db/db_cam.c b/storage/bdb/db/db_cam.c deleted file mode 100644 index f7b93ad36b1..00000000000 --- a/storage/bdb/db/db_cam.c +++ /dev/null @@ -1,2367 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2000-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_cam.c,v 12.21 2005/10/07 20:21:22 ubell Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/btree.h" -#include "dbinc/hash.h" -#include "dbinc/lock.h" -#include "dbinc/mp.h" -#include "dbinc/qam.h" - -static int __db_buildpartial __P((DB *, DBT *, DBT *, DBT *)); -static int __db_c_cleanup __P((DBC *, DBC *, int)); -static int __db_c_del_secondary __P((DBC *)); -static int __db_c_pget_recno __P((DBC *, DBT *, DBT *, u_int32_t)); -static int __db_wrlock_err __P((DB_ENV *)); - -#define CDB_LOCKING_INIT(dbp, dbc) \ - /* \ - * If we are running CDB, this had better be either a write \ - * cursor or an immediate writer. If it's a regular writer, \ - * that means we have an IWRITE lock and we need to upgrade \ - * it to a write lock. \ - */ \ - if (CDB_LOCKING((dbp)->dbenv)) { \ - if (!F_ISSET(dbc, DBC_WRITECURSOR | DBC_WRITER)) \ - return (__db_wrlock_err(dbp->dbenv)); \ - \ - if (F_ISSET(dbc, DBC_WRITECURSOR) && \ - (ret = __lock_get((dbp)->dbenv, \ - (dbc)->locker, DB_LOCK_UPGRADE, &(dbc)->lock_dbt, \ - DB_LOCK_WRITE, &(dbc)->mylock)) != 0) \ - return (ret); \ - } -#define CDB_LOCKING_DONE(dbp, dbc) \ - /* Release the upgraded lock. */ \ - if (F_ISSET(dbc, DBC_WRITECURSOR)) \ - (void)__lock_downgrade( \ - (dbp)->dbenv, &(dbc)->mylock, DB_LOCK_IWRITE, 0); - -/* - * __db_c_close -- - * DBC->c_close. - * - * PUBLIC: int __db_c_close __P((DBC *)); - */ -int -__db_c_close(dbc) - DBC *dbc; -{ - DB *dbp; - DBC *opd; - DBC_INTERNAL *cp; - DB_ENV *dbenv; - int ret, t_ret; - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - cp = dbc->internal; - opd = cp->opd; - ret = 0; - - /* - * Remove the cursor(s) from the active queue. We may be closing two - * cursors at once here, a top-level one and a lower-level, off-page - * duplicate one. The access-method specific cursor close routine must - * close both of them in a single call. - * - * !!! - * Cursors must be removed from the active queue before calling the - * access specific cursor close routine, btree depends on having that - * order of operations. - */ - MUTEX_LOCK(dbenv, dbp->mutex); - - if (opd != NULL) { - DB_ASSERT(F_ISSET(opd, DBC_ACTIVE)); - F_CLR(opd, DBC_ACTIVE); - TAILQ_REMOVE(&dbp->active_queue, opd, links); - } - DB_ASSERT(F_ISSET(dbc, DBC_ACTIVE)); - F_CLR(dbc, DBC_ACTIVE); - TAILQ_REMOVE(&dbp->active_queue, dbc, links); - - MUTEX_UNLOCK(dbenv, dbp->mutex); - - /* Call the access specific cursor close routine. */ - if ((t_ret = - dbc->c_am_close(dbc, PGNO_INVALID, NULL)) != 0 && ret == 0) - ret = t_ret; - - /* - * Release the lock after calling the access method specific close - * routine, a Btree cursor may have had pending deletes. - */ - if (CDB_LOCKING(dbenv)) { - /* - * Also, be sure not to free anything if mylock.off is - * INVALID; in some cases, such as idup'ed read cursors - * and secondary update cursors, a cursor in a CDB - * environment may not have a lock at all. - */ - if ((t_ret = __LPUT(dbc, dbc->mylock)) != 0 && ret == 0) - ret = t_ret; - - /* For safety's sake, since this is going on the free queue. */ - memset(&dbc->mylock, 0, sizeof(dbc->mylock)); - if (opd != NULL) - memset(&opd->mylock, 0, sizeof(opd->mylock)); - } - - if (dbc->txn != NULL) - dbc->txn->cursors--; - - /* Move the cursor(s) to the free queue. */ - MUTEX_LOCK(dbenv, dbp->mutex); - if (opd != NULL) { - if (dbc->txn != NULL) - dbc->txn->cursors--; - TAILQ_INSERT_TAIL(&dbp->free_queue, opd, links); - opd = NULL; - } - TAILQ_INSERT_TAIL(&dbp->free_queue, dbc, links); - MUTEX_UNLOCK(dbenv, dbp->mutex); - - return (ret); -} - -/* - * __db_c_destroy -- - * Destroy the cursor, called after DBC->c_close. - * - * PUBLIC: int __db_c_destroy __P((DBC *)); - */ -int -__db_c_destroy(dbc) - DBC *dbc; -{ - DB *dbp; - DB_ENV *dbenv; - int ret, t_ret; - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - - /* Remove the cursor from the free queue. */ - MUTEX_LOCK(dbenv, dbp->mutex); - TAILQ_REMOVE(&dbp->free_queue, dbc, links); - MUTEX_UNLOCK(dbenv, dbp->mutex); - - /* Free up allocated memory. */ - if (dbc->my_rskey.data != NULL) - __os_free(dbenv, dbc->my_rskey.data); - if (dbc->my_rkey.data != NULL) - __os_free(dbenv, dbc->my_rkey.data); - if (dbc->my_rdata.data != NULL) - __os_free(dbenv, dbc->my_rdata.data); - - /* Call the access specific cursor destroy routine. */ - ret = dbc->c_am_destroy == NULL ? 0 : dbc->c_am_destroy(dbc); - - /* - * Release the lock id for this cursor. - */ - if (LOCKING_ON(dbenv) && - F_ISSET(dbc, DBC_OWN_LID) && - (t_ret = __lock_id_free(dbenv, - ((DB_LOCKER *)dbc->lref)->id)) != 0 && ret == 0) - ret = t_ret; - - __os_free(dbenv, dbc); - - return (ret); -} - -/* - * __db_c_count -- - * Return a count of duplicate data items. - * - * PUBLIC: int __db_c_count __P((DBC *, db_recno_t *)); - */ -int -__db_c_count(dbc, recnop) - DBC *dbc; - db_recno_t *recnop; -{ - DB_ENV *dbenv; - int ret; - - dbenv = dbc->dbp->dbenv; - - /* - * Cursor Cleanup Note: - * All of the cursors passed to the underlying access methods by this - * routine are not duplicated and will not be cleaned up on return. - * So, pages/locks that the cursor references must be resolved by the - * underlying functions. - */ - switch (dbc->dbtype) { - case DB_QUEUE: - case DB_RECNO: - *recnop = 1; - break; - case DB_HASH: - if (dbc->internal->opd == NULL) { - if ((ret = __ham_c_count(dbc, recnop)) != 0) - return (ret); - break; - } - /* FALLTHROUGH */ - case DB_BTREE: - if ((ret = __bam_c_count(dbc, recnop)) != 0) - return (ret); - break; - case DB_UNKNOWN: - default: - return (__db_unknown_type(dbenv, "__db_c_count", dbc->dbtype)); - } - return (0); -} - -/* - * __db_c_del -- - * DBC->c_del. - * - * PUBLIC: int __db_c_del __P((DBC *, u_int32_t)); - */ -int -__db_c_del(dbc, flags) - DBC *dbc; - u_int32_t flags; -{ - DB *dbp; - DBC *opd; - int ret, t_ret; - - dbp = dbc->dbp; - - /* - * Cursor Cleanup Note: - * All of the cursors passed to the underlying access methods by this - * routine are not duplicated and will not be cleaned up on return. - * So, pages/locks that the cursor references must be resolved by the - * underlying functions. - */ - - CDB_LOCKING_INIT(dbp, dbc); - - /* - * If we're a secondary index, and DB_UPDATE_SECONDARY isn't set - * (which it only is if we're being called from a primary update), - * then we need to call through to the primary and delete the item. - * - * Note that this will delete the current item; we don't need to - * delete it ourselves as well, so we can just goto done. - */ - if (flags != DB_UPDATE_SECONDARY && F_ISSET(dbp, DB_AM_SECONDARY)) { - ret = __db_c_del_secondary(dbc); - goto done; - } - - /* - * If we are a primary and have secondary indices, go through - * and delete any secondary keys that point at the current record. - */ - if (LIST_FIRST(&dbp->s_secondaries) != NULL && - (ret = __db_c_del_primary(dbc)) != 0) - goto done; - - /* - * Off-page duplicate trees are locked in the primary tree, that is, - * we acquire a write lock in the primary tree and no locks in the - * off-page dup tree. If the del operation is done in an off-page - * duplicate tree, call the primary cursor's upgrade routine first. - */ - opd = dbc->internal->opd; - if (opd == NULL) - ret = dbc->c_am_del(dbc); - else - if ((ret = dbc->c_am_writelock(dbc)) == 0) - ret = opd->c_am_del(opd); - - /* - * If this was an update that is supporting dirty reads - * then we may have just swapped our read for a write lock - * which is held by the surviving cursor. We need - * to explicitly downgrade this lock. The closed cursor - * may only have had a read lock. - */ - if (F_ISSET(dbc->dbp, DB_AM_READ_UNCOMMITTED) && - dbc->internal->lock_mode == DB_LOCK_WRITE) { - if ((t_ret = - __TLPUT(dbc, dbc->internal->lock)) != 0 && ret == 0) - ret = t_ret; - if (t_ret == 0) - dbc->internal->lock_mode = DB_LOCK_WWRITE; - } - -done: CDB_LOCKING_DONE(dbp, dbc); - - return (ret); -} - -/* - * __db_c_dup -- - * Duplicate a cursor - * - * PUBLIC: int __db_c_dup __P((DBC *, DBC **, u_int32_t)); - */ -int -__db_c_dup(dbc_orig, dbcp, flags) - DBC *dbc_orig; - DBC **dbcp; - u_int32_t flags; -{ - DBC *dbc_n, *dbc_nopd; - int ret; - - dbc_n = dbc_nopd = NULL; - - /* Allocate a new cursor and initialize it. */ - if ((ret = __db_c_idup(dbc_orig, &dbc_n, flags)) != 0) - goto err; - *dbcp = dbc_n; - - /* - * If the cursor references an off-page duplicate tree, allocate a - * new cursor for that tree and initialize it. - */ - if (dbc_orig->internal->opd != NULL) { - if ((ret = - __db_c_idup(dbc_orig->internal->opd, &dbc_nopd, flags)) != 0) - goto err; - dbc_n->internal->opd = dbc_nopd; - } - return (0); - -err: if (dbc_n != NULL) - (void)__db_c_close(dbc_n); - if (dbc_nopd != NULL) - (void)__db_c_close(dbc_nopd); - - return (ret); -} - -/* - * __db_c_idup -- - * Internal version of __db_c_dup. - * - * PUBLIC: int __db_c_idup __P((DBC *, DBC **, u_int32_t)); - */ -int -__db_c_idup(dbc_orig, dbcp, flags) - DBC *dbc_orig, **dbcp; - u_int32_t flags; -{ - DB *dbp; - DBC *dbc_n; - DBC_INTERNAL *int_n, *int_orig; - int ret; - - dbp = dbc_orig->dbp; - dbc_n = *dbcp; - - if ((ret = __db_cursor_int(dbp, dbc_orig->txn, dbc_orig->dbtype, - dbc_orig->internal->root, F_ISSET(dbc_orig, DBC_OPD), - dbc_orig->locker, &dbc_n)) != 0) - return (ret); - - /* Position the cursor if requested, acquiring the necessary locks. */ - if (flags == DB_POSITION) { - int_n = dbc_n->internal; - int_orig = dbc_orig->internal; - - dbc_n->flags |= dbc_orig->flags & ~DBC_OWN_LID; - - int_n->indx = int_orig->indx; - int_n->pgno = int_orig->pgno; - int_n->root = int_orig->root; - int_n->lock_mode = int_orig->lock_mode; - - switch (dbc_orig->dbtype) { - case DB_QUEUE: - if ((ret = __qam_c_dup(dbc_orig, dbc_n)) != 0) - goto err; - break; - case DB_BTREE: - case DB_RECNO: - if ((ret = __bam_c_dup(dbc_orig, dbc_n)) != 0) - goto err; - break; - case DB_HASH: - if ((ret = __ham_c_dup(dbc_orig, dbc_n)) != 0) - goto err; - break; - case DB_UNKNOWN: - default: - ret = __db_unknown_type(dbp->dbenv, - "__db_c_idup", dbc_orig->dbtype); - goto err; - } - } - - /* Copy the locking flags to the new cursor. */ - F_SET(dbc_n, F_ISSET(dbc_orig, - DBC_READ_COMMITTED | DBC_READ_UNCOMMITTED | DBC_WRITECURSOR)); - - /* - * If we're in CDB and this isn't an offpage dup cursor, then - * we need to get a lock for the duplicated cursor. - */ - if (CDB_LOCKING(dbp->dbenv) && !F_ISSET(dbc_n, DBC_OPD) && - (ret = __lock_get(dbp->dbenv, dbc_n->locker, 0, - &dbc_n->lock_dbt, F_ISSET(dbc_orig, DBC_WRITECURSOR) ? - DB_LOCK_IWRITE : DB_LOCK_READ, &dbc_n->mylock)) != 0) - goto err; - - *dbcp = dbc_n; - return (0); - -err: (void)__db_c_close(dbc_n); - return (ret); -} - -/* - * __db_c_newopd -- - * Create a new off-page duplicate cursor. - * - * PUBLIC: int __db_c_newopd __P((DBC *, db_pgno_t, DBC *, DBC **)); - */ -int -__db_c_newopd(dbc_parent, root, oldopd, dbcp) - DBC *dbc_parent; - db_pgno_t root; - DBC *oldopd; - DBC **dbcp; -{ - DB *dbp; - DBC *opd; - DBTYPE dbtype; - int ret; - - dbp = dbc_parent->dbp; - dbtype = (dbp->dup_compare == NULL) ? DB_RECNO : DB_BTREE; - - /* - * On failure, we want to default to returning the old off-page dup - * cursor, if any; our caller can't be left with a dangling pointer - * to a freed cursor. On error the only allowable behavior is to - * close the cursor (and the old OPD cursor it in turn points to), so - * this should be safe. - */ - *dbcp = oldopd; - - if ((ret = __db_cursor_int(dbp, - dbc_parent->txn, dbtype, root, 1, dbc_parent->locker, &opd)) != 0) - return (ret); - - *dbcp = opd; - - /* - * Check to see if we already have an off-page dup cursor that we've - * passed in. If we do, close it. It'd be nice to use it again - * if it's a cursor belonging to the right tree, but if we're doing - * a cursor-relative operation this might not be safe, so for now - * we'll take the easy way out and always close and reopen. - * - * Note that under no circumstances do we want to close the old - * cursor without returning a valid new one; we don't want to - * leave the main cursor in our caller with a non-NULL pointer - * to a freed off-page dup cursor. - */ - if (oldopd != NULL && (ret = __db_c_close(oldopd)) != 0) - return (ret); - - return (0); -} - -/* - * __db_c_get -- - * Get using a cursor. - * - * PUBLIC: int __db_c_get __P((DBC *, DBT *, DBT *, u_int32_t)); - */ -int -__db_c_get(dbc_arg, key, data, flags) - DBC *dbc_arg; - DBT *key, *data; - u_int32_t flags; -{ - DB *dbp; - DBC *dbc, *dbc_n, *opd; - DBC_INTERNAL *cp, *cp_n; - DB_MPOOLFILE *mpf; - db_pgno_t pgno; - u_int32_t multi, orig_ulen, tmp_flags, tmp_read_uncommitted, tmp_rmw; - u_int8_t type; - int key_small, ret, t_ret; - - COMPQUIET(orig_ulen, 0); - - key_small = 0; - - /* - * Cursor Cleanup Note: - * All of the cursors passed to the underlying access methods by this - * routine are duplicated cursors. On return, any referenced pages - * will be discarded, and, if the cursor is not intended to be used - * again, the close function will be called. So, pages/locks that - * the cursor references do not need to be resolved by the underlying - * functions. - */ - dbp = dbc_arg->dbp; - mpf = dbp->mpf; - dbc_n = NULL; - opd = NULL; - - /* Clear OR'd in additional bits so we can check for flag equality. */ - tmp_rmw = LF_ISSET(DB_RMW); - LF_CLR(DB_RMW); - - tmp_read_uncommitted = - LF_ISSET(DB_READ_UNCOMMITTED) && - !F_ISSET(dbc_arg, DBC_READ_UNCOMMITTED); - LF_CLR(DB_READ_UNCOMMITTED); - - multi = LF_ISSET(DB_MULTIPLE|DB_MULTIPLE_KEY); - LF_CLR(DB_MULTIPLE|DB_MULTIPLE_KEY); - - /* - * Return a cursor's record number. It has nothing to do with the - * cursor get code except that it was put into the interface. - */ - if (flags == DB_GET_RECNO) { - if (tmp_rmw) - F_SET(dbc_arg, DBC_RMW); - if (tmp_read_uncommitted) - F_SET(dbc_arg, DBC_READ_UNCOMMITTED); - ret = __bam_c_rget(dbc_arg, data); - if (tmp_rmw) - F_CLR(dbc_arg, DBC_RMW); - if (tmp_read_uncommitted) - F_CLR(dbc_arg, DBC_READ_UNCOMMITTED); - return (ret); - } - - if (flags == DB_CONSUME || flags == DB_CONSUME_WAIT) - CDB_LOCKING_INIT(dbp, dbc_arg); - - /* - * If we have an off-page duplicates cursor, and the operation applies - * to it, perform the operation. Duplicate the cursor and call the - * underlying function. - * - * Off-page duplicate trees are locked in the primary tree, that is, - * we acquire a write lock in the primary tree and no locks in the - * off-page dup tree. If the DB_RMW flag was specified and the get - * operation is done in an off-page duplicate tree, call the primary - * cursor's upgrade routine first. - */ - cp = dbc_arg->internal; - if (cp->opd != NULL && - (flags == DB_CURRENT || flags == DB_GET_BOTHC || - flags == DB_NEXT || flags == DB_NEXT_DUP || flags == DB_PREV)) { - if (tmp_rmw && (ret = dbc_arg->c_am_writelock(dbc_arg)) != 0) - return (ret); - if ((ret = __db_c_idup(cp->opd, &opd, DB_POSITION)) != 0) - return (ret); - - switch (ret = - opd->c_am_get(opd, key, data, flags, NULL)) { - case 0: - goto done; - case DB_NOTFOUND: - /* - * Translate DB_NOTFOUND failures for the DB_NEXT and - * DB_PREV operations into a subsequent operation on - * the parent cursor. - */ - if (flags == DB_NEXT || flags == DB_PREV) { - if ((ret = __db_c_close(opd)) != 0) - goto err; - opd = NULL; - break; - } - goto err; - default: - goto err; - } - } - - /* - * Perform an operation on the main cursor. Duplicate the cursor, - * upgrade the lock as required, and call the underlying function. - */ - switch (flags) { - case DB_CURRENT: - case DB_GET_BOTHC: - case DB_NEXT: - case DB_NEXT_DUP: - case DB_NEXT_NODUP: - case DB_PREV: - case DB_PREV_NODUP: - tmp_flags = DB_POSITION; - break; - default: - tmp_flags = 0; - break; - } - - if (tmp_read_uncommitted) - F_SET(dbc_arg, DBC_READ_UNCOMMITTED); - - /* - * If this cursor is going to be closed immediately, we don't - * need to take precautions to clean it up on error. - */ - if (F_ISSET(dbc_arg, DBC_TRANSIENT)) - dbc_n = dbc_arg; - else { - ret = __db_c_idup(dbc_arg, &dbc_n, tmp_flags); - if (tmp_read_uncommitted) - F_CLR(dbc_arg, DBC_READ_UNCOMMITTED); - - if (ret != 0) - goto err; - COPY_RET_MEM(dbc_arg, dbc_n); - } - - if (tmp_rmw) - F_SET(dbc_n, DBC_RMW); - - switch (multi) { - case DB_MULTIPLE: - F_SET(dbc_n, DBC_MULTIPLE); - break; - case DB_MULTIPLE_KEY: - F_SET(dbc_n, DBC_MULTIPLE_KEY); - break; - case DB_MULTIPLE | DB_MULTIPLE_KEY: - F_SET(dbc_n, DBC_MULTIPLE|DBC_MULTIPLE_KEY); - break; - case 0: - default: - break; - } - - pgno = PGNO_INVALID; - ret = dbc_n->c_am_get(dbc_n, key, data, flags, &pgno); - if (tmp_rmw) - F_CLR(dbc_n, DBC_RMW); - if (tmp_read_uncommitted) - F_CLR(dbc_arg, DBC_READ_UNCOMMITTED); - F_CLR(dbc_n, DBC_MULTIPLE|DBC_MULTIPLE_KEY); - if (ret != 0) - goto err; - - cp_n = dbc_n->internal; - - /* - * We may be referencing a new off-page duplicates tree. Acquire - * a new cursor and call the underlying function. - */ - if (pgno != PGNO_INVALID) { - if ((ret = __db_c_newopd(dbc_arg, - pgno, cp_n->opd, &cp_n->opd)) != 0) - goto err; - - switch (flags) { - case DB_FIRST: - case DB_NEXT: - case DB_NEXT_NODUP: - case DB_SET: - case DB_SET_RECNO: - case DB_SET_RANGE: - tmp_flags = DB_FIRST; - break; - case DB_LAST: - case DB_PREV: - case DB_PREV_NODUP: - tmp_flags = DB_LAST; - break; - case DB_GET_BOTH: - case DB_GET_BOTHC: - case DB_GET_BOTH_RANGE: - tmp_flags = flags; - break; - default: - ret = - __db_unknown_flag(dbp->dbenv, "__db_c_get", flags); - goto err; - } - if ((ret = cp_n->opd->c_am_get( - cp_n->opd, key, data, tmp_flags, NULL)) != 0) - goto err; - } - -done: /* - * Return a key/data item. The only exception is that we don't return - * a key if the user already gave us one, that is, if the DB_SET flag - * was set. The DB_SET flag is necessary. In a Btree, the user's key - * doesn't have to be the same as the key stored the tree, depending on - * the magic performed by the comparison function. As we may not have - * done any key-oriented operation here, the page reference may not be - * valid. Fill it in as necessary. We don't have to worry about any - * locks, the cursor must already be holding appropriate locks. - * - * XXX - * If not a Btree and DB_SET_RANGE is set, we shouldn't return a key - * either, should we? - */ - cp_n = dbc_n == NULL ? dbc_arg->internal : dbc_n->internal; - if (!F_ISSET(key, DB_DBT_ISSET)) { - if (cp_n->page == NULL && (ret = - __memp_fget(mpf, &cp_n->pgno, 0, &cp_n->page)) != 0) - goto err; - - if ((ret = __db_ret(dbp, cp_n->page, cp_n->indx, - key, &dbc_arg->rkey->data, &dbc_arg->rkey->ulen)) != 0) { - /* - * If the key DBT is too small, we still want to return - * the size of the data. Otherwise applications are - * forced to check each one with a separate call. We - * don't want to copy the data, so we set the ulen to - * zero before calling __db_ret. - */ - if (ret == DB_BUFFER_SMALL && - F_ISSET(data, DB_DBT_USERMEM)) { - key_small = 1; - orig_ulen = data->ulen; - data->ulen = 0; - } else - goto err; - } - } - if (multi != 0) { - /* - * Even if fetching from the OPD cursor we need a duplicate - * primary cursor if we are going after multiple keys. - */ - if (dbc_n == NULL) { - /* - * Non-"_KEY" DB_MULTIPLE doesn't move the main cursor, - * so it's safe to just use dbc_arg, unless dbc_arg - * has an open OPD cursor whose state might need to - * be preserved. - */ - if ((!(multi & DB_MULTIPLE_KEY) && - dbc_arg->internal->opd == NULL) || - F_ISSET(dbc_arg, DBC_TRANSIENT)) - dbc_n = dbc_arg; - else { - if ((ret = __db_c_idup(dbc_arg, - &dbc_n, DB_POSITION)) != 0) - goto err; - if ((ret = dbc_n->c_am_get(dbc_n, - key, data, DB_CURRENT, &pgno)) != 0) - goto err; - } - cp_n = dbc_n->internal; - } - - /* - * If opd is set then we dupped the opd that we came in with. - * When we return we may have a new opd if we went to another - * key. - */ - if (opd != NULL) { - DB_ASSERT(cp_n->opd == NULL); - cp_n->opd = opd; - opd = NULL; - } - - /* - * Bulk get doesn't use __db_retcopy, so data.size won't - * get set up unless there is an error. Assume success - * here. This is the only call to c_am_bulk, and it avoids - * setting it exactly the same everywhere. If we have an - * DB_BUFFER_SMALL error, it'll get overwritten with the - * needed value. - */ - data->size = data->ulen; - ret = dbc_n->c_am_bulk(dbc_n, data, flags | multi); - } else if (!F_ISSET(data, DB_DBT_ISSET)) { - dbc = opd != NULL ? opd : cp_n->opd != NULL ? cp_n->opd : dbc_n; - type = TYPE(dbc->internal->page); - ret = __db_ret(dbp, dbc->internal->page, dbc->internal->indx + - (type == P_LBTREE || type == P_HASH ? O_INDX : 0), - data, &dbc_arg->rdata->data, &dbc_arg->rdata->ulen); - } - -err: /* Don't pass DB_DBT_ISSET back to application level, error or no. */ - F_CLR(key, DB_DBT_ISSET); - F_CLR(data, DB_DBT_ISSET); - - /* Cleanup and cursor resolution. */ - if (opd != NULL) { - /* - * To support dirty reads we must reget the write lock - * if we have just stepped off a deleted record. - * Since the OPD cursor does not know anything - * about the referencing page or cursor we need - * to peek at the OPD cursor and get the lock here. - */ - if (F_ISSET(dbc_arg->dbp, DB_AM_READ_UNCOMMITTED) && - F_ISSET((BTREE_CURSOR *) - dbc_arg->internal->opd->internal, C_DELETED)) - if ((t_ret = - dbc_arg->c_am_writelock(dbc_arg)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = __db_c_cleanup( - dbc_arg->internal->opd, opd, ret)) != 0 && ret == 0) - ret = t_ret; - - } - - if ((t_ret = __db_c_cleanup(dbc_arg, dbc_n, ret)) != 0 && ret == 0) - ret = t_ret; - - if (key_small) { - data->ulen = orig_ulen; - if (ret == 0) - ret = DB_BUFFER_SMALL; - } - - if (flags == DB_CONSUME || flags == DB_CONSUME_WAIT) - CDB_LOCKING_DONE(dbp, dbc_arg); - return (ret); -} - -/* - * __db_c_put -- - * Put using a cursor. - * - * PUBLIC: int __db_c_put __P((DBC *, DBT *, DBT *, u_int32_t)); - */ -int -__db_c_put(dbc_arg, key, data, flags) - DBC *dbc_arg; - DBT *key, *data; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB *dbp, *sdbp; - DBC *dbc_n, *oldopd, *opd, *sdbc, *pdbc; - DBT olddata, oldpkey, oldskey, newdata, pkey, skey, temppkey, tempskey; - db_pgno_t pgno; - int cmp, have_oldrec, ispartial, nodel, re_pad, ret, rmw, t_ret; - u_int32_t re_len, size, tmp_flags; - - /* - * Cursor Cleanup Note: - * All of the cursors passed to the underlying access methods by this - * routine are duplicated cursors. On return, any referenced pages - * will be discarded, and, if the cursor is not intended to be used - * again, the close function will be called. So, pages/locks that - * the cursor references do not need to be resolved by the underlying - * functions. - */ - dbp = dbc_arg->dbp; - dbenv = dbp->dbenv; - sdbp = NULL; - pdbc = dbc_n = NULL; - memset(&newdata, 0, sizeof(DBT)); - ret = 0; - - /* - * We do multiple cursor operations in some cases and subsequently - * access the data DBT information. Set DB_DBT_MALLOC so we don't risk - * modification of the data between our uses of it. - */ - memset(&olddata, 0, sizeof(DBT)); - F_SET(&olddata, DB_DBT_MALLOC); - - /* - * Putting to secondary indices is forbidden; when we need - * to internally update one, we'll call this with a private - * synonym for DB_KEYLAST, DB_UPDATE_SECONDARY, which does - * the right thing but won't return an error from cputchk(). - */ - if (flags == DB_UPDATE_SECONDARY) - flags = DB_KEYLAST; - - CDB_LOCKING_INIT(dbp, dbc_arg); - - /* - * Check to see if we are a primary and have secondary indices. - * If we are not, we save ourselves a good bit of trouble and - * just skip to the "normal" put. - */ - if (LIST_FIRST(&dbp->s_secondaries) == NULL) - goto skip_s_update; - - /* - * We have at least one secondary which we may need to update. - * - * There is a rather vile locking issue here. Secondary gets - * will always involve acquiring a read lock in the secondary, - * then acquiring a read lock in the primary. Ideally, we - * would likewise perform puts by updating all the secondaries - * first, then doing the actual put in the primary, to avoid - * deadlock (since having multiple threads doing secondary - * gets and puts simultaneously is probably a common case). - * - * However, if this put is a put-overwrite--and we have no way to - * tell in advance whether it will be--we may need to delete - * an outdated secondary key. In order to find that old - * secondary key, we need to get the record we're overwriting, - * before we overwrite it. - * - * (XXX: It would be nice to avoid this extra get, and have the - * underlying put routines somehow pass us the old record - * since they need to traverse the tree anyway. I'm saving - * this optimization for later, as it's a lot of work, and it - * would be hard to fit into this locking paradigm anyway.) - * - * The simple thing to do would be to go get the old record before - * we do anything else. Unfortunately, though, doing so would - * violate our "secondary, then primary" lock acquisition - * ordering--even in the common case where no old primary record - * exists, we'll still acquire and keep a lock on the page where - * we're about to do the primary insert. - * - * To get around this, we do the following gyrations, which - * hopefully solve this problem in the common case: - * - * 1) If this is a c_put(DB_CURRENT), go ahead and get the - * old record. We already hold the lock on this page in - * the primary, so no harm done, and we'll need the primary - * key (which we weren't passed in this case) to do any - * secondary puts anyway. - * - * 2) If we're doing a partial put, we need to perform the - * get on the primary key right away, since we don't have - * the whole datum that the secondary key is based on. - * We may also need to pad out the record if the primary - * has a fixed record length. - * - * 3) Loop through the secondary indices, putting into each a - * new secondary key that corresponds to the new record. - * - * 4) If we haven't done so in (1) or (2), get the old primary - * key/data pair. If one does not exist--the common case--we're - * done with secondary indices, and can go straight on to the - * primary put. - * - * 5) If we do have an old primary key/data pair, however, we need - * to loop through all the secondaries a second time and delete - * the old secondary in each. - */ - memset(&pkey, 0, sizeof(DBT)); - have_oldrec = nodel = 0; - - /* - * Primary indices can't have duplicates, so only DB_CURRENT, - * DB_KEYFIRST, and DB_KEYLAST make any sense. Other flags - * should have been caught by the checking routine, but - * add a sprinkling of paranoia. - */ - DB_ASSERT(flags == DB_CURRENT || - flags == DB_KEYFIRST || flags == DB_KEYLAST); - - /* - * We'll want to use DB_RMW in a few places, but it's only legal - * when locking is on. - */ - rmw = STD_LOCKING(dbc_arg) ? DB_RMW : 0; - - if (flags == DB_CURRENT) { /* Step 1. */ - /* - * This is safe to do on the cursor we already have; - * error or no, it won't move. - * - * We use DB_RMW for all of these gets because we'll be - * writing soon enough in the "normal" put code. In - * transactional databases we'll hold those write locks - * even if we close the cursor we're reading with. - * - * The DB_KEYEMPTY return needs special handling -- if the - * cursor is on a deleted key, we return DB_NOTFOUND. - */ - ret = __db_c_get(dbc_arg, &pkey, &olddata, rmw | DB_CURRENT); - if (ret == DB_KEYEMPTY) - ret = DB_NOTFOUND; - if (ret != 0) - goto err; - - have_oldrec = 1; /* We've looked for the old record. */ - } else { - /* - * Set pkey so we can use &pkey everywhere instead of key. - * If DB_CURRENT is set and there is a key at the current - * location, pkey will be overwritten before it's used. - */ - pkey.data = key->data; - pkey.size = key->size; - } - - /* - * Check for partial puts (step 2). - */ - if (F_ISSET(data, DB_DBT_PARTIAL)) { - if (!have_oldrec && !nodel) { - /* - * We're going to have to search the tree for the - * specified key. Dup a cursor (so we have the same - * locking info) and do a c_get. - */ - if ((ret = __db_c_idup(dbc_arg, &pdbc, 0)) != 0) - goto err; - - /* We should have gotten DB_CURRENT in step 1. */ - DB_ASSERT(flags != DB_CURRENT); - - ret = __db_c_get(pdbc, &pkey, &olddata, rmw | DB_SET); - if (ret == DB_KEYEMPTY || ret == DB_NOTFOUND) { - nodel = 1; - ret = 0; - } - if ((t_ret = __db_c_close(pdbc)) != 0) - ret = t_ret; - if (ret != 0) - goto err; - - have_oldrec = 1; - } - - /* - * Now build the new datum from olddata and the partial data we - * were given. It's okay to do this if no record was returned - * above: a partial put on an empty record is allowed, if a - * little strange. The data is zero-padded. - */ - if ((ret = - __db_buildpartial(dbp, &olddata, data, &newdata)) != 0) - goto err; - ispartial = 1; - } else - ispartial = 0; - - /* - * Handle fixed-length records. If the primary database has - * fixed-length records, we need to pad out the datum before - * we pass it into the callback function; we always index the - * "real" record. - */ - if ((dbp->type == DB_RECNO && F_ISSET(dbp, DB_AM_FIXEDLEN)) || - (dbp->type == DB_QUEUE)) { - if (dbp->type == DB_QUEUE) { - re_len = ((QUEUE *)dbp->q_internal)->re_len; - re_pad = ((QUEUE *)dbp->q_internal)->re_pad; - } else { - re_len = ((BTREE *)dbp->bt_internal)->re_len; - re_pad = ((BTREE *)dbp->bt_internal)->re_pad; - } - - size = ispartial ? newdata.size : data->size; - if (size > re_len) { - ret = __db_rec_toobig(dbenv, size, re_len); - goto err; - } else if (size < re_len) { - /* - * If we're not doing a partial put, copy - * data->data into newdata.data, then pad out - * newdata.data. - * - * If we're doing a partial put, the data - * we want are already in newdata.data; we - * just need to pad. - * - * Either way, realloc is safe. - */ - if ((ret = - __os_realloc(dbenv, re_len, &newdata.data)) != 0) - goto err; - if (!ispartial) - memcpy(newdata.data, data->data, size); - memset((u_int8_t *)newdata.data + size, re_pad, - re_len - size); - newdata.size = re_len; - ispartial = 1; - } - } - - /* - * Loop through the secondaries. (Step 3.) - * - * Note that __db_s_first and __db_s_next will take care of - * thread-locking and refcounting issues. - */ - if ((ret = __db_s_first(dbp, &sdbp)) != 0) - goto err; - for (; sdbp != NULL && ret == 0; ret = __db_s_next(&sdbp)) { - /* - * Don't process this secondary if the key is immutable and we - * know that the old record exists. This optimization can't be - * used if we have not checked for the old record yet. - */ - if (have_oldrec && !nodel && - FLD_ISSET(sdbp->s_assoc_flags, DB_ASSOC_IMMUTABLE_KEY)) - continue; - - /* - * Call the callback for this secondary, to get the - * appropriate secondary key. - */ - memset(&skey, 0, sizeof(DBT)); - if ((ret = sdbp->s_callback(sdbp, - &pkey, ispartial ? &newdata : data, &skey)) != 0) { - if (ret == DB_DONOTINDEX) - /* - * The callback returned a null value--don't - * put this key in the secondary. Just - * move on to the next one--we'll handle - * any necessary deletes in step 5. - */ - continue; - goto err; - } - - /* - * Open a cursor in this secondary. - * - * Use the same locker ID as our primary cursor, so that - * we're guaranteed that the locks don't conflict (e.g. in CDB - * or if we're subdatabases that share and want to lock a - * metadata page). - */ - if ((ret = __db_cursor_int(sdbp, dbc_arg->txn, sdbp->type, - PGNO_INVALID, 0, dbc_arg->locker, &sdbc)) != 0) - goto err; - - /* - * If we're in CDB, updates will fail since the new cursor - * isn't a writer. However, we hold the WRITE lock in the - * primary and will for as long as our new cursor lasts, - * and the primary and secondary share a lock file ID, - * so it's safe to consider this a WRITER. The close - * routine won't try to put anything because we don't - * really have a lock. - */ - if (CDB_LOCKING(dbenv)) { - DB_ASSERT(sdbc->mylock.off == LOCK_INVALID); - F_SET(sdbc, DBC_WRITER); - } - - /* - * Swap the primary key to the byte order of this secondary, if - * necessary. By doing this now, we can compare directly - * against the data already in the secondary without having to - * swap it after reading. - */ - SWAP_IF_NEEDED(dbp, sdbp, &pkey); - - /* - * There are three cases here-- - * 1) The secondary supports sorted duplicates. - * If we attempt to put a secondary/primary pair - * that already exists, that's a duplicate duplicate, - * and c_put will return DB_KEYEXIST (see __db_duperr). - * This will leave us with exactly one copy of the - * secondary/primary pair, and this is just right--we'll - * avoid deleting it later, as the old and new secondaries - * will match (since the old secondary is the dup dup - * that's already there). - * 2) The secondary supports duplicates, but they're not - * sorted. We need to avoid putting a duplicate - * duplicate, because the matching old and new secondaries - * will prevent us from deleting anything and we'll - * wind up with two secondary records that point to the - * same primary key. Do a c_get(DB_GET_BOTH); only - * do the put if the secondary doesn't exist. - * 3) The secondary doesn't support duplicates at all. - * In this case, secondary keys must be unique; if - * another primary key already exists for this - * secondary key, we have to either overwrite it or - * not put this one, and in either case we've - * corrupted the secondary index. Do a c_get(DB_SET). - * If the secondary/primary pair already exists, do - * nothing; if the secondary exists with a different - * primary, return an error; and if the secondary - * does not exist, put it. - */ - if (!F_ISSET(sdbp, DB_AM_DUP)) { - /* Case 3. */ - memset(&oldpkey, 0, sizeof(DBT)); - F_SET(&oldpkey, DB_DBT_MALLOC); - ret = __db_c_get(sdbc, - &skey, &oldpkey, rmw | DB_SET); - if (ret == 0) { - cmp = __bam_defcmp(sdbp, &oldpkey, &pkey); - __os_ufree(dbenv, oldpkey.data); - if (cmp != 0) { - __db_err(dbenv, "%s%s", - "Put results in a non-unique secondary key in an ", - "index not configured to support duplicates"); - ret = EINVAL; - } - } - if (ret != DB_NOTFOUND && ret != DB_KEYEMPTY) - goto skipput; - } else if (!F_ISSET(sdbp, DB_AM_DUPSORT)) { - /* Case 2. */ - memset(&tempskey, 0, sizeof(DBT)); - tempskey.data = skey.data; - tempskey.size = skey.size; - memset(&temppkey, 0, sizeof(DBT)); - temppkey.data = pkey.data; - temppkey.size = pkey.size; - ret = __db_c_get(sdbc, &tempskey, &temppkey, - rmw | DB_GET_BOTH); - if (ret != DB_NOTFOUND && ret != DB_KEYEMPTY) - goto skipput; - } - - ret = __db_c_put(sdbc, &skey, &pkey, DB_UPDATE_SECONDARY); - - /* - * We don't know yet whether this was a put-overwrite that - * in fact changed nothing. If it was, we may get DB_KEYEXIST. - * This is not an error. - */ - if (ret == DB_KEYEXIST) - ret = 0; - -skipput: FREE_IF_NEEDED(sdbp, &skey) - - /* Make sure the primary key is back in native byte-order. */ - SWAP_IF_NEEDED(dbp, sdbp, &pkey); - - if ((t_ret = __db_c_close(sdbc)) != 0 && ret == 0) - ret = t_ret; - - if (ret != 0) - goto err; - } - if (ret != 0) - goto err; - - /* If still necessary, go get the old primary key/data. (Step 4.) */ - if (!have_oldrec) { - /* See the comments in step 2. This is real familiar. */ - if ((ret = __db_c_idup(dbc_arg, &pdbc, 0)) != 0) - goto err; - DB_ASSERT(flags != DB_CURRENT); - pkey.data = key->data; - pkey.size = key->size; - ret = __db_c_get(pdbc, &pkey, &olddata, rmw | DB_SET); - if (ret == DB_KEYEMPTY || ret == DB_NOTFOUND) { - nodel = 1; - ret = 0; - } - if ((t_ret = __db_c_close(pdbc)) != 0 && ret == 0) - ret = t_ret; - if (ret != 0) - goto err; - have_oldrec = 1; - } - - /* - * If we don't follow this goto, we do in fact have an old record - * we may need to go delete. (Step 5). - */ - if (nodel) - goto skip_s_update; - - if ((ret = __db_s_first(dbp, &sdbp)) != 0) - goto err; - for (; sdbp != NULL && ret == 0; ret = __db_s_next(&sdbp)) { - /* - * Don't process this secondary if the key is immutable. We - * know that the old record exists, so this optimization can - * always be used. - */ - if (FLD_ISSET(sdbp->s_assoc_flags, DB_ASSOC_IMMUTABLE_KEY)) - continue; - - /* - * Call the callback for this secondary to get the - * old secondary key. - */ - memset(&oldskey, 0, sizeof(DBT)); - if ((ret = sdbp->s_callback(sdbp, - &pkey, &olddata, &oldskey)) != 0) { - if (ret == DB_DONOTINDEX) - /* - * The callback returned a null value--there's - * nothing to delete. Go on to the next - * secondary. - */ - continue; - goto err; - } - memset(&skey, 0, sizeof(DBT)); - if ((ret = sdbp->s_callback(sdbp, - &pkey, ispartial ? &newdata : data, &skey)) != 0 && - ret != DB_DONOTINDEX) - goto err; - - /* - * If there is no new secondary key, or if the old secondary - * key is different from the new secondary key, then - * we need to delete the old one. - * - * Note that bt_compare is (and must be) set no matter - * what access method we're in. - */ - sdbc = NULL; - if (ret == DB_DONOTINDEX || - ((BTREE *)sdbp->bt_internal)->bt_compare(sdbp, - &oldskey, &skey) != 0) { - if ((ret = __db_cursor_int( - sdbp, dbc_arg->txn, sdbp->type, - PGNO_INVALID, 0, dbc_arg->locker, &sdbc)) != 0) - goto err; - if (CDB_LOCKING(dbenv)) { - DB_ASSERT(sdbc->mylock.off == LOCK_INVALID); - F_SET(sdbc, DBC_WRITER); - } - - /* - * Don't let c_get(DB_GET_BOTH) stomp on - * our data. Use a temp DBT instead. - */ - memset(&tempskey, 0, sizeof(DBT)); - tempskey.data = oldskey.data; - tempskey.size = oldskey.size; - SWAP_IF_NEEDED(dbp, sdbp, &pkey); - memset(&temppkey, 0, sizeof(DBT)); - temppkey.data = pkey.data; - temppkey.size = pkey.size; - if ((ret = __db_c_get(sdbc, - &tempskey, &temppkey, rmw | DB_GET_BOTH)) == 0) - ret = __db_c_del(sdbc, DB_UPDATE_SECONDARY); - else if (ret == DB_NOTFOUND) - ret = __db_secondary_corrupt(dbp); - SWAP_IF_NEEDED(dbp, sdbp, &pkey); - } - - FREE_IF_NEEDED(sdbp, &skey); - FREE_IF_NEEDED(sdbp, &oldskey); - if (sdbc != NULL && (t_ret = __db_c_close(sdbc)) != 0 && - ret == 0) - ret = t_ret; - if (ret != 0) - goto err; - } - - /* Secondary index updates are now done. On to the "real" stuff. */ - -skip_s_update: - /* - * If we have an off-page duplicates cursor, and the operation applies - * to it, perform the operation. Duplicate the cursor and call the - * underlying function. - * - * Off-page duplicate trees are locked in the primary tree, that is, - * we acquire a write lock in the primary tree and no locks in the - * off-page dup tree. If the put operation is done in an off-page - * duplicate tree, call the primary cursor's upgrade routine first. - */ - if (dbc_arg->internal->opd != NULL && - (flags == DB_AFTER || flags == DB_BEFORE || flags == DB_CURRENT)) { - /* - * A special case for hash off-page duplicates. Hash doesn't - * support (and is documented not to support) put operations - * relative to a cursor which references an already deleted - * item. For consistency, apply the same criteria to off-page - * duplicates as well. - */ - if (dbc_arg->dbtype == DB_HASH && F_ISSET( - ((BTREE_CURSOR *)(dbc_arg->internal->opd->internal)), - C_DELETED)) { - ret = DB_NOTFOUND; - goto err; - } - - if ((ret = dbc_arg->c_am_writelock(dbc_arg)) != 0 || - (ret = __db_c_dup(dbc_arg, &dbc_n, DB_POSITION)) != 0) - goto err; - opd = dbc_n->internal->opd; - if ((ret = opd->c_am_put( - opd, key, data, flags, NULL)) != 0) - goto err; - goto done; - } - - /* - * Perform an operation on the main cursor. Duplicate the cursor, - * and call the underlying function. - * - * XXX: MARGO - * - tmp_flags = flags == DB_AFTER || - flags == DB_BEFORE || flags == DB_CURRENT ? DB_POSITION : 0; - */ - tmp_flags = DB_POSITION; - - /* - * If this cursor is going to be closed immediately, we don't - * need to take precautions to clean it up on error. - */ - if (F_ISSET(dbc_arg, DBC_TRANSIENT)) - dbc_n = dbc_arg; - else if ((ret = __db_c_idup(dbc_arg, &dbc_n, tmp_flags)) != 0) - goto err; - - pgno = PGNO_INVALID; - if ((ret = dbc_n->c_am_put(dbc_n, key, data, flags, &pgno)) != 0) - goto err; - - /* - * We may be referencing a new off-page duplicates tree. Acquire - * a new cursor and call the underlying function. - */ - if (pgno != PGNO_INVALID) { - oldopd = dbc_n->internal->opd; - if ((ret = __db_c_newopd(dbc_arg, pgno, oldopd, &opd)) != 0) { - dbc_n->internal->opd = opd; - goto err; - } - - dbc_n->internal->opd = opd; - - if ((ret = opd->c_am_put( - opd, key, data, flags, NULL)) != 0) - goto err; - } - -done: -err: /* Cleanup and cursor resolution. */ - if ((t_ret = __db_c_cleanup(dbc_arg, dbc_n, ret)) != 0 && ret == 0) - ret = t_ret; - - /* If newdata or olddata were used, free their buffers. */ - if (newdata.data != NULL) - __os_free(dbenv, newdata.data); - if (olddata.data != NULL) - __os_ufree(dbenv, olddata.data); - - CDB_LOCKING_DONE(dbp, dbc_arg); - - if (sdbp != NULL && (t_ret = __db_s_done(sdbp)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __db_duperr() - * Error message: we don't currently support sorted duplicate duplicates. - * PUBLIC: int __db_duperr __P((DB *, u_int32_t)); - */ -int -__db_duperr(dbp, flags) - DB *dbp; - u_int32_t flags; -{ - - /* - * If we run into this error while updating a secondary index, - * don't yell--there's no clean way to pass DB_NODUPDATA in along - * with DB_UPDATE_SECONDARY, but we may run into this problem - * in a normal, non-error course of events. - * - * !!! - * If and when we ever permit duplicate duplicates in sorted-dup - * databases, we need to either change the secondary index code - * to check for dup dups, or we need to maintain the implicit - * "DB_NODUPDATA" behavior for databases with DB_AM_SECONDARY set. - */ - if (flags != DB_NODUPDATA && !F_ISSET(dbp, DB_AM_SECONDARY)) - __db_err(dbp->dbenv, - "Duplicate data items are not supported with sorted data"); - return (DB_KEYEXIST); -} - -/* - * __db_c_cleanup -- - * Clean up duplicate cursors. - */ -static int -__db_c_cleanup(dbc, dbc_n, failed) - DBC *dbc, *dbc_n; - int failed; -{ - DB *dbp; - DBC *opd; - DBC_INTERNAL *internal; - DB_MPOOLFILE *mpf; - int ret, t_ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - internal = dbc->internal; - ret = 0; - - /* Discard any pages we're holding. */ - if (internal->page != NULL) { - if ((t_ret = - __memp_fput(mpf, internal->page, 0)) != 0 && ret == 0) - ret = t_ret; - internal->page = NULL; - } - opd = internal->opd; - if (opd != NULL && opd->internal->page != NULL) { - if ((t_ret = - __memp_fput(mpf, opd->internal->page, 0)) != 0 && ret == 0) - ret = t_ret; - opd->internal->page = NULL; - } - - /* - * If dbc_n is NULL, there's no internal cursor swapping to be done - * and no dbc_n to close--we probably did the entire operation on an - * offpage duplicate cursor. Just return. - * - * If dbc and dbc_n are the same, we're either inside a DB->{put/get} - * operation, and as an optimization we performed the operation on - * the main cursor rather than on a duplicated one, or we're in a - * bulk get that can't have moved the cursor (DB_MULTIPLE with the - * initial c_get operation on an off-page dup cursor). Just - * return--either we know we didn't move the cursor, or we're going - * to close it before we return to application code, so we're sure - * not to visibly violate the "cursor stays put on error" rule. - */ - if (dbc_n == NULL || dbc == dbc_n) - return (ret); - - if (dbc_n->internal->page != NULL) { - if ((t_ret = __memp_fput( - mpf, dbc_n->internal->page, 0)) != 0 && ret == 0) - ret = t_ret; - dbc_n->internal->page = NULL; - } - opd = dbc_n->internal->opd; - if (opd != NULL && opd->internal->page != NULL) { - if ((t_ret = - __memp_fput(mpf, opd->internal->page, 0)) != 0 && ret == 0) - ret = t_ret; - opd->internal->page = NULL; - } - - /* - * If we didn't fail before entering this routine or just now when - * freeing pages, swap the interesting contents of the old and new - * cursors. - */ - if (!failed && ret == 0) { - dbc->internal = dbc_n->internal; - dbc_n->internal = internal; - } - - /* - * Close the cursor we don't care about anymore. The close can fail, - * but we only expect DB_LOCK_DEADLOCK failures. This violates our - * "the cursor is unchanged on error" semantics, but since all you can - * do with a DB_LOCK_DEADLOCK failure is close the cursor, I believe - * that's OK. - * - * XXX - * There's no way to recover from failure to close the old cursor. - * All we can do is move to the new position and return an error. - * - * XXX - * We might want to consider adding a flag to the cursor, so that any - * subsequent operations other than close just return an error? - */ - if ((t_ret = __db_c_close(dbc_n)) != 0 && ret == 0) - ret = t_ret; - - /* - * If this was an update that is supporting dirty reads - * then we may have just swapped our read for a write lock - * which is held by the surviving cursor. We need - * to explicitly downgrade this lock. The closed cursor - * may only have had a read lock. - */ - if (F_ISSET(dbp, DB_AM_READ_UNCOMMITTED) && - dbc->internal->lock_mode == DB_LOCK_WRITE) { - if ((t_ret = - __TLPUT(dbc, dbc->internal->lock)) != 0 && ret == 0) - ret = t_ret; - if (t_ret == 0) - dbc->internal->lock_mode = DB_LOCK_WWRITE; - } - - return (ret); -} - -/* - * __db_c_secondary_get_pp -- - * This wrapper function for DBC->c_pget() is the DBC->c_get() function - * for a secondary index cursor. - * - * PUBLIC: int __db_c_secondary_get_pp __P((DBC *, DBT *, DBT *, u_int32_t)); - */ -int -__db_c_secondary_get_pp(dbc, skey, data, flags) - DBC *dbc; - DBT *skey, *data; - u_int32_t flags; -{ - - DB_ASSERT(F_ISSET(dbc->dbp, DB_AM_SECONDARY)); - return (__db_c_pget_pp(dbc, skey, NULL, data, flags)); -} - -/* - * __db_c_pget -- - * Get a primary key/data pair through a secondary index. - * - * PUBLIC: int __db_c_pget __P((DBC *, DBT *, DBT *, DBT *, u_int32_t)); - */ -int -__db_c_pget(dbc, skey, pkey, data, flags) - DBC *dbc; - DBT *skey, *pkey, *data; - u_int32_t flags; -{ - DB *pdbp, *sdbp; - DBC *dbc_n, *pdbc; - DBT nullpkey; - u_int32_t save_pkey_flags, tmp_flags, tmp_read_uncommitted, tmp_rmw; - int pkeymalloc, ret, t_ret; - - sdbp = dbc->dbp; - pdbp = sdbp->s_primary; - dbc_n = NULL; - pkeymalloc = t_ret = 0; - - /* - * The challenging part of this function is getting the behavior - * right for all the various permutations of DBT flags. The - * next several blocks handle the various cases we need to - * deal with specially. - */ - - /* - * We may be called with a NULL pkey argument, if we've been - * wrapped by a 2-DBT get call. If so, we need to use our - * own DBT. - */ - if (pkey == NULL) { - memset(&nullpkey, 0, sizeof(DBT)); - pkey = &nullpkey; - } - - /* Clear OR'd in additional bits so we can check for flag equality. */ - tmp_rmw = LF_ISSET(DB_RMW); - LF_CLR(DB_RMW); - - tmp_read_uncommitted = - LF_ISSET(DB_READ_UNCOMMITTED) && - !F_ISSET(dbc, DBC_READ_UNCOMMITTED); - LF_CLR(DB_READ_UNCOMMITTED); - - /* - * DB_GET_RECNO is a special case, because we're interested not in - * the primary key/data pair, but rather in the primary's record - * number. - */ - if (flags == DB_GET_RECNO) { - if (tmp_rmw) - F_SET(dbc, DBC_RMW); - if (tmp_read_uncommitted) - F_SET(dbc, DBC_READ_UNCOMMITTED); - ret = __db_c_pget_recno(dbc, pkey, data, flags); - if (tmp_rmw) - F_CLR(dbc, DBC_RMW); - if (tmp_read_uncommitted) - F_CLR(dbc, DBC_READ_UNCOMMITTED); - return (ret); - } - - /* - * If the DBTs we've been passed don't have any of the - * user-specified memory management flags set, we want to make sure - * we return values using the DBTs dbc->rskey, dbc->rkey, and - * dbc->rdata, respectively. - * - * There are two tricky aspects to this: first, we need to pass - * skey and pkey *in* to the initial c_get on the secondary key, - * since either or both may be looked at by it (depending on the - * get flag). Second, we must not use a normal DB->get call - * on the secondary, even though that's what we want to accomplish, - * because the DB handle may be free-threaded. Instead, - * we open a cursor, then take steps to ensure that we actually use - * the rkey/rdata from the *secondary* cursor. - * - * We accomplish all this by passing in the DBTs we started out - * with to the c_get, but swapping the contents of rskey and rkey, - * respectively, into rkey and rdata; __db_ret will treat them like - * the normal key/data pair in a c_get call, and will realloc them as - * need be (this is "step 1"). Then, for "step 2", we swap back - * rskey/rkey/rdata to normal, and do a get on the primary with the - * secondary dbc appointed as the owner of the returned-data memory. - * - * Note that in step 2, we copy the flags field in case we need to - * pass down a DB_DBT_PARTIAL or other flag that is compatible with - * letting DB do the memory management. - */ - - /* - * It is correct, though slightly sick, to attempt a partial get of a - * primary key. However, if we do so here, we'll never find the - * primary record; clear the DB_DBT_PARTIAL field of pkey just for the - * duration of the next call. - */ - save_pkey_flags = pkey->flags; - F_CLR(pkey, DB_DBT_PARTIAL); - - /* - * Now we can go ahead with the meat of this call. First, get the - * primary key from the secondary index. (What exactly we get depends - * on the flags, but the underlying cursor get will take care of the - * dirty work.) Duplicate the cursor, in case the later get on the - * primary fails. - */ - switch (flags) { - case DB_CURRENT: - case DB_GET_BOTHC: - case DB_NEXT: - case DB_NEXT_DUP: - case DB_NEXT_NODUP: - case DB_PREV: - case DB_PREV_NODUP: - tmp_flags = DB_POSITION; - break; - default: - tmp_flags = 0; - break; - } - - if (tmp_read_uncommitted) - F_SET(dbc, DBC_READ_UNCOMMITTED); - - if ((ret = __db_c_dup(dbc, &dbc_n, tmp_flags)) != 0) { - if (tmp_read_uncommitted) - F_CLR(dbc, DBC_READ_UNCOMMITTED); - - return (ret); - } - - F_SET(dbc_n, DBC_TRANSIENT); - - if (tmp_rmw) - F_SET(dbc_n, DBC_RMW); - - /* - * If we've been handed a primary key, it will be in native byte order, - * so we need to swap it before reading from the secondary. - */ - if (flags == DB_GET_BOTH || flags == DB_GET_BOTHC || - flags == DB_GET_BOTH_RANGE) - SWAP_IF_NEEDED(pdbp, sdbp, pkey); - - /* Step 1. */ - dbc_n->rdata = dbc->rkey; - dbc_n->rkey = dbc->rskey; - ret = __db_c_get(dbc_n, skey, pkey, flags); - /* Restore pkey's flags in case we stomped the PARTIAL flag. */ - pkey->flags = save_pkey_flags; - - if (tmp_read_uncommitted) - F_CLR(dbc_n, DBC_READ_UNCOMMITTED); - if (tmp_rmw) - F_CLR(dbc_n, DBC_RMW); - - /* - * We need to swap the primary key to native byte order if we read it - * successfully, or if we swapped it on entry above. We can't return - * with the application's data modified. - */ - if (ret == 0 || flags == DB_GET_BOTH || flags == DB_GET_BOTHC || - flags == DB_GET_BOTH_RANGE) - SWAP_IF_NEEDED(pdbp, sdbp, pkey); - - if (ret != 0) - goto err; - - /* - * Now we're ready for "step 2". If either or both of pkey and data do - * not have memory management flags set--that is, if DB is managing - * their memory--we need to swap around the rkey/rdata structures so - * that we don't wind up trying to use memory managed by the primary - * database cursor, which we'll close before we return. - * - * !!! - * If you're carefully following the bouncing ball, you'll note that in - * the DB-managed case, the buffer hanging off of pkey is the same as - * dbc->rkey->data. This is just fine; we may well realloc and stomp - * on it when we return, if we're doing a DB_GET_BOTH and need to - * return a different partial or key (depending on the comparison - * function), but this is safe. - * - * !!! - * We need to use __db_cursor_int here rather than simply calling - * pdbp->cursor, because otherwise, if we're in CDB, we'll allocate a - * new locker ID and leave ourselves open to deadlocks. (Even though - * we're only acquiring read locks, we'll still block if there are any - * waiters.) - */ - if ((ret = __db_cursor_int(pdbp, - dbc->txn, pdbp->type, PGNO_INVALID, 0, dbc->locker, &pdbc)) != 0) - goto err; - - if (tmp_read_uncommitted) - F_SET(pdbc, DBC_READ_UNCOMMITTED); - if (tmp_rmw) - F_SET(pdbc, DBC_RMW); - if (F_ISSET(dbc, DBC_READ_COMMITTED)) - F_SET(pdbc, DBC_READ_COMMITTED); - - /* - * We're about to use pkey a second time. If DB_DBT_MALLOC is set on - * it, we'll leak the memory we allocated the first time. Thus, set - * DB_DBT_REALLOC instead so that we reuse that memory instead of - * leaking it. - * - * !!! - * This assumes that the user must always specify a compatible realloc - * function if a malloc function is specified. I think this is a - * reasonable requirement. - */ - if (F_ISSET(pkey, DB_DBT_MALLOC)) { - F_CLR(pkey, DB_DBT_MALLOC); - F_SET(pkey, DB_DBT_REALLOC); - pkeymalloc = 1; - } - - /* - * Do the actual get. Set DBC_TRANSIENT since we don't care about - * preserving the position on error, and it's faster. SET_RET_MEM so - * that the secondary DBC owns any returned-data memory. - */ - F_SET(pdbc, DBC_TRANSIENT); - SET_RET_MEM(pdbc, dbc); - ret = __db_c_get(pdbc, pkey, data, DB_SET); - - /* - * If the item wasn't found in the primary, this is a bug; our - * secondary has somehow gotten corrupted, and contains elements that - * don't correspond to anything in the primary. Complain. - */ - if (ret == DB_NOTFOUND) - ret = __db_secondary_corrupt(pdbp); - - /* Now close the primary cursor. */ - if ((t_ret = __db_c_close(pdbc)) != 0 && ret == 0) - ret = t_ret; - -err: /* Cleanup and cursor resolution. */ - if ((t_ret = __db_c_cleanup(dbc, dbc_n, ret)) != 0 && ret == 0) - ret = t_ret; - if (pkeymalloc) { - /* - * If pkey had a MALLOC flag, we need to restore it; otherwise, - * if the user frees the buffer but reuses the DBT without - * NULL'ing its data field or changing the flags, we may drop - * core. - */ - F_CLR(pkey, DB_DBT_REALLOC); - F_SET(pkey, DB_DBT_MALLOC); - } - - return (ret); -} - -/* - * __db_c_pget_recno -- - * Perform a DB_GET_RECNO c_pget on a secondary index. Returns - * the secondary's record number in the pkey field and the primary's - * in the data field. - */ -static int -__db_c_pget_recno(sdbc, pkey, data, flags) - DBC *sdbc; - DBT *pkey, *data; - u_int32_t flags; -{ - DB *pdbp, *sdbp; - DB_ENV *dbenv; - DBC *pdbc; - DBT discardme, primary_key; - db_recno_t oob; - u_int32_t rmw; - int ret, t_ret; - - sdbp = sdbc->dbp; - pdbp = sdbp->s_primary; - dbenv = sdbp->dbenv; - pdbc = NULL; - ret = t_ret = 0; - - rmw = LF_ISSET(DB_RMW); - - memset(&discardme, 0, sizeof(DBT)); - F_SET(&discardme, DB_DBT_USERMEM | DB_DBT_PARTIAL); - - oob = RECNO_OOB; - - /* - * If the primary is an rbtree, we want its record number, whether - * or not the secondary is one too. Fetch the recno into "data". - * - * If it's not an rbtree, return RECNO_OOB in "data". - */ - if (F_ISSET(pdbp, DB_AM_RECNUM)) { - /* - * Get the primary key, so we can find the record number - * in the primary. (We're uninterested in the secondary key.) - */ - memset(&primary_key, 0, sizeof(DBT)); - F_SET(&primary_key, DB_DBT_MALLOC); - if ((ret = __db_c_get(sdbc, - &discardme, &primary_key, rmw | DB_CURRENT)) != 0) - return (ret); - - /* - * Open a cursor on the primary, set it to the right record, - * and fetch its recno into "data". - * - * (See __db_c_pget for comments on the use of __db_cursor_int.) - * - * SET_RET_MEM so that the secondary DBC owns any returned-data - * memory. - */ - if ((ret = __db_cursor_int(pdbp, sdbc->txn, - pdbp->type, PGNO_INVALID, 0, sdbc->locker, &pdbc)) != 0) - goto perr; - SET_RET_MEM(pdbc, sdbc); - if ((ret = __db_c_get(pdbc, - &primary_key, &discardme, rmw | DB_SET)) != 0) - goto perr; - - ret = __db_c_get(pdbc, &discardme, data, rmw | DB_GET_RECNO); - -perr: __os_ufree(sdbp->dbenv, primary_key.data); - if (pdbc != NULL && - (t_ret = __db_c_close(pdbc)) != 0 && ret == 0) - ret = t_ret; - if (ret != 0) - return (ret); - } else if ((ret = __db_retcopy(dbenv, data, &oob, - sizeof(oob), &sdbc->rkey->data, &sdbc->rkey->ulen)) != 0) - return (ret); - - /* - * If the secondary is an rbtree, we want its record number, whether - * or not the primary is one too. Fetch the recno into "pkey". - * - * If it's not an rbtree, return RECNO_OOB in "pkey". - */ - if (F_ISSET(sdbp, DB_AM_RECNUM)) - return (__db_c_get(sdbc, &discardme, pkey, flags)); - else - return (__db_retcopy(dbenv, pkey, &oob, - sizeof(oob), &sdbc->rdata->data, &sdbc->rdata->ulen)); -} - -/* - * __db_wrlock_err -- do not have a write lock. - */ -static int -__db_wrlock_err(dbenv) - DB_ENV *dbenv; -{ - __db_err(dbenv, "Write attempted on read-only cursor"); - return (EPERM); -} - -/* - * __db_c_del_secondary -- - * Perform a delete operation on a secondary index: call through - * to the primary and delete the primary record that this record - * points to. - * - * Note that deleting the primary record will call c_del on all - * the secondaries, including this one; thus, it is not necessary - * to execute both this function and an actual delete. - */ -static int -__db_c_del_secondary(dbc) - DBC *dbc; -{ - DB *pdbp; - DBC *pdbc; - DBT skey, pkey; - int ret, t_ret; - - memset(&skey, 0, sizeof(DBT)); - memset(&pkey, 0, sizeof(DBT)); - pdbp = dbc->dbp->s_primary; - - /* - * Get the current item that we're pointing at. - * We don't actually care about the secondary key, just - * the primary. - */ - F_SET(&skey, DB_DBT_PARTIAL | DB_DBT_USERMEM); - if ((ret = __db_c_get(dbc, &skey, &pkey, DB_CURRENT)) != 0) - return (ret); - - SWAP_IF_NEEDED(pdbp, dbc->dbp, &pkey); - - /* - * Create a cursor on the primary with our locker ID, - * so that when it calls back, we don't conflict. - * - * We create a cursor explicitly because there's no - * way to specify the same locker ID if we're using - * locking but not transactions if we use the DB->del - * interface. This shouldn't be any less efficient - * anyway. - */ - if ((ret = __db_cursor_int(pdbp, dbc->txn, - pdbp->type, PGNO_INVALID, 0, dbc->locker, &pdbc)) != 0) - return (ret); - - /* - * See comment in __db_c_put--if we're in CDB, - * we already hold the locks we need, and we need to flag - * the cursor as a WRITER so we don't run into errors - * when we try to delete. - */ - if (CDB_LOCKING(pdbp->dbenv)) { - DB_ASSERT(pdbc->mylock.off == LOCK_INVALID); - F_SET(pdbc, DBC_WRITER); - } - - /* - * Set the new cursor to the correct primary key. Then - * delete it. We don't really care about the datum; - * just reuse our skey DBT. - * - * If the primary get returns DB_NOTFOUND, something is amiss-- - * every record in the secondary should correspond to some record - * in the primary. - */ - if ((ret = __db_c_get(pdbc, &pkey, &skey, - (STD_LOCKING(dbc) ? DB_RMW : 0) | DB_SET)) == 0) - ret = __db_c_del(pdbc, 0); - else if (ret == DB_NOTFOUND) - ret = __db_secondary_corrupt(pdbp); - - if ((t_ret = __db_c_close(pdbc)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __db_c_del_primary -- - * Perform a delete operation on a primary index. Loop through - * all the secondary indices which correspond to this primary - * database, and delete any secondary keys that point at the current - * record. - * - * PUBLIC: int __db_c_del_primary __P((DBC *)); - */ -int -__db_c_del_primary(dbc) - DBC *dbc; -{ - DB *dbp, *sdbp; - DBC *sdbc; - DBT data, pkey, skey, temppkey, tempskey; - int ret, t_ret; - - dbp = dbc->dbp; - - /* - * If we're called at all, we have at least one secondary. - * (Unfortunately, we can't assert this without grabbing the mutex.) - * Get the current record so that we can construct appropriate - * secondary keys as needed. - */ - memset(&pkey, 0, sizeof(DBT)); - memset(&data, 0, sizeof(DBT)); - if ((ret = __db_c_get(dbc, &pkey, &data, DB_CURRENT)) != 0) - return (ret); - - if ((ret = __db_s_first(dbp, &sdbp)) != 0) - goto err; - for (; sdbp != NULL && ret == 0; ret = __db_s_next(&sdbp)) { - /* - * Get the secondary key for this secondary and the current - * item. - */ - memset(&skey, 0, sizeof(DBT)); - if ((ret = sdbp->s_callback(sdbp, &pkey, &data, &skey)) != 0) { - /* - * If the current item isn't in this index, we - * have no work to do. Proceed. - */ - if (ret == DB_DONOTINDEX) - continue; - - /* We had a substantive error. Bail. */ - FREE_IF_NEEDED(sdbp, &skey); - goto err; - } - - /* Open a secondary cursor. */ - if ((ret = __db_cursor_int(sdbp, dbc->txn, sdbp->type, - PGNO_INVALID, 0, dbc->locker, &sdbc)) != 0) - goto err; - /* See comment above and in __db_c_put. */ - if (CDB_LOCKING(sdbp->dbenv)) { - DB_ASSERT(sdbc->mylock.off == LOCK_INVALID); - F_SET(sdbc, DBC_WRITER); - } - - /* - * Set the secondary cursor to the appropriate item. - * Delete it. - * - * We want to use DB_RMW if locking is on; it's only - * legal then, though. - * - * !!! - * Don't stomp on any callback-allocated buffer in skey - * when we do a c_get(DB_GET_BOTH); use a temp DBT instead. - * Similarly, don't allow pkey to be invalidated when the - * cursor is closed. - */ - memset(&tempskey, 0, sizeof(DBT)); - tempskey.data = skey.data; - tempskey.size = skey.size; - SWAP_IF_NEEDED(dbp, sdbp, &pkey); - memset(&temppkey, 0, sizeof(DBT)); - temppkey.data = pkey.data; - temppkey.size = pkey.size; - if ((ret = __db_c_get(sdbc, &tempskey, &temppkey, - (STD_LOCKING(dbc) ? DB_RMW : 0) | DB_GET_BOTH)) == 0) - ret = __db_c_del(sdbc, DB_UPDATE_SECONDARY); - else if (ret == DB_NOTFOUND) - ret = __db_secondary_corrupt(dbp); - SWAP_IF_NEEDED(dbp, sdbp, &pkey); - - FREE_IF_NEEDED(sdbp, &skey); - - if ((t_ret = __db_c_close(sdbc)) != 0 && ret == 0) - ret = t_ret; - if (ret != 0) - goto err; - } - -err: if (sdbp != NULL && (t_ret = __db_s_done(sdbp)) != 0 && ret == 0) - ret = t_ret; - return (ret); -} - -/* - * __db_s_first -- - * Get the first secondary, if any are present, from the primary. - * - * PUBLIC: int __db_s_first __P((DB *, DB **)); - */ -int -__db_s_first(pdbp, sdbpp) - DB *pdbp, **sdbpp; -{ - DB *sdbp; - - MUTEX_LOCK(pdbp->dbenv, pdbp->mutex); - sdbp = LIST_FIRST(&pdbp->s_secondaries); - - /* See __db_s_next. */ - if (sdbp != NULL) - sdbp->s_refcnt++; - MUTEX_UNLOCK(pdbp->dbenv, pdbp->mutex); - - *sdbpp = sdbp; - - return (0); -} - -/* - * __db_s_next -- - * Get the next secondary in the list. - * - * PUBLIC: int __db_s_next __P((DB **)); - */ -int -__db_s_next(sdbpp) - DB **sdbpp; -{ - DB *sdbp, *pdbp, *closeme; - int ret; - - /* - * Secondary indices are kept in a linked list, s_secondaries, - * off each primary DB handle. If a primary is free-threaded, - * this list may only be traversed or modified while the primary's - * thread mutex is held. - * - * The tricky part is that we don't want to hold the thread mutex - * across the full set of secondary puts necessary for each primary - * put, or we'll wind up essentially single-threading all the puts - * to the handle; the secondary puts will each take about as - * long as the primary does, and may require I/O. So we instead - * hold the thread mutex only long enough to follow one link to the - * next secondary, and then we release it before performing the - * actual secondary put. - * - * The only danger here is that we might legitimately close a - * secondary index in one thread while another thread is performing - * a put and trying to update that same secondary index. To - * prevent this from happening, we refcount the secondary handles. - * If close is called on a secondary index handle while we're putting - * to it, it won't really be closed--the refcount will simply drop, - * and we'll be responsible for closing it here. - */ - sdbp = *sdbpp; - pdbp = sdbp->s_primary; - closeme = NULL; - - MUTEX_LOCK(pdbp->dbenv, pdbp->mutex); - DB_ASSERT(sdbp->s_refcnt != 0); - if (--sdbp->s_refcnt == 0) { - LIST_REMOVE(sdbp, s_links); - closeme = sdbp; - } - sdbp = LIST_NEXT(sdbp, s_links); - if (sdbp != NULL) - sdbp->s_refcnt++; - MUTEX_UNLOCK(pdbp->dbenv, pdbp->mutex); - - *sdbpp = sdbp; - - /* - * closeme->close() is a wrapper; call __db_close explicitly. - */ - ret = closeme != NULL ? __db_close(closeme, NULL, 0) : 0; - return (ret); -} - -/* - * __db_s_done -- - * Properly decrement the refcount on a secondary database handle we're - * using, without calling __db_s_next. - * - * PUBLIC: int __db_s_done __P((DB *)); - */ -int -__db_s_done(sdbp) - DB *sdbp; -{ - DB *pdbp; - int doclose; - - pdbp = sdbp->s_primary; - doclose = 0; - - MUTEX_LOCK(pdbp->dbenv, pdbp->mutex); - DB_ASSERT(sdbp->s_refcnt != 0); - if (--sdbp->s_refcnt == 0) { - LIST_REMOVE(sdbp, s_links); - doclose = 1; - } - MUTEX_UNLOCK(pdbp->dbenv, pdbp->mutex); - - return (doclose ? __db_close(sdbp, NULL, 0) : 0); -} - -/* - * __db_buildpartial -- - * Build the record that will result after a partial put is applied to - * an existing record. - * - * This should probably be merged with __bam_build, but that requires - * a little trickery if we plan to keep the overflow-record optimization - * in that function. - */ -static int -__db_buildpartial(dbp, oldrec, partial, newrec) - DB *dbp; - DBT *oldrec, *partial, *newrec; -{ - int ret; - u_int8_t *buf; - u_int32_t len, nbytes; - - DB_ASSERT(F_ISSET(partial, DB_DBT_PARTIAL)); - - memset(newrec, 0, sizeof(DBT)); - - nbytes = __db_partsize(oldrec->size, partial); - newrec->size = nbytes; - - if ((ret = __os_malloc(dbp->dbenv, nbytes, &buf)) != 0) - return (ret); - newrec->data = buf; - - /* Nul or pad out the buffer, for any part that isn't specified. */ - memset(buf, - F_ISSET(dbp, DB_AM_FIXEDLEN) ? ((BTREE *)dbp->bt_internal)->re_pad : - 0, nbytes); - - /* Copy in any leading data from the original record. */ - memcpy(buf, oldrec->data, - partial->doff > oldrec->size ? oldrec->size : partial->doff); - - /* Copy the data from partial. */ - memcpy(buf + partial->doff, partial->data, partial->size); - - /* Copy any trailing data from the original record. */ - len = partial->doff + partial->dlen; - if (oldrec->size > len) - memcpy(buf + partial->doff + partial->size, - (u_int8_t *)oldrec->data + len, oldrec->size - len); - - return (0); -} - -/* - * __db_partsize -- - * Given the number of bytes in an existing record and a DBT that - * is about to be partial-put, calculate the size of the record - * after the put. - * - * This code is called from __bam_partsize. - * - * PUBLIC: u_int32_t __db_partsize __P((u_int32_t, DBT *)); - */ -u_int32_t -__db_partsize(nbytes, data) - u_int32_t nbytes; - DBT *data; -{ - - /* - * There are really two cases here: - * - * Case 1: We are replacing some bytes that do not exist (i.e., they - * are past the end of the record). In this case the number of bytes - * we are replacing is irrelevant and all we care about is how many - * bytes we are going to add from offset. So, the new record length - * is going to be the size of the new bytes (size) plus wherever those - * new bytes begin (doff). - * - * Case 2: All the bytes we are replacing exist. Therefore, the new - * size is the oldsize (nbytes) minus the bytes we are replacing (dlen) - * plus the bytes we are adding (size). - */ - if (nbytes < data->doff + data->dlen) /* Case 1 */ - return (data->doff + data->size); - - return (nbytes + data->size - data->dlen); /* Case 2 */ -} diff --git a/storage/bdb/db/db_conv.c b/storage/bdb/db/db_conv.c deleted file mode 100644 index 53f4e638d5c..00000000000 --- a/storage/bdb/db/db_conv.c +++ /dev/null @@ -1,561 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994, 1995, 1996 - * Keith Bostic. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994, 1995 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: db_conv.c,v 12.1 2005/06/16 20:21:09 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/crypto.h" -#include "dbinc/hmac.h" -#include "dbinc/db_page.h" -#include "dbinc/db_swap.h" -#include "dbinc/btree.h" -#include "dbinc/hash.h" -#include "dbinc/log.h" -#include "dbinc/qam.h" - -/* - * __db_pgin -- - * Primary page-swap routine. - * - * PUBLIC: int __db_pgin __P((DB_ENV *, db_pgno_t, void *, DBT *)); - */ -int -__db_pgin(dbenv, pg, pp, cookie) - DB_ENV *dbenv; - db_pgno_t pg; - void *pp; - DBT *cookie; -{ - DB dummydb, *dbp; - DB_PGINFO *pginfo; - DB_CIPHER *db_cipher; - DB_LSN not_used; - PAGE *pagep; - size_t pg_off, pg_len, sum_len; - int is_hmac, ret; - u_int8_t *chksum, *iv; - - pginfo = (DB_PGINFO *)cookie->data; - pagep = (PAGE *)pp; - - ret = is_hmac = 0; - chksum = iv = NULL; - memset(&dummydb, 0, sizeof(DB)); - dbp = &dummydb; - dummydb.flags = pginfo->flags; - db_cipher = (DB_CIPHER *)dbenv->crypto_handle; - switch (pagep->type) { - case P_HASHMETA: - case P_BTREEMETA: - case P_QAMMETA: - /* - * If checksumming is set on the meta-page, we must set - * it in the dbp. - */ - if (FLD_ISSET(((DBMETA *)pp)->metaflags, DBMETA_CHKSUM)) - F_SET(dbp, DB_AM_CHKSUM); - else - F_CLR(dbp, DB_AM_CHKSUM); - if (((DBMETA *)pp)->encrypt_alg != 0 || - F_ISSET(dbp, DB_AM_ENCRYPT)) - is_hmac = 1; - /* - * !!! - * For all meta pages it is required that the chksum - * be at the same location. Use BTMETA to get to it - * for any meta type. - */ - chksum = ((BTMETA *)pp)->chksum; - sum_len = DBMETASIZE; - break; - case P_INVALID: - /* - * We assume that we've read a file hole if we have - * a zero LSN, zero page number and P_INVALID. Otherwise - * we have an invalid page that might contain real data. - */ - if (IS_ZERO_LSN(LSN(pagep)) && pagep->pgno == PGNO_INVALID) { - sum_len = 0; - break; - } - /* FALLTHROUGH */ - default: - chksum = P_CHKSUM(dbp, pagep); - sum_len = pginfo->db_pagesize; - /* - * If we are reading in a non-meta page, then if we have - * a db_cipher then we are using hmac. - */ - is_hmac = CRYPTO_ON(dbenv) ? 1 : 0; - break; - } - - /* - * We expect a checksum error if there was a configuration problem. - * If there is no configuration problem and we don't get a match, - * it's fatal: panic the system. - */ - if (F_ISSET(dbp, DB_AM_CHKSUM) && sum_len != 0) { - if (F_ISSET(dbp, DB_AM_SWAP) && is_hmac == 0) - P_32_SWAP(chksum); - switch (ret = __db_check_chksum( - dbenv, db_cipher, chksum, pp, sum_len, is_hmac)) { - case 0: - break; - case -1: - if (DBENV_LOGGING(dbenv)) - (void)__db_cksum_log( - dbenv, NULL, ¬_used, DB_FLUSH); - __db_err(dbenv, - "checksum error: page %lu: catastrophic recovery required", - (u_long)pg); - return (__db_panic(dbenv, DB_RUNRECOVERY)); - default: - return (ret); - } - } - if (F_ISSET(dbp, DB_AM_ENCRYPT)) { - DB_ASSERT(db_cipher != NULL); - DB_ASSERT(F_ISSET(dbp, DB_AM_CHKSUM)); - - pg_off = P_OVERHEAD(dbp); - DB_ASSERT(db_cipher->adj_size(pg_off) == 0); - - switch (pagep->type) { - case P_HASHMETA: - case P_BTREEMETA: - case P_QAMMETA: - /* - * !!! - * For all meta pages it is required that the iv - * be at the same location. Use BTMETA to get to it - * for any meta type. - */ - iv = ((BTMETA *)pp)->iv; - pg_len = DBMETASIZE; - break; - case P_INVALID: - if (IS_ZERO_LSN(LSN(pagep)) && - pagep->pgno == PGNO_INVALID) { - pg_len = 0; - break; - } - /* FALLTHROUGH */ - default: - iv = P_IV(dbp, pagep); - pg_len = pginfo->db_pagesize; - break; - } - if (pg_len != 0 && (ret = db_cipher->decrypt(dbenv, - db_cipher->data, iv, ((u_int8_t *)pagep) + pg_off, - pg_len - pg_off)) != 0) - return (ret); - } - switch (pagep->type) { - case P_INVALID: - if (pginfo->type == DB_QUEUE) - return (__qam_pgin_out(dbenv, pg, pp, cookie)); - else - return (__ham_pgin(dbenv, dbp, pg, pp, cookie)); - case P_HASH: - case P_HASHMETA: - return (__ham_pgin(dbenv, dbp, pg, pp, cookie)); - case P_BTREEMETA: - case P_IBTREE: - case P_IRECNO: - case P_LBTREE: - case P_LDUP: - case P_LRECNO: - case P_OVERFLOW: - return (__bam_pgin(dbenv, dbp, pg, pp, cookie)); - case P_QAMMETA: - case P_QAMDATA: - return (__qam_pgin_out(dbenv, pg, pp, cookie)); - default: - break; - } - return (__db_pgfmt(dbenv, pg)); -} - -/* - * __db_pgout -- - * Primary page-swap routine. - * - * PUBLIC: int __db_pgout __P((DB_ENV *, db_pgno_t, void *, DBT *)); - */ -int -__db_pgout(dbenv, pg, pp, cookie) - DB_ENV *dbenv; - db_pgno_t pg; - void *pp; - DBT *cookie; -{ - DB dummydb, *dbp; - DB_CIPHER *db_cipher; - DB_PGINFO *pginfo; - PAGE *pagep; - size_t pg_off, pg_len, sum_len; - int ret; - u_int8_t *chksum, *iv, *key; - - pginfo = (DB_PGINFO *)cookie->data; - pagep = (PAGE *)pp; - - chksum = iv = key = NULL; - memset(&dummydb, 0, sizeof(DB)); - dbp = &dummydb; - dummydb.flags = pginfo->flags; - ret = 0; - switch (pagep->type) { - case P_INVALID: - if (pginfo->type == DB_QUEUE) - ret = __qam_pgin_out(dbenv, pg, pp, cookie); - else - ret = __ham_pgout(dbenv, dbp, pg, pp, cookie); - break; - case P_HASH: - case P_HASHMETA: - ret = __ham_pgout(dbenv, dbp, pg, pp, cookie); - break; - case P_BTREEMETA: - case P_IBTREE: - case P_IRECNO: - case P_LBTREE: - case P_LDUP: - case P_LRECNO: - case P_OVERFLOW: - ret = __bam_pgout(dbenv, dbp, pg, pp, cookie); - break; - case P_QAMMETA: - case P_QAMDATA: - ret = __qam_pgin_out(dbenv, pg, pp, cookie); - break; - default: - return (__db_pgfmt(dbenv, pg)); - } - if (ret) - return (ret); - - db_cipher = (DB_CIPHER *)dbenv->crypto_handle; - if (F_ISSET(dbp, DB_AM_ENCRYPT)) { - - DB_ASSERT(db_cipher != NULL); - DB_ASSERT(F_ISSET(dbp, DB_AM_CHKSUM)); - - pg_off = P_OVERHEAD(dbp); - DB_ASSERT(db_cipher->adj_size(pg_off) == 0); - - key = db_cipher->mac_key; - - switch (pagep->type) { - case P_HASHMETA: - case P_BTREEMETA: - case P_QAMMETA: - /* - * !!! - * For all meta pages it is required that the iv - * be at the same location. Use BTMETA to get to it - * for any meta type. - */ - iv = ((BTMETA *)pp)->iv; - pg_len = DBMETASIZE; - break; - default: - iv = P_IV(dbp, pagep); - pg_len = pginfo->db_pagesize; - break; - } - if ((ret = db_cipher->encrypt(dbenv, db_cipher->data, - iv, ((u_int8_t *)pagep) + pg_off, pg_len - pg_off)) != 0) - return (ret); - } - if (F_ISSET(dbp, DB_AM_CHKSUM)) { - switch (pagep->type) { - case P_HASHMETA: - case P_BTREEMETA: - case P_QAMMETA: - /* - * !!! - * For all meta pages it is required that the chksum - * be at the same location. Use BTMETA to get to it - * for any meta type. - */ - chksum = ((BTMETA *)pp)->chksum; - sum_len = DBMETASIZE; - break; - default: - chksum = P_CHKSUM(dbp, pagep); - sum_len = pginfo->db_pagesize; - break; - } - __db_chksum(pp, sum_len, key, chksum); - if (F_ISSET(dbp, DB_AM_SWAP) && !F_ISSET(dbp, DB_AM_ENCRYPT)) - P_32_SWAP(chksum); - } - return (0); -} - -/* - * __db_metaswap -- - * Byteswap the common part of the meta-data page. - * - * PUBLIC: void __db_metaswap __P((PAGE *)); - */ -void -__db_metaswap(pg) - PAGE *pg; -{ - u_int8_t *p; - - p = (u_int8_t *)pg; - - /* Swap the meta-data information. */ - SWAP32(p); /* lsn.file */ - SWAP32(p); /* lsn.offset */ - SWAP32(p); /* pgno */ - SWAP32(p); /* magic */ - SWAP32(p); /* version */ - SWAP32(p); /* pagesize */ - p += 4; /* unused, page type, unused, unused */ - SWAP32(p); /* free */ - SWAP32(p); /* alloc_lsn part 1 */ - SWAP32(p); /* alloc_lsn part 2 */ - SWAP32(p); /* cached key count */ - SWAP32(p); /* cached record count */ - SWAP32(p); /* flags */ -} - -/* - * __db_byteswap -- - * Byteswap a page. - * - * PUBLIC: int __db_byteswap - * PUBLIC: __P((DB_ENV *, DB *, db_pgno_t, PAGE *, size_t, int)); - */ -int -__db_byteswap(dbenv, dbp, pg, h, pagesize, pgin) - DB_ENV *dbenv; - DB *dbp; - db_pgno_t pg; - PAGE *h; - size_t pagesize; - int pgin; -{ - BINTERNAL *bi; - BKEYDATA *bk; - BOVERFLOW *bo; - RINTERNAL *ri; - db_indx_t i, *inp, len, tmp; - u_int8_t *p, *end; - - COMPQUIET(pg, 0); - - inp = P_INP(dbp, h); - if (pgin) { - M_32_SWAP(h->lsn.file); - M_32_SWAP(h->lsn.offset); - M_32_SWAP(h->pgno); - M_32_SWAP(h->prev_pgno); - M_32_SWAP(h->next_pgno); - M_16_SWAP(h->entries); - M_16_SWAP(h->hf_offset); - } - - switch (h->type) { - case P_HASH: - for (i = 0; i < NUM_ENT(h); i++) { - if (pgin) - M_16_SWAP(inp[i]); - - switch (HPAGE_TYPE(dbp, h, i)) { - case H_KEYDATA: - break; - case H_DUPLICATE: - len = LEN_HKEYDATA(dbp, h, pagesize, i); - p = HKEYDATA_DATA(P_ENTRY(dbp, h, i)); - for (end = p + len; p < end;) { - if (pgin) { - P_16_SWAP(p); - memcpy(&tmp, - p, sizeof(db_indx_t)); - p += sizeof(db_indx_t); - } else { - memcpy(&tmp, - p, sizeof(db_indx_t)); - SWAP16(p); - } - p += tmp; - SWAP16(p); - } - break; - case H_OFFDUP: - p = HOFFPAGE_PGNO(P_ENTRY(dbp, h, i)); - SWAP32(p); /* pgno */ - break; - case H_OFFPAGE: - p = HOFFPAGE_PGNO(P_ENTRY(dbp, h, i)); - SWAP32(p); /* pgno */ - SWAP32(p); /* tlen */ - break; - default: - return (__db_pgfmt(dbenv, pg)); - } - - } - - /* - * The offsets in the inp array are used to determine - * the size of entries on a page; therefore they - * cannot be converted until we've done all the - * entries. - */ - if (!pgin) - for (i = 0; i < NUM_ENT(h); i++) - M_16_SWAP(inp[i]); - break; - case P_LBTREE: - case P_LDUP: - case P_LRECNO: - for (i = 0; i < NUM_ENT(h); i++) { - if (pgin) - M_16_SWAP(inp[i]); - - /* - * In the case of on-page duplicates, key information - * should only be swapped once. - */ - if (h->type == P_LBTREE && i > 1) { - if (pgin) { - if (inp[i] == inp[i - 2]) - continue; - } else { - M_16_SWAP(inp[i]); - if (inp[i] == inp[i - 2]) - continue; - M_16_SWAP(inp[i]); - } - } - - bk = GET_BKEYDATA(dbp, h, i); - switch (B_TYPE(bk->type)) { - case B_KEYDATA: - M_16_SWAP(bk->len); - break; - case B_DUPLICATE: - case B_OVERFLOW: - bo = (BOVERFLOW *)bk; - M_32_SWAP(bo->pgno); - M_32_SWAP(bo->tlen); - break; - default: - return (__db_pgfmt(dbenv, pg)); - } - - if (!pgin) - M_16_SWAP(inp[i]); - } - break; - case P_IBTREE: - for (i = 0; i < NUM_ENT(h); i++) { - if (pgin) - M_16_SWAP(inp[i]); - - bi = GET_BINTERNAL(dbp, h, i); - M_16_SWAP(bi->len); - M_32_SWAP(bi->pgno); - M_32_SWAP(bi->nrecs); - - switch (B_TYPE(bi->type)) { - case B_KEYDATA: - break; - case B_DUPLICATE: - case B_OVERFLOW: - bo = (BOVERFLOW *)bi->data; - M_32_SWAP(bo->pgno); - M_32_SWAP(bo->tlen); - break; - default: - return (__db_pgfmt(dbenv, pg)); - } - - if (!pgin) - M_16_SWAP(inp[i]); - } - break; - case P_IRECNO: - for (i = 0; i < NUM_ENT(h); i++) { - if (pgin) - M_16_SWAP(inp[i]); - - ri = GET_RINTERNAL(dbp, h, i); - M_32_SWAP(ri->pgno); - M_32_SWAP(ri->nrecs); - - if (!pgin) - M_16_SWAP(inp[i]); - } - break; - case P_OVERFLOW: - case P_INVALID: - /* Nothing to do. */ - break; - default: - return (__db_pgfmt(dbenv, pg)); - } - - if (!pgin) { - /* Swap the header information. */ - M_32_SWAP(h->lsn.file); - M_32_SWAP(h->lsn.offset); - M_32_SWAP(h->pgno); - M_32_SWAP(h->prev_pgno); - M_32_SWAP(h->next_pgno); - M_16_SWAP(h->entries); - M_16_SWAP(h->hf_offset); - } - return (0); -} diff --git a/storage/bdb/db/db_dispatch.c b/storage/bdb/db/db_dispatch.c deleted file mode 100644 index 3c56b556219..00000000000 --- a/storage/bdb/db/db_dispatch.c +++ /dev/null @@ -1,1603 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1995, 1996 - * The President and Fellows of Harvard University. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Margo Seltzer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: db_dispatch.c,v 12.12 2005/11/10 21:11:42 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#ifndef HAVE_FTRUNCATE -#include "dbinc/db_shash.h" -#endif -#include "dbinc/hash.h" -#ifndef HAVE_FTRUNCATE -#include "dbinc/lock.h" -#include "dbinc/mp.h" -#endif -#include "dbinc/log.h" -#include "dbinc/fop.h" -#include "dbinc/txn.h" - -#ifndef HAVE_FTRUNCATE -static int __db_limbo_fix __P((DB *, DB_TXN *, - DB_TXNLIST *, db_pgno_t *, DBMETA *, db_limbo_state)); -static int __db_limbo_bucket __P((DB_ENV *, - DB_TXN *, DB_TXNLIST *, db_limbo_state)); -static int __db_limbo_move __P((DB_ENV *, DB_TXN *, DB_TXN *, DB_TXNLIST *)); -static int __db_limbo_prepare __P(( DB *, DB_TXN *, DB_TXNLIST *)); -static int __db_lock_move __P((DB_ENV *, - u_int8_t *, db_pgno_t, db_lockmode_t, DB_TXN *, DB_TXN *)); -static int __db_txnlist_pgnoadd __P((DB_ENV *, DB_TXNHEAD *, - int32_t, u_int8_t *, char *, db_pgno_t)); -#endif -static int __db_txnlist_find_internal __P((DB_ENV *, DB_TXNHEAD *, - db_txnlist_type, u_int32_t, u_int8_t *, DB_TXNLIST **, - int, u_int32_t *)); - -/* - * __db_dispatch -- - * - * This is the transaction dispatch function used by the db access methods. - * It is designed to handle the record format used by all the access - * methods (the one automatically generated by the db_{h,log,read}.sh - * scripts in the tools directory). An application using a different - * recovery paradigm will supply a different dispatch function to txn_open. - * - * PUBLIC: int __db_dispatch __P((DB_ENV *, - * PUBLIC: int (**)__P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)), - * PUBLIC: size_t, DBT *, DB_LSN *, db_recops, DB_TXNHEAD *)); - */ -int -__db_dispatch(dbenv, dtab, dtabsize, db, lsnp, redo, info) - DB_ENV *dbenv; /* The environment. */ - int (**dtab)__P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - size_t dtabsize; /* Size of the dtab. */ - DBT *db; /* The log record upon which to dispatch. */ - DB_LSN *lsnp; /* The lsn of the record being dispatched. */ - db_recops redo; /* Redo this op (or undo it). */ - DB_TXNHEAD *info; /* Transaction list. */ -{ - DB_LSN prev_lsn; - u_int32_t rectype, status, txnid; - int make_call, ret; - - memcpy(&rectype, db->data, sizeof(rectype)); - memcpy(&txnid, (u_int8_t *)db->data + sizeof(rectype), sizeof(txnid)); - make_call = ret = 0; - - /* If we don't have a dispatch table, it's hard to dispatch. */ - DB_ASSERT(dtab != NULL); - - /* - * If we find a record that is in the user's number space and they - * have specified a recovery routine, let them handle it. If they - * didn't specify a recovery routine, then we expect that they've - * followed all our rules and registered new recovery functions. - */ - switch (redo) { - case DB_TXN_ABORT: - case DB_TXN_APPLY: - case DB_TXN_PRINT: - make_call = 1; - break; - case DB_TXN_OPENFILES: - /* - * We collect all the transactions that have - * "begin" records, those with no previous LSN, - * so that we do not abort partial transactions. - * These are known to be undone, otherwise the - * log would not have been freeable. - */ - memcpy(&prev_lsn, (u_int8_t *)db->data + - sizeof(rectype) + sizeof(txnid), sizeof(prev_lsn)); - if (txnid != 0 && prev_lsn.file == 0 && (ret = - __db_txnlist_add(dbenv, info, txnid, TXN_OK, NULL)) != 0) - return (ret); - - /* FALLTHROUGH */ - case DB_TXN_POPENFILES: - if (rectype == DB___dbreg_register || - rectype == DB___txn_child || - rectype == DB___txn_ckp || rectype == DB___txn_recycle) - return (dtab[rectype](dbenv, db, lsnp, redo, info)); - break; - case DB_TXN_BACKWARD_ROLL: - /* - * Running full recovery in the backward pass. In general, - * we only process records during this pass that belong - * to aborted transactions. Unfortunately, there are several - * exceptions: - * 1. If this is a meta-record, one not associated with - * a transaction, then we must always process it. - * 2. If this is a transaction commit/abort, we must - * always process it, so that we know the status of - * every transaction. - * 3. If this is a child commit, we need to process it - * because the outcome of the child transaction depends - * on the outcome of the parent. - * 4. If this is a dbreg_register record, we must always - * process is because they contain non-transactional - * closes that must be properly handled. - * 5. If this is a noop, we must always undo it so that we - * properly handle any aborts before a file was closed. - * 6. If this a file remove, we need to process it to - * determine if the on-disk file is the same as the - * one being described. - */ - switch (rectype) { - /* - * These either do not belong to a transaction or (regop) - * must be processed regardless of the status of the - * transaction. - */ - case DB___txn_regop: - case DB___txn_recycle: - case DB___txn_ckp: - make_call = 1; - break; - /* - * These belong to a transaction whose status must be - * checked. - */ - case DB___txn_child: - case DB___db_noop: - case DB___fop_file_remove: - case DB___dbreg_register: - make_call = 1; - - /* FALLTHROUGH */ - default: - if (txnid == 0) - break; - - ret = __db_txnlist_find(dbenv, info, txnid, &status); - - /* If not found, this is an incomplete abort. */ - if (ret == DB_NOTFOUND) - return (__db_txnlist_add(dbenv, - info, txnid, TXN_IGNORE, lsnp)); - if (ret != 0) - return (ret); - - /* - * If we ignore the transaction, ignore the operation - * UNLESS this is a child commit in which case we need - * to make sure that the child also gets marked as - * ignore. - */ - if (status == TXN_IGNORE && rectype != DB___txn_child) { - make_call = 0; - break; - } - if (status == TXN_COMMIT) - break; - - /* Set make_call in case we came through default */ - make_call = 1; - if (status == TXN_OK && - (ret = __db_txnlist_update(dbenv, - info, txnid, rectype == DB___txn_xa_regop ? - TXN_PREPARE : TXN_ABORT, NULL, &status, 0)) != 0) - return (ret); - } - break; - case DB_TXN_FORWARD_ROLL: - /* - * In the forward pass, if we haven't seen the transaction, - * do nothing, else recover it. - * - * We need to always redo DB___db_noop records, so that we - * properly handle any commits after the file was closed. - */ - switch (rectype) { - case DB___txn_recycle: - case DB___txn_ckp: - case DB___db_noop: - make_call = 1; - break; - - default: - if (txnid == 0) - status = 0; - else { - ret = __db_txnlist_find(dbenv, - info, txnid, &status); - - if (ret == DB_NOTFOUND) - /* Break out out of if clause. */ - ; - else if (ret != 0) - return (ret); - else if (status == TXN_COMMIT) { - make_call = 1; - break; - } - } - -#ifndef HAVE_FTRUNCATE - if (status != TXN_IGNORE && - (rectype == DB___ham_metagroup || - rectype == DB___ham_groupalloc || - rectype == DB___db_pg_alloc)) { - /* - * Because we do not have truncate - * all allocation records must be reprocessed - * during rollforward in case the file was - * just created. It may not have been - * present during the backward pass. - */ - make_call = 1; - redo = DB_TXN_BACKWARD_ALLOC; - } else -#endif - if (rectype == DB___dbreg_register) { - /* - * This may be a transaction dbreg_register. - * If it is, we only make the call on a COMMIT, - * which we checked above. If it's not, then we - * should always make the call, because we need - * the file open information. - */ - if (txnid == 0) - make_call = 1; - } - } - break; - case DB_TXN_BACKWARD_ALLOC: - default: - return (__db_unknown_flag( - dbenv, "__db_dispatch", (u_int32_t)redo)); - } - - if (make_call) { - /* - * If the debug flag is set then we are logging - * records for a non-durable update so that they - * may be examined for diagnostic purposes. - * So only make the call if we are printing, - * otherwise we need to extract the previous - * lsn so undo will work properly. - */ - if (rectype & DB_debug_FLAG) { - if (redo == DB_TXN_PRINT) - rectype &= ~DB_debug_FLAG; - else { - memcpy(lsnp, - (u_int8_t *)db->data + - sizeof(rectype) + - sizeof(txnid), sizeof(*lsnp)); - return (0); - } - } - if (rectype >= DB_user_BEGIN && dbenv->app_dispatch != NULL) - return (dbenv->app_dispatch(dbenv, db, lsnp, redo)); - else { - /* - * The size of the dtab table argument is the same as - * the standard table, use the standard table's size - * as our sanity check. - */ - if (rectype > dtabsize || dtab[rectype] == NULL) { - __db_err(dbenv, - "Illegal record type %lu in log", - (u_long)rectype); - return (EINVAL); - } - return (dtab[rectype](dbenv, db, lsnp, redo, info)); - } - } - - return (0); -} - -/* - * __db_add_recovery -- - * - * PUBLIC: int __db_add_recovery __P((DB_ENV *, - * PUBLIC: int (***)(DB_ENV *, DBT *, DB_LSN *, db_recops, void *), size_t *, - * PUBLIC: int (*)(DB_ENV *, DBT *, DB_LSN *, db_recops, void *), u_int32_t)); - */ -int -__db_add_recovery(dbenv, dtab, dtabsize, func, ndx) - DB_ENV *dbenv; - int (***dtab) __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - size_t *dtabsize; - int (*func) __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - u_int32_t ndx; -{ - size_t i, nsize; - int ret; - - /* Check if we have to grow the table. */ - if (ndx >= *dtabsize) { - nsize = ndx + 40; - if ((ret = - __os_realloc(dbenv, nsize * sizeof((*dtab)[0]), dtab)) != 0) - return (ret); - for (i = *dtabsize; i < nsize; ++i) - (*dtab)[i] = NULL; - *dtabsize = nsize; - } - - (*dtab)[ndx] = func; - return (0); -} - -/* - * __db_txnlist_init -- - * Initialize transaction linked list. - * - * PUBLIC: int __db_txnlist_init __P((DB_ENV *, - * PUBLIC: u_int32_t, u_int32_t, DB_LSN *, DB_TXNHEAD **)); - */ -int -__db_txnlist_init(dbenv, low_txn, hi_txn, trunc_lsn, retp) - DB_ENV *dbenv; - u_int32_t low_txn, hi_txn; - DB_LSN *trunc_lsn; - DB_TXNHEAD **retp; -{ - DB_TXNHEAD *headp; - u_int32_t size, tmp; - int ret; - - /* - * Size a hash table. - * If low is zero then we are being called during rollback - * and we need only one slot. - * Hi maybe lower than low if we have recycled txnid's. - * The numbers here are guesses about txn density, we can afford - * to look at a few entries in each slot. - */ - if (low_txn == 0) - size = 1; - else { - if (hi_txn < low_txn) { - tmp = hi_txn; - hi_txn = low_txn; - low_txn = tmp; - } - tmp = hi_txn - low_txn; - /* See if we wrapped around. */ - if (tmp > (TXN_MAXIMUM - TXN_MINIMUM) / 2) - tmp = (low_txn - TXN_MINIMUM) + (TXN_MAXIMUM - hi_txn); - size = tmp / 5; - if (size < 100) - size = 100; - } - if ((ret = __os_malloc(dbenv, - sizeof(DB_TXNHEAD) + size * sizeof(headp->head), &headp)) != 0) - return (ret); - - memset(headp, 0, sizeof(DB_TXNHEAD) + size * sizeof(headp->head)); - headp->maxid = hi_txn; - headp->generation = 0; - headp->nslots = size; - headp->gen_alloc = 8; - if ((ret = __os_malloc(dbenv, headp->gen_alloc * - sizeof(headp->gen_array[0]), &headp->gen_array)) != 0) { - __os_free(dbenv, headp); - return (ret); - } - headp->gen_array[0].generation = 0; - headp->gen_array[0].txn_min = TXN_MINIMUM; - headp->gen_array[0].txn_max = TXN_MAXIMUM; - if (trunc_lsn != NULL) { - headp->trunc_lsn = *trunc_lsn; - headp->maxlsn = *trunc_lsn; - } else { - ZERO_LSN(headp->trunc_lsn); - ZERO_LSN(headp->maxlsn); - } - ZERO_LSN(headp->ckplsn); - - *retp = headp; - return (0); -} - -/* - * __db_txnlist_add -- - * Add an element to our transaction linked list. - * - * PUBLIC: int __db_txnlist_add __P((DB_ENV *, - * PUBLIC: DB_TXNHEAD *, u_int32_t, u_int32_t, DB_LSN *)); - */ -int -__db_txnlist_add(dbenv, hp, txnid, status, lsn) - DB_ENV *dbenv; - DB_TXNHEAD *hp; - u_int32_t txnid, status; - DB_LSN *lsn; -{ - DB_TXNLIST *elp; - int ret; - - if ((ret = __os_malloc(dbenv, sizeof(DB_TXNLIST), &elp)) != 0) - return (ret); - - LIST_INSERT_HEAD(&hp->head[DB_TXNLIST_MASK(hp, txnid)], elp, links); - - elp->type = TXNLIST_TXNID; - elp->u.t.txnid = txnid; - elp->u.t.status = status; - elp->u.t.generation = hp->generation; - if (txnid > hp->maxid) - hp->maxid = txnid; - if (lsn != NULL && IS_ZERO_LSN(hp->maxlsn) && status == TXN_COMMIT) - hp->maxlsn = *lsn; - - DB_ASSERT(lsn == NULL || - status != TXN_COMMIT || log_compare(&hp->maxlsn, lsn) >= 0); - - return (0); -} - -/* - * __db_txnlist_remove -- - * Remove an element from our transaction linked list. - * - * PUBLIC: int __db_txnlist_remove __P((DB_ENV *, DB_TXNHEAD *, u_int32_t)); - */ -int -__db_txnlist_remove(dbenv, hp, txnid) - DB_ENV *dbenv; - DB_TXNHEAD *hp; - u_int32_t txnid; -{ - DB_TXNLIST *entry; - u_int32_t status; - - return (__db_txnlist_find_internal(dbenv, - hp, TXNLIST_TXNID, txnid, NULL, &entry, 1, &status)); -} - -/* - * __db_txnlist_ckp -- - * Used to record the maximum checkpoint that will be retained - * after recovery. Typically this is simply the max checkpoint, but - * if we are doing client replication recovery or timestamp-based - * recovery, we are going to virtually truncate the log and we need - * to retain the last checkpoint before the truncation point. - * - * PUBLIC: void __db_txnlist_ckp __P((DB_ENV *, DB_TXNHEAD *, DB_LSN *)); - */ -void -__db_txnlist_ckp(dbenv, hp, ckp_lsn) - DB_ENV *dbenv; - DB_TXNHEAD *hp; - DB_LSN *ckp_lsn; -{ - - COMPQUIET(dbenv, NULL); - - if (IS_ZERO_LSN(hp->ckplsn) && !IS_ZERO_LSN(hp->maxlsn) && - log_compare(&hp->maxlsn, ckp_lsn) >= 0) - hp->ckplsn = *ckp_lsn; -} - -/* - * __db_txnlist_end -- - * Discard transaction linked list. - * - * PUBLIC: void __db_txnlist_end __P((DB_ENV *, DB_TXNHEAD *)); - */ -void -__db_txnlist_end(dbenv, hp) - DB_ENV *dbenv; - DB_TXNHEAD *hp; -{ - u_int32_t i; - DB_TXNLIST *p; - - if (hp == NULL) - return; - - for (i = 0; i < hp->nslots; i++) - while (hp != NULL && (p = LIST_FIRST(&hp->head[i])) != NULL) { - switch (p->type) { - case TXNLIST_LSN: - __os_free(dbenv, p->u.l.lsn_stack); - break; - case TXNLIST_DELETE: - case TXNLIST_PGNO: - case TXNLIST_TXNID: - default: - /* - * Possibly an incomplete DB_TXNLIST; just - * free it. - */ - break; - } - LIST_REMOVE(p, links); - __os_free(dbenv, p); - } - - if (hp->gen_array != NULL) - __os_free(dbenv, hp->gen_array); - __os_free(dbenv, hp); -} - -/* - * __db_txnlist_find -- - * Checks to see if a txnid with the current generation is in the - * txnid list. This returns DB_NOTFOUND if the item isn't in the - * list otherwise it returns (like __db_txnlist_find_internal) - * the status of the transaction. A txnid of 0 means the record - * was generated while not in a transaction. - * - * PUBLIC: int __db_txnlist_find __P((DB_ENV *, - * PUBLIC: DB_TXNHEAD *, u_int32_t, u_int32_t *)); - */ -int -__db_txnlist_find(dbenv, hp, txnid, statusp) - DB_ENV *dbenv; - DB_TXNHEAD *hp; - u_int32_t txnid, *statusp; -{ - DB_TXNLIST *entry; - - if (txnid == 0) - return (DB_NOTFOUND); - - return (__db_txnlist_find_internal(dbenv, hp, - TXNLIST_TXNID, txnid, NULL, &entry, 0, statusp)); -} - -/* - * __db_txnlist_update -- - * Change the status of an existing transaction entry. - * Returns DB_NOTFOUND if no such entry exists. - * - * PUBLIC: int __db_txnlist_update __P((DB_ENV *, DB_TXNHEAD *, - * PUBLIC: u_int32_t, u_int32_t, DB_LSN *, u_int32_t *, int)); - */ -int -__db_txnlist_update(dbenv, hp, txnid, status, lsn, ret_status, add_ok) - DB_ENV *dbenv; - DB_TXNHEAD *hp; - u_int32_t txnid, status; - DB_LSN *lsn; - u_int32_t *ret_status; - int add_ok; -{ - DB_TXNLIST *elp; - int ret; - - if (txnid == 0) - return (DB_NOTFOUND); - - ret = __db_txnlist_find_internal(dbenv, - hp, TXNLIST_TXNID, txnid, NULL, &elp, 0, ret_status); - - if (ret == DB_NOTFOUND && add_ok) { - *ret_status = status; - return (__db_txnlist_add(dbenv, hp, txnid, status, lsn)); - } - if (ret != 0) - return (ret); - - if (*ret_status == TXN_IGNORE) - return (0); - - elp->u.t.status = status; - - if (lsn != NULL && IS_ZERO_LSN(hp->maxlsn) && status == TXN_COMMIT) - hp->maxlsn = *lsn; - - return (ret); -} - -/* - * __db_txnlist_find_internal -- - * Find an entry on the transaction list. If the entry is not there or - * the list pointer is not initialized we return DB_NOTFOUND. If the - * item is found, we return the status. Currently we always call this - * with an initialized list pointer but checking for NULL keeps it general. - */ -static int -__db_txnlist_find_internal(dbenv, - hp, type, txnid, uid, txnlistp, delete, statusp) - DB_ENV *dbenv; - DB_TXNHEAD *hp; - db_txnlist_type type; - u_int32_t txnid; - u_int8_t uid[DB_FILE_ID_LEN]; - DB_TXNLIST **txnlistp; - int delete; - u_int32_t *statusp; -{ - struct __db_headlink *head; - DB_TXNLIST *p; - u_int32_t generation, hash, i; - int ret; - - ret = 0; - - if (hp == NULL) - return (DB_NOTFOUND); - - switch (type) { - case TXNLIST_TXNID: - hash = txnid; - /* Find the most recent generation containing this ID */ - for (i = 0; i <= hp->generation; i++) - /* The range may wrap around the end. */ - if (hp->gen_array[i].txn_min < - hp->gen_array[i].txn_max ? - (txnid >= hp->gen_array[i].txn_min && - txnid <= hp->gen_array[i].txn_max) : - (txnid >= hp->gen_array[i].txn_min || - txnid <= hp->gen_array[i].txn_max)) - break; - DB_ASSERT(i <= hp->generation); - generation = hp->gen_array[i].generation; - break; - case TXNLIST_PGNO: - memcpy(&hash, uid, sizeof(hash)); - generation = 0; - break; - case TXNLIST_DELETE: - case TXNLIST_LSN: - default: - return (__db_panic(dbenv, EINVAL)); - } - - head = &hp->head[DB_TXNLIST_MASK(hp, hash)]; - - for (p = LIST_FIRST(head); p != NULL; p = LIST_NEXT(p, links)) { - if (p->type != type) - continue; - switch (type) { - case TXNLIST_TXNID: - if (p->u.t.txnid != txnid || - generation != p->u.t.generation) - continue; - *statusp = p->u.t.status; - break; - - case TXNLIST_PGNO: - if (memcmp(uid, p->u.p.uid, DB_FILE_ID_LEN) != 0) - continue; - break; - case TXNLIST_DELETE: - case TXNLIST_LSN: - default: - return (__db_panic(dbenv, EINVAL)); - } - if (delete == 1) { - LIST_REMOVE(p, links); - __os_free(dbenv, p); - *txnlistp = NULL; - } else if (p != LIST_FIRST(head)) { - /* Move it to head of list. */ - LIST_REMOVE(p, links); - LIST_INSERT_HEAD(head, p, links); - *txnlistp = p; - } else - *txnlistp = p; - return (ret); - } - - return (DB_NOTFOUND); -} - -/* - * __db_txnlist_gen -- - * Change the current generation number. - * - * PUBLIC: int __db_txnlist_gen __P((DB_ENV *, - * PUBLIC: DB_TXNHEAD *, int, u_int32_t, u_int32_t)); - */ -int -__db_txnlist_gen(dbenv, hp, incr, min, max) - DB_ENV *dbenv; - DB_TXNHEAD *hp; - int incr; - u_int32_t min, max; -{ - int ret; - - /* - * During recovery generation numbers keep track of "restart" - * checkpoints and recycle records. Restart checkpoints occur - * whenever we take a checkpoint and there are no outstanding - * transactions. When that happens, we can reset transaction IDs - * back to TXNID_MINIMUM. Currently we only do the reset - * at then end of recovery. Recycle records occur when txnids - * are exhausted during runtime. A free range of ids is identified - * and logged. This code maintains a stack of ranges. A txnid - * is given the generation number of the first range it falls into - * in the stack. - */ - if (incr < 0) { - --hp->generation; - memmove(hp->gen_array, &hp->gen_array[1], - (hp->generation + 1) * sizeof(hp->gen_array[0])); - } else { - ++hp->generation; - if (hp->generation >= hp->gen_alloc) { - hp->gen_alloc *= 2; - if ((ret = __os_realloc(dbenv, hp->gen_alloc * - sizeof(hp->gen_array[0]), &hp->gen_array)) != 0) - return (ret); - } - memmove(&hp->gen_array[1], &hp->gen_array[0], - hp->generation * sizeof(hp->gen_array[0])); - hp->gen_array[0].generation = hp->generation; - hp->gen_array[0].txn_min = min; - hp->gen_array[0].txn_max = max; - } - return (0); -} - -/* - * __db_txnlist_lsnadd -- - * Save the prev_lsn from a txn_child record. - * - * PUBLIC: int __db_txnlist_lsnadd __P((DB_ENV *, DB_TXNHEAD *, DB_LSN *)); - */ -int -__db_txnlist_lsnadd(dbenv, hp, lsnp) - DB_ENV *dbenv; - DB_TXNHEAD *hp; - DB_LSN *lsnp; -{ - DB_TXNLIST *elp; - int ret; - - if (IS_ZERO_LSN(*lsnp)) - return (0); - - for (elp = LIST_FIRST(&hp->head[0]); - elp != NULL; elp = LIST_NEXT(elp, links)) - if (elp->type == TXNLIST_LSN) - break; - - if (elp == NULL) { - if ((ret = __db_txnlist_lsninit(dbenv, hp, lsnp)) != 0) - return (ret); - return (DB_SURPRISE_KID); - } - - if (elp->u.l.stack_indx == elp->u.l.stack_size) { - elp->u.l.stack_size <<= 1; - if ((ret = __os_realloc(dbenv, sizeof(DB_LSN) * - elp->u.l.stack_size, &elp->u.l.lsn_stack)) != 0) { - __db_txnlist_end(dbenv, hp); - return (ret); - } - } - elp->u.l.lsn_stack[elp->u.l.stack_indx++] = *lsnp; - - return (0); -} - -/* - * __db_txnlist_lsnget -- - * - * PUBLIC: int __db_txnlist_lsnget __P((DB_ENV *, - * PUBLIC: DB_TXNHEAD *, DB_LSN *, u_int32_t)); - * Get the lsn saved from a txn_child record. - */ -int -__db_txnlist_lsnget(dbenv, hp, lsnp, flags) - DB_ENV *dbenv; - DB_TXNHEAD *hp; - DB_LSN *lsnp; - u_int32_t flags; -{ - DB_TXNLIST *elp; - - COMPQUIET(dbenv, NULL); - COMPQUIET(flags, 0); - - for (elp = LIST_FIRST(&hp->head[0]); - elp != NULL; elp = LIST_NEXT(elp, links)) - if (elp->type == TXNLIST_LSN) - break; - - if (elp == NULL || elp->u.l.stack_indx == 0) { - ZERO_LSN(*lsnp); - return (0); - } - - *lsnp = elp->u.l.lsn_stack[--elp->u.l.stack_indx]; - - return (0); -} - -/* - * __db_txnlist_lsninit -- - * Initialize a transaction list with an lsn array entry. - * - * PUBLIC: int __db_txnlist_lsninit __P((DB_ENV *, DB_TXNHEAD *, DB_LSN *)); - */ -int -__db_txnlist_lsninit(dbenv, hp, lsnp) - DB_ENV *dbenv; - DB_TXNHEAD *hp; - DB_LSN *lsnp; -{ - DB_TXNLIST *elp; - int ret; - - elp = NULL; - - if ((ret = __os_malloc(dbenv, sizeof(DB_TXNLIST), &elp)) != 0) - goto err; - LIST_INSERT_HEAD(&hp->head[0], elp, links); - - elp->type = TXNLIST_LSN; - if ((ret = __os_malloc(dbenv, - sizeof(DB_LSN) * DB_LSN_STACK_SIZE, &elp->u.l.lsn_stack)) != 0) - goto err; - elp->u.l.stack_indx = 1; - elp->u.l.stack_size = DB_LSN_STACK_SIZE; - elp->u.l.lsn_stack[0] = *lsnp; - - return (0); - -err: __db_txnlist_end(dbenv, hp); - return (ret); -} - -#ifndef HAVE_FTRUNCATE -/* - * __db_add_limbo -- add pages to the limbo list. - * Get the file information and call pgnoadd for each page. - * - * PUBLIC: #ifndef HAVE_FTRUNCATE - * PUBLIC: int __db_add_limbo __P((DB_ENV *, - * PUBLIC: DB_TXNHEAD *, int32_t, db_pgno_t, int32_t)); - * PUBLIC: #endif - */ -int -__db_add_limbo(dbenv, hp, fileid, pgno, count) - DB_ENV *dbenv; - DB_TXNHEAD *hp; - int32_t fileid; - db_pgno_t pgno; - int32_t count; -{ - DB_LOG *dblp; - FNAME *fnp; - int ret; - - dblp = dbenv->lg_handle; - if ((ret = __dbreg_id_to_fname(dblp, fileid, 0, &fnp)) != 0) - return (ret); - - do { - if ((ret = - __db_txnlist_pgnoadd(dbenv, hp, fileid, fnp->ufid, - R_ADDR(&dblp->reginfo, fnp->name_off), pgno)) != 0) - return (ret); - pgno++; - } while (--count != 0); - - return (0); -} - -/* - * __db_do_the_limbo -- move pages from limbo to free. - * - * Limbo processing is what ensures that we correctly handle and - * recover from page allocations. During recovery, for each database, - * we process each in-question allocation, link them into the free list - * and then write out the new meta-data page that contains the pointer - * to the new beginning of the free list. On an abort, we use our - * standard __db_free mechanism in a compensating transaction which logs - * the specific modifications to the free list. - * - * If we run out of log space during an abort, then we can't write the - * compensating transaction, so we abandon the idea of a compensating - * transaction, and go back to processing how we do during recovery. - * The reason that this is not the norm is that it's expensive: it requires - * that we flush any database with an in-question allocation. Thus if - * a compensating transaction fails, we never try to restart it. - * - * Since files may be open and closed within transactions (in particular, - * the master database for subdatabases), we must be prepared to open - * files during this process. If there is a compensating transaction, we - * can open the files in that transaction. If this was an abort and there - * is no compensating transaction, then we've got to perform these opens - * in the context of the aborting transaction so that we do not deadlock. - * During recovery, there's no locking, so this isn't an issue. - * - * What you want to keep in mind when reading this is that there are two - * algorithms going on here: ctxn == NULL, then we're either in recovery - * or our compensating transaction has failed and we're doing the - * "create list and write meta-data page" algorithm. Otherwise, we're in - * an abort and doing the "use compensating transaction" algorithm. - * - * PUBLIC: #ifndef HAVE_FTRUNCATE - * PUBLIC: int __db_do_the_limbo __P((DB_ENV *, - * PUBLIC: DB_TXN *, DB_TXN *, DB_TXNHEAD *, db_limbo_state)); - * PUBLIC: #endif - */ -int -__db_do_the_limbo(dbenv, ptxn, txn, hp, state) - DB_ENV *dbenv; - DB_TXN *ptxn, *txn; - DB_TXNHEAD *hp; - db_limbo_state state; -{ - DB_TXNLIST *elp; - u_int32_t h; - int ret; - - ret = 0; - /* - * The slots correspond to hash buckets. We've hashed the - * fileids into hash buckets and need to pick up all affected - * files. (There will only be a single slot for an abort.) - */ - for (h = 0; h < hp->nslots; h++) { - if ((elp = LIST_FIRST(&hp->head[h])) == NULL) - continue; - if (ptxn != NULL) { - if ((ret = - __db_limbo_move(dbenv, ptxn, txn, elp)) != 0) - goto err; - } else if ((ret = - __db_limbo_bucket(dbenv, txn, elp, state)) != 0) - goto err; - } - -err: if (ret != 0) { - __db_err(dbenv, "Fatal error in abort of an allocation"); - ret = __db_panic(dbenv, ret); - } - - return (ret); -} - -/* Limbo support routines. */ - -/* - * __db_lock_move -- - * Move a lock from child to parent. - */ -static int -__db_lock_move(dbenv, fileid, pgno, mode, ptxn, txn) - DB_ENV *dbenv; - u_int8_t *fileid; - db_pgno_t pgno; - db_lockmode_t mode; - DB_TXN *ptxn, *txn; -{ - DBT lock_dbt; - DB_LOCK lock; - DB_LOCK_ILOCK lock_obj; - DB_LOCKREQ req; - int ret; - - lock_obj.pgno = pgno; - memcpy(lock_obj.fileid, fileid, DB_FILE_ID_LEN); - lock_obj.type = DB_PAGE_LOCK; - - memset(&lock_dbt, 0, sizeof(lock_dbt)); - lock_dbt.data = &lock_obj; - lock_dbt.size = sizeof(lock_obj); - - if ((ret = __lock_get(dbenv, - txn->txnid, 0, &lock_dbt, mode, &lock)) == 0) { - memset(&req, 0, sizeof(req)); - req.lock = lock; - req.op = DB_LOCK_TRADE; - ret = __lock_vec(dbenv, ptxn->txnid, 0, &req, 1, NULL); - } - return (ret); -} - -/* - * __db_limbo_move - * Move just the metapage lock to the parent. - */ -static int -__db_limbo_move(dbenv, ptxn, txn, elp) - DB_ENV *dbenv; - DB_TXN *ptxn, *txn; - DB_TXNLIST *elp; -{ - int ret; - - for (; elp != NULL; elp = LIST_NEXT(elp, links)) { - if (elp->type != TXNLIST_PGNO || elp->u.p.locked == 1) - continue; - if ((ret = __db_lock_move(dbenv, elp->u.p.uid, - PGNO_BASE_MD, DB_LOCK_WRITE, ptxn, txn)) != 0) - return (ret); - elp->u.p.locked = 1; - } - - return (0); -} -/* - * __db_limbo_bucket - * Perform limbo processing for a single hash bucket in the txnlist. - * txn is the transaction aborting in the case of an abort and ctxn is the - * compensating transaction. - */ - -#define T_RESTORED(txn) ((txn) != NULL && F_ISSET(txn, TXN_RESTORED)) -static int -__db_limbo_bucket(dbenv, txn, elp, state) - DB_ENV *dbenv; - DB_TXN *txn; - DB_TXNLIST *elp; - db_limbo_state state; -{ - DB *dbp; - DB_MPOOLFILE *mpf; - DBMETA *meta; - DB_TXN *ctxn, *t; - FNAME *fname; - db_pgno_t last_pgno, pgno; - int dbp_created, in_retry, ret, t_ret; - - ctxn = NULL; - in_retry = 0; - meta = NULL; - mpf = NULL; - ret = 0; - for (; elp != NULL; elp = LIST_NEXT(elp, links)) { - if (elp->type != TXNLIST_PGNO) - continue; -retry: dbp_created = 0; - - /* - * Pick the transaction in which to potentially - * log compensations. - */ - if (state == LIMBO_PREPARE) - ctxn = txn; - else if (!in_retry && state != LIMBO_RECOVER && - state != LIMBO_TIMESTAMP && !T_RESTORED(txn) && - (ret = __txn_compensate_begin(dbenv, &ctxn)) != 0) - return (ret); - - /* - * Either use the compensating transaction or - * the one passed in, which will be null if recovering. - */ - t = ctxn == NULL ? txn : ctxn; - - /* First try to get a dbp by fileid. */ - ret = __dbreg_id_to_db(dbenv, t, &dbp, elp->u.p.fileid, 0); - - /* - * If the file was closed and reopened its id could change. - * Look it up the hard way. - */ - if (ret == DB_DELETED || ret == ENOENT || - ((ret == 0 && - memcmp(elp->u.p.uid, dbp->fileid, DB_FILE_ID_LEN) != 0))) { - if ((ret = __dbreg_fid_to_fname( - dbenv->lg_handle, elp->u.p.uid, 0, &fname)) == 0) - ret = __dbreg_id_to_db( - dbenv, t, &dbp, fname->id, 0); - } - /* - * File is being destroyed. No need to worry about - * dealing with recovery of allocations. - */ - if (ret == DB_DELETED || - (ret == 0 && F_ISSET(dbp, DB_AM_DISCARD))) - goto next; - - if (ret != 0) { - if ((ret = db_create(&dbp, dbenv, 0)) != 0) - goto err; - - /* - * This tells the system not to lock, which is always - * OK, whether this is an abort or recovery. - */ - F_SET(dbp, DB_AM_COMPENSATE); - dbp_created = 1; - - /* It is ok if the file is nolonger there. */ - ret = __db_open(dbp, t, elp->u.p.fname, NULL, - DB_UNKNOWN, DB_ODDFILESIZE, __db_omode(OWNER_RW), - PGNO_BASE_MD); - if (ret == ENOENT) - goto next; - } - - /* - * Verify that we are opening the same file that we were - * referring to when we wrote this log record. - */ - if (memcmp(elp->u.p.uid, dbp->fileid, DB_FILE_ID_LEN) != 0) - goto next; - - mpf = dbp->mpf; - last_pgno = PGNO_INVALID; - - if (meta == NULL && - (ctxn == NULL || state == LIMBO_COMPENSATE)) { - pgno = PGNO_BASE_MD; - if ((ret = __memp_fget(mpf, &pgno, 0, &meta)) != 0) - goto err; - last_pgno = meta->free; - } - - if (state == LIMBO_PREPARE) { - if ((ret = __db_limbo_prepare(dbp, ctxn, elp)) != 0) - goto err; - } else - ret = __db_limbo_fix(dbp, - ctxn, elp, &last_pgno, meta, state); - /* - * If we were doing compensating transactions, then we are - * going to hope this error was due to running out of space. - * We'll change modes (into the sync the file mode) and keep - * trying. If we weren't doing compensating transactions, - * then this is a real error and we're sunk. - */ - if (ret != 0) { - if (ret == DB_RUNRECOVERY || ctxn == NULL) - goto err; - in_retry = 1; - if ((ret = __txn_abort(ctxn)) != 0) - goto err; - ctxn = NULL; - goto retry; - } - - if (state == LIMBO_PREPARE) - ctxn = NULL; - - else if (ctxn != NULL) { - /* - * We only force compensation at the end of recovery. - * We want the txn_commit to be logged so turn - * off the recovery flag briefly. - */ - if (state == LIMBO_COMPENSATE) - F_CLR( - (DB_LOG *)dbenv->lg_handle, DBLOG_RECOVER); - ret = __txn_commit(ctxn, DB_TXN_NOSYNC); - ctxn = NULL; - if (state == LIMBO_COMPENSATE) - F_SET( - (DB_LOG *)dbenv->lg_handle, DBLOG_RECOVER); - if (ret != 0) - goto retry; - } - - /* - * This is where we handle the case where we're explicitly - * putting together a free list. We need to decide whether - * we have to write the meta-data page, and if we do, then - * we need to sync it as well. - */ - else if (last_pgno == meta->free) { - /* No change to page; just put the page back. */ - if ((ret = __memp_fput(mpf, meta, 0)) != 0) - goto err; - meta = NULL; - } else { - /* - * These changes are unlogged so we cannot have the - * metapage pointing at pages that are not on disk. - * Therefore, we flush the new free list, then update - * the metapage. We have to put the meta-data page - * first so that it isn't pinned when we try to sync. - */ - if (!IS_RECOVERING(dbenv) && !T_RESTORED(txn)) - __db_err(dbenv, "Flushing free list to disk"); - if ((ret = __memp_fput(mpf, meta, 0)) != 0) - goto err; - meta = NULL; - /* - * If the sync fails then we cannot flush the - * newly allocated pages. That is, the file - * cannot be extended. Don't let the metapage - * point at them. - * We may lose these pages from the file if it - * can be extended later. If there is never - * space for the pages, then things will be ok. - */ - if ((ret = __db_sync(dbp)) == 0) { - pgno = PGNO_BASE_MD; - if ((ret = - __memp_fget(mpf, &pgno, 0, &meta)) != 0) - goto err; - meta->free = last_pgno; - if ((ret = __memp_fput(mpf, - meta, DB_MPOOL_DIRTY)) != 0) - goto err; - meta = NULL; - } else { - __db_err(dbenv, - "%s: %s", dbp->fname, db_strerror(ret)); - __db_err(dbenv, "%s: %s %s", dbp->fname, - "allocation flush failed, some free pages", - "may not appear in the free list"); - ret = 0; - } - } - -next: - /* - * If we get here, either we have processed the list - * or the db file has been deleted or could not be opened. - */ - if (ctxn != NULL && - (t_ret = __txn_abort(ctxn)) != 0 && ret == 0) - ret = t_ret; - - if (dbp_created && - (t_ret = __db_close(dbp, txn, DB_NOSYNC)) != 0 && ret == 0) - ret = t_ret; - dbp = NULL; - if (state != LIMBO_PREPARE && state != LIMBO_TIMESTAMP) { - __os_free(dbenv, elp->u.p.fname); - __os_free(dbenv, elp->u.p.pgno_array); - } - if (ret == ENOENT) - ret = 0; - else if (ret != 0) - goto err; - } - -err: if (meta != NULL) - (void)__memp_fput(mpf, meta, 0); - return (ret); -} - -/* - * __db_limbo_fix -- - * Process a single limbo entry which describes all the page allocations - * for a single file. - */ -static int -__db_limbo_fix(dbp, ctxn, elp, lastp, meta, state) - DB *dbp; - DB_TXN *ctxn; - DB_TXNLIST *elp; - db_pgno_t *lastp; - DBMETA *meta; - db_limbo_state state; -{ - DBC *dbc; - DBT ldbt; - DB_MPOOLFILE *mpf; - PAGE *freep, *pagep; - db_pgno_t next, pgno; - u_int32_t i; - int ret, t_ret; - - /* - * Loop through the entries for this txnlist element and - * either link them into the free list or write a compensating - * record for each. - */ - dbc = NULL; - mpf = dbp->mpf; - pagep = NULL; - ret = 0; - - for (i = 0; i < elp->u.p.nentries; i++) { - pgno = elp->u.p.pgno_array[i]; - - if (pgno == PGNO_INVALID) - continue; - - if ((ret = - __memp_fget(mpf, &pgno, DB_MPOOL_CREATE, &pagep)) != 0) { - if (ret != ENOSPC) - goto err; - continue; - } - - if (state == LIMBO_COMPENSATE || IS_ZERO_LSN(LSN(pagep))) { - if (ctxn == NULL) { - /* - * If this is a fatal recovery which - * spans a previous crash this page may - * be on the free list already. - */ - for (next = *lastp; next != 0; ) { - if (next == pgno) - break; - if ((ret = __memp_fget(mpf, - &next, 0, &freep)) != 0) - goto err; - next = NEXT_PGNO(freep); - if ((ret = - __memp_fput(mpf, freep, 0)) != 0) - goto err; - } - - if (next != pgno) { - P_INIT(pagep, dbp->pgsize, pgno, - PGNO_INVALID, *lastp, 0, P_INVALID); - /* Make the lsn non-zero but generic. */ - INIT_LSN(LSN(pagep)); - *lastp = pgno; - } - } else if (state == LIMBO_COMPENSATE) { - /* - * Generate a log record for what we did on the - * LIMBO_TIMESTAMP pass. All pages here are - * free so P_OVERHEAD is sufficient. - */ - ZERO_LSN(pagep->lsn); - memset(&ldbt, 0, sizeof(ldbt)); - ldbt.data = pagep; - ldbt.size = P_OVERHEAD(dbp); - if ((ret = __db_pg_new_log(dbp, ctxn, - &LSN(meta), 0, pagep->pgno, - &LSN(meta), PGNO_BASE_MD, - &ldbt, pagep->next_pgno)) != 0) - goto err; - } else { - if (dbc == NULL && (ret = - __db_cursor(dbp, ctxn, &dbc, 0)) != 0) - goto err; - /* - * If the dbp is compensating (because we - * opened it), the dbc will automatically be - * marked compensating, but in case we didn't - * do the open, we have to mark it explicitly. - */ - F_SET(dbc, DBC_COMPENSATE); - - /* - * If aborting a txn for a different process - * via XA or failchk, DB_AM_RECOVER will be - * set but we need to log the compensating - * transactions. - */ - F_CLR(dbc, DBC_RECOVER); - - ret = __db_free(dbc, pagep); - pagep = NULL; - - /* - * On any error, we hope that the error was - * caused due to running out of space, and we - * switch modes, doing the processing where we - * sync out files instead of doing compensating - * transactions. If this was a real error and - * not out of space, we assume that some other - * call will fail real soon. - */ - if (ret != 0) { - /* Assume that this is out of space. */ - (void)__db_c_close(dbc); - dbc = NULL; - goto err; - } - } - } - else - elp->u.p.pgno_array[i] = PGNO_INVALID; - - if (pagep != NULL) { - ret = __memp_fput(mpf, pagep, DB_MPOOL_DIRTY); - pagep = NULL; - } - if (ret != 0) - goto err; - } - -err: if (pagep != NULL && - (t_ret = __memp_fput(mpf, pagep, DB_MPOOL_DIRTY)) != 0 && ret == 0) - ret = t_ret; - if (dbc != NULL && (t_ret = __db_c_close(dbc)) != 0 && ret == 0) - ret = t_ret; - return (ret); -} - -static int -__db_limbo_prepare(dbp, txn, elp) - DB *dbp; - DB_TXN *txn; - DB_TXNLIST *elp; -{ - DB_LSN lsn; - DB_MPOOLFILE *mpf; - PAGE *pagep; - db_pgno_t pgno; - u_int32_t i; - int ret, t_ret; - - /* - * Loop through the entries for this txnlist element and - * output a prepare record for them. - */ - pagep = NULL; - ret = 0; - mpf = dbp->mpf; - - for (i = 0; i < elp->u.p.nentries; i++) { - pgno = elp->u.p.pgno_array[i]; - - if ((ret = - __memp_fget(mpf, &pgno, DB_MPOOL_CREATE, &pagep)) != 0) { - if (ret != ENOSPC) - return (ret); - continue; - } - - if (IS_ZERO_LSN(LSN(pagep))) - ret = __db_pg_prepare_log(dbp, txn, &lsn, 0, pgno); - - if ((t_ret = __memp_fput(mpf, pagep, 0)) != 0 && ret == 0) - ret = t_ret; - - if (ret != 0) - return (ret); - } - - return (0); -} - -#define DB_TXNLIST_MAX_PGNO 8 /* A nice even number. */ - -/* - * __db_txnlist_pgnoadd -- - * Find the txnlist entry for a file and add this pgno, or add the list - * entry for the file and then add the pgno. - */ -static int -__db_txnlist_pgnoadd(dbenv, hp, fileid, uid, fname, pgno) - DB_ENV *dbenv; - DB_TXNHEAD *hp; - int32_t fileid; - u_int8_t uid[DB_FILE_ID_LEN]; - char *fname; - db_pgno_t pgno; -{ - DB_TXNLIST *elp; - size_t len; - u_int32_t hash, status; - int ret; - - elp = NULL; - - if ((ret = __db_txnlist_find_internal(dbenv, hp, - TXNLIST_PGNO, 0, uid, &elp, 0, &status)) != 0 && ret != DB_NOTFOUND) - goto err; - - if (ret == DB_NOTFOUND || status != TXN_OK) { - if ((ret = - __os_malloc(dbenv, sizeof(DB_TXNLIST), &elp)) != 0) - goto err; - memcpy(&hash, uid, sizeof(hash)); - LIST_INSERT_HEAD( - &hp->head[DB_TXNLIST_MASK(hp, hash)], elp, links); - memcpy(elp->u.p.uid, uid, DB_FILE_ID_LEN); - - len = strlen(fname) + 1; - if ((ret = __os_malloc(dbenv, len, &elp->u.p.fname)) != 0) - goto err; - memcpy(elp->u.p.fname, fname, len); - - elp->u.p.maxentry = 0; - elp->u.p.locked = 0; - elp->type = TXNLIST_PGNO; - if ((ret = __os_malloc(dbenv, - 8 * sizeof(db_pgno_t), &elp->u.p.pgno_array)) != 0) - goto err; - elp->u.p.maxentry = DB_TXNLIST_MAX_PGNO; - elp->u.p.nentries = 0; - } else if (elp->u.p.nentries == elp->u.p.maxentry) { - elp->u.p.maxentry <<= 1; - if ((ret = __os_realloc(dbenv, elp->u.p.maxentry * - sizeof(db_pgno_t), &elp->u.p.pgno_array)) != 0) - goto err; - } - - elp->u.p.pgno_array[elp->u.p.nentries++] = pgno; - /* Update to the latest fileid. Limbo will find it faster. */ - elp->u.p.fileid = fileid; - - return (0); - -err: return (ret); -} -#endif - -#ifdef DEBUG -/* - * __db_txnlist_print -- - * Print out the transaction list. - * - * PUBLIC: void __db_txnlist_print __P((DB_TXNHEAD *)); - */ -void -__db_txnlist_print(hp) - DB_TXNHEAD *hp; -{ - DB_TXNLIST *p; - u_int32_t i; - char *txntype; - - printf("Maxid: %lu Generation: %lu\n", - (u_long)hp->maxid, (u_long)hp->generation); - for (i = 0; i < hp->nslots; i++) - for (p = LIST_FIRST(&hp->head[i]); - p != NULL; p = LIST_NEXT(p, links)) { - if (p->type != TXNLIST_TXNID) { - printf("Unrecognized type: %d\n", p->type); - continue; - } - switch (p->u.t.status) { - case TXN_OK: - txntype = "OK"; - break; - case TXN_COMMIT: - txntype = "commit"; - break; - case TXN_PREPARE: - txntype = "prepare"; - break; - case TXN_ABORT: - txntype = "abort"; - break; - case TXN_IGNORE: - txntype = "ignore"; - break; - case TXN_EXPECTED: - txntype = "expected"; - break; - case TXN_UNEXPECTED: - txntype = "unexpected"; - break; - default: - txntype = "UNKNOWN"; - break; - } - printf("TXNID: %lx(%lu): %s\n", - (u_long)p->u.t.txnid, - (u_long)p->u.t.generation, txntype); - } -} -#endif diff --git a/storage/bdb/db/db_dup.c b/storage/bdb/db/db_dup.c deleted file mode 100644 index 2f0732c6b5c..00000000000 --- a/storage/bdb/db/db_dup.c +++ /dev/null @@ -1,164 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_dup.c,v 12.2 2005/06/16 20:21:10 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/mp.h" -#include "dbinc/db_am.h" - -/* - * __db_ditem -- - * Remove an item from a page. - * - * PUBLIC: int __db_ditem __P((DBC *, PAGE *, u_int32_t, u_int32_t)); - */ -int -__db_ditem(dbc, pagep, indx, nbytes) - DBC *dbc; - PAGE *pagep; - u_int32_t indx, nbytes; -{ - DB *dbp; - DBT ldbt; - db_indx_t cnt, *inp, offset; - int ret; - u_int8_t *from; - - dbp = dbc->dbp; - if (DBC_LOGGING(dbc)) { - ldbt.data = P_ENTRY(dbp, pagep, indx); - ldbt.size = nbytes; - if ((ret = __db_addrem_log(dbp, dbc->txn, - &LSN(pagep), 0, DB_REM_DUP, PGNO(pagep), - (u_int32_t)indx, nbytes, &ldbt, NULL, &LSN(pagep))) != 0) - return (ret); - } else - LSN_NOT_LOGGED(LSN(pagep)); - - /* - * If there's only a single item on the page, we don't have to - * work hard. - */ - if (NUM_ENT(pagep) == 1) { - NUM_ENT(pagep) = 0; - HOFFSET(pagep) = dbp->pgsize; - return (0); - } - - inp = P_INP(dbp, pagep); - /* - * Pack the remaining key/data items at the end of the page. Use - * memmove(3), the regions may overlap. - */ - from = (u_int8_t *)pagep + HOFFSET(pagep); - DB_ASSERT(inp[indx] >= HOFFSET(pagep)); - memmove(from + nbytes, from, inp[indx] - HOFFSET(pagep)); - HOFFSET(pagep) += nbytes; - - /* Adjust the indices' offsets. */ - offset = inp[indx]; - for (cnt = 0; cnt < NUM_ENT(pagep); ++cnt) - if (inp[cnt] < offset) - inp[cnt] += nbytes; - - /* Shift the indices down. */ - --NUM_ENT(pagep); - if (indx != NUM_ENT(pagep)) - memmove(&inp[indx], &inp[indx + 1], - sizeof(db_indx_t) * (NUM_ENT(pagep) - indx)); - - return (0); -} - -/* - * __db_pitem -- - * Put an item on a page. - * - * PUBLIC: int __db_pitem - * PUBLIC: __P((DBC *, PAGE *, u_int32_t, u_int32_t, DBT *, DBT *)); - */ -int -__db_pitem(dbc, pagep, indx, nbytes, hdr, data) - DBC *dbc; - PAGE *pagep; - u_int32_t indx; - u_int32_t nbytes; - DBT *hdr, *data; -{ - DB *dbp; - BKEYDATA bk; - DBT thdr; - db_indx_t *inp; - int ret; - u_int8_t *p; - - dbp = dbc->dbp; - if (nbytes > P_FREESPACE(dbp, pagep)) { - DB_ASSERT(nbytes <= P_FREESPACE(dbp, pagep)); - return (EINVAL); - } - /* - * Put a single item onto a page. The logic figuring out where to - * insert and whether it fits is handled in the caller. All we do - * here is manage the page shuffling. We cheat a little bit in that - * we don't want to copy the dbt on a normal put twice. If hdr is - * NULL, we create a BKEYDATA structure on the page, otherwise, just - * copy the caller's information onto the page. - * - * This routine is also used to put entries onto the page where the - * entry is pre-built, e.g., during recovery. In this case, the hdr - * will point to the entry, and the data argument will be NULL. - * - * !!! - * There's a tremendous potential for off-by-one errors here, since - * the passed in header sizes must be adjusted for the structure's - * placeholder for the trailing variable-length data field. - */ - if (DBC_LOGGING(dbc)) { - if ((ret = __db_addrem_log(dbp, dbc->txn, - &LSN(pagep), 0, DB_ADD_DUP, PGNO(pagep), - (u_int32_t)indx, nbytes, hdr, data, &LSN(pagep))) != 0) - return (ret); - } else - LSN_NOT_LOGGED(LSN(pagep)); - - if (hdr == NULL) { - B_TSET(bk.type, B_KEYDATA, 0); - bk.len = data == NULL ? 0 : data->size; - - thdr.data = &bk; - thdr.size = SSZA(BKEYDATA, data); - hdr = &thdr; - } - inp = P_INP(dbp, pagep); - - /* Adjust the index table, then put the item on the page. */ - if (indx != NUM_ENT(pagep)) - memmove(&inp[indx + 1], &inp[indx], - sizeof(db_indx_t) * (NUM_ENT(pagep) - indx)); - HOFFSET(pagep) -= nbytes; - inp[indx] = HOFFSET(pagep); - ++NUM_ENT(pagep); - - p = P_ENTRY(dbp, pagep, indx); - memcpy(p, hdr->data, hdr->size); - if (data != NULL) - memcpy(p + hdr->size, data->data, data->size); - - return (0); -} diff --git a/storage/bdb/db/db_iface.c b/storage/bdb/db/db_iface.c deleted file mode 100644 index 37811a17a26..00000000000 --- a/storage/bdb/db/db_iface.c +++ /dev/null @@ -1,2438 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_iface.c,v 12.29 2005/11/08 14:49:44 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/btree.h" -#ifndef HAVE_HASH -#include "dbinc/hash.h" /* For __db_no_hash_am(). */ -#endif -#ifndef HAVE_QUEUE -#include "dbinc/qam.h" /* For __db_no_queue_am(). */ -#endif -#include "dbinc/lock.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" -#include "dbinc/txn.h" - -static int __db_associate_arg __P((DB *, DB *, - int (*)(DB *, const DBT *, const DBT *, DBT *), u_int32_t)); -static int __db_c_del_arg __P((DBC *, u_int32_t)); -static int __db_c_get_arg __P((DBC *, DBT *, DBT *, u_int32_t)); -static int __db_c_pget_arg __P((DBC *, DBT *, u_int32_t)); -static int __db_c_put_arg __P((DBC *, DBT *, DBT *, u_int32_t)); -static int __db_curinval __P((const DB_ENV *)); -static int __db_cursor_arg __P((DB *, u_int32_t)); -static int __db_del_arg __P((DB *, u_int32_t)); -static int __db_get_arg __P((const DB *, const DBT *, DBT *, u_int32_t)); -static int __db_join_arg __P((DB *, DBC **, u_int32_t)); -static int __db_open_arg __P((DB *, - DB_TXN *, const char *, const char *, DBTYPE, u_int32_t)); -static int __db_pget_arg __P((DB *, DBT *, u_int32_t)); -static int __db_put_arg __P((DB *, DBT *, DBT *, u_int32_t)); -static int __dbt_ferr __P((const DB *, const char *, const DBT *, int)); - -/* - * These functions implement the Berkeley DB API. They are organized in a - * layered fashion. The interface functions (XXX_pp) perform all generic - * error checks (for example, PANIC'd region, replication state change - * in progress, inconsistent transaction usage), call function-specific - * check routines (_arg) to check for proper flag usage, etc., do pre-amble - * processing (incrementing handle counts, handling local transactions), - * call the function and then do post-amble processing (local transactions, - * decrement handle counts). - * - * The basic structure is: - * Check for simple/generic errors (PANIC'd region) - * Check if replication is changing state (increment handle count). - * Call function-specific argument checking routine - * Create internal transaction if necessary - * Call underlying worker function - * Commit/abort internal transaction if necessary - * Decrement handle count - */ - -/* - * __db_associate_pp -- - * DB->associate pre/post processing. - * - * PUBLIC: int __db_associate_pp __P((DB *, DB_TXN *, DB *, - * PUBLIC: int (*)(DB *, const DBT *, const DBT *, DBT *), u_int32_t)); - */ -int -__db_associate_pp(dbp, txn, sdbp, callback, flags) - DB *dbp, *sdbp; - DB_TXN *txn; - int (*callback) __P((DB *, const DBT *, const DBT *, DBT *)); - u_int32_t flags; -{ - DBC *sdbc; - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int handle_check, ret, t_ret, txn_local; - - dbenv = dbp->dbenv; - txn_local = 0; - - PANIC_CHECK(dbenv); - STRIP_AUTO_COMMIT(flags); - - ENV_ENTER(dbenv, ip); - - /* Check for replication block. */ - handle_check = IS_ENV_REPLICATED(dbenv); - if (handle_check && - (ret = __db_rep_enter(dbp, 1, 0, txn != NULL)) != 0) { - handle_check = 0; - goto err; - } - - /* - * Secondary cursors may have the primary's lock file ID, so we need - * to make sure that no older cursors are lying around when we make - * the transition. - */ - if (TAILQ_FIRST(&sdbp->active_queue) != NULL || - TAILQ_FIRST(&sdbp->join_queue) != NULL) { - __db_err(dbenv, - "Databases may not become secondary indices while cursors are open"); - ret = EINVAL; - goto err; - } - - if ((ret = __db_associate_arg(dbp, sdbp, callback, flags)) != 0) - goto err; - - /* - * Create a local transaction as necessary, check for consistent - * transaction usage, and, if we have no transaction but do have - * locking on, acquire a locker id for the handle lock acquisition. - */ - if (IS_DB_AUTO_COMMIT(dbp, txn)) { - if ((ret = __txn_begin(dbenv, NULL, &txn, 0)) != 0) - goto err; - txn_local = 1; - } - - /* Check for consistent transaction usage. */ - if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 0)) != 0) - goto err; - - while ((sdbc = TAILQ_FIRST(&sdbp->free_queue)) != NULL) - if ((ret = __db_c_destroy(sdbc)) != 0) - goto err; - - ret = __db_associate(dbp, txn, sdbp, callback, flags); - -err: if (txn_local && - (t_ret = __db_txn_auto_resolve(dbenv, txn, 0, ret)) && ret == 0) - ret = t_ret; - - /* Release replication block. */ - if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __db_associate_arg -- - * Check DB->associate arguments. - */ -static int -__db_associate_arg(dbp, sdbp, callback, flags) - DB *dbp, *sdbp; - int (*callback) __P((DB *, const DBT *, const DBT *, DBT *)); - u_int32_t flags; -{ - DB_ENV *dbenv; - int ret; - - dbenv = dbp->dbenv; - - if (F_ISSET(sdbp, DB_AM_SECONDARY)) { - __db_err(dbenv, - "Secondary index handles may not be re-associated"); - return (EINVAL); - } - if (F_ISSET(dbp, DB_AM_SECONDARY)) { - __db_err(dbenv, - "Secondary indices may not be used as primary databases"); - return (EINVAL); - } - if (F_ISSET(dbp, DB_AM_DUP)) { - __db_err(dbenv, - "Primary databases may not be configured with duplicates"); - return (EINVAL); - } - if (F_ISSET(dbp, DB_AM_RENUMBER)) { - __db_err(dbenv, - "Renumbering recno databases may not be used as primary databases"); - return (EINVAL); - } - if (dbp->dbenv != sdbp->dbenv && - (!F_ISSET(dbp->dbenv, DB_ENV_DBLOCAL) || - !F_ISSET(sdbp->dbenv, DB_ENV_DBLOCAL))) { - __db_err(dbenv, - "The primary and secondary must be opened in the same environment"); - return (EINVAL); - } - if ((DB_IS_THREADED(dbp) && !DB_IS_THREADED(sdbp)) || - (!DB_IS_THREADED(dbp) && DB_IS_THREADED(sdbp))) { - __db_err(dbenv, - "The DB_THREAD setting must be the same for primary and secondary"); - return (EINVAL); - } - if (callback == NULL && - (!F_ISSET(dbp, DB_AM_RDONLY) || !F_ISSET(sdbp, DB_AM_RDONLY))) { - __db_err(dbenv, - "Callback function may be NULL only when database handles are read-only"); - return (EINVAL); - } - - if ((ret = __db_fchk(dbenv, "DB->associate", flags, DB_CREATE | - DB_IMMUTABLE_KEY)) != 0) - return (ret); - - return (0); -} - -/* - * __db_close_pp -- - * DB->close pre/post processing. - * - * PUBLIC: int __db_close_pp __P((DB *, u_int32_t)); - */ -int -__db_close_pp(dbp, flags) - DB *dbp; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int handle_check, ret, t_ret; - - dbenv = dbp->dbenv; - ret = 0; - - PANIC_CHECK(dbenv); - - /* - * Close a DB handle -- as a handle destructor, we can't fail. - * - * !!! - * The actual argument checking is simple, do it inline, outside of - * the replication block. - */ - if (flags != 0 && flags != DB_NOSYNC) - ret = __db_ferr(dbenv, "DB->close", 0); - - ENV_ENTER(dbenv, ip); - - /* Check for replication block. */ - handle_check = IS_ENV_REPLICATED(dbenv); - if (handle_check && (t_ret = __db_rep_enter(dbp, 0, 0, 0)) != 0) { - handle_check = 0; - if (ret == 0) - ret = t_ret; - } - - if ((t_ret = __db_close(dbp, NULL, flags)) != 0 && ret == 0) - ret = t_ret; - - /* Release replication block. */ - if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __db_cursor_pp -- - * DB->cursor pre/post processing. - * - * PUBLIC: int __db_cursor_pp __P((DB *, DB_TXN *, DBC **, u_int32_t)); - */ -int -__db_cursor_pp(dbp, txn, dbcp, flags) - DB *dbp; - DB_TXN *txn; - DBC **dbcp; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int handle_check, ret; - - dbenv = dbp->dbenv; - - PANIC_CHECK(dbenv); - DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->cursor"); - - ENV_ENTER(dbenv, ip); - - /* Check for replication block. */ - if (txn == NULL) { - handle_check = IS_ENV_REPLICATED(dbenv) ? 1 : 0; - if (handle_check && (ret = __op_rep_enter(dbenv)) != 0) { - handle_check = 0; - goto err; - } - } else - handle_check = 0; - if ((ret = __db_cursor_arg(dbp, flags)) != 0) - goto err; - - /* - * Check for consistent transaction usage. For now, assume this - * cursor might be used for read operations only (in which case - * it may not require a txn). We'll check more stringently in - * c_del and c_put. (Note this means the read-op txn tests have - * to be a subset of the write-op ones.) - */ - if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 1)) != 0) - goto err; - - ret = __db_cursor(dbp, txn, dbcp, flags); - -err: /* Release replication block on error. */ - if (ret != 0 && handle_check) - (void)__op_rep_exit(dbenv); - - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __db_cursor -- - * DB->cursor. - * - * PUBLIC: int __db_cursor __P((DB *, DB_TXN *, DBC **, u_int32_t)); - */ -int -__db_cursor(dbp, txn, dbcp, flags) - DB *dbp; - DB_TXN *txn; - DBC **dbcp; - u_int32_t flags; -{ - DB_ENV *dbenv; - DBC *dbc; - db_lockmode_t mode; - u_int32_t op; - int ret; - - dbenv = dbp->dbenv; - - if ((ret = __db_cursor_int(dbp, - txn, dbp->type, PGNO_INVALID, 0, DB_LOCK_INVALIDID, &dbc)) != 0) - return (ret); - - /* - * If this is CDB, do all the locking in the interface, which is - * right here. - */ - if (CDB_LOCKING(dbenv)) { - op = LF_ISSET(DB_OPFLAGS_MASK); - mode = (op == DB_WRITELOCK) ? DB_LOCK_WRITE : - ((op == DB_WRITECURSOR) ? DB_LOCK_IWRITE : DB_LOCK_READ); - if ((ret = __lock_get(dbenv, dbc->locker, 0, - &dbc->lock_dbt, mode, &dbc->mylock)) != 0) - goto err; - if (op == DB_WRITECURSOR) - F_SET(dbc, DBC_WRITECURSOR); - if (op == DB_WRITELOCK) - F_SET(dbc, DBC_WRITER); - } - - if (LF_ISSET(DB_READ_UNCOMMITTED) || - (txn != NULL && F_ISSET(txn, TXN_READ_UNCOMMITTED))) - F_SET(dbc, DBC_READ_UNCOMMITTED); - - if (LF_ISSET(DB_READ_COMMITTED) || - (txn != NULL && F_ISSET(txn, TXN_READ_COMMITTED))) - F_SET(dbc, DBC_READ_COMMITTED); - - *dbcp = dbc; - return (0); - -err: (void)__db_c_close(dbc); - return (ret); -} - -/* - * __db_cursor_arg -- - * Check DB->cursor arguments. - */ -static int -__db_cursor_arg(dbp, flags) - DB *dbp; - u_int32_t flags; -{ - DB_ENV *dbenv; - - dbenv = dbp->dbenv; - - /* - * DB_READ_COMMITTED and DB_READ_UNCOMMITTED are the only valid - * bit-flags; they require locking. - */ - if (LF_ISSET(DB_READ_COMMITTED | DB_READ_UNCOMMITTED)) { - if (!LOCKING_ON(dbenv)) - return (__db_fnl(dbenv, "DB->cursor")); - LF_CLR(DB_READ_COMMITTED| DB_READ_UNCOMMITTED); - } - - /* Check for invalid function flags. */ - switch (flags) { - case 0: - break; - case DB_WRITECURSOR: - if (DB_IS_READONLY(dbp)) - return (__db_rdonly(dbenv, "DB->cursor")); - if (!CDB_LOCKING(dbenv)) - return (__db_ferr(dbenv, "DB->cursor", 0)); - break; - case DB_WRITELOCK: - if (DB_IS_READONLY(dbp)) - return (__db_rdonly(dbenv, "DB->cursor")); - break; - default: - return (__db_ferr(dbenv, "DB->cursor", 0)); - } - - return (0); -} - -/* - * __db_del_pp -- - * DB->del pre/post processing. - * - * PUBLIC: int __db_del_pp __P((DB *, DB_TXN *, DBT *, u_int32_t)); - */ -int -__db_del_pp(dbp, txn, key, flags) - DB *dbp; - DB_TXN *txn; - DBT *key; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int handle_check, ret, t_ret, txn_local; - - dbenv = dbp->dbenv; - txn_local = 0; - - PANIC_CHECK(dbenv); - STRIP_AUTO_COMMIT(flags); - DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->del"); - -#if CONFIG_TEST - if (IS_REP_MASTER(dbenv)) - DB_TEST_WAIT(dbenv, dbenv->test_check); -#endif - ENV_ENTER(dbenv, ip); - - /* Check for replication block. */ - handle_check = IS_ENV_REPLICATED(dbenv); - if (handle_check && - (ret = __db_rep_enter(dbp, 1, 0, txn != NULL)) != 0) { - handle_check = 0; - goto err; - } - - if ((ret = __db_del_arg(dbp, flags)) != 0) - goto err; - - /* Create local transaction as necessary. */ - if (IS_DB_AUTO_COMMIT(dbp, txn)) { - if ((ret = __txn_begin(dbenv, NULL, &txn, 0)) != 0) - goto err; - txn_local = 1; - } - - /* Check for consistent transaction usage. */ - if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 0)) != 0) - goto err; - - ret = __db_del(dbp, txn, key, flags); - -err: if (txn_local && - (t_ret = __db_txn_auto_resolve(dbenv, txn, 0, ret)) && ret == 0) - ret = t_ret; - - /* Release replication block. */ - if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __db_del_arg -- - * Check DB->delete arguments. - */ -static int -__db_del_arg(dbp, flags) - DB *dbp; - u_int32_t flags; -{ - DB_ENV *dbenv; - - dbenv = dbp->dbenv; - - /* Check for changes to a read-only tree. */ - if (DB_IS_READONLY(dbp)) - return (__db_rdonly(dbenv, "DB->del")); - - /* Check for invalid function flags. */ - switch (flags) { - case 0: - break; - default: - return (__db_ferr(dbenv, "DB->del", 0)); - } - - return (0); -} - -/* - * db_fd_pp -- - * DB->fd pre/post processing. - * - * PUBLIC: int __db_fd_pp __P((DB *, int *)); - */ -int -__db_fd_pp(dbp, fdp) - DB *dbp; - int *fdp; -{ - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - DB_FH *fhp; - int handle_check, ret, t_ret; - - dbenv = dbp->dbenv; - - PANIC_CHECK(dbenv); - DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->fd"); - - ENV_ENTER(dbenv, ip); - - /* Check for replication block. */ - handle_check = IS_ENV_REPLICATED(dbenv); - if (handle_check && (ret = __db_rep_enter(dbp, 1, 0, 0)) != 0) - goto err; - - /* - * !!! - * There's no argument checking to be done. - * - * !!! - * The actual method call is simple, do it inline. - * - * XXX - * Truly spectacular layering violation. - */ - if ((ret = __mp_xxx_fh(dbp->mpf, &fhp)) == 0) { - if (fhp == NULL) { - *fdp = -1; - __db_err(dbenv, - "Database does not have a valid file handle"); - ret = ENOENT; - } else - *fdp = fhp->fd; - } - - /* Release replication block. */ - if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - -err: ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __db_get_pp -- - * DB->get pre/post processing. - * - * PUBLIC: int __db_get_pp __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); - */ -int -__db_get_pp(dbp, txn, key, data, flags) - DB *dbp; - DB_TXN *txn; - DBT *key, *data; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - u_int32_t mode; - int handle_check, ret, t_ret, txn_local; - - dbenv = dbp->dbenv; - mode = 0; - txn_local = 0; - - PANIC_CHECK(dbenv); - STRIP_AUTO_COMMIT(flags); - DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->get"); - - ENV_ENTER(dbenv, ip); - - /* Check for replication block. */ - handle_check = IS_ENV_REPLICATED(dbenv); - if (handle_check && - (ret = __db_rep_enter(dbp, 1, 0, txn != NULL)) != 0) { - handle_check = 0; - goto err; - } - - if ((ret = __db_get_arg(dbp, key, data, flags)) != 0) - goto err; - - if (LF_ISSET(DB_READ_UNCOMMITTED)) - mode = DB_READ_UNCOMMITTED; - else if ((flags & DB_OPFLAGS_MASK) == DB_CONSUME || - (flags & DB_OPFLAGS_MASK) == DB_CONSUME_WAIT) { - mode = DB_WRITELOCK; - if (IS_DB_AUTO_COMMIT(dbp, txn)) { - if ((ret = __txn_begin(dbenv, NULL, &txn, 0)) != 0) - goto err; - txn_local = 1; - } - } - - /* Check for consistent transaction usage. */ - if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, - mode == DB_WRITELOCK || LF_ISSET(DB_RMW) ? 0 : 1)) != 0) - goto err; - - ret = __db_get(dbp, txn, key, data, flags); - -err: if (txn_local && - (t_ret = __db_txn_auto_resolve(dbenv, txn, 0, ret)) && ret == 0) - ret = t_ret; - - /* Release replication block. */ - if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __db_get -- - * DB->get. - * - * PUBLIC: int __db_get __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); - */ -int -__db_get(dbp, txn, key, data, flags) - DB *dbp; - DB_TXN *txn; - DBT *key, *data; - u_int32_t flags; -{ - DBC *dbc; - u_int32_t mode; - int ret, t_ret; - - mode = 0; - if (LF_ISSET(DB_READ_UNCOMMITTED)) { - mode = DB_READ_UNCOMMITTED; - LF_CLR(DB_READ_UNCOMMITTED); - } else if (LF_ISSET(DB_READ_COMMITTED)) { - mode = DB_READ_COMMITTED; - LF_CLR(DB_READ_COMMITTED); - } else if ((flags & DB_OPFLAGS_MASK) == DB_CONSUME || - (flags & DB_OPFLAGS_MASK) == DB_CONSUME_WAIT) - mode = DB_WRITELOCK; - - if ((ret = __db_cursor(dbp, txn, &dbc, mode)) != 0) - return (ret); - - DEBUG_LREAD(dbc, txn, "DB->get", key, NULL, flags); - - /* - * The DBC_TRANSIENT flag indicates that we're just doing a - * single operation with this cursor, and that in case of - * error we don't need to restore it to its old position--we're - * going to close it right away. Thus, we can perform the get - * without duplicating the cursor, saving some cycles in this - * common case. - */ - F_SET(dbc, DBC_TRANSIENT); - - /* - * SET_RET_MEM indicates that if key and/or data have no DBT - * flags set and DB manages the returned-data memory, that memory - * will belong to this handle, not to the underlying cursor. - */ - SET_RET_MEM(dbc, dbp); - - if (LF_ISSET(~(DB_RMW | DB_MULTIPLE)) == 0) - LF_SET(DB_SET); - - ret = __db_c_get(dbc, key, data, flags); - - if (dbc != NULL && (t_ret = __db_c_close(dbc)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __db_get_arg -- - * DB->get argument checking, used by both DB->get and DB->pget. - */ -static int -__db_get_arg(dbp, key, data, flags) - const DB *dbp; - const DBT *key; - DBT *data; - u_int32_t flags; -{ - DB_ENV *dbenv; - int check_thread, dirty, multi, ret; - - dbenv = dbp->dbenv; - - /* - * Check for read-modify-write validity. DB_RMW doesn't make sense - * with CDB cursors since if you're going to write the cursor, you - * had to create it with DB_WRITECURSOR. Regardless, we check for - * LOCKING_ON and not STD_LOCKING, as we don't want to disallow it. - * If this changes, confirm that DB does not itself set the DB_RMW - * flag in a path where CDB may have been configured. - */ - check_thread = dirty = 0; - if (LF_ISSET(DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_RMW)) { - if (!LOCKING_ON(dbenv)) - return (__db_fnl(dbenv, "DB->get")); - if ((ret = __db_fcchk(dbenv, "DB->get", - flags, DB_READ_UNCOMMITTED, DB_READ_COMMITTED)) != 0) - return (ret); - if (LF_ISSET(DB_READ_COMMITTED | DB_READ_UNCOMMITTED)) - dirty = 1; - LF_CLR(DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_RMW); - } - - multi = 0; - if (LF_ISSET(DB_MULTIPLE | DB_MULTIPLE_KEY)) { - if (LF_ISSET(DB_MULTIPLE_KEY)) - goto multi_err; - multi = LF_ISSET(DB_MULTIPLE) ? 1 : 0; - LF_CLR(DB_MULTIPLE); - } - - /* Check for invalid function flags. */ - switch (flags) { - case 0: - case DB_GET_BOTH: - break; - case DB_SET_RECNO: - check_thread = 1; - if (!F_ISSET(dbp, DB_AM_RECNUM)) - goto err; - break; - case DB_CONSUME: - case DB_CONSUME_WAIT: - check_thread = 1; - if (dirty) { - __db_err(dbenv, - "%s is not supported with DB_CONSUME or DB_CONSUME_WAIT", - LF_ISSET(DB_READ_UNCOMMITTED) ? - "DB_READ_UNCOMMITTED" : "DB_READ_COMMITTED"); - return (EINVAL); - } - if (multi) -multi_err: return (__db_ferr(dbenv, "DB->get", 1)); - if (dbp->type == DB_QUEUE) - break; - /* FALLTHROUGH */ - default: -err: return (__db_ferr(dbenv, "DB->get", 0)); - } - - /* - * Check for invalid key/data flags. - * - * XXX: Dave Krinsky - * Remember to modify this when we fix the flag-returning problem. - */ - if ((ret = __dbt_ferr(dbp, "key", key, check_thread)) != 0) - return (ret); - if ((ret = __dbt_ferr(dbp, "data", data, 1)) != 0) - return (ret); - - if (multi) { - if (!F_ISSET(data, DB_DBT_USERMEM)) { - __db_err(dbenv, - "DB_MULTIPLE requires DB_DBT_USERMEM be set"); - return (EINVAL); - } - if (F_ISSET(key, DB_DBT_PARTIAL) || - F_ISSET(data, DB_DBT_PARTIAL)) { - __db_err(dbenv, - "DB_MULTIPLE does not support DB_DBT_PARTIAL"); - return (EINVAL); - } - if (data->ulen < 1024 || - data->ulen < dbp->pgsize || data->ulen % 1024 != 0) { - __db_err(dbenv, "%s%s", - "DB_MULTIPLE buffers must be ", - "aligned, at least page size and multiples of 1KB"); - return (EINVAL); - } - } - - return (0); -} - -/* - * __db_join_pp -- - * DB->join pre/post processing. - * - * PUBLIC: int __db_join_pp __P((DB *, DBC **, DBC **, u_int32_t)); - */ -int -__db_join_pp(primary, curslist, dbcp, flags) - DB *primary; - DBC **curslist, **dbcp; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int handle_check, ret, t_ret; - - dbenv = primary->dbenv; - - PANIC_CHECK(dbenv); - - ENV_ENTER(dbenv, ip); - - /* Check for replication block. */ - handle_check = IS_ENV_REPLICATED(dbenv); - if (handle_check && (ret = - __db_rep_enter(primary, 1, 0, curslist[0]->txn != NULL)) != 0) { - handle_check = 0; - goto err; - } - - if ((ret = __db_join_arg(primary, curslist, flags)) == 0) - ret = __db_join(primary, curslist, dbcp, flags); - - /* Release replication block. */ - if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - -err: ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __db_join_arg -- - * Check DB->join arguments. - */ -static int -__db_join_arg(primary, curslist, flags) - DB *primary; - DBC **curslist; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_TXN *txn; - int i; - - dbenv = primary->dbenv; - - switch (flags) { - case 0: - case DB_JOIN_NOSORT: - break; - default: - return (__db_ferr(dbenv, "DB->join", 0)); - } - - if (curslist == NULL || curslist[0] == NULL) { - __db_err(dbenv, - "At least one secondary cursor must be specified to DB->join"); - return (EINVAL); - } - - txn = curslist[0]->txn; - for (i = 1; curslist[i] != NULL; i++) - if (curslist[i]->txn != txn) { - __db_err(dbenv, - "All secondary cursors must share the same transaction"); - return (EINVAL); - } - - return (0); -} - -/* - * __db_key_range_pp -- - * DB->key_range pre/post processing. - * - * PUBLIC: int __db_key_range_pp - * PUBLIC: __P((DB *, DB_TXN *, DBT *, DB_KEY_RANGE *, u_int32_t)); - */ -int -__db_key_range_pp(dbp, txn, key, kr, flags) - DB *dbp; - DB_TXN *txn; - DBT *key; - DB_KEY_RANGE *kr; - u_int32_t flags; -{ - DBC *dbc; - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int handle_check, ret, t_ret; - - dbenv = dbp->dbenv; - - PANIC_CHECK(dbp->dbenv); - DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->key_range"); - - /* - * !!! - * The actual argument checking is simple, do it inline, outside of - * the replication block. - */ - if (flags != 0) - return (__db_ferr(dbenv, "DB->key_range", 0)); - - ENV_ENTER(dbenv, ip); - - /* Check for replication block. */ - handle_check = IS_ENV_REPLICATED(dbenv); - if (handle_check && - (ret = __db_rep_enter(dbp, 1, 0, txn != NULL)) != 0) { - handle_check = 0; - goto err; - } - - /* Check for consistent transaction usage. */ - if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 1)) != 0) - goto err; - - /* - * !!! - * The actual method call is simple, do it inline. - */ - switch (dbp->type) { - case DB_BTREE: - /* Acquire a cursor. */ - if ((ret = __db_cursor(dbp, txn, &dbc, 0)) != 0) - break; - - DEBUG_LWRITE(dbc, NULL, "bam_key_range", NULL, NULL, 0); - - ret = __bam_key_range(dbc, key, kr, flags); - - if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0) - ret = t_ret; - break; - case DB_HASH: - case DB_QUEUE: - case DB_RECNO: - ret = __dbh_am_chk(dbp, DB_OK_BTREE); - break; - case DB_UNKNOWN: - default: - ret = __db_unknown_type(dbenv, "DB->key_range", dbp->type); - break; - } - -err: /* Release replication block. */ - if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __db_open_pp -- - * DB->open pre/post processing. - * - * PUBLIC: int __db_open_pp __P((DB *, DB_TXN *, - * PUBLIC: const char *, const char *, DBTYPE, u_int32_t, int)); - */ -int -__db_open_pp(dbp, txn, fname, dname, type, flags, mode) - DB *dbp; - DB_TXN *txn; - const char *fname, *dname; - DBTYPE type; - u_int32_t flags; - int mode; -{ - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int handle_check, nosync, remove_me, ret, t_ret, txn_local; - - dbenv = dbp->dbenv; - nosync = 1; - remove_me = txn_local = 0; - handle_check = 0; - - PANIC_CHECK(dbenv); - - ENV_ENTER(dbenv, ip); - - /* - * Save the file and database names and flags. We do this here - * because we don't pass all of the flags down into the actual - * DB->open method call, we strip DB_AUTO_COMMIT at this layer. - */ - if ((fname != NULL && - (ret = __os_strdup(dbenv, fname, &dbp->fname)) != 0)) - goto err; - if ((dname != NULL && - (ret = __os_strdup(dbenv, dname, &dbp->dname)) != 0)) - goto err; - dbp->open_flags = flags; - - /* Save the current DB handle flags for refresh. */ - dbp->orig_flags = dbp->flags; - - /* Check for replication block. */ - handle_check = IS_ENV_REPLICATED(dbenv); - if (handle_check && - (ret = __db_rep_enter(dbp, 1, 0, txn != NULL)) != 0) { - handle_check = 0; - goto err; - } - - /* - * Create local transaction as necessary, check for consistent - * transaction usage. - */ - if (IS_ENV_AUTO_COMMIT(dbenv, txn, flags)) { - if ((ret = __db_txn_auto_init(dbenv, &txn)) != 0) - goto err; - txn_local = 1; - } else - if (txn != NULL && !TXN_ON(dbenv)) { - ret = __db_not_txn_env(dbenv); - goto err; - } - LF_CLR(DB_AUTO_COMMIT); - - /* - * We check arguments after possibly creating a local transaction, - * which is unusual -- the reason is some flags are illegal if any - * kind of transaction is in effect. - */ - if ((ret = __db_open_arg(dbp, txn, fname, dname, type, flags)) == 0) - if ((ret = __db_open(dbp, txn, fname, dname, type, - flags, mode, PGNO_BASE_MD)) != 0) - goto txnerr; - - /* - * You can open the database that describes the subdatabases in the - * rest of the file read-only. The content of each key's data is - * unspecified and applications should never be adding new records - * or updating existing records. However, during recovery, we need - * to open these databases R/W so we can redo/undo changes in them. - * Likewise, we need to open master databases read/write during - * rename and remove so we can be sure they're fully sync'ed, so - * we provide an override flag for the purpose. - */ - if (dname == NULL && !IS_RECOVERING(dbenv) && !LF_ISSET(DB_RDONLY) && - !LF_ISSET(DB_RDWRMASTER) && F_ISSET(dbp, DB_AM_SUBDB)) { - __db_err(dbenv, - "files containing multiple databases may only be opened read-only"); - ret = EINVAL; - goto txnerr; - } - - /* - * Success: file creations have to be synchronous, otherwise we don't - * care. - */ - if (F_ISSET(dbp, DB_AM_CREATED | DB_AM_CREATED_MSTR)) - nosync = 0; - - /* Success: don't discard the file on close. */ - F_CLR(dbp, DB_AM_DISCARD | DB_AM_CREATED | DB_AM_CREATED_MSTR); - - /* - * If not transactional, remove the databases/subdatabases. If we're - * transactional, the child transaction abort cleans up. - */ -txnerr: if (ret != 0 && txn == NULL) { - remove_me = F_ISSET(dbp, DB_AM_CREATED); - if (F_ISSET(dbp, DB_AM_CREATED_MSTR) || - (dname == NULL && remove_me)) - /* Remove file. */ - (void)__db_remove_int(dbp, txn, fname, NULL, DB_FORCE); - else if (remove_me) - /* Remove subdatabase. */ - (void)__db_remove_int(dbp, txn, fname, dname, DB_FORCE); - } - - if (txn_local && (t_ret = - __db_txn_auto_resolve(dbenv, txn, nosync, ret)) && ret == 0) - ret = t_ret; - -err: /* Release replication block. */ - if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __db_open_arg -- - * Check DB->open arguments. - */ -static int -__db_open_arg(dbp, txn, fname, dname, type, flags) - DB *dbp; - DB_TXN *txn; - const char *fname, *dname; - DBTYPE type; - u_int32_t flags; -{ - DB_ENV *dbenv; - u_int32_t ok_flags; - int ret; - - dbenv = dbp->dbenv; - - /* Validate arguments. */ -#undef OKFLAGS -#define OKFLAGS \ - (DB_AUTO_COMMIT | DB_CREATE | DB_EXCL | DB_FCNTL_LOCKING | \ - DB_NOMMAP | DB_NO_AUTO_COMMIT | DB_RDONLY | DB_RDWRMASTER | \ - DB_READ_UNCOMMITTED | DB_THREAD | DB_TRUNCATE | DB_WRITEOPEN) - if ((ret = __db_fchk(dbenv, "DB->open", flags, OKFLAGS)) != 0) - return (ret); - if (LF_ISSET(DB_EXCL) && !LF_ISSET(DB_CREATE)) - return (__db_ferr(dbenv, "DB->open", 1)); - if (LF_ISSET(DB_RDONLY) && LF_ISSET(DB_CREATE)) - return (__db_ferr(dbenv, "DB->open", 1)); - -#ifdef HAVE_VXWORKS - if (LF_ISSET(DB_TRUNCATE)) { - __db_err(dbenv, "DB_TRUNCATE not supported on VxWorks"); - return (DB_OPNOTSUP); - } -#endif - switch (type) { - case DB_UNKNOWN: - if (LF_ISSET(DB_CREATE|DB_TRUNCATE)) { - __db_err(dbenv, - "DB_UNKNOWN type specified with DB_CREATE or DB_TRUNCATE"); - return (EINVAL); - } - ok_flags = 0; - break; - case DB_BTREE: - ok_flags = DB_OK_BTREE; - break; - case DB_HASH: -#ifndef HAVE_HASH - return (__db_no_hash_am(dbenv)); -#endif - ok_flags = DB_OK_HASH; - break; - case DB_QUEUE: -#ifndef HAVE_QUEUE - return (__db_no_queue_am(dbenv)); -#endif - ok_flags = DB_OK_QUEUE; - break; - case DB_RECNO: - ok_flags = DB_OK_RECNO; - break; - default: - __db_err(dbenv, "unknown type: %lu", (u_long)type); - return (EINVAL); - } - if (ok_flags) - DB_ILLEGAL_METHOD(dbp, ok_flags); - - /* The environment may have been created, but never opened. */ - if (!F_ISSET(dbenv, DB_ENV_DBLOCAL | DB_ENV_OPEN_CALLED)) { - __db_err(dbenv, "environment not yet opened"); - return (EINVAL); - } - - /* - * Historically, you could pass in an environment that didn't have a - * mpool, and DB would create a private one behind the scenes. This - * no longer works. - */ - if (!F_ISSET(dbenv, DB_ENV_DBLOCAL) && !MPOOL_ON(dbenv)) { - __db_err(dbenv, "environment did not include a memory pool"); - return (EINVAL); - } - - /* - * You can't specify threads during DB->open if subsystems in the - * environment weren't configured with them. - */ - if (LF_ISSET(DB_THREAD) && - !F_ISSET(dbenv, DB_ENV_DBLOCAL | DB_ENV_THREAD)) { - __db_err(dbenv, "environment not created using DB_THREAD"); - return (EINVAL); - } - - /* DB_TRUNCATE is neither transaction recoverable nor lockable. */ - if (LF_ISSET(DB_TRUNCATE) && (LOCKING_ON(dbenv) || txn != NULL)) { - __db_err(dbenv, - "DB_TRUNCATE illegal with %s specified", - LOCKING_ON(dbenv) ? "locking" : "transactions"); - return (EINVAL); - } - - /* Subdatabase checks. */ - if (dname != NULL) { - /* QAM can only be done on in-memory subdatabases. */ - if (type == DB_QUEUE && fname != NULL) { - __db_err(dbenv, "Queue databases must be one-per-file"); - return (EINVAL); - } - - /* - * Named in-memory databases can't support certain flags, - * so check here. - */ - if (fname == NULL) - F_CLR(dbp, DB_AM_CHKSUM | DB_AM_ENCRYPT); - } - - return (0); -} - -/* - * __db_pget_pp -- - * DB->pget pre/post processing. - * - * PUBLIC: int __db_pget_pp - * PUBLIC: __P((DB *, DB_TXN *, DBT *, DBT *, DBT *, u_int32_t)); - */ -int -__db_pget_pp(dbp, txn, skey, pkey, data, flags) - DB *dbp; - DB_TXN *txn; - DBT *skey, *pkey, *data; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int handle_check, ret, t_ret; - - dbenv = dbp->dbenv; - - PANIC_CHECK(dbenv); - DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->pget"); - - ENV_ENTER(dbenv, ip); - - /* Check for replication block. */ - handle_check = IS_ENV_REPLICATED(dbenv); - if (handle_check && - (ret = __db_rep_enter(dbp, 1, 0, txn != NULL)) != 0) { - handle_check = 0; - goto err; - } - - if ((ret = __db_pget_arg(dbp, pkey, flags)) != 0 || - (ret = __db_get_arg(dbp, skey, data, flags)) != 0) - goto err; - - ret = __db_pget(dbp, txn, skey, pkey, data, flags); - -err: /* Release replication block. */ - if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __db_pget -- - * DB->pget. - * - * PUBLIC: int __db_pget - * PUBLIC: __P((DB *, DB_TXN *, DBT *, DBT *, DBT *, u_int32_t)); - */ -int -__db_pget(dbp, txn, skey, pkey, data, flags) - DB *dbp; - DB_TXN *txn; - DBT *skey, *pkey, *data; - u_int32_t flags; -{ - DBC *dbc; - u_int32_t mode; - int ret, t_ret; - - if (LF_ISSET(DB_READ_UNCOMMITTED)) { - mode = DB_READ_UNCOMMITTED; - LF_CLR(DB_READ_UNCOMMITTED); - } else if (LF_ISSET(DB_READ_COMMITTED)) { - mode = DB_READ_COMMITTED; - LF_CLR(DB_READ_COMMITTED); - } else - mode = 0; - - if ((ret = __db_cursor(dbp, txn, &dbc, mode)) != 0) - return (ret); - - SET_RET_MEM(dbc, dbp); - - DEBUG_LREAD(dbc, txn, "__db_pget", skey, NULL, flags); - - /* - * !!! - * The actual method call is simple, do it inline. - * - * The underlying cursor pget will fill in a default DBT for null - * pkeys, and use the cursor's returned-key memory internally to - * store any intermediate primary keys. However, we've just set - * the returned-key memory to the DB handle's key memory, which - * is unsafe to use if the DB handle is threaded. If the pkey - * argument is NULL, use the DBC-owned returned-key memory - * instead; it'll go away when we close the cursor before we - * return, but in this case that's just fine, as we're not - * returning the primary key. - */ - if (pkey == NULL) - dbc->rkey = &dbc->my_rkey; - - /* - * The cursor is just a perfectly ordinary secondary database cursor. - * Call its c_pget() method to do the dirty work. - */ - if (flags == 0 || flags == DB_RMW) - flags |= DB_SET; - - ret = __db_c_pget(dbc, skey, pkey, data, flags); - - if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __db_pget_arg -- - * Check DB->pget arguments. - */ -static int -__db_pget_arg(dbp, pkey, flags) - DB *dbp; - DBT *pkey; - u_int32_t flags; -{ - DB_ENV *dbenv; - int ret; - - dbenv = dbp->dbenv; - - if (!F_ISSET(dbp, DB_AM_SECONDARY)) { - __db_err(dbenv, - "DB->pget may only be used on secondary indices"); - return (EINVAL); - } - - if (LF_ISSET(DB_MULTIPLE | DB_MULTIPLE_KEY)) { - __db_err(dbenv, - "DB_MULTIPLE and DB_MULTIPLE_KEY may not be used on secondary indices"); - return (EINVAL); - } - - /* DB_CONSUME makes no sense on a secondary index. */ - LF_CLR(DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_RMW); - switch (flags) { - case DB_CONSUME: - case DB_CONSUME_WAIT: - return (__db_ferr(dbenv, "DB->pget", 0)); - default: - /* __db_get_arg will catch the rest. */ - break; - } - - /* - * We allow the pkey field to be NULL, so that we can make the - * two-DBT get calls into wrappers for the three-DBT ones. - */ - if (pkey != NULL && - (ret = __dbt_ferr(dbp, "primary key", pkey, 1)) != 0) - return (ret); - - /* But the pkey field can't be NULL if we're doing a DB_GET_BOTH. */ - if (pkey == NULL && flags == DB_GET_BOTH) { - __db_err(dbenv, - "DB_GET_BOTH on a secondary index requires a primary key"); - return (EINVAL); - } - - return (0); -} - -/* - * __db_put_pp -- - * DB->put pre/post processing. - * - * PUBLIC: int __db_put_pp __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); - */ -int -__db_put_pp(dbp, txn, key, data, flags) - DB *dbp; - DB_TXN *txn; - DBT *key, *data; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int handle_check, ret, txn_local, t_ret; - - dbenv = dbp->dbenv; - txn_local = 0; - - PANIC_CHECK(dbenv); - STRIP_AUTO_COMMIT(flags); - DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->put"); - - ENV_ENTER(dbenv, ip); - - /* Check for replication block. */ - handle_check = IS_ENV_REPLICATED(dbenv); - if (handle_check && - (ret = __db_rep_enter(dbp, 1, 0, txn != NULL)) != 0) { - handle_check = 0; - goto err; - } - - if ((ret = __db_put_arg(dbp, key, data, flags)) != 0) - goto err; - - /* Create local transaction as necessary. */ - if (IS_DB_AUTO_COMMIT(dbp, txn)) { - if ((ret = __txn_begin(dbenv, NULL, &txn, 0)) != 0) - goto err; - txn_local = 1; - } - - /* Check for consistent transaction usage. */ - if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 0)) != 0) - goto err; - - ret = __db_put(dbp, txn, key, data, flags); - -err: if (txn_local && - (t_ret = __db_txn_auto_resolve(dbenv, txn, 0, ret)) && ret == 0) - ret = t_ret; - - /* Release replication block. */ - if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __db_put_arg -- - * Check DB->put arguments. - */ -static int -__db_put_arg(dbp, key, data, flags) - DB *dbp; - DBT *key, *data; - u_int32_t flags; -{ - DB_ENV *dbenv; - int ret, returnkey; - - dbenv = dbp->dbenv; - returnkey = 0; - - /* Check for changes to a read-only tree. */ - if (DB_IS_READONLY(dbp)) - return (__db_rdonly(dbenv, "DB->put")); - - /* Check for puts on a secondary. */ - if (F_ISSET(dbp, DB_AM_SECONDARY)) { - __db_err(dbenv, "DB->put forbidden on secondary indices"); - return (EINVAL); - } - - /* Check for invalid function flags. */ - switch (flags) { - case 0: - case DB_NOOVERWRITE: - break; - case DB_APPEND: - if (dbp->type != DB_RECNO && dbp->type != DB_QUEUE) - goto err; - returnkey = 1; - break; - case DB_NODUPDATA: - if (F_ISSET(dbp, DB_AM_DUPSORT)) - break; - /* FALLTHROUGH */ - default: -err: return (__db_ferr(dbenv, "DB->put", 0)); - } - - /* Check for invalid key/data flags. */ - if ((ret = __dbt_ferr(dbp, "key", key, returnkey)) != 0) - return (ret); - if ((ret = __dbt_ferr(dbp, "data", data, 0)) != 0) - return (ret); - - /* Keys shouldn't have partial flags during a put. */ - if (F_ISSET(key, DB_DBT_PARTIAL)) - return (__db_ferr(dbenv, "key DBT", 0)); - - /* Check for partial puts in the presence of duplicates. */ - if (F_ISSET(data, DB_DBT_PARTIAL) && - (F_ISSET(dbp, DB_AM_DUP) || F_ISSET(key, DB_DBT_DUPOK))) { - __db_err(dbenv, -"a partial put in the presence of duplicates requires a cursor operation"); - return (EINVAL); - } - - return (0); -} - -/* - * __db_compact_pp -- - * DB->compact pre/post processing. - * - * PUBLIC: int __db_compact_pp __P((DB *, DB_TXN *, - * PUBLIC: DBT *, DBT *, DB_COMPACT *, u_int32_t, DBT *)); - */ -int -__db_compact_pp(dbp, txn, start, stop, c_data, flags, end) - DB *dbp; - DB_TXN *txn; - DBT *start, *stop; - DB_COMPACT *c_data; - u_int32_t flags; - DBT *end; -{ - DB_COMPACT *dp, l_data; - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int handle_check, ret, t_ret; - - dbenv = dbp->dbenv; - - PANIC_CHECK(dbenv); - DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->compact"); - - /* - * !!! - * The actual argument checking is simple, do it inline, outside of - * the replication block. - */ - if ((flags & ~DB_COMPACT_FLAGS) != 0) - return (__db_ferr(dbenv, "DB->compact", 0)); - - /* Check for changes to a read-only database. */ - if (DB_IS_READONLY(dbp)) - return (__db_rdonly(dbenv, "DB->compact")); - - ENV_ENTER(dbenv, ip); - - /* Check for replication block. */ - handle_check = IS_ENV_REPLICATED(dbenv); - if (handle_check && (ret = __db_rep_enter(dbp, 1, 0, 0)) != 0) { - handle_check = 0; - goto err; - } - - if (c_data == NULL) { - dp = &l_data; - memset(dp, 0, sizeof(*dp)); - } else - dp = c_data; - - switch (dbp->type) { - case DB_HASH: - if (!LF_ISSET(DB_FREELIST_ONLY)) - goto err; - /* FALLTHROUGH */ - case DB_BTREE: - case DB_RECNO: - ret = __bam_compact(dbp, txn, start, stop, dp, flags, end); - break; - - default: -err: ret = __dbh_am_chk(dbp, DB_OK_BTREE); - break; - } - - /* Release replication block. */ - if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __db_sync_pp -- - * DB->sync pre/post processing. - * - * PUBLIC: int __db_sync_pp __P((DB *, u_int32_t)); - */ -int -__db_sync_pp(dbp, flags) - DB *dbp; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int handle_check, ret, t_ret; - - dbenv = dbp->dbenv; - - PANIC_CHECK(dbenv); - DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->sync"); - - /* - * !!! - * The actual argument checking is simple, do it inline, outside of - * the replication block. - */ - if (flags != 0) - return (__db_ferr(dbenv, "DB->sync", 0)); - - ENV_ENTER(dbenv, ip); - - /* Check for replication block. */ - handle_check = IS_ENV_REPLICATED(dbenv); - if (handle_check && (ret = __db_rep_enter(dbp, 1, 0, 0)) != 0) { - handle_check = 0; - goto err; - } - - ret = __db_sync(dbp); - - /* Release replication block. */ - if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - -err: ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __db_c_close_pp -- - * DBC->c_close pre/post processing. - * - * PUBLIC: int __db_c_close_pp __P((DBC *)); - */ -int -__db_c_close_pp(dbc) - DBC *dbc; -{ - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - DB *dbp; - int handle_check, ret, t_ret; - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - - PANIC_CHECK(dbenv); - ENV_ENTER(dbenv, ip); - - /* - * If the cursor is already closed we have a serious problem, and we - * assume that the cursor isn't on the active queue. Don't do any of - * the remaining cursor close processing. - */ - if (!F_ISSET(dbc, DBC_ACTIVE)) { - if (dbp != NULL) - __db_err(dbenv, "Closing already-closed cursor"); - DB_ASSERT(0); - ret = EINVAL; - goto err; - } - - /* Check for replication block. */ - handle_check = dbc->txn == NULL && IS_ENV_REPLICATED(dbenv); - ret = __db_c_close(dbc); - - /* Release replication block. */ - if (handle_check && - (t_ret = __op_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - -err: ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __db_c_count_pp -- - * DBC->c_count pre/post processing. - * - * PUBLIC: int __db_c_count_pp __P((DBC *, db_recno_t *, u_int32_t)); - */ -int -__db_c_count_pp(dbc, recnop, flags) - DBC *dbc; - db_recno_t *recnop; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - DB *dbp; - int ret; - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - - PANIC_CHECK(dbenv); - - /* - * !!! - * The actual argument checking is simple, do it inline, outside of - * the replication block. - * - * The cursor must be initialized, return EINVAL for an invalid cursor. - */ - if (flags != 0) - return (__db_ferr(dbenv, "DBcursor->count", 0)); - - if (!IS_INITIALIZED(dbc)) - return (__db_curinval(dbenv)); - - ENV_ENTER(dbenv, ip); - - ret = __db_c_count(dbc, recnop); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __db_c_del_pp -- - * DBC->c_del pre/post processing. - * - * PUBLIC: int __db_c_del_pp __P((DBC *, u_int32_t)); - */ -int -__db_c_del_pp(dbc, flags) - DBC *dbc; - u_int32_t flags; -{ - DB *dbp; - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int ret; - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - - PANIC_CHECK(dbenv); - - if ((ret = __db_c_del_arg(dbc, flags)) != 0) - return (ret); - - ENV_ENTER(dbenv, ip); - - /* Check for consistent transaction usage. */ - if ((ret = __db_check_txn(dbp, dbc->txn, dbc->locker, 0)) != 0) - goto err; - - DEBUG_LWRITE(dbc, dbc->txn, "DBcursor->del", NULL, NULL, flags); - ret = __db_c_del(dbc, flags); -err: - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __db_c_del_arg -- - * Check DBC->c_del arguments. - */ -static int -__db_c_del_arg(dbc, flags) - DBC *dbc; - u_int32_t flags; -{ - DB *dbp; - DB_ENV *dbenv; - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - - /* Check for changes to a read-only tree. */ - if (DB_IS_READONLY(dbp)) - return (__db_rdonly(dbenv, "DBcursor->del")); - - /* Check for invalid function flags. */ - switch (flags) { - case 0: - break; - case DB_UPDATE_SECONDARY: - DB_ASSERT(F_ISSET(dbp, DB_AM_SECONDARY)); - break; - default: - return (__db_ferr(dbenv, "DBcursor->del", 0)); - } - - /* - * The cursor must be initialized, return EINVAL for an invalid cursor, - * otherwise 0. - */ - if (!IS_INITIALIZED(dbc)) - return (__db_curinval(dbenv)); - - return (0); -} - -/* - * __db_c_dup_pp -- - * DBC->c_dup pre/post processing. - * - * PUBLIC: int __db_c_dup_pp __P((DBC *, DBC **, u_int32_t)); - */ -int -__db_c_dup_pp(dbc, dbcp, flags) - DBC *dbc, **dbcp; - u_int32_t flags; -{ - DB *dbp; - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int ret; - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - - PANIC_CHECK(dbenv); - - /* - * !!! - * The actual argument checking is simple, do it inline, outside of - * the replication block. - */ - if (flags != 0 && flags != DB_POSITION) - return (__db_ferr(dbenv, "DBcursor->dup", 0)); - - ENV_ENTER(dbenv, ip); - - ret = __db_c_dup(dbc, dbcp, flags); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __db_c_get_pp -- - * DBC->c_get pre/post processing. - * - * PUBLIC: int __db_c_get_pp __P((DBC *, DBT *, DBT *, u_int32_t)); - */ -int -__db_c_get_pp(dbc, key, data, flags) - DBC *dbc; - DBT *key, *data; - u_int32_t flags; -{ - DB *dbp; - DB_ENV *dbenv; - int ret; - DB_THREAD_INFO *ip; - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - - PANIC_CHECK(dbenv); - - if ((ret = __db_c_get_arg(dbc, key, data, flags)) != 0) - return (ret); - - ENV_ENTER(dbenv, ip); - - DEBUG_LREAD(dbc, dbc->txn, "DBcursor->get", - flags == DB_SET || flags == DB_SET_RANGE ? key : NULL, NULL, flags); - ret = __db_c_get(dbc, key, data, flags); - - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __db_c_get_arg -- - * Common DBC->get argument checking, used by both DBC->get and DBC->pget. - */ -static int -__db_c_get_arg(dbc, key, data, flags) - DBC *dbc; - DBT *key, *data; - u_int32_t flags; -{ - DB *dbp; - DB_ENV *dbenv; - int dirty, multi, ret; - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - - /* - * Typically in checking routines that modify the flags, we have - * to save them and restore them, because the checking routine - * calls the work routine. However, this is a pure-checking - * routine which returns to a function that calls the work routine, - * so it's OK that we do not save and restore the flags, even though - * we modify them. - * - * Check for read-modify-write validity. DB_RMW doesn't make sense - * with CDB cursors since if you're going to write the cursor, you - * had to create it with DB_WRITECURSOR. Regardless, we check for - * LOCKING_ON and not STD_LOCKING, as we don't want to disallow it. - * If this changes, confirm that DB does not itself set the DB_RMW - * flag in a path where CDB may have been configured. - */ - dirty = 0; - if (LF_ISSET(DB_READ_UNCOMMITTED | DB_RMW)) { - if (!LOCKING_ON(dbenv)) - return (__db_fnl(dbenv, "DBcursor->get")); - if (LF_ISSET(DB_READ_UNCOMMITTED)) - dirty = 1; - LF_CLR(DB_READ_UNCOMMITTED | DB_RMW); - } - - multi = 0; - if (LF_ISSET(DB_MULTIPLE | DB_MULTIPLE_KEY)) { - multi = 1; - if (LF_ISSET(DB_MULTIPLE) && LF_ISSET(DB_MULTIPLE_KEY)) - goto multi_err; - LF_CLR(DB_MULTIPLE | DB_MULTIPLE_KEY); - } - - /* Check for invalid function flags. */ - switch (flags) { - case DB_CONSUME: - case DB_CONSUME_WAIT: - if (dirty) { - __db_err(dbenv, - "DB_READ_UNCOMMITTED is not supported with DB_CONSUME or DB_CONSUME_WAIT"); - return (EINVAL); - } - if (dbp->type != DB_QUEUE) - goto err; - break; - case DB_CURRENT: - case DB_FIRST: - case DB_GET_BOTH: - case DB_GET_BOTH_RANGE: - case DB_NEXT: - case DB_NEXT_DUP: - case DB_NEXT_NODUP: - case DB_SET: - case DB_SET_RANGE: - break; - case DB_LAST: - case DB_PREV: - case DB_PREV_NODUP: - if (multi) -multi_err: return (__db_ferr(dbenv, "DBcursor->get", 1)); - break; - case DB_GET_BOTHC: - if (dbp->type == DB_QUEUE) - goto err; - break; - case DB_GET_RECNO: - /* - * The one situation in which this might be legal with a - * non-RECNUM dbp is if dbp is a secondary and its primary is - * DB_AM_RECNUM. - */ - if (!F_ISSET(dbp, DB_AM_RECNUM) && - (!F_ISSET(dbp, DB_AM_SECONDARY) || - !F_ISSET(dbp->s_primary, DB_AM_RECNUM))) - goto err; - break; - case DB_SET_RECNO: - if (!F_ISSET(dbp, DB_AM_RECNUM)) - goto err; - break; - default: -err: return (__db_ferr(dbenv, "DBcursor->get", 0)); - } - - /* Check for invalid key/data flags. */ - if ((ret = __dbt_ferr(dbp, "key", key, 0)) != 0) - return (ret); - if ((ret = __dbt_ferr(dbp, "data", data, 0)) != 0) - return (ret); - - if (multi) { - if (!F_ISSET(data, DB_DBT_USERMEM)) { - __db_err(dbenv, - "DB_MULTIPLE/DB_MULTIPLE_KEY require DB_DBT_USERMEM be set"); - return (EINVAL); - } - if (F_ISSET(key, DB_DBT_PARTIAL) || - F_ISSET(data, DB_DBT_PARTIAL)) { - __db_err(dbenv, - "DB_MULTIPLE/DB_MULTIPLE_KEY do not support DB_DBT_PARTIAL"); - return (EINVAL); - } - if (data->ulen < 1024 || - data->ulen < dbp->pgsize || data->ulen % 1024 != 0) { - __db_err(dbenv, "%s%s", - "DB_MULTIPLE/DB_MULTIPLE_KEY buffers must be ", - "aligned, at least page size and multiples of 1KB"); - return (EINVAL); - } - } - - /* - * The cursor must be initialized for DB_CURRENT, DB_GET_RECNO and - * DB_NEXT_DUP. Return EINVAL for an invalid cursor, otherwise 0. - */ - if (!IS_INITIALIZED(dbc) && (flags == DB_CURRENT || - flags == DB_GET_RECNO || flags == DB_NEXT_DUP)) - return (__db_curinval(dbenv)); - - /* Check for consistent transaction usage. */ - if (LF_ISSET(DB_RMW) && - (ret = __db_check_txn(dbp, dbc->txn, dbc->locker, 0)) != 0) - return (ret); - - return (0); -} - -/* - * __db_secondary_close_pp -- - * DB->close for secondaries - * - * PUBLIC: int __db_secondary_close_pp __P((DB *, u_int32_t)); - */ -int -__db_secondary_close_pp(dbp, flags) - DB *dbp; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int handle_check, ret, t_ret; - - dbenv = dbp->dbenv; - ret = 0; - - PANIC_CHECK(dbenv); - - /* - * As a DB handle destructor, we can't fail. - * - * !!! - * The actual argument checking is simple, do it inline, outside of - * the replication block. - */ - if (flags != 0 && flags != DB_NOSYNC) - ret = __db_ferr(dbenv, "DB->close", 0); - - ENV_ENTER(dbenv, ip); - - /* Check for replication block. */ - handle_check = IS_ENV_REPLICATED(dbenv); - if (handle_check && (t_ret = __db_rep_enter(dbp, 0, 0, 0)) != 0) { - handle_check = 0; - if (ret == 0) - ret = t_ret; - } - - if ((t_ret = __db_secondary_close(dbp, flags)) != 0 && ret == 0) - ret = t_ret; - - /* Release replication block. */ - if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __db_c_pget_pp -- - * DBC->c_pget pre/post processing. - * - * PUBLIC: int __db_c_pget_pp __P((DBC *, DBT *, DBT *, DBT *, u_int32_t)); - */ -int -__db_c_pget_pp(dbc, skey, pkey, data, flags) - DBC *dbc; - DBT *skey, *pkey, *data; - u_int32_t flags; -{ - DB *dbp; - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int ret; - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - - PANIC_CHECK(dbenv); - - if ((ret = __db_c_pget_arg(dbc, pkey, flags)) != 0 || - (ret = __db_c_get_arg(dbc, skey, data, flags)) != 0) - return (ret); - - ENV_ENTER(dbenv, ip); - - ret = __db_c_pget(dbc, skey, pkey, data, flags); - - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __db_c_pget_arg -- - * Check DBC->pget arguments. - */ -static int -__db_c_pget_arg(dbc, pkey, flags) - DBC *dbc; - DBT *pkey; - u_int32_t flags; -{ - DB *dbp; - DB_ENV *dbenv; - int ret; - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - - if (!F_ISSET(dbp, DB_AM_SECONDARY)) { - __db_err(dbenv, - "DBcursor->pget may only be used on secondary indices"); - return (EINVAL); - } - - if (LF_ISSET(DB_MULTIPLE | DB_MULTIPLE_KEY)) { - __db_err(dbenv, - "DB_MULTIPLE and DB_MULTIPLE_KEY may not be used on secondary indices"); - return (EINVAL); - } - - switch (LF_ISSET(~DB_RMW)) { - case DB_CONSUME: - case DB_CONSUME_WAIT: - /* These flags make no sense on a secondary index. */ - return (__db_ferr(dbenv, "DBcursor->pget", 0)); - case DB_GET_BOTH: - /* DB_GET_BOTH is "get both the primary and the secondary". */ - if (pkey == NULL) { - __db_err(dbenv, - "DB_GET_BOTH requires both a secondary and a primary key"); - return (EINVAL); - } - break; - default: - /* __db_c_get_arg will catch the rest. */ - break; - } - - /* - * We allow the pkey field to be NULL, so that we can make the - * two-DBT get calls into wrappers for the three-DBT ones. - */ - if (pkey != NULL && - (ret = __dbt_ferr(dbp, "primary key", pkey, 0)) != 0) - return (ret); - - /* But the pkey field can't be NULL if we're doing a DB_GET_BOTH. */ - if (pkey == NULL && (flags & DB_OPFLAGS_MASK) == DB_GET_BOTH) { - __db_err(dbenv, - "DB_GET_BOTH on a secondary index requires a primary key"); - return (EINVAL); - } - return (0); -} - -/* - * __db_c_put_pp -- - * DBC->put pre/post processing. - * - * PUBLIC: int __db_c_put_pp __P((DBC *, DBT *, DBT *, u_int32_t)); - */ -int -__db_c_put_pp(dbc, key, data, flags) - DBC *dbc; - DBT *key, *data; - u_int32_t flags; -{ - DB *dbp; - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int ret; - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - - PANIC_CHECK(dbenv); - - if ((ret = __db_c_put_arg(dbc, key, data, flags)) != 0) - return (ret); - - ENV_ENTER(dbenv, ip); - - /* Check for consistent transaction usage. */ - if ((ret = __db_check_txn(dbp, dbc->txn, dbc->locker, 0)) != 0) - goto err; - - DEBUG_LWRITE(dbc, dbc->txn, "DBcursor->put", - flags == DB_KEYFIRST || flags == DB_KEYLAST || - flags == DB_NODUPDATA || flags == DB_UPDATE_SECONDARY ? - key : NULL, data, flags); - ret =__db_c_put(dbc, key, data, flags); -err: - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __db_c_put_arg -- - * Check DBC->put arguments. - */ -static int -__db_c_put_arg(dbc, key, data, flags) - DBC *dbc; - DBT *key, *data; - u_int32_t flags; -{ - DB *dbp; - DB_ENV *dbenv; - int key_flags, ret; - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - key_flags = 0; - - /* Check for changes to a read-only tree. */ - if (DB_IS_READONLY(dbp)) - return (__db_rdonly(dbenv, "DBcursor->put")); - - /* Check for puts on a secondary. */ - if (F_ISSET(dbp, DB_AM_SECONDARY)) { - if (flags == DB_UPDATE_SECONDARY) - flags = DB_KEYLAST; - else { - __db_err(dbenv, - "DBcursor->put forbidden on secondary indices"); - return (EINVAL); - } - } - - /* Check for invalid function flags. */ - switch (flags) { - case DB_AFTER: - case DB_BEFORE: - switch (dbp->type) { - case DB_BTREE: - case DB_HASH: /* Only with unsorted duplicates. */ - if (!F_ISSET(dbp, DB_AM_DUP)) - goto err; - if (dbp->dup_compare != NULL) - goto err; - break; - case DB_QUEUE: /* Not permitted. */ - goto err; - case DB_RECNO: /* Only with mutable record numbers. */ - if (!F_ISSET(dbp, DB_AM_RENUMBER)) - goto err; - key_flags = 1; - break; - case DB_UNKNOWN: - default: - goto err; - } - break; - case DB_CURRENT: - /* - * If there is a comparison function, doing a DB_CURRENT - * must not change the part of the data item that is used - * for the comparison. - */ - break; - case DB_NODUPDATA: - if (!F_ISSET(dbp, DB_AM_DUPSORT)) - goto err; - /* FALLTHROUGH */ - case DB_KEYFIRST: - case DB_KEYLAST: - key_flags = 1; - break; - default: -err: return (__db_ferr(dbenv, "DBcursor->put", 0)); - } - - /* Check for invalid key/data flags. */ - if (key_flags && (ret = __dbt_ferr(dbp, "key", key, 0)) != 0) - return (ret); - if ((ret = __dbt_ferr(dbp, "data", data, 0)) != 0) - return (ret); - - /* Keys shouldn't have partial flags during a put. */ - if (F_ISSET(key, DB_DBT_PARTIAL)) - return (__db_ferr(dbenv, "key DBT", 0)); - - /* - * The cursor must be initialized for anything other than DB_KEYFIRST - * and DB_KEYLAST, return EINVAL for an invalid cursor, otherwise 0. - */ - if (!IS_INITIALIZED(dbc) && flags != DB_KEYFIRST && - flags != DB_KEYLAST && flags != DB_NODUPDATA) - return (__db_curinval(dbenv)); - - return (0); -} - -/* - * __dbt_ferr -- - * Check a DBT for flag errors. - */ -static int -__dbt_ferr(dbp, name, dbt, check_thread) - const DB *dbp; - const char *name; - const DBT *dbt; - int check_thread; -{ - DB_ENV *dbenv; - int ret; - - dbenv = dbp->dbenv; - - /* - * Check for invalid DBT flags. We allow any of the flags to be - * specified to any DB or DBcursor call so that applications can - * set DB_DBT_MALLOC when retrieving a data item from a secondary - * database and then specify that same DBT as a key to a primary - * database, without having to clear flags. - */ - if ((ret = __db_fchk(dbenv, name, dbt->flags, DB_DBT_APPMALLOC | - DB_DBT_MALLOC | DB_DBT_DUPOK | DB_DBT_REALLOC | DB_DBT_USERMEM | - DB_DBT_PARTIAL)) != 0) - return (ret); - switch (F_ISSET(dbt, DB_DBT_MALLOC | DB_DBT_REALLOC | DB_DBT_USERMEM)) { - case 0: - case DB_DBT_MALLOC: - case DB_DBT_REALLOC: - case DB_DBT_USERMEM: - break; - default: - return (__db_ferr(dbenv, name, 1)); - } - - if (check_thread && DB_IS_THREADED(dbp) && - !F_ISSET(dbt, DB_DBT_MALLOC | DB_DBT_REALLOC | DB_DBT_USERMEM)) { - __db_err(dbenv, - "DB_THREAD mandates memory allocation flag on DBT %s", - name); - return (EINVAL); - } - return (0); -} - -/* - * __db_curinval - * Report that a cursor is in an invalid state. - */ -static int -__db_curinval(dbenv) - const DB_ENV *dbenv; -{ - __db_err(dbenv, - "Cursor position must be set before performing this operation"); - return (EINVAL); -} - -/* - * __db_txn_auto_init -- - * Handle DB_AUTO_COMMIT initialization. - * - * PUBLIC: int __db_txn_auto_init __P((DB_ENV *, DB_TXN **)); - */ -int -__db_txn_auto_init(dbenv, txnidp) - DB_ENV *dbenv; - DB_TXN **txnidp; -{ - /* - * Method calls where applications explicitly specify DB_AUTO_COMMIT - * require additional validation: the DB_AUTO_COMMIT flag cannot be - * specified if a transaction cookie is also specified, nor can the - * flag be specified in a non-transactional environment. - */ - if (*txnidp != NULL) { - __db_err(dbenv, - "DB_AUTO_COMMIT may not be specified along with a transaction handle"); - return (EINVAL); - } - - if (!TXN_ON(dbenv)) { - __db_err(dbenv, - "DB_AUTO_COMMIT may not be specified in non-transactional environment"); - return (EINVAL); - } - - /* - * Our caller checked to see if replication is making a state change. - * Don't call the user-level API (which would repeat that check). - */ - return (__txn_begin(dbenv, NULL, txnidp, 0)); -} - -/* - * __db_txn_auto_resolve -- - * Resolve local transactions. - * - * PUBLIC: int __db_txn_auto_resolve __P((DB_ENV *, DB_TXN *, int, int)); - */ -int -__db_txn_auto_resolve(dbenv, txn, nosync, ret) - DB_ENV *dbenv; - DB_TXN *txn; - int nosync, ret; -{ - int t_ret; - - /* - * We're resolving a transaction for the user, and must decrement the - * replication handle count. Call the user-level API. - */ - if (ret == 0) - return (__txn_commit(txn, nosync ? DB_TXN_NOSYNC : 0)); - - if ((t_ret = __txn_abort(txn)) != 0) - return (__db_panic(dbenv, t_ret)); - - return (ret); -} diff --git a/storage/bdb/db/db_join.c b/storage/bdb/db/db_join.c deleted file mode 100644 index 720891ac07e..00000000000 --- a/storage/bdb/db/db_join.c +++ /dev/null @@ -1,942 +0,0 @@ -/* - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1998-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_join.c,v 12.6 2005/10/07 20:21:22 ubell Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stdlib.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_join.h" -#include "dbinc/btree.h" - -static int __db_join_close_pp __P((DBC *)); -static int __db_join_cmp __P((const void *, const void *)); -static int __db_join_del __P((DBC *, u_int32_t)); -static int __db_join_get __P((DBC *, DBT *, DBT *, u_int32_t)); -static int __db_join_get_pp __P((DBC *, DBT *, DBT *, u_int32_t)); -static int __db_join_getnext __P((DBC *, DBT *, DBT *, u_int32_t, u_int32_t)); -static int __db_join_primget __P((DB *, - DB_TXN *, u_int32_t, DBT *, DBT *, u_int32_t)); -static int __db_join_put __P((DBC *, DBT *, DBT *, u_int32_t)); - -/* - * Check to see if the Nth secondary cursor of join cursor jc is pointing - * to a sorted duplicate set. - */ -#define SORTED_SET(jc, n) ((jc)->j_curslist[(n)]->dbp->dup_compare != NULL) - -/* - * This is the duplicate-assisted join functionality. Right now we're - * going to write it such that we return one item at a time, although - * I think we may need to optimize it to return them all at once. - * It should be easier to get it working this way, and I believe that - * changing it should be fairly straightforward. - * - * We optimize the join by sorting cursors from smallest to largest - * cardinality. In most cases, this is indeed optimal. However, if - * a cursor with large cardinality has very few data in common with the - * first cursor, it is possible that the join will be made faster by - * putting it earlier in the cursor list. Since we have no way to detect - * cases like this, we simply provide a flag, DB_JOIN_NOSORT, which retains - * the sort order specified by the caller, who may know more about the - * structure of the data. - * - * The first cursor moves sequentially through the duplicate set while - * the others search explicitly for the duplicate in question. - * - */ - -/* - * __db_join -- - * This is the interface to the duplicate-assisted join functionality. - * In the same way that cursors mark a position in a database, a cursor - * can mark a position in a join. While most cursors are created by the - * cursor method of a DB, join cursors are created through an explicit - * call to DB->join. - * - * The curslist is an array of existing, initialized cursors and primary - * is the DB of the primary file. The data item that joins all the - * cursors in the curslist is used as the key into the primary and that - * key and data are returned. When no more items are left in the join - * set, the c_next operation off the join cursor will return DB_NOTFOUND. - * - * PUBLIC: int __db_join __P((DB *, DBC **, DBC **, u_int32_t)); - */ -int -__db_join(primary, curslist, dbcp, flags) - DB *primary; - DBC **curslist, **dbcp; - u_int32_t flags; -{ - DB_ENV *dbenv; - DBC *dbc; - JOIN_CURSOR *jc; - size_t ncurs, nslots; - u_int32_t i; - int ret; - - dbenv = primary->dbenv; - dbc = NULL; - jc = NULL; - - if ((ret = __os_calloc(dbenv, 1, sizeof(DBC), &dbc)) != 0) - goto err; - - if ((ret = __os_calloc(dbenv, 1, sizeof(JOIN_CURSOR), &jc)) != 0) - goto err; - - if ((ret = __os_malloc(dbenv, 256, &jc->j_key.data)) != 0) - goto err; - jc->j_key.ulen = 256; - F_SET(&jc->j_key, DB_DBT_USERMEM); - - F_SET(&jc->j_rdata, DB_DBT_REALLOC); - - for (jc->j_curslist = curslist; - *jc->j_curslist != NULL; jc->j_curslist++) - ; - - /* - * The number of cursor slots we allocate is one greater than - * the number of cursors involved in the join, because the - * list is NULL-terminated. - */ - ncurs = (size_t)(jc->j_curslist - curslist); - nslots = ncurs + 1; - - /* - * !!! -- A note on the various lists hanging off jc. - * - * j_curslist is the initial NULL-terminated list of cursors passed - * into __db_join. The original cursors are not modified; pristine - * copies are required because, in databases with unsorted dups, we - * must reset all of the secondary cursors after the first each - * time the first one is incremented, or else we will lose data - * which happen to be sorted differently in two different cursors. - * - * j_workcurs is where we put those copies that we're planning to - * work with. They're lazily c_dup'ed from j_curslist as we need - * them, and closed when the join cursor is closed or when we need - * to reset them to their original values (in which case we just - * c_dup afresh). - * - * j_fdupcurs is an array of cursors which point to the first - * duplicate in the duplicate set that contains the data value - * we're currently interested in. We need this to make - * __db_join_get correctly return duplicate duplicates; i.e., if a - * given data value occurs twice in the set belonging to cursor #2, - * and thrice in the set belonging to cursor #3, and once in all - * the other cursors, successive calls to __db_join_get need to - * return that data item six times. To make this happen, each time - * cursor N is allowed to advance to a new datum, all cursors M - * such that M > N have to be reset to the first duplicate with - * that datum, so __db_join_get will return all the dup-dups again. - * We could just reset them to the original cursor from j_curslist, - * but that would be a bit slower in the unsorted case and a LOT - * slower in the sorted one. - * - * j_exhausted is a list of boolean values which represent - * whether or not their corresponding cursors are "exhausted", - * i.e. whether the datum under the corresponding cursor has - * been found not to exist in any unreturned combinations of - * later secondary cursors, in which case they are ready to be - * incremented. - */ - - /* We don't want to free regions whose callocs have failed. */ - jc->j_curslist = NULL; - jc->j_workcurs = NULL; - jc->j_fdupcurs = NULL; - jc->j_exhausted = NULL; - - if ((ret = __os_calloc(dbenv, nslots, sizeof(DBC *), - &jc->j_curslist)) != 0) - goto err; - if ((ret = __os_calloc(dbenv, nslots, sizeof(DBC *), - &jc->j_workcurs)) != 0) - goto err; - if ((ret = __os_calloc(dbenv, nslots, sizeof(DBC *), - &jc->j_fdupcurs)) != 0) - goto err; - if ((ret = __os_calloc(dbenv, nslots, sizeof(u_int8_t), - &jc->j_exhausted)) != 0) - goto err; - for (i = 0; curslist[i] != NULL; i++) { - jc->j_curslist[i] = curslist[i]; - jc->j_workcurs[i] = NULL; - jc->j_fdupcurs[i] = NULL; - jc->j_exhausted[i] = 0; - } - jc->j_ncurs = (u_int32_t)ncurs; - - /* - * If DB_JOIN_NOSORT is not set, optimize secondary cursors by - * sorting in order of increasing cardinality. - */ - if (!LF_ISSET(DB_JOIN_NOSORT)) - qsort(jc->j_curslist, ncurs, sizeof(DBC *), __db_join_cmp); - - /* - * We never need to reset the 0th cursor, so there's no - * solid reason to use workcurs[0] rather than curslist[0] in - * join_get. Nonetheless, it feels cleaner to do it for symmetry, - * and this is the most logical place to copy it. - * - * !!! - * There's no need to close the new cursor if we goto err only - * because this is the last thing that can fail. Modifier of this - * function beware! - */ - if ((ret = - __db_c_dup(jc->j_curslist[0], jc->j_workcurs, DB_POSITION)) != 0) - goto err; - - dbc->c_close = __db_join_close_pp; - dbc->c_del = __db_join_del; - dbc->c_get = __db_join_get_pp; - dbc->c_put = __db_join_put; - dbc->internal = (DBC_INTERNAL *)jc; - dbc->dbp = primary; - jc->j_primary = primary; - - /* Stash the first cursor's transaction here for easy access. */ - dbc->txn = curslist[0]->txn; - - *dbcp = dbc; - - MUTEX_LOCK(dbenv, primary->mutex); - TAILQ_INSERT_TAIL(&primary->join_queue, dbc, links); - MUTEX_UNLOCK(dbenv, primary->mutex); - - return (0); - -err: if (jc != NULL) { - if (jc->j_curslist != NULL) - __os_free(dbenv, jc->j_curslist); - if (jc->j_workcurs != NULL) { - if (jc->j_workcurs[0] != NULL) - (void)__db_c_close(jc->j_workcurs[0]); - __os_free(dbenv, jc->j_workcurs); - } - if (jc->j_fdupcurs != NULL) - __os_free(dbenv, jc->j_fdupcurs); - if (jc->j_exhausted != NULL) - __os_free(dbenv, jc->j_exhausted); - __os_free(dbenv, jc); - } - if (dbc != NULL) - __os_free(dbenv, dbc); - return (ret); -} - -/* - * __db_join_close_pp -- - * DBC->c_close pre/post processing for join cursors. - */ -static int -__db_join_close_pp(dbc) - DBC *dbc; -{ - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - DB *dbp; - int handle_check, ret, t_ret; - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - - PANIC_CHECK(dbenv); - - ENV_ENTER(dbenv, ip); - - handle_check = IS_ENV_REPLICATED(dbenv); - if (handle_check && - (ret = __db_rep_enter(dbp, 1, 0, dbc->txn != NULL)) != 0) { - handle_check = 0; - goto err; - } - - ret = __db_join_close(dbc); - - if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - -err: ENV_LEAVE(dbenv, ip); - return (ret); -} - -static int -__db_join_put(dbc, key, data, flags) - DBC *dbc; - DBT *key; - DBT *data; - u_int32_t flags; -{ - PANIC_CHECK(dbc->dbp->dbenv); - - COMPQUIET(key, NULL); - COMPQUIET(data, NULL); - COMPQUIET(flags, 0); - return (EINVAL); -} - -static int -__db_join_del(dbc, flags) - DBC *dbc; - u_int32_t flags; -{ - PANIC_CHECK(dbc->dbp->dbenv); - - COMPQUIET(flags, 0); - return (EINVAL); -} - -/* - * __db_join_get_pp -- - * DBjoin->get pre/post processing. - */ -static int -__db_join_get_pp(dbc, key, data, flags) - DBC *dbc; - DBT *key, *data; - u_int32_t flags; -{ - DB *dbp; - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - u_int32_t handle_check, save_flags; - int ret, t_ret; - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - - /* Save the original flags value. */ - save_flags = flags; - - PANIC_CHECK(dbenv); - - if (LF_ISSET(DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_RMW)) { - if (!LOCKING_ON(dbp->dbenv)) - return (__db_fnl(dbp->dbenv, "DBcursor->c_get")); - LF_CLR(DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_RMW); - } - - switch (flags) { - case 0: - case DB_JOIN_ITEM: - break; - default: - return (__db_ferr(dbp->dbenv, "DBcursor->c_get", 0)); - } - - /* - * A partial get of the key of a join cursor don't make much sense; - * the entire key is necessary to query the primary database - * and find the datum, and so regardless of the size of the key - * it would not be a performance improvement. Since it would require - * special handling, we simply disallow it. - * - * A partial get of the data, however, potentially makes sense (if - * all possible data are a predictable large structure, for instance) - * and causes us no headaches, so we permit it. - */ - if (F_ISSET(key, DB_DBT_PARTIAL)) { - __db_err(dbp->dbenv, - "DB_DBT_PARTIAL may not be set on key during join_get"); - return (EINVAL); - } - - ENV_ENTER(dbenv, ip); - - handle_check = IS_ENV_REPLICATED(dbp->dbenv); - if (handle_check && - (ret = __db_rep_enter(dbp, 1, 0, dbc->txn != NULL)) != 0) { - handle_check = 0; - goto err; - } - - /* Restore the original flags value. */ - flags = save_flags; - - ret = __db_join_get(dbc, key, data, flags); - - if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - -err: ENV_LEAVE(dbenv, ip); - return (ret); -} - -static int -__db_join_get(dbc, key_arg, data_arg, flags) - DBC *dbc; - DBT *key_arg, *data_arg; - u_int32_t flags; -{ - DBT *key_n, key_n_mem; - DB *dbp; - DBC *cp; - JOIN_CURSOR *jc; - int db_manage_data, ret; - u_int32_t i, j, operation, opmods; - - dbp = dbc->dbp; - jc = (JOIN_CURSOR *)dbc->internal; - - operation = LF_ISSET(DB_OPFLAGS_MASK); - - /* !!! - * If the set of flags here changes, check that __db_join_primget - * is updated to handle them properly. - */ - opmods = LF_ISSET(DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_RMW); - - /* - * Since we are fetching the key as a datum in the secondary indices, - * we must be careful of caller-specified DB_DBT_* memory - * management flags. If necessary, use a stack-allocated DBT; - * we'll appropriately copy and/or allocate the data later. - */ - if (F_ISSET(key_arg, DB_DBT_USERMEM) || - F_ISSET(key_arg, DB_DBT_MALLOC)) { - /* We just use the default buffer; no need to go malloc. */ - key_n = &key_n_mem; - memset(key_n, 0, sizeof(DBT)); - } else { - /* - * Either DB_DBT_REALLOC or the default buffer will work - * fine if we have to reuse it, as we do. - */ - key_n = key_arg; - } - - /* - * If our last attempt to do a get on the primary key failed, - * short-circuit the join and try again with the same key. - */ - if (F_ISSET(jc, JOIN_RETRY)) - goto samekey; - F_CLR(jc, JOIN_RETRY); - -retry: ret = __db_c_get(jc->j_workcurs[0], &jc->j_key, key_n, - opmods | (jc->j_exhausted[0] ? DB_NEXT_DUP : DB_CURRENT)); - - if (ret == DB_BUFFER_SMALL) { - jc->j_key.ulen <<= 1; - if ((ret = __os_realloc(dbp->dbenv, - jc->j_key.ulen, &jc->j_key.data)) != 0) - goto mem_err; - goto retry; - } - - /* - * If ret == DB_NOTFOUND, we're out of elements of the first - * secondary cursor. This is how we finally finish the join - * if all goes well. - */ - if (ret != 0) - goto err; - - /* - * If jc->j_exhausted[0] == 1, we've just advanced the first cursor, - * and we're going to want to advance all the cursors that point to - * the first member of a duplicate duplicate set (j_fdupcurs[1..N]). - * Close all the cursors in j_fdupcurs; we'll reopen them the - * first time through the upcoming loop. - */ - for (i = 1; i < jc->j_ncurs; i++) { - if (jc->j_fdupcurs[i] != NULL && - (ret = __db_c_close(jc->j_fdupcurs[i])) != 0) - goto err; - jc->j_fdupcurs[i] = NULL; - } - - /* - * If jc->j_curslist[1] == NULL, we have only one cursor in the join. - * Thus, we can safely increment that one cursor on each call - * to __db_join_get, and we signal this by setting jc->j_exhausted[0] - * right away. - * - * Otherwise, reset jc->j_exhausted[0] to 0, so that we don't - * increment it until we know we're ready to. - */ - if (jc->j_curslist[1] == NULL) - jc->j_exhausted[0] = 1; - else - jc->j_exhausted[0] = 0; - - /* We have the first element; now look for it in the other cursors. */ - for (i = 1; i < jc->j_ncurs; i++) { - DB_ASSERT(jc->j_curslist[i] != NULL); - if (jc->j_workcurs[i] == NULL) - /* If this is NULL, we need to dup curslist into it. */ - if ((ret = __db_c_dup(jc->j_curslist[i], - &jc->j_workcurs[i], DB_POSITION)) != 0) - goto err; - -retry2: cp = jc->j_workcurs[i]; - - if ((ret = __db_join_getnext(cp, &jc->j_key, key_n, - jc->j_exhausted[i], opmods)) == DB_NOTFOUND) { - /* - * jc->j_workcurs[i] has no more of the datum we're - * interested in. Go back one cursor and get - * a new dup. We can't just move to a new - * element of the outer relation, because that way - * we might miss duplicate duplicates in cursor i-1. - * - * If this takes us back to the first cursor, - * -then- we can move to a new element of the outer - * relation. - */ - --i; - jc->j_exhausted[i] = 1; - - if (i == 0) { - for (j = 1; jc->j_workcurs[j] != NULL; j++) { - /* - * We're moving to a new element of - * the first secondary cursor. If - * that cursor is sorted, then any - * other sorted cursors can be safely - * reset to the first duplicate - * duplicate in the current set if we - * have a pointer to it (we can't just - * leave them be, or we'll miss - * duplicate duplicates in the outer - * relation). - * - * If the first cursor is unsorted, or - * if cursor j is unsorted, we can - * make no assumptions about what - * we're looking for next or where it - * will be, so we reset to the very - * beginning (setting workcurs NULL - * will achieve this next go-round). - * - * XXX: This is likely to break - * horribly if any two cursors are - * both sorted, but have different - * specified sort functions. For, - * now, we dismiss this as pathology - * and let strange things happen--we - * can't make rope childproof. - */ - if ((ret = __db_c_close( - jc->j_workcurs[j])) != 0) - goto err; - if (!SORTED_SET(jc, 0) || - !SORTED_SET(jc, j) || - jc->j_fdupcurs[j] == NULL) - /* - * Unsafe conditions; - * reset fully. - */ - jc->j_workcurs[j] = NULL; - else - /* Partial reset suffices. */ - if ((__db_c_dup( - jc->j_fdupcurs[j], - &jc->j_workcurs[j], - DB_POSITION)) != 0) - goto err; - jc->j_exhausted[j] = 0; - } - goto retry; - /* NOTREACHED */ - } - - /* - * We're about to advance the cursor and need to - * reset all of the workcurs[j] where j>i, so that - * we don't miss any duplicate duplicates. - */ - for (j = i + 1; - jc->j_workcurs[j] != NULL; - j++) { - if ((ret = - __db_c_close(jc->j_workcurs[j])) != 0) - goto err; - jc->j_exhausted[j] = 0; - if (jc->j_fdupcurs[j] == NULL) - jc->j_workcurs[j] = NULL; - else if ((ret = __db_c_dup(jc->j_fdupcurs[j], - &jc->j_workcurs[j], DB_POSITION)) != 0) - goto err; - } - goto retry2; - /* NOTREACHED */ - } - - if (ret == DB_BUFFER_SMALL) { - jc->j_key.ulen <<= 1; - if ((ret = __os_realloc(dbp->dbenv, jc->j_key.ulen, - &jc->j_key.data)) != 0) { -mem_err: __db_err(dbp->dbenv, - "Allocation failed for join key, len = %lu", - (u_long)jc->j_key.ulen); - goto err; - } - goto retry2; - } - - if (ret != 0) - goto err; - - /* - * If we made it this far, we've found a matching - * datum in cursor i. Mark the current cursor - * unexhausted, so we don't miss any duplicate - * duplicates the next go-round--unless this is the - * very last cursor, in which case there are none to - * miss, and we'll need that exhausted flag to finally - * get a DB_NOTFOUND and move on to the next datum in - * the outermost cursor. - */ - if (i + 1 != jc->j_ncurs) - jc->j_exhausted[i] = 0; - else - jc->j_exhausted[i] = 1; - - /* - * If jc->j_fdupcurs[i] is NULL and the ith cursor's dups are - * sorted, then we're here for the first time since advancing - * cursor 0, and we have a new datum of interest. - * jc->j_workcurs[i] points to the beginning of a set of - * duplicate duplicates; store this into jc->j_fdupcurs[i]. - */ - if (SORTED_SET(jc, i) && jc->j_fdupcurs[i] == NULL && (ret = - __db_c_dup(cp, &jc->j_fdupcurs[i], DB_POSITION)) != 0) - goto err; - } - -err: if (ret != 0) - return (ret); - - if (0) { -samekey: /* - * Get the key we tried and failed to return last time; - * it should be the current datum of all the secondary cursors. - */ - if ((ret = __db_c_get(jc->j_workcurs[0], - &jc->j_key, key_n, DB_CURRENT | opmods)) != 0) - return (ret); - F_CLR(jc, JOIN_RETRY); - } - - /* - * ret == 0; we have a key to return. - * - * If DB_DBT_USERMEM or DB_DBT_MALLOC is set, we need to copy the key - * back into the dbt we were given for the key; call __db_retcopy. - * Otherwise, assert that we do not need to copy anything and proceed. - */ - DB_ASSERT(F_ISSET( - key_arg, DB_DBT_USERMEM | DB_DBT_MALLOC) || key_n == key_arg); - - if (F_ISSET(key_arg, DB_DBT_USERMEM | DB_DBT_MALLOC) && - (ret = __db_retcopy(dbp->dbenv, - key_arg, key_n->data, key_n->size, NULL, NULL)) != 0) { - /* - * The retcopy failed, most commonly because we have a user - * buffer for the key which is too small. Set things up to - * retry next time, and return. - */ - F_SET(jc, JOIN_RETRY); - return (ret); - } - - /* - * If DB_JOIN_ITEM is set, we return it; otherwise we do the lookup - * in the primary and then return. - * - * Note that we use key_arg here; it is safe (and appropriate) - * to do so. - */ - if (operation == DB_JOIN_ITEM) - return (0); - - /* - * If data_arg->flags == 0--that is, if DB is managing the - * data DBT's memory--it's not safe to just pass the DBT - * through to the primary get call, since we don't want that - * memory to belong to the primary DB handle (and if the primary - * is free-threaded, it can't anyway). - * - * Instead, use memory that is managed by the join cursor, in - * jc->j_rdata. - */ - if (!F_ISSET(data_arg, DB_DBT_MALLOC | DB_DBT_REALLOC | DB_DBT_USERMEM)) - db_manage_data = 1; - else - db_manage_data = 0; - if ((ret = __db_join_primget(jc->j_primary, - jc->j_curslist[0]->txn, jc->j_curslist[0]->locker, key_arg, - db_manage_data ? &jc->j_rdata : data_arg, opmods)) != 0) { - if (ret == DB_NOTFOUND) - /* - * If ret == DB_NOTFOUND, the primary and secondary - * are out of sync; every item in each secondary - * should correspond to something in the primary, - * or we shouldn't have done the join this way. - * Wail. - */ - ret = __db_secondary_corrupt(jc->j_primary); - else - /* - * The get on the primary failed for some other - * reason, most commonly because we're using a user - * buffer that's not big enough. Flag our failure - * so we can return the same key next time. - */ - F_SET(jc, JOIN_RETRY); - } - if (db_manage_data && ret == 0) { - data_arg->data = jc->j_rdata.data; - data_arg->size = jc->j_rdata.size; - } - - return (ret); -} - -/* - * __db_join_close -- - * DBC->c_close for join cursors. - * - * PUBLIC: int __db_join_close __P((DBC *)); - */ -int -__db_join_close(dbc) - DBC *dbc; -{ - DB *dbp; - DB_ENV *dbenv; - JOIN_CURSOR *jc; - int ret, t_ret; - u_int32_t i; - - jc = (JOIN_CURSOR *)dbc->internal; - dbp = dbc->dbp; - dbenv = dbp->dbenv; - ret = t_ret = 0; - - /* - * Remove from active list of join cursors. Note that this - * must happen before any action that can fail and return, or else - * __db_close may loop indefinitely. - */ - MUTEX_LOCK(dbenv, dbp->mutex); - TAILQ_REMOVE(&dbp->join_queue, dbc, links); - MUTEX_UNLOCK(dbenv, dbp->mutex); - - PANIC_CHECK(dbenv); - - /* - * Close any open scratch cursors. In each case, there may - * not be as many outstanding as there are cursors in - * curslist, but we want to close whatever's there. - * - * If any close fails, there's no reason not to close everything else; - * we'll just return the error code of the last one to fail. There's - * not much the caller can do anyway, since these cursors only exist - * hanging off a db-internal data structure that they shouldn't be - * mucking with. - */ - for (i = 0; i < jc->j_ncurs; i++) { - if (jc->j_workcurs[i] != NULL && - (t_ret = __db_c_close(jc->j_workcurs[i])) != 0) - ret = t_ret; - if (jc->j_fdupcurs[i] != NULL && - (t_ret = __db_c_close(jc->j_fdupcurs[i])) != 0) - ret = t_ret; - } - - __os_free(dbenv, jc->j_exhausted); - __os_free(dbenv, jc->j_curslist); - __os_free(dbenv, jc->j_workcurs); - __os_free(dbenv, jc->j_fdupcurs); - __os_free(dbenv, jc->j_key.data); - if (jc->j_rdata.data != NULL) - __os_ufree(dbenv, jc->j_rdata.data); - __os_free(dbenv, jc); - __os_free(dbenv, dbc); - - return (ret); -} - -/* - * __db_join_getnext -- - * This function replaces the DBC_CONTINUE and DBC_KEYSET - * functionality inside the various cursor get routines. - * - * If exhausted == 0, we're not done with the current datum; - * return it if it matches "matching", otherwise search - * using DB_GET_BOTHC (which is faster than iteratively doing - * DB_NEXT_DUP) forward until we find one that does. - * - * If exhausted == 1, we are done with the current datum, so just - * leap forward to searching NEXT_DUPs. - * - * If no matching datum exists, returns DB_NOTFOUND, else 0. - */ -static int -__db_join_getnext(dbc, key, data, exhausted, opmods) - DBC *dbc; - DBT *key, *data; - u_int32_t exhausted, opmods; -{ - int ret, cmp; - DB *dbp; - DBT ldata; - int (*func) __P((DB *, const DBT *, const DBT *)); - - dbp = dbc->dbp; - func = (dbp->dup_compare == NULL) ? __bam_defcmp : dbp->dup_compare; - - switch (exhausted) { - case 0: - /* - * We don't want to step on data->data; use a new - * DBT and malloc so we don't step on dbc's rdata memory. - */ - memset(&ldata, 0, sizeof(DBT)); - F_SET(&ldata, DB_DBT_MALLOC); - if ((ret = __db_c_get(dbc, - key, &ldata, opmods | DB_CURRENT)) != 0) - break; - cmp = func(dbp, data, &ldata); - if (cmp == 0) { - /* - * We have to return the real data value. Copy - * it into data, then free the buffer we malloc'ed - * above. - */ - if ((ret = __db_retcopy(dbp->dbenv, data, ldata.data, - ldata.size, &data->data, &data->size)) != 0) - return (ret); - __os_ufree(dbp->dbenv, ldata.data); - return (0); - } - - /* - * Didn't match--we want to fall through and search future - * dups. We just forget about ldata and free - * its buffer--data contains the value we're searching for. - */ - __os_ufree(dbp->dbenv, ldata.data); - /* FALLTHROUGH */ - case 1: - ret = __db_c_get(dbc, key, data, opmods | DB_GET_BOTHC); - break; - default: - ret = EINVAL; - break; - } - - return (ret); -} - -/* - * __db_join_cmp -- - * Comparison function for sorting DBCs in cardinality order. - */ -static int -__db_join_cmp(a, b) - const void *a, *b; -{ - DBC *dbca, *dbcb; - db_recno_t counta, countb; - - dbca = *((DBC * const *)a); - dbcb = *((DBC * const *)b); - - if (__db_c_count(dbca, &counta) != 0 || - __db_c_count(dbcb, &countb) != 0) - return (0); - - return ((long)counta - (long)countb); -} - -/* - * __db_join_primget -- - * Perform a DB->get in the primary, being careful not to use a new - * locker ID if we're doing CDB locking. - */ -static int -__db_join_primget(dbp, txn, lockerid, key, data, flags) - DB *dbp; - DB_TXN *txn; - u_int32_t lockerid; - DBT *key, *data; - u_int32_t flags; -{ - DBC *dbc; - u_int32_t rmw; - int ret, t_ret; - - if ((ret = __db_cursor_int(dbp, - txn, dbp->type, PGNO_INVALID, 0, lockerid, &dbc)) != 0) - return (ret); - - /* - * The only allowable flags here are the two flags copied into "opmods" - * in __db_join_get, DB_RMW and DB_READ_UNCOMMITTED. The former is an - * op on the c_get call, the latter on the cursor call. It's a DB bug - * if we allow any other flags down in here. - */ - rmw = LF_ISSET(DB_RMW); - if (LF_ISSET(DB_READ_UNCOMMITTED) || - (txn != NULL && F_ISSET(txn, TXN_READ_UNCOMMITTED))) - F_SET(dbc, DBC_READ_UNCOMMITTED); - - if (LF_ISSET(DB_READ_COMMITTED) || - (txn != NULL && F_ISSET(txn, TXN_READ_COMMITTED))) - F_SET(dbc, DBC_READ_COMMITTED); - - LF_CLR(DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_RMW); - DB_ASSERT(flags == 0); - - F_SET(dbc, DBC_TRANSIENT); - - /* - * This shouldn't be necessary, thanks to the fact that join cursors - * swap in their own DB_DBT_REALLOC'ed buffers, but just for form's - * sake, we mirror what __db_get does. - */ - SET_RET_MEM(dbc, dbp); - - ret = __db_c_get(dbc, key, data, DB_SET | rmw); - - if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __db_secondary_corrupt -- - * Report that a secondary index appears corrupt, as it has a record - * that does not correspond to a record in the primary or vice versa. - * - * PUBLIC: int __db_secondary_corrupt __P((DB *)); - */ -int -__db_secondary_corrupt(dbp) - DB *dbp; -{ - __db_err(dbp->dbenv, - "Secondary index corrupt: not consistent with primary"); - return (DB_SECONDARY_BAD); -} diff --git a/storage/bdb/db/db_meta.c b/storage/bdb/db/db_meta.c deleted file mode 100644 index c1264d38fb1..00000000000 --- a/storage/bdb/db/db_meta.c +++ /dev/null @@ -1,1065 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994, 1995, 1996 - * Keith Bostic. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994, 1995 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Mike Olson. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: db_meta.c,v 12.22 2005/10/27 01:46:34 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stdlib.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/lock.h" -#include "dbinc/mp.h" -#include "dbinc/db_am.h" - -static void __db_init_meta __P((DB *, void *, db_pgno_t, u_int32_t)); -#ifdef HAVE_FTRUNCATE -static void __db_freelist_sort __P((struct pglist *, u_int32_t)); -static int __db_pglistcmp __P((const void *, const void *)); -static int __db_truncate_freelist __P((DBC *, DBMETA *, - PAGE *, db_pgno_t *, u_int32_t, u_int32_t)); -#endif - -/* - * __db_init_meta -- - * Helper function for __db_new that initializes the important fields in - * a meta-data page (used instead of P_INIT). We need to make sure that we - * retain the page number and LSN of the existing page. - */ -static void -__db_init_meta(dbp, p, pgno, pgtype) - DB *dbp; - void *p; - db_pgno_t pgno; - u_int32_t pgtype; -{ - DB_LSN save_lsn; - DBMETA *meta; - - meta = (DBMETA *)p; - save_lsn = meta->lsn; - memset(meta, 0, sizeof(DBMETA)); - meta->lsn = save_lsn; - meta->pagesize = dbp->pgsize; - if (F_ISSET(dbp, DB_AM_CHKSUM)) - FLD_SET(meta->metaflags, DBMETA_CHKSUM); - meta->pgno = pgno; - meta->type = (u_int8_t)pgtype; -} - -/* - * __db_new -- - * Get a new page, preferably from the freelist. - * - * PUBLIC: int __db_new __P((DBC *, u_int32_t, PAGE **)); - */ -int -__db_new(dbc, type, pagepp) - DBC *dbc; - u_int32_t type; - PAGE **pagepp; -{ - DBMETA *meta; - DB *dbp; - DB_LOCK metalock; - DB_LSN lsn; - DB_MPOOLFILE *mpf; - PAGE *h; - db_pgno_t last, *list, pgno, newnext; - u_int32_t meta_flags; - int extend, ret, t_ret; - - meta = NULL; - meta_flags = 0; - dbp = dbc->dbp; - mpf = dbp->mpf; - h = NULL; - newnext = PGNO_INVALID; - - pgno = PGNO_BASE_MD; - if ((ret = __db_lget(dbc, - LCK_ALWAYS, pgno, DB_LOCK_WRITE, 0, &metalock)) != 0) - goto err; - if ((ret = __memp_fget(mpf, &pgno, 0, &meta)) != 0) - goto err; - last = meta->last_pgno; - if (meta->free == PGNO_INVALID) { - if (FLD_ISSET(type, P_DONTEXTEND)) { - *pagepp = NULL; - goto err; - } - last = pgno = meta->last_pgno + 1; - ZERO_LSN(lsn); - extend = 1; - } else { - pgno = meta->free; - if ((ret = __memp_fget(mpf, &pgno, 0, &h)) != 0) - goto err; - - /* - * We want to take the first page off the free list and - * then set meta->free to the that page's next_pgno, but - * we need to log the change first. - */ - newnext = h->next_pgno; - lsn = h->lsn; - extend = 0; - } - - FLD_CLR(type, P_DONTEXTEND); - - /* - * Log the allocation before fetching the new page. If we - * don't have room in the log then we don't want to tell - * mpool to extend the file. - */ - if (DBC_LOGGING(dbc)) { - if ((ret = __db_pg_alloc_log(dbp, dbc->txn, &LSN(meta), 0, - &LSN(meta), PGNO_BASE_MD, &lsn, - pgno, (u_int32_t)type, newnext, meta->last_pgno)) != 0) - goto err; - } else - LSN_NOT_LOGGED(LSN(meta)); - - meta_flags = DB_MPOOL_DIRTY; - meta->free = newnext; - - if (extend == 1) { - if ((ret = __memp_fget(mpf, &pgno, DB_MPOOL_NEW, &h)) != 0) - goto err; - DB_ASSERT(last == pgno); - meta->last_pgno = pgno; - ZERO_LSN(h->lsn); - h->pgno = pgno; - } - LSN(h) = LSN(meta); - - DB_ASSERT(TYPE(h) == P_INVALID); - - if (TYPE(h) != P_INVALID) - return (__db_panic(dbp->dbenv, EINVAL)); - - ret = __memp_fput(mpf, (PAGE *)meta, DB_MPOOL_DIRTY); - meta = NULL; - if ((t_ret = __TLPUT(dbc, metalock)) != 0 && ret == 0) - ret = t_ret; - if (ret != 0) - goto err; - - switch (type) { - case P_BTREEMETA: - case P_HASHMETA: - case P_QAMMETA: - __db_init_meta(dbp, h, h->pgno, type); - break; - default: - P_INIT(h, dbp->pgsize, - h->pgno, PGNO_INVALID, PGNO_INVALID, 0, type); - break; - } - - /* Fix up the sorted free list if necessary. */ -#ifdef HAVE_FTRUNCATE - if (extend == 0) { - u_int32_t nelems = 0; - - if ((ret = __memp_get_freelist(dbp->mpf, &nelems, &list)) != 0) - goto err; - if (nelems != 0) { - DB_ASSERT(h->pgno == list[0]); - memmove(list, &list[1], (nelems - 1) * sizeof(*list)); - if ((ret = __memp_extend_freelist( - dbp->mpf, nelems - 1, &list)) != 0) - goto err; - } - } -#else - COMPQUIET(list, NULL); -#endif - - /* - * If dirty reads are enabled and we are in a transaction, we could - * abort this allocation after the page(s) pointing to this - * one have their locks downgraded. This would permit dirty readers - * to access this page which is ok, but they must be off the - * page when we abort. We never lock overflow pages or off page - * duplicate trees. - */ - if (type != P_OVERFLOW && !F_ISSET(dbc, DBC_OPD) && - F_ISSET(dbc->dbp, DB_AM_READ_UNCOMMITTED) && dbc->txn != NULL) { - if ((ret = __db_lget(dbc, 0, - h->pgno, DB_LOCK_WWRITE, 0, &metalock)) != 0) - goto err; - } - - *pagepp = h; - return (0); - -err: if (h != NULL) - (void)__memp_fput(mpf, h, 0); - if (meta != NULL) - (void)__memp_fput(mpf, meta, meta_flags); - (void)__TLPUT(dbc, metalock); - return (ret); -} - -/* - * __db_free -- - * Add a page to the head of the freelist. - * - * PUBLIC: int __db_free __P((DBC *, PAGE *)); - */ -int -__db_free(dbc, h) - DBC *dbc; - PAGE *h; -{ - DBMETA *meta; - DB *dbp; - DBT ddbt, ldbt; - DB_LOCK metalock; - DB_MPOOLFILE *mpf; - db_pgno_t last_pgno, *lp, next_pgno, pgno, prev_pgno; - u_int32_t dirty_flag, lflag, nelem; - int do_truncate, ret, t_ret; -#ifdef HAVE_FTRUNCATE - db_pgno_t *list; - u_int32_t position, start; -#endif - - dbp = dbc->dbp; - mpf = dbp->mpf; - prev_pgno = PGNO_INVALID; - nelem = 0; - meta = NULL; - do_truncate = 0; - lp = NULL; - - /* - * Retrieve the metadata page. If we are not keeping a sorted - * free list put the page at the head of the the free list. - * If we are keeping a sorted free list, for truncation, - * then figure out where this page belongs and either - * link it in or truncate the file as much as possible. - * If either the lock get or page get routines - * fail, then we need to put the page with which we were called - * back because our caller assumes we take care of it. - */ - dirty_flag = 0; - pgno = PGNO_BASE_MD; - if ((ret = __db_lget(dbc, - LCK_ALWAYS, pgno, DB_LOCK_WRITE, 0, &metalock)) != 0) - goto err; - if ((ret = __memp_fget(mpf, &pgno, 0, &meta)) != 0) - goto err1; - - last_pgno = meta->last_pgno; - next_pgno = meta->free; - - DB_ASSERT(h->pgno != next_pgno); - -#ifdef HAVE_FTRUNCATE - /* - * If we are maintaining a sorted free list see if we either have a - * new truncation point or the page goes somewhere in the middle of - * the list. If it goes in the middle of the list, we will drop the - * meta page and get the previous page. - */ - if ((ret = __memp_get_freelist(mpf, &nelem, &list)) != 0) - goto err; - if (list == NULL) - goto no_sort; - - if (h->pgno != last_pgno) { - /* - * Put the page number in the sorted list. - * Finds its position and the previous page, - * extend the list, make room and insert. - */ - position = 0; - if (nelem != 0) { - __db_freelist_pos(h->pgno, list, nelem, &position); - - DB_ASSERT(h->pgno != list[position]); - - /* Get the previous page if this is not the smallest. */ - if (position != 0 || h->pgno > list[0]) - prev_pgno = list[position]; - } - - /* Put the page number into the list. */ - if ((ret = __memp_extend_freelist(mpf, nelem + 1, &list)) != 0) - return (ret); - if (prev_pgno != PGNO_INVALID) - lp = &list[position + 1]; - else - lp = list; - if (nelem != 0 && position != nelem) - memmove(lp + 1, lp, - (size_t)((u_int8_t*)&list[nelem] - (u_int8_t*)lp)); - *lp = h->pgno; - } else if (nelem != 0) { - /* Find the truncation point. */ - for (lp = &list[nelem - 1]; lp >= list; lp--) - if (--last_pgno != *lp) - break; - if (lp < list || last_pgno < h->pgno - 1) - do_truncate = 1; - last_pgno = meta->last_pgno; - } - -no_sort: - if (prev_pgno != PGNO_INVALID) { - if ((ret = __memp_fput(mpf, meta, 0)) != 0) - goto err1; - meta = NULL; - pgno = prev_pgno; - if ((ret = __memp_fget(mpf, &pgno, 0, &meta)) != 0) - goto err1; - next_pgno = NEXT_PGNO(meta); - } -#endif - - /* Log the change. */ - if (DBC_LOGGING(dbc)) { - memset(&ldbt, 0, sizeof(ldbt)); - ldbt.data = h; - ldbt.size = P_OVERHEAD(dbp); - switch (h->type) { - case P_HASH: - case P_IBTREE: - case P_IRECNO: - case P_LBTREE: - case P_LRECNO: - case P_LDUP: - if (h->entries > 0) { - ldbt.size += h->entries * sizeof(db_indx_t); - ddbt.data = (u_int8_t *)h + HOFFSET(h); - ddbt.size = dbp->pgsize - HOFFSET(h); - if ((ret = __db_pg_freedata_log(dbp, dbc->txn, - &LSN(meta), 0, h->pgno, &LSN(meta), pgno, - &ldbt, next_pgno, last_pgno, &ddbt)) != 0) - goto err1; - goto logged; - } - break; - case P_HASHMETA: - ldbt.size = sizeof(HMETA); - break; - case P_BTREEMETA: - ldbt.size = sizeof(BTMETA); - break; - case P_OVERFLOW: - ldbt.size += OV_LEN(h); - break; - default: - DB_ASSERT(h->type != P_QAMDATA); - } - - /* - * If we are truncating the file, we need to make sure - * the logging happens before the truncation. If we - * are truncating multiple pages we don't need to flush the - * log here as it will be flushed by __db_truncate_freelist. - */ - lflag = 0; -#ifdef HAVE_FTRUNCATE - if (do_truncate == 0 && h->pgno == last_pgno) - lflag = DB_FLUSH; -#endif - if ((ret = __db_pg_free_log(dbp, - dbc->txn, &LSN(meta), lflag, h->pgno, - &LSN(meta), pgno, &ldbt, next_pgno, last_pgno)) != 0) - goto err1; - } else - LSN_NOT_LOGGED(LSN(meta)); -logged: LSN(h) = LSN(meta); - -#ifdef HAVE_FTRUNCATE - if (do_truncate) { - start = (u_int32_t) (lp - list) + 1; - meta->last_pgno--; - ret = __db_truncate_freelist( - dbc, meta, h, list, start, nelem); - h = NULL; - } else if (h->pgno == last_pgno) { - if ((ret = __memp_fput(mpf, h, DB_MPOOL_DISCARD)) != 0) - goto err; - /* Give the page back to the OS. */ - if ((ret = __memp_ftruncate(mpf, last_pgno, 0)) != 0) - goto err; - DB_ASSERT(meta->pgno == PGNO_BASE_MD); - meta->last_pgno--; - h = NULL; - } else -#endif - - { - /* - * If we are not truncating the page then we - * reinitialize it and put it at the head of - * the free list. - */ - P_INIT(h, dbp->pgsize, - h->pgno, PGNO_INVALID, next_pgno, 0, P_INVALID); -#ifdef DIAGNOSTIC - memset((u_int8_t *) h + P_OVERHEAD(dbp), - CLEAR_BYTE, dbp->pgsize - P_OVERHEAD(dbp)); -#endif - if (prev_pgno == PGNO_INVALID) - meta->free = h->pgno; - else - NEXT_PGNO(meta) = h->pgno; - } - - /* Discard the metadata or previous page. */ -err1: if (meta != NULL && (t_ret = - __memp_fput(mpf, (PAGE *)meta, DB_MPOOL_DIRTY)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = __TLPUT(dbc, metalock)) != 0 && ret == 0) - ret = t_ret; - - /* Discard the caller's page reference. */ - dirty_flag = DB_MPOOL_DIRTY; -err: if (h != NULL && - (t_ret = __memp_fput(mpf, h, dirty_flag)) != 0 && ret == 0) - ret = t_ret; - - /* - * XXX - * We have to unlock the caller's page in the caller! - */ - return (ret); -} - -#ifdef HAVE_FTRUNCATE -/* - * __db_freelist_pos -- find the position of a page in the freelist. - * The list is sorted, we do a binary search. - * - * PUBLIC: #ifdef HAVE_FTRUNCATE - * PUBLIC: void __db_freelist_pos __P((db_pgno_t, - * PUBLIC: db_pgno_t *, u_int32_t, u_int32_t *)); - * PUBLIC: #endif - */ -void -__db_freelist_pos(pgno, list, nelem, posp) - db_pgno_t pgno; - db_pgno_t *list; - u_int32_t nelem; - u_int32_t *posp; -{ - u_int32_t base, indx, lim; - - indx = 0; - for (base = 0, lim = nelem; lim != 0; lim >>= 1) { - indx = base + (lim >> 1); - if (pgno == list[indx]) { - *posp = indx; - return; - } - if (pgno > list[indx]) { - base = indx + 1; - --lim; - } - } - if (base != 0) - base--; - *posp = base; - return; -} - -static int -__db_pglistcmp(a, b) - const void *a, *b; -{ - struct pglist *ap, *bp; - - ap = (struct pglist *)a; - bp = (struct pglist *)b; - - return ((ap->pgno > bp->pgno) ? 1 : (ap->pgno < bp->pgno) ? -1: 0); -} - -/* - * __db_freelist_sort -- sort a list of free pages. - */ -static void -__db_freelist_sort(list, nelems) - struct pglist *list; - u_int32_t nelems; -{ - qsort(list, (size_t)nelems, sizeof(struct pglist), __db_pglistcmp); -} - -/* - * __db_pg_truncate -- sort the freelist and find the truncation point. - * - * PUBLIC: #ifdef HAVE_FTRUNCATE - * PUBLIC: int __db_pg_truncate __P((DB_MPOOLFILE *, struct pglist *list, - * PUBLIC: DB_COMPACT *, u_int32_t *, db_pgno_t *, DB_LSN *, int)); - * PUBLIC: #endif - */ -int -__db_pg_truncate(mpf, list, c_data, nelemp, last_pgno, lsnp, in_recovery) - DB_MPOOLFILE *mpf; - struct pglist *list; - DB_COMPACT *c_data; - u_int32_t *nelemp; - db_pgno_t *last_pgno; - DB_LSN *lsnp; - int in_recovery; -{ - PAGE *h; - struct pglist *lp; - db_pgno_t pgno; - u_int32_t nelems; - int modified, ret; - - ret = 0; - - nelems = *nelemp; - /* Sort the list */ - __db_freelist_sort(list, nelems); - - /* Find the truncation point. */ - pgno = *last_pgno; - lp = &list[nelems - 1]; - while (nelems != 0) { - if (lp->pgno != pgno) - break; - pgno--; - nelems--; - lp--; - } - - /* - * Figure out what (if any) pages can be truncated immediately and - * record the place from which we can truncate, so we can do the - * memp_ftruncate below. We also use this to avoid ever putting - * these pages on the freelist, which we are about to relink. - */ - for (lp = list; lp < &list[nelems]; lp++) { - if ((ret = __memp_fget(mpf, &lp->pgno, 0, &h)) != 0) { - /* Page may have been truncated later. */ - if (in_recovery && ret == DB_PAGE_NOTFOUND) { - ret = 0; - continue; - } - goto err; - } - modified = 0; - if (!in_recovery || log_compare(&LSN(h), &lp->lsn) == 0) { - if (lp == &list[nelems - 1]) - NEXT_PGNO(h) = PGNO_INVALID; - else - NEXT_PGNO(h) = lp[1].pgno; - DB_ASSERT(NEXT_PGNO(h) < *last_pgno); - - LSN(h) = *lsnp; - modified = 1; - } - if ((ret = __memp_fput(mpf, h, - modified ? DB_MPOOL_DIRTY : 0)) != 0) - goto err; - } - - if (pgno != *last_pgno) { - if ((ret = __memp_ftruncate(mpf, - pgno + 1, in_recovery ? MP_TRUNC_RECOVER : 0)) != 0) - goto err; - if (c_data) - c_data->compact_pages_truncated += *last_pgno - pgno; - *last_pgno = pgno; - } - *nelemp = nelems; - -err: return (ret); -} - -/* - * __db_free_truncate -- - * Truncate free pages at the end of the file. - * - * PUBLIC: #ifdef HAVE_FTRUNCATE - * PUBLIC: int __db_free_truncate __P((DB *, DB_TXN *, u_int32_t, - * PUBLIC: DB_COMPACT *, struct pglist **, u_int32_t *, db_pgno_t *)); - * PUBLIC: #endif - */ -int -__db_free_truncate(dbp, txn, flags, c_data, listp, nelemp, last_pgnop) - DB *dbp; - DB_TXN *txn; - u_int32_t flags; - DB_COMPACT *c_data; - struct pglist **listp; - u_int32_t *nelemp; - db_pgno_t *last_pgnop; -{ - DBC *dbc; - DB_ENV *dbenv; - DBMETA *meta; - DBT ddbt; - DB_LOCK metalock; - DB_LSN null_lsn; - DB_MPOOLFILE *mpf; - PAGE *h; - db_pgno_t pgno; - u_int32_t nelems; - struct pglist *list, *lp; - int ret, t_ret; - size_t size; - - COMPQUIET(flags, 0); - list = NULL; - meta = NULL; - dbenv = dbp->dbenv; - mpf = dbp->mpf; - h = NULL; - nelems = 0; - if (listp != NULL) { - *listp = NULL; - DB_ASSERT(nelemp != NULL); - *nelemp = 0; - } - - if ((ret = __db_cursor(dbp, txn, &dbc, DB_WRITELOCK)) != 0) - return (ret); - - pgno = PGNO_BASE_MD; - if ((ret = __db_lget(dbc, - LCK_ALWAYS, pgno, DB_LOCK_WRITE, 0, &metalock)) != 0) - goto err; - if ((ret = __memp_fget(mpf, &pgno, 0, &meta)) != 0) - goto err; - - if (last_pgnop != NULL) - *last_pgnop = meta->last_pgno; - if ((pgno = meta->free) == PGNO_INVALID) - goto done; - - size = 128; - if ((ret = __os_malloc(dbenv, size * sizeof(*list), &list)) != 0) - goto err; - lp = list; - - do { - if (lp == &list[size]) { - size *= 2; - if ((ret = __os_realloc(dbenv, - size * sizeof(*list), &list)) != 0) - goto err; - lp = &list[size / 2]; - } - if ((ret = __memp_fget(mpf, &pgno, 0, &h)) != 0) - goto err; - - lp->pgno = pgno; - lp->lsn = LSN(h); - pgno = NEXT_PGNO(h); - if ((ret = __memp_fput(mpf, h, 0)) != 0) - goto err; - lp++; - } while (pgno != PGNO_INVALID); - nelems = (u_int32_t)(lp - list); - - /* Log the current state of the free list */ - if (DBC_LOGGING(dbc)) { - ddbt.data = list; - ddbt.size = nelems * sizeof(*lp); - ZERO_LSN(null_lsn); - if ((ret = __db_pg_sort_log(dbp, - dbc->txn, &LSN(meta), DB_FLUSH, PGNO_BASE_MD, &LSN(meta), - PGNO_INVALID, &null_lsn, meta->last_pgno, &ddbt)) != 0) - goto err; - } else - LSN_NOT_LOGGED(LSN(meta)); - - if ((ret = __db_pg_truncate(mpf, list, c_data, - &nelems, &meta->last_pgno, &LSN(meta), 0)) != 0) - goto err; - - if (nelems == 0) - meta->free = PGNO_INVALID; - else - meta->free = list[0].pgno; - -done: if (last_pgnop != NULL) - *last_pgnop = meta->last_pgno; - - /* - * The truncate point is the number of pages in the free - * list back from the last page. The number of pages - * in the free list are the number that we can swap in. - */ - if (c_data) - c_data->compact_truncate = (u_int32_t)meta->last_pgno - nelems; - - if (nelems != 0 && listp != NULL) { - *listp = list; - *nelemp = nelems; - list = NULL; - } - -err: if (list != NULL) - __os_free(dbenv, list); - if (meta != NULL && (t_ret = - __memp_fput(mpf, (PAGE *)meta, DB_MPOOL_DIRTY)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = __TLPUT(dbc, metalock)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0) - ret = t_ret; - return (ret); -} - -static int -__db_truncate_freelist(dbc, meta, h, list, start, nelem) - DBC *dbc; - DBMETA *meta; - PAGE *h; - db_pgno_t *list; - u_int32_t start, nelem; -{ - DB *dbp; - DB_LSN null_lsn; - DB_MPOOLFILE *mpf; - DBT ddbt; - PAGE *last_free, *pg; - db_pgno_t *lp; - struct pglist *plist, *pp; - int ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - plist = NULL; - last_free = NULL; - - if (start != 0 && - (ret = __memp_fget(mpf, &list[start - 1], 0, &last_free)) != 0) - goto err; - - if (DBC_LOGGING(dbc)) { - if ((ret = __os_malloc(dbp->dbenv, - (nelem - start) * sizeof(*pp), &plist)) != 0) - goto err; - - pp = plist; - for (lp = &list[start]; lp < &list[nelem]; lp++) { - pp->pgno = *lp; - if ((ret = __memp_fget(mpf, lp, 0, &pg)) != 0) - goto err; - pp->lsn = LSN(pg); - if ((ret = __memp_fput(mpf, pg, DB_MPOOL_DISCARD)) != 0) - goto err; - pp++; - } - ddbt.data = plist; - ddbt.size = (nelem - start) * sizeof(*pp); - ZERO_LSN(null_lsn); - if (last_free != NULL) { - if ((ret = __db_pg_sort_log(dbp, dbc->txn, &LSN(meta), - DB_FLUSH, PGNO(meta), &LSN(meta), PGNO(last_free), - &LSN(last_free), meta->last_pgno, &ddbt)) != 0) - goto err; - } else if ((ret = __db_pg_sort_log(dbp, dbc->txn, - &LSN(meta), DB_FLUSH, PGNO(meta), &LSN(meta), - PGNO_INVALID, &null_lsn, meta->last_pgno, &ddbt)) != 0) - goto err; - } else - LSN_NOT_LOGGED(LSN(meta)); - if (last_free != NULL) - LSN(last_free) = LSN(meta); - - if ((ret = __memp_fput(mpf, h, DB_MPOOL_DISCARD)) != 0) - goto err; - h = NULL; - if ((ret = __memp_ftruncate(mpf, list[start], 0)) != 0) - goto err; - meta->last_pgno = list[start] - 1; - - if (start == 0) - meta->free = PGNO_INVALID; - else { - NEXT_PGNO(last_free) = PGNO_INVALID; - if ((ret = __memp_fput(mpf, last_free, DB_MPOOL_DIRTY)) != 0) - goto err; - last_free = NULL; - } - - /* Shrink the number of elements in the list. */ - ret = __memp_extend_freelist(mpf, start, &list); - -err: if (plist != NULL) - __os_free(dbp->dbenv, plist); - - /* We need to put the page on error. */ - if (h != NULL) - (void)__memp_fput(mpf, h, 0); - if (last_free != NULL) - (void)__memp_fput(mpf, last_free, 0); - - return (ret); -} -#endif - -#ifdef DEBUG -/* - * __db_lprint -- - * Print out the list of locks currently held by a cursor. - * - * PUBLIC: int __db_lprint __P((DBC *)); - */ -int -__db_lprint(dbc) - DBC *dbc; -{ - DB_ENV *dbenv; - DB *dbp; - DB_LOCKREQ req; - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - - if (LOCKING_ON(dbenv)) { - req.op = DB_LOCK_DUMP; - (void)__lock_vec(dbenv, dbc->locker, 0, &req, 1, NULL); - } - return (0); -} -#endif - -/* - * __db_lget -- - * The standard lock get call. - * - * PUBLIC: int __db_lget __P((DBC *, - * PUBLIC: int, db_pgno_t, db_lockmode_t, u_int32_t, DB_LOCK *)); - */ -int -__db_lget(dbc, action, pgno, mode, lkflags, lockp) - DBC *dbc; - int action; - db_pgno_t pgno; - db_lockmode_t mode; - u_int32_t lkflags; - DB_LOCK *lockp; -{ - DB *dbp; - DB_ENV *dbenv; - DB_LOCKREQ couple[3], *reqp; - DB_TXN *txn; - int has_timeout, i, ret; - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - txn = dbc->txn; - - /* - * We do not always check if we're configured for locking before - * calling __db_lget to acquire the lock. - */ - if (CDB_LOCKING(dbenv) || - !LOCKING_ON(dbenv) || F_ISSET(dbc, DBC_COMPENSATE) || - (F_ISSET(dbc, DBC_RECOVER) && - (action != LCK_ROLLBACK || IS_REP_CLIENT(dbenv))) || - (action != LCK_ALWAYS && F_ISSET(dbc, DBC_OPD))) { - LOCK_INIT(*lockp); - return (0); - } - - dbc->lock.pgno = pgno; - if (lkflags & DB_LOCK_RECORD) - dbc->lock.type = DB_RECORD_LOCK; - else - dbc->lock.type = DB_PAGE_LOCK; - lkflags &= ~DB_LOCK_RECORD; - if (action == LCK_ROLLBACK) - lkflags |= DB_LOCK_ABORT; - - /* - * If the transaction enclosing this cursor has DB_LOCK_NOWAIT set, - * pass that along to the lock call. - */ - if (DB_NONBLOCK(dbc)) - lkflags |= DB_LOCK_NOWAIT; - - if (F_ISSET(dbc, DBC_READ_UNCOMMITTED) && mode == DB_LOCK_READ) - mode = DB_LOCK_READ_UNCOMMITTED; - - has_timeout = F_ISSET(dbc, DBC_RECOVER) || - (txn != NULL && F_ISSET(txn, TXN_LOCKTIMEOUT)); - - /* - * Transactional locking. - * Hold on to the previous read lock only if we are in full isolation. - * COUPLE_ALWAYS indicates we are holding an interior node which need - * not be isolated. - * Downgrade write locks if we are supporting dirty readers. - */ - if ((action != LCK_COUPLE && action != LCK_COUPLE_ALWAYS) || - !LOCK_ISSET(*lockp)) - action = 0; - else if (dbc->txn == NULL || action == LCK_COUPLE_ALWAYS) - action = LCK_COUPLE; - else if (F_ISSET(dbc, - DBC_READ_COMMITTED) && lockp->mode == DB_LOCK_READ) - action = LCK_COUPLE; - else if (F_ISSET(dbc, - DBC_READ_UNCOMMITTED) && lockp->mode == DB_LOCK_READ_UNCOMMITTED) - action = LCK_COUPLE; - else if (F_ISSET(dbc->dbp, - DB_AM_READ_UNCOMMITTED) && lockp->mode == DB_LOCK_WRITE) - action = LCK_DOWNGRADE; - else - action = 0; - - i = 0; - switch (action) { - default: - if (has_timeout) - goto couple; - ret = __lock_get(dbenv, - dbc->locker, lkflags, &dbc->lock_dbt, mode, lockp); - break; - - case LCK_DOWNGRADE: - couple[0].op = DB_LOCK_GET; - couple[0].obj = NULL; - couple[0].lock = *lockp; - couple[0].mode = DB_LOCK_WWRITE; - UMRW_SET(couple[0].timeout); - i++; - /* FALLTHROUGH */ - case LCK_COUPLE: -couple: couple[i].op = has_timeout? DB_LOCK_GET_TIMEOUT : DB_LOCK_GET; - couple[i].obj = &dbc->lock_dbt; - couple[i].mode = mode; - UMRW_SET(couple[i].timeout); - i++; - if (has_timeout) - couple[0].timeout = - F_ISSET(dbc, DBC_RECOVER) ? 0 : txn->lock_timeout; - if (action == LCK_COUPLE || action == LCK_DOWNGRADE) { - couple[i].op = DB_LOCK_PUT; - couple[i].lock = *lockp; - i++; - } - - ret = __lock_vec(dbenv, - dbc->locker, lkflags, couple, i, &reqp); - if (ret == 0 || reqp == &couple[i - 1]) - *lockp = i == 1 ? couple[0].lock : couple[i - 2].lock; - break; - } - - if (txn != NULL && ret == DB_LOCK_DEADLOCK) - F_SET(txn, TXN_DEADLOCK); - return ((ret == DB_LOCK_NOTGRANTED && - !F_ISSET(dbenv, DB_ENV_TIME_NOTGRANTED)) ? DB_LOCK_DEADLOCK : ret); -} - -/* - * __db_lput -- - * The standard lock put call. - * - * PUBLIC: int __db_lput __P((DBC *, DB_LOCK *)); - */ -int -__db_lput(dbc, lockp) - DBC *dbc; - DB_LOCK *lockp; -{ - DB_ENV *dbenv; - DB_LOCKREQ couple[2], *reqp; - int action, ret; - - /* - * Transactional locking. - * Hold on to the read locks only if we are in full isolation. - * Downgrade write locks if we are supporting dirty readers. - */ - if (F_ISSET(dbc->dbp, - DB_AM_READ_UNCOMMITTED) && lockp->mode == DB_LOCK_WRITE) - action = LCK_DOWNGRADE; - else if (dbc->txn == NULL) - action = LCK_COUPLE; - else if (F_ISSET(dbc, - DBC_READ_COMMITTED) && lockp->mode == DB_LOCK_READ) - action = LCK_COUPLE; - else if (F_ISSET(dbc, - DBC_READ_UNCOMMITTED) && lockp->mode == DB_LOCK_READ_UNCOMMITTED) - action = LCK_COUPLE; - else - action = 0; - - dbenv = dbc->dbp->dbenv; - switch (action) { - case LCK_COUPLE: - ret = __lock_put(dbenv, lockp); - break; - case LCK_DOWNGRADE: - couple[0].op = DB_LOCK_GET; - couple[0].obj = NULL; - couple[0].mode = DB_LOCK_WWRITE; - couple[0].lock = *lockp; - UMRW_SET(couple[0].timeout); - couple[1].op = DB_LOCK_PUT; - couple[1].lock = *lockp; - ret = __lock_vec(dbenv, dbc->locker, 0, couple, 2, &reqp); - if (ret == 0 || reqp == &couple[1]) - *lockp = couple[0].lock; - break; - default: - ret = 0; - break; - } - - return (ret); -} diff --git a/storage/bdb/db/db_method.c b/storage/bdb/db/db_method.c deleted file mode 100644 index 141392148e7..00000000000 --- a/storage/bdb/db/db_method.c +++ /dev/null @@ -1,867 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_method.c,v 12.15 2005/11/08 03:24:58 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#ifdef HAVE_RPC -#include <rpc/rpc.h> -#endif - -#include <string.h> -#endif - -#ifdef HAVE_RPC -#include "db_server.h" -#endif - -#include "db_int.h" -#include "dbinc/crypto.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/btree.h" -#include "dbinc/hash.h" -#include "dbinc/lock.h" -#include "dbinc/mp.h" -#include "dbinc/qam.h" -#include "dbinc/txn.h" - -#ifdef HAVE_RPC -#include "dbinc_auto/rpc_client_ext.h" -#endif - -static int __db_get_byteswapped __P((DB *, int *)); -static int __db_get_dbname __P((DB *, const char **, const char **)); -static DB_ENV *__db_get_env __P((DB *)); -static DB_MPOOLFILE *__db_get_mpf __P((DB *)); -static int __db_get_transactional __P((DB *)); -static int __db_get_type __P((DB *, DBTYPE *dbtype)); -static int __db_init __P((DB_ENV *, DB *, u_int32_t)); -static int __db_set_alloc __P((DB *, void *(*)(size_t), - void *(*)(void *, size_t), void (*)(void *))); -static int __db_set_append_recno __P((DB *, int (*)(DB *, DBT *, db_recno_t))); -static int __db_get_cachesize __P((DB *, u_int32_t *, u_int32_t *, int *)); -static int __db_set_cachesize __P((DB *, u_int32_t, u_int32_t, int)); -static int __db_set_dup_compare - __P((DB *, int (*)(DB *, const DBT *, const DBT *))); -static int __db_get_encrypt_flags __P((DB *, u_int32_t *)); -static int __db_set_encrypt __P((DB *, const char *, u_int32_t)); -static int __db_set_feedback __P((DB *, void (*)(DB *, int, int))); -static void __db_map_flags __P((DB *, u_int32_t *, u_int32_t *)); -static int __db_get_pagesize __P((DB *, u_int32_t *)); -static int __db_set_paniccall __P((DB *, void (*)(DB_ENV *, int))); -static void __db_set_errcall - __P((DB *, void (*)(const DB_ENV *, const char *, const char *))); -static void __db_get_errfile __P((DB *, FILE **)); -static void __db_set_errfile __P((DB *, FILE *)); -static void __db_get_errpfx __P((DB *, const char **)); -static void __db_set_errpfx __P((DB *, const char *)); -static void __db_set_msgcall - __P((DB *, void (*)(const DB_ENV *, const char *))); -static void __db_get_msgfile __P((DB *, FILE **)); -static void __db_set_msgfile __P((DB *, FILE *)); -static void __dbh_err __P((DB *, int, const char *, ...)); -static void __dbh_errx __P((DB *, const char *, ...)); - -/* - * db_create -- - * DB constructor. - * - * EXTERN: int db_create __P((DB **, DB_ENV *, u_int32_t)); - */ -int -db_create(dbpp, dbenv, flags) - DB **dbpp; - DB_ENV *dbenv; - u_int32_t flags; -{ - DB *dbp; - DB_THREAD_INFO *ip; - DB_REP *db_rep; - int ret; - - /* Check for invalid function flags. */ - switch (flags) { - case 0: - break; - case DB_XA_CREATE: - if (dbenv != NULL) { - __db_err(dbenv, - "XA applications may not specify an environment to db_create"); - return (EINVAL); - } - - /* - * If it's an XA database, open it within the XA environment, - * taken from the global list of environments. (When the XA - * transaction manager called our xa_start() routine the - * "current" environment was moved to the start of the list. - */ - dbenv = TAILQ_FIRST(&DB_GLOBAL(db_envq)); - break; - default: - return (__db_ferr(dbenv, "db_create", 0)); - } - - ip = NULL; - if (dbenv != NULL) - ENV_ENTER(dbenv, ip); - /* Allocate the DB. */ - if ((ret = __os_calloc(dbenv, 1, sizeof(*dbp), &dbp)) != 0) { - if (dbenv != NULL) - ENV_LEAVE(dbenv, ip); - return (ret); - } - - if ((ret = __db_init(dbenv, dbp, flags)) != 0) - goto err; - - /* If we don't have an environment yet, allocate a local one. */ - if (dbenv == NULL) { - if ((ret = db_env_create(&dbenv, 0)) != 0) - goto err; - F_SET(dbenv, DB_ENV_DBLOCAL); - ENV_ENTER(dbenv, ip); - } - dbp->dbenv = dbenv; - MUTEX_LOCK(dbenv, dbenv->mtx_dblist); - ++dbenv->db_ref; - MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist); - - /* - * Set the replication timestamp; it's 0 if we're not in a replicated - * environment. Don't acquire a lock to read the value, even though - * it's opaque: all we check later is value equality, nothing else. - */ - dbp->timestamp = REP_ON(dbenv) ? - ((REGENV *)((REGINFO *)dbenv->reginfo)->primary)->rep_timestamp : 0; - /* - * Set the replication generation number for fid management; valid - * replication generations start at 1. Don't acquire a lock to - * read the value. All we check later is value equality. - */ - db_rep = dbenv->rep_handle; - dbp->fid_gen = - (REP_ON(dbenv) && db_rep->region != NULL) ? - ((REP *)db_rep->region)->gen : 0; - - /* If not RPC, open a backing DB_MPOOLFILE handle in the memory pool. */ - if (!RPC_ON(dbenv) && - (ret = __memp_fcreate(dbenv, &dbp->mpf)) != 0) - goto err; - - dbp->type = DB_UNKNOWN; - - *dbpp = dbp; - return (0); - -err: if (dbp->mpf != NULL) - (void)__memp_fclose(dbp->mpf, 0); - if (dbenv != NULL && F_ISSET(dbenv, DB_ENV_DBLOCAL)) - (void)__env_close(dbenv, 0); - __os_free(dbenv, dbp); - *dbpp = NULL; - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __db_init -- - * Initialize a DB structure. - */ -static int -__db_init(dbenv, dbp, flags) - DB_ENV *dbenv; - DB *dbp; - u_int32_t flags; -{ - int ret; - - dbp->lid = DB_LOCK_INVALIDID; - LOCK_INIT(dbp->handle_lock); - - TAILQ_INIT(&dbp->free_queue); - TAILQ_INIT(&dbp->active_queue); - TAILQ_INIT(&dbp->join_queue); - LIST_INIT(&dbp->s_secondaries); - - FLD_SET(dbp->am_ok, - DB_OK_BTREE | DB_OK_HASH | DB_OK_QUEUE | DB_OK_RECNO); - - /* DB PUBLIC HANDLE LIST BEGIN */ - dbp->associate = __db_associate_pp; - dbp->close = __db_close_pp; - dbp->compact = __db_compact_pp; - dbp->cursor = __db_cursor_pp; - dbp->del = __db_del_pp; - dbp->dump = __db_dump_pp; - dbp->err = __dbh_err; - dbp->errx = __dbh_errx; - dbp->fd = __db_fd_pp; - dbp->get = __db_get_pp; - dbp->get_byteswapped = __db_get_byteswapped; - dbp->get_cachesize = __db_get_cachesize; - dbp->get_dbname = __db_get_dbname; - dbp->get_encrypt_flags = __db_get_encrypt_flags; - dbp->get_env = __db_get_env; - dbp->get_errfile = __db_get_errfile; - dbp->get_errpfx = __db_get_errpfx; - dbp->get_flags = __db_get_flags; - dbp->get_lorder = __db_get_lorder; - dbp->get_mpf = __db_get_mpf; - dbp->get_msgfile = __db_get_msgfile; - dbp->get_open_flags = __db_get_open_flags; - dbp->get_pagesize = __db_get_pagesize; - dbp->get_transactional = __db_get_transactional; - dbp->get_type = __db_get_type; - dbp->join = __db_join_pp; - dbp->key_range = __db_key_range_pp; - dbp->open = __db_open_pp; - dbp->pget = __db_pget_pp; - dbp->put = __db_put_pp; - dbp->remove = __db_remove_pp; - dbp->rename = __db_rename_pp; - dbp->set_alloc = __db_set_alloc; - dbp->set_append_recno = __db_set_append_recno; - dbp->set_cachesize = __db_set_cachesize; - dbp->set_dup_compare = __db_set_dup_compare; - dbp->set_encrypt = __db_set_encrypt; - dbp->set_errcall = __db_set_errcall; - dbp->set_errfile = __db_set_errfile; - dbp->set_errpfx = __db_set_errpfx; - dbp->set_feedback = __db_set_feedback; - dbp->set_flags = __db_set_flags; - dbp->set_lorder = __db_set_lorder; - dbp->set_msgcall = __db_set_msgcall; - dbp->set_msgfile = __db_set_msgfile; - dbp->set_pagesize = __db_set_pagesize; - dbp->set_paniccall = __db_set_paniccall; - dbp->stat = __db_stat_pp; - dbp->stat_print = __db_stat_print_pp; - dbp->sync = __db_sync_pp; - dbp->truncate = __db_truncate_pp; - dbp->upgrade = __db_upgrade_pp; - dbp->verify = __db_verify_pp; - /* DB PUBLIC HANDLE LIST END */ - - /* Access method specific. */ - if ((ret = __bam_db_create(dbp)) != 0) - return (ret); - if ((ret = __ham_db_create(dbp)) != 0) - return (ret); - if ((ret = __qam_db_create(dbp)) != 0) - return (ret); - - /* - * XA specific: must be last, as we replace methods set by the - * access methods. - */ - if (LF_ISSET(DB_XA_CREATE) && (ret = __db_xa_create(dbp)) != 0) - return (ret); - -#ifdef HAVE_RPC - /* - * RPC specific: must be last, as we replace methods set by the - * access methods. - */ - if (dbenv != NULL && RPC_ON(dbenv)) { - __dbcl_dbp_init(dbp); - /* - * !!! - * We wrap the DB->open method for RPC, and the rpc.src file - * can't handle that. - */ - dbp->open = __dbcl_db_open_wrap; - if ((ret = __dbcl_db_create(dbp, dbenv, flags)) != 0) - return (ret); - } -#else - COMPQUIET(dbenv, NULL); -#endif - - return (0); -} - -/* - * __dbh_am_chk -- - * Error if an unreasonable method is called. - * - * PUBLIC: int __dbh_am_chk __P((DB *, u_int32_t)); - */ -int -__dbh_am_chk(dbp, flags) - DB *dbp; - u_int32_t flags; -{ - /* - * We start out allowing any access methods to be called, and as the - * application calls the methods the options become restricted. The - * idea is to quit as soon as an illegal method combination is called. - */ - if ((LF_ISSET(DB_OK_BTREE) && FLD_ISSET(dbp->am_ok, DB_OK_BTREE)) || - (LF_ISSET(DB_OK_HASH) && FLD_ISSET(dbp->am_ok, DB_OK_HASH)) || - (LF_ISSET(DB_OK_QUEUE) && FLD_ISSET(dbp->am_ok, DB_OK_QUEUE)) || - (LF_ISSET(DB_OK_RECNO) && FLD_ISSET(dbp->am_ok, DB_OK_RECNO))) { - FLD_CLR(dbp->am_ok, ~flags); - return (0); - } - - __db_err(dbp->dbenv, - "call implies an access method which is inconsistent with previous calls"); - return (EINVAL); -} - -/* - * __dbh_err -- - * Error message, including the standard error string. - */ -static void -#ifdef STDC_HEADERS -__dbh_err(DB *dbp, int error, const char *fmt, ...) -#else -__dbh_err(dbp, error, fmt, va_alist) - DB *dbp; - int error; - const char *fmt; - va_dcl -#endif -{ - DB_REAL_ERR(dbp->dbenv, error, 1, 1, fmt); -} - -/* - * __dbh_errx -- - * Error message. - */ -static void -#ifdef STDC_HEADERS -__dbh_errx(DB *dbp, const char *fmt, ...) -#else -__dbh_errx(dbp, fmt, va_alist) - DB *dbp; - const char *fmt; - va_dcl -#endif -{ - DB_REAL_ERR(dbp->dbenv, 0, 0, 1, fmt); -} - -/* - * __db_get_byteswapped -- - * Return if database requires byte swapping. - */ -static int -__db_get_byteswapped(dbp, isswapped) - DB *dbp; - int *isswapped; -{ - DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->get_byteswapped"); - - *isswapped = F_ISSET(dbp, DB_AM_SWAP) ? 1 : 0; - return (0); -} - -/* - * __db_get_dbname -- - * Get the name of the database as passed to DB->open. - */ -static int -__db_get_dbname(dbp, fnamep, dnamep) - DB *dbp; - const char **fnamep, **dnamep; -{ - DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->get_dbname"); - - if (fnamep != NULL) - *fnamep = dbp->fname; - if (dnamep != NULL) - *dnamep = dbp->dname; - return (0); -} - -/* - * __db_get_env -- - * Get the DB_ENV handle that was passed to db_create. - */ -static DB_ENV * -__db_get_env(dbp) - DB *dbp; -{ - return (dbp->dbenv); -} - -/* - * __db_get_mpf -- - * Get the underlying DB_MPOOLFILE handle. - */ -static DB_MPOOLFILE * -__db_get_mpf(dbp) - DB *dbp; -{ - return (dbp->mpf); -} - -/* - * get_transactional -- - * Get whether this database was created in a transaction. - */ -static int -__db_get_transactional(dbp) - DB *dbp; -{ - return (F_ISSET(dbp, DB_AM_TXN) ? 1 : 0); -} - -/* - * __db_get_type -- - * Return type of underlying database. - */ -static int -__db_get_type(dbp, dbtype) - DB *dbp; - DBTYPE *dbtype; -{ - DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->get_type"); - - *dbtype = dbp->type; - return (0); -} - -/* - * __db_set_append_recno -- - * Set record number append routine. - */ -static int -__db_set_append_recno(dbp, func) - DB *dbp; - int (*func) __P((DB *, DBT *, db_recno_t)); -{ - DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_append_recno"); - DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO); - - dbp->db_append_recno = func; - - return (0); -} - -/* - * __db_get_cachesize -- - * Get underlying cache size. - */ -static int -__db_get_cachesize(dbp, cache_gbytesp, cache_bytesp, ncachep) - DB *dbp; - u_int32_t *cache_gbytesp, *cache_bytesp; - int *ncachep; -{ - DB_ILLEGAL_IN_ENV(dbp, "DB->get_cachesize"); - - return (__memp_get_cachesize(dbp->dbenv, - cache_gbytesp, cache_bytesp, ncachep)); -} - -/* - * __db_set_cachesize -- - * Set underlying cache size. - */ -static int -__db_set_cachesize(dbp, cache_gbytes, cache_bytes, ncache) - DB *dbp; - u_int32_t cache_gbytes, cache_bytes; - int ncache; -{ - DB_ILLEGAL_IN_ENV(dbp, "DB->set_cachesize"); - DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_cachesize"); - - return (__memp_set_cachesize( - dbp->dbenv, cache_gbytes, cache_bytes, ncache)); -} - -/* - * __db_set_dup_compare -- - * Set duplicate comparison routine. - */ -static int -__db_set_dup_compare(dbp, func) - DB *dbp; - int (*func) __P((DB *, const DBT *, const DBT *)); -{ - int ret; - - DB_ILLEGAL_AFTER_OPEN(dbp, "DB->dup_compare"); - DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE | DB_OK_HASH); - - if ((ret = __db_set_flags(dbp, DB_DUPSORT)) != 0) - return (ret); - - dbp->dup_compare = func; - - return (0); -} - -/* - * __db_get_encrypt_flags -- - */ -static int -__db_get_encrypt_flags(dbp, flagsp) - DB *dbp; - u_int32_t *flagsp; -{ - DB_ILLEGAL_IN_ENV(dbp, "DB->get_encrypt_flags"); - - return (__env_get_encrypt_flags(dbp->dbenv, flagsp)); -} - -/* - * __db_set_encrypt -- - * Set database passwd. - */ -static int -__db_set_encrypt(dbp, passwd, flags) - DB *dbp; - const char *passwd; - u_int32_t flags; -{ - DB_CIPHER *db_cipher; - int ret; - - DB_ILLEGAL_IN_ENV(dbp, "DB->set_encrypt"); - DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_encrypt"); - - if ((ret = __env_set_encrypt(dbp->dbenv, passwd, flags)) != 0) - return (ret); - - /* - * In a real env, this gets initialized with the region. In a local - * env, we must do it here. - */ - db_cipher = (DB_CIPHER *)dbp->dbenv->crypto_handle; - if (!F_ISSET(db_cipher, CIPHER_ANY) && - (ret = db_cipher->init(dbp->dbenv, db_cipher)) != 0) - return (ret); - - return (__db_set_flags(dbp, DB_ENCRYPT)); -} - -static void -__db_set_errcall(dbp, errcall) - DB *dbp; - void (*errcall) __P((const DB_ENV *, const char *, const char *)); -{ - __env_set_errcall(dbp->dbenv, errcall); -} - -static void -__db_get_errfile(dbp, errfilep) - DB *dbp; - FILE **errfilep; -{ - __env_get_errfile(dbp->dbenv, errfilep); -} - -static void -__db_set_errfile(dbp, errfile) - DB *dbp; - FILE *errfile; -{ - __env_set_errfile(dbp->dbenv, errfile); -} - -static void -__db_get_errpfx(dbp, errpfxp) - DB *dbp; - const char **errpfxp; -{ - __env_get_errpfx(dbp->dbenv, errpfxp); -} - -static void -__db_set_errpfx(dbp, errpfx) - DB *dbp; - const char *errpfx; -{ - __env_set_errpfx(dbp->dbenv, errpfx); -} - -static int -__db_set_feedback(dbp, feedback) - DB *dbp; - void (*feedback) __P((DB *, int, int)); -{ - dbp->db_feedback = feedback; - return (0); -} - -/* - * __db_map_flags -- - * Maps between public and internal flag values. - * This function doesn't check for validity, so it can't fail. - */ -static void -__db_map_flags(dbp, inflagsp, outflagsp) - DB *dbp; - u_int32_t *inflagsp, *outflagsp; -{ - COMPQUIET(dbp, NULL); - - if (FLD_ISSET(*inflagsp, DB_CHKSUM)) { - FLD_SET(*outflagsp, DB_AM_CHKSUM); - FLD_CLR(*inflagsp, DB_CHKSUM); - } - if (FLD_ISSET(*inflagsp, DB_ENCRYPT)) { - FLD_SET(*outflagsp, DB_AM_ENCRYPT | DB_AM_CHKSUM); - FLD_CLR(*inflagsp, DB_ENCRYPT); - } - if (FLD_ISSET(*inflagsp, DB_TXN_NOT_DURABLE)) { - FLD_SET(*outflagsp, DB_AM_NOT_DURABLE); - FLD_CLR(*inflagsp, DB_TXN_NOT_DURABLE); - } -} - -/* - * __db_get_flags -- - * The DB->get_flags method. - * - * PUBLIC: int __db_get_flags __P((DB *, u_int32_t *)); - */ -int -__db_get_flags(dbp, flagsp) - DB *dbp; - u_int32_t *flagsp; -{ - static const u_int32_t db_flags[] = { - DB_CHKSUM, - DB_DUP, - DB_DUPSORT, - DB_ENCRYPT, - DB_INORDER, - DB_RECNUM, - DB_RENUMBER, - DB_REVSPLITOFF, - DB_SNAPSHOT, - DB_TXN_NOT_DURABLE, - 0 - }; - u_int32_t f, flags, mapped_flag; - int i; - - flags = 0; - for (i = 0; (f = db_flags[i]) != 0; i++) { - mapped_flag = 0; - __db_map_flags(dbp, &f, &mapped_flag); - __bam_map_flags(dbp, &f, &mapped_flag); - __ram_map_flags(dbp, &f, &mapped_flag); -#ifdef HAVE_QUEUE - __qam_map_flags(dbp, &f, &mapped_flag); -#endif - DB_ASSERT(f == 0); - if (F_ISSET(dbp, mapped_flag) == mapped_flag) - LF_SET(db_flags[i]); - } - - *flagsp = flags; - return (0); -} - -/* - * __db_set_flags -- - * DB->set_flags. - * - * PUBLIC: int __db_set_flags __P((DB *, u_int32_t)); - */ -int -__db_set_flags(dbp, flags) - DB *dbp; - u_int32_t flags; -{ - DB_ENV *dbenv; - int ret; - - dbenv = dbp->dbenv; - - if (LF_ISSET(DB_ENCRYPT) && !CRYPTO_ON(dbenv)) { - __db_err(dbenv, - "Database environment not configured for encryption"); - return (EINVAL); - } - if (LF_ISSET(DB_TXN_NOT_DURABLE)) - ENV_REQUIRES_CONFIG(dbenv, - dbenv->tx_handle, "DB_NOT_DURABLE", DB_INIT_TXN); - - __db_map_flags(dbp, &flags, &dbp->flags); - - if ((ret = __bam_set_flags(dbp, &flags)) != 0) - return (ret); - if ((ret = __ram_set_flags(dbp, &flags)) != 0) - return (ret); -#ifdef HAVE_QUEUE - if ((ret = __qam_set_flags(dbp, &flags)) != 0) - return (ret); -#endif - - return (flags == 0 ? 0 : __db_ferr(dbenv, "DB->set_flags", 0)); -} - -/* - * __db_get_lorder -- - * Get whether lorder is swapped or not. - * - * PUBLIC: int __db_get_lorder __P((DB *, int *)); - */ -int -__db_get_lorder(dbp, db_lorderp) - DB *dbp; - int *db_lorderp; -{ - int ret; - - /* Flag if the specified byte order requires swapping. */ - switch (ret = __db_byteorder(dbp->dbenv, 1234)) { - case 0: - *db_lorderp = F_ISSET(dbp, DB_AM_SWAP) ? 4321 : 1234; - break; - case DB_SWAPBYTES: - *db_lorderp = F_ISSET(dbp, DB_AM_SWAP) ? 1234 : 4321; - break; - default: - return (ret); - /* NOTREACHED */ - } - - return (0); -} - -/* - * __db_set_lorder -- - * Set whether lorder is swapped or not. - * - * PUBLIC: int __db_set_lorder __P((DB *, int)); - */ -int -__db_set_lorder(dbp, db_lorder) - DB *dbp; - int db_lorder; -{ - int ret; - - DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_lorder"); - - /* Flag if the specified byte order requires swapping. */ - switch (ret = __db_byteorder(dbp->dbenv, db_lorder)) { - case 0: - F_CLR(dbp, DB_AM_SWAP); - break; - case DB_SWAPBYTES: - F_SET(dbp, DB_AM_SWAP); - break; - default: - return (ret); - /* NOTREACHED */ - } - return (0); -} - -static int -__db_set_alloc(dbp, mal_func, real_func, free_func) - DB *dbp; - void *(*mal_func) __P((size_t)); - void *(*real_func) __P((void *, size_t)); - void (*free_func) __P((void *)); -{ - DB_ILLEGAL_IN_ENV(dbp, "DB->set_alloc"); - DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_alloc"); - - return (__env_set_alloc(dbp->dbenv, mal_func, real_func, free_func)); -} - -static void -__db_set_msgcall(dbp, msgcall) - DB *dbp; - void (*msgcall) __P((const DB_ENV *, const char *)); -{ - __env_set_msgcall(dbp->dbenv, msgcall); -} - -static void -__db_get_msgfile(dbp, msgfilep) - DB *dbp; - FILE **msgfilep; -{ - __env_get_msgfile(dbp->dbenv, msgfilep); -} - -static void -__db_set_msgfile(dbp, msgfile) - DB *dbp; - FILE *msgfile; -{ - __env_set_msgfile(dbp->dbenv, msgfile); -} - -static int -__db_get_pagesize(dbp, db_pagesizep) - DB *dbp; - u_int32_t *db_pagesizep; -{ - *db_pagesizep = dbp->pgsize; - return (0); -} - -/* - * __db_set_pagesize -- - * DB->set_pagesize - * - * PUBLIC: int __db_set_pagesize __P((DB *, u_int32_t)); - */ -int -__db_set_pagesize(dbp, db_pagesize) - DB *dbp; - u_int32_t db_pagesize; -{ - DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_pagesize"); - - if (db_pagesize < DB_MIN_PGSIZE) { - __db_err(dbp->dbenv, "page sizes may not be smaller than %lu", - (u_long)DB_MIN_PGSIZE); - return (EINVAL); - } - if (db_pagesize > DB_MAX_PGSIZE) { - __db_err(dbp->dbenv, "page sizes may not be larger than %lu", - (u_long)DB_MAX_PGSIZE); - return (EINVAL); - } - - /* - * We don't want anything that's not a power-of-2, as we rely on that - * for alignment of various types on the pages. - */ - if (!POWER_OF_TWO(db_pagesize)) { - __db_err(dbp->dbenv, "page sizes must be a power-of-2"); - return (EINVAL); - } - - /* - * XXX - * Should we be checking for a page size that's not a multiple of 512, - * so that we never try and write less than a disk sector? - */ - dbp->pgsize = db_pagesize; - - return (0); -} - -static int -__db_set_paniccall(dbp, paniccall) - DB *dbp; - void (*paniccall) __P((DB_ENV *, int)); -{ - return (__env_set_paniccall(dbp->dbenv, paniccall)); -} diff --git a/storage/bdb/db/db_open.c b/storage/bdb/db/db_open.c deleted file mode 100644 index a397c92bc53..00000000000 --- a/storage/bdb/db/db_open.c +++ /dev/null @@ -1,616 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_open.c,v 12.13 2005/10/12 17:45:53 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stdlib.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/db_swap.h" -#include "dbinc/btree.h" -#include "dbinc/crypto.h" -#include "dbinc/hmac.h" -#include "dbinc/fop.h" -#include "dbinc/hash.h" -#include "dbinc/lock.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" -#include "dbinc/qam.h" -#include "dbinc/txn.h" - -/* - * __db_open -- - * DB->open method. - * - * This routine gets called in three different ways: - * - * 1. It can be called to open a file/database. In this case, subdb will - * be NULL and meta_pgno will be PGNO_BASE_MD. - * 2. It can be called to open a subdatabase during normal operation. In - * this case, name and subname will both be non-NULL and meta_pgno will - * be PGNO_BASE_MD (also PGNO_INVALID). - * 3. It can be called to open an in-memory database (name == NULL; - * subname = name). - * 4. It can be called during recovery to open a file/database, in which case - * name will be non-NULL, subname will be NULL, and meta-pgno will be - * PGNO_BASE_MD. - * 5. It can be called during recovery to open a subdatabase, in which case - * name will be non-NULL, subname may be NULL and meta-pgno will be - * a valid pgno (i.e., not PGNO_BASE_MD). - * 6. It can be called during recovery to open an in-memory database. - * - * PUBLIC: int __db_open __P((DB *, DB_TXN *, - * PUBLIC: const char *, const char *, DBTYPE, u_int32_t, int, db_pgno_t)); - */ -int -__db_open(dbp, txn, fname, dname, type, flags, mode, meta_pgno) - DB *dbp; - DB_TXN *txn; - const char *fname, *dname; - DBTYPE type; - u_int32_t flags; - int mode; - db_pgno_t meta_pgno; -{ - DB_ENV *dbenv; - int ret; - u_int32_t id; - - dbenv = dbp->dbenv; - id = TXN_INVALID; - - DB_TEST_RECOVERY(dbp, DB_TEST_PREOPEN, ret, fname); - - /* - * If the environment was configured with threads, the DB handle - * must also be free-threaded, so we force the DB_THREAD flag on. - * (See SR #2033 for why this is a requirement--recovery needs - * to be able to grab a dbp using __db_fileid_to_dbp, and it has - * no way of knowing which dbp goes with which thread, so whichever - * one it finds has to be usable in any of them.) - */ - if (F_ISSET(dbenv, DB_ENV_THREAD)) - LF_SET(DB_THREAD); - - /* Convert any DB->open flags. */ - if (LF_ISSET(DB_RDONLY)) - F_SET(dbp, DB_AM_RDONLY); - if (LF_ISSET(DB_READ_UNCOMMITTED)) - F_SET(dbp, DB_AM_READ_UNCOMMITTED); - - if (txn != NULL) - F_SET(dbp, DB_AM_TXN); - - /* Fill in the type. */ - dbp->type = type; - - /* - * If both fname and subname are NULL, it's always a create, so make - * sure that we have both DB_CREATE and a type specified. It would - * be nice if this checking were done in __db_open where most of the - * interface checking is done, but this interface (__db_dbopen) is - * used by the recovery and limbo system, so we need to safeguard - * this interface as well. - */ - if (fname == NULL) { - if (dname == NULL) { - if (!LF_ISSET(DB_CREATE)) { - __db_err(dbenv, - "DB_CREATE must be specified to create databases."); - return (ENOENT); - } - - F_SET(dbp, DB_AM_INMEM); - F_SET(dbp, DB_AM_CREATED); - - if (dbp->type == DB_UNKNOWN) { - __db_err(dbenv, - "DBTYPE of unknown without existing file"); - return (EINVAL); - } - - if (dbp->pgsize == 0) - dbp->pgsize = DB_DEF_IOSIZE; - - /* - * If the file is a temporary file and we're - * doing locking, then we have to create a - * unique file ID. We can't use our normal - * dev/inode pair (or whatever this OS uses - * in place of dev/inode pairs) because no - * backing file will be created until the - * mpool cache is filled forcing the buffers - * to disk. Grab a random locker ID to use - * as a file ID. The created ID must never - * match a potential real file ID -- we know - * it won't because real file IDs contain a - * time stamp after the dev/inode pair, and - * we're simply storing a 4-byte value. - - * !!! - * Store the locker in the file id structure - * -- we can get it from there as necessary, - * and it saves having two copies. - */ - if (LOCKING_ON(dbenv) && (ret = __lock_id(dbenv, - (u_int32_t *)dbp->fileid, NULL)) != 0) - return (ret); - } else - MAKE_INMEM(dbp); - - /* - * Normally we would do handle locking here, however, with - * in-memory files, we cannot do any database manipulation - * until the mpool is open, so it happens later. - */ - } else if (dname == NULL && meta_pgno == PGNO_BASE_MD) { - /* Open/create the underlying file. Acquire locks. */ - if ((ret = - __fop_file_setup(dbp, txn, fname, mode, flags, &id)) != 0) - return (ret); - } else { - if ((ret = __fop_subdb_setup(dbp, - txn, fname, dname, mode, flags)) != 0) - return (ret); - meta_pgno = dbp->meta_pgno; - } - - /* - * If we created the file, set the truncate flag for the mpool. This - * isn't for anything we've done, it's protection against stupid user - * tricks: if the user deleted a file behind Berkeley DB's back, we - * may still have pages in the mpool that match the file's "unique" ID. - * - * Note that if we're opening a subdatabase, we don't want to set - * the TRUNCATE flag even if we just created the file--we already - * opened and updated the master using access method interfaces, - * so we don't want to get rid of any pages that are in the mpool. - * If we created the file when we opened the master, we already hit - * this check in a non-subdatabase context then. - */ - if (dname == NULL && F_ISSET(dbp, DB_AM_CREATED)) - LF_SET(DB_TRUNCATE); - - /* Set up the underlying environment. */ - if ((ret = __db_dbenv_setup(dbp, txn, fname, dname, id, flags)) != 0) - return (ret); - - /* For in-memory databases, we now need to open/create the database. */ - if (F_ISSET(dbp, DB_AM_INMEM)) { - if (dname == NULL) - ret = __db_new_file(dbp, txn, NULL, NULL); - else { - id = TXN_INVALID; - if ((ret = __fop_file_setup(dbp, - txn, dname, mode, flags, &id)) == 0 && - DBENV_LOGGING(dbenv) && !F_ISSET(dbp, DB_AM_RECOVER) -#if !defined(DEBUG_ROP) - && !F_ISSET(dbp, DB_AM_RDONLY) -#endif - ) - ret = __dbreg_log_id(dbp, - txn, dbp->log_filename->id, 1); - } - if (ret != 0) - goto err; - } - - switch (dbp->type) { - case DB_BTREE: - ret = __bam_open(dbp, txn, fname, meta_pgno, flags); - break; - case DB_HASH: - ret = __ham_open(dbp, txn, fname, meta_pgno, flags); - break; - case DB_RECNO: - ret = __ram_open(dbp, txn, fname, meta_pgno, flags); - break; - case DB_QUEUE: - ret = __qam_open( - dbp, txn, fname, meta_pgno, mode, flags); - break; - case DB_UNKNOWN: - return ( - __db_unknown_type(dbenv, "__db_dbopen", dbp->type)); - } - if (ret != 0) - goto err; - - DB_TEST_RECOVERY(dbp, DB_TEST_POSTOPEN, ret, fname); - - /* - * Temporary files don't need handle locks, so we only have to check - * for a handle lock downgrade or lockevent in the case of named - * files. - */ - if (!F_ISSET(dbp, DB_AM_RECOVER) && (fname != NULL || dname != NULL) - && LOCK_ISSET(dbp->handle_lock)) { - if (txn != NULL) - ret = __txn_lockevent(dbenv, - txn, dbp, &dbp->handle_lock, dbp->lid); - else if (LOCKING_ON(dbenv)) - /* Trade write handle lock for read handle lock. */ - ret = __lock_downgrade(dbenv, - &dbp->handle_lock, DB_LOCK_READ, 0); - } -DB_TEST_RECOVERY_LABEL -err: - return (ret); -} - -/* - * __db_get_open_flags -- - * Accessor for flags passed into DB->open call - * - * PUBLIC: int __db_get_open_flags __P((DB *, u_int32_t *)); - */ -int -__db_get_open_flags(dbp, flagsp) - DB *dbp; - u_int32_t *flagsp; -{ - DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->get_open_flags"); - - *flagsp = dbp->open_flags; - return (0); -} - -/* - * __db_new_file -- - * Create a new database file. - * - * PUBLIC: int __db_new_file __P((DB *, DB_TXN *, DB_FH *, const char *)); - */ -int -__db_new_file(dbp, txn, fhp, name) - DB *dbp; - DB_TXN *txn; - DB_FH *fhp; - const char *name; -{ - int ret; - - switch (dbp->type) { - case DB_BTREE: - case DB_RECNO: - ret = __bam_new_file(dbp, txn, fhp, name); - break; - case DB_HASH: - ret = __ham_new_file(dbp, txn, fhp, name); - break; - case DB_QUEUE: - ret = __qam_new_file(dbp, txn, fhp, name); - break; - case DB_UNKNOWN: - default: - __db_err(dbp->dbenv, - "%s: Invalid type %d specified", name, dbp->type); - ret = EINVAL; - break; - } - - DB_TEST_RECOVERY(dbp, DB_TEST_POSTLOGMETA, ret, name); - /* Sync the file in preparation for moving it into place. */ - if (ret == 0 && fhp != NULL) - ret = __os_fsync(dbp->dbenv, fhp); - - DB_TEST_RECOVERY(dbp, DB_TEST_POSTSYNC, ret, name); - -DB_TEST_RECOVERY_LABEL - return (ret); -} - -/* - * __db_init_subdb -- - * Initialize the dbp for a subdb. - * - * PUBLIC: int __db_init_subdb __P((DB *, DB *, const char *, DB_TXN *)); - */ -int -__db_init_subdb(mdbp, dbp, name, txn) - DB *mdbp, *dbp; - const char *name; - DB_TXN *txn; -{ - DBMETA *meta; - DB_MPOOLFILE *mpf; - int ret, t_ret; - - ret = 0; - if (!F_ISSET(dbp, DB_AM_CREATED)) { - /* Subdb exists; read meta-data page and initialize. */ - mpf = mdbp->mpf; - if ((ret = __memp_fget(mpf, &dbp->meta_pgno, 0, &meta)) != 0) - goto err; - ret = __db_meta_setup(mdbp->dbenv, dbp, name, meta, 0, 0); - if ((t_ret = __memp_fput(mpf, meta, 0)) != 0 && ret == 0) - ret = t_ret; - /* - * If __db_meta_setup found that the meta-page hadn't - * been written out during recovery, we can just return. - */ - if (ret == ENOENT) - ret = 0; - goto err; - } - - /* Handle the create case here. */ - switch (dbp->type) { - case DB_BTREE: - case DB_RECNO: - ret = __bam_new_subdb(mdbp, dbp, txn); - break; - case DB_HASH: - ret = __ham_new_subdb(mdbp, dbp, txn); - break; - case DB_QUEUE: - ret = EINVAL; - break; - case DB_UNKNOWN: - default: - __db_err(dbp->dbenv, - "Invalid subdatabase type %d specified", dbp->type); - return (EINVAL); - } - -err: return (ret); -} - -/* - * __db_chk_meta -- - * Take a buffer containing a meta-data page and check it for a valid LSN, - * checksum (and verify the checksum if necessary) and possibly decrypt it. - * - * Return 0 on success, >0 (errno) on error, -1 on checksum mismatch. - * - * PUBLIC: int __db_chk_meta __P((DB_ENV *, DB *, DBMETA *, int)); - */ -int -__db_chk_meta(dbenv, dbp, meta, do_metachk) - DB_ENV *dbenv; - DB *dbp; - DBMETA *meta; - int do_metachk; -{ - DB_LSN cur_lsn, swap_lsn; - int is_hmac, ret, swapped; - u_int32_t magic, orig_chk; - u_int8_t *chksum; - - ret = 0; - swapped = 0; - - if (FLD_ISSET(meta->metaflags, DBMETA_CHKSUM)) { - if (dbp != NULL) - F_SET(dbp, DB_AM_CHKSUM); - - is_hmac = meta->encrypt_alg == 0 ? 0 : 1; - chksum = ((BTMETA *)meta)->chksum; - - /* - * If we need to swap, the checksum function overwrites the - * original checksum with 0, so we need to save a copy of the - * original for swapping later. - */ - orig_chk = *(u_int32_t *)chksum; - - /* - * We cannot add this to __db_metaswap because that gets done - * later after we've verified the checksum or decrypted. - */ - if (do_metachk) { - swapped = 0; -chk_retry: if ((ret = __db_check_chksum(dbenv, - (DB_CIPHER *)dbenv->crypto_handle, chksum, meta, - DBMETASIZE, is_hmac)) != 0) { - if (is_hmac || swapped) - return (ret); - - M_32_SWAP(orig_chk); - swapped = 1; - *(u_int32_t *)chksum = orig_chk; - goto chk_retry; - } - } - } else if (dbp != NULL) - F_CLR(dbp, DB_AM_CHKSUM); - -#ifdef HAVE_CRYPTO - ret = __crypto_decrypt_meta(dbenv, dbp, (u_int8_t *)meta, do_metachk); -#endif - - /* Now that we're decrypted, we can check LSN. */ - if (LOGGING_ON(dbenv)) { - /* - * This gets called both before and after swapping, so we - * need to check ourselves. If we already swapped it above, - * we'll know that here. - */ - - swap_lsn = meta->lsn; - magic = meta->magic; -lsn_retry: - if (swapped) { - M_32_SWAP(swap_lsn.file); - M_32_SWAP(swap_lsn.offset); - M_32_SWAP(magic); - } - switch (magic) { - case DB_BTREEMAGIC: - case DB_HASHMAGIC: - case DB_QAMMAGIC: - case DB_RENAMEMAGIC: - break; - default: - if (swapped) - return (EINVAL); - swapped = 1; - goto lsn_retry; - } - if (!IS_REP_CLIENT(dbenv) && - !IS_NOT_LOGGED_LSN(swap_lsn) && !IS_ZERO_LSN(swap_lsn)) { - /* Need to do check. */ - if ((ret = __log_current_lsn(dbenv, - &cur_lsn, NULL, NULL)) != 0) - return (ret); - if (log_compare(&swap_lsn, &cur_lsn) > 0) { - __db_err(dbenv, - "file %s (meta pgno = %lu) has LSN [%lu][%lu].", - dbp->fname == NULL - ? "unknown" : dbp->fname, - (u_long)dbp->meta_pgno, - (u_long)swap_lsn.file, - (u_long)swap_lsn.offset); - __db_err(dbenv, "end of log is [%lu][%lu]", - (u_long)cur_lsn.file, - (u_long)cur_lsn.offset); - return (EINVAL); - } - } - } - return (ret); -} - -/* - * __db_meta_setup -- - * - * Take a buffer containing a meta-data page and figure out if it's - * valid, and if so, initialize the dbp from the meta-data page. - * - * PUBLIC: int __db_meta_setup __P((DB_ENV *, - * PUBLIC: DB *, const char *, DBMETA *, u_int32_t, int)); - */ -int -__db_meta_setup(dbenv, dbp, name, meta, oflags, do_metachk) - DB_ENV *dbenv; - DB *dbp; - const char *name; - DBMETA *meta; - u_int32_t oflags; - int do_metachk; -{ - u_int32_t flags, magic; - int ret; - - ret = 0; - - /* - * Figure out what access method we're dealing with, and then - * call access method specific code to check error conditions - * based on conflicts between the found file and application - * arguments. A found file overrides some user information -- - * we don't consider it an error, for example, if the user set - * an expected byte order and the found file doesn't match it. - */ - F_CLR(dbp, DB_AM_SWAP | DB_AM_IN_RENAME); - magic = meta->magic; - -swap_retry: - switch (magic) { - case DB_BTREEMAGIC: - case DB_HASHMAGIC: - case DB_QAMMAGIC: - case DB_RENAMEMAGIC: - break; - case 0: - /* - * The only time this should be 0 is if we're in the - * midst of opening a subdb during recovery and that - * subdatabase had its meta-data page allocated, but - * not yet initialized. - */ - if (F_ISSET(dbp, DB_AM_SUBDB) && ((IS_RECOVERING(dbenv) && - F_ISSET((DB_LOG *) dbenv->lg_handle, DBLOG_FORCE_OPEN)) || - meta->pgno != PGNO_INVALID)) - return (ENOENT); - - goto bad_format; - default: - if (F_ISSET(dbp, DB_AM_SWAP)) - goto bad_format; - - M_32_SWAP(magic); - F_SET(dbp, DB_AM_SWAP); - goto swap_retry; - } - - /* - * We can only check the meta page if we are sure we have a meta page. - * If it is random data, then this check can fail. So only now can we - * checksum and decrypt. Don't distinguish between configuration and - * checksum match errors here, because we haven't opened the database - * and even a checksum error isn't a reason to panic the environment. - */ - if ((ret = __db_chk_meta(dbenv, dbp, meta, do_metachk)) != 0) { - if (ret == -1) - __db_err(dbenv, - "%s: metadata page checksum error", name); - goto bad_format; - } - - switch (magic) { - case DB_BTREEMAGIC: - if (dbp->type != DB_UNKNOWN && - dbp->type != DB_RECNO && dbp->type != DB_BTREE) - goto bad_format; - - flags = meta->flags; - if (F_ISSET(dbp, DB_AM_SWAP)) - M_32_SWAP(flags); - if (LF_ISSET(BTM_RECNO)) - dbp->type = DB_RECNO; - else - dbp->type = DB_BTREE; - if ((oflags & DB_TRUNCATE) == 0 && (ret = - __bam_metachk(dbp, name, (BTMETA *)meta)) != 0) - return (ret); - break; - case DB_HASHMAGIC: - if (dbp->type != DB_UNKNOWN && dbp->type != DB_HASH) - goto bad_format; - - dbp->type = DB_HASH; - if ((oflags & DB_TRUNCATE) == 0 && (ret = - __ham_metachk(dbp, name, (HMETA *)meta)) != 0) - return (ret); - break; - case DB_QAMMAGIC: - if (dbp->type != DB_UNKNOWN && dbp->type != DB_QUEUE) - goto bad_format; - dbp->type = DB_QUEUE; - if ((oflags & DB_TRUNCATE) == 0 && (ret = - __qam_metachk(dbp, name, (QMETA *)meta)) != 0) - return (ret); - break; - case DB_RENAMEMAGIC: - F_SET(dbp, DB_AM_IN_RENAME); - - /* Copy the file's ID. */ - memcpy(dbp->fileid, ((DBMETA *)meta)->uid, DB_FILE_ID_LEN); - - break; - default: - goto bad_format; - } - return (0); - -bad_format: - if (F_ISSET(dbp, DB_AM_RECOVER)) - ret = ENOENT; - else - __db_err(dbenv, "%s: unexpected file type or format", name); - return (ret == 0 ? EINVAL : ret); -} diff --git a/storage/bdb/db/db_overflow.c b/storage/bdb/db/db_overflow.c deleted file mode 100644 index 818ee91a8b2..00000000000 --- a/storage/bdb/db/db_overflow.c +++ /dev/null @@ -1,441 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994, 1995, 1996 - * Keith Bostic. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994, 1995 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Mike Olson. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: db_overflow.c,v 12.3 2005/08/08 17:30:51 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/db_am.h" -#include "dbinc/mp.h" - -/* - * Big key/data code. - * - * Big key and data entries are stored on linked lists of pages. The initial - * reference is a structure with the total length of the item and the page - * number where it begins. Each entry in the linked list contains a pointer - * to the next page of data, and so on. - */ - -/* - * __db_goff -- - * Get an offpage item. - * - * PUBLIC: int __db_goff __P((DB *, DBT *, - * PUBLIC: u_int32_t, db_pgno_t, void **, u_int32_t *)); - */ -int -__db_goff(dbp, dbt, tlen, pgno, bpp, bpsz) - DB *dbp; - DBT *dbt; - u_int32_t tlen; - db_pgno_t pgno; - void **bpp; - u_int32_t *bpsz; -{ - DB_ENV *dbenv; - DB_MPOOLFILE *mpf; - PAGE *h; - db_indx_t bytes; - u_int32_t curoff, needed, start; - u_int8_t *p, *src; - int ret; - - dbenv = dbp->dbenv; - mpf = dbp->mpf; - - /* - * Check if the buffer is big enough; if it is not and we are - * allowed to malloc space, then we'll malloc it. If we are - * not (DB_DBT_USERMEM), then we'll set the dbt and return - * appropriately. - */ - if (F_ISSET(dbt, DB_DBT_PARTIAL)) { - start = dbt->doff; - if (start > tlen) - needed = 0; - else if (dbt->dlen > tlen - start) - needed = tlen - start; - else - needed = dbt->dlen; - } else { - start = 0; - needed = tlen; - } - - /* Allocate any necessary memory. */ - if (F_ISSET(dbt, DB_DBT_USERMEM)) { - if (needed > dbt->ulen) { - dbt->size = needed; - return (DB_BUFFER_SMALL); - } - } else if (F_ISSET(dbt, DB_DBT_MALLOC)) { - if ((ret = __os_umalloc(dbenv, needed, &dbt->data)) != 0) - return (ret); - } else if (F_ISSET(dbt, DB_DBT_REALLOC)) { - if ((ret = __os_urealloc(dbenv, needed, &dbt->data)) != 0) - return (ret); - } else if (bpsz != NULL && (*bpsz == 0 || *bpsz < needed)) { - if ((ret = __os_realloc(dbenv, needed, bpp)) != 0) - return (ret); - *bpsz = needed; - dbt->data = *bpp; - } else if (bpp != NULL) - dbt->data = *bpp; - else { - DB_ASSERT( - F_ISSET(dbt, - DB_DBT_USERMEM | DB_DBT_MALLOC | DB_DBT_REALLOC) || - bpsz != NULL || bpp != NULL); - return (DB_BUFFER_SMALL); - } - - /* - * Step through the linked list of pages, copying the data on each - * one into the buffer. Never copy more than the total data length. - */ - dbt->size = needed; - for (curoff = 0, p = dbt->data; pgno != PGNO_INVALID && needed > 0;) { - if ((ret = __memp_fget(mpf, &pgno, 0, &h)) != 0) - return (ret); - - /* Check if we need any bytes from this page. */ - if (curoff + OV_LEN(h) >= start) { - src = (u_int8_t *)h + P_OVERHEAD(dbp); - bytes = OV_LEN(h); - if (start > curoff) { - src += start - curoff; - bytes -= start - curoff; - } - if (bytes > needed) - bytes = needed; - memcpy(p, src, bytes); - p += bytes; - needed -= bytes; - } - curoff += OV_LEN(h); - pgno = h->next_pgno; - (void)__memp_fput(mpf, h, 0); - } - return (0); -} - -/* - * __db_poff -- - * Put an offpage item. - * - * PUBLIC: int __db_poff __P((DBC *, const DBT *, db_pgno_t *)); - */ -int -__db_poff(dbc, dbt, pgnop) - DBC *dbc; - const DBT *dbt; - db_pgno_t *pgnop; -{ - DB *dbp; - DBT tmp_dbt; - DB_LSN new_lsn, null_lsn; - DB_MPOOLFILE *mpf; - PAGE *pagep, *lastp; - db_indx_t pagespace; - u_int32_t sz; - u_int8_t *p; - int ret, t_ret; - - /* - * Allocate pages and copy the key/data item into them. Calculate the - * number of bytes we get for pages we fill completely with a single - * item. - */ - dbp = dbc->dbp; - mpf = dbp->mpf; - pagespace = P_MAXSPACE(dbp, dbp->pgsize); - - ret = 0; - lastp = NULL; - for (p = dbt->data, - sz = dbt->size; sz > 0; p += pagespace, sz -= pagespace) { - /* - * Reduce pagespace so we terminate the loop correctly and - * don't copy too much data. - */ - if (sz < pagespace) - pagespace = sz; - - /* - * Allocate and initialize a new page and copy all or part of - * the item onto the page. If sz is less than pagespace, we - * have a partial record. - */ - if ((ret = __db_new(dbc, P_OVERFLOW, &pagep)) != 0) - break; - if (DBC_LOGGING(dbc)) { - tmp_dbt.data = p; - tmp_dbt.size = pagespace; - ZERO_LSN(null_lsn); - if ((ret = __db_big_log(dbp, dbc->txn, - &new_lsn, 0, DB_ADD_BIG, PGNO(pagep), - lastp ? PGNO(lastp) : PGNO_INVALID, - PGNO_INVALID, &tmp_dbt, &LSN(pagep), - lastp == NULL ? &null_lsn : &LSN(lastp), - &null_lsn)) != 0) { - if (lastp != NULL) - (void)__memp_fput(mpf, - lastp, DB_MPOOL_DIRTY); - lastp = pagep; - break; - } - } else - LSN_NOT_LOGGED(new_lsn); - - /* Move LSN onto page. */ - if (lastp != NULL) - LSN(lastp) = new_lsn; - LSN(pagep) = new_lsn; - - OV_LEN(pagep) = pagespace; - OV_REF(pagep) = 1; - memcpy((u_int8_t *)pagep + P_OVERHEAD(dbp), p, pagespace); - - /* - * If this is the first entry, update the user's info. - * Otherwise, update the entry on the last page filled - * in and release that page. - */ - if (lastp == NULL) - *pgnop = PGNO(pagep); - else { - lastp->next_pgno = PGNO(pagep); - pagep->prev_pgno = PGNO(lastp); - (void)__memp_fput(mpf, lastp, DB_MPOOL_DIRTY); - } - lastp = pagep; - } - if (lastp != NULL && - (t_ret = __memp_fput(mpf, lastp, DB_MPOOL_DIRTY)) != 0 && ret == 0) - ret = t_ret; - return (ret); -} - -/* - * __db_ovref -- - * Increment/decrement the reference count on an overflow page. - * - * PUBLIC: int __db_ovref __P((DBC *, db_pgno_t, int32_t)); - */ -int -__db_ovref(dbc, pgno, adjust) - DBC *dbc; - db_pgno_t pgno; - int32_t adjust; -{ - DB *dbp; - DB_MPOOLFILE *mpf; - PAGE *h; - int ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - - if ((ret = __memp_fget(mpf, &pgno, 0, &h)) != 0) - return (ret); - - if (DBC_LOGGING(dbc)) { - if ((ret = __db_ovref_log(dbp, - dbc->txn, &LSN(h), 0, h->pgno, adjust, &LSN(h))) != 0) { - (void)__memp_fput(mpf, h, 0); - return (ret); - } - } else - LSN_NOT_LOGGED(LSN(h)); - OV_REF(h) += adjust; - - (void)__memp_fput(mpf, h, DB_MPOOL_DIRTY); - return (0); -} - -/* - * __db_doff -- - * Delete an offpage chain of overflow pages. - * - * PUBLIC: int __db_doff __P((DBC *, db_pgno_t)); - */ -int -__db_doff(dbc, pgno) - DBC *dbc; - db_pgno_t pgno; -{ - DB *dbp; - PAGE *pagep; - DB_LSN null_lsn; - DB_MPOOLFILE *mpf; - DBT tmp_dbt; - int ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - - do { - if ((ret = __memp_fget(mpf, &pgno, 0, &pagep)) != 0) - return (ret); - - DB_ASSERT(TYPE(pagep) == P_OVERFLOW); - /* - * If it's referenced by more than one key/data item, - * decrement the reference count and return. - */ - if (OV_REF(pagep) > 1) { - (void)__memp_fput(mpf, pagep, 0); - return (__db_ovref(dbc, pgno, -1)); - } - - if (DBC_LOGGING(dbc)) { - tmp_dbt.data = (u_int8_t *)pagep + P_OVERHEAD(dbp); - tmp_dbt.size = OV_LEN(pagep); - ZERO_LSN(null_lsn); - if ((ret = __db_big_log(dbp, dbc->txn, - &LSN(pagep), 0, DB_REM_BIG, - PGNO(pagep), PREV_PGNO(pagep), - NEXT_PGNO(pagep), &tmp_dbt, - &LSN(pagep), &null_lsn, &null_lsn)) != 0) { - (void)__memp_fput(mpf, pagep, 0); - return (ret); - } - } else - LSN_NOT_LOGGED(LSN(pagep)); - pgno = pagep->next_pgno; - OV_LEN(pagep) = 0; - if ((ret = __db_free(dbc, pagep)) != 0) - return (ret); - } while (pgno != PGNO_INVALID); - - return (0); -} - -/* - * __db_moff -- - * Match on overflow pages. - * - * Given a starting page number and a key, return <0, 0, >0 to indicate if the - * key on the page is less than, equal to or greater than the key specified. - * We optimize this by doing chunk at a time comparison unless the user has - * specified a comparison function. In this case, we need to materialize - * the entire object and call their comparison routine. - * - * PUBLIC: int __db_moff __P((DB *, const DBT *, db_pgno_t, u_int32_t, - * PUBLIC: int (*)(DB *, const DBT *, const DBT *), int *)); - */ -int -__db_moff(dbp, dbt, pgno, tlen, cmpfunc, cmpp) - DB *dbp; - const DBT *dbt; - db_pgno_t pgno; - u_int32_t tlen; - int (*cmpfunc) __P((DB *, const DBT *, const DBT *)), *cmpp; -{ - DBT local_dbt; - DB_MPOOLFILE *mpf; - PAGE *pagep; - void *buf; - u_int32_t bufsize, cmp_bytes, key_left; - u_int8_t *p1, *p2; - int ret; - - mpf = dbp->mpf; - - /* - * If there is a user-specified comparison function, build a - * contiguous copy of the key, and call it. - */ - if (cmpfunc != NULL) { - memset(&local_dbt, 0, sizeof(local_dbt)); - buf = NULL; - bufsize = 0; - - if ((ret = __db_goff(dbp, - &local_dbt, tlen, pgno, &buf, &bufsize)) != 0) - return (ret); - /* Pass the key as the first argument */ - *cmpp = cmpfunc(dbp, dbt, &local_dbt); - __os_free(dbp->dbenv, buf); - return (0); - } - - /* While there are both keys to compare. */ - for (*cmpp = 0, p1 = dbt->data, - key_left = dbt->size; key_left > 0 && pgno != PGNO_INVALID;) { - if ((ret = __memp_fget(mpf, &pgno, 0, &pagep)) != 0) - return (ret); - - cmp_bytes = OV_LEN(pagep) < key_left ? OV_LEN(pagep) : key_left; - tlen -= cmp_bytes; - key_left -= cmp_bytes; - for (p2 = (u_int8_t *)pagep + P_OVERHEAD(dbp); - cmp_bytes-- > 0; ++p1, ++p2) - if (*p1 != *p2) { - *cmpp = (long)*p1 - (long)*p2; - break; - } - pgno = NEXT_PGNO(pagep); - if ((ret = __memp_fput(mpf, pagep, 0)) != 0) - return (ret); - if (*cmpp != 0) - return (0); - } - if (key_left > 0) /* DBT is longer than the page key. */ - *cmpp = 1; - else if (tlen > 0) /* DBT is shorter than the page key. */ - *cmpp = -1; - else - *cmpp = 0; - - return (0); -} diff --git a/storage/bdb/db/db_ovfl_vrfy.c b/storage/bdb/db/db_ovfl_vrfy.c deleted file mode 100644 index ceff4d2569c..00000000000 --- a/storage/bdb/db/db_ovfl_vrfy.c +++ /dev/null @@ -1,374 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994, 1995, 1996 - * Keith Bostic. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994, 1995 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Mike Olson. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: db_ovfl_vrfy.c,v 12.1 2005/06/16 20:21:13 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/db_am.h" -#include "dbinc/db_verify.h" -#include "dbinc/mp.h" - -/* - * __db_vrfy_overflow -- - * Verify overflow page. - * - * PUBLIC: int __db_vrfy_overflow __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, - * PUBLIC: u_int32_t)); - */ -int -__db_vrfy_overflow(dbp, vdp, h, pgno, flags) - DB *dbp; - VRFY_DBINFO *vdp; - PAGE *h; - db_pgno_t pgno; - u_int32_t flags; -{ - VRFY_PAGEINFO *pip; - int isbad, ret, t_ret; - - isbad = 0; - if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) - return (ret); - - if ((ret = __db_vrfy_datapage(dbp, vdp, h, pgno, flags)) != 0) { - if (ret == DB_VERIFY_BAD) - isbad = 1; - else - goto err; - } - - pip->refcount = OV_REF(h); - if (pip->refcount < 1) { - EPRINT((dbp->dbenv, - "Page %lu: overflow page has zero reference count", - (u_long)pgno)); - isbad = 1; - } - - /* Just store for now. */ - pip->olen = HOFFSET(h); - -err: if ((t_ret = __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0) - ret = t_ret; - return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); -} - -/* - * __db_vrfy_ovfl_structure -- - * Walk a list of overflow pages, avoiding cycles and marking - * pages seen. - * - * PUBLIC: int __db_vrfy_ovfl_structure - * PUBLIC: __P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t, u_int32_t)); - */ -int -__db_vrfy_ovfl_structure(dbp, vdp, pgno, tlen, flags) - DB *dbp; - VRFY_DBINFO *vdp; - db_pgno_t pgno; - u_int32_t tlen; - u_int32_t flags; -{ - DB *pgset; - VRFY_PAGEINFO *pip; - db_pgno_t next, prev; - int isbad, ret, seen_cnt, t_ret; - u_int32_t refcount; - - pgset = vdp->pgset; - DB_ASSERT(pgset != NULL); - isbad = 0; - - /* This shouldn't happen, but just to be sure. */ - if (!IS_VALID_PGNO(pgno)) - return (DB_VERIFY_BAD); - - /* - * Check the first prev_pgno; it ought to be PGNO_INVALID, - * since there's no prev page. - */ - if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) - return (ret); - - /* The refcount is stored on the first overflow page. */ - refcount = pip->refcount; - - if (pip->type != P_OVERFLOW) { - EPRINT((dbp->dbenv, - "Page %lu: overflow page of invalid type %lu", - (u_long)pgno, (u_long)pip->type)); - ret = DB_VERIFY_BAD; - goto err; /* Unsafe to continue. */ - } - - prev = pip->prev_pgno; - if (prev != PGNO_INVALID) { - EPRINT((dbp->dbenv, - "Page %lu: first page in overflow chain has a prev_pgno %lu", - (u_long)pgno, (u_long)prev)); - isbad = 1; - } - - for (;;) { - /* - * We may have seen this page elsewhere, if the overflow entry - * has been promoted to an internal page; we just want to - * make sure that each overflow page is seen exactly as many - * times as its refcount dictates. - * - * Note that this code also serves to keep us from looping - * infinitely if there's a cycle in an overflow chain. - */ - if ((ret = __db_vrfy_pgset_get(pgset, pgno, &seen_cnt)) != 0) - goto err; - if ((u_int32_t)seen_cnt > refcount) { - EPRINT((dbp->dbenv, - "Page %lu: encountered too many times in overflow traversal", - (u_long)pgno)); - ret = DB_VERIFY_BAD; - goto err; - } - if ((ret = __db_vrfy_pgset_inc(pgset, pgno)) != 0) - goto err; - - /* - * Each overflow page can be referenced multiple times, - * because it's possible for overflow Btree keys to get - * promoted to internal pages. We want to make sure that - * each page is referenced from a Btree leaf (or Hash data - * page, which we consider a "leaf" here) exactly once; if - * the parent was a leaf, set a flag to indicate that we've - * seen this page in a leaf context. - * - * If the parent is not a leaf--in which case it's a Btree - * internal page--we don't need to bother doing any further - * verification, as we'll do it when we hit the leaf (or - * complain that we never saw the leaf). Only the first - * page in an overflow chain should ever have a refcount - * greater than 1, and the combination of the LEAFSEEN check - * and the fact that we bail after the first page for - * non-leaves should ensure this. - * - * Note that each "child" of a page, such as an overflow page, - * is stored and verified in a structure check exactly once, - * so this code does not need to contend with the fact that - * overflow chains used as Btree duplicate keys may be - * referenced multiply from a single Btree leaf page. - */ - if (LF_ISSET(ST_OVFL_LEAF)) { - if (F_ISSET(pip, VRFY_OVFL_LEAFSEEN)) { - EPRINT((dbp->dbenv, - "Page %lu: overflow page linked twice from leaf or data page", - (u_long)pgno)); - ret = DB_VERIFY_BAD; - goto err; - } - F_SET(pip, VRFY_OVFL_LEAFSEEN); - } - - /* - * We want to verify each overflow chain only once, and - * although no chain should be linked more than once from a - * leaf page, we can't guarantee that it'll be linked that - * once if it's linked from an internal page and the key - * is gone. - * - * seen_cnt is the number of times we'd encountered this page - * before calling this function. - */ - if (seen_cnt == 0) { - /* - * Keep a running tab on how much of the item we've - * seen. - */ - tlen -= pip->olen; - - /* Send the application feedback about our progress. */ - if (!LF_ISSET(DB_SALVAGE)) - __db_vrfy_struct_feedback(dbp, vdp); - } else - goto done; - - next = pip->next_pgno; - - /* Are we there yet? */ - if (next == PGNO_INVALID) - break; - - /* - * We've already checked this when we saved it, but just - * to be sure... - */ - if (!IS_VALID_PGNO(next)) { - DB_ASSERT(0); - EPRINT((dbp->dbenv, - "Page %lu: bad next_pgno %lu on overflow page", - (u_long)pgno, (u_long)next)); - ret = DB_VERIFY_BAD; - goto err; - } - - if ((ret = __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0 || - (ret = __db_vrfy_getpageinfo(vdp, next, &pip)) != 0) - return (ret); - if (pip->prev_pgno != pgno) { - EPRINT((dbp->dbenv, - "Page %lu: bad prev_pgno %lu on overflow page (should be %lu)", - (u_long)next, (u_long)pip->prev_pgno, - (u_long)pgno)); - isbad = 1; - /* - * It's safe to continue because we have separate - * cycle detection. - */ - } - - pgno = next; - } - - if (tlen > 0) { - isbad = 1; - EPRINT((dbp->dbenv, - "Page %lu: overflow item incomplete", (u_long)pgno)); - } - -done: -err: if ((t_ret = - __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0 && ret == 0) - ret = t_ret; - return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); -} - -/* - * __db_safe_goff -- - * Get an overflow item, very carefully, from an untrusted database, - * in the context of the salvager. - * - * PUBLIC: int __db_safe_goff __P((DB *, VRFY_DBINFO *, db_pgno_t, - * PUBLIC: DBT *, void *, u_int32_t)); - */ -int -__db_safe_goff(dbp, vdp, pgno, dbt, buf, flags) - DB *dbp; - VRFY_DBINFO *vdp; - db_pgno_t pgno; - DBT *dbt; - void *buf; - u_int32_t flags; -{ - DB_MPOOLFILE *mpf; - PAGE *h; - int ret, t_ret; - u_int32_t bytesgot, bytes; - u_int8_t *src, *dest; - - mpf = dbp->mpf; - h = NULL; - ret = t_ret = 0; - bytesgot = bytes = 0; - - while ((pgno != PGNO_INVALID) && (IS_VALID_PGNO(pgno))) { - /* - * Mark that we're looking at this page; if we've seen it - * already, quit. - */ - if ((ret = __db_salvage_markdone(vdp, pgno)) != 0) - break; - - if ((ret = __memp_fget(mpf, &pgno, 0, &h)) != 0) - break; - - /* - * Make sure it's really an overflow page, unless we're - * being aggressive, in which case we pretend it is. - */ - if (!LF_ISSET(DB_AGGRESSIVE) && TYPE(h) != P_OVERFLOW) { - ret = DB_VERIFY_BAD; - break; - } - - src = (u_int8_t *)h + P_OVERHEAD(dbp); - bytes = OV_LEN(h); - - if (bytes + P_OVERHEAD(dbp) > dbp->pgsize) - bytes = dbp->pgsize - P_OVERHEAD(dbp); - - if ((ret = __os_realloc(dbp->dbenv, - bytesgot + bytes, buf)) != 0) - break; - - dest = *(u_int8_t **)buf + bytesgot; - bytesgot += bytes; - - memcpy(dest, src, bytes); - - pgno = NEXT_PGNO(h); - - if ((ret = __memp_fput(mpf, h, 0)) != 0) - break; - h = NULL; - } - - /* - * If we're being aggressive, salvage a partial datum if there - * was an error somewhere along the way. - */ - if (ret == 0 || LF_ISSET(DB_AGGRESSIVE)) { - dbt->size = bytesgot; - dbt->data = *(void **)buf; - } - - /* If we broke out on error, don't leave pages pinned. */ - if (h != NULL && (t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} diff --git a/storage/bdb/db/db_pr.c b/storage/bdb/db/db_pr.c deleted file mode 100644 index 4618d4f4754..00000000000 --- a/storage/bdb/db/db_pr.c +++ /dev/null @@ -1,1614 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_pr.c,v 12.17 2005/11/08 03:13:30 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <ctype.h> -#include <stdlib.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/btree.h" -#include "dbinc/hash.h" -#include "dbinc/mp.h" -#include "dbinc/qam.h" -#include "dbinc/db_verify.h" - -/* - * __db_loadme -- - * A nice place to put a breakpoint. - * - * PUBLIC: void __db_loadme __P((void)); - */ -void -__db_loadme() -{ - pid_t pid; - db_threadid_t tid; - - __os_id(NULL, &pid, &tid); -} - -#ifdef HAVE_STATISTICS -static int __db_bmeta __P((DB *, BTMETA *, u_int32_t)); -static int __db_hmeta __P((DB *, HMETA *, u_int32_t)); -static void __db_meta __P((DB *, DBMETA *, FN const *, u_int32_t)); -static const char *__db_pagetype_to_string __P((u_int32_t)); -static void __db_prdb __P((DB *, u_int32_t)); -static void __db_proff __P((DB_ENV *, DB_MSGBUF *, void *)); -static int __db_prtree __P((DB *, u_int32_t)); -static int __db_qmeta __P((DB *, QMETA *, u_int32_t)); - -/* - * __db_dumptree -- - * Dump the tree to a file. - * - * PUBLIC: int __db_dumptree __P((DB *, char *, char *)); - */ -int -__db_dumptree(dbp, op, name) - DB *dbp; - char *op, *name; -{ - DB_ENV *dbenv; - FILE *fp, *orig_fp; - u_int32_t flags; - int ret; - - dbenv = dbp->dbenv; - - for (flags = 0; *op != '\0'; ++op) - switch (*op) { - case 'a': - LF_SET(DB_PR_PAGE); - break; - case 'h': - break; - case 'r': - LF_SET(DB_PR_RECOVERYTEST); - break; - default: - return (EINVAL); - } - - if (name != NULL) { - if ((fp = fopen(name, "w")) == NULL) - return (__os_get_errno()); - - orig_fp = dbenv->db_msgfile; - dbenv->db_msgfile = fp; - } else - fp = orig_fp = NULL; - - __db_prdb(dbp, flags); - - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - - ret = __db_prtree(dbp, flags); - - if (fp != NULL) { - (void)fclose(fp); - dbenv->db_msgfile = orig_fp; - } - - return (ret); -} - -static const FN __db_flags_fn[] = { - { DB_AM_CHKSUM, "checksumming" }, - { DB_AM_CL_WRITER, "client replica writer" }, - { DB_AM_COMPENSATE, "created by compensating transaction" }, - { DB_AM_CREATED, "database created" }, - { DB_AM_CREATED_MSTR, "encompassing file created" }, - { DB_AM_DBM_ERROR, "dbm/ndbm error" }, - { DB_AM_DELIMITER, "variable length" }, - { DB_AM_DISCARD, "discard cached pages" }, - { DB_AM_DUP, "duplicates" }, - { DB_AM_DUPSORT, "sorted duplicates" }, - { DB_AM_ENCRYPT, "encrypted" }, - { DB_AM_FIXEDLEN, "fixed-length records" }, - { DB_AM_INMEM, "in-memory" }, - { DB_AM_IN_RENAME, "file is being renamed" }, - { DB_AM_NOT_DURABLE, "changes not logged" }, - { DB_AM_OPEN_CALLED, "open called" }, - { DB_AM_PAD, "pad value" }, - { DB_AM_PGDEF, "default page size" }, - { DB_AM_RDONLY, "read-only" }, - { DB_AM_READ_UNCOMMITTED, "read-uncommitted" }, - { DB_AM_RECNUM, "Btree record numbers" }, - { DB_AM_RECOVER, "opened for recovery" }, - { DB_AM_RENUMBER, "renumber" }, - { DB_AM_REVSPLITOFF, "no reverse splits" }, - { DB_AM_SECONDARY, "secondary" }, - { DB_AM_SNAPSHOT, "load on open" }, - { DB_AM_SUBDB, "subdatabases" }, - { DB_AM_SWAP, "needswap" }, - { DB_AM_TXN, "transactional" }, - { DB_AM_VERIFYING, "verifier" }, - { 0, NULL } -}; - -/* - * __db_get_flags_fn -- - * Return the __db_flags_fn array. - * - * PUBLIC: const FN * __db_get_flags_fn __P((void)); - */ -const FN * -__db_get_flags_fn() -{ - return (__db_flags_fn); -} - -/* - * __db_prdb -- - * Print out the DB structure information. - */ -static void -__db_prdb(dbp, flags) - DB *dbp; - u_int32_t flags; -{ - DB_MSGBUF mb; - DB_ENV *dbenv; - BTREE *bt; - HASH *h; - QUEUE *q; - - dbenv = dbp->dbenv; - - DB_MSGBUF_INIT(&mb); - __db_msg(dbenv, "In-memory DB structure:"); - __db_msgadd(dbenv, &mb, "%s: %#lx", - __db_dbtype_to_string(dbp->type), (u_long)dbp->flags); - __db_prflags(dbenv, &mb, dbp->flags, __db_flags_fn, " (", ")"); - DB_MSGBUF_FLUSH(dbenv, &mb); - - switch (dbp->type) { - case DB_BTREE: - case DB_RECNO: - bt = dbp->bt_internal; - __db_msg(dbenv, "bt_meta: %lu bt_root: %lu", - (u_long)bt->bt_meta, (u_long)bt->bt_root); - __db_msg(dbenv, "bt_minkey: %lu", (u_long)bt->bt_minkey); - if (!LF_ISSET(DB_PR_RECOVERYTEST)) - __db_msg(dbenv, "bt_compare: %#lx bt_prefix: %#lx", - P_TO_ULONG(bt->bt_compare), - P_TO_ULONG(bt->bt_prefix)); - __db_msg(dbenv, "bt_lpgno: %lu", (u_long)bt->bt_lpgno); - if (dbp->type == DB_RECNO) { - __db_msg(dbenv, - "re_pad: %#lx re_delim: %#lx re_len: %lu re_source: %s", - (u_long)bt->re_pad, (u_long)bt->re_delim, - (u_long)bt->re_len, - bt->re_source == NULL ? "" : bt->re_source); - __db_msg(dbenv, - "re_modified: %d re_eof: %d re_last: %lu", - bt->re_modified, bt->re_eof, (u_long)bt->re_last); - } - break; - case DB_HASH: - h = dbp->h_internal; - __db_msg(dbenv, "meta_pgno: %lu", (u_long)h->meta_pgno); - __db_msg(dbenv, "h_ffactor: %lu", (u_long)h->h_ffactor); - __db_msg(dbenv, "h_nelem: %lu", (u_long)h->h_nelem); - if (!LF_ISSET(DB_PR_RECOVERYTEST)) - __db_msg(dbenv, "h_hash: %#lx", P_TO_ULONG(h->h_hash)); - break; - case DB_QUEUE: - q = dbp->q_internal; - __db_msg(dbenv, "q_meta: %lu", (u_long)q->q_meta); - __db_msg(dbenv, "q_root: %lu", (u_long)q->q_root); - __db_msg(dbenv, "re_pad: %#lx re_len: %lu", - (u_long)q->re_pad, (u_long)q->re_len); - __db_msg(dbenv, "rec_page: %lu", (u_long)q->rec_page); - __db_msg(dbenv, "page_ext: %lu", (u_long)q->page_ext); - break; - case DB_UNKNOWN: - default: - break; - } -} - -/* - * __db_prtree -- - * Print out the entire tree. - */ -static int -__db_prtree(dbp, flags) - DB *dbp; - u_int32_t flags; -{ - DB_MPOOLFILE *mpf; - PAGE *h; - db_pgno_t i, last; - int ret; - - mpf = dbp->mpf; - - if (dbp->type == DB_QUEUE) - return (__db_prqueue(dbp, flags)); - - /* - * Find out the page number of the last page in the database, then - * dump each page. - */ - if ((ret = __memp_last_pgno(mpf, &last)) != 0) - return (ret); - for (i = 0; i <= last; ++i) { - if ((ret = __memp_fget(mpf, &i, 0, &h)) != 0) - return (ret); - (void)__db_prpage(dbp, h, flags); - if ((ret = __memp_fput(mpf, h, 0)) != 0) - return (ret); - } - - return (0); -} - -/* - * __db_meta -- - * Print out common metadata information. - */ -static void -__db_meta(dbp, dbmeta, fn, flags) - DB *dbp; - DBMETA *dbmeta; - FN const *fn; - u_int32_t flags; -{ - DB_MSGBUF mb; - DB_ENV *dbenv; - DB_MPOOLFILE *mpf; - PAGE *h; - db_pgno_t pgno; - u_int8_t *p; - int cnt, ret; - const char *sep; - - dbenv = dbp->dbenv; - mpf = dbp->mpf; - DB_MSGBUF_INIT(&mb); - - __db_msg(dbenv, "\tmagic: %#lx", (u_long)dbmeta->magic); - __db_msg(dbenv, "\tversion: %lu", (u_long)dbmeta->version); - __db_msg(dbenv, "\tpagesize: %lu", (u_long)dbmeta->pagesize); - __db_msg(dbenv, "\ttype: %lu", (u_long)dbmeta->type); - __db_msg(dbenv, "\tkeys: %lu\trecords: %lu", - (u_long)dbmeta->key_count, (u_long)dbmeta->record_count); - - /* - * If we're doing recovery testing, don't display the free list, - * it may have changed and that makes the dump diff not work. - */ - if (!LF_ISSET(DB_PR_RECOVERYTEST)) { - __db_msgadd( - dbenv, &mb, "\tfree list: %lu", (u_long)dbmeta->free); - for (pgno = dbmeta->free, - cnt = 0, sep = ", "; pgno != PGNO_INVALID;) { - if ((ret = __memp_fget(mpf, &pgno, 0, &h)) != 0) { - DB_MSGBUF_FLUSH(dbenv, &mb); - __db_msg(dbenv, - "Unable to retrieve free-list page: %lu: %s", - (u_long)pgno, db_strerror(ret)); - break; - } - pgno = h->next_pgno; - (void)__memp_fput(mpf, h, 0); - __db_msgadd(dbenv, &mb, "%s%lu", sep, (u_long)pgno); - if (++cnt % 10 == 0) { - DB_MSGBUF_FLUSH(dbenv, &mb); - cnt = 0; - sep = "\t"; - } else - sep = ", "; - } - DB_MSGBUF_FLUSH(dbenv, &mb); - __db_msg(dbenv, "\tlast_pgno: %lu", (u_long)dbmeta->last_pgno); - } - - if (fn != NULL) { - DB_MSGBUF_FLUSH(dbenv, &mb); - __db_msgadd(dbenv, &mb, "\tflags: %#lx", (u_long)dbmeta->flags); - __db_prflags(dbenv, &mb, dbmeta->flags, fn, " (", ")"); - } - - DB_MSGBUF_FLUSH(dbenv, &mb); - __db_msgadd(dbenv, &mb, "\tuid: "); - for (p = (u_int8_t *)dbmeta->uid, - cnt = 0; cnt < DB_FILE_ID_LEN; ++cnt) { - __db_msgadd(dbenv, &mb, "%x", *p++); - if (cnt < DB_FILE_ID_LEN - 1) - __db_msgadd(dbenv, &mb, " "); - } - DB_MSGBUF_FLUSH(dbenv, &mb); -} - -/* - * __db_bmeta -- - * Print out the btree meta-data page. - */ -static int -__db_bmeta(dbp, h, flags) - DB *dbp; - BTMETA *h; - u_int32_t flags; -{ - static const FN fn[] = { - { BTM_DUP, "duplicates" }, - { BTM_RECNO, "recno" }, - { BTM_RECNUM, "btree:recnum" }, - { BTM_FIXEDLEN, "recno:fixed-length" }, - { BTM_RENUMBER, "recno:renumber" }, - { BTM_SUBDB, "multiple-databases" }, - { BTM_DUPSORT, "sorted duplicates" }, - { 0, NULL } - }; - DB_ENV *dbenv; - - dbenv = dbp->dbenv; - - __db_meta(dbp, (DBMETA *)h, fn, flags); - - __db_msg(dbenv, "\tminkey: %lu", (u_long)h->minkey); - if (dbp->type == DB_RECNO) - __db_msg(dbenv, "\tre_len: %#lx re_pad: %#lx", - (u_long)h->re_len, (u_long)h->re_pad); - __db_msg(dbenv, "\troot: %lu", (u_long)h->root); - - return (0); -} - -/* - * __db_hmeta -- - * Print out the hash meta-data page. - */ -static int -__db_hmeta(dbp, h, flags) - DB *dbp; - HMETA *h; - u_int32_t flags; -{ - DB_MSGBUF mb; - static const FN fn[] = { - { DB_HASH_DUP, "duplicates" }, - { DB_HASH_SUBDB, "multiple-databases" }, - { DB_HASH_DUPSORT, "sorted duplicates" }, - { 0, NULL } - }; - DB_ENV *dbenv; - int i; - - dbenv = dbp->dbenv; - DB_MSGBUF_INIT(&mb); - - __db_meta(dbp, (DBMETA *)h, fn, flags); - - __db_msg(dbenv, "\tmax_bucket: %lu", (u_long)h->max_bucket); - __db_msg(dbenv, "\thigh_mask: %#lx", (u_long)h->high_mask); - __db_msg(dbenv, "\tlow_mask: %#lx", (u_long)h->low_mask); - __db_msg(dbenv, "\tffactor: %lu", (u_long)h->ffactor); - __db_msg(dbenv, "\tnelem: %lu", (u_long)h->nelem); - __db_msg(dbenv, "\th_charkey: %#lx", (u_long)h->h_charkey); - __db_msgadd(dbenv, &mb, "\tspare points: "); - for (i = 0; i < NCACHED; i++) - __db_msgadd(dbenv, &mb, "%lu ", (u_long)h->spares[i]); - DB_MSGBUF_FLUSH(dbenv, &mb); - - return (0); -} - -/* - * __db_qmeta -- - * Print out the queue meta-data page. - */ -static int -__db_qmeta(dbp, h, flags) - DB *dbp; - QMETA *h; - u_int32_t flags; -{ - DB_ENV *dbenv; - - dbenv = dbp->dbenv; - - __db_meta(dbp, (DBMETA *)h, NULL, flags); - - __db_msg(dbenv, "\tfirst_recno: %lu", (u_long)h->first_recno); - __db_msg(dbenv, "\tcur_recno: %lu", (u_long)h->cur_recno); - __db_msg(dbenv, "\tre_len: %#lx re_pad: %lu", - (u_long)h->re_len, (u_long)h->re_pad); - __db_msg(dbenv, "\trec_page: %lu", (u_long)h->rec_page); - __db_msg(dbenv, "\tpage_ext: %lu", (u_long)h->page_ext); - - return (0); -} - -/* - * __db_prnpage - * -- Print out a specific page. - * - * PUBLIC: int __db_prnpage __P((DB *, db_pgno_t)); - */ -int -__db_prnpage(dbp, pgno) - DB *dbp; - db_pgno_t pgno; -{ - DB_MPOOLFILE *mpf; - PAGE *h; - int ret, t_ret; - - mpf = dbp->mpf; - - if ((ret = __memp_fget(mpf, &pgno, 0, &h)) != 0) - return (ret); - - ret = __db_prpage(dbp, h, DB_PR_PAGE); - - if ((t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __db_prpage - * -- Print out a page. - * - * PUBLIC: int __db_prpage __P((DB *, PAGE *, u_int32_t)); - */ -int -__db_prpage(dbp, h, flags) - DB *dbp; - PAGE *h; - u_int32_t flags; -{ - BINTERNAL *bi; - BKEYDATA *bk; - DB_ENV *dbenv; - DB_MSGBUF mb; - HOFFPAGE a_hkd; - QAMDATA *qp, *qep; - RINTERNAL *ri; - db_indx_t dlen, len, i, *inp; - db_pgno_t pgno; - db_recno_t recno; - u_int32_t pagesize, qlen; - u_int8_t *ep, *hk, *p; - int deleted, ret; - const char *s; - void *sp; - - dbenv = dbp->dbenv; - DB_MSGBUF_INIT(&mb); - - /* - * If we're doing recovery testing and this page is P_INVALID, - * assume it's a page that's on the free list, and don't display it. - */ - if (LF_ISSET(DB_PR_RECOVERYTEST) && TYPE(h) == P_INVALID) - return (0); - - if ((s = __db_pagetype_to_string(TYPE(h))) == NULL) { - __db_msg(dbenv, "ILLEGAL PAGE TYPE: page: %lu type: %lu", - (u_long)h->pgno, (u_long)TYPE(h)); - return (1); - } - - /* - * !!! - * Find out the page size. We don't want to do it the "right" way, - * by reading the value from the meta-data page, that's going to be - * slow. Reach down into the mpool region. - */ - pagesize = (u_int32_t)dbp->mpf->mfp->stat.st_pagesize; - - /* Page number, page type. */ - __db_msgadd(dbenv, &mb, "page %lu: %s:", (u_long)h->pgno, s); - - /* - * LSNs on a metadata page will be different from the original after an - * abort, in some cases. Don't display them if we're testing recovery. - */ - if (!LF_ISSET(DB_PR_RECOVERYTEST) || - (TYPE(h) != P_BTREEMETA && TYPE(h) != P_HASHMETA && - TYPE(h) != P_QAMMETA && TYPE(h) != P_QAMDATA)) - __db_msgadd(dbenv, &mb, " LSN [%lu][%lu]:", - (u_long)LSN(h).file, (u_long)LSN(h).offset); - - /* - * Page level (only applicable for Btree/Recno, but we always display - * it, for no particular reason. - */ - __db_msgadd(dbenv, &mb, " level %lu", (u_long)h->level); - - /* Record count. */ - if (TYPE(h) == P_IBTREE || - TYPE(h) == P_IRECNO || (TYPE(h) == P_LRECNO && - h->pgno == ((BTREE *)dbp->bt_internal)->bt_root)) - __db_msgadd(dbenv, &mb, " records: %lu", (u_long)RE_NREC(h)); - DB_MSGBUF_FLUSH(dbenv, &mb); - - switch (TYPE(h)) { - case P_BTREEMETA: - return (__db_bmeta(dbp, (BTMETA *)h, flags)); - case P_HASHMETA: - return (__db_hmeta(dbp, (HMETA *)h, flags)); - case P_QAMMETA: - return (__db_qmeta(dbp, (QMETA *)h, flags)); - case P_QAMDATA: /* Should be meta->start. */ - if (!LF_ISSET(DB_PR_PAGE)) - return (0); - - qlen = ((QUEUE *)dbp->q_internal)->re_len; - recno = (h->pgno - 1) * QAM_RECNO_PER_PAGE(dbp) + 1; - i = 0; - qep = (QAMDATA *)((u_int8_t *)h + pagesize - qlen); - for (qp = QAM_GET_RECORD(dbp, h, i); qp < qep; - recno++, i++, qp = QAM_GET_RECORD(dbp, h, i)) { - if (!F_ISSET(qp, QAM_SET)) - continue; - - __db_msgadd(dbenv, &mb, "%s", - F_ISSET(qp, QAM_VALID) ? "\t" : " D"); - __db_msgadd(dbenv, &mb, "[%03lu] %4lu ", (u_long)recno, - (u_long)((u_int8_t *)qp - (u_int8_t *)h)); - __db_pr(dbenv, &mb, qp->data, qlen); - } - return (0); - default: - break; - } - - s = "\t"; - if (TYPE(h) != P_IBTREE && TYPE(h) != P_IRECNO) { - __db_msgadd(dbenv, &mb, "%sprev: %4lu next: %4lu", - s, (u_long)PREV_PGNO(h), (u_long)NEXT_PGNO(h)); - s = " "; - } - if (TYPE(h) == P_OVERFLOW) { - __db_msgadd(dbenv, &mb, - "%sref cnt: %4lu ", s, (u_long)OV_REF(h)); - __db_pr(dbenv, &mb, (u_int8_t *)h + P_OVERHEAD(dbp), OV_LEN(h)); - return (0); - } - __db_msgadd(dbenv, &mb, "%sentries: %4lu", s, (u_long)NUM_ENT(h)); - __db_msgadd(dbenv, &mb, " offset: %4lu", (u_long)HOFFSET(h)); - DB_MSGBUF_FLUSH(dbenv, &mb); - - if (TYPE(h) == P_INVALID || !LF_ISSET(DB_PR_PAGE)) - return (0); - - ret = 0; - inp = P_INP(dbp, h); - for (i = 0; i < NUM_ENT(h); i++) { - if ((uintptr_t)(P_ENTRY(dbp, h, i) - (u_int8_t *)h) < - (uintptr_t)(P_OVERHEAD(dbp)) || - (size_t)(P_ENTRY(dbp, h, i) - (u_int8_t *)h) >= pagesize) { - __db_msg(dbenv, - "ILLEGAL PAGE OFFSET: indx: %lu of %lu", - (u_long)i, (u_long)inp[i]); - ret = EINVAL; - continue; - } - deleted = 0; - switch (TYPE(h)) { - case P_HASH: - case P_IBTREE: - case P_IRECNO: - sp = P_ENTRY(dbp, h, i); - break; - case P_LBTREE: - sp = P_ENTRY(dbp, h, i); - deleted = i % 2 == 0 && - B_DISSET(GET_BKEYDATA(dbp, h, i + O_INDX)->type); - break; - case P_LDUP: - case P_LRECNO: - sp = P_ENTRY(dbp, h, i); - deleted = B_DISSET(GET_BKEYDATA(dbp, h, i)->type); - break; - default: - goto type_err; - } - __db_msgadd(dbenv, &mb, "%s", deleted ? " D" : "\t"); - __db_msgadd( - dbenv, &mb, "[%03lu] %4lu ", (u_long)i, (u_long)inp[i]); - switch (TYPE(h)) { - case P_HASH: - hk = sp; - switch (HPAGE_PTYPE(hk)) { - case H_OFFDUP: - memcpy(&pgno, - HOFFDUP_PGNO(hk), sizeof(db_pgno_t)); - __db_msgadd(dbenv, &mb, - "%4lu [offpage dups]", (u_long)pgno); - DB_MSGBUF_FLUSH(dbenv, &mb); - break; - case H_DUPLICATE: - /* - * If this is the first item on a page, then - * we cannot figure out how long it is, so - * we only print the first one in the duplicate - * set. - */ - if (i != 0) - len = LEN_HKEYDATA(dbp, h, 0, i); - else - len = 1; - - __db_msgadd(dbenv, &mb, "Duplicates:"); - DB_MSGBUF_FLUSH(dbenv, &mb); - for (p = HKEYDATA_DATA(hk), - ep = p + len; p < ep;) { - memcpy(&dlen, p, sizeof(db_indx_t)); - p += sizeof(db_indx_t); - __db_msgadd(dbenv, &mb, "\t\t"); - __db_pr(dbenv, &mb, p, dlen); - p += sizeof(db_indx_t) + dlen; - } - break; - case H_KEYDATA: - __db_pr(dbenv, &mb, HKEYDATA_DATA(hk), - LEN_HKEYDATA(dbp, h, i == 0 ? - pagesize : 0, i)); - break; - case H_OFFPAGE: - memcpy(&a_hkd, hk, HOFFPAGE_SIZE); - __db_msgadd(dbenv, &mb, - "overflow: total len: %4lu page: %4lu", - (u_long)a_hkd.tlen, (u_long)a_hkd.pgno); - DB_MSGBUF_FLUSH(dbenv, &mb); - break; - default: - DB_MSGBUF_FLUSH(dbenv, &mb); - __db_msg(dbenv, "ILLEGAL HASH PAGE TYPE: %lu", - (u_long)HPAGE_PTYPE(hk)); - ret = EINVAL; - break; - } - break; - case P_IBTREE: - bi = sp; - __db_msgadd(dbenv, &mb, - "count: %4lu pgno: %4lu type: %lu ", - (u_long)bi->nrecs, (u_long)bi->pgno, - (u_long)bi->type); - switch (B_TYPE(bi->type)) { - case B_KEYDATA: - __db_pr(dbenv, &mb, bi->data, bi->len); - break; - case B_DUPLICATE: - case B_OVERFLOW: - __db_proff(dbenv, &mb, bi->data); - break; - default: - DB_MSGBUF_FLUSH(dbenv, &mb); - __db_msg(dbenv, "ILLEGAL BINTERNAL TYPE: %lu", - (u_long)B_TYPE(bi->type)); - ret = EINVAL; - break; - } - break; - case P_IRECNO: - ri = sp; - __db_msgadd(dbenv, &mb, "entries %4lu pgno %4lu", - (u_long)ri->nrecs, (u_long)ri->pgno); - DB_MSGBUF_FLUSH(dbenv, &mb); - break; - case P_LBTREE: - case P_LDUP: - case P_LRECNO: - bk = sp; - switch (B_TYPE(bk->type)) { - case B_KEYDATA: - __db_pr(dbenv, &mb, bk->data, bk->len); - break; - case B_DUPLICATE: - case B_OVERFLOW: - __db_proff(dbenv, &mb, bk); - break; - default: - DB_MSGBUF_FLUSH(dbenv, &mb); - __db_msg(dbenv, - "ILLEGAL DUPLICATE/LBTREE/LRECNO TYPE: %lu", - (u_long)B_TYPE(bk->type)); - ret = EINVAL; - break; - } - break; - default: -type_err: DB_MSGBUF_FLUSH(dbenv, &mb); - __db_msg(dbenv, - "ILLEGAL PAGE TYPE: %lu", (u_long)TYPE(h)); - ret = EINVAL; - continue; - } - } - return (ret); -} - -/* - * __db_pr -- - * Print out a data element. - * - * PUBLIC: void __db_pr __P((DB_ENV *, DB_MSGBUF *, u_int8_t *, u_int32_t)); - */ -void -__db_pr(dbenv, mbp, p, len) - DB_ENV *dbenv; - DB_MSGBUF *mbp; - u_int8_t *p; - u_int32_t len; -{ - u_int32_t i; - - __db_msgadd(dbenv, mbp, "len: %3lu", (u_long)len); - if (len != 0) { - __db_msgadd(dbenv, mbp, " data: "); - for (i = len <= 20 ? len : 20; i > 0; --i, ++p) { - if (isprint((int)*p) || *p == '\n') - __db_msgadd(dbenv, mbp, "%c", *p); - else - __db_msgadd(dbenv, mbp, "%#.2x", (u_int)*p); - } - if (len > 20) - __db_msgadd(dbenv, mbp, "..."); - } - DB_MSGBUF_FLUSH(dbenv, mbp); -} - -/* - * __db_proff -- - * Print out an off-page element. - */ -static void -__db_proff(dbenv, mbp, vp) - DB_ENV *dbenv; - DB_MSGBUF *mbp; - void *vp; -{ - BOVERFLOW *bo; - - bo = vp; - switch (B_TYPE(bo->type)) { - case B_OVERFLOW: - __db_msgadd(dbenv, mbp, "overflow: total len: %4lu page: %4lu", - (u_long)bo->tlen, (u_long)bo->pgno); - break; - case B_DUPLICATE: - __db_msgadd( - dbenv, mbp, "duplicate: page: %4lu", (u_long)bo->pgno); - break; - default: - /* NOTREACHED */ - break; - } - DB_MSGBUF_FLUSH(dbenv, mbp); -} - -/* - * __db_prflags -- - * Print out flags values. - * - * PUBLIC: void __db_prflags __P((DB_ENV *, DB_MSGBUF *, - * PUBLIC: u_int32_t, const FN *, const char *, const char *)); - */ -void -__db_prflags(dbenv, mbp, flags, fn, prefix, suffix) - DB_ENV *dbenv; - DB_MSGBUF *mbp; - u_int32_t flags; - FN const *fn; - const char *prefix, *suffix; -{ - DB_MSGBUF mb; - const FN *fnp; - int found, standalone; - const char *sep; - - /* - * If it's a standalone message, output the suffix (which will be the - * label), regardless of whether we found anything or not, and flush - * the line. - */ - if (mbp == NULL) { - standalone = 1; - mbp = &mb; - DB_MSGBUF_INIT(mbp); - } else - standalone = 0; - - sep = prefix == NULL ? "" : prefix; - for (found = 0, fnp = fn; fnp->mask != 0; ++fnp) - if (LF_ISSET(fnp->mask)) { - __db_msgadd(dbenv, mbp, "%s%s", sep, fnp->name); - sep = ", "; - found = 1; - } - - if ((standalone || found) && suffix != NULL) - __db_msgadd(dbenv, mbp, "%s", suffix); - if (standalone) - DB_MSGBUF_FLUSH(dbenv, mbp); -} - -/* - * __db_lockmode_to_string -- - * Return the name of the lock mode. - * - * PUBLIC: const char * __db_lockmode_to_string __P((db_lockmode_t)); - */ -const char * -__db_lockmode_to_string(mode) - db_lockmode_t mode; -{ - switch (mode) { - case DB_LOCK_NG: - return ("Not granted"); - case DB_LOCK_READ: - return ("Shared/read"); - case DB_LOCK_WRITE: - return ("Exclusive/write"); - case DB_LOCK_WAIT: - return ("Wait for event"); - case DB_LOCK_IWRITE: - return ("Intent exclusive/write"); - case DB_LOCK_IREAD: - return ("Intent shared/read"); - case DB_LOCK_IWR: - return ("Intent to read/write"); - case DB_LOCK_READ_UNCOMMITTED: - return ("Read uncommitted"); - case DB_LOCK_WWRITE: - return ("Was written"); - default: - break; - } - return ("UNKNOWN LOCK MODE"); -} - -/* - * __db_pagetype_to_string -- - * Return the name of the specified page type. - */ -static const char * -__db_pagetype_to_string(type) - u_int32_t type; -{ - char *s; - - s = NULL; - switch (type) { - case P_BTREEMETA: - s = "btree metadata"; - break; - case P_LDUP: - s = "duplicate"; - break; - case P_HASH: - s = "hash"; - break; - case P_HASHMETA: - s = "hash metadata"; - break; - case P_IBTREE: - s = "btree internal"; - break; - case P_INVALID: - s = "invalid"; - break; - case P_IRECNO: - s = "recno internal"; - break; - case P_LBTREE: - s = "btree leaf"; - break; - case P_LRECNO: - s = "recno leaf"; - break; - case P_OVERFLOW: - s = "overflow"; - break; - case P_QAMMETA: - s = "queue metadata"; - break; - case P_QAMDATA: - s = "queue"; - break; - default: - /* Just return a NULL. */ - break; - } - return (s); -} - -#else /* !HAVE_STATISTICS */ - -/* - * __db_dumptree -- - * Dump the tree to a file. - * - * PUBLIC: int __db_dumptree __P((DB *, char *, char *)); - */ -int -__db_dumptree(dbp, op, name) - DB *dbp; - char *op, *name; -{ - COMPQUIET(op, NULL); - COMPQUIET(name, NULL); - - return (__db_stat_not_built(dbp->dbenv)); -} - -/* - * __db_get_flags_fn -- - * Return the __db_flags_fn array. - * - * PUBLIC: const FN * __db_get_flags_fn __P((void)); - */ -const FN * -__db_get_flags_fn() -{ - static const FN __db_flags_fn[] = { - { 0, NULL } - }; - - /* - * !!! - * The Tcl API uses this interface, stub it off. - */ - return (__db_flags_fn); -} -#endif - -/* - * __db_dump_pp -- - * DB->dump pre/post processing. - * - * PUBLIC: int __db_dump_pp __P((DB *, const char *, - * PUBLIC: int (*)(void *, const void *), void *, int, int)); - */ -int -__db_dump_pp(dbp, subname, callback, handle, pflag, keyflag) - DB *dbp; - const char *subname; - int (*callback) __P((void *, const void *)); - void *handle; - int pflag, keyflag; -{ - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int handle_check, ret, t_ret; - - dbenv = dbp->dbenv; - - PANIC_CHECK(dbenv); - DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->dump"); - - ENV_ENTER(dbenv, ip); - - /* Check for replication block. */ - handle_check = IS_ENV_REPLICATED(dbenv); - if (handle_check && (ret = __db_rep_enter(dbp, 1, 0, 1)) != 0) { - handle_check = 0; - goto err; - } - - ret = __db_dump(dbp, subname, callback, handle, pflag, keyflag); - - /* Release replication block. */ - if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - -err: ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __db_dump -- - * DB->dump. - * - * PUBLIC: int __db_dump __P((DB *, const char *, - * PUBLIC: int (*)(void *, const void *), void *, int, int)); - */ -int -__db_dump(dbp, subname, callback, handle, pflag, keyflag) - DB *dbp; - const char *subname; - int (*callback) __P((void *, const void *)); - void *handle; - int pflag, keyflag; -{ - DB_ENV *dbenv; - DBC *dbcp; - DBT key, data; - DBT keyret, dataret; - db_recno_t recno; - int is_recno, ret, t_ret; - void *pointer; - - dbenv = dbp->dbenv; - - if ((ret = __db_prheader( - dbp, subname, pflag, keyflag, handle, callback, NULL, 0)) != 0) - return (ret); - - /* - * Get a cursor and step through the database, printing out each - * key/data pair. - */ - if ((ret = __db_cursor(dbp, NULL, &dbcp, 0)) != 0) - return (ret); - - memset(&key, 0, sizeof(key)); - memset(&data, 0, sizeof(data)); - if ((ret = __os_malloc(dbenv, 1024 * 1024, &data.data)) != 0) - goto err; - data.ulen = 1024 * 1024; - data.flags = DB_DBT_USERMEM; - is_recno = (dbp->type == DB_RECNO || dbp->type == DB_QUEUE); - keyflag = is_recno ? keyflag : 1; - if (is_recno) { - keyret.data = &recno; - keyret.size = sizeof(recno); - } - -retry: while ((ret = - __db_c_get(dbcp, &key, &data, DB_NEXT | DB_MULTIPLE_KEY)) == 0) { - DB_MULTIPLE_INIT(pointer, &data); - for (;;) { - if (is_recno) - DB_MULTIPLE_RECNO_NEXT(pointer, &data, - recno, dataret.data, dataret.size); - else - DB_MULTIPLE_KEY_NEXT(pointer, - &data, keyret.data, - keyret.size, dataret.data, dataret.size); - - if (dataret.data == NULL) - break; - - if ((keyflag && - (ret = __db_prdbt(&keyret, pflag, " ", - handle, callback, is_recno)) != 0) || - (ret = __db_prdbt(&dataret, pflag, " ", - handle, callback, 0)) != 0) - goto err; - } - } - if (ret == DB_BUFFER_SMALL) { - data.size = (u_int32_t)DB_ALIGN(data.size, 1024); - if ((ret = __os_realloc(dbenv, data.size, &data.data)) != 0) - goto err; - data.ulen = data.size; - goto retry; - } - if (ret == DB_NOTFOUND) - ret = 0; - - if ((t_ret = __db_prfooter(handle, callback)) != 0 && ret == 0) - ret = t_ret; - -err: if ((t_ret = __db_c_close(dbcp)) != 0 && ret == 0) - ret = t_ret; - if (data.data != NULL) - __os_free(dbenv, data.data); - - return (ret); -} - -/* - * __db_prdbt -- - * Print out a DBT data element. - * - * PUBLIC: int __db_prdbt __P((DBT *, int, const char *, void *, - * PUBLIC: int (*)(void *, const void *), int)); - */ -int -__db_prdbt(dbtp, checkprint, prefix, handle, callback, is_recno) - DBT *dbtp; - int checkprint; - const char *prefix; - void *handle; - int (*callback) __P((void *, const void *)); - int is_recno; -{ - static const u_char hex[] = "0123456789abcdef"; - db_recno_t recno; - size_t len; - int ret; -#define DBTBUFLEN 100 - u_int8_t *p, *hp; - char buf[DBTBUFLEN], hbuf[DBTBUFLEN]; - - /* - * !!! - * This routine is the routine that dumps out items in the format - * used by db_dump(1) and db_load(1). This means that the format - * cannot change. - */ - if (prefix != NULL && (ret = callback(handle, prefix)) != 0) - return (ret); - if (is_recno) { - /* - * We're printing a record number, and this has to be done - * in a platform-independent way. So we use the numeral in - * straight ASCII. - */ - (void)__ua_memcpy(&recno, dbtp->data, sizeof(recno)); - snprintf(buf, DBTBUFLEN, "%lu", (u_long)recno); - - /* If we're printing data as hex, print keys as hex too. */ - if (!checkprint) { - for (len = strlen(buf), p = (u_int8_t *)buf, - hp = (u_int8_t *)hbuf; len-- > 0; ++p) { - *hp++ = hex[(u_int8_t)(*p & 0xf0) >> 4]; - *hp++ = hex[*p & 0x0f]; - } - *hp = '\0'; - ret = callback(handle, hbuf); - } else - ret = callback(handle, buf); - - if (ret != 0) - return (ret); - } else if (checkprint) { - for (len = dbtp->size, p = dbtp->data; len--; ++p) - if (isprint((int)*p)) { - if (*p == '\\' && - (ret = callback(handle, "\\")) != 0) - return (ret); - snprintf(buf, DBTBUFLEN, "%c", *p); - if ((ret = callback(handle, buf)) != 0) - return (ret); - } else { - snprintf(buf, DBTBUFLEN, "\\%c%c", - hex[(u_int8_t)(*p & 0xf0) >> 4], - hex[*p & 0x0f]); - if ((ret = callback(handle, buf)) != 0) - return (ret); - } - } else - for (len = dbtp->size, p = dbtp->data; len--; ++p) { - snprintf(buf, DBTBUFLEN, "%c%c", - hex[(u_int8_t)(*p & 0xf0) >> 4], - hex[*p & 0x0f]); - if ((ret = callback(handle, buf)) != 0) - return (ret); - } - - return (callback(handle, "\n")); -} - -/* - * __db_prheader -- - * Write out header information in the format expected by db_load. - * - * PUBLIC: int __db_prheader __P((DB *, const char *, int, int, void *, - * PUBLIC: int (*)(void *, const void *), VRFY_DBINFO *, db_pgno_t)); - */ -int -__db_prheader(dbp, subname, pflag, keyflag, handle, callback, vdp, meta_pgno) - DB *dbp; - const char *subname; - int pflag, keyflag; - void *handle; - int (*callback) __P((void *, const void *)); - VRFY_DBINFO *vdp; - db_pgno_t meta_pgno; -{ - DBT dbt; - DB_ENV *dbenv; - DBTYPE dbtype; - VRFY_PAGEINFO *pip; - u_int32_t flags, tmp_u_int32; - size_t buflen; - char *buf; - int using_vdp, ret, t_ret, tmp_int; - - ret = 0; - buf = NULL; - COMPQUIET(buflen, 0); - - /* - * If dbp is NULL, then pip is guaranteed to be non-NULL; we only ever - * call __db_prheader with a NULL dbp from one case inside __db_prdbt, - * and this is a special subdatabase for "lost" items. In this case - * we have a vdp (from which we'll get a pip). In all other cases, we - * will have a non-NULL dbp (and vdp may or may not be NULL depending - * on whether we're salvaging). - */ - DB_ASSERT(dbp != NULL || vdp != NULL); - - if (dbp == NULL) - dbenv = NULL; - else - dbenv = dbp->dbenv; - - /* - * If we've been passed a verifier statistics object, use that; we're - * being called in a context where dbp->stat is unsafe. - * - * Also, the verifier may set the pflag on a per-salvage basis. If so, - * respect that. - */ - if (vdp != NULL) { - if ((ret = __db_vrfy_getpageinfo(vdp, meta_pgno, &pip)) != 0) - return (ret); - - if (F_ISSET(vdp, SALVAGE_PRINTABLE)) - pflag = 1; - using_vdp = 1; - } else { - pip = NULL; - using_vdp = 0; - } - - /* - * If dbp is NULL, make it a btree. Otherwise, set dbtype to whatever - * appropriate type for the specified meta page, or the type of the dbp. - */ - if (dbp == NULL) - dbtype = DB_BTREE; - else if (using_vdp) - switch (pip->type) { - case P_BTREEMETA: - if (F_ISSET(pip, VRFY_IS_RECNO)) - dbtype = DB_RECNO; - else - dbtype = DB_BTREE; - break; - case P_HASHMETA: - dbtype = DB_HASH; - break; - case P_QAMMETA: - dbtype = DB_QUEUE; - break; - default: - /* - * If the meta page is of a bogus type, it's because - * we have a badly corrupt database. (We must be in - * the verifier for pip to be non-NULL.) Pretend we're - * a Btree and salvage what we can. - */ - DB_ASSERT(F_ISSET(dbp, DB_AM_VERIFYING)); - dbtype = DB_BTREE; - break; - } - else - dbtype = dbp->type; - - if ((ret = callback(handle, "VERSION=3\n")) != 0) - goto err; - if (pflag) { - if ((ret = callback(handle, "format=print\n")) != 0) - goto err; - } else if ((ret = callback(handle, "format=bytevalue\n")) != 0) - goto err; - - /* - * 64 bytes is long enough, as a minimum bound, for any of the - * fields besides subname. Subname uses __db_prdbt and therefore - * does not need buffer space here. - */ - buflen = 64; - if ((ret = __os_malloc(dbenv, buflen, &buf)) != 0) - goto err; - if (subname != NULL) { - snprintf(buf, buflen, "database="); - if ((ret = callback(handle, buf)) != 0) - goto err; - memset(&dbt, 0, sizeof(dbt)); - dbt.data = (char *)subname; - dbt.size = (u_int32_t)strlen(subname); - if ((ret = __db_prdbt(&dbt, 1, NULL, handle, callback, 0)) != 0) - goto err; - } - switch (dbtype) { - case DB_BTREE: - if ((ret = callback(handle, "type=btree\n")) != 0) - goto err; - if (using_vdp) - tmp_int = F_ISSET(pip, VRFY_HAS_RECNUMS) ? 1 : 0; - else { - if ((ret = __db_get_flags(dbp, &flags)) != 0) { - __db_err(dbenv, - "DB->get_flags: %s", db_strerror(ret)); - goto err; - } - tmp_int = F_ISSET(dbp, DB_AM_RECNUM) ? 1 : 0; - } - if (tmp_int && (ret = callback(handle, "recnum=1\n")) != 0) - goto err; - - if (using_vdp) - tmp_u_int32 = pip->bt_minkey; - else - if ((ret = - __bam_get_bt_minkey(dbp, &tmp_u_int32)) != 0) { - __db_err(dbenv, - "DB->get_bt_minkey: %s", db_strerror(ret)); - goto err; - } - if (tmp_u_int32 != 0 && tmp_u_int32 != DEFMINKEYPAGE) { - snprintf(buf, buflen, - "bt_minkey=%lu\n", (u_long)tmp_u_int32); - if ((ret = callback(handle, buf)) != 0) - goto err; - } - break; - case DB_HASH: -#ifdef HAVE_HASH - if ((ret = callback(handle, "type=hash\n")) != 0) - goto err; - if (using_vdp) - tmp_u_int32 = pip->h_ffactor; - else - if ((ret = - __ham_get_h_ffactor(dbp, &tmp_u_int32)) != 0) { - __db_err(dbenv, - "DB->get_h_ffactor: %s", db_strerror(ret)); - goto err; - } - if (tmp_u_int32 != 0) { - snprintf(buf, buflen, - "h_ffactor=%lu\n", (u_long)tmp_u_int32); - if ((ret = callback(handle, buf)) != 0) - goto err; - } - - if (using_vdp) - tmp_u_int32 = pip->h_nelem; - else - if ((ret = __ham_get_h_nelem(dbp, &tmp_u_int32)) != 0) { - __db_err(dbenv, - "DB->get_h_nelem: %s", db_strerror(ret)); - goto err; - } - /* - * Hash databases have an h_nelem field of 0 or 1, neither - * of those values is interesting. - */ - if (tmp_u_int32 > 1) { - snprintf(buf, buflen, - "h_nelem=%lu\n", (u_long)tmp_u_int32); - if ((ret = callback(handle, buf)) != 0) - goto err; - } - break; -#else - ret = __db_no_hash_am(dbenv); - goto err; -#endif - case DB_QUEUE: -#ifdef HAVE_QUEUE - if ((ret = callback(handle, "type=queue\n")) != 0) - goto err; - if (using_vdp) - tmp_u_int32 = vdp->re_len; - else - if ((ret = __ram_get_re_len(dbp, &tmp_u_int32)) != 0) { - __db_err(dbenv, - "DB->get_re_len: %s", db_strerror(ret)); - goto err; - } - snprintf(buf, buflen, "re_len=%lu\n", (u_long)tmp_u_int32); - if ((ret = callback(handle, buf)) != 0) - goto err; - - if (using_vdp) - tmp_int = (int)vdp->re_pad; - else - if ((ret = __ram_get_re_pad(dbp, &tmp_int)) != 0) { - __db_err(dbenv, - "DB->get_re_pad: %s", db_strerror(ret)); - goto err; - } - if (tmp_int != 0 && tmp_int != ' ') { - snprintf(buf, buflen, "re_pad=%#x\n", tmp_int); - if ((ret = callback(handle, buf)) != 0) - goto err; - } - - if (using_vdp) - tmp_u_int32 = vdp->page_ext; - else - if ((ret = - __qam_get_extentsize(dbp, &tmp_u_int32)) != 0) { - __db_err(dbenv, "DB->get_q_extentsize: %s", - db_strerror(ret)); - goto err; - } - if (tmp_u_int32 != 0) { - snprintf(buf, buflen, - "extentsize=%lu\n", (u_long)tmp_u_int32); - if ((ret = callback(handle, buf)) != 0) - goto err; - } - break; -#else - ret = __db_no_queue_am(dbenv); - goto err; -#endif - case DB_RECNO: - if ((ret = callback(handle, "type=recno\n")) != 0) - goto err; - if (using_vdp) - tmp_int = F_ISSET(pip, VRFY_IS_RRECNO) ? 1 : 0; - else - tmp_int = F_ISSET(dbp, DB_AM_RENUMBER) ? 1 : 0; - if (tmp_int != 0 && - (ret = callback(handle, "renumber=1\n")) != 0) - goto err; - - if (using_vdp) - tmp_int = F_ISSET(pip, VRFY_IS_FIXEDLEN) ? 1 : 0; - else - tmp_int = F_ISSET(dbp, DB_AM_FIXEDLEN) ? 1 : 0; - if (tmp_int) { - if (using_vdp) - tmp_u_int32 = pip->re_len; - else - if ((ret = - __ram_get_re_len(dbp, &tmp_u_int32)) != 0) { - __db_err(dbenv, "DB->get_re_len: %s", - db_strerror(ret)); - goto err; - } - snprintf(buf, buflen, - "re_len=%lu\n", (u_long)tmp_u_int32); - if ((ret = callback(handle, buf)) != 0) - goto err; - - if (using_vdp) - tmp_int = (int)pip->re_pad; - else - if ((ret = - __ram_get_re_pad(dbp, &tmp_int)) != 0) { - __db_err(dbenv, "DB->get_re_pad: %s", - db_strerror(ret)); - goto err; - } - if (tmp_int != 0 && tmp_int != ' ') { - snprintf(buf, - buflen, "re_pad=%#x\n", (u_int)tmp_int); - if ((ret = callback(handle, buf)) != 0) - goto err; - } - } - break; - case DB_UNKNOWN: - DB_ASSERT(0); /* Impossible. */ - __db_err(dbenv, - "Unknown or unsupported DB type in __db_prheader"); - ret = EINVAL; - goto err; - } - - if (using_vdp) { - if (F_ISSET(pip, VRFY_HAS_CHKSUM)) - if ((ret = callback(handle, "chksum=1\n")) != 0) - goto err; - if (F_ISSET(pip, VRFY_HAS_DUPS)) - if ((ret = callback(handle, "duplicates=1\n")) != 0) - goto err; - if (F_ISSET(pip, VRFY_HAS_DUPSORT)) - if ((ret = callback(handle, "dupsort=1\n")) != 0) - goto err; - /* - * !!! - * We don't know if the page size was the default if we're - * salvaging. It doesn't seem that interesting to have, so - * we ignore it for now. - */ - } else { - if (F_ISSET(dbp, DB_AM_CHKSUM)) - if ((ret = callback(handle, "chksum=1\n")) != 0) - goto err; - if (F_ISSET(dbp, DB_AM_DUP)) - if ((ret = callback(handle, "duplicates=1\n")) != 0) - goto err; - if (F_ISSET(dbp, DB_AM_DUPSORT)) - if ((ret = callback(handle, "dupsort=1\n")) != 0) - goto err; - if (!F_ISSET(dbp, DB_AM_PGDEF)) { - snprintf(buf, buflen, - "db_pagesize=%lu\n", (u_long)dbp->pgsize); - if ((ret = callback(handle, buf)) != 0) - goto err; - } - } - - if (keyflag && (ret = callback(handle, "keys=1\n")) != 0) - goto err; - - ret = callback(handle, "HEADER=END\n"); - -err: if (using_vdp && - (t_ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0 && ret == 0) - ret = t_ret; - if (buf != NULL) - __os_free(dbenv, buf); - - return (ret); -} - -/* - * __db_prfooter -- - * Print the footer that marks the end of a DB dump. This is trivial, - * but for consistency's sake we don't want to put its literal contents - * in multiple places. - * - * PUBLIC: int __db_prfooter __P((void *, int (*)(void *, const void *))); - */ -int -__db_prfooter(handle, callback) - void *handle; - int (*callback) __P((void *, const void *)); -{ - return (callback(handle, "DATA=END\n")); -} - -/* - * __db_pr_callback -- - * Callback function for using pr_* functions from C. - * - * PUBLIC: int __db_pr_callback __P((void *, const void *)); - */ -int -__db_pr_callback(handle, str_arg) - void *handle; - const void *str_arg; -{ - char *str; - FILE *f; - - str = (char *)str_arg; - f = (FILE *)handle; - - if (fprintf(f, "%s", str) != (int)strlen(str)) - return (EIO); - - return (0); -} - -/* - * __db_dbtype_to_string -- - * Return the name of the database type. - * - * PUBLIC: const char * __db_dbtype_to_string __P((DBTYPE)); - */ -const char * -__db_dbtype_to_string(type) - DBTYPE type; -{ - switch (type) { - case DB_BTREE: - return ("btree"); - case DB_HASH: - return ("hash"); - case DB_RECNO: - return ("recno"); - case DB_QUEUE: - return ("queue"); - case DB_UNKNOWN: - default: - break; - } - return ("UNKNOWN TYPE"); -} diff --git a/storage/bdb/db/db_rec.c b/storage/bdb/db/db_rec.c deleted file mode 100644 index e0c13f255c1..00000000000 --- a/storage/bdb/db/db_rec.c +++ /dev/null @@ -1,1266 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_rec.c,v 12.12 2005/10/27 01:03:01 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" -#include "dbinc/hash.h" - -static int __db_pg_free_recover_int __P((DB_ENV *, - __db_pg_freedata_args *, DB *, DB_LSN *, DB_MPOOLFILE *, db_recops, int)); - -/* - * PUBLIC: int __db_addrem_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - * - * This log message is generated whenever we add or remove a duplicate - * to/from a duplicate page. On recover, we just do the opposite. - */ -int -__db_addrem_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __db_addrem_args *argp; - DB *file_dbp; - DBC *dbc; - DB_MPOOLFILE *mpf; - PAGE *pagep; - u_int32_t change; - int cmp_n, cmp_p, ret; - - pagep = NULL; - COMPQUIET(info, NULL); - REC_PRINT(__db_addrem_print); - REC_INTRO(__db_addrem_read, 1, 1); - - REC_FGET(mpf, argp->pgno, &pagep, done); - - cmp_n = log_compare(lsnp, &LSN(pagep)); - cmp_p = log_compare(&LSN(pagep), &argp->pagelsn); - CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->pagelsn); - change = 0; - if ((cmp_p == 0 && DB_REDO(op) && argp->opcode == DB_ADD_DUP) || - (cmp_n == 0 && DB_UNDO(op) && argp->opcode == DB_REM_DUP)) { - - /* Need to redo an add, or undo a delete. */ - if ((ret = __db_pitem(dbc, pagep, argp->indx, argp->nbytes, - argp->hdr.size == 0 ? NULL : &argp->hdr, - argp->dbt.size == 0 ? NULL : &argp->dbt)) != 0) - goto out; - - change = DB_MPOOL_DIRTY; - - } else if ((cmp_n == 0 && DB_UNDO(op) && argp->opcode == DB_ADD_DUP) || - (cmp_p == 0 && DB_REDO(op) && argp->opcode == DB_REM_DUP)) { - /* Need to undo an add, or redo a delete. */ - if ((ret = __db_ditem(dbc, - pagep, argp->indx, argp->nbytes)) != 0) - goto out; - change = DB_MPOOL_DIRTY; - } - - if (change) { - if (DB_REDO(op)) - LSN(pagep) = *lsnp; - else - LSN(pagep) = argp->pagelsn; - } - - if ((ret = __memp_fput(mpf, pagep, change)) != 0) - goto out; - pagep = NULL; - -done: *lsnp = argp->prev_lsn; - ret = 0; - -out: if (pagep != NULL) - (void)__memp_fput(mpf, pagep, 0); - REC_CLOSE; -} - -/* - * PUBLIC: int __db_big_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__db_big_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __db_big_args *argp; - DB *file_dbp; - DBC *dbc; - DB_MPOOLFILE *mpf; - PAGE *pagep; - u_int32_t change; - int cmp_n, cmp_p, ret; - - pagep = NULL; - COMPQUIET(info, NULL); - REC_PRINT(__db_big_print); - REC_INTRO(__db_big_read, 1, 0); - - REC_FGET(mpf, argp->pgno, &pagep, ppage); - - /* - * There are three pages we need to check. The one on which we are - * adding data, the previous one whose next_pointer may have - * been updated, and the next one whose prev_pointer may have - * been updated. - */ - cmp_n = log_compare(lsnp, &LSN(pagep)); - cmp_p = log_compare(&LSN(pagep), &argp->pagelsn); - CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->pagelsn); - change = 0; - if ((cmp_p == 0 && DB_REDO(op) && argp->opcode == DB_ADD_BIG) || - (cmp_n == 0 && DB_UNDO(op) && argp->opcode == DB_REM_BIG)) { - /* We are either redo-ing an add, or undoing a delete. */ - P_INIT(pagep, file_dbp->pgsize, argp->pgno, argp->prev_pgno, - argp->next_pgno, 0, P_OVERFLOW); - OV_LEN(pagep) = argp->dbt.size; - OV_REF(pagep) = 1; - memcpy((u_int8_t *)pagep + P_OVERHEAD(file_dbp), argp->dbt.data, - argp->dbt.size); - PREV_PGNO(pagep) = argp->prev_pgno; - change = DB_MPOOL_DIRTY; - } else if ((cmp_n == 0 && DB_UNDO(op) && argp->opcode == DB_ADD_BIG) || - (cmp_p == 0 && DB_REDO(op) && argp->opcode == DB_REM_BIG)) { - /* - * We are either undo-ing an add or redo-ing a delete. - * The page is about to be reclaimed in either case, so - * there really isn't anything to do here. - */ - change = DB_MPOOL_DIRTY; - } - if (change) - LSN(pagep) = DB_REDO(op) ? *lsnp : argp->pagelsn; - - if ((ret = __memp_fput(mpf, pagep, change)) != 0) - goto out; - pagep = NULL; - - /* - * We only delete a whole chain of overflow. - * Each page is handled individually - */ - if (argp->opcode == DB_REM_BIG) - goto done; - - /* Now check the previous page. */ -ppage: if (argp->prev_pgno != PGNO_INVALID) { - change = 0; - REC_FGET(mpf, argp->prev_pgno, &pagep, npage); - - cmp_n = log_compare(lsnp, &LSN(pagep)); - cmp_p = log_compare(&LSN(pagep), &argp->prevlsn); - CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->prevlsn); - - if (cmp_p == 0 && DB_REDO(op) && argp->opcode == DB_ADD_BIG) { - /* Redo add, undo delete. */ - NEXT_PGNO(pagep) = argp->pgno; - change = DB_MPOOL_DIRTY; - } else if (cmp_n == 0 && - DB_UNDO(op) && argp->opcode == DB_ADD_BIG) { - /* Redo delete, undo add. */ - NEXT_PGNO(pagep) = argp->next_pgno; - change = DB_MPOOL_DIRTY; - } - if (change) - LSN(pagep) = DB_REDO(op) ? *lsnp : argp->prevlsn; - if ((ret = __memp_fput(mpf, pagep, change)) != 0) - goto out; - } - pagep = NULL; - - /* Now check the next page. Can only be set on a delete. */ -npage: if (argp->next_pgno != PGNO_INVALID) { - change = 0; - REC_FGET(mpf, argp->next_pgno, &pagep, done); - - cmp_n = log_compare(lsnp, &LSN(pagep)); - cmp_p = log_compare(&LSN(pagep), &argp->nextlsn); - CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->nextlsn); - if (cmp_p == 0 && DB_REDO(op)) { - PREV_PGNO(pagep) = PGNO_INVALID; - change = DB_MPOOL_DIRTY; - } else if (cmp_n == 0 && DB_UNDO(op)) { - PREV_PGNO(pagep) = argp->pgno; - change = DB_MPOOL_DIRTY; - } - if (change) - LSN(pagep) = DB_REDO(op) ? *lsnp : argp->nextlsn; - if ((ret = __memp_fput(mpf, pagep, change)) != 0) - goto out; - } - pagep = NULL; - -done: *lsnp = argp->prev_lsn; - ret = 0; - -out: if (pagep != NULL) - (void)__memp_fput(mpf, pagep, 0); - REC_CLOSE; -} - -/* - * __db_ovref_recover -- - * Recovery function for __db_ovref(). - * - * PUBLIC: int __db_ovref_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__db_ovref_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __db_ovref_args *argp; - DB *file_dbp; - DBC *dbc; - DB_MPOOLFILE *mpf; - PAGE *pagep; - int cmp, modified, ret; - - pagep = NULL; - COMPQUIET(info, NULL); - REC_PRINT(__db_ovref_print); - REC_INTRO(__db_ovref_read, 1, 0); - - REC_FGET(mpf, argp->pgno, &pagep, done); - - modified = 0; - cmp = log_compare(&LSN(pagep), &argp->lsn); - CHECK_LSN(dbenv, op, cmp, &LSN(pagep), &argp->lsn); - if (cmp == 0 && DB_REDO(op)) { - /* Need to redo update described. */ - OV_REF(pagep) += argp->adjust; - - pagep->lsn = *lsnp; - modified = 1; - } else if (log_compare(lsnp, &LSN(pagep)) == 0 && DB_UNDO(op)) { - /* Need to undo update described. */ - OV_REF(pagep) -= argp->adjust; - - pagep->lsn = argp->lsn; - modified = 1; - } - if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0) - goto out; - pagep = NULL; - -done: *lsnp = argp->prev_lsn; - ret = 0; - -out: if (pagep != NULL) - (void)__memp_fput(mpf, pagep, 0); - REC_CLOSE; -} - -/* - * __db_debug_recover -- - * Recovery function for debug. - * - * PUBLIC: int __db_debug_recover __P((DB_ENV *, - * PUBLIC: DBT *, DB_LSN *, db_recops, void *)); - */ -int -__db_debug_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __db_debug_args *argp; - int ret; - - COMPQUIET(dbenv, NULL); - COMPQUIET(op, DB_TXN_ABORT); - COMPQUIET(info, NULL); - - REC_PRINT(__db_debug_print); - REC_NOOP_INTRO(__db_debug_read); - - *lsnp = argp->prev_lsn; - ret = 0; - - REC_NOOP_CLOSE; -} - -/* - * __db_noop_recover -- - * Recovery function for noop. - * - * PUBLIC: int __db_noop_recover __P((DB_ENV *, - * PUBLIC: DBT *, DB_LSN *, db_recops, void *)); - */ -int -__db_noop_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __db_noop_args *argp; - DB *file_dbp; - DBC *dbc; - DB_MPOOLFILE *mpf; - PAGE *pagep; - u_int32_t change; - int cmp_n, cmp_p, ret; - - pagep = NULL; - COMPQUIET(info, NULL); - REC_PRINT(__db_noop_print); - REC_INTRO(__db_noop_read, 0, 0); - - REC_FGET(mpf, argp->pgno, &pagep, done); - - cmp_n = log_compare(lsnp, &LSN(pagep)); - cmp_p = log_compare(&LSN(pagep), &argp->prevlsn); - CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->prevlsn); - change = 0; - if (cmp_p == 0 && DB_REDO(op)) { - LSN(pagep) = *lsnp; - change = DB_MPOOL_DIRTY; - } else if (cmp_n == 0 && DB_UNDO(op)) { - LSN(pagep) = argp->prevlsn; - change = DB_MPOOL_DIRTY; - } - ret = __memp_fput(mpf, pagep, change); - pagep = NULL; - -done: *lsnp = argp->prev_lsn; -out: if (pagep != NULL) - (void)__memp_fput(mpf, pagep, 0); - REC_CLOSE; -} - -/* - * __db_pg_alloc_recover -- - * Recovery function for pg_alloc. - * - * PUBLIC: int __db_pg_alloc_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__db_pg_alloc_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __db_pg_alloc_args *argp; - DB *file_dbp; - DBC *dbc; - DBMETA *meta; - DB_MPOOLFILE *mpf; - PAGE *pagep; - db_pgno_t pgno; - int cmp_n, cmp_p, created, level, meta_modified, modified, ret; - - meta = NULL; - pagep = NULL; - created = meta_modified = modified = 0; - REC_PRINT(__db_pg_alloc_print); - REC_INTRO(__db_pg_alloc_read, 0, 0); - - /* - * Fix up the metadata page. If we're redoing the operation, we have - * to get the metadata page and update its LSN and its free pointer. - * If we're undoing the operation and the page was ever created, we put - * it on the freelist. - */ - pgno = PGNO_BASE_MD; - if ((ret = __memp_fget(mpf, &pgno, 0, &meta)) != 0) { - /* The metadata page must always exist on redo. */ - if (DB_REDO(op)) { - ret = __db_pgerr(file_dbp, pgno, ret); - goto out; - } else - goto done; - } - cmp_n = log_compare(lsnp, &LSN(meta)); - cmp_p = log_compare(&LSN(meta), &argp->meta_lsn); - CHECK_LSN(dbenv, op, cmp_p, &LSN(meta), &argp->meta_lsn); - if (cmp_p == 0 && DB_REDO(op)) { - /* Need to redo update described. */ - LSN(meta) = *lsnp; - meta->free = argp->next; - meta_modified = 1; - if (argp->pgno > meta->last_pgno) - meta->last_pgno = argp->pgno; - } else if (cmp_n == 0 && DB_UNDO(op)) { - /* Need to undo update described. */ - LSN(meta) = argp->meta_lsn; - /* - * If the page has a zero LSN then its newly created - * and will be truncated or go into limbo rather than - * directly on the free list. - */ - if (!IS_ZERO_LSN(argp->page_lsn)) - meta->free = argp->pgno; -#ifdef HAVE_FTRUNCATE - /* - * With truncate we will restore the file to - * its original length. Without truncate - * the last_pgno never goes backward. - */ - meta->last_pgno = argp->last_pgno; -#endif - meta_modified = 1; - } - -#ifdef HAVE_FTRUNCATE - /* - * Check to see if we are keeping a sorted - * freelist, if so put this back in the in - * memory list. It must be the first element. - */ - if (op == DB_TXN_ABORT && !IS_ZERO_LSN(argp->page_lsn)) { - db_pgno_t *list; - u_int32_t nelem; - - if ((ret = __memp_get_freelist(mpf, &nelem, &list)) != 0) - goto out; - if (list != NULL) { - if ((ret = - __memp_extend_freelist(mpf, nelem + 1, &list)) != 0) - goto out; - if (nelem != 0) - memmove(list + 1, list, nelem * sizeof(list)); - *list = argp->pgno; - } - } -#endif - - /* - * Fix up the allocated page. If the page does not exist - * and we can truncate it then don't create it. - * Otherwise if we're redoing the operation, we have - * to get the page (creating it if it doesn't exist), and update its - * LSN. If we're undoing the operation, we have to reset the page's - * LSN and put it on the free list, or into limbo.. - */ - if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) { - /* - * We have to be able to identify if a page was newly - * created so we can recover it properly. We cannot simply - * look for an empty header, because hash uses a pgin - * function that will set the header. Instead, we explicitly - * try for the page without CREATE and if that fails, then - * create it. - */ -#ifdef HAVE_FTRUNCATE - if (DB_UNDO(op)) - goto do_truncate; -#endif - if ((ret = __memp_fget( - mpf, &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) { - if (DB_UNDO(op) && ret == ENOSPC) - goto do_truncate; - ret = __db_pgerr(file_dbp, argp->pgno, ret); - goto out; - } - created = modified = 1; - } - - /* Fix up the allocated page. */ - cmp_n = log_compare(lsnp, &LSN(pagep)); - cmp_p = log_compare(&LSN(pagep), &argp->page_lsn); - - /* - * If an initial allocation is aborted and then reallocated during - * an archival restore the log record will have an LSN for the page - * but the page will be empty. - * If we we rolled back this allocation previously during an - * archive restore, the page may have INIT_LSN from the limbo list. - */ - if (IS_ZERO_LSN(LSN(pagep)) || - (IS_ZERO_LSN(argp->page_lsn) && IS_INIT_LSN(LSN(pagep)))) - cmp_p = 0; - - CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->page_lsn); - /* - * Another special case we have to handle is if we ended up with a - * page of all 0's which can happen if we abort between allocating a - * page in mpool and initializing it. In that case, even if we're - * undoing, we need to re-initialize the page. - */ - if (DB_REDO(op) && cmp_p == 0) { - /* Need to redo update described. */ - switch (argp->ptype) { - case P_LBTREE: - case P_LRECNO: - case P_LDUP: - level = LEAFLEVEL; - break; - default: - level = 0; - break; - } - P_INIT(pagep, file_dbp->pgsize, - argp->pgno, PGNO_INVALID, PGNO_INVALID, level, argp->ptype); - - pagep->lsn = *lsnp; - modified = 1; - } else if (DB_UNDO(op) && (cmp_n == 0 || created)) { - /* - * This is where we handle the case of a 0'd page (pagep->pgno - * is equal to PGNO_INVALID). - * Undo the allocation, reinitialize the page and - * link its next pointer to the free list. - */ - P_INIT(pagep, file_dbp->pgsize, - argp->pgno, PGNO_INVALID, argp->next, 0, P_INVALID); - - pagep->lsn = argp->page_lsn; - modified = 1; - } - -do_truncate: - /* - * If the page was newly created, give it back, if - * possible. Otherwise put it into limbo. - */ - if ((pagep == NULL || IS_ZERO_LSN(LSN(pagep))) && - IS_ZERO_LSN(argp->page_lsn) && DB_UNDO(op)) { -#ifdef HAVE_FTRUNCATE - COMPQUIET(info, NULL); - /* Discard the page. */ - if (pagep != NULL) { - if ((ret = - __memp_fput(mpf, pagep, DB_MPOOL_DISCARD)) != 0) - goto out; - pagep = NULL; - /* Give the page back to the OS. */ - if (meta->last_pgno <= argp->pgno && - (ret = __memp_ftruncate(mpf, argp->pgno, 0)) != 0) - goto out; - } -#else - /* Put the page in limbo.*/ - if ((ret = __db_add_limbo(dbenv, - info, argp->fileid, argp->pgno, 1)) != 0) - goto out; - /* The last_pgno grows if this was a new page. */ - if (argp->pgno > meta->last_pgno) { - meta->last_pgno = argp->pgno; - meta_modified = 1; - } -#endif - } - - if (pagep != NULL && - (ret = __memp_fput(mpf, - pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0) - goto out; - pagep = NULL; - - if ((ret = __memp_fput(mpf, - meta, meta_modified ? DB_MPOOL_DIRTY : 0)) != 0) - goto out; - meta = NULL; - -done: *lsnp = argp->prev_lsn; - ret = 0; - -out: if (pagep != NULL) - (void)__memp_fput(mpf, pagep, 0); - if (meta != NULL) - (void)__memp_fput(mpf, meta, 0); - if (ret == ENOENT && op == DB_TXN_BACKWARD_ALLOC) - ret = 0; - REC_CLOSE; -} - -/* - * __db_pg_free_recover_int -- - */ -static int -__db_pg_free_recover_int(dbenv, argp, file_dbp, lsnp, mpf, op, data) - DB_ENV *dbenv; - __db_pg_freedata_args *argp; - DB *file_dbp; - DB_LSN *lsnp; - DB_MPOOLFILE *mpf; - db_recops op; - int data; -{ - DBMETA *meta; - DB_LSN copy_lsn; - PAGE *pagep, *prevp; - int cmp_n, cmp_p, is_meta, meta_modified, modified, ret; - - meta = NULL; - pagep = NULL; - prevp = NULL; - meta_modified = modified = 0; - - /* - * Get the "metapage". This will either be the metapage - * or the previous page in the free list if we are doing - * sorted allocations. If its a previous page then - * we will not be truncating. - */ - is_meta = argp->meta_pgno == PGNO_BASE_MD; - - REC_FGET(mpf, argp->meta_pgno, &meta, check_meta); - - if (argp->meta_pgno != PGNO_BASE_MD) - prevp = (PAGE *)meta; - - cmp_n = log_compare(lsnp, &LSN(meta)); - cmp_p = log_compare(&LSN(meta), &argp->meta_lsn); - CHECK_LSN(dbenv, op, cmp_p, &LSN(meta), &argp->meta_lsn); - - /* - * Fix up the metadata page. If we're redoing or undoing the operation - * we get the page and update its LSN, last and free pointer. - */ - if (cmp_p == 0 && DB_REDO(op)) { -#ifdef HAVE_FTRUNCATE - /* - * If we are at the end of the file truncate, otherwise - * put on the free list. - */ - if (argp->pgno == argp->last_pgno) - meta->last_pgno = argp->pgno - 1; - else if (prevp == NULL) - meta->free = argp->pgno; - else - NEXT_PGNO(prevp) = argp->pgno; -#else - /* Need to redo the deallocation. */ - if (prevp == NULL) - meta->free = argp->pgno; - else - NEXT_PGNO(prevp) = argp->pgno; - /* - * If this was a compensating transaction and - * we are a replica, then we never executed the - * original allocation which incremented meta->free. - */ - if (prevp == NULL && meta->last_pgno < meta->free) - meta->last_pgno = meta->free; -#endif - LSN(meta) = *lsnp; - meta_modified = 1; - } else if (cmp_n == 0 && DB_UNDO(op)) { - /* Need to undo the deallocation. */ - if (prevp == NULL) - meta->free = argp->next; - else - NEXT_PGNO(prevp) = argp->next; - LSN(meta) = argp->meta_lsn; - if (prevp == NULL && meta->last_pgno < argp->pgno) - meta->last_pgno = argp->pgno; - meta_modified = 1; - } - -check_meta: - if (ret != 0 && is_meta) { - /* The metadata page must always exist. */ - ret = __db_pgerr(file_dbp, argp->meta_pgno, ret); - goto out; - } - - /* - * Get the freed page. If we support truncate then don't - * create the page if we are going to free it. If we're - * redoing the operation we get the page and explicitly discard - * its contents, then update its LSN. If we're undoing the - * operation, we get the page and restore its header. - * If we don't support truncate, then we must create the page - * and roll it back. - */ -#ifdef HAVE_FTRUNCATE - if (DB_REDO(op) || (is_meta && meta->last_pgno < argp->pgno)) { - if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) { - if (ret == DB_PAGE_NOTFOUND) - goto done; - goto out; - } - } else -#endif - if ((ret = - __memp_fget(mpf, &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) - goto out; - - (void)__ua_memcpy(©_lsn, &LSN(argp->header.data), sizeof(DB_LSN)); - cmp_n = IS_ZERO_LSN(LSN(pagep)) ? 0 : log_compare(lsnp, &LSN(pagep)); - cmp_p = log_compare(&LSN(pagep), ©_lsn); - -#ifdef HAVE_FTRUNCATE - /* - * This page got extended by a later allocation, - * but its allocation was not in the scope of this - * recovery pass. - */ - if (IS_ZERO_LSN(LSN(pagep))) - cmp_p = 0; -#endif - - CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), ©_lsn); - if (DB_REDO(op) && - (cmp_p == 0 || - (IS_ZERO_LSN(copy_lsn) && - log_compare(&LSN(pagep), &argp->meta_lsn) <= 0))) { - /* Need to redo the deallocation. */ -#ifdef HAVE_FTRUNCATE - /* - * The page can be truncated if it was truncated at runtime - * and the current metapage reflects the truncation. - */ - if (is_meta && meta->last_pgno <= argp->pgno && - argp->last_pgno <= argp->pgno) { - if ((ret = - __memp_fput(mpf, pagep, DB_MPOOL_DISCARD)) != 0) - goto out; - pagep = NULL; - if ((ret = __memp_ftruncate(mpf, argp->pgno, 0)) != 0) - goto out; - } else if (argp->last_pgno == argp->pgno) { - /* The page was truncated at runtime, zero it out. */ - P_INIT(pagep, 0, PGNO_INVALID, - PGNO_INVALID, PGNO_INVALID, 0, P_INVALID); - ZERO_LSN(pagep->lsn); - modified = 1; - } else -#endif - { - P_INIT(pagep, file_dbp->pgsize, - argp->pgno, PGNO_INVALID, argp->next, 0, P_INVALID); - pagep->lsn = *lsnp; - - modified = 1; - } - } else if (cmp_n == 0 && DB_UNDO(op)) { - /* Need to reallocate the page. */ - memcpy(pagep, argp->header.data, argp->header.size); - if (data) - memcpy((u_int8_t*)pagep + HOFFSET(pagep), - argp->data.data, argp->data.size); - - modified = 1; - } - if (pagep != NULL && - (ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0) - goto out; - - pagep = NULL; -#ifdef HAVE_FTRUNCATE - /* - * If we are keeping an in memory free list remove this - * element from the list. - */ - if (op == DB_TXN_ABORT && argp->pgno != argp->last_pgno) { - db_pgno_t *lp; - u_int32_t nelem, pos; - - if ((ret = __memp_get_freelist(mpf, &nelem, &lp)) != 0) - goto out; - if (lp != NULL) { - pos = 0; - if (!is_meta && nelem != 0) { - __db_freelist_pos(argp->pgno, lp, nelem, &pos); - - DB_ASSERT(argp->pgno == lp[pos]); - DB_ASSERT(argp->meta_pgno == lp[pos - 1]); - } - - if (nelem != 0 && pos != nelem) - memmove(&lp[pos], &lp[pos + 1], - (nelem - pos) * sizeof(*lp)); - - /* Shrink the list */ - if ((ret = - __memp_extend_freelist(mpf, nelem - 1, &lp)) != 0) - goto out; - } - } -done: -#endif - if (meta != NULL && (ret = __memp_fput(mpf, - meta, meta_modified ? DB_MPOOL_DIRTY : 0)) != 0) - goto out; - meta = NULL; - - ret = 0; - -out: if (pagep != NULL) - (void)__memp_fput(mpf, pagep, 0); - if (meta != NULL) - (void)__memp_fput(mpf, meta, 0); - - return (ret); -} - -/* - * __db_pg_free_recover -- - * Recovery function for pg_free. - * - * PUBLIC: int __db_pg_free_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__db_pg_free_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - DB *file_dbp; - DBC *dbc; - DB_MPOOLFILE *mpf; - __db_pg_free_args *argp; - int ret; - - COMPQUIET(info, NULL); - REC_PRINT(__db_pg_free_print); - REC_INTRO(__db_pg_free_read, 1, 0); - - ret = __db_pg_free_recover_int(dbenv, - (__db_pg_freedata_args *)argp, file_dbp, lsnp, mpf, op, 0); - -done: *lsnp = argp->prev_lsn; -out: - REC_CLOSE; -} - -/* - * __db_pg_new_recover -- - * A new page from the file was put on the free list. - * This record is only generated during a LIMBO_COMPENSATE. - * - * PUBLIC: int __db_pg_new_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__db_pg_new_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ -#ifndef HAVE_FTRUNCATE - DB *file_dbp; - DBC *dbc; - DB_MPOOLFILE *mpf; - __db_pg_free_args *argp; - int ret; - - REC_PRINT(__db_pg_free_print); - REC_INTRO(__db_pg_free_read, 1, 0); - COMPQUIET(op, DB_TXN_ABORT); - - if ((ret = - __db_add_limbo(dbenv, info, argp->fileid, argp->pgno, 1)) == 0) - *lsnp = argp->prev_lsn; - -done: -out: - REC_CLOSE; -#else - COMPQUIET(dbenv, NULL); - COMPQUIET(dbtp, NULL); - COMPQUIET(lsnp, NULL); - COMPQUIET(op, DB_TXN_PRINT); - COMPQUIET(info, NULL); - return (0); -#endif -} - -/* - * __db_pg_freedata_recover -- - * Recovery function for pg_freedata. - * - * PUBLIC: int __db_pg_freedata_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__db_pg_freedata_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - DB *file_dbp; - DBC *dbc; - DB_MPOOLFILE *mpf; - __db_pg_freedata_args *argp; - int ret; - - COMPQUIET(info, NULL); - REC_PRINT(__db_pg_freedata_print); - REC_INTRO(__db_pg_freedata_read, 1, 0); - - ret = __db_pg_free_recover_int(dbenv, argp, file_dbp, lsnp, mpf, op, 1); - -done: *lsnp = argp->prev_lsn; -out: - REC_CLOSE; -} - -/* - * __db_cksum_recover -- - * Recovery function for checksum failure log record. - * - * PUBLIC: int __db_cksum_recover __P((DB_ENV *, - * PUBLIC: DBT *, DB_LSN *, db_recops, void *)); - */ -int -__db_cksum_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __db_cksum_args *argp; - - int ret; - - COMPQUIET(info, NULL); - COMPQUIET(lsnp, NULL); - COMPQUIET(op, DB_TXN_ABORT); - - REC_PRINT(__db_cksum_print); - - if ((ret = __db_cksum_read(dbenv, dbtp->data, &argp)) != 0) - return (ret); - - /* - * We had a checksum failure -- the only option is to run catastrophic - * recovery. - */ - if (F_ISSET(dbenv, DB_ENV_FATAL)) - ret = 0; - else { - __db_err(dbenv, - "Checksum failure requires catastrophic recovery"); - ret = __db_panic(dbenv, DB_RUNRECOVERY); - } - - __os_free(dbenv, argp); - return (ret); -} - -/* - * __db_pg_prepare_recover -- - * Recovery function for pg_prepare. - * - * PUBLIC: int __db_pg_prepare_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__db_pg_prepare_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ -#ifndef HAVE_FTRUNCATE - __db_pg_prepare_args *argp; - DB *file_dbp; - DBC *dbc; - DB_MPOOLFILE *mpf; - PAGE *pagep; - int ret, t_ret; - - REC_PRINT(__db_pg_prepare_print); - REC_INTRO(__db_pg_prepare_read, 1, 0); - - mpf = file_dbp->mpf; - - /* - * If this made it into the limbo list at prepare time then - * it was a new free page allocated by an aborted subtransaction. - * Only that subtransaction could have toched the page. - * All other pages in the free list at this point are - * either of the same nature or were put there by this subtransactions - * other subtransactions that followed this one. If - * they were put there by this subtransaction the log records - * of the following allocations will reflect that. - * Note that only one transaction could have had the - * metapage locked at the point of the crash. - * All this is to say that we can P_INIT this page without - * loosing other pages on the free list because they - * will be linked in by records earlier in the log for - * this transaction which we will roll back. - */ - if (op == DB_TXN_ABORT) { - if ((ret = __memp_fget( - mpf, &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) - goto out; - P_INIT(pagep, file_dbp->pgsize, - argp->pgno, PGNO_INVALID, PGNO_INVALID, 0, P_INVALID); - ZERO_LSN(pagep->lsn); - ret = __db_add_limbo(dbenv, info, argp->fileid, argp->pgno, 1); - if ((t_ret = - __memp_fput(mpf, pagep, DB_MPOOL_DIRTY)) != 0 && ret == 0) - ret = t_ret; - } - -done: if (ret == 0) - *lsnp = argp->prev_lsn; -out: REC_CLOSE; -#else - COMPQUIET(dbenv, NULL); - COMPQUIET(dbtp, NULL); - COMPQUIET(lsnp, NULL); - COMPQUIET(op, DB_TXN_PRINT); - COMPQUIET(info, NULL); - return (0); -#endif - -} - -/* - * __db_pg_init_recover -- - * Recovery function to reinit pages for truncate. - * - * PUBLIC: int __db_pg_init_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__db_pg_init_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __db_pg_init_args *argp; - DB *file_dbp; - DBC *dbc; - DB_LSN copy_lsn; - DB_MPOOLFILE *mpf; - PAGE *pagep; - int cmp_n, cmp_p, modified, ret, type; - - COMPQUIET(info, NULL); - REC_PRINT(__db_pg_init_print); - REC_INTRO(__db_pg_init_read, 1, 0); - - mpf = file_dbp->mpf; - REC_FGET(mpf, argp->pgno, &pagep, done); - - modified = 0; - (void)__ua_memcpy(©_lsn, &LSN(argp->header.data), sizeof(DB_LSN)); - cmp_n = log_compare(lsnp, &LSN(pagep)); - cmp_p = log_compare(&LSN(pagep), ©_lsn); - CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), ©_lsn); - - if (cmp_p == 0 && DB_REDO(op)) { - if (TYPE(pagep) == P_HASH) - type = P_HASH; - else - type = file_dbp->type == DB_RECNO ? P_LRECNO : P_LBTREE; - P_INIT(pagep, file_dbp->pgsize, PGNO(pagep), PGNO_INVALID, - PGNO_INVALID, TYPE(pagep) == P_HASH ? 0 : 1, type); - pagep->lsn = *lsnp; - modified = 1; - } else if (cmp_n == 0 && DB_UNDO(op)) { - /* Put the data back on the page. */ - memcpy(pagep, argp->header.data, argp->header.size); - if (argp->data.size > 0) - memcpy((u_int8_t*)pagep + HOFFSET(pagep), - argp->data.data, argp->data.size); - - modified = 1; - } - if ((ret = __memp_fput(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0) - goto out; - -done: *lsnp = argp->prev_lsn; -out: - REC_CLOSE; -} - -/* - * __db_pg_sort_recover -- - * Recovery function for pg_sort. - * - * PUBLIC: int __db_pg_sort_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__db_pg_sort_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ -#ifdef HAVE_FTRUNCATE - __db_pg_sort_args *argp; - DB *file_dbp; - DBC *dbc; - DBMETA *meta; - DB_MPOOLFILE *mpf; - PAGE *pagep; - db_pgno_t pgno, *list; - u_int32_t felem, nelem; - struct pglist *pglist, *lp; - int modified, ret; - - COMPQUIET(info, NULL); - - REC_PRINT(__db_pg_sort_print); - REC_INTRO(__db_pg_sort_read, 1, 1); - - modified = 0; - - pglist = (struct pglist *) argp->list.data; - nelem = argp->list.size / sizeof(struct pglist); - if (DB_REDO(op)) { - pgno = argp->last_pgno; - if ((ret = __db_pg_truncate(mpf, - pglist, NULL, &nelem, &pgno, lsnp, 1)) != 0) - goto out; - - if (argp->last_free != PGNO_INVALID) { - if ((ret = __memp_fget(mpf, - &argp->last_free, 0, &meta)) == 0) { - if (log_compare(&LSN(meta), - &argp->last_lsn) == 0) { - NEXT_PGNO(meta) = PGNO_INVALID; - LSN(meta) = *lsnp; - modified = 1; - } - if ((ret = __memp_fput(mpf, - meta, modified ? DB_MPOOL_DIRTY : 0)) != 0) - goto out; - meta = NULL; - modified = 0; - } else if (ret != DB_PAGE_NOTFOUND) - goto out; - } - if ((ret = __memp_fget(mpf, &argp->meta, 0, &meta)) != 0) - goto out; - if (log_compare(&LSN(meta), &argp->meta_lsn) == 0) { - if (argp->last_free == PGNO_INVALID) { - if (nelem == 0) - meta->free = PGNO_INVALID; - else - meta->free = pglist->pgno; - } - meta->last_pgno = pgno; - LSN(meta) = *lsnp; - modified = 1; - } - } else { - /* Put the free list back in its original order. */ - for (lp = pglist; lp < &pglist[nelem]; lp++) { - if ((ret = __memp_fget(mpf, - &lp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) - goto out; - if (IS_ZERO_LSN(LSN(pagep)) || - log_compare(&LSN(pagep), lsnp) == 0) { - if (lp == &pglist[nelem - 1]) - pgno = PGNO_INVALID; - else - pgno = lp[1].pgno; - - P_INIT(pagep, file_dbp->pgsize, - lp->pgno, PGNO_INVALID, pgno, 0, P_INVALID); - LSN(pagep) = lp->lsn; - modified = 1; - } - if ((ret = __memp_fput(mpf, - pagep, modified ? DB_MPOOL_DIRTY: 0)) != 0) - goto out; - } - if (argp->last_free != PGNO_INVALID) { - if ((ret = __memp_fget(mpf, - &argp->last_free, 0, &meta)) == 0) { - if (log_compare(&LSN(meta), lsnp) == 0) { - NEXT_PGNO(meta) = pglist->pgno; - LSN(meta) = argp->last_lsn; - modified = 1; - } - if ((ret = __memp_fput(mpf, - meta, modified ? DB_MPOOL_DIRTY : 0)) != 0) - goto out; - } else if (ret != DB_PAGE_NOTFOUND) - goto out; - modified = 0; - meta = NULL; - } - if ((ret = __memp_fget(mpf, &argp->meta, 0, &meta)) != 0) - goto out; - if (log_compare(&LSN(meta), lsnp) == 0) { - meta->last_pgno = argp->last_pgno; - if (argp->last_pgno == PGNO_INVALID) - meta->free = pglist->pgno; - LSN(meta) = argp->meta_lsn; - modified = 1; - } - } - if (op == DB_TXN_ABORT) { - if ((ret = __memp_get_freelist(mpf, &felem, &list)) != 0) - goto out; - if (list != NULL) { - DB_ASSERT(felem == 0 || - argp->last_free == list[felem - 1]); - if ((ret = __memp_extend_freelist( - mpf, felem + nelem, &list)) != 0) - goto out; - for (lp = pglist; lp < &pglist[nelem]; lp++) - list[felem++] = lp->pgno; - } - } - - if ((ret = __memp_fput(mpf, meta, modified ? DB_MPOOL_DIRTY : 0)) != 0) - goto out; - -done: *lsnp = argp->prev_lsn; - ret = 0; - -out: REC_CLOSE; -#else - /* - * If HAVE_FTRUNCATE is not defined, we'll never see pg_sort records - * to recover. - */ - COMPQUIET(dbenv, NULL); - COMPQUIET(dbtp, NULL); - COMPQUIET(lsnp, NULL); - COMPQUIET(op, DB_TXN_ABORT); - COMPQUIET(info, NULL); - return (EINVAL); -#endif -} diff --git a/storage/bdb/db/db_reclaim.c b/storage/bdb/db/db_reclaim.c deleted file mode 100644 index ed68bc6eae7..00000000000 --- a/storage/bdb/db/db_reclaim.c +++ /dev/null @@ -1,239 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_reclaim.c,v 12.2 2005/06/16 20:21:14 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/btree.h" -#include "dbinc/mp.h" - -/* - * __db_traverse_big - * Traverse a chain of overflow pages and call the callback routine - * on each one. The calling convention for the callback is: - * callback(dbp, page, cookie, did_put), - * where did_put is a return value indicating if the page in question has - * already been returned to the mpool. - * - * PUBLIC: int __db_traverse_big __P((DB *, - * PUBLIC: db_pgno_t, int (*)(DB *, PAGE *, void *, int *), void *)); - */ -int -__db_traverse_big(dbp, pgno, callback, cookie) - DB *dbp; - db_pgno_t pgno; - int (*callback) __P((DB *, PAGE *, void *, int *)); - void *cookie; -{ - DB_MPOOLFILE *mpf; - PAGE *p; - int did_put, ret; - - mpf = dbp->mpf; - - do { - did_put = 0; - if ((ret = __memp_fget(mpf, &pgno, 0, &p)) != 0) - return (ret); - /* - * If we are freeing pages only process the overflow - * chain if the head of the chain has a refcount of 1. - */ - pgno = NEXT_PGNO(p); - if (callback == __db_truncate_callback && OV_REF(p) != 1) - pgno = PGNO_INVALID; - if ((ret = callback(dbp, p, cookie, &did_put)) == 0 && - !did_put) - ret = __memp_fput(mpf, p, 0); - } while (ret == 0 && pgno != PGNO_INVALID); - - return (ret); -} - -/* - * __db_reclaim_callback - * This is the callback routine used during a delete of a subdatabase. - * we are traversing a btree or hash table and trying to free all the - * pages. Since they share common code for duplicates and overflow - * items, we traverse them identically and use this routine to do the - * actual free. The reason that this is callback is because hash uses - * the same traversal code for statistics gathering. - * - * PUBLIC: int __db_reclaim_callback __P((DB *, PAGE *, void *, int *)); - */ -int -__db_reclaim_callback(dbp, p, cookie, putp) - DB *dbp; - PAGE *p; - void *cookie; - int *putp; -{ - int ret; - - /* - * We don't want to log the free of the root with the subdb. - * If we abort then the subdb may not be openable to undo - * the free. - */ - - if ((dbp->type == DB_BTREE || dbp->type == DB_RECNO) && - PGNO(p) == ((BTREE *)dbp->bt_internal)->bt_root) - return (0); - if ((ret = __db_free(cookie, p)) != 0) - return (ret); - *putp = 1; - - return (0); -} - -/* - * __db_truncate_callback - * This is the callback routine used during a truncate. - * we are traversing a btree or hash table and trying to free all the - * pages. - * - * PUBLIC: int __db_truncate_callback __P((DB *, PAGE *, void *, int *)); - */ -int -__db_truncate_callback(dbp, p, cookie, putp) - DB *dbp; - PAGE *p; - void *cookie; - int *putp; -{ - DB_MPOOLFILE *mpf; - DBT ddbt, ldbt; - db_indx_t indx, len, off, tlen, top; - db_trunc_param *param; - u_int8_t *hk, type; - int ret; - - top = NUM_ENT(p); - mpf = dbp->mpf; - param = cookie; - *putp = 1; - - switch (TYPE(p)) { - case P_LBTREE: - /* Skip for off-page duplicates and deleted items. */ - for (indx = 0; indx < top; indx += P_INDX) { - type = GET_BKEYDATA(dbp, p, indx + O_INDX)->type; - if (!B_DISSET(type) && B_TYPE(type) != B_DUPLICATE) - ++param->count; - } - /* FALLTHROUGH */ - case P_IBTREE: - case P_IRECNO: - case P_INVALID: - if (dbp->type != DB_HASH && - ((BTREE *)dbp->bt_internal)->bt_root == PGNO(p)) { - type = dbp->type == DB_RECNO ? P_LRECNO : P_LBTREE; - goto reinit; - } - break; - case P_OVERFLOW: - if (DBC_LOGGING(param->dbc)) { - if ((ret = __db_ovref_log(dbp, param->dbc->txn, - &LSN(p), 0, p->pgno, -1, &LSN(p))) != 0) - return (ret); - } else - LSN_NOT_LOGGED(LSN(p)); - if (--OV_REF(p) != 0) - *putp = 0; - break; - case P_LRECNO: - for (indx = 0; indx < top; indx += O_INDX) { - type = GET_BKEYDATA(dbp, p, indx)->type; - if (!B_DISSET(type)) - ++param->count; - } - - if (((BTREE *)dbp->bt_internal)->bt_root == PGNO(p)) { - type = P_LRECNO; - goto reinit; - } - break; - case P_LDUP: - /* Correct for deleted items. */ - for (indx = 0; indx < top; indx += O_INDX) - if (!B_DISSET(GET_BKEYDATA(dbp, p, indx)->type)) - ++param->count; - - break; - case P_HASH: - /* Correct for on-page duplicates and deleted items. */ - for (indx = 0; indx < top; indx += P_INDX) { - switch (*H_PAIRDATA(dbp, p, indx)) { - case H_OFFDUP: - break; - case H_OFFPAGE: - case H_KEYDATA: - ++param->count; - break; - case H_DUPLICATE: - tlen = LEN_HDATA(dbp, p, 0, indx); - hk = H_PAIRDATA(dbp, p, indx); - for (off = 0; off < tlen; - off += len + 2 * sizeof(db_indx_t)) { - ++param->count; - memcpy(&len, - HKEYDATA_DATA(hk) - + off, sizeof(db_indx_t)); - } - break; - default: - return (__db_pgfmt(dbp->dbenv, p->pgno)); - } - } - /* Don't free the head of the bucket. */ - if (PREV_PGNO(p) == PGNO_INVALID) { - type = P_HASH; - -reinit: *putp = 0; - if (DBC_LOGGING(param->dbc)) { - memset(&ldbt, 0, sizeof(ldbt)); - memset(&ddbt, 0, sizeof(ddbt)); - ldbt.data = p; - ldbt.size = P_OVERHEAD(dbp); - ldbt.size += p->entries * sizeof(db_indx_t); - ddbt.data = (u_int8_t *)p + HOFFSET(p); - ddbt.size = dbp->pgsize - HOFFSET(p); - if ((ret = __db_pg_init_log(dbp, - param->dbc->txn, &LSN(p), 0, - p->pgno, &ldbt, &ddbt)) != 0) - return (ret); - } else - LSN_NOT_LOGGED(LSN(p)); - - P_INIT(p, dbp->pgsize, PGNO(p), PGNO_INVALID, - PGNO_INVALID, type == P_HASH ? 0 : 1, type); - } - break; - default: - return (__db_pgfmt(dbp->dbenv, p->pgno)); - } - - if (*putp == 1) { - if ((ret = __db_free(param->dbc, p)) != 0) - return (ret); - } else { - if ((ret = __memp_fput(mpf, p, DB_MPOOL_DIRTY)) != 0) - return (ret); - *putp = 1; - } - - return (0); -} diff --git a/storage/bdb/db/db_remove.c b/storage/bdb/db/db_remove.c deleted file mode 100644 index c37c1876dd7..00000000000 --- a/storage/bdb/db/db_remove.c +++ /dev/null @@ -1,490 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2001-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_remove.c,v 12.16 2005/10/27 01:25:53 mjc Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/fop.h" -#include "dbinc/btree.h" -#include "dbinc/hash.h" -#include "dbinc/db_shash.h" -#include "dbinc/lock.h" -#include "dbinc/mp.h" -#include "dbinc/txn.h" - -static int __db_dbtxn_remove __P((DB *, DB_TXN *, const char *, const char *)); -static int __db_subdb_remove __P((DB *, DB_TXN *, const char *, const char *)); - -/* - * __env_dbremove_pp - * DB_ENV->dbremove pre/post processing. - * - * PUBLIC: int __env_dbremove_pp __P((DB_ENV *, - * PUBLIC: DB_TXN *, const char *, const char *, u_int32_t)); - */ -int -__env_dbremove_pp(dbenv, txn, name, subdb, flags) - DB_ENV *dbenv; - DB_TXN *txn; - const char *name, *subdb; - u_int32_t flags; -{ - DB *dbp; - DB_THREAD_INFO *ip; - int handle_check, ret, t_ret, txn_local; - - dbp = NULL; - txn_local = 0; - - PANIC_CHECK(dbenv); - ENV_ILLEGAL_BEFORE_OPEN(dbenv, "DB_ENV->dbremove"); - - /* - * The actual argument checking is simple, do it inline, outside of - * the replication block. - */ - if ((ret = __db_fchk(dbenv, "DB->remove", flags, DB_AUTO_COMMIT)) != 0) - return (ret); - - ENV_ENTER(dbenv, ip); - - /* Check for replication block. */ - handle_check = IS_ENV_REPLICATED(dbenv); - if (handle_check && (ret = __env_rep_enter(dbenv, 1)) != 0) { - handle_check = 0; - goto err; - } - - /* - * Create local transaction as necessary, check for consistent - * transaction usage. - */ - if (IS_ENV_AUTO_COMMIT(dbenv, txn, flags)) { - if ((ret = __db_txn_auto_init(dbenv, &txn)) != 0) - goto err; - txn_local = 1; - } else - if (txn != NULL && !TXN_ON(dbenv)) { - ret = __db_not_txn_env(dbenv); - goto err; - } - LF_CLR(DB_AUTO_COMMIT); - - if ((ret = db_create(&dbp, dbenv, 0)) != 0) - goto err; - - ret = __db_remove_int(dbp, txn, name, subdb, flags); - - if (txn_local) { - /* - * We created the DBP here and when we commit/abort, we'll - * release all the transactional locks, including the handle - * lock; mark the handle cleared explicitly. - */ - LOCK_INIT(dbp->handle_lock); - dbp->lid = DB_LOCK_INVALIDID; - } else if (txn != NULL) { - /* - * We created this handle locally so we need to close it - * and clean it up. Unfortunately, it's holding transactional - * locks that need to persist until the end of transaction. - * If we invalidate the locker id (dbp->lid), then the close - * won't free these locks prematurely. - */ - dbp->lid = DB_LOCK_INVALIDID; - } - -err: if (txn_local && (t_ret = - __db_txn_auto_resolve(dbenv, txn, 0, ret)) != 0 && ret == 0) - ret = t_ret; - - /* - * We never opened this dbp for real, so don't include a transaction - * handle, and use NOSYNC to avoid calling into mpool. - * - * !!! - * Note we're reversing the order of operations: we started the txn and - * then opened the DB handle; we're resolving the txn and then closing - * closing the DB handle -- it's safer. - */ - if (dbp != NULL && - (t_ret = __db_close(dbp, NULL, DB_NOSYNC)) != 0 && ret == 0) - ret = t_ret; - - if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __db_remove_pp - * DB->remove pre/post processing. - * - * PUBLIC: int __db_remove_pp - * PUBLIC: __P((DB *, const char *, const char *, u_int32_t)); - */ -int -__db_remove_pp(dbp, name, subdb, flags) - DB *dbp; - const char *name, *subdb; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int handle_check, ret, t_ret; - - dbenv = dbp->dbenv; - - PANIC_CHECK(dbenv); - - /* - * Validate arguments, continuing to destroy the handle on failure. - * - * Cannot use DB_ILLEGAL_AFTER_OPEN directly because it returns. - * - * !!! - * We have a serious problem if we're here with a handle used to open - * a database -- we'll destroy the handle, and the application won't - * ever be able to close the database. - */ - if (F_ISSET(dbp, DB_AM_OPEN_CALLED)) { - ret = __db_mi_open(dbenv, "DB->remove", 1); - return (ret); - } - - /* Validate arguments. */ - if ((ret = __db_fchk(dbenv, "DB->remove", flags, 0)) != 0) - return (ret); - - /* Check for consistent transaction usage. */ - if ((ret = __db_check_txn(dbp, NULL, DB_LOCK_INVALIDID, 0)) != 0) - return (ret); - - ENV_ENTER(dbenv, ip); - - handle_check = IS_ENV_REPLICATED(dbenv); - if (handle_check && (ret = __db_rep_enter(dbp, 1, 1, 0)) != 0) { - handle_check = 0; - goto err; - } - - /* Remove the file. */ - ret = __db_remove(dbp, NULL, name, subdb, flags); - - if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - -err: ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __db_remove - * DB->remove method. - * - * PUBLIC: int __db_remove - * PUBLIC: __P((DB *, DB_TXN *, const char *, const char *, u_int32_t)); - */ -int -__db_remove(dbp, txn, name, subdb, flags) - DB *dbp; - DB_TXN *txn; - const char *name, *subdb; - u_int32_t flags; -{ - int ret, t_ret; - - ret = __db_remove_int(dbp, txn, name, subdb, flags); - - if ((t_ret = __db_close(dbp, txn, DB_NOSYNC)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __db_remove_int - * Worker function for the DB->remove method. - * - * PUBLIC: int __db_remove_int __P((DB *, - * PUBLIC: DB_TXN *, const char *, const char *, u_int32_t)); - */ -int -__db_remove_int(dbp, txn, name, subdb, flags) - DB *dbp; - DB_TXN *txn; - const char *name, *subdb; - u_int32_t flags; -{ - DB_ENV *dbenv; - int ret; - char *real_name, *tmpname; - - dbenv = dbp->dbenv; - real_name = tmpname = NULL; - - if (name == NULL && subdb == NULL) { - __db_err(dbenv, "Remove on temporary files invalid"); - ret = EINVAL; - goto err; - } - - if (name == NULL) { - MAKE_INMEM(dbp); - real_name = (char *)subdb; - } else if (subdb != NULL) { - ret = __db_subdb_remove(dbp, txn, name, subdb); - goto err; - } - - /* Handle transactional file removes separately. */ - if (txn != NULL) { - ret = __db_dbtxn_remove(dbp, txn, name, subdb); - goto err; - } - - /* - * The remaining case is a non-transactional file remove. - * - * Find the real name of the file. - */ - if (!F_ISSET(dbp, DB_AM_INMEM) && (ret = - __db_appname(dbenv, DB_APP_DATA, name, 0, NULL, &real_name)) != 0) - goto err; - - /* - * If this is a file and force is set, remove the temporary file, which - * may have been left around. Ignore errors because the temporary file - * might not exist. - */ - if (!F_ISSET(dbp, DB_AM_INMEM) && LF_ISSET(DB_FORCE) && - (ret = __db_backup_name(dbenv, real_name, NULL, &tmpname)) == 0) - (void)__os_unlink(dbenv, tmpname); - - if ((ret = __fop_remove_setup(dbp, NULL, real_name, 0)) != 0) - goto err; - - if (dbp->db_am_remove != NULL && - (ret = dbp->db_am_remove(dbp, NULL, name, subdb)) != 0) - goto err; - - ret = F_ISSET(dbp, DB_AM_INMEM) ? - __db_inmem_remove(dbp, NULL, real_name) : - __fop_remove(dbenv, NULL, dbp->fileid, name, DB_APP_DATA, - F_ISSET(dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0); - -err: if (!F_ISSET(dbp, DB_AM_INMEM) && real_name != NULL) - __os_free(dbenv, real_name); - if (tmpname != NULL) - __os_free(dbenv, tmpname); - - return (ret); -} - -/* - * __db_inmem_remove -- - * Removal of a named in-memory database. - * PUBLIC: int __db_inmem_remove __P((DB *, DB_TXN *, const char *)); - */ -int -__db_inmem_remove(dbp, txn, name) - DB *dbp; - DB_TXN *txn; - const char *name; -{ - DB_ENV *dbenv; - DB_LSN lsn; - DBT fid_dbt, name_dbt; - u_int32_t locker; - int ret; - - dbenv = dbp->dbenv; - locker = DB_LOCK_INVALIDID; - - DB_ASSERT(name != NULL); - - /* This had better exist if we are trying to do a remove. */ - (void)__memp_set_flags(dbp->mpf, DB_MPOOL_NOFILE, 1); - if ((ret = __memp_fopen(dbp->mpf, NULL, name, 0, 0, 0)) != 0) - return (ret); - if ((ret = __memp_get_fileid(dbp->mpf, dbp->fileid)) != 0) - goto err; - dbp->preserve_fid = 1; - - if (LOCKING_ON(dbenv)) { - if (dbp->lid == DB_LOCK_INVALIDID && - (ret = __lock_id(dbenv, &dbp->lid, NULL)) != 0) - goto err; - locker = txn == NULL ? dbp->lid : txn->txnid; - } - - /* - * In a transactional environment, we'll play the same game - * that we play for databases in the file system -- create a - * temporary database and put it in with the current name - * and then rename this one to another name. We'll then use - * a commit-time event to remove the entry. - */ - - if ((ret = __fop_lock_handle(dbenv, - dbp, locker, DB_LOCK_WRITE, NULL, 0)) != 0) - goto err; - - if (LOGGING_ON(dbenv)) { - memset(&fid_dbt, 0, sizeof(fid_dbt)); - fid_dbt.data = dbp->fileid; - fid_dbt.size = DB_FILE_ID_LEN; - memset(&name_dbt, 0, sizeof(name_dbt)); - name_dbt.data = (void *)name; - name_dbt.size = (u_int32_t)strlen(name) + 1; - - if (txn != NULL && (ret = - __txn_remevent(dbenv, txn, name, dbp->fileid, 1)) != 0) - goto err; - - if ((ret = __crdel_inmem_remove_log(dbenv, - txn, &lsn, 0, &name_dbt, &fid_dbt)) != 0) - goto err; - } - - if (txn == NULL) - ret = __memp_nameop(dbenv, dbp->fileid, NULL, name, NULL, 1); - -err: return (ret); -} - -/* - * __db_subdb_remove -- - * Remove a subdatabase. - */ -static int -__db_subdb_remove(dbp, txn, name, subdb) - DB *dbp; - DB_TXN *txn; - const char *name, *subdb; -{ - DB *mdbp, *sdbp; - int ret, t_ret; - - mdbp = sdbp = NULL; - - /* Open the subdatabase. */ - if ((ret = db_create(&sdbp, dbp->dbenv, 0)) != 0) - goto err; - if ((ret = __db_open(sdbp, - txn, name, subdb, DB_UNKNOWN, DB_WRITEOPEN, 0, PGNO_BASE_MD)) != 0) - goto err; - - DB_TEST_RECOVERY(sdbp, DB_TEST_PREDESTROY, ret, name); - - /* Free up the pages in the subdatabase. */ - switch (sdbp->type) { - case DB_BTREE: - case DB_RECNO: - if ((ret = __bam_reclaim(sdbp, txn)) != 0) - goto err; - break; - case DB_HASH: - if ((ret = __ham_reclaim(sdbp, txn)) != 0) - goto err; - break; - case DB_QUEUE: - case DB_UNKNOWN: - default: - ret = __db_unknown_type( - sdbp->dbenv, "__db_subdb_remove", sdbp->type); - goto err; - } - - /* - * Remove the entry from the main database and free the subdatabase - * metadata page. - */ - if ((ret = __db_master_open(sdbp, txn, name, 0, 0, &mdbp)) != 0) - goto err; - - if ((ret = __db_master_update( - mdbp, sdbp, txn, subdb, sdbp->type, MU_REMOVE, NULL, 0)) != 0) - goto err; - - DB_TEST_RECOVERY(sdbp, DB_TEST_POSTDESTROY, ret, name); - -DB_TEST_RECOVERY_LABEL -err: - /* Close the main and subdatabases. */ - if ((t_ret = __db_close(sdbp, txn, 0)) != 0 && ret == 0) - ret = t_ret; - - if (mdbp != NULL && - (t_ret = __db_close(mdbp, txn, DB_NOSYNC)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -static int -__db_dbtxn_remove(dbp, txn, name, subdb) - DB *dbp; - DB_TXN *txn; - const char *name, *subdb; -{ - DB_ENV *dbenv; - int ret; - char *tmpname; - - dbenv = dbp->dbenv; - tmpname = NULL; - - /* - * This is a transactional remove, so we have to keep the name - * of the file locked until the transaction commits. As a result, - * we implement remove by renaming the file to some other name - * (which creates a dummy named file as a placeholder for the - * file being rename/dremoved) and then deleting that file as - * a delayed remove at commit. - */ - if ((ret = __db_backup_name(dbenv, - F_ISSET(dbp, DB_AM_INMEM) ? subdb : name, txn, &tmpname)) != 0) - return (ret); - - DB_TEST_RECOVERY(dbp, DB_TEST_PREDESTROY, ret, name); - - if ((ret = __db_rename_int(dbp, txn, name, subdb, tmpname)) != 0) - goto err; - - /* - * The internal removes will also translate into delayed removes. - */ - if (dbp->db_am_remove != NULL && - (ret = dbp->db_am_remove(dbp, txn, tmpname, NULL)) != 0) - goto err; - - ret = F_ISSET(dbp, DB_AM_INMEM) ? - __db_inmem_remove(dbp, txn, tmpname) : - __fop_remove(dbenv, txn, dbp->fileid, tmpname, DB_APP_DATA, - F_ISSET(dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0); - - DB_TEST_RECOVERY(dbp, DB_TEST_POSTDESTROY, ret, name); - -err: -DB_TEST_RECOVERY_LABEL - if (tmpname != NULL) - __os_free(dbenv, tmpname); - - return (ret); -} diff --git a/storage/bdb/db/db_rename.c b/storage/bdb/db/db_rename.c deleted file mode 100644 index 827d772751d..00000000000 --- a/storage/bdb/db/db_rename.c +++ /dev/null @@ -1,373 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2001-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_rename.c,v 12.11 2005/10/07 20:21:22 ubell Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/db_am.h" -#include "dbinc/fop.h" -#include "dbinc/lock.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" - -static int __db_subdb_rename __P((DB *, - DB_TXN *, const char *, const char *, const char *)); - -/* - * __env_dbrename_pp - * DB_ENV->dbrename pre/post processing. - * - * PUBLIC: int __env_dbrename_pp __P((DB_ENV *, DB_TXN *, - * PUBLIC: const char *, const char *, const char *, u_int32_t)); - */ -int -__env_dbrename_pp(dbenv, txn, name, subdb, newname, flags) - DB_ENV *dbenv; - DB_TXN *txn; - const char *name, *subdb, *newname; - u_int32_t flags; -{ - DB *dbp; - DB_THREAD_INFO *ip; - int handle_check, ret, t_ret, txn_local; - - dbp = NULL; - txn_local = 0; - - PANIC_CHECK(dbenv); - ENV_ILLEGAL_BEFORE_OPEN(dbenv, "DB_ENV->dbrename"); - - /* - * The actual argument checking is simple, do it inline, outside of - * the replication block. - */ - if ((ret = __db_fchk(dbenv, "DB->rename", flags, DB_AUTO_COMMIT)) != 0) - return (ret); - - ENV_ENTER(dbenv, ip); - - /* Check for replication block. */ - handle_check = IS_ENV_REPLICATED(dbenv); - if (handle_check && (ret = __env_rep_enter(dbenv, 1)) != 0) { - handle_check = 0; - goto err; - } - - /* - * Create local transaction as necessary, check for consistent - * transaction usage. - */ - if (IS_ENV_AUTO_COMMIT(dbenv, txn, flags)) { - if ((ret = __db_txn_auto_init(dbenv, &txn)) != 0) - goto err; - txn_local = 1; - } else - if (txn != NULL && !TXN_ON(dbenv)) { - ret = __db_not_txn_env(dbenv); - goto err; - } - - LF_CLR(DB_AUTO_COMMIT); - - if ((ret = db_create(&dbp, dbenv, 0)) != 0) - goto err; - - ret = __db_rename_int(dbp, txn, name, subdb, newname); - - if (txn_local) { - /* - * We created the DBP here and when we commit/abort, we'll - * release all the transactional locks, including the handle - * lock; mark the handle cleared explicitly. - */ - LOCK_INIT(dbp->handle_lock); - dbp->lid = DB_LOCK_INVALIDID; - } else if (txn != NULL) { - /* - * We created this handle locally so we need to close it - * and clean it up. Unfortunately, it's holding transactional - * locks that need to persist until the end of transaction. - * If we invalidate the locker id (dbp->lid), then the close - * won't free these locks prematurely. - */ - dbp->lid = DB_LOCK_INVALIDID; - } - -err: if (txn_local && (t_ret = - __db_txn_auto_resolve(dbenv, txn, 0, ret)) != 0 && ret == 0) - ret = t_ret; - - /* - * We never opened this dbp for real, so don't include a transaction - * handle, and use NOSYNC to avoid calling into mpool. - * - * !!! - * Note we're reversing the order of operations: we started the txn and - * then opened the DB handle; we're resolving the txn and then closing - * closing the DB handle -- it's safer. - */ - if (dbp != NULL && - (t_ret = __db_close(dbp, NULL, DB_NOSYNC)) != 0 && ret == 0) - ret = t_ret; - - if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __db_rename_pp - * DB->rename pre/post processing. - * - * PUBLIC: int __db_rename_pp __P((DB *, - * PUBLIC: const char *, const char *, const char *, u_int32_t)); - */ -int -__db_rename_pp(dbp, name, subdb, newname, flags) - DB *dbp; - const char *name, *subdb, *newname; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int handle_check, ret, t_ret; - - dbenv = dbp->dbenv; - handle_check = 0; - - PANIC_CHECK(dbenv); - - /* - * Validate arguments, continuing to destroy the handle on failure. - * - * Cannot use DB_ILLEGAL_AFTER_OPEN directly because it returns. - * - * !!! - * We have a serious problem if we're here with a handle used to open - * a database -- we'll destroy the handle, and the application won't - * ever be able to close the database. - */ - if (F_ISSET(dbp, DB_AM_OPEN_CALLED)) - return (__db_mi_open(dbenv, "DB->rename", 1)); - - /* Validate arguments. */ - if ((ret = __db_fchk(dbenv, "DB->rename", flags, 0)) != 0) - return (ret); - - /* Check for consistent transaction usage. */ - if ((ret = __db_check_txn(dbp, NULL, DB_LOCK_INVALIDID, 0)) != 0) - return (ret); - - ENV_ENTER(dbenv, ip); - - handle_check = IS_ENV_REPLICATED(dbenv); - if (handle_check && (ret = __db_rep_enter(dbp, 1, 1, 0)) != 0) { - handle_check = 0; - goto err; - } - - /* Rename the file. */ - ret = __db_rename(dbp, NULL, name, subdb, newname); - - if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; -err: ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __db_rename - * DB->rename method. - * - * PUBLIC: int __db_rename - * PUBLIC: __P((DB *, DB_TXN *, const char *, const char *, const char *)); - */ -int -__db_rename(dbp, txn, name, subdb, newname) - DB *dbp; - DB_TXN *txn; - const char *name, *subdb, *newname; -{ - int ret, t_ret; - - ret = __db_rename_int(dbp, txn, name, subdb, newname); - - if ((t_ret = __db_close(dbp, txn, DB_NOSYNC)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __db_rename_int - * Worker function for DB->rename method; the close of the dbp is - * left in the wrapper routine. - * - * PUBLIC: int __db_rename_int - * PUBLIC: __P((DB *, DB_TXN *, const char *, const char *, const char *)); - */ -int -__db_rename_int(dbp, txn, name, subdb, newname) - DB *dbp; - DB_TXN *txn; - const char *name, *subdb, *newname; -{ - DB_ENV *dbenv; - int ret; - char *old, *real_name; - - dbenv = dbp->dbenv; - real_name = NULL; - - DB_TEST_RECOVERY(dbp, DB_TEST_PREDESTROY, ret, name); - - if (name == NULL && subdb == NULL) { - __db_err(dbenv, "Rename on temporary files invalid"); - ret = EINVAL; - goto err; - } - - if (name == NULL) - MAKE_INMEM(dbp); - else if (subdb != NULL) { - ret = __db_subdb_rename(dbp, txn, name, subdb, newname); - goto err; - } - - /* - * From here on down, this pertains to files or in-memory databases. - * - * Find the real name of the file. - */ - if (F_ISSET(dbp, DB_AM_INMEM)) { - old = (char *)subdb; - real_name = (char *)subdb; - } else { - if ((ret = __db_appname(dbenv, - DB_APP_DATA, name, 0, NULL, &real_name)) != 0) - goto err; - old = (char *)name; - } - - if ((ret = __fop_remove_setup(dbp, txn, real_name, 0)) != 0) - goto err; - - if (dbp->db_am_rename != NULL && - (ret = dbp->db_am_rename(dbp, txn, name, subdb, newname)) != 0) - goto err; - - /* - * The transactional case and non-transactional case are - * quite different. In the non-transactional case, we simply - * do the rename. In the transactional case, since we need - * the ability to back out and maintain locking, we have to - * create a temporary object as a placeholder. This is all - * taken care of in the fop layer. - */ - if (txn != NULL) { - if ((ret = __fop_dummy(dbp, txn, old, newname, 0)) != 0) - goto err; - } else { - if ((ret = __fop_dbrename(dbp, old, newname)) != 0) - goto err; - } - - /* - * I am pretty sure that we haven't gotten a dbreg id, so calling - * dbreg_filelist_update is not necessary. - */ - DB_ASSERT(dbp->log_filename == NULL || - dbp->log_filename->id == DB_LOGFILEID_INVALID); - - DB_TEST_RECOVERY(dbp, DB_TEST_POSTDESTROY, ret, newname); - -DB_TEST_RECOVERY_LABEL -err: if (!F_ISSET(dbp, DB_AM_INMEM) && real_name != NULL) - __os_free(dbenv, real_name); - - return (ret); -} - -/* - * __db_subdb_rename -- - * Rename a subdatabase. - */ -static int -__db_subdb_rename(dbp, txn, name, subdb, newname) - DB *dbp; - DB_TXN *txn; - const char *name, *subdb, *newname; -{ - DB *mdbp; - DB_ENV *dbenv; - PAGE *meta; - int ret, t_ret; - - mdbp = NULL; - meta = NULL; - dbenv = dbp->dbenv; - - /* - * We have not opened this dbp so it isn't marked as a subdb, - * but it ought to be. - */ - F_SET(dbp, DB_AM_SUBDB); - - /* - * Rename the entry in the main database. We need to first - * get the meta-data page number (via MU_OPEN) so that we can - * read the meta-data page and obtain a handle lock. Once we've - * done that, we can proceed to do the rename in the master. - */ - if ((ret = __db_master_open(dbp, txn, name, 0, 0, &mdbp)) != 0) - goto err; - - if ((ret = __db_master_update(mdbp, dbp, txn, subdb, dbp->type, - MU_OPEN, NULL, 0)) != 0) - goto err; - - if ((ret = __memp_fget(mdbp->mpf, &dbp->meta_pgno, 0, &meta)) != 0) - goto err; - memcpy(dbp->fileid, ((DBMETA *)meta)->uid, DB_FILE_ID_LEN); - if ((ret = __fop_lock_handle(dbenv, - dbp, mdbp->lid, DB_LOCK_WRITE, NULL, NOWAIT_FLAG(txn))) != 0) - goto err; - - ret = __memp_fput(mdbp->mpf, meta, 0); - meta = NULL; - if (ret != 0) - goto err; - - if ((ret = __db_master_update(mdbp, dbp, txn, - subdb, dbp->type, MU_RENAME, newname, 0)) != 0) - goto err; - - DB_TEST_RECOVERY(dbp, DB_TEST_POSTDESTROY, ret, name); - -DB_TEST_RECOVERY_LABEL -err: - if (meta != NULL && - (t_ret = __memp_fput(mdbp->mpf, meta, 0)) != 0 && ret == 0) - ret = t_ret; - - if (mdbp != NULL && - (t_ret = __db_close(mdbp, txn, DB_NOSYNC)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} diff --git a/storage/bdb/db/db_ret.c b/storage/bdb/db/db_ret.c deleted file mode 100644 index 39446ea443c..00000000000 --- a/storage/bdb/db/db_ret.c +++ /dev/null @@ -1,154 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_ret.c,v 12.1 2005/06/16 20:21:14 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_am.h" - -/* - * __db_ret -- - * Build return DBT. - * - * PUBLIC: int __db_ret __P((DB *, - * PUBLIC: PAGE *, u_int32_t, DBT *, void **, u_int32_t *)); - */ -int -__db_ret(dbp, h, indx, dbt, memp, memsize) - DB *dbp; - PAGE *h; - u_int32_t indx; - DBT *dbt; - void **memp; - u_int32_t *memsize; -{ - BKEYDATA *bk; - HOFFPAGE ho; - BOVERFLOW *bo; - u_int32_t len; - u_int8_t *hk; - void *data; - - switch (TYPE(h)) { - case P_HASH: - hk = P_ENTRY(dbp, h, indx); - if (HPAGE_PTYPE(hk) == H_OFFPAGE) { - memcpy(&ho, hk, sizeof(HOFFPAGE)); - return (__db_goff(dbp, dbt, - ho.tlen, ho.pgno, memp, memsize)); - } - len = LEN_HKEYDATA(dbp, h, dbp->pgsize, indx); - data = HKEYDATA_DATA(hk); - break; - case P_LBTREE: - case P_LDUP: - case P_LRECNO: - bk = GET_BKEYDATA(dbp, h, indx); - if (B_TYPE(bk->type) == B_OVERFLOW) { - bo = (BOVERFLOW *)bk; - return (__db_goff(dbp, dbt, - bo->tlen, bo->pgno, memp, memsize)); - } - len = bk->len; - data = bk->data; - break; - default: - return (__db_pgfmt(dbp->dbenv, h->pgno)); - } - - return (__db_retcopy(dbp->dbenv, dbt, data, len, memp, memsize)); -} - -/* - * __db_retcopy -- - * Copy the returned data into the user's DBT, handling special flags. - * - * PUBLIC: int __db_retcopy __P((DB_ENV *, DBT *, - * PUBLIC: void *, u_int32_t, void **, u_int32_t *)); - */ -int -__db_retcopy(dbenv, dbt, data, len, memp, memsize) - DB_ENV *dbenv; - DBT *dbt; - void *data; - u_int32_t len; - void **memp; - u_int32_t *memsize; -{ - int ret; - - ret = 0; - - /* If returning a partial record, reset the length. */ - if (F_ISSET(dbt, DB_DBT_PARTIAL)) { - data = (u_int8_t *)data + dbt->doff; - if (len > dbt->doff) { - len -= dbt->doff; - if (len > dbt->dlen) - len = dbt->dlen; - } else - len = 0; - } - - /* - * Allocate memory to be owned by the application: DB_DBT_MALLOC, - * DB_DBT_REALLOC. - * - * !!! - * We always allocate memory, even if we're copying out 0 bytes. This - * guarantees consistency, i.e., the application can always free memory - * without concern as to how many bytes of the record were requested. - * - * Use the memory specified by the application: DB_DBT_USERMEM. - * - * !!! - * If the length we're going to copy is 0, the application-supplied - * memory pointer is allowed to be NULL. - */ - if (F_ISSET(dbt, DB_DBT_MALLOC)) { - ret = __os_umalloc(dbenv, len, &dbt->data); - } else if (F_ISSET(dbt, DB_DBT_REALLOC)) { - if (dbt->data == NULL || dbt->size == 0 || dbt->size < len) - ret = __os_urealloc(dbenv, len, &dbt->data); - } else if (F_ISSET(dbt, DB_DBT_USERMEM)) { - if (len != 0 && (dbt->data == NULL || dbt->ulen < len)) - ret = DB_BUFFER_SMALL; - } else if (memp == NULL || memsize == NULL) { - ret = EINVAL; - } else { - if (len != 0 && (*memsize == 0 || *memsize < len)) { - if ((ret = __os_realloc(dbenv, len, memp)) == 0) - *memsize = len; - else - *memsize = 0; - } - if (ret == 0) - dbt->data = *memp; - } - - if (ret == 0 && len != 0) - memcpy(dbt->data, data, len); - - /* - * Return the length of the returned record in the DBT size field. - * This satisfies the requirement that if we're using user memory - * and insufficient memory was provided, return the amount necessary - * in the size field. - */ - dbt->size = len; - - return (ret); -} diff --git a/storage/bdb/db/db_setid.c b/storage/bdb/db/db_setid.c deleted file mode 100644 index 4ba3ae9b4d2..00000000000 --- a/storage/bdb/db/db_setid.c +++ /dev/null @@ -1,169 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2000-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_setid.c,v 12.8 2005/10/18 14:17:08 mjc Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/db_swap.h" -#include "dbinc/db_am.h" -#include "dbinc/mp.h" - -static int __env_fileid_reset __P((DB_ENV *, const char *, int)); - -/* - * __env_fileid_reset_pp -- - * DB_ENV->fileid_reset pre/post processing. - * - * PUBLIC: int __env_fileid_reset_pp __P((DB_ENV *, const char *, u_int32_t)); - */ -int -__env_fileid_reset_pp(dbenv, name, flags) - DB_ENV *dbenv; - const char *name; - u_int32_t flags; -{ - DB_THREAD_INFO *ip; - int handle_check, ret, t_ret; - - PANIC_CHECK(dbenv); - ENV_ILLEGAL_BEFORE_OPEN(dbenv, "DB_ENV->fileid_reset"); - - /* - * !!! - * The actual argument checking is simple, do it inline, outside of - * the replication block. - */ - if (flags != 0 && flags != DB_ENCRYPT) - return (__db_ferr(dbenv, "DB_ENV->fileid_reset", 0)); - - ENV_ENTER(dbenv, ip); - - /* Check for replication block. */ - handle_check = IS_ENV_REPLICATED(dbenv); - if (handle_check && (ret = __env_rep_enter(dbenv, 1)) != 0) - goto err; - - ret = __env_fileid_reset(dbenv, name, LF_ISSET(DB_ENCRYPT) ? 1 : 0); - - if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - -err: ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __env_fileid_reset -- - * Reset the file IDs for every database in the file. - */ -static int -__env_fileid_reset(dbenv, name, encrypted) - DB_ENV *dbenv; - const char *name; - int encrypted; -{ - DB *dbp; - DBC *dbcp; - DBT key, data; - DB_MPOOLFILE *mpf; - db_pgno_t pgno; - int t_ret, ret; - void *pagep; - char *real_name; - u_int8_t fileid[DB_FILE_ID_LEN]; - - dbp = NULL; - dbcp = NULL; - real_name = NULL; - - /* Get the real backing file name. */ - if ((ret = - __db_appname(dbenv, DB_APP_DATA, name, 0, NULL, &real_name)) != 0) - return (ret); - - /* Get a new file ID. */ - if ((ret = __os_fileid(dbenv, real_name, 1, fileid)) != 0) - goto err; - - /* Create the DB object. */ - if ((ret = db_create(&dbp, dbenv, 0)) != 0) - goto err; - - /* If configured with a password, the databases are encrypted. */ - if (encrypted && (ret = __db_set_flags(dbp, DB_ENCRYPT)) != 0) - goto err; - - /* - * Open the DB file. - * - * !!! - * Note DB_RDWRMASTER flag, we need to open the master database file - * for writing in this case. - */ - if ((ret = __db_open(dbp, NULL, - name, NULL, DB_UNKNOWN, DB_RDWRMASTER, 0, PGNO_BASE_MD)) != 0) - goto err; - - mpf = dbp->mpf; - - pgno = PGNO_BASE_MD; - if ((ret = __memp_fget(mpf, &pgno, 0, &pagep)) != 0) - goto err; - memcpy(((DBMETA *)pagep)->uid, fileid, DB_FILE_ID_LEN); - if ((ret = __memp_fput(mpf, pagep, DB_MPOOL_DIRTY)) != 0) - goto err; - - /* - * If the database file doesn't support subdatabases, we only have - * to update a single metadata page. Otherwise, we have to open a - * cursor and step through the master database, and update all of - * the subdatabases' metadata pages. - */ - if (!F_ISSET(dbp, DB_AM_SUBDB)) - goto err; - - memset(&key, 0, sizeof(key)); - memset(&data, 0, sizeof(data)); - if ((ret = __db_cursor(dbp, NULL, &dbcp, 0)) != 0) - goto err; - while ((ret = __db_c_get(dbcp, &key, &data, DB_NEXT)) == 0) { - /* - * XXX - * We're handling actual data, not on-page meta-data, so it - * hasn't been converted to/from opposite endian architectures. - * Do it explicitly, now. - */ - memcpy(&pgno, data.data, sizeof(db_pgno_t)); - DB_NTOHL(&pgno); - if ((ret = __memp_fget(mpf, &pgno, 0, &pagep)) != 0) - goto err; - memcpy(((DBMETA *)pagep)->uid, fileid, DB_FILE_ID_LEN); - if ((ret = __memp_fput(mpf, pagep, DB_MPOOL_DIRTY)) != 0) - goto err; - } - if (ret == DB_NOTFOUND) - ret = 0; - -err: if (dbcp != NULL && (t_ret = __db_c_close(dbcp)) != 0 && ret == 0) - ret = t_ret; - if (dbp != NULL && (t_ret = __db_close(dbp, NULL, 0)) != 0 && ret == 0) - ret = t_ret; - if (real_name != NULL) - __os_free(dbenv, real_name); - - return (ret); -} diff --git a/storage/bdb/db/db_setlsn.c b/storage/bdb/db/db_setlsn.c deleted file mode 100644 index ef07fc49925..00000000000 --- a/storage/bdb/db/db_setlsn.c +++ /dev/null @@ -1,116 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2000-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_setlsn.c,v 12.8 2005/10/21 19:17:40 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/db_am.h" -#include "dbinc/mp.h" - -static int __env_lsn_reset __P((DB_ENV *, const char *, int)); - -/* - * __env_lsn_reset_pp -- - * DB_ENV->lsn_reset pre/post processing. - * - * PUBLIC: int __env_lsn_reset_pp __P((DB_ENV *, const char *, u_int32_t)); - */ -int -__env_lsn_reset_pp(dbenv, name, flags) - DB_ENV *dbenv; - const char *name; - u_int32_t flags; -{ - DB_THREAD_INFO *ip; - int handle_check, ret, t_ret; - - PANIC_CHECK(dbenv); - ENV_ILLEGAL_BEFORE_OPEN(dbenv, "DB_ENV->lsn_reset"); - - /* - * !!! - * The actual argument checking is simple, do it inline, outside of - * the replication block. - */ - if (flags != 0 && flags != DB_ENCRYPT) - return (__db_ferr(dbenv, "DB_ENV->lsn_reset", 0)); - - ENV_ENTER(dbenv, ip); - - /* Check for replication block. */ - handle_check = IS_ENV_REPLICATED(dbenv); - if (handle_check && (ret = __env_rep_enter(dbenv, 1)) != 0) - goto err; - - ret = __env_lsn_reset(dbenv, name, LF_ISSET(DB_ENCRYPT) ? 1 : 0); - - if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - -err: ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __env_lsn_reset -- - * Reset the LSNs for every page in the file. - */ -static int -__env_lsn_reset(dbenv, name, encrypted) - DB_ENV *dbenv; - const char *name; - int encrypted; -{ - DB *dbp; - DB_MPOOLFILE *mpf; - PAGE *pagep; - db_pgno_t pgno; - int t_ret, ret; - - /* Create the DB object. */ - if ((ret = db_create(&dbp, dbenv, 0)) != 0) - return (ret); - - /* If configured with a password, the databases are encrypted. */ - if (encrypted && (ret = __db_set_flags(dbp, DB_ENCRYPT)) != 0) - goto err; - - /* - * Open the DB file. - * - * !!! - * Note DB_RDWRMASTER flag, we need to open the master database file - * for writing in this case. - */ - if ((ret = __db_open(dbp, NULL, - name, NULL, DB_UNKNOWN, DB_RDWRMASTER, 0, PGNO_BASE_MD)) != 0) - goto err; - - /* Reset the LSN on every page of the database file. */ - mpf = dbp->mpf; - for (pgno = 0; - (ret = __memp_fget(mpf, &pgno, 0, &pagep)) == 0; ++pgno) { - LSN_NOT_LOGGED(pagep->lsn); - if ((ret = __memp_fput(mpf, pagep, DB_MPOOL_DIRTY)) != 0) - goto err; - } - - if (ret == DB_PAGE_NOTFOUND) - ret = 0; - -err: if ((t_ret = __db_close(dbp, NULL, 0)) != 0 && ret == 0) - ret = t_ret; - return (ret); -} diff --git a/storage/bdb/db/db_stati.c b/storage/bdb/db/db_stati.c deleted file mode 100644 index fb0bf4bee4f..00000000000 --- a/storage/bdb/db/db_stati.c +++ /dev/null @@ -1,514 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_stati.c,v 12.10 2005/11/08 03:13:31 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#if TIME_WITH_SYS_TIME -#include <sys/time.h> -#include <time.h> -#else -#if HAVE_SYS_TIME_H -#include <sys/time.h> -#else -#include <time.h> -#endif -#endif - -#include <string.h> -#endif - -#include "db_int.h" - -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/btree.h" -#include "dbinc/hash.h" -#include "dbinc/qam.h" -#include "dbinc/lock.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" - -#ifdef HAVE_STATISTICS -static int __db_print_all __P((DB *, u_int32_t)); -static int __db_print_citem __P((DBC *)); -static int __db_print_cursor __P((DB *)); -static int __db_print_stats __P((DB *, u_int32_t)); -static int __db_stat_arg __P((DB *, u_int32_t)); - -/* - * __db_stat_pp -- - * DB->stat pre/post processing. - * - * PUBLIC: int __db_stat_pp __P((DB *, DB_TXN *, void *, u_int32_t)); - */ -int -__db_stat_pp(dbp, txn, spp, flags) - DB *dbp; - DB_TXN *txn; - void *spp; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int handle_check, ret, t_ret; - - dbenv = dbp->dbenv; - - PANIC_CHECK(dbp->dbenv); - DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->stat"); - - if ((ret = __db_stat_arg(dbp, flags)) != 0) - return (ret); - - ENV_ENTER(dbenv, ip); - - /* Check for replication block. */ - handle_check = IS_ENV_REPLICATED(dbenv); - if (handle_check && (ret = __db_rep_enter(dbp, 1, 0, 0)) != 0) { - handle_check = 0; - goto err; - } - - ret = __db_stat(dbp, txn, spp, flags); - - /* Release replication block. */ - if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - -err: ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __db_stat -- - * DB->stat. - * - * PUBLIC: int __db_stat __P((DB *, DB_TXN *, void *, u_int32_t)); - */ -int -__db_stat(dbp, txn, spp, flags) - DB *dbp; - DB_TXN *txn; - void *spp; - u_int32_t flags; -{ - DB_ENV *dbenv; - DBC *dbc; - int ret, t_ret; - - dbenv = dbp->dbenv; - - /* Acquire a cursor. */ - if ((ret = __db_cursor(dbp, txn, - &dbc, LF_ISSET(DB_READ_COMMITTED | DB_READ_UNCOMMITTED))) != 0) - return (ret); - - DEBUG_LWRITE(dbc, NULL, "DB->stat", NULL, NULL, flags); - LF_CLR(DB_READ_COMMITTED | DB_READ_UNCOMMITTED); - - switch (dbp->type) { - case DB_BTREE: - case DB_RECNO: - ret = __bam_stat(dbc, spp, flags); - break; - case DB_HASH: - ret = __ham_stat(dbc, spp, flags); - break; - case DB_QUEUE: - ret = __qam_stat(dbc, spp, flags); - break; - case DB_UNKNOWN: - default: - ret = (__db_unknown_type(dbenv, "DB->stat", dbp->type)); - break; - } - - if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __db_stat_arg -- - * Check DB->stat arguments. - */ -static int -__db_stat_arg(dbp, flags) - DB *dbp; - u_int32_t flags; -{ - DB_ENV *dbenv; - - dbenv = dbp->dbenv; - - /* Check for invalid function flags. */ - LF_CLR(DB_READ_COMMITTED | DB_READ_UNCOMMITTED); - switch (flags) { - case 0: - case DB_FAST_STAT: - case DB_CACHED_COUNTS: /* Deprecated and undocumented. */ - break; - case DB_RECORDCOUNT: /* Deprecated and undocumented. */ - if (dbp->type == DB_RECNO) - break; - if (dbp->type == DB_BTREE && F_ISSET(dbp, DB_AM_RECNUM)) - break; - /* FALLTHROUGH */ - default: - return (__db_ferr(dbenv, "DB->stat", 0)); - } - - return (0); -} - -/* - * __db_stat_print_pp -- - * DB->stat_print pre/post processing. - * - * PUBLIC: int __db_stat_print_pp __P((DB *, u_int32_t)); - */ -int -__db_stat_print_pp(dbp, flags) - DB *dbp; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int handle_check, ret, t_ret; - - dbenv = dbp->dbenv; - - PANIC_CHECK(dbenv); - DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->stat"); - - /* - * !!! - * The actual argument checking is simple, do it inline. - */ - if ((ret = __db_fchk(dbenv, - "DB->stat_print", flags, DB_FAST_STAT | DB_STAT_ALL)) != 0) - return (ret); - - ENV_ENTER(dbenv, ip); - - /* Check for replication block. */ - handle_check = IS_ENV_REPLICATED(dbenv); - if (handle_check && (ret = __db_rep_enter(dbp, 1, 0, 0)) != 0) { - handle_check = 0; - goto err; - } - - ret = __db_stat_print(dbp, flags); - - /* Release replication block. */ - if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - -err: ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __db_stat_print -- - * DB->stat_print. - * - * PUBLIC: int __db_stat_print __P((DB *, u_int32_t)); - */ -int -__db_stat_print(dbp, flags) - DB *dbp; - u_int32_t flags; -{ - int ret; - time_t now; - - (void)time(&now); - __db_msg(dbp->dbenv, "%.24s\tLocal time", ctime(&now)); - - if (LF_ISSET(DB_STAT_ALL) && (ret = __db_print_all(dbp, flags)) != 0) - return (ret); - - if ((ret = __db_print_stats(dbp, flags)) != 0) - return (ret); - - return (0); -} - -/* - * __db_print_stats -- - * Display default DB handle statistics. - */ -static int -__db_print_stats(dbp, flags) - DB *dbp; - u_int32_t flags; -{ - DBC *dbc; - DB_ENV *dbenv; - int ret, t_ret; - - dbenv = dbp->dbenv; - - /* Acquire a cursor. */ - if ((ret = __db_cursor(dbp, NULL, &dbc, 0)) != 0) - return (ret); - - DEBUG_LWRITE(dbc, NULL, "DB->stat_print", NULL, NULL, 0); - - switch (dbp->type) { - case DB_BTREE: - case DB_RECNO: - ret = __bam_stat_print(dbc, flags); - break; - case DB_HASH: - ret = __ham_stat_print(dbc, flags); - break; - case DB_QUEUE: - ret = __qam_stat_print(dbc, flags); - break; - case DB_UNKNOWN: - default: - ret = (__db_unknown_type(dbenv, "DB->stat_print", dbp->type)); - break; - } - - if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __db_print_all -- - * Display debugging DB handle statistics. - */ -static int -__db_print_all(dbp, flags) - DB *dbp; - u_int32_t flags; -{ - static const FN fn[] = { - { DB_AM_CHKSUM, "DB_AM_CHKSUM" }, - { DB_AM_CL_WRITER, "DB_AM_CL_WRITER" }, - { DB_AM_COMPENSATE, "DB_AM_COMPENSATE" }, - { DB_AM_CREATED, "DB_AM_CREATED" }, - { DB_AM_CREATED_MSTR, "DB_AM_CREATED_MSTR" }, - { DB_AM_DBM_ERROR, "DB_AM_DBM_ERROR" }, - { DB_AM_DELIMITER, "DB_AM_DELIMITER" }, - { DB_AM_DISCARD, "DB_AM_DISCARD" }, - { DB_AM_DUP, "DB_AM_DUP" }, - { DB_AM_DUPSORT, "DB_AM_DUPSORT" }, - { DB_AM_ENCRYPT, "DB_AM_ENCRYPT" }, - { DB_AM_FIXEDLEN, "DB_AM_FIXEDLEN" }, - { DB_AM_INMEM, "DB_AM_INMEM" }, - { DB_AM_IN_RENAME, "DB_AM_IN_RENAME" }, - { DB_AM_NOT_DURABLE, "DB_AM_NOT_DURABLE" }, - { DB_AM_OPEN_CALLED, "DB_AM_OPEN_CALLED" }, - { DB_AM_PAD, "DB_AM_PAD" }, - { DB_AM_PGDEF, "DB_AM_PGDEF" }, - { DB_AM_RDONLY, "DB_AM_RDONLY" }, - { DB_AM_READ_UNCOMMITTED, "DB_AM_READ_UNCOMMITTED" }, - { DB_AM_RECNUM, "DB_AM_RECNUM" }, - { DB_AM_RECOVER, "DB_AM_RECOVER" }, - { DB_AM_RENUMBER, "DB_AM_RENUMBER" }, - { DB_AM_REVSPLITOFF, "DB_AM_REVSPLITOFF" }, - { DB_AM_SECONDARY, "DB_AM_SECONDARY" }, - { DB_AM_SNAPSHOT, "DB_AM_SNAPSHOT" }, - { DB_AM_SUBDB, "DB_AM_SUBDB" }, - { DB_AM_SWAP, "DB_AM_SWAP" }, - { DB_AM_TXN, "DB_AM_TXN" }, - { DB_AM_VERIFYING, "DB_AM_VERIFYING" }, - { 0, NULL } - }; - DB_ENV *dbenv; - - dbenv = dbp->dbenv; - - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_msg(dbenv, "DB handle information:"); - STAT_ULONG("Page size", dbp->pgsize); - STAT_ISSET("Append recno", dbp->db_append_recno); - STAT_ISSET("Feedback", dbp->db_feedback); - STAT_ISSET("Dup compare", dbp->dup_compare); - STAT_ISSET("App private", dbp->app_private); - STAT_ISSET("DbEnv", dbp->dbenv); - STAT_STRING("Type", __db_dbtype_to_string(dbp->type)); - - __mutex_print_debug_single(dbenv, "Thread mutex", dbp->mutex, flags); - - STAT_STRING("File", dbp->fname); - STAT_STRING("Database", dbp->dname); - STAT_HEX("Open flags", dbp->open_flags); - - __db_print_fileid(dbenv, dbp->fileid, "\tFile ID"); - - STAT_ULONG("Cursor adjust ID", dbp->adj_fileid); - STAT_ULONG("Meta pgno", dbp->meta_pgno); - STAT_ULONG("Locker ID", dbp->lid); - STAT_ULONG("Handle lock", dbp->cur_lid); - STAT_ULONG("Associate lock", dbp->associate_lid); - STAT_ULONG("RPC remote ID", dbp->cl_id); - - __db_msg(dbenv, - "%.24s\tReplication handle timestamp", - dbp->timestamp == 0 ? "0" : ctime(&dbp->timestamp)); - - STAT_ISSET("Secondary callback", dbp->s_callback); - STAT_ISSET("Primary handle", dbp->s_primary); - - STAT_ISSET("api internal", dbp->api_internal); - STAT_ISSET("Btree/Recno internal", dbp->bt_internal); - STAT_ISSET("Hash internal", dbp->h_internal); - STAT_ISSET("Queue internal", dbp->q_internal); - STAT_ISSET("XA internal", dbp->xa_internal); - - __db_prflags(dbenv, NULL, dbp->flags, fn, NULL, "\tFlags"); - - if (dbp->log_filename == NULL) - STAT_ISSET("File naming information", dbp->log_filename); - else - __dbreg_print_fname(dbenv, dbp->log_filename); - - (void)__db_print_cursor(dbp); - - return (0); -} - -/* - * __db_print_cursor -- - * Display the cursor active and free queues. - */ -static int -__db_print_cursor(dbp) - DB *dbp; -{ - DB_ENV *dbenv; - DBC *dbc; - int ret, t_ret; - - dbenv = dbp->dbenv; - - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_msg(dbenv, "DB handle cursors:"); - - ret = 0; - MUTEX_LOCK(dbp->dbenv, dbp->mutex); - __db_msg(dbenv, "Active queue:"); - for (dbc = TAILQ_FIRST(&dbp->active_queue); - dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) - if ((t_ret = __db_print_citem(dbc)) != 0 && ret == 0) - ret = t_ret; - __db_msg(dbenv, "Join queue:"); - for (dbc = TAILQ_FIRST(&dbp->join_queue); - dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) - if ((t_ret = __db_print_citem(dbc)) != 0 && ret == 0) - ret = t_ret; - __db_msg(dbenv, "Free queue:"); - for (dbc = TAILQ_FIRST(&dbp->free_queue); - dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) - if ((t_ret = __db_print_citem(dbc)) != 0 && ret == 0) - ret = t_ret; - MUTEX_UNLOCK(dbp->dbenv, dbp->mutex); - - return (ret); -} - -static -int __db_print_citem(dbc) - DBC *dbc; -{ - static const FN fn[] = { - { DBC_ACTIVE, "DBC_ACTIVE" }, - { DBC_COMPENSATE, "DBC_COMPENSATE" }, - { DBC_MULTIPLE, "DBC_MULTIPLE" }, - { DBC_MULTIPLE_KEY, "DBC_MULTIPLE_KEY" }, - { DBC_OPD, "DBC_OPD" }, - { DBC_OWN_LID, "DBC_OWN_LID" }, - { DBC_READ_COMMITTED, "DBC_READ_COMMITTED" }, - { DBC_READ_UNCOMMITTED, "DBC_READ_UNCOMMITTED" }, - { DBC_RECOVER, "DBC_RECOVER" }, - { DBC_RMW, "DBC_RMW" }, - { DBC_TRANSIENT, "DBC_TRANSIENT" }, - { DBC_WRITECURSOR, "DBC_WRITECURSOR" }, - { DBC_WRITER, "DBC_WRITER" }, - { 0, NULL } - }; - DB *dbp; - DBC_INTERNAL *cp; - DB_ENV *dbenv; - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - cp = dbc->internal; - - STAT_POINTER("DBC", dbc); - STAT_POINTER("Associated dbp", dbc->dbp); - STAT_POINTER("Associated txn", dbc->txn); - STAT_POINTER("Internal", cp); - STAT_HEX("Default locker ID", - dbc->lref == NULL ? 0 : ((DB_LOCKER *)dbc->lref)->id); - STAT_HEX("Locker", dbc->locker); - STAT_STRING("Type", __db_dbtype_to_string(dbc->dbtype)); - - STAT_POINTER("Off-page duplicate cursor", cp->opd); - STAT_POINTER("Referenced page", cp->page); - STAT_ULONG("Root", cp->root); - STAT_ULONG("Page number", cp->pgno); - STAT_ULONG("Page index", cp->indx); - STAT_STRING("Lock mode", __db_lockmode_to_string(cp->lock_mode)); - __db_prflags(dbenv, NULL, dbc->flags, fn, NULL, "\tFlags"); - - switch (dbc->dbtype) { - case DB_BTREE: - case DB_RECNO: - __bam_print_cursor(dbc); - break; - case DB_HASH: - __ham_print_cursor(dbc); - break; - case DB_UNKNOWN: - DB_ASSERT(dbp->type != DB_UNKNOWN); - /* FALLTHROUGH */ - case DB_QUEUE: - default: - break; - } - return (0); -} - -#else /* !HAVE_STATISTICS */ - -int -__db_stat_pp(dbp, txn, spp, flags) - DB *dbp; - DB_TXN *txn; - void *spp; - u_int32_t flags; -{ - COMPQUIET(spp, NULL); - COMPQUIET(txn, NULL); - COMPQUIET(flags, 0); - - return (__db_stat_not_built(dbp->dbenv)); -} - -int -__db_stat_print_pp(dbp, flags) - DB *dbp; - u_int32_t flags; -{ - COMPQUIET(flags, 0); - - return (__db_stat_not_built(dbp->dbenv)); -} -#endif diff --git a/storage/bdb/db/db_truncate.c b/storage/bdb/db/db_truncate.c deleted file mode 100644 index c6b740969fb..00000000000 --- a/storage/bdb/db/db_truncate.c +++ /dev/null @@ -1,233 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2001-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_truncate.c,v 12.10 2005/10/21 19:22:59 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/btree.h" -#include "dbinc/hash.h" -#include "dbinc/qam.h" -#include "dbinc/lock.h" -#include "dbinc/log.h" -#include "dbinc/txn.h" - -static int __db_cursor_check __P((DB *)); - -/* - * __db_truncate_pp - * DB->truncate pre/post processing. - * - * PUBLIC: int __db_truncate_pp __P((DB *, DB_TXN *, u_int32_t *, u_int32_t)); - */ -int -__db_truncate_pp(dbp, txn, countp, flags) - DB *dbp; - DB_TXN *txn; - u_int32_t *countp, flags; -{ - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int handle_check, ret, t_ret, txn_local; - - dbenv = dbp->dbenv; - txn_local = 0; - handle_check = 0; - - PANIC_CHECK(dbenv); - STRIP_AUTO_COMMIT(flags); - - /* Check for invalid flags. */ - if (F_ISSET(dbp, DB_AM_SECONDARY)) { - __db_err(dbenv, - "DB->truncate forbidden on secondary indices"); - return (EINVAL); - } - if ((ret = __db_fchk(dbenv, "DB->truncate", flags, 0)) != 0) - return (ret); - - ENV_ENTER(dbenv, ip); - - /* - * Make sure there are no active cursors on this db. Since we drop - * pages we cannot really adjust cursors. - */ - if (__db_cursor_check(dbp) != 0) { - __db_err(dbenv, - "DB->truncate not permitted with active cursors"); - goto err; - } - -#if CONFIG_TEST - if (IS_REP_MASTER(dbenv)) - DB_TEST_WAIT(dbenv, dbenv->test_check); -#endif - /* Check for replication block. */ - handle_check = IS_ENV_REPLICATED(dbenv); - if (handle_check && - (ret = __db_rep_enter(dbp, 1, 0, txn != NULL)) != 0) { - handle_check = 0; - goto err; - } - - /* - * Check for changes to a read-only database. - * This must be after the replication block so that we - * cannot race master/client state changes. - */ - if (DB_IS_READONLY(dbp)) { - ret = __db_rdonly(dbenv, "DB->truncate"); - goto err; - } - - /* - * Create local transaction as necessary, check for consistent - * transaction usage. - */ - if (IS_DB_AUTO_COMMIT(dbp, txn)) { - if ((ret = __txn_begin(dbenv, NULL, &txn, 0)) != 0) - goto err; - txn_local = 1; - } - - /* Check for consistent transaction usage. */ - if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 0)) != 0) - goto err; - - ret = __db_truncate(dbp, txn, countp); - -err: if (txn_local && - (t_ret = __db_txn_auto_resolve(dbenv, txn, 0, ret)) && ret == 0) - ret = t_ret; - - /* Release replication block. */ - if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __db_truncate - * DB->truncate. - * - * PUBLIC: int __db_truncate __P((DB *, DB_TXN *, u_int32_t *)); - */ -int -__db_truncate(dbp, txn, countp) - DB *dbp; - DB_TXN *txn; - u_int32_t *countp; -{ - DB *sdbp; - DBC *dbc; - DB_ENV *dbenv; - u_int32_t scount; - int ret, t_ret; - - dbenv = dbp->dbenv; - dbc = NULL; - ret = 0; - - /* - * Run through all secondaries and truncate them first. The count - * returned is the count of the primary only. QUEUE uses normal - * processing to truncate so it will update the secondaries normally. - */ - if (dbp->type != DB_QUEUE && LIST_FIRST(&dbp->s_secondaries) != NULL) { - if ((ret = __db_s_first(dbp, &sdbp)) != 0) - return (ret); - for (; sdbp != NULL && ret == 0; ret = __db_s_next(&sdbp)) - if ((ret = __db_truncate(sdbp, txn, &scount)) != 0) - break; - if (sdbp != NULL) - (void)__db_s_done(sdbp); - if (ret != 0) - return (ret); - } - - DB_TEST_RECOVERY(dbp, DB_TEST_PREDESTROY, ret, NULL); - - /* Acquire a cursor. */ - if ((ret = __db_cursor(dbp, txn, &dbc, 0)) != 0) - return (ret); - - DEBUG_LWRITE(dbc, txn, "DB->truncate", NULL, NULL, 0); - - switch (dbp->type) { - case DB_BTREE: - case DB_RECNO: - ret = __bam_truncate(dbc, countp); - break; - case DB_HASH: - ret = __ham_truncate(dbc, countp); - break; - case DB_QUEUE: - ret = __qam_truncate(dbc, countp); - break; - case DB_UNKNOWN: - default: - ret = __db_unknown_type(dbenv, "DB->truncate", dbp->type); - break; - } - - /* Discard the cursor. */ - if (dbc != NULL && (t_ret = __db_c_close(dbc)) != 0 && ret == 0) - ret = t_ret; - - DB_TEST_RECOVERY(dbp, DB_TEST_POSTDESTROY, ret, NULL); - -DB_TEST_RECOVERY_LABEL - - return (ret); -} - -/* - * __db_cursor_check -- - * See if there are any active cursors on this db. - */ -static int -__db_cursor_check(dbp) - DB *dbp; -{ - DB *ldbp; - DBC *dbc; - DB_ENV *dbenv; - int found; - - dbenv = dbp->dbenv; - - MUTEX_LOCK(dbenv, dbenv->mtx_dblist); - for (found = 0, ldbp = __dblist_get(dbenv, dbp->adj_fileid); - ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid; - ldbp = LIST_NEXT(ldbp, dblistlinks)) { - MUTEX_LOCK(dbenv, dbp->mutex); - for (dbc = TAILQ_FIRST(&ldbp->active_queue); - dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) { - if (IS_INITIALIZED(dbc)) { - found = 1; - break; - } - } - MUTEX_UNLOCK(dbenv, dbp->mutex); - if (found == 1) - break; - } - MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist); - - return (found); -} diff --git a/storage/bdb/db/db_upg.c b/storage/bdb/db/db_upg.c deleted file mode 100644 index 674202d5bb7..00000000000 --- a/storage/bdb/db/db_upg.c +++ /dev/null @@ -1,370 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_upg.c,v 12.1 2005/06/16 20:21:15 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_swap.h" -#include "dbinc/btree.h" -#include "dbinc/hash.h" -#include "dbinc/qam.h" - -static int (* const func_31_list[P_PAGETYPE_MAX]) - __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *)) = { - NULL, /* P_INVALID */ - NULL, /* __P_DUPLICATE */ - __ham_31_hash, /* P_HASH */ - NULL, /* P_IBTREE */ - NULL, /* P_IRECNO */ - __bam_31_lbtree, /* P_LBTREE */ - NULL, /* P_LRECNO */ - NULL, /* P_OVERFLOW */ - __ham_31_hashmeta, /* P_HASHMETA */ - __bam_31_btreemeta, /* P_BTREEMETA */ - NULL, /* P_QAMMETA */ - NULL, /* P_QAMDATA */ - NULL, /* P_LDUP */ -}; - -static int __db_page_pass __P((DB *, char *, u_int32_t, int (* const []) - (DB *, char *, u_int32_t, DB_FH *, PAGE *, int *), DB_FH *)); - -/* - * __db_upgrade_pp -- - * DB->upgrade pre/post processing. - * - * PUBLIC: int __db_upgrade_pp __P((DB *, const char *, u_int32_t)); - */ -int -__db_upgrade_pp(dbp, fname, flags) - DB *dbp; - const char *fname; - u_int32_t flags; -{ - DB_ENV *dbenv; - int ret; - - dbenv = dbp->dbenv; - - PANIC_CHECK(dbp->dbenv); - - /* - * !!! - * The actual argument checking is simple, do it inline. - */ - if ((ret = __db_fchk(dbenv, "DB->upgrade", flags, DB_DUPSORT)) != 0) - return (ret); - - return (__db_upgrade(dbp, fname, flags)); -} - -/* - * __db_upgrade -- - * Upgrade an existing database. - * - * PUBLIC: int __db_upgrade __P((DB *, const char *, u_int32_t)); - */ -int -__db_upgrade(dbp, fname, flags) - DB *dbp; - const char *fname; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_FH *fhp; - size_t n; - int ret, t_ret; - u_int8_t mbuf[256]; - char *real_name; - - dbenv = dbp->dbenv; - fhp = NULL; - - /* Get the real backing file name. */ - if ((ret = __db_appname(dbenv, - DB_APP_DATA, fname, 0, NULL, &real_name)) != 0) - return (ret); - - /* Open the file. */ - if ((ret = __os_open(dbenv, real_name, 0, 0, &fhp)) != 0) { - __db_err(dbenv, "%s: %s", real_name, db_strerror(ret)); - return (ret); - } - - /* Initialize the feedback. */ - if (dbp->db_feedback != NULL) - dbp->db_feedback(dbp, DB_UPGRADE, 0); - - /* - * Read the metadata page. We read 256 bytes, which is larger than - * any access method's metadata page and smaller than any disk sector. - */ - if ((ret = __os_read(dbenv, fhp, mbuf, sizeof(mbuf), &n)) != 0) - goto err; - - switch (((DBMETA *)mbuf)->magic) { - case DB_BTREEMAGIC: - switch (((DBMETA *)mbuf)->version) { - case 6: - /* - * Before V7 not all pages had page types, so we do the - * single meta-data page by hand. - */ - if ((ret = - __bam_30_btreemeta(dbp, real_name, mbuf)) != 0) - goto err; - if ((ret = __os_seek(dbenv, - fhp, 0, 0, 0, 0, DB_OS_SEEK_SET)) != 0) - goto err; - if ((ret = __os_write(dbenv, fhp, mbuf, 256, &n)) != 0) - goto err; - /* FALLTHROUGH */ - case 7: - /* - * We need the page size to do more. Rip it out of - * the meta-data page. - */ - memcpy(&dbp->pgsize, mbuf + 20, sizeof(u_int32_t)); - - if ((ret = __db_page_pass( - dbp, real_name, flags, func_31_list, fhp)) != 0) - goto err; - /* FALLTHROUGH */ - case 8: - case 9: - break; - default: - __db_err(dbenv, "%s: unsupported btree version: %lu", - real_name, (u_long)((DBMETA *)mbuf)->version); - ret = DB_OLD_VERSION; - goto err; - } - break; - case DB_HASHMAGIC: - switch (((DBMETA *)mbuf)->version) { - case 4: - case 5: - /* - * Before V6 not all pages had page types, so we do the - * single meta-data page by hand. - */ - if ((ret = - __ham_30_hashmeta(dbp, real_name, mbuf)) != 0) - goto err; - if ((ret = __os_seek(dbenv, - fhp, 0, 0, 0, 0, DB_OS_SEEK_SET)) != 0) - goto err; - if ((ret = __os_write(dbenv, fhp, mbuf, 256, &n)) != 0) - goto err; - - /* - * Before V6, we created hash pages one by one as they - * were needed, using hashhdr.ovfl_point to reserve - * a block of page numbers for them. A consequence - * of this was that, if no overflow pages had been - * created, the current doubling might extend past - * the end of the database file. - * - * In DB 3.X, we now create all the hash pages - * belonging to a doubling atomically; it's not - * safe to just save them for later, because when - * we create an overflow page we'll just create - * a new last page (whatever that may be). Grow - * the database to the end of the current doubling. - */ - if ((ret = - __ham_30_sizefix(dbp, fhp, real_name, mbuf)) != 0) - goto err; - /* FALLTHROUGH */ - case 6: - /* - * We need the page size to do more. Rip it out of - * the meta-data page. - */ - memcpy(&dbp->pgsize, mbuf + 20, sizeof(u_int32_t)); - - if ((ret = __db_page_pass( - dbp, real_name, flags, func_31_list, fhp)) != 0) - goto err; - /* FALLTHROUGH */ - case 7: - case 8: - break; - default: - __db_err(dbenv, "%s: unsupported hash version: %lu", - real_name, (u_long)((DBMETA *)mbuf)->version); - ret = DB_OLD_VERSION; - goto err; - } - break; - case DB_QAMMAGIC: - switch (((DBMETA *)mbuf)->version) { - case 1: - /* - * If we're in a Queue database, the only page that - * needs upgrading is the meta-database page, don't - * bother with a full pass. - */ - if ((ret = __qam_31_qammeta(dbp, real_name, mbuf)) != 0) - return (ret); - /* FALLTHROUGH */ - case 2: - if ((ret = __qam_32_qammeta(dbp, real_name, mbuf)) != 0) - return (ret); - if ((ret = __os_seek(dbenv, - fhp, 0, 0, 0, 0, DB_OS_SEEK_SET)) != 0) - goto err; - if ((ret = __os_write(dbenv, fhp, mbuf, 256, &n)) != 0) - goto err; - /* FALLTHROUGH */ - case 3: - case 4: - break; - default: - __db_err(dbenv, "%s: unsupported queue version: %lu", - real_name, (u_long)((DBMETA *)mbuf)->version); - ret = DB_OLD_VERSION; - goto err; - } - break; - default: - M_32_SWAP(((DBMETA *)mbuf)->magic); - switch (((DBMETA *)mbuf)->magic) { - case DB_BTREEMAGIC: - case DB_HASHMAGIC: - case DB_QAMMAGIC: - __db_err(dbenv, - "%s: DB->upgrade only supported on native byte-order systems", - real_name); - break; - default: - __db_err(dbenv, - "%s: unrecognized file type", real_name); - break; - } - ret = EINVAL; - goto err; - } - - ret = __os_fsync(dbenv, fhp); - -err: if (fhp != NULL && - (t_ret = __os_closehandle(dbenv, fhp)) != 0 && ret == 0) - ret = t_ret; - __os_free(dbenv, real_name); - - /* We're done. */ - if (dbp->db_feedback != NULL) - dbp->db_feedback(dbp, DB_UPGRADE, 100); - - return (ret); -} - -/* - * __db_page_pass -- - * Walk the pages of the database, upgrading whatever needs it. - */ -static int -__db_page_pass(dbp, real_name, flags, fl, fhp) - DB *dbp; - char *real_name; - u_int32_t flags; - int (* const fl[P_PAGETYPE_MAX]) - __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *)); - DB_FH *fhp; -{ - DB_ENV *dbenv; - PAGE *page; - db_pgno_t i, pgno_last; - size_t n; - int dirty, ret; - - dbenv = dbp->dbenv; - - /* Determine the last page of the file. */ - if ((ret = __db_lastpgno(dbp, real_name, fhp, &pgno_last)) != 0) - return (ret); - - /* Allocate memory for a single page. */ - if ((ret = __os_malloc(dbenv, dbp->pgsize, &page)) != 0) - return (ret); - - /* Walk the file, calling the underlying conversion functions. */ - for (i = 0; i < pgno_last; ++i) { - if (dbp->db_feedback != NULL) - dbp->db_feedback( - dbp, DB_UPGRADE, (int)((i * 100)/pgno_last)); - if ((ret = __os_seek(dbenv, - fhp, dbp->pgsize, i, 0, 0, DB_OS_SEEK_SET)) != 0) - break; - if ((ret = __os_read(dbenv, fhp, page, dbp->pgsize, &n)) != 0) - break; - dirty = 0; - if (fl[TYPE(page)] != NULL && (ret = fl[TYPE(page)] - (dbp, real_name, flags, fhp, page, &dirty)) != 0) - break; - if (dirty) { - if ((ret = __os_seek(dbenv, - fhp, dbp->pgsize, i, 0, 0, DB_OS_SEEK_SET)) != 0) - break; - if ((ret = __os_write(dbenv, - fhp, page, dbp->pgsize, &n)) != 0) - break; - } - } - - __os_free(dbp->dbenv, page); - return (ret); -} - -/* - * __db_lastpgno -- - * Return the current last page number of the file. - * - * PUBLIC: int __db_lastpgno __P((DB *, char *, DB_FH *, db_pgno_t *)); - */ -int -__db_lastpgno(dbp, real_name, fhp, pgno_lastp) - DB *dbp; - char *real_name; - DB_FH *fhp; - db_pgno_t *pgno_lastp; -{ - DB_ENV *dbenv; - db_pgno_t pgno_last; - u_int32_t mbytes, bytes; - int ret; - - dbenv = dbp->dbenv; - - if ((ret = __os_ioinfo(dbenv, - real_name, fhp, &mbytes, &bytes, NULL)) != 0) { - __db_err(dbenv, "%s: %s", real_name, db_strerror(ret)); - return (ret); - } - - /* Page sizes have to be a power-of-two. */ - if (bytes % dbp->pgsize != 0) { - __db_err(dbenv, - "%s: file size not a multiple of the pagesize", real_name); - return (EINVAL); - } - pgno_last = mbytes * (MEGABYTE / dbp->pgsize); - pgno_last += bytes / dbp->pgsize; - - *pgno_lastp = pgno_last; - return (0); -} diff --git a/storage/bdb/db/db_upg_opd.c b/storage/bdb/db/db_upg_opd.c deleted file mode 100644 index 23838be9ca8..00000000000 --- a/storage/bdb/db/db_upg_opd.c +++ /dev/null @@ -1,350 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_upg_opd.c,v 12.1 2005/06/16 20:21:15 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/btree.h" - -static int __db_build_bi __P((DB *, DB_FH *, PAGE *, PAGE *, u_int32_t, int *)); -static int __db_build_ri __P((DB *, DB_FH *, PAGE *, PAGE *, u_int32_t, int *)); -static int __db_up_ovref __P((DB *, DB_FH *, db_pgno_t)); - -#define GET_PAGE(dbp, fhp, pgno, page) { \ - if ((ret = __os_seek(dbp->dbenv, \ - fhp, (dbp)->pgsize, pgno, 0, 0, DB_OS_SEEK_SET)) != 0) \ - goto err; \ - if ((ret = __os_read(dbp->dbenv, \ - fhp, page, (dbp)->pgsize, &n)) != 0) \ - goto err; \ -} -#define PUT_PAGE(dbp, fhp, pgno, page) { \ - if ((ret = __os_seek(dbp->dbenv, \ - fhp, (dbp)->pgsize, pgno, 0, 0, DB_OS_SEEK_SET)) != 0) \ - goto err; \ - if ((ret = __os_write(dbp->dbenv, \ - fhp, page, (dbp)->pgsize, &n)) != 0) \ - goto err; \ -} - -/* - * __db_31_offdup -- - * Convert 3.0 off-page duplicates to 3.1 off-page duplicates. - * - * PUBLIC: int __db_31_offdup __P((DB *, char *, DB_FH *, int, db_pgno_t *)); - */ -int -__db_31_offdup(dbp, real_name, fhp, sorted, pgnop) - DB *dbp; - char *real_name; - DB_FH *fhp; - int sorted; - db_pgno_t *pgnop; -{ - PAGE *ipage, *page; - db_indx_t indx; - db_pgno_t cur_cnt, i, next_cnt, pgno, *pgno_cur, pgno_last; - db_pgno_t *pgno_next, pgno_max, *tmp; - db_recno_t nrecs; - size_t n; - int level, nomem, ret; - - ipage = page = NULL; - pgno_cur = pgno_next = NULL; - - /* Allocate room to hold a page. */ - if ((ret = __os_malloc(dbp->dbenv, dbp->pgsize, &page)) != 0) - goto err; - - /* - * Walk the chain of 3.0 off-page duplicates. Each one is converted - * in place to a 3.1 off-page duplicate page. If the duplicates are - * sorted, they are converted to a Btree leaf page, otherwise to a - * Recno leaf page. - */ - for (nrecs = 0, cur_cnt = pgno_max = 0, - pgno = *pgnop; pgno != PGNO_INVALID;) { - if (pgno_max == cur_cnt) { - pgno_max += 20; - if ((ret = __os_realloc(dbp->dbenv, pgno_max * - sizeof(db_pgno_t), &pgno_cur)) != 0) - goto err; - } - pgno_cur[cur_cnt++] = pgno; - - GET_PAGE(dbp, fhp, pgno, page); - nrecs += NUM_ENT(page); - LEVEL(page) = LEAFLEVEL; - TYPE(page) = sorted ? P_LDUP : P_LRECNO; - /* - * !!! - * DB didn't zero the LSNs on off-page duplicates pages. - */ - ZERO_LSN(LSN(page)); - PUT_PAGE(dbp, fhp, pgno, page); - - pgno = NEXT_PGNO(page); - } - - /* If we only have a single page, it's easy. */ - if (cur_cnt <= 1) - goto done; - - /* - * pgno_cur is the list of pages we just converted. We're - * going to walk that list, but we'll need to create a new - * list while we do so. - */ - if ((ret = __os_malloc(dbp->dbenv, - cur_cnt * sizeof(db_pgno_t), &pgno_next)) != 0) - goto err; - - /* Figure out where we can start allocating new pages. */ - if ((ret = __db_lastpgno(dbp, real_name, fhp, &pgno_last)) != 0) - goto err; - - /* Allocate room for an internal page. */ - if ((ret = __os_malloc(dbp->dbenv, dbp->pgsize, &ipage)) != 0) - goto err; - PGNO(ipage) = PGNO_INVALID; - - /* - * Repeatedly walk the list of pages, building internal pages, until - * there's only one page at a level. - */ - for (level = LEAFLEVEL + 1; cur_cnt > 1; ++level) { - for (indx = 0, i = next_cnt = 0; i < cur_cnt;) { - if (indx == 0) { - P_INIT(ipage, dbp->pgsize, pgno_last, - PGNO_INVALID, PGNO_INVALID, - level, sorted ? P_IBTREE : P_IRECNO); - ZERO_LSN(LSN(ipage)); - - pgno_next[next_cnt++] = pgno_last++; - } - - GET_PAGE(dbp, fhp, pgno_cur[i], page); - - /* - * If the duplicates are sorted, put the first item on - * the lower-level page onto a Btree internal page. If - * the duplicates are not sorted, create an internal - * Recno structure on the page. If either case doesn't - * fit, push out the current page and start a new one. - */ - nomem = 0; - if (sorted) { - if ((ret = __db_build_bi( - dbp, fhp, ipage, page, indx, &nomem)) != 0) - goto err; - } else - if ((ret = __db_build_ri( - dbp, fhp, ipage, page, indx, &nomem)) != 0) - goto err; - if (nomem) { - indx = 0; - PUT_PAGE(dbp, fhp, PGNO(ipage), ipage); - } else { - ++indx; - ++NUM_ENT(ipage); - ++i; - } - } - - /* - * Push out the last internal page. Set the top-level record - * count if we've reached the top. - */ - if (next_cnt == 1) - RE_NREC_SET(ipage, nrecs); - PUT_PAGE(dbp, fhp, PGNO(ipage), ipage); - - /* Swap the current and next page number arrays. */ - cur_cnt = next_cnt; - tmp = pgno_cur; - pgno_cur = pgno_next; - pgno_next = tmp; - } - -done: *pgnop = pgno_cur[0]; - -err: if (pgno_cur != NULL) - __os_free(dbp->dbenv, pgno_cur); - if (pgno_next != NULL) - __os_free(dbp->dbenv, pgno_next); - if (ipage != NULL) - __os_free(dbp->dbenv, ipage); - if (page != NULL) - __os_free(dbp->dbenv, page); - - return (ret); -} - -/* - * __db_build_bi -- - * Build a BINTERNAL entry for a parent page. - */ -static int -__db_build_bi(dbp, fhp, ipage, page, indx, nomemp) - DB *dbp; - DB_FH *fhp; - PAGE *ipage, *page; - u_int32_t indx; - int *nomemp; -{ - BINTERNAL bi, *child_bi; - BKEYDATA *child_bk; - u_int8_t *p; - int ret; - db_indx_t *inp; - - inp = P_INP(dbp, ipage); - switch (TYPE(page)) { - case P_IBTREE: - child_bi = GET_BINTERNAL(dbp, page, 0); - if (P_FREESPACE(dbp, ipage) < BINTERNAL_PSIZE(child_bi->len)) { - *nomemp = 1; - return (0); - } - inp[indx] = - HOFFSET(ipage) -= BINTERNAL_SIZE(child_bi->len); - p = P_ENTRY(dbp, ipage, indx); - - bi.len = child_bi->len; - B_TSET(bi.type, child_bi->type, 0); - bi.pgno = PGNO(page); - bi.nrecs = __bam_total(dbp, page); - memcpy(p, &bi, SSZA(BINTERNAL, data)); - p += SSZA(BINTERNAL, data); - memcpy(p, child_bi->data, child_bi->len); - - /* Increment the overflow ref count. */ - if (B_TYPE(child_bi->type) == B_OVERFLOW) - if ((ret = __db_up_ovref(dbp, fhp, - ((BOVERFLOW *)(child_bi->data))->pgno)) != 0) - return (ret); - break; - case P_LDUP: - child_bk = GET_BKEYDATA(dbp, page, 0); - switch (B_TYPE(child_bk->type)) { - case B_KEYDATA: - if (P_FREESPACE(dbp, ipage) < - BINTERNAL_PSIZE(child_bk->len)) { - *nomemp = 1; - return (0); - } - inp[indx] = - HOFFSET(ipage) -= BINTERNAL_SIZE(child_bk->len); - p = P_ENTRY(dbp, ipage, indx); - - bi.len = child_bk->len; - B_TSET(bi.type, child_bk->type, 0); - bi.pgno = PGNO(page); - bi.nrecs = __bam_total(dbp, page); - memcpy(p, &bi, SSZA(BINTERNAL, data)); - p += SSZA(BINTERNAL, data); - memcpy(p, child_bk->data, child_bk->len); - break; - case B_OVERFLOW: - if (P_FREESPACE(dbp, ipage) < - BINTERNAL_PSIZE(BOVERFLOW_SIZE)) { - *nomemp = 1; - return (0); - } - inp[indx] = - HOFFSET(ipage) -= BINTERNAL_SIZE(BOVERFLOW_SIZE); - p = P_ENTRY(dbp, ipage, indx); - - bi.len = BOVERFLOW_SIZE; - B_TSET(bi.type, child_bk->type, 0); - bi.pgno = PGNO(page); - bi.nrecs = __bam_total(dbp, page); - memcpy(p, &bi, SSZA(BINTERNAL, data)); - p += SSZA(BINTERNAL, data); - memcpy(p, child_bk, BOVERFLOW_SIZE); - - /* Increment the overflow ref count. */ - if ((ret = __db_up_ovref(dbp, fhp, - ((BOVERFLOW *)child_bk)->pgno)) != 0) - return (ret); - break; - default: - return (__db_pgfmt(dbp->dbenv, PGNO(page))); - } - break; - default: - return (__db_pgfmt(dbp->dbenv, PGNO(page))); - } - - return (0); -} - -/* - * __db_build_ri -- - * Build a RINTERNAL entry for an internal parent page. - */ -static int -__db_build_ri(dbp, fhp, ipage, page, indx, nomemp) - DB *dbp; - DB_FH *fhp; - PAGE *ipage, *page; - u_int32_t indx; - int *nomemp; -{ - RINTERNAL ri; - db_indx_t *inp; - - COMPQUIET(fhp, NULL); - inp = P_INP(dbp, ipage); - if (P_FREESPACE(dbp, ipage) < RINTERNAL_PSIZE) { - *nomemp = 1; - return (0); - } - - ri.pgno = PGNO(page); - ri.nrecs = __bam_total(dbp, page); - inp[indx] = HOFFSET(ipage) -= RINTERNAL_SIZE; - memcpy(P_ENTRY(dbp, ipage, indx), &ri, RINTERNAL_SIZE); - - return (0); -} - -/* - * __db_up_ovref -- - * Increment/decrement the reference count on an overflow page. - */ -static int -__db_up_ovref(dbp, fhp, pgno) - DB *dbp; - DB_FH *fhp; - db_pgno_t pgno; -{ - PAGE *page; - size_t n; - int ret; - - /* Allocate room to hold a page. */ - if ((ret = __os_malloc(dbp->dbenv, dbp->pgsize, &page)) != 0) - return (ret); - - GET_PAGE(dbp, fhp, pgno, page); - ++OV_REF(page); - PUT_PAGE(dbp, fhp, pgno, page); - -err: __os_free(dbp->dbenv, page); - - return (ret); -} diff --git a/storage/bdb/db/db_vrfy.c b/storage/bdb/db/db_vrfy.c deleted file mode 100644 index 4f33e451099..00000000000 --- a/storage/bdb/db/db_vrfy.c +++ /dev/null @@ -1,2592 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2000-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_vrfy.c,v 12.14 2005/10/07 16:49:47 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/db_swap.h" -#include "dbinc/db_verify.h" -#include "dbinc/btree.h" -#include "dbinc/hash.h" -#include "dbinc/lock.h" -#include "dbinc/mp.h" -#include "dbinc/qam.h" -#include "dbinc/txn.h" - -/* - * This is the code for DB->verify, the DB database consistency checker. - * For now, it checks all subdatabases in a database, and verifies - * everything it knows how to (i.e. it's all-or-nothing, and one can't - * check only for a subset of possible problems). - */ - -static u_int __db_guesspgsize __P((DB_ENV *, DB_FH *)); -static int __db_is_valid_magicno __P((u_int32_t, DBTYPE *)); -static int __db_is_valid_pagetype __P((u_int32_t)); -static int __db_meta2pgset - __P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t, DB *)); -static int __db_salvage_subdbpg __P((DB *, VRFY_DBINFO *, - PAGE *, void *, int (*)(void *, const void *), u_int32_t)); -static int __db_salvage_subdbs __P((DB *, VRFY_DBINFO *, void *, - int(*)(void *, const void *), u_int32_t, int *)); -static int __db_salvage_unknowns __P((DB *, VRFY_DBINFO *, void *, - int (*)(void *, const void *), u_int32_t)); -static int __db_verify __P((DB *, const char *, const char *, - void *, int (*)(void *, const void *), u_int32_t)); -static int __db_verify_arg __P((DB *, const char *, void *, u_int32_t)); -static int __db_vrfy_freelist - __P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t)); -static int __db_vrfy_invalid - __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, u_int32_t)); -static int __db_vrfy_orderchkonly __P((DB *, - VRFY_DBINFO *, const char *, const char *, u_int32_t)); -static int __db_vrfy_pagezero __P((DB *, VRFY_DBINFO *, DB_FH *, u_int32_t)); -static int __db_vrfy_subdbs - __P((DB *, VRFY_DBINFO *, const char *, u_int32_t)); -static int __db_vrfy_structure - __P((DB *, VRFY_DBINFO *, const char *, db_pgno_t, u_int32_t)); -static int __db_vrfy_walkpages __P((DB *, VRFY_DBINFO *, - void *, int (*)(void *, const void *), u_int32_t)); - -#define VERIFY_FLAGS \ - (DB_AGGRESSIVE | \ - DB_NOORDERCHK | DB_ORDERCHKONLY | DB_PRINTABLE | DB_SALVAGE | DB_UNREF) - -/* - * __db_verify_pp -- - * DB->verify public interface. - * - * PUBLIC: int __db_verify_pp - * PUBLIC: __P((DB *, const char *, const char *, FILE *, u_int32_t)); - */ -int -__db_verify_pp(dbp, file, database, outfile, flags) - DB *dbp; - const char *file, *database; - FILE *outfile; - u_int32_t flags; -{ - /* - * __db_verify_pp is a wrapper to __db_verify_internal, which lets - * us pass appropriate equivalents to FILE * in from the non-C APIs. - */ - return (__db_verify_internal(dbp, - file, database, outfile, __db_pr_callback, flags)); -} - -/* - * __db_verify_internal -- - * - * PUBLIC: int __db_verify_internal __P((DB *, const char *, - * PUBLIC: const char *, void *, int (*)(void *, const void *), u_int32_t)); - */ -int -__db_verify_internal(dbp, fname, dname, handle, callback, flags) - DB *dbp; - const char *fname, *dname; - void *handle; - int (*callback) __P((void *, const void *)); - u_int32_t flags; -{ - DB_ENV *dbenv; - int ret, t_ret; - - dbenv = dbp->dbenv; - - PANIC_CHECK(dbenv); - DB_ILLEGAL_AFTER_OPEN(dbp, "DB->verify"); - -#ifdef HAVE_FTRUNCATE - /* - * If we're using ftruncate to abort page-allocation functions, there - * should never be unreferenced pages. Always check for unreferenced - * pages on those systems. - */ - if (!LF_ISSET(DB_SALVAGE)) - LF_SET(DB_UNREF); -#endif - - if ((ret = __db_verify_arg(dbp, dname, handle, flags)) == 0) - ret = __db_verify(dbp, fname, dname, handle, callback, flags); - - /* Db.verify is a DB handle destructor. */ - if ((t_ret = __db_close(dbp, NULL, 0)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __db_verify_arg -- - * Check DB->verify arguments. - */ -static int -__db_verify_arg(dbp, dname, handle, flags) - DB *dbp; - const char *dname; - void *handle; - u_int32_t flags; -{ - DB_ENV *dbenv; - int ret; - - dbenv = dbp->dbenv; - - if ((ret = __db_fchk(dbenv, "DB->verify", flags, VERIFY_FLAGS)) != 0) - return (ret); - - /* - * DB_SALVAGE is mutually exclusive with the other flags except - * DB_AGGRESSIVE, DB_PRINTABLE. - * - * DB_AGGRESSIVE and DB_PRINTABLE are only meaningful when salvaging. - * - * DB_SALVAGE requires an output stream. - */ - if (LF_ISSET(DB_SALVAGE)) { - if (LF_ISSET(~(DB_AGGRESSIVE | DB_PRINTABLE | DB_SALVAGE))) - return (__db_ferr(dbenv, "DB->verify", 1)); - if (handle == NULL) { - __db_err(dbenv, - "DB_SALVAGE requires a an output handle"); - return (EINVAL); - } - } else - if (LF_ISSET(DB_AGGRESSIVE | DB_PRINTABLE)) - return (__db_ferr(dbenv, "DB->verify", 1)); - - /* - * DB_ORDERCHKONLY is mutually exclusive with DB_SALVAGE and - * DB_NOORDERCHK, and requires a database name. - */ - if ((ret = __db_fcchk(dbenv, "DB->verify", flags, - DB_ORDERCHKONLY, DB_SALVAGE | DB_NOORDERCHK)) != 0) - return (ret); - if (LF_ISSET(DB_ORDERCHKONLY) && dname == NULL) { - __db_err(dbenv, "DB_ORDERCHKONLY requires a database name"); - return (EINVAL); - } - return (0); -} - -/* - * __db_verify -- - * Walk the entire file page-by-page, either verifying with or without - * dumping in db_dump -d format, or DB_SALVAGE-ing whatever key/data - * pairs can be found and dumping them in standard (db_load-ready) - * dump format. - * - * (Salvaging isn't really a verification operation, but we put it - * here anyway because it requires essentially identical top-level - * code.) - * - * flags may be 0, DB_NOORDERCHK, DB_ORDERCHKONLY, or DB_SALVAGE - * (and optionally DB_AGGRESSIVE). - */ -static int -__db_verify(dbp, name, subdb, handle, callback, flags) - DB *dbp; - const char *name, *subdb; - void *handle; - int (*callback) __P((void *, const void *)); - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_FH *fhp; - VRFY_DBINFO *vdp; - int has_subdbs, isbad, ret, t_ret; - char *real_name; - - dbenv = dbp->dbenv; - fhp = NULL; - vdp = NULL; - real_name = NULL; - has_subdbs = isbad = ret = 0; - - F_SET(dbp, DB_AM_VERIFYING); - - /* Initialize any feedback function. */ - if (!LF_ISSET(DB_SALVAGE) && dbp->db_feedback != NULL) - dbp->db_feedback(dbp, DB_VERIFY, 0); - - /* - * We don't know how large the cache is, and if the database - * in question uses a small page size--which we don't know - * yet!--it may be uncomfortably small for the default page - * size [#2143]. However, the things we need temporary - * databases for in dbinfo are largely tiny, so using a - * 1024-byte pagesize is probably not going to be a big hit, - * and will make us fit better into small spaces. - */ - if ((ret = __db_vrfy_dbinfo_create(dbenv, 1024, &vdp)) != 0) - goto err; - - /* - * Note whether the user has requested that we use printable - * chars where possible. We won't get here with this flag if - * we're not salvaging. - */ - if (LF_ISSET(DB_PRINTABLE)) - F_SET(vdp, SALVAGE_PRINTABLE); - - /* Find the real name of the file. */ - if ((ret = __db_appname(dbenv, - DB_APP_DATA, name, 0, NULL, &real_name)) != 0) - goto err; - - /* - * Our first order of business is to verify page 0, which is - * the metadata page for the master database of subdatabases - * or of the only database in the file. We want to do this by hand - * rather than just calling __db_open in case it's corrupt--various - * things in __db_open might act funny. - * - * Once we know the metadata page is healthy, I believe that it's - * safe to open the database normally and then use the page swapping - * code, which makes life easier. - */ - if ((ret = __os_open(dbenv, real_name, DB_OSO_RDONLY, 0, &fhp)) != 0) - goto err; - - /* Verify the metadata page 0; set pagesize and type. */ - if ((ret = __db_vrfy_pagezero(dbp, vdp, fhp, flags)) != 0) { - if (ret == DB_VERIFY_BAD) - isbad = 1; - else - goto err; - } - - /* - * We can assume at this point that dbp->pagesize and dbp->type are - * set correctly, or at least as well as they can be, and that - * locking, logging, and txns are not in use. Thus we can trust - * the memp code not to look at the page, and thus to be safe - * enough to use. - * - * The dbp is not open, but the file is open in the fhp, and we - * cannot assume that __db_open is safe. Call __db_dbenv_setup, - * the [safe] part of __db_open that initializes the environment-- - * and the mpool--manually. - */ - if ((ret = __db_dbenv_setup(dbp, NULL, - name, subdb, TXN_INVALID, DB_ODDFILESIZE | DB_RDONLY)) != 0) - goto err; - - /* - * Set our name in the Queue subsystem; we may need it later - * to deal with extents. - */ - if (dbp->type == DB_QUEUE && - (ret = __qam_set_ext_data(dbp, name)) != 0) - goto err; - - /* Mark the dbp as opened, so that we correctly handle its close. */ - F_SET(dbp, DB_AM_OPEN_CALLED); - - /* Find out the page number of the last page in the database. */ - if ((ret = __memp_last_pgno(dbp->mpf, &vdp->last_pgno)) != 0) - goto err; - - /* - * DB_ORDERCHKONLY is a special case; our file consists of - * several subdatabases, which use different hash, bt_compare, - * and/or dup_compare functions. Consequently, we couldn't verify - * sorting and hashing simply by calling DB->verify() on the file. - * DB_ORDERCHKONLY allows us to come back and check those things; it - * requires a subdatabase, and assumes that everything but that - * database's sorting/hashing is correct. - */ - if (LF_ISSET(DB_ORDERCHKONLY)) { - ret = __db_vrfy_orderchkonly(dbp, vdp, name, subdb, flags); - goto done; - } - - /* - * When salvaging, we use a db to keep track of whether we've seen a - * given overflow or dup page in the course of traversing normal data. - * If in the end we have not, we assume its key got lost and print it - * with key "UNKNOWN". - */ - if (LF_ISSET(DB_SALVAGE)) { - if ((ret = __db_salvage_init(vdp)) != 0) - goto err; - - /* - * If we're not being aggressive, attempt to crack subdatabases. - * "has_subdbs" will indicate whether the attempt has succeeded - * (even in part), meaning that we have some semblance of - * subdatabases; on the walkpages pass, we print out whichever - * data pages we have not seen. - */ - if (!LF_ISSET(DB_AGGRESSIVE) && __db_salvage_subdbs( - dbp, vdp, handle, callback, flags, &has_subdbs) != 0) - isbad = 1; - - /* - * If we have subdatabases, flag if any keys are found that - * don't belong to a subdatabase -- they'll need to have an - * "__OTHER__" subdatabase header printed first. - */ - if (has_subdbs) - F_SET(vdp, SALVAGE_PRINTHEADER); - } - - if ((ret = - __db_vrfy_walkpages(dbp, vdp, handle, callback, flags)) != 0) { - if (ret == DB_VERIFY_BAD) - isbad = 1; - else - goto err; - } - - /* If we're verifying, verify inter-page structure. */ - if (!LF_ISSET(DB_SALVAGE) && isbad == 0) - if ((ret = - __db_vrfy_structure(dbp, vdp, name, 0, flags)) != 0) { - if (ret == DB_VERIFY_BAD) - isbad = 1; - else - goto err; - } - - /* - * If we're salvaging, output with key UNKNOWN any overflow or dup pages - * we haven't been able to put in context. Then destroy the salvager's - * state-saving database. - */ - if (LF_ISSET(DB_SALVAGE)) { - if ((ret = __db_salvage_unknowns(dbp, - vdp, handle, callback, flags)) != 0) - isbad = 1; - /* No return value, since there's little we can do. */ - __db_salvage_destroy(vdp); - } - - /* Don't display a footer for a database holding other databases. */ - if (LF_ISSET(DB_SALVAGE) && - (!has_subdbs || F_ISSET(vdp, SALVAGE_PRINTFOOTER))) - (void)__db_prfooter(handle, callback); - -done: err: - /* Send feedback that we're done. */ - if (!LF_ISSET(DB_SALVAGE) && dbp->db_feedback != NULL) - dbp->db_feedback(dbp, DB_VERIFY, 100); - - if (fhp != NULL && - (t_ret = __os_closehandle(dbenv, fhp)) != 0 && ret == 0) - ret = t_ret; - if (vdp != NULL && - (t_ret = __db_vrfy_dbinfo_destroy(dbenv, vdp)) != 0 && ret == 0) - ret = t_ret; - if (real_name != NULL) - __os_free(dbenv, real_name); - - /* - * DB_VERIFY_FATAL is a private error, translate to a public one. - * - * If we didn't find a page, it's probably a page number was corrupted. - * Return the standard corruption error. - * - * Otherwise, if we found corruption along the way, set the return. - */ - if (ret == DB_VERIFY_FATAL || - ret == DB_PAGE_NOTFOUND || (ret == 0 && isbad == 1)) - ret = DB_VERIFY_BAD; - - /* Make sure there's a public complaint if we found corruption. */ - if (ret != 0) - __db_err(dbenv, "%s: %s", name, db_strerror(ret)); - - return (ret); -} - -/* - * __db_vrfy_pagezero -- - * Verify the master metadata page. Use seek, read, and a local buffer - * rather than the DB paging code, for safety. - * - * Must correctly (or best-guess) set dbp->type and dbp->pagesize. - */ -static int -__db_vrfy_pagezero(dbp, vdp, fhp, flags) - DB *dbp; - VRFY_DBINFO *vdp; - DB_FH *fhp; - u_int32_t flags; -{ - DBMETA *meta; - DB_ENV *dbenv; - VRFY_PAGEINFO *pip; - db_pgno_t freelist; - size_t nr; - int isbad, ret, swapped; - u_int8_t mbuf[DBMETASIZE]; - - isbad = ret = swapped = 0; - freelist = 0; - dbenv = dbp->dbenv; - meta = (DBMETA *)mbuf; - dbp->type = DB_UNKNOWN; - - if ((ret = __db_vrfy_getpageinfo(vdp, PGNO_BASE_MD, &pip)) != 0) - return (ret); - - /* - * Seek to the metadata page. - * Note that if we're just starting a verification, dbp->pgsize - * may be zero; this is okay, as we want page zero anyway and - * 0*0 == 0. - */ - if ((ret = __os_seek(dbenv, fhp, 0, 0, 0, 0, DB_OS_SEEK_SET)) != 0 || - (ret = __os_read(dbenv, fhp, mbuf, DBMETASIZE, &nr)) != 0) { - __db_err(dbenv, - "Metadata page %lu cannot be read: %s", - (u_long)PGNO_BASE_MD, db_strerror(ret)); - return (ret); - } - - if (nr != DBMETASIZE) { - EPRINT((dbenv, - "Page %lu: Incomplete metadata page", - (u_long)PGNO_BASE_MD)); - return (DB_VERIFY_FATAL); - } - - if ((ret = __db_chk_meta(dbenv, dbp, meta, 1)) != 0) { - EPRINT((dbenv, - "Page %lu: metadata page corrupted", (u_long)PGNO_BASE_MD)); - isbad = 1; - if (ret != -1) { - EPRINT((dbenv, - "Page %lu: could not check metadata page", - (u_long)PGNO_BASE_MD)); - return (DB_VERIFY_FATAL); - } - } - - /* - * Check all of the fields that we can. - * - * 08-11: Current page number. Must == pgno. - * Note that endianness doesn't matter--it's zero. - */ - if (meta->pgno != PGNO_BASE_MD) { - isbad = 1; - EPRINT((dbenv, "Page %lu: pgno incorrectly set to %lu", - (u_long)PGNO_BASE_MD, (u_long)meta->pgno)); - } - - /* 12-15: Magic number. Must be one of valid set. */ - if (__db_is_valid_magicno(meta->magic, &dbp->type)) - swapped = 0; - else { - M_32_SWAP(meta->magic); - if (__db_is_valid_magicno(meta->magic, - &dbp->type)) - swapped = 1; - else { - isbad = 1; - EPRINT((dbenv, - "Page %lu: bad magic number %lu", - (u_long)PGNO_BASE_MD, (u_long)meta->magic)); - } - } - - /* - * 16-19: Version. Must be current; for now, we - * don't support verification of old versions. - */ - if (swapped) - M_32_SWAP(meta->version); - if ((dbp->type == DB_BTREE && - (meta->version > DB_BTREEVERSION || - meta->version < DB_BTREEOLDVER)) || - (dbp->type == DB_HASH && - (meta->version > DB_HASHVERSION || - meta->version < DB_HASHOLDVER)) || - (dbp->type == DB_QUEUE && - (meta->version > DB_QAMVERSION || - meta->version < DB_QAMOLDVER))) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: unsupported DB version %lu; extraneous errors may result", - (u_long)PGNO_BASE_MD, (u_long)meta->version)); - } - - /* - * 20-23: Pagesize. Must be power of two, - * greater than 512, and less than 64K. - */ - if (swapped) - M_32_SWAP(meta->pagesize); - if (IS_VALID_PAGESIZE(meta->pagesize)) - dbp->pgsize = meta->pagesize; - else { - isbad = 1; - EPRINT((dbenv, "Page %lu: bad page size %lu", - (u_long)PGNO_BASE_MD, (u_long)meta->pagesize)); - - /* - * Now try to settle on a pagesize to use. - * If the user-supplied one is reasonable, - * use it; else, guess. - */ - if (!IS_VALID_PAGESIZE(dbp->pgsize)) - dbp->pgsize = __db_guesspgsize(dbenv, fhp); - } - - /* - * 25: Page type. Must be correct for dbp->type, - * which is by now set as well as it can be. - */ - /* Needs no swapping--only one byte! */ - if ((dbp->type == DB_BTREE && meta->type != P_BTREEMETA) || - (dbp->type == DB_HASH && meta->type != P_HASHMETA) || - (dbp->type == DB_QUEUE && meta->type != P_QAMMETA)) { - isbad = 1; - EPRINT((dbenv, "Page %lu: bad page type %lu", - (u_long)PGNO_BASE_MD, (u_long)meta->type)); - } - - /* - * 26: Meta-flags. - */ - if (meta->metaflags != 0) { - if (meta->metaflags == DBMETA_CHKSUM) - F_SET(pip, VRFY_HAS_CHKSUM); - else { - isbad = 1; - EPRINT((dbenv, - "Page %lu: bad meta-data flags value %#lx", - (u_long)PGNO_BASE_MD, (u_long)meta->metaflags)); - } - } - - /* - * 28-31: Free list page number. - * We'll verify its sensibility when we do inter-page - * verification later; for now, just store it. - */ - if (swapped) - M_32_SWAP(meta->free); - freelist = meta->free; - - /* - * Initialize vdp->pages to fit a single pageinfo structure for - * this one page. We'll realloc later when we know how many - * pages there are. - */ - pip->pgno = PGNO_BASE_MD; - pip->type = meta->type; - - /* - * Signal that we still have to check the info specific to - * a given type of meta page. - */ - F_SET(pip, VRFY_INCOMPLETE); - - pip->free = freelist; - - if ((ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0) - return (ret); - - /* Set up the dbp's fileid. We don't use the regular open path. */ - memcpy(dbp->fileid, meta->uid, DB_FILE_ID_LEN); - - if (swapped == 1) - F_SET(dbp, DB_AM_SWAP); - - return (isbad ? DB_VERIFY_BAD : 0); -} - -/* - * __db_vrfy_walkpages -- - * Main loop of the verifier/salvager. Walks through, - * page by page, and verifies all pages and/or prints all data pages. - */ -static int -__db_vrfy_walkpages(dbp, vdp, handle, callback, flags) - DB *dbp; - VRFY_DBINFO *vdp; - void *handle; - int (*callback) __P((void *, const void *)); - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_MPOOLFILE *mpf; - PAGE *h; - db_pgno_t i; - int ret, t_ret, isbad; - - dbenv = dbp->dbenv; - mpf = dbp->mpf; - h = NULL; - ret = isbad = t_ret = 0; - - for (i = 0; i <= vdp->last_pgno; i++) { - /* - * If DB_SALVAGE is set, we inspect our database of completed - * pages, and skip any we've already printed in the subdb pass. - */ - if (LF_ISSET(DB_SALVAGE) && (__db_salvage_isdone(vdp, i) != 0)) - continue; - - /* - * If an individual page get fails, keep going if and only - * if we're salvaging. - */ - if ((t_ret = __memp_fget(mpf, &i, 0, &h)) != 0) { - if (ret == 0) - ret = t_ret; - if (LF_ISSET(DB_SALVAGE)) - continue; - return (ret); - } - - if (LF_ISSET(DB_SALVAGE)) { - /* - * We pretty much don't want to quit unless a - * bomb hits. May as well return that something - * was screwy, however. - */ - if ((t_ret = __db_salvage(dbp, - vdp, i, h, handle, callback, flags)) != 0) { - if (ret == 0) - ret = t_ret; - isbad = 1; - } - } else { - /* - * If we are not salvaging, and we get any error - * other than DB_VERIFY_BAD, return immediately; - * it may not be safe to proceed. If we get - * DB_VERIFY_BAD, keep going; listing more errors - * may make it easier to diagnose problems and - * determine the magnitude of the corruption. - * - * Verify info common to all page types. - */ - if (i != PGNO_BASE_MD) { - ret = __db_vrfy_common(dbp, vdp, h, i, flags); - if (ret == DB_VERIFY_BAD) - isbad = 1; - else if (ret != 0) - goto err; - } - - switch (TYPE(h)) { - case P_INVALID: - ret = __db_vrfy_invalid(dbp, vdp, h, i, flags); - break; - case __P_DUPLICATE: - isbad = 1; - EPRINT((dbenv, - "Page %lu: old-style duplicate page", - (u_long)i)); - break; - case P_HASH: - ret = __ham_vrfy(dbp, vdp, h, i, flags); - break; - case P_IBTREE: - case P_IRECNO: - case P_LBTREE: - case P_LDUP: - ret = __bam_vrfy(dbp, vdp, h, i, flags); - break; - case P_LRECNO: - ret = __ram_vrfy_leaf(dbp, vdp, h, i, flags); - break; - case P_OVERFLOW: - ret = __db_vrfy_overflow(dbp, vdp, h, i, flags); - break; - case P_HASHMETA: - ret = __ham_vrfy_meta(dbp, - vdp, (HMETA *)h, i, flags); - break; - case P_BTREEMETA: - ret = __bam_vrfy_meta(dbp, - vdp, (BTMETA *)h, i, flags); - break; - case P_QAMMETA: - ret = __qam_vrfy_meta(dbp, - vdp, (QMETA *)h, i, flags); - break; - case P_QAMDATA: - ret = __qam_vrfy_data(dbp, - vdp, (QPAGE *)h, i, flags); - break; - default: - EPRINT((dbenv, - "Page %lu: unknown page type %lu", - (u_long)i, (u_long)TYPE(h))); - isbad = 1; - break; - } - - /* - * Set up error return. - */ - if (ret == DB_VERIFY_BAD) - isbad = 1; - else if (ret != 0) - goto err; - - /* - * Provide feedback to the application about our - * progress. The range 0-50% comes from the fact - * that this is the first of two passes through the - * database (front-to-back, then top-to-bottom). - */ - if (dbp->db_feedback != NULL) - dbp->db_feedback(dbp, DB_VERIFY, - (int)((i + 1) * 50 / (vdp->last_pgno + 1))); - } - - /* - * Just as with the page get, bail if and only if we're - * not salvaging. - */ - if ((t_ret = __memp_fput(mpf, h, 0)) != 0) { - if (ret == 0) - ret = t_ret; - if (!LF_ISSET(DB_SALVAGE)) - return (ret); - } - } - - /* - * If we've seen a Queue metadata page, we may need to walk Queue - * extent pages that won't show up between 0 and vdp->last_pgno. - */ - if (F_ISSET(vdp, VRFY_QMETA_SET) && (t_ret = - __qam_vrfy_walkqueue(dbp, vdp, handle, callback, flags)) != 0) { - if (ret == 0) - ret = t_ret; - if (t_ret == DB_VERIFY_BAD) - isbad = 1; - else if (!LF_ISSET(DB_SALVAGE)) - return (ret); - } - - if (0) { -err: if (h != NULL && (t_ret = __memp_fput(mpf, h, 0)) != 0) - return (ret == 0 ? t_ret : ret); - } - - return ((isbad == 1 && ret == 0) ? DB_VERIFY_BAD : ret); -} - -/* - * __db_vrfy_structure-- - * After a beginning-to-end walk through the database has been - * completed, put together the information that has been collected - * to verify the overall database structure. - * - * Should only be called if we want to do a database verification, - * i.e. if DB_SALVAGE is not set. - */ -static int -__db_vrfy_structure(dbp, vdp, dbname, meta_pgno, flags) - DB *dbp; - VRFY_DBINFO *vdp; - const char *dbname; - db_pgno_t meta_pgno; - u_int32_t flags; -{ - DB *pgset; - DB_ENV *dbenv; - VRFY_PAGEINFO *pip; - db_pgno_t i; - int ret, isbad, hassubs, p; - - isbad = 0; - pip = NULL; - dbenv = dbp->dbenv; - pgset = vdp->pgset; - - /* - * Providing feedback here is tricky; in most situations, - * we fetch each page one more time, but we do so in a top-down - * order that depends on the access method. Worse, we do this - * recursively in btree, such that on any call where we're traversing - * a subtree we don't know where that subtree is in the whole database; - * worse still, any given database may be one of several subdbs. - * - * The solution is to decrement a counter vdp->pgs_remaining each time - * we verify (and call feedback on) a page. We may over- or - * under-count, but the structure feedback function will ensure that we - * never give a percentage under 50 or over 100. (The first pass - * covered the range 0-50%.) - */ - if (dbp->db_feedback != NULL) - vdp->pgs_remaining = vdp->last_pgno + 1; - - /* - * Call the appropriate function to downwards-traverse the db type. - */ - switch (dbp->type) { - case DB_BTREE: - case DB_RECNO: - if ((ret = __bam_vrfy_structure(dbp, vdp, 0, flags)) != 0) { - if (ret == DB_VERIFY_BAD) - isbad = 1; - else - goto err; - } - - /* - * If we have subdatabases and we know that the database is, - * thus far, sound, it's safe to walk the tree of subdatabases. - * Do so, and verify the structure of the databases within. - */ - if ((ret = __db_vrfy_getpageinfo(vdp, 0, &pip)) != 0) - goto err; - hassubs = F_ISSET(pip, VRFY_HAS_SUBDBS) ? 1 : 0; - if ((ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0) - goto err; - pip = NULL; - - if (isbad == 0 && hassubs) - if ((ret = - __db_vrfy_subdbs(dbp, vdp, dbname, flags)) != 0) { - if (ret == DB_VERIFY_BAD) - isbad = 1; - else - goto err; - } - break; - case DB_HASH: - if ((ret = __ham_vrfy_structure(dbp, vdp, 0, flags)) != 0) { - if (ret == DB_VERIFY_BAD) - isbad = 1; - else - goto err; - } - break; - case DB_QUEUE: - if ((ret = __qam_vrfy_structure(dbp, vdp, flags)) != 0) { - if (ret == DB_VERIFY_BAD) - isbad = 1; - } - - /* - * Queue pages may be unreferenced and totally zeroed, if - * they're empty; queue doesn't have much structure, so - * this is unlikely to be wrong in any troublesome sense. - * Skip to "err". - */ - goto err; - case DB_UNKNOWN: - default: - /* This should only happen if the verifier is somehow broken. */ - DB_ASSERT(0); - ret = EINVAL; - goto err; - } - - /* Walk free list. */ - if ((ret = - __db_vrfy_freelist(dbp, vdp, meta_pgno, flags)) == DB_VERIFY_BAD) - isbad = 1; - - /* - * If structure checks up until now have failed, it's likely that - * checking what pages have been missed will result in oodles of - * extraneous error messages being EPRINTed. Skip to the end - * if this is the case; we're going to be printing at least one - * error anyway, and probably all the more salient ones. - */ - if (ret != 0 || isbad == 1) - goto err; - - /* - * Make sure no page has been missed and that no page is still marked - * "all zeroes" (only certain hash pages can be, and they're unmarked - * in __ham_vrfy_structure). - */ - for (i = 0; i < vdp->last_pgno + 1; i++) { - if ((ret = __db_vrfy_getpageinfo(vdp, i, &pip)) != 0) - goto err; - if ((ret = __db_vrfy_pgset_get(pgset, i, &p)) != 0) - goto err; - if (pip->type == P_OVERFLOW) { - if ((u_int32_t)p != pip->refcount) { - EPRINT((dbenv, - "Page %lu: overflow refcount %lu, referenced %lu times", - (u_long)i, - (u_long)pip->refcount, (u_long)p)); - isbad = 1; - } - } else if (p == 0 && LF_ISSET(DB_UNREF)) { - EPRINT((dbenv, - "Page %lu: unreferenced page", (u_long)i)); - isbad = 1; - } - - if (F_ISSET(pip, VRFY_IS_ALLZEROES)) { - EPRINT((dbenv, - "Page %lu: totally zeroed page", (u_long)i)); - isbad = 1; - } - if ((ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0) - goto err; - pip = NULL; - } - -err: if (pip != NULL) - (void)__db_vrfy_putpageinfo(dbenv, vdp, pip); - - return ((isbad == 1 && ret == 0) ? DB_VERIFY_BAD : ret); -} - -/* - * __db_is_valid_pagetype - */ -static int -__db_is_valid_pagetype(type) - u_int32_t type; -{ - switch (type) { - case P_INVALID: /* Order matches ordinal value. */ - case P_HASH: - case P_IBTREE: - case P_IRECNO: - case P_LBTREE: - case P_LRECNO: - case P_OVERFLOW: - case P_HASHMETA: - case P_BTREEMETA: - case P_QAMMETA: - case P_QAMDATA: - case P_LDUP: - return (1); - default: - break; - } - return (0); -} - -/* - * __db_is_valid_magicno - */ -static int -__db_is_valid_magicno(magic, typep) - u_int32_t magic; - DBTYPE *typep; -{ - switch (magic) { - case DB_BTREEMAGIC: - *typep = DB_BTREE; - return (1); - case DB_HASHMAGIC: - *typep = DB_HASH; - return (1); - case DB_QAMMAGIC: - *typep = DB_QUEUE; - return (1); - default: - break; - } - *typep = DB_UNKNOWN; - return (0); -} - -/* - * __db_vrfy_common -- - * Verify info common to all page types. - * - * PUBLIC: int __db_vrfy_common - * PUBLIC: __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, u_int32_t)); - */ -int -__db_vrfy_common(dbp, vdp, h, pgno, flags) - DB *dbp; - VRFY_DBINFO *vdp; - PAGE *h; - db_pgno_t pgno; - u_int32_t flags; -{ - DB_ENV *dbenv; - VRFY_PAGEINFO *pip; - int ret, t_ret; - u_int8_t *p; - - dbenv = dbp->dbenv; - - if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) - return (ret); - - pip->pgno = pgno; - F_CLR(pip, VRFY_IS_ALLZEROES); - - /* - * Hash expands the table by leaving some pages between the - * old last and the new last totally zeroed. Its pgin function - * should fix things, but we might not be using that (e.g. if - * we're a subdatabase). - * - * Queue will create sparse files if sparse record numbers are used. - */ - if (pgno != 0 && PGNO(h) == 0) { - for (p = (u_int8_t *)h; p < (u_int8_t *)h + dbp->pgsize; p++) - if (*p != 0) { - EPRINT((dbenv, - "Page %lu: partially zeroed page", - (u_long)pgno)); - ret = DB_VERIFY_BAD; - goto err; - } - /* - * It's totally zeroed; mark it as a hash, and we'll - * check that that makes sense structurally later. - * (The queue verification doesn't care, since queues - * don't really have much in the way of structure.) - */ - pip->type = P_HASH; - F_SET(pip, VRFY_IS_ALLZEROES); - ret = 0; - goto err; /* well, not really an err. */ - } - - if (PGNO(h) != pgno) { - EPRINT((dbenv, "Page %lu: bad page number %lu", - (u_long)pgno, (u_long)h->pgno)); - ret = DB_VERIFY_BAD; - } - - if (!__db_is_valid_pagetype(h->type)) { - EPRINT((dbenv, "Page %lu: bad page type %lu", - (u_long)pgno, (u_long)h->type)); - ret = DB_VERIFY_BAD; - } - pip->type = h->type; - -err: if ((t_ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __db_vrfy_invalid -- - * Verify P_INVALID page. - * (Yes, there's not much to do here.) - */ -static int -__db_vrfy_invalid(dbp, vdp, h, pgno, flags) - DB *dbp; - VRFY_DBINFO *vdp; - PAGE *h; - db_pgno_t pgno; - u_int32_t flags; -{ - DB_ENV *dbenv; - VRFY_PAGEINFO *pip; - int ret, t_ret; - - dbenv = dbp->dbenv; - - if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) - return (ret); - pip->next_pgno = pip->prev_pgno = 0; - - if (!IS_VALID_PGNO(NEXT_PGNO(h))) { - EPRINT((dbenv, "Page %lu: invalid next_pgno %lu", - (u_long)pgno, (u_long)NEXT_PGNO(h))); - ret = DB_VERIFY_BAD; - } else - pip->next_pgno = NEXT_PGNO(h); - - if ((t_ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0 && ret == 0) - ret = t_ret; - return (ret); -} - -/* - * __db_vrfy_datapage -- - * Verify elements common to data pages (P_HASH, P_LBTREE, - * P_IBTREE, P_IRECNO, P_LRECNO, P_OVERFLOW, P_DUPLICATE)--i.e., - * those defined in the PAGE structure. - * - * Called from each of the per-page routines, after the - * all-page-type-common elements of pip have been verified and filled - * in. - * - * PUBLIC: int __db_vrfy_datapage - * PUBLIC: __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, u_int32_t)); - */ -int -__db_vrfy_datapage(dbp, vdp, h, pgno, flags) - DB *dbp; - VRFY_DBINFO *vdp; - PAGE *h; - db_pgno_t pgno; - u_int32_t flags; -{ - DB_ENV *dbenv; - VRFY_PAGEINFO *pip; - int isbad, ret, t_ret; - - dbenv = dbp->dbenv; - - if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) - return (ret); - isbad = 0; - - /* - * prev_pgno and next_pgno: store for inter-page checks, - * verify that they point to actual pages and not to self. - * - * !!! - * Internal btree pages do not maintain these fields (indeed, - * they overload them). Skip. - */ - if (TYPE(h) != P_IBTREE && TYPE(h) != P_IRECNO) { - if (!IS_VALID_PGNO(PREV_PGNO(h)) || PREV_PGNO(h) == pip->pgno) { - isbad = 1; - EPRINT((dbenv, "Page %lu: invalid prev_pgno %lu", - (u_long)pip->pgno, (u_long)PREV_PGNO(h))); - } - if (!IS_VALID_PGNO(NEXT_PGNO(h)) || NEXT_PGNO(h) == pip->pgno) { - isbad = 1; - EPRINT((dbenv, "Page %lu: invalid next_pgno %lu", - (u_long)pip->pgno, (u_long)NEXT_PGNO(h))); - } - pip->prev_pgno = PREV_PGNO(h); - pip->next_pgno = NEXT_PGNO(h); - } - - /* - * Verify the number of entries on the page. - * There is no good way to determine if this is accurate; the - * best we can do is verify that it's not more than can, in theory, - * fit on the page. Then, we make sure there are at least - * this many valid elements in inp[], and hope that this catches - * most cases. - */ - if (TYPE(h) != P_OVERFLOW) { - if (BKEYDATA_PSIZE(0) * NUM_ENT(h) > dbp->pgsize) { - isbad = 1; - EPRINT((dbenv, "Page %lu: too many entries: %lu", - (u_long)pgno, (u_long)NUM_ENT(h))); - } - pip->entries = NUM_ENT(h); - } - - /* - * btree level. Should be zero unless we're a btree; - * if we are a btree, should be between LEAFLEVEL and MAXBTREELEVEL, - * and we need to save it off. - */ - switch (TYPE(h)) { - case P_IBTREE: - case P_IRECNO: - if (LEVEL(h) < LEAFLEVEL + 1) { - isbad = 1; - EPRINT((dbenv, "Page %lu: bad btree level %lu", - (u_long)pgno, (u_long)LEVEL(h))); - } - pip->bt_level = LEVEL(h); - break; - case P_LBTREE: - case P_LDUP: - case P_LRECNO: - if (LEVEL(h) != LEAFLEVEL) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: btree leaf page has incorrect level %lu", - (u_long)pgno, (u_long)LEVEL(h))); - } - break; - default: - if (LEVEL(h) != 0) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: nonzero level %lu in non-btree database", - (u_long)pgno, (u_long)LEVEL(h))); - } - break; - } - - /* - * Even though inp[] occurs in all PAGEs, we look at it in the - * access-method-specific code, since btree and hash treat - * item lengths very differently, and one of the most important - * things we want to verify is that the data--as specified - * by offset and length--cover the right part of the page - * without overlaps, gaps, or violations of the page boundary. - */ - if ((t_ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0 && ret == 0) - ret = t_ret; - - return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); -} - -/* - * __db_vrfy_meta-- - * Verify the access-method common parts of a meta page, using - * normal mpool routines. - * - * PUBLIC: int __db_vrfy_meta - * PUBLIC: __P((DB *, VRFY_DBINFO *, DBMETA *, db_pgno_t, u_int32_t)); - */ -int -__db_vrfy_meta(dbp, vdp, meta, pgno, flags) - DB *dbp; - VRFY_DBINFO *vdp; - DBMETA *meta; - db_pgno_t pgno; - u_int32_t flags; -{ - DB_ENV *dbenv; - DBTYPE dbtype, magtype; - VRFY_PAGEINFO *pip; - int isbad, ret, t_ret; - - isbad = 0; - dbenv = dbp->dbenv; - - if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) - return (ret); - - /* type plausible for a meta page */ - switch (meta->type) { - case P_BTREEMETA: - dbtype = DB_BTREE; - break; - case P_HASHMETA: - dbtype = DB_HASH; - break; - case P_QAMMETA: - dbtype = DB_QUEUE; - break; - default: - /* The verifier should never let us get here. */ - DB_ASSERT(0); - ret = EINVAL; - goto err; - } - - /* magic number valid */ - if (!__db_is_valid_magicno(meta->magic, &magtype)) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: invalid magic number", (u_long)pgno)); - } - if (magtype != dbtype) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: magic number does not match database type", - (u_long)pgno)); - } - - /* version */ - if ((dbtype == DB_BTREE && - (meta->version > DB_BTREEVERSION || - meta->version < DB_BTREEOLDVER)) || - (dbtype == DB_HASH && - (meta->version > DB_HASHVERSION || - meta->version < DB_HASHOLDVER)) || - (dbtype == DB_QUEUE && - (meta->version > DB_QAMVERSION || - meta->version < DB_QAMOLDVER))) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: unsupported database version %lu; extraneous errors may result", - (u_long)pgno, (u_long)meta->version)); - } - - /* pagesize */ - if (meta->pagesize != dbp->pgsize) { - isbad = 1; - EPRINT((dbenv, "Page %lu: invalid pagesize %lu", - (u_long)pgno, (u_long)meta->pagesize)); - } - - /* Flags */ - if (meta->metaflags != 0) { - if (meta->metaflags == DBMETA_CHKSUM) - F_SET(pip, VRFY_HAS_CHKSUM); - else { - isbad = 1; - EPRINT((dbenv, - "Page %lu: bad meta-data flags value %#lx", - (u_long)PGNO_BASE_MD, (u_long)meta->metaflags)); - } - } - - /* - * Free list. - * - * If this is not the main, master-database meta page, it - * should not have a free list. - */ - if (pgno != PGNO_BASE_MD && meta->free != PGNO_INVALID) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: nonempty free list on subdatabase metadata page", - (u_long)pgno)); - } - - /* Can correctly be PGNO_INVALID--that's just the end of the list. */ - if (meta->free != PGNO_INVALID && IS_VALID_PGNO(meta->free)) - pip->free = meta->free; - else if (!IS_VALID_PGNO(meta->free)) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: nonsensical free list pgno %lu", - (u_long)pgno, (u_long)meta->free)); - } - - /* - * We have now verified the common fields of the metadata page. - * Clear the flag that told us they had been incompletely checked. - */ - F_CLR(pip, VRFY_INCOMPLETE); - -err: if ((t_ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0 && ret == 0) - ret = t_ret; - - return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); -} - -/* - * __db_vrfy_freelist -- - * Walk free list, checking off pages and verifying absence of - * loops. - */ -static int -__db_vrfy_freelist(dbp, vdp, meta, flags) - DB *dbp; - VRFY_DBINFO *vdp; - db_pgno_t meta; - u_int32_t flags; -{ - DB *pgset; - DB_ENV *dbenv; - VRFY_PAGEINFO *pip; - db_pgno_t cur_pgno, next_pgno; - int p, ret, t_ret; - - pgset = vdp->pgset; - DB_ASSERT(pgset != NULL); - dbenv = dbp->dbenv; - - if ((ret = __db_vrfy_getpageinfo(vdp, meta, &pip)) != 0) - return (ret); - for (next_pgno = pip->free; - next_pgno != PGNO_INVALID; next_pgno = pip->next_pgno) { - cur_pgno = pip->pgno; - if ((ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0) - return (ret); - - /* This shouldn't happen, but just in case. */ - if (!IS_VALID_PGNO(next_pgno)) { - EPRINT((dbenv, - "Page %lu: invalid next_pgno %lu on free list page", - (u_long)cur_pgno, (u_long)next_pgno)); - return (DB_VERIFY_BAD); - } - - /* Detect cycles. */ - if ((ret = __db_vrfy_pgset_get(pgset, next_pgno, &p)) != 0) - return (ret); - if (p != 0) { - EPRINT((dbenv, - "Page %lu: page %lu encountered a second time on free list", - (u_long)cur_pgno, (u_long)next_pgno)); - return (DB_VERIFY_BAD); - } - if ((ret = __db_vrfy_pgset_inc(pgset, next_pgno)) != 0) - return (ret); - - if ((ret = __db_vrfy_getpageinfo(vdp, next_pgno, &pip)) != 0) - return (ret); - - if (pip->type != P_INVALID) { - EPRINT((dbenv, - "Page %lu: non-invalid page %lu on free list", - (u_long)cur_pgno, (u_long)next_pgno)); - ret = DB_VERIFY_BAD; /* unsafe to continue */ - break; - } - } - - if ((t_ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0) - ret = t_ret; - return (ret); -} - -/* - * __db_vrfy_subdbs -- - * Walk the known-safe master database of subdbs with a cursor, - * verifying the structure of each subdatabase we encounter. - */ -static int -__db_vrfy_subdbs(dbp, vdp, dbname, flags) - DB *dbp; - VRFY_DBINFO *vdp; - const char *dbname; - u_int32_t flags; -{ - DB *mdbp; - DBC *dbc; - DBT key, data; - DB_ENV *dbenv; - VRFY_PAGEINFO *pip; - db_pgno_t meta_pgno; - int ret, t_ret, isbad; - u_int8_t type; - - isbad = 0; - dbc = NULL; - dbenv = dbp->dbenv; - - if ((ret = - __db_master_open(dbp, NULL, dbname, DB_RDONLY, 0, &mdbp)) != 0) - return (ret); - - if ((ret = __db_cursor_int(mdbp, - NULL, DB_BTREE, PGNO_INVALID, 0, DB_LOCK_INVALIDID, &dbc)) != 0) - goto err; - - memset(&key, 0, sizeof(key)); - memset(&data, 0, sizeof(data)); - while ((ret = __db_c_get(dbc, &key, &data, DB_NEXT)) == 0) { - if (data.size != sizeof(db_pgno_t)) { - EPRINT((dbenv, - "Subdatabase entry not page-number size")); - isbad = 1; - goto err; - } - memcpy(&meta_pgno, data.data, data.size); - /* - * Subdatabase meta pgnos are stored in network byte - * order for cross-endian compatibility. Swap if appropriate. - */ - DB_NTOHL(&meta_pgno); - if (meta_pgno == PGNO_INVALID || meta_pgno > vdp->last_pgno) { - EPRINT((dbenv, - "Subdatabase entry references invalid page %lu", - (u_long)meta_pgno)); - isbad = 1; - goto err; - } - if ((ret = __db_vrfy_getpageinfo(vdp, meta_pgno, &pip)) != 0) - goto err; - type = pip->type; - if ((ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0) - goto err; - switch (type) { - case P_BTREEMETA: - if ((ret = __bam_vrfy_structure( - dbp, vdp, meta_pgno, flags)) != 0) { - if (ret == DB_VERIFY_BAD) - isbad = 1; - else - goto err; - } - break; - case P_HASHMETA: - if ((ret = __ham_vrfy_structure( - dbp, vdp, meta_pgno, flags)) != 0) { - if (ret == DB_VERIFY_BAD) - isbad = 1; - else - goto err; - } - break; - case P_QAMMETA: - default: - EPRINT((dbenv, - "Subdatabase entry references page %lu of invalid type %lu", - (u_long)meta_pgno, (u_long)type)); - ret = DB_VERIFY_BAD; - goto err; - } - } - - if (ret == DB_NOTFOUND) - ret = 0; - -err: if (dbc != NULL && (t_ret = __db_c_close(dbc)) != 0 && ret == 0) - ret = t_ret; - - if ((t_ret = __db_close(mdbp, NULL, 0)) != 0 && ret == 0) - ret = t_ret; - - return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); -} - -/* - * __db_vrfy_struct_feedback -- - * Provide feedback during top-down database structure traversal. - * (See comment at the beginning of __db_vrfy_structure.) - * - * PUBLIC: void __db_vrfy_struct_feedback __P((DB *, VRFY_DBINFO *)); - */ -void -__db_vrfy_struct_feedback(dbp, vdp) - DB *dbp; - VRFY_DBINFO *vdp; -{ - int progress; - - if (dbp->db_feedback == NULL) - return; - - if (vdp->pgs_remaining > 0) - vdp->pgs_remaining--; - - /* Don't allow a feedback call of 100 until we're really done. */ - progress = 100 - (int)(vdp->pgs_remaining * 50 / (vdp->last_pgno + 1)); - dbp->db_feedback(dbp, DB_VERIFY, progress == 100 ? 99 : progress); -} - -/* - * __db_vrfy_orderchkonly -- - * Do an sort-order/hashing check on a known-otherwise-good subdb. - */ -static int -__db_vrfy_orderchkonly(dbp, vdp, name, subdb, flags) - DB *dbp; - VRFY_DBINFO *vdp; - const char *name, *subdb; - u_int32_t flags; -{ - BTMETA *btmeta; - DB *mdbp, *pgset; - DBC *pgsc; - DBT key, data; - DB_ENV *dbenv; - DB_MPOOLFILE *mpf; - HASH *h_internal; - HMETA *hmeta; - PAGE *h, *currpg; - db_pgno_t meta_pgno, p, pgno; - u_int32_t bucket; - int t_ret, ret; - - pgset = NULL; - pgsc = NULL; - dbenv = dbp->dbenv; - mpf = dbp->mpf; - currpg = h = NULL; - - LF_CLR(DB_NOORDERCHK); - - /* Open the master database and get the meta_pgno for the subdb. */ - if ((ret = __db_master_open(dbp, NULL, name, DB_RDONLY, 0, &mdbp)) != 0) - goto err; - - memset(&key, 0, sizeof(key)); - key.data = (void *)subdb; - key.size = (u_int32_t)strlen(subdb); - memset(&data, 0, sizeof(data)); - if ((ret = __db_get(mdbp, NULL, &key, &data, 0)) != 0) - goto err; - - if (data.size != sizeof(db_pgno_t)) { - EPRINT((dbenv, "Subdatabase entry of invalid size")); - ret = DB_VERIFY_BAD; - goto err; - } - - memcpy(&meta_pgno, data.data, data.size); - - /* - * Subdatabase meta pgnos are stored in network byte - * order for cross-endian compatibility. Swap if appropriate. - */ - DB_NTOHL(&meta_pgno); - - if ((ret = __memp_fget(mpf, &meta_pgno, 0, &h)) != 0) - goto err; - - if ((ret = __db_vrfy_pgset(dbenv, dbp->pgsize, &pgset)) != 0) - goto err; - - switch (TYPE(h)) { - case P_BTREEMETA: - btmeta = (BTMETA *)h; - if (F_ISSET(&btmeta->dbmeta, BTM_RECNO)) { - /* Recnos have no order to check. */ - ret = 0; - goto err; - } - if ((ret = - __db_meta2pgset(dbp, vdp, meta_pgno, flags, pgset)) != 0) - goto err; - if ((ret = __db_cursor_int(pgset, NULL, dbp->type, - PGNO_INVALID, 0, DB_LOCK_INVALIDID, &pgsc)) != 0) - goto err; - while ((ret = __db_vrfy_pgset_next(pgsc, &p)) == 0) { - if ((ret = __memp_fget(mpf, &p, 0, &currpg)) != 0) - goto err; - if ((ret = __bam_vrfy_itemorder(dbp, - NULL, currpg, p, NUM_ENT(currpg), 1, - F_ISSET(&btmeta->dbmeta, BTM_DUP), flags)) != 0) - goto err; - if ((ret = __memp_fput(mpf, currpg, 0)) != 0) - goto err; - currpg = NULL; - } - - /* - * The normal exit condition for the loop above is DB_NOTFOUND. - * If we see that, zero it and continue on to cleanup. - * Otherwise, it's a real error and will be returned. - */ - if (ret == DB_NOTFOUND) - ret = 0; - break; - case P_HASHMETA: - hmeta = (HMETA *)h; - h_internal = (HASH *)dbp->h_internal; - /* - * Make sure h_charkey is right. - */ - if (h_internal == NULL) { - EPRINT((dbenv, - "Page %lu: DB->h_internal field is NULL", - (u_long)meta_pgno)); - ret = DB_VERIFY_BAD; - goto err; - } - if (h_internal->h_hash == NULL) - h_internal->h_hash = hmeta->dbmeta.version < 5 - ? __ham_func4 : __ham_func5; - if (hmeta->h_charkey != - h_internal->h_hash(dbp, CHARKEY, sizeof(CHARKEY))) { - EPRINT((dbenv, - "Page %lu: incorrect hash function for database", - (u_long)meta_pgno)); - ret = DB_VERIFY_BAD; - goto err; - } - - /* - * Foreach bucket, verify hashing on each page in the - * corresponding chain of pages. - */ - for (bucket = 0; bucket <= hmeta->max_bucket; bucket++) { - pgno = BS_TO_PAGE(bucket, hmeta->spares); - while (pgno != PGNO_INVALID) { - if ((ret = __memp_fget(mpf, - &pgno, 0, &currpg)) != 0) - goto err; - if ((ret = __ham_vrfy_hashing(dbp, - NUM_ENT(currpg), hmeta, bucket, pgno, - flags, h_internal->h_hash)) != 0) - goto err; - pgno = NEXT_PGNO(currpg); - if ((ret = __memp_fput(mpf, currpg, 0)) != 0) - goto err; - currpg = NULL; - } - } - break; - default: - EPRINT((dbenv, "Page %lu: database metapage of bad type %lu", - (u_long)meta_pgno, (u_long)TYPE(h))); - ret = DB_VERIFY_BAD; - break; - } - -err: if (pgsc != NULL && (t_ret = __db_c_close(pgsc)) != 0 && ret == 0) - ret = t_ret; - if (pgset != NULL && - (t_ret = __db_close(pgset, NULL, 0)) != 0 && ret == 0) - ret = t_ret; - if (h != NULL && (t_ret = __memp_fput(mpf, h, 0)) != 0) - ret = t_ret; - if (currpg != NULL && (t_ret = __memp_fput(mpf, currpg, 0)) != 0) - ret = t_ret; - if ((t_ret = __db_close(mdbp, NULL, 0)) != 0) - ret = t_ret; - return (ret); -} - -/* - * __db_salvage -- - * Walk through a page, salvaging all likely or plausible (w/ - * DB_AGGRESSIVE) key/data pairs. - * - * PUBLIC: int __db_salvage __P((DB *, VRFY_DBINFO *, db_pgno_t, - * PUBLIC: PAGE *, void *, int (*)(void *, const void *), u_int32_t)); - */ -int -__db_salvage(dbp, vdp, pgno, h, handle, callback, flags) - DB *dbp; - VRFY_DBINFO *vdp; - db_pgno_t pgno; - PAGE *h; - void *handle; - int (*callback) __P((void *, const void *)); - u_int32_t flags; -{ - DB_ENV *dbenv; - VRFY_PAGEINFO *pip; - int keyflag, ret, t_ret; - - DB_ASSERT(LF_ISSET(DB_SALVAGE)); - - dbenv = dbp->dbenv; - - /* - * !!! - * We dump record numbers when salvaging Queue databases, but not for - * immutable Recno databases. The problem is we can't figure out the - * record number from the database page in the Recno case, while the - * offset in the file is sufficient for Queue. - */ - keyflag = 0; - - /* If we got this page in the subdb pass, we can safely skip it. */ - if (__db_salvage_isdone(vdp, pgno)) - return (0); - - switch (TYPE(h)) { - case P_HASHMETA: - ret = __ham_vrfy_meta(dbp, vdp, (HMETA *)h, pgno, flags); - break; - case P_BTREEMETA: - ret = __bam_vrfy_meta(dbp, vdp, (BTMETA *)h, pgno, flags); - break; - case P_QAMMETA: - keyflag = 1; - ret = __qam_vrfy_meta(dbp, vdp, (QMETA *)h, pgno, flags); - break; - case P_HASH: - return (__ham_salvage( - dbp, vdp, pgno, h, handle, callback, flags)); - case P_LBTREE: - return (__bam_salvage(dbp, - vdp, pgno, P_LBTREE, h, handle, callback, NULL, flags)); - case P_LDUP: - return (__db_salvage_markneeded(vdp, pgno, SALVAGE_LDUP)); - case P_OVERFLOW: - return (__db_salvage_markneeded(vdp, pgno, SALVAGE_OVERFLOW)); - case P_LRECNO: - /* - * Recnos are tricky -- they may represent dup pages, or - * they may be subdatabase/regular database pages in their - * own right. If the former, they need to be printed with a - * key, preferably when we hit the corresponding datum in - * a btree/hash page. If the latter, there is no key. - * - * If a database is sufficiently frotzed, we're not going - * to be able to get this right, so we best-guess: just - * mark it needed now, and if we're really a normal recno - * database page, the "unknowns" pass will pick us up. - */ - return (__db_salvage_markneeded(vdp, pgno, SALVAGE_LRECNO)); - case P_QAMDATA: - return (__qam_salvage(dbp, - vdp, pgno, h, handle, callback, flags)); - case P_IBTREE: - case P_INVALID: - case P_IRECNO: - case __P_DUPLICATE: - default: - /* XXX: Should we be more aggressive here? */ - return (0); - } - if (ret != 0) - return (ret); - - /* - * We have to display the dump header if it's a metadata page. It's - * our last chance as the page was marked "seen" in the vrfy routine, - * and we won't see the page again. We don't display headers for - * the first database in a multi-database file, that database simply - * contains a list of subdatabases. - */ - if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) - return (ret); - if (!F_ISSET(pip, VRFY_HAS_SUBDBS)) - ret = __db_prheader( - dbp, NULL, 0, keyflag, handle, callback, vdp, pgno); - if ((t_ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0 && ret == 0) - ret = t_ret; - return (ret); -} - -/* - * __db_salvage_unknowns -- - * Walk through the salvager database, printing with key "UNKNOWN" - * any pages we haven't dealt with. - */ -static int -__db_salvage_unknowns(dbp, vdp, handle, callback, flags) - DB *dbp; - VRFY_DBINFO *vdp; - void *handle; - int (*callback) __P((void *, const void *)); - u_int32_t flags; -{ - DBC *dbc; - DBT unkdbt, key, *dbt; - DB_ENV *dbenv; - DB_MPOOLFILE *mpf; - PAGE *h; - db_pgno_t pgno; - u_int32_t pgtype; - int ret, t_ret; - void *ovflbuf; - - dbc = NULL; - dbenv = dbp->dbenv; - mpf = dbp->mpf; - - memset(&unkdbt, 0, sizeof(DBT)); - unkdbt.size = (u_int32_t)strlen("UNKNOWN") + 1; - unkdbt.data = "UNKNOWN"; - - if ((ret = __os_malloc(dbenv, dbp->pgsize, &ovflbuf)) != 0) - return (ret); - - /* - * We make two passes -- in the first pass, skip SALVAGE_OVERFLOW - * pages, because they may be referenced by the standard database - * pages that we're resolving. - */ - while ((t_ret = - __db_salvage_getnext(vdp, &dbc, &pgno, &pgtype, 1)) == 0) { - if ((t_ret = __memp_fget(mpf, &pgno, 0, &h)) != 0) { - if (ret == 0) - ret = t_ret; - continue; - } - - dbt = NULL; - switch (pgtype) { - case SALVAGE_LDUP: - case SALVAGE_LRECNODUP: - dbt = &unkdbt; - /* FALLTHROUGH */ - case SALVAGE_LBTREE: - case SALVAGE_LRECNO: - if ((t_ret = __bam_salvage(dbp, vdp, pgno, pgtype, - h, handle, callback, dbt, flags)) != 0 && ret == 0) - ret = t_ret; - break; - case SALVAGE_OVERFLOW: - DB_ASSERT(0); /* Shouldn't ever happen. */ - break; - case SALVAGE_HASH: - if ((t_ret = __ham_salvage(dbp, vdp, - pgno, h, handle, callback, flags)) != 0 && ret == 0) - ret = t_ret; - break; - case SALVAGE_INVALID: - case SALVAGE_IGNORE: - default: - /* - * Shouldn't happen, but if it does, just do what the - * nice man says. - */ - DB_ASSERT(0); - break; - } - if ((t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0) - ret = t_ret; - } - - /* We should have reached the end of the database. */ - if (t_ret == DB_NOTFOUND) - t_ret = 0; - if (t_ret != 0 && ret == 0) - ret = t_ret; - - /* Re-open the cursor so we traverse the database again. */ - if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0) - ret = t_ret; - dbc = NULL; - - /* Now, deal with any remaining overflow pages. */ - while ((t_ret = - __db_salvage_getnext(vdp, &dbc, &pgno, &pgtype, 0)) == 0) { - if ((t_ret = __memp_fget(mpf, &pgno, 0, &h)) != 0) { - if (ret == 0) - ret = t_ret; - continue; - } - - switch (pgtype) { - case SALVAGE_OVERFLOW: - /* - * XXX: - * This may generate multiple "UNKNOWN" keys in - * a database with no dups. What to do? - */ - if ((t_ret = __db_safe_goff(dbp, - vdp, pgno, &key, &ovflbuf, flags)) != 0 || - ((vdp->type == DB_BTREE || vdp->type == DB_HASH) && - (t_ret = __db_vrfy_prdbt(&unkdbt, - 0, " ", handle, callback, 0, vdp)) != 0) || - (t_ret = __db_vrfy_prdbt( - &key, 0, " ", handle, callback, 0, vdp)) != 0) - if (ret == 0) - ret = t_ret; - break; - default: - DB_ASSERT(0); /* Shouldn't ever happen. */ - break; - } - if ((t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0) - ret = t_ret; - } - - /* We should have reached the end of the database. */ - if (t_ret == DB_NOTFOUND) - t_ret = 0; - if (t_ret != 0 && ret == 0) - ret = t_ret; - - if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0) - ret = t_ret; - - __os_free(dbenv, ovflbuf); - - return (ret); -} - -/* - * Offset of the ith inp array entry, which we can compare to the offset - * the entry stores. - */ -#define INP_OFFSET(dbp, h, i) \ - ((db_indx_t)((u_int8_t *)((P_INP(dbp,(h))) + (i)) - (u_int8_t *)(h))) - -/* - * __db_vrfy_inpitem -- - * Verify that a single entry in the inp array is sane, and update - * the high water mark and current item offset. (The former of these is - * used for state information between calls, and is required; it must - * be initialized to the pagesize before the first call.) - * - * Returns DB_VERIFY_FATAL if inp has collided with the data, - * since verification can't continue from there; returns DB_VERIFY_BAD - * if anything else is wrong. - * - * PUBLIC: int __db_vrfy_inpitem __P((DB *, PAGE *, - * PUBLIC: db_pgno_t, u_int32_t, int, u_int32_t, u_int32_t *, u_int32_t *)); - */ -int -__db_vrfy_inpitem(dbp, h, pgno, i, is_btree, flags, himarkp, offsetp) - DB *dbp; - PAGE *h; - db_pgno_t pgno; - u_int32_t i; - int is_btree; - u_int32_t flags, *himarkp, *offsetp; -{ - BKEYDATA *bk; - DB_ENV *dbenv; - db_indx_t *inp, offset, len; - - dbenv = dbp->dbenv; - - DB_ASSERT(himarkp != NULL); - inp = P_INP(dbp, h); - - /* - * Check that the inp array, which grows from the beginning of the - * page forward, has not collided with the data, which grow from the - * end of the page backward. - */ - if (inp + i >= (db_indx_t *)((u_int8_t *)h + *himarkp)) { - /* We've collided with the data. We need to bail. */ - EPRINT((dbenv, "Page %lu: entries listing %lu overlaps data", - (u_long)pgno, (u_long)i)); - return (DB_VERIFY_FATAL); - } - - offset = inp[i]; - - /* - * Check that the item offset is reasonable: it points somewhere - * after the inp array and before the end of the page. - */ - if (offset <= INP_OFFSET(dbp, h, i) || offset > dbp->pgsize) { - EPRINT((dbenv, "Page %lu: bad offset %lu at page index %lu", - (u_long)pgno, (u_long)offset, (u_long)i)); - return (DB_VERIFY_BAD); - } - - /* Update the high-water mark (what HOFFSET should be) */ - if (offset < *himarkp) - *himarkp = offset; - - if (is_btree) { - /* - * Check alignment; if it's unaligned, it's unsafe to - * manipulate this item. - */ - if (offset != DB_ALIGN(offset, sizeof(u_int32_t))) { - EPRINT((dbenv, - "Page %lu: unaligned offset %lu at page index %lu", - (u_long)pgno, (u_long)offset, (u_long)i)); - return (DB_VERIFY_BAD); - } - - /* - * Check that the item length remains on-page. - */ - bk = GET_BKEYDATA(dbp, h, i); - - /* - * We need to verify the type of the item here; - * we can't simply assume that it will be one of the - * expected three. If it's not a recognizable type, - * it can't be considered to have a verifiable - * length, so it's not possible to certify it as safe. - */ - switch (B_TYPE(bk->type)) { - case B_KEYDATA: - len = bk->len; - break; - case B_DUPLICATE: - case B_OVERFLOW: - len = BOVERFLOW_SIZE; - break; - default: - EPRINT((dbenv, - "Page %lu: item %lu of unrecognizable type", - (u_long)pgno, (u_long)i)); - return (DB_VERIFY_BAD); - } - - if ((size_t)(offset + len) > dbp->pgsize) { - EPRINT((dbenv, - "Page %lu: item %lu extends past page boundary", - (u_long)pgno, (u_long)i)); - return (DB_VERIFY_BAD); - } - } - - if (offsetp != NULL) - *offsetp = offset; - return (0); -} - -/* - * __db_vrfy_duptype-- - * Given a page number and a set of flags to __bam_vrfy_subtree, - * verify that the dup tree type is correct--i.e., it's a recno - * if DUPSORT is not set and a btree if it is. - * - * PUBLIC: int __db_vrfy_duptype - * PUBLIC: __P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t)); - */ -int -__db_vrfy_duptype(dbp, vdp, pgno, flags) - DB *dbp; - VRFY_DBINFO *vdp; - db_pgno_t pgno; - u_int32_t flags; -{ - DB_ENV *dbenv; - VRFY_PAGEINFO *pip; - int ret, isbad; - - dbenv = dbp->dbenv; - isbad = 0; - - if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) - return (ret); - - switch (pip->type) { - case P_IBTREE: - case P_LDUP: - if (!LF_ISSET(ST_DUPSORT)) { - EPRINT((dbenv, - "Page %lu: sorted duplicate set in unsorted-dup database", - (u_long)pgno)); - isbad = 1; - } - break; - case P_IRECNO: - case P_LRECNO: - if (LF_ISSET(ST_DUPSORT)) { - EPRINT((dbenv, - "Page %lu: unsorted duplicate set in sorted-dup database", - (u_long)pgno)); - isbad = 1; - } - break; - default: - /* - * If the page is entirely zeroed, its pip->type will be a lie - * (we assumed it was a hash page, as they're allowed to be - * zeroed); handle this case specially. - */ - if (F_ISSET(pip, VRFY_IS_ALLZEROES)) - ZEROPG_ERR_PRINT(dbenv, pgno, "duplicate page"); - else - EPRINT((dbenv, - "Page %lu: duplicate page of inappropriate type %lu", - (u_long)pgno, (u_long)pip->type)); - isbad = 1; - break; - } - - if ((ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0) - return (ret); - return (isbad == 1 ? DB_VERIFY_BAD : 0); -} - -/* - * __db_salvage_duptree -- - * Attempt to salvage a given duplicate tree, given its alleged root. - * - * The key that corresponds to this dup set has been passed to us - * in DBT *key. Because data items follow keys, though, it has been - * printed once already. - * - * The basic idea here is that pgno ought to be a P_LDUP, a P_LRECNO, a - * P_IBTREE, or a P_IRECNO. If it's an internal page, use the verifier - * functions to make sure it's safe; if it's not, we simply bail and the - * data will have to be printed with no key later on. if it is safe, - * recurse on each of its children. - * - * Whether or not it's safe, if it's a leaf page, __bam_salvage it. - * - * At all times, use the DB hanging off vdp to mark and check what we've - * done, so each page gets printed exactly once and we don't get caught - * in any cycles. - * - * PUBLIC: int __db_salvage_duptree __P((DB *, VRFY_DBINFO *, db_pgno_t, - * PUBLIC: DBT *, void *, int (*)(void *, const void *), u_int32_t)); - */ -int -__db_salvage_duptree(dbp, vdp, pgno, key, handle, callback, flags) - DB *dbp; - VRFY_DBINFO *vdp; - db_pgno_t pgno; - DBT *key; - void *handle; - int (*callback) __P((void *, const void *)); - u_int32_t flags; -{ - DB_MPOOLFILE *mpf; - PAGE *h; - int ret, t_ret; - - mpf = dbp->mpf; - - if (pgno == PGNO_INVALID || !IS_VALID_PGNO(pgno)) - return (DB_VERIFY_BAD); - - /* We have a plausible page. Try it. */ - if ((ret = __memp_fget(mpf, &pgno, 0, &h)) != 0) - return (ret); - - switch (TYPE(h)) { - case P_IBTREE: - case P_IRECNO: - if ((ret = __db_vrfy_common(dbp, vdp, h, pgno, flags)) != 0) - goto err; - if ((ret = __bam_vrfy(dbp, - vdp, h, pgno, flags | DB_NOORDERCHK)) != 0 || - (ret = __db_salvage_markdone(vdp, pgno)) != 0) - goto err; - /* - * We have a known-healthy internal page. Walk it. - */ - if ((ret = __bam_salvage_walkdupint(dbp, vdp, h, key, - handle, callback, flags)) != 0) - goto err; - break; - case P_LRECNO: - case P_LDUP: - if ((ret = __bam_salvage(dbp, - vdp, pgno, TYPE(h), h, handle, callback, key, flags)) != 0) - goto err; - break; - default: - ret = DB_VERIFY_BAD; - goto err; - } - -err: if ((t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0) - ret = t_ret; - return (ret); -} - -/* - * __db_salvage_subdbs -- - * Check and see if this database has subdbs; if so, try to salvage - * them independently. - */ -static int -__db_salvage_subdbs(dbp, vdp, handle, callback, flags, hassubsp) - DB *dbp; - VRFY_DBINFO *vdp; - void *handle; - int (*callback) __P((void *, const void *)); - u_int32_t flags; - int *hassubsp; -{ - DB *pgset; - DBC *pgsc; - DB_ENV *dbenv; - DB_MPOOLFILE *mpf; - PAGE *h; - VRFY_PAGEINFO *pip; - db_pgno_t p, meta_pgno; - int ret, t_ret; - - *hassubsp = 0; - - dbenv = dbp->dbenv; - pgset = NULL; - pgsc = NULL; - mpf = dbp->mpf; - h = NULL; - pip = NULL; - ret = 0; - - /* - * Check to make sure the page is OK and find out if it contains - * subdatabases. - */ - meta_pgno = PGNO_BASE_MD; - if ((t_ret = __memp_fget(mpf, &meta_pgno, 0, &h)) == 0 && - (t_ret = __db_vrfy_common(dbp, vdp, h, PGNO_BASE_MD, flags)) == 0 && - (t_ret = __db_salvage( - dbp, vdp, PGNO_BASE_MD, h, handle, callback, flags)) == 0 && - (t_ret = __db_vrfy_getpageinfo(vdp, 0, &pip)) == 0) - if (F_ISSET(pip, VRFY_HAS_SUBDBS)) - *hassubsp = 1; - if (pip != NULL && - (t_ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0 && ret == 0) - ret = t_ret; - if (h != NULL) { - if ((t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0) - ret = t_ret; - h = NULL; - } - if (ret != 0 || *hassubsp == 0) - return (ret); - - /* - * We have subdbs. Try to crack them. - * - * To do so, get a set of leaf pages in the master database, and then - * walk each of the valid ones, salvaging subdbs as we go. If any - * prove invalid, just drop them; we'll pick them up on a later pass. - */ - if ((ret = __db_vrfy_pgset(dbenv, dbp->pgsize, &pgset)) != 0) - goto err; - if ((ret = __db_meta2pgset(dbp, vdp, PGNO_BASE_MD, flags, pgset)) != 0) - goto err; - if ((ret = __db_cursor(pgset, NULL, &pgsc, 0)) != 0) - goto err; - while ((t_ret = __db_vrfy_pgset_next(pgsc, &p)) == 0) { - if ((t_ret = __memp_fget(mpf, &p, 0, &h)) == 0 && - (t_ret = __db_vrfy_common(dbp, vdp, h, p, flags)) == 0 && - (t_ret = - __bam_vrfy(dbp, vdp, h, p, flags | DB_NOORDERCHK)) == 0) - t_ret = __db_salvage_subdbpg( - dbp, vdp, h, handle, callback, flags); - if (t_ret != 0 && ret == 0) - ret = t_ret; - if (h != NULL) { - if ((t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0) - ret = t_ret; - h = NULL; - } - } - - if (t_ret != DB_NOTFOUND && ret == 0) - ret = t_ret; - -err: if (pgsc != NULL && (t_ret = __db_c_close(pgsc)) != 0 && ret == 0) - ret = t_ret; - if (pgset != NULL && - (t_ret = __db_close(pgset, NULL, 0)) != 0 && ret ==0) - ret = t_ret; - if (h != NULL && (t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0) - ret = t_ret; - return (ret); -} - -/* - * __db_salvage_subdbpg -- - * Given a known-good leaf page in the master database, salvage all - * leaf pages corresponding to each subdb. - */ -static int -__db_salvage_subdbpg(dbp, vdp, master, handle, callback, flags) - DB *dbp; - VRFY_DBINFO *vdp; - PAGE *master; - void *handle; - int (*callback) __P((void *, const void *)); - u_int32_t flags; -{ - BKEYDATA *bkkey, *bkdata; - BOVERFLOW *bo; - DB *pgset; - DBC *pgsc; - DBT key; - DB_ENV *dbenv; - DB_MPOOLFILE *mpf; - PAGE *subpg; - db_indx_t i; - db_pgno_t meta_pgno, p; - int ret, err_ret, t_ret; - char *subdbname; - - dbenv = dbp->dbenv; - mpf = dbp->mpf; - ret = err_ret = 0; - subdbname = NULL; - - if ((ret = __db_vrfy_pgset(dbenv, dbp->pgsize, &pgset)) != 0) - return (ret); - - /* - * For each entry, get and salvage the set of pages - * corresponding to that entry. - */ - for (i = 0; i < NUM_ENT(master); i += P_INDX) { - bkkey = GET_BKEYDATA(dbp, master, i); - bkdata = GET_BKEYDATA(dbp, master, i + O_INDX); - - /* Get the subdatabase name. */ - if (B_TYPE(bkkey->type) == B_OVERFLOW) { - /* - * We can, in principle anyway, have a subdb - * name so long it overflows. Ick. - */ - bo = (BOVERFLOW *)bkkey; - if ((ret = __db_safe_goff(dbp, vdp, - bo->pgno, &key, &subdbname, flags)) != 0) { - err_ret = DB_VERIFY_BAD; - continue; - } - - /* Nul-terminate it. */ - if ((ret = __os_realloc(dbenv, - key.size + 1, &subdbname)) != 0) - goto err; - subdbname[key.size] = '\0'; - } else if (B_TYPE(bkkey->type) == B_KEYDATA) { - if ((ret = __os_realloc(dbenv, - bkkey->len + 1, &subdbname)) != 0) - goto err; - memcpy(subdbname, bkkey->data, bkkey->len); - subdbname[bkkey->len] = '\0'; - } - - /* Get the corresponding pgno. */ - if (bkdata->len != sizeof(db_pgno_t)) { - err_ret = DB_VERIFY_BAD; - continue; - } - memcpy(&meta_pgno, - (db_pgno_t *)bkdata->data, sizeof(db_pgno_t)); - - /* - * Subdatabase meta pgnos are stored in network byte - * order for cross-endian compatibility. Swap if appropriate. - */ - DB_NTOHL(&meta_pgno); - - /* If we can't get the subdb meta page, just skip the subdb. */ - if (!IS_VALID_PGNO(meta_pgno) || - (ret = __memp_fget(mpf, &meta_pgno, 0, &subpg)) != 0) { - err_ret = ret; - continue; - } - - /* - * Verify the subdatabase meta page. This has two functions. - * First, if it's bad, we have no choice but to skip the subdb - * and let the pages just get printed on a later pass. Second, - * the access-method-specific meta verification routines record - * the various state info (such as the presence of dups) - * that we need for __db_prheader(). - */ - if ((ret = - __db_vrfy_common(dbp, vdp, subpg, meta_pgno, flags)) != 0) { - err_ret = ret; - (void)__memp_fput(mpf, subpg, 0); - continue; - } - switch (TYPE(subpg)) { - case P_BTREEMETA: - if ((ret = __bam_vrfy_meta(dbp, - vdp, (BTMETA *)subpg, meta_pgno, flags)) != 0) { - err_ret = ret; - (void)__memp_fput(mpf, subpg, 0); - continue; - } - break; - case P_HASHMETA: - if ((ret = __ham_vrfy_meta(dbp, - vdp, (HMETA *)subpg, meta_pgno, flags)) != 0) { - err_ret = ret; - (void)__memp_fput(mpf, subpg, 0); - continue; - } - break; - default: - /* This isn't an appropriate page; skip this subdb. */ - err_ret = DB_VERIFY_BAD; - continue; - } - - if ((ret = __memp_fput(mpf, subpg, 0)) != 0) { - err_ret = ret; - continue; - } - - /* Print a subdatabase header. */ - if ((ret = __db_prheader(dbp, - subdbname, 0, 0, handle, callback, vdp, meta_pgno)) != 0) - goto err; - - if ((ret = __db_meta2pgset(dbp, vdp, meta_pgno, - flags, pgset)) != 0) { - err_ret = ret; - continue; - } - - if ((ret = __db_cursor(pgset, NULL, &pgsc, 0)) != 0) - goto err; - while ((ret = __db_vrfy_pgset_next(pgsc, &p)) == 0) { - if ((ret = __memp_fget(mpf, &p, 0, &subpg)) != 0) { - err_ret = ret; - continue; - } - if ((ret = __db_salvage(dbp, vdp, p, subpg, - handle, callback, flags)) != 0) - err_ret = ret; - if ((ret = __memp_fput(mpf, subpg, 0)) != 0) - err_ret = ret; - } - - if (ret != DB_NOTFOUND) - goto err; - - if ((ret = __db_c_close(pgsc)) != 0) - goto err; - if ((ret = __db_prfooter(handle, callback)) != 0) - goto err; - } -err: if (subdbname) - __os_free(dbenv, subdbname); - - if ((t_ret = __db_close(pgset, NULL, 0)) != 0) - ret = t_ret; - - if ((t_ret = __db_salvage_markdone(vdp, PGNO(master))) != 0) - return (t_ret); - - return ((err_ret != 0) ? err_ret : ret); -} - -/* - * __db_meta2pgset -- - * Given a known-safe meta page number, return the set of pages - * corresponding to the database it represents. Return DB_VERIFY_BAD if - * it's not a suitable meta page or is invalid. - */ -static int -__db_meta2pgset(dbp, vdp, pgno, flags, pgset) - DB *dbp; - VRFY_DBINFO *vdp; - db_pgno_t pgno; - u_int32_t flags; - DB *pgset; -{ - DB_MPOOLFILE *mpf; - PAGE *h; - int ret, t_ret; - - mpf = dbp->mpf; - - if ((ret = __memp_fget(mpf, &pgno, 0, &h)) != 0) - return (ret); - - switch (TYPE(h)) { - case P_BTREEMETA: - ret = __bam_meta2pgset(dbp, vdp, (BTMETA *)h, flags, pgset); - break; - case P_HASHMETA: - ret = __ham_meta2pgset(dbp, vdp, (HMETA *)h, flags, pgset); - break; - default: - ret = DB_VERIFY_BAD; - break; - } - - if ((t_ret = __memp_fput(mpf, h, 0)) != 0) - return (t_ret); - return (ret); -} - -/* - * __db_guesspgsize -- - * Try to guess what the pagesize is if the one on the meta page - * and the one in the db are invalid. - */ -static u_int -__db_guesspgsize(dbenv, fhp) - DB_ENV *dbenv; - DB_FH *fhp; -{ - db_pgno_t i; - size_t nr; - u_int32_t guess; - u_int8_t type; - - for (guess = DB_MAX_PGSIZE; guess >= DB_MIN_PGSIZE; guess >>= 1) { - /* - * We try to read three pages ahead after the first one - * and make sure we have plausible types for all of them. - * If the seeks fail, continue with a smaller size; - * we're probably just looking past the end of the database. - * If they succeed and the types are reasonable, also continue - * with a size smaller; we may be looking at pages N, - * 2N, and 3N for some N > 1. - * - * As soon as we hit an invalid type, we stop and return - * our previous guess; that last one was probably the page size. - */ - for (i = 1; i <= 3; i++) { - if (__os_seek(dbenv, fhp, guess, - i, SSZ(DBMETA, type), 0, DB_OS_SEEK_SET) != 0) - break; - if (__os_read(dbenv, - fhp, &type, 1, &nr) != 0 || nr == 0) - break; - if (type == P_INVALID || type >= P_PAGETYPE_MAX) - return (guess << 1); - } - } - - /* - * If we're just totally confused--the corruption takes up most of the - * beginning pages of the database--go with the default size. - */ - return (DB_DEF_IOSIZE); -} diff --git a/storage/bdb/db/db_vrfy_stub.c b/storage/bdb/db/db_vrfy_stub.c deleted file mode 100644 index 46f0b1134e1..00000000000 --- a/storage/bdb/db/db_vrfy_stub.c +++ /dev/null @@ -1,103 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_vrfy_stub.c,v 12.1 2005/06/16 20:21:15 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef HAVE_VERIFY -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_am.h" -#include "dbinc/db_verify.h" - -/* - * If the library wasn't compiled with the verification support, various - * routines aren't available. Stub them here, returning an appropriate - * error. - */ - -static int __db_novrfy __P((DB_ENV *)); - -/* - * __db_novrfy -- - * Error when a Berkeley DB build doesn't include the access method. - */ -static int -__db_novrfy(dbenv) - DB_ENV *dbenv; -{ - __db_err(dbenv, - "library build did not include support for database verification"); - return (DB_OPNOTSUP); -} - -int -__db_verify_pp(dbp, file, database, outfile, flags) - DB *dbp; - const char *file, *database; - FILE *outfile; - u_int32_t flags; -{ - int ret; - - COMPQUIET(file, NULL); - COMPQUIET(database, NULL); - COMPQUIET(outfile, NULL); - COMPQUIET(flags, 0); - - ret = __db_novrfy(dbp->dbenv); - - /* The verify method is a destructor. */ - (void)__db_close(dbp, NULL, 0); - - return (ret); -} - -int -__db_verify_internal(dbp, name, subdb, handle, callback, flags) - DB *dbp; - const char *name, *subdb; - void *handle; - int (*callback) __P((void *, const void *)); - u_int32_t flags; -{ - COMPQUIET(dbp, NULL); - COMPQUIET(name, NULL); - COMPQUIET(subdb, NULL); - COMPQUIET(handle, NULL); - COMPQUIET(callback, NULL); - COMPQUIET(flags, 0); - return (0); -} - -int -__db_vrfy_getpageinfo(vdp, pgno, pipp) - VRFY_DBINFO *vdp; - db_pgno_t pgno; - VRFY_PAGEINFO **pipp; -{ - COMPQUIET(pgno, 0); - COMPQUIET(pipp, NULL); - return (__db_novrfy(vdp->pgdbp->dbenv)); -} - -int -__db_vrfy_putpageinfo(dbenv, vdp, pip) - DB_ENV *dbenv; - VRFY_DBINFO *vdp; - VRFY_PAGEINFO *pip; -{ - COMPQUIET(vdp, NULL); - COMPQUIET(pip, NULL); - return (__db_novrfy(dbenv)); -} -#endif /* !HAVE_VERIFY */ diff --git a/storage/bdb/db/db_vrfyutil.c b/storage/bdb/db/db_vrfyutil.c deleted file mode 100644 index f1508872238..00000000000 --- a/storage/bdb/db/db_vrfyutil.c +++ /dev/null @@ -1,898 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2000-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_vrfyutil.c,v 12.5 2005/06/16 20:21:15 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_verify.h" -#include "dbinc/db_am.h" - -static int __db_vrfy_childinc __P((DBC *, VRFY_CHILDINFO *)); -static int __db_vrfy_pageinfo_create __P((DB_ENV *, VRFY_PAGEINFO **)); - -/* - * __db_vrfy_dbinfo_create -- - * Allocate and initialize a VRFY_DBINFO structure. - * - * PUBLIC: int __db_vrfy_dbinfo_create - * PUBLIC: __P((DB_ENV *, u_int32_t, VRFY_DBINFO **)); - */ -int -__db_vrfy_dbinfo_create(dbenv, pgsize, vdpp) - DB_ENV *dbenv; - u_int32_t pgsize; - VRFY_DBINFO **vdpp; -{ - DB *cdbp, *pgdbp, *pgset; - VRFY_DBINFO *vdp; - int ret; - - vdp = NULL; - cdbp = pgdbp = pgset = NULL; - - if ((ret = __os_calloc(NULL, 1, sizeof(VRFY_DBINFO), &vdp)) != 0) - goto err; - - if ((ret = db_create(&cdbp, dbenv, 0)) != 0) - goto err; - - if ((ret = __db_set_flags(cdbp, DB_DUP)) != 0) - goto err; - - if ((ret = __db_set_pagesize(cdbp, pgsize)) != 0) - goto err; - - if ((ret = __db_open(cdbp, - NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0600, PGNO_BASE_MD)) != 0) - goto err; - - if ((ret = db_create(&pgdbp, dbenv, 0)) != 0) - goto err; - - if ((ret = __db_set_pagesize(pgdbp, pgsize)) != 0) - goto err; - - if ((ret = __db_open(pgdbp, - NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0600, PGNO_BASE_MD)) != 0) - goto err; - - if ((ret = __db_vrfy_pgset(dbenv, pgsize, &pgset)) != 0) - goto err; - - LIST_INIT(&vdp->subdbs); - LIST_INIT(&vdp->activepips); - - vdp->cdbp = cdbp; - vdp->pgdbp = pgdbp; - vdp->pgset = pgset; - *vdpp = vdp; - return (0); - -err: if (cdbp != NULL) - (void)__db_close(cdbp, NULL, 0); - if (pgdbp != NULL) - (void)__db_close(pgdbp, NULL, 0); - if (vdp != NULL) - __os_free(dbenv, vdp); - return (ret); -} - -/* - * __db_vrfy_dbinfo_destroy -- - * Destructor for VRFY_DBINFO. Destroys VRFY_PAGEINFOs and deallocates - * structure. - * - * PUBLIC: int __db_vrfy_dbinfo_destroy __P((DB_ENV *, VRFY_DBINFO *)); - */ -int -__db_vrfy_dbinfo_destroy(dbenv, vdp) - DB_ENV *dbenv; - VRFY_DBINFO *vdp; -{ - VRFY_CHILDINFO *c; - int t_ret, ret; - - ret = 0; - - /* - * Discard active page structures. Ideally there wouldn't be any, - * but in some error cases we may not have cleared them all out. - */ - while (LIST_FIRST(&vdp->activepips) != NULL) - if ((t_ret = __db_vrfy_putpageinfo( - dbenv, vdp, LIST_FIRST(&vdp->activepips))) != 0) { - if (ret == 0) - ret = t_ret; - break; - } - - /* Discard subdatabase list structures. */ - while ((c = LIST_FIRST(&vdp->subdbs)) != NULL) { - LIST_REMOVE(c, links); - __os_free(NULL, c); - } - - if ((t_ret = __db_close(vdp->pgdbp, NULL, 0)) != 0) - ret = t_ret; - - if ((t_ret = __db_close(vdp->cdbp, NULL, 0)) != 0 && ret == 0) - ret = t_ret; - - if ((t_ret = __db_close(vdp->pgset, NULL, 0)) != 0 && ret == 0) - ret = t_ret; - - if (vdp->extents != NULL) - __os_free(dbenv, vdp->extents); - __os_free(dbenv, vdp); - return (ret); -} - -/* - * __db_vrfy_getpageinfo -- - * Get a PAGEINFO structure for a given page, creating it if necessary. - * - * PUBLIC: int __db_vrfy_getpageinfo - * PUBLIC: __P((VRFY_DBINFO *, db_pgno_t, VRFY_PAGEINFO **)); - */ -int -__db_vrfy_getpageinfo(vdp, pgno, pipp) - VRFY_DBINFO *vdp; - db_pgno_t pgno; - VRFY_PAGEINFO **pipp; -{ - DBT key, data; - DB *pgdbp; - VRFY_PAGEINFO *pip; - int ret; - - /* - * We want a page info struct. There are three places to get it from, - * in decreasing order of preference: - * - * 1. vdp->activepips. If it's already "checked out", we're - * already using it, we return the same exact structure with a - * bumped refcount. This is necessary because this code is - * replacing array accesses, and it's common for f() to make some - * changes to a pip, and then call g() and h() which each make - * changes to the same pip. vdps are never shared between threads - * (they're never returned to the application), so this is safe. - * 2. The pgdbp. It's not in memory, but it's in the database, so - * get it, give it a refcount of 1, and stick it on activepips. - * 3. malloc. It doesn't exist yet; create it, then stick it on - * activepips. We'll put it in the database when we putpageinfo - * later. - */ - - /* Case 1. */ - for (pip = LIST_FIRST(&vdp->activepips); pip != NULL; - pip = LIST_NEXT(pip, links)) - if (pip->pgno == pgno) - /* Found it. */ - goto found; - - /* Case 2. */ - pgdbp = vdp->pgdbp; - memset(&key, 0, sizeof(DBT)); - memset(&data, 0, sizeof(DBT)); - F_SET(&data, DB_DBT_MALLOC); - key.data = &pgno; - key.size = sizeof(db_pgno_t); - - if ((ret = __db_get(pgdbp, NULL, &key, &data, 0)) == 0) { - /* Found it. */ - DB_ASSERT(data.size == sizeof(VRFY_PAGEINFO)); - pip = data.data; - LIST_INSERT_HEAD(&vdp->activepips, pip, links); - goto found; - } else if (ret != DB_NOTFOUND) /* Something nasty happened. */ - return (ret); - - /* Case 3 */ - if ((ret = __db_vrfy_pageinfo_create(pgdbp->dbenv, &pip)) != 0) - return (ret); - - LIST_INSERT_HEAD(&vdp->activepips, pip, links); -found: pip->pi_refcount++; - - *pipp = pip; - return (0); -} - -/* - * __db_vrfy_putpageinfo -- - * Put back a VRFY_PAGEINFO that we're done with. - * - * PUBLIC: int __db_vrfy_putpageinfo __P((DB_ENV *, - * PUBLIC: VRFY_DBINFO *, VRFY_PAGEINFO *)); - */ -int -__db_vrfy_putpageinfo(dbenv, vdp, pip) - DB_ENV *dbenv; - VRFY_DBINFO *vdp; - VRFY_PAGEINFO *pip; -{ - DBT key, data; - DB *pgdbp; - VRFY_PAGEINFO *p; - int ret; - - if (--pip->pi_refcount > 0) - return (0); - - pgdbp = vdp->pgdbp; - memset(&key, 0, sizeof(DBT)); - memset(&data, 0, sizeof(DBT)); - - key.data = &pip->pgno; - key.size = sizeof(db_pgno_t); - data.data = pip; - data.size = sizeof(VRFY_PAGEINFO); - - if ((ret = __db_put(pgdbp, NULL, &key, &data, 0)) != 0) - return (ret); - - for (p = - LIST_FIRST(&vdp->activepips); p != NULL; p = LIST_NEXT(p, links)) - if (p == pip) - break; - if (p != NULL) - LIST_REMOVE(p, links); - - __os_ufree(dbenv, p); - return (0); -} - -/* - * __db_vrfy_pgset -- - * Create a temporary database for the storing of sets of page numbers. - * (A mapping from page number to int, used by the *_meta2pgset functions, - * as well as for keeping track of which pages the verifier has seen.) - * - * PUBLIC: int __db_vrfy_pgset __P((DB_ENV *, u_int32_t, DB **)); - */ -int -__db_vrfy_pgset(dbenv, pgsize, dbpp) - DB_ENV *dbenv; - u_int32_t pgsize; - DB **dbpp; -{ - DB *dbp; - int ret; - - if ((ret = db_create(&dbp, dbenv, 0)) != 0) - return (ret); - if ((ret = __db_set_pagesize(dbp, pgsize)) != 0) - goto err; - if ((ret = __db_open(dbp, - NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0600, PGNO_BASE_MD)) == 0) - *dbpp = dbp; - else -err: (void)__db_close(dbp, NULL, 0); - - return (ret); -} - -/* - * __db_vrfy_pgset_get -- - * Get the value associated in a page set with a given pgno. Return - * a 0 value (and succeed) if we've never heard of this page. - * - * PUBLIC: int __db_vrfy_pgset_get __P((DB *, db_pgno_t, int *)); - */ -int -__db_vrfy_pgset_get(dbp, pgno, valp) - DB *dbp; - db_pgno_t pgno; - int *valp; -{ - DBT key, data; - int ret, val; - - memset(&key, 0, sizeof(DBT)); - memset(&data, 0, sizeof(DBT)); - - key.data = &pgno; - key.size = sizeof(db_pgno_t); - data.data = &val; - data.ulen = sizeof(int); - F_SET(&data, DB_DBT_USERMEM); - - if ((ret = __db_get(dbp, NULL, &key, &data, 0)) == 0) { - DB_ASSERT(data.size == sizeof(int)); - } else if (ret == DB_NOTFOUND) - val = 0; - else - return (ret); - - *valp = val; - return (0); -} - -/* - * __db_vrfy_pgset_inc -- - * Increment the value associated with a pgno by 1. - * - * PUBLIC: int __db_vrfy_pgset_inc __P((DB *, db_pgno_t)); - */ -int -__db_vrfy_pgset_inc(dbp, pgno) - DB *dbp; - db_pgno_t pgno; -{ - DBT key, data; - int ret; - int val; - - memset(&key, 0, sizeof(DBT)); - memset(&data, 0, sizeof(DBT)); - - val = 0; - - key.data = &pgno; - key.size = sizeof(db_pgno_t); - data.data = &val; - data.ulen = sizeof(int); - F_SET(&data, DB_DBT_USERMEM); - - if ((ret = __db_get(dbp, NULL, &key, &data, 0)) == 0) { - DB_ASSERT(data.size == sizeof(int)); - } else if (ret != DB_NOTFOUND) - return (ret); - - data.size = sizeof(int); - ++val; - - return (__db_put(dbp, NULL, &key, &data, 0)); -} - -/* - * __db_vrfy_pgset_next -- - * Given a cursor open in a pgset database, get the next page in the - * set. - * - * PUBLIC: int __db_vrfy_pgset_next __P((DBC *, db_pgno_t *)); - */ -int -__db_vrfy_pgset_next(dbc, pgnop) - DBC *dbc; - db_pgno_t *pgnop; -{ - DBT key, data; - db_pgno_t pgno; - int ret; - - memset(&key, 0, sizeof(DBT)); - memset(&data, 0, sizeof(DBT)); - /* We don't care about the data, just the keys. */ - F_SET(&data, DB_DBT_USERMEM | DB_DBT_PARTIAL); - F_SET(&key, DB_DBT_USERMEM); - key.data = &pgno; - key.ulen = sizeof(db_pgno_t); - - if ((ret = __db_c_get(dbc, &key, &data, DB_NEXT)) != 0) - return (ret); - - DB_ASSERT(key.size == sizeof(db_pgno_t)); - *pgnop = pgno; - - return (0); -} - -/* - * __db_vrfy_childcursor -- - * Create a cursor to walk the child list with. Returns with a nonzero - * final argument if the specified page has no children. - * - * PUBLIC: int __db_vrfy_childcursor __P((VRFY_DBINFO *, DBC **)); - */ -int -__db_vrfy_childcursor(vdp, dbcp) - VRFY_DBINFO *vdp; - DBC **dbcp; -{ - DB *cdbp; - DBC *dbc; - int ret; - - cdbp = vdp->cdbp; - - if ((ret = __db_cursor(cdbp, NULL, &dbc, 0)) == 0) - *dbcp = dbc; - - return (ret); -} - -/* - * __db_vrfy_childput -- - * Add a child structure to the set for a given page. - * - * PUBLIC: int __db_vrfy_childput - * PUBLIC: __P((VRFY_DBINFO *, db_pgno_t, VRFY_CHILDINFO *)); - */ -int -__db_vrfy_childput(vdp, pgno, cip) - VRFY_DBINFO *vdp; - db_pgno_t pgno; - VRFY_CHILDINFO *cip; -{ - DB *cdbp; - DBC *cc; - DBT key, data; - VRFY_CHILDINFO *oldcip; - int ret; - - cdbp = vdp->cdbp; - memset(&key, 0, sizeof(DBT)); - memset(&data, 0, sizeof(DBT)); - - key.data = &pgno; - key.size = sizeof(db_pgno_t); - - /* - * We want to avoid adding multiple entries for a single child page; - * we only need to verify each child once, even if a child (such - * as an overflow key) is multiply referenced. - * - * However, we also need to make sure that when walking the list - * of children, we encounter them in the order they're referenced - * on a page. (This permits us, for example, to verify the - * prev_pgno/next_pgno chain of Btree leaf pages.) - * - * Check the child database to make sure that this page isn't - * already a child of the specified page number. If it's not, - * put it at the end of the duplicate set. - */ - if ((ret = __db_vrfy_childcursor(vdp, &cc)) != 0) - return (ret); - for (ret = __db_vrfy_ccset(cc, pgno, &oldcip); ret == 0; - ret = __db_vrfy_ccnext(cc, &oldcip)) - if (oldcip->pgno == cip->pgno) { - /* - * Found a matching child. Increment its reference - * count--we've run into it again--but don't put it - * again. - */ - if ((ret = __db_vrfy_childinc(cc, oldcip)) != 0 || - (ret = __db_vrfy_ccclose(cc)) != 0) - return (ret); - return (0); - } - if (ret != DB_NOTFOUND) { - (void)__db_vrfy_ccclose(cc); - return (ret); - } - if ((ret = __db_vrfy_ccclose(cc)) != 0) - return (ret); - - cip->refcnt = 1; - data.data = cip; - data.size = sizeof(VRFY_CHILDINFO); - - return (__db_put(cdbp, NULL, &key, &data, 0)); -} - -/* - * __db_vrfy_childinc -- - * Increment the refcount of the VRFY_CHILDINFO struct that the child - * cursor is pointing to. (The caller has just retrieved this struct, and - * passes it in as cip to save us a get.) - */ -static int -__db_vrfy_childinc(dbc, cip) - DBC *dbc; - VRFY_CHILDINFO *cip; -{ - DBT key, data; - - memset(&key, 0, sizeof(DBT)); - memset(&data, 0, sizeof(DBT)); - - cip->refcnt++; - data.data = cip; - data.size = sizeof(VRFY_CHILDINFO); - - return (__db_c_put(dbc, &key, &data, DB_CURRENT)); -} - -/* - * __db_vrfy_ccset -- - * Sets a cursor created with __db_vrfy_childcursor to the first - * child of the given pgno, and returns it in the third arg. - * - * PUBLIC: int __db_vrfy_ccset __P((DBC *, db_pgno_t, VRFY_CHILDINFO **)); - */ -int -__db_vrfy_ccset(dbc, pgno, cipp) - DBC *dbc; - db_pgno_t pgno; - VRFY_CHILDINFO **cipp; -{ - DBT key, data; - int ret; - - memset(&key, 0, sizeof(DBT)); - memset(&data, 0, sizeof(DBT)); - - key.data = &pgno; - key.size = sizeof(db_pgno_t); - - if ((ret = __db_c_get(dbc, &key, &data, DB_SET)) != 0) - return (ret); - - DB_ASSERT(data.size == sizeof(VRFY_CHILDINFO)); - *cipp = (VRFY_CHILDINFO *)data.data; - - return (0); -} - -/* - * __db_vrfy_ccnext -- - * Gets the next child of the given cursor created with - * __db_vrfy_childcursor, and returns it in the memory provided in the - * second arg. - * - * PUBLIC: int __db_vrfy_ccnext __P((DBC *, VRFY_CHILDINFO **)); - */ -int -__db_vrfy_ccnext(dbc, cipp) - DBC *dbc; - VRFY_CHILDINFO **cipp; -{ - DBT key, data; - int ret; - - memset(&key, 0, sizeof(DBT)); - memset(&data, 0, sizeof(DBT)); - - if ((ret = __db_c_get(dbc, &key, &data, DB_NEXT_DUP)) != 0) - return (ret); - - DB_ASSERT(data.size == sizeof(VRFY_CHILDINFO)); - *cipp = (VRFY_CHILDINFO *)data.data; - - return (0); -} - -/* - * __db_vrfy_ccclose -- - * Closes the cursor created with __db_vrfy_childcursor. - * - * This doesn't actually do anything interesting now, but it's - * not inconceivable that we might change the internal database usage - * and keep the interfaces the same, and a function call here or there - * seldom hurts anyone. - * - * PUBLIC: int __db_vrfy_ccclose __P((DBC *)); - */ -int -__db_vrfy_ccclose(dbc) - DBC *dbc; -{ - - return (__db_c_close(dbc)); -} - -/* - * __db_vrfy_pageinfo_create -- - * Constructor for VRFY_PAGEINFO; allocates and initializes. - */ -static int -__db_vrfy_pageinfo_create(dbenv, pipp) - DB_ENV *dbenv; - VRFY_PAGEINFO **pipp; -{ - VRFY_PAGEINFO *pip; - int ret; - - /* - * pageinfo structs are sometimes allocated here and sometimes - * allocated by fetching them from a database with DB_DBT_MALLOC. - * There's no easy way for the destructor to tell which was - * used, and so we always allocate with __os_umalloc so we can free - * with __os_ufree. - */ - if ((ret = __os_umalloc(dbenv, sizeof(VRFY_PAGEINFO), &pip)) != 0) - return (ret); - memset(pip, 0, sizeof(VRFY_PAGEINFO)); - - *pipp = pip; - return (0); -} - -/* - * __db_salvage_init -- - * Set up salvager database. - * - * PUBLIC: int __db_salvage_init __P((VRFY_DBINFO *)); - */ -int -__db_salvage_init(vdp) - VRFY_DBINFO *vdp; -{ - DB *dbp; - int ret; - - if ((ret = db_create(&dbp, NULL, 0)) != 0) - return (ret); - - if ((ret = __db_set_pagesize(dbp, 1024)) != 0) - goto err; - - if ((ret = __db_open(dbp, - NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0, PGNO_BASE_MD)) != 0) - goto err; - - vdp->salvage_pages = dbp; - return (0); - -err: (void)__db_close(dbp, NULL, 0); - return (ret); -} - -/* - * __db_salvage_destroy -- - * Close salvager database. - * PUBLIC: void __db_salvage_destroy __P((VRFY_DBINFO *)); - */ -void -__db_salvage_destroy(vdp) - VRFY_DBINFO *vdp; -{ - (void)__db_close(vdp->salvage_pages, NULL, 0); -} - -/* - * __db_salvage_getnext -- - * Get the next (first) unprinted page in the database of pages we need to - * print still. Delete entries for any already-printed pages we encounter - * in this search, as well as the page we're returning. - * - * PUBLIC: int __db_salvage_getnext - * PUBLIC: __P((VRFY_DBINFO *, DBC **, db_pgno_t *, u_int32_t *, int)); - */ -int -__db_salvage_getnext(vdp, dbcp, pgnop, pgtypep, skip_overflow) - VRFY_DBINFO *vdp; - DBC **dbcp; - db_pgno_t *pgnop; - u_int32_t *pgtypep; - int skip_overflow; -{ - DB *dbp; - DBT key, data; - int ret; - u_int32_t pgtype; - - dbp = vdp->salvage_pages; - - memset(&key, 0, sizeof(DBT)); - memset(&data, 0, sizeof(DBT)); - - if (*dbcp == NULL && - (ret = __db_cursor(dbp, NULL, dbcp, 0)) != 0) - return (ret); - - while ((ret = __db_c_get(*dbcp, &key, &data, DB_NEXT)) == 0) { - DB_ASSERT(data.size == sizeof(u_int32_t)); - memcpy(&pgtype, data.data, sizeof(pgtype)); - - if (skip_overflow && pgtype == SALVAGE_OVERFLOW) - continue; - - if ((ret = __db_c_del(*dbcp, 0)) != 0) - return (ret); - if (pgtype != SALVAGE_IGNORE) { - DB_ASSERT(key.size == sizeof(db_pgno_t)); - DB_ASSERT(data.size == sizeof(u_int32_t)); - - *pgnop = *(db_pgno_t *)key.data; - *pgtypep = *(u_int32_t *)data.data; - break; - } - } - - return (ret); -} - -/* - * __db_salvage_isdone -- - * Return whether or not the given pgno is already marked - * SALVAGE_IGNORE (meaning that we don't need to print it again). - * - * Returns DB_KEYEXIST if it is marked, 0 if not, or another error on - * error. - * - * PUBLIC: int __db_salvage_isdone __P((VRFY_DBINFO *, db_pgno_t)); - */ -int -__db_salvage_isdone(vdp, pgno) - VRFY_DBINFO *vdp; - db_pgno_t pgno; -{ - DBT key, data; - DB *dbp; - int ret; - u_int32_t currtype; - - dbp = vdp->salvage_pages; - - memset(&key, 0, sizeof(DBT)); - memset(&data, 0, sizeof(DBT)); - - currtype = SALVAGE_INVALID; - data.data = &currtype; - data.ulen = sizeof(u_int32_t); - data.flags = DB_DBT_USERMEM; - - key.data = &pgno; - key.size = sizeof(db_pgno_t); - - /* - * Put an entry for this page, with pgno as key and type as data, - * unless it's already there and is marked done. - * If it's there and is marked anything else, that's fine--we - * want to mark it done. - */ - if ((ret = __db_get(dbp, NULL, &key, &data, 0)) == 0) { - /* - * The key's already here. Check and see if it's already - * marked done. If it is, return DB_KEYEXIST. If it's not, - * return 0. - */ - if (currtype == SALVAGE_IGNORE) - return (DB_KEYEXIST); - else - return (0); - } else if (ret != DB_NOTFOUND) - return (ret); - - /* The pgno is not yet marked anything; return 0. */ - return (0); -} - -/* - * __db_salvage_markdone -- - * Mark as done a given page. - * - * PUBLIC: int __db_salvage_markdone __P((VRFY_DBINFO *, db_pgno_t)); - */ -int -__db_salvage_markdone(vdp, pgno) - VRFY_DBINFO *vdp; - db_pgno_t pgno; -{ - DBT key, data; - DB *dbp; - int pgtype, ret; - u_int32_t currtype; - - pgtype = SALVAGE_IGNORE; - dbp = vdp->salvage_pages; - - memset(&key, 0, sizeof(DBT)); - memset(&data, 0, sizeof(DBT)); - - currtype = SALVAGE_INVALID; - data.data = &currtype; - data.ulen = sizeof(u_int32_t); - data.flags = DB_DBT_USERMEM; - - key.data = &pgno; - key.size = sizeof(db_pgno_t); - - /* - * Put an entry for this page, with pgno as key and type as data, - * unless it's already there and is marked done. - * If it's there and is marked anything else, that's fine--we - * want to mark it done, but db_salvage_isdone only lets - * us know if it's marked IGNORE. - * - * We don't want to return DB_KEYEXIST, though; this will - * likely get passed up all the way and make no sense to the - * application. Instead, use DB_VERIFY_BAD to indicate that - * we've seen this page already--it probably indicates a - * multiply-linked page. - */ - if ((ret = __db_salvage_isdone(vdp, pgno)) != 0) - return (ret == DB_KEYEXIST ? DB_VERIFY_BAD : ret); - - data.size = sizeof(u_int32_t); - data.data = &pgtype; - - return (__db_put(dbp, NULL, &key, &data, 0)); -} - -/* - * __db_salvage_markneeded -- - * If it has not yet been printed, make note of the fact that a page - * must be dealt with later. - * - * PUBLIC: int __db_salvage_markneeded - * PUBLIC: __P((VRFY_DBINFO *, db_pgno_t, u_int32_t)); - */ -int -__db_salvage_markneeded(vdp, pgno, pgtype) - VRFY_DBINFO *vdp; - db_pgno_t pgno; - u_int32_t pgtype; -{ - DB *dbp; - DBT key, data; - int ret; - - dbp = vdp->salvage_pages; - - memset(&key, 0, sizeof(DBT)); - memset(&data, 0, sizeof(DBT)); - - key.data = &pgno; - key.size = sizeof(db_pgno_t); - - data.data = &pgtype; - data.size = sizeof(u_int32_t); - - /* - * Put an entry for this page, with pgno as key and type as data, - * unless it's already there, in which case it's presumably - * already been marked done. - */ - ret = __db_put(dbp, NULL, &key, &data, DB_NOOVERWRITE); - return (ret == DB_KEYEXIST ? 0 : ret); -} - -/* - * __db_vrfy_prdbt -- - * Print out a DBT data element from a verification routine. - * - * PUBLIC: int __db_vrfy_prdbt __P((DBT *, int, const char *, void *, - * PUBLIC: int (*)(void *, const void *), int, VRFY_DBINFO *)); - */ -int -__db_vrfy_prdbt(dbtp, checkprint, prefix, handle, callback, is_recno, vdp) - DBT *dbtp; - int checkprint; - const char *prefix; - void *handle; - int (*callback) __P((void *, const void *)); - int is_recno; - VRFY_DBINFO *vdp; -{ - if (vdp != NULL) { - /* - * If vdp is non-NULL, we might be the first key in the - * "fake" subdatabase used for key/data pairs we can't - * associate with a known subdb. - * - * Check and clear the SALVAGE_PRINTHEADER flag; if - * it was set, print a subdatabase header. - */ - if (F_ISSET(vdp, SALVAGE_PRINTHEADER)) { - (void)__db_prheader( - NULL, "__OTHER__", 0, 0, handle, callback, vdp, 0); - F_CLR(vdp, SALVAGE_PRINTHEADER); - F_SET(vdp, SALVAGE_PRINTFOOTER); - } - - /* - * Even if the printable flag wasn't set by our immediate - * caller, it may be set on a salvage-wide basis. - */ - if (F_ISSET(vdp, SALVAGE_PRINTABLE)) - checkprint = 1; - } - return ( - __db_prdbt(dbtp, checkprint, prefix, handle, callback, is_recno)); -} diff --git a/storage/bdb/db185/db185.c b/storage/bdb/db185/db185.c deleted file mode 100644 index 59b3260e4f1..00000000000 --- a/storage/bdb/db185/db185.c +++ /dev/null @@ -1,583 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db185.c,v 12.2 2005/10/06 14:36:51 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef lint -static const char copyright[] = - "Copyright (c) 1996-2005\nSleepycat Software Inc. All rights reserved.\n"; -#endif - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <fcntl.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "db185_int.h" - -static int db185_close __P((DB185 *)); -static int db185_compare __P((DB *, const DBT *, const DBT *)); -static int db185_del __P((const DB185 *, const DBT185 *, u_int)); -static int db185_fd __P((const DB185 *)); -static int db185_get __P((const DB185 *, const DBT185 *, DBT185 *, u_int)); -static u_int32_t - db185_hash __P((DB *, const void *, u_int32_t)); -static size_t db185_prefix __P((DB *, const DBT *, const DBT *)); -static int db185_put __P((const DB185 *, DBT185 *, const DBT185 *, u_int)); -static int db185_seq __P((const DB185 *, DBT185 *, DBT185 *, u_int)); -static int db185_sync __P((const DB185 *, u_int)); - -/* - * EXTERN: #ifdef _DB185_INT_H_ - * EXTERN: DB185 *__db185_open - * EXTERN: __P((const char *, int, int, DBTYPE, const void *)); - * EXTERN: #else - * EXTERN: DB *__db185_open - * EXTERN: __P((const char *, int, int, DBTYPE, const void *)); - * EXTERN: #endif - */ -DB185 * -__db185_open(file, oflags, mode, type, openinfo) - const char *file; - int oflags, mode; - DBTYPE type; - const void *openinfo; -{ - const BTREEINFO *bi; - const HASHINFO *hi; - const RECNOINFO *ri; - DB *dbp; - DB185 *db185p; - DB_FH *fhp; - int ret; - - dbp = NULL; - db185p = NULL; - - if ((ret = db_create(&dbp, NULL, 0)) != 0) - goto err; - - if ((ret = __os_calloc(NULL, 1, sizeof(DB185), &db185p)) != 0) - goto err; - - /* - * !!! - * The DBTYPE enum wasn't initialized in DB 185, so it's off-by-one - * from DB 2.0. - */ - switch (type) { - case 0: /* DB_BTREE */ - type = DB_BTREE; - if ((bi = openinfo) != NULL) { - if (bi->flags & ~R_DUP) - goto einval; - if (bi->flags & R_DUP) - (void)dbp->set_flags(dbp, DB_DUP); - if (bi->cachesize != 0) - (void)dbp->set_cachesize - (dbp, 0, bi->cachesize, 0); - if (bi->minkeypage != 0) - (void)dbp->set_bt_minkey(dbp, bi->minkeypage); - if (bi->psize != 0) - (void)dbp->set_pagesize(dbp, bi->psize); - if (bi->prefix != NULL) { - db185p->prefix = bi->prefix; - dbp->set_bt_prefix(dbp, db185_prefix); - } - if (bi->compare != NULL) { - db185p->compare = bi->compare; - dbp->set_bt_compare(dbp, db185_compare); - } - if (bi->lorder != 0) - dbp->set_lorder(dbp, bi->lorder); - } - break; - case 1: /* DB_HASH */ - type = DB_HASH; - if ((hi = openinfo) != NULL) { - if (hi->bsize != 0) - (void)dbp->set_pagesize(dbp, hi->bsize); - if (hi->ffactor != 0) - (void)dbp->set_h_ffactor(dbp, hi->ffactor); - if (hi->nelem != 0) - (void)dbp->set_h_nelem(dbp, hi->nelem); - if (hi->cachesize != 0) - (void)dbp->set_cachesize - (dbp, 0, hi->cachesize, 0); - if (hi->hash != NULL) { - db185p->hash = hi->hash; - (void)dbp->set_h_hash(dbp, db185_hash); - } - if (hi->lorder != 0) - dbp->set_lorder(dbp, hi->lorder); - } - - break; - case 2: /* DB_RECNO */ - type = DB_RECNO; - - /* DB 1.85 did renumbering by default. */ - (void)dbp->set_flags(dbp, DB_RENUMBER); - - /* - * !!! - * The file name given to DB 1.85 recno is the name of the DB - * 2.0 backing file. If the file doesn't exist, create it if - * the user has the O_CREAT flag set, DB 1.85 did it for you, - * and DB 2.0 doesn't. - * - * !!! - * Setting the file name to NULL specifies that we're creating - * a temporary backing file, in DB 2.X. If we're opening the - * DB file read-only, change the flags to read-write, because - * temporary backing files cannot be opened read-only, and DB - * 2.X will return an error. We are cheating here -- if the - * application does a put on the database, it will succeed -- - * although that would be a stupid thing for the application - * to do. - * - * !!! - * Note, the file name in DB 1.85 was a const -- we don't do - * that in DB 2.0, so do that cast. - */ - if (file != NULL) { - if (oflags & O_CREAT && __os_exists(file, NULL) != 0) - if (__os_openhandle(NULL, file, - oflags, mode, &fhp) == 0) - (void)__os_closehandle(NULL, fhp); - (void)dbp->set_re_source(dbp, file); - - if (O_RDONLY) - oflags &= ~O_RDONLY; - oflags |= O_RDWR; - file = NULL; - } - - if ((ri = openinfo) != NULL) { - /* - * !!! - * We can't support the bfname field. - */ -#define BFMSG \ - "Berkeley DB: DB 1.85's recno bfname field is not supported.\n" - if (ri->bfname != NULL) { - dbp->errx(dbp, "%s", BFMSG); - goto einval; - } - - if (ri->flags & ~(R_FIXEDLEN | R_NOKEY | R_SNAPSHOT)) - goto einval; - if (ri->flags & R_FIXEDLEN) { - if (ri->bval != 0) - (void)dbp->set_re_pad(dbp, ri->bval); - if (ri->reclen != 0) - (void)dbp->set_re_len(dbp, ri->reclen); - } else - if (ri->bval != 0) - (void)dbp->set_re_delim(dbp, ri->bval); - - /* - * !!! - * We ignore the R_NOKEY flag, but that's okay, it was - * only an optimization that was never implemented. - */ - if (ri->flags & R_SNAPSHOT) - (void)dbp->set_flags(dbp, DB_SNAPSHOT); - - if (ri->cachesize != 0) - (void)dbp->set_cachesize - (dbp, 0, ri->cachesize, 0); - if (ri->psize != 0) - (void)dbp->set_pagesize(dbp, ri->psize); - if (ri->lorder != 0) - dbp->set_lorder(dbp, ri->lorder); - } - break; - default: - goto einval; - } - - db185p->close = db185_close; - db185p->del = db185_del; - db185p->fd = db185_fd; - db185p->get = db185_get; - db185p->put = db185_put; - db185p->seq = db185_seq; - db185p->sync = db185_sync; - - /* - * Store a reference so we can indirect from the DB 1.85 structure - * to the underlying DB structure, and vice-versa. This has to be - * done BEFORE the DB::open method call because the hash callback - * is exercised as part of hash database initialization. - */ - db185p->dbp = dbp; - dbp->api_internal = db185p; - - /* Open the database. */ - if ((ret = dbp->open(dbp, NULL, - file, NULL, type, __db_oflags(oflags), mode)) != 0) - goto err; - - /* Create the cursor used for sequential ops. */ - if ((ret = dbp->cursor(dbp, NULL, &((DB185 *)db185p)->dbc, 0)) != 0) - goto err; - - return (db185p); - -einval: ret = EINVAL; - -err: if (db185p != NULL) - __os_free(NULL, db185p); - if (dbp != NULL) - (void)dbp->close(dbp, 0); - - __os_set_errno(ret); - return (NULL); -} - -static int -db185_close(db185p) - DB185 *db185p; -{ - DB *dbp; - int ret; - - dbp = db185p->dbp; - - ret = dbp->close(dbp, 0); - - __os_free(NULL, db185p); - - if (ret == 0) - return (0); - - __os_set_errno(ret); - return (-1); -} - -static int -db185_del(db185p, key185, flags) - const DB185 *db185p; - const DBT185 *key185; - u_int flags; -{ - DB *dbp; - DBT key; - int ret; - - dbp = db185p->dbp; - - memset(&key, 0, sizeof(key)); - key.data = key185->data; - key.size = key185->size; - - if (flags & ~R_CURSOR) - goto einval; - if (flags & R_CURSOR) - ret = db185p->dbc->c_del(db185p->dbc, 0); - else - ret = dbp->del(dbp, NULL, &key, 0); - - switch (ret) { - case 0: - return (0); - case DB_NOTFOUND: - return (1); - } - - if (0) { -einval: ret = EINVAL; - } - __os_set_errno(ret); - return (-1); -} - -static int -db185_fd(db185p) - const DB185 *db185p; -{ - DB *dbp; - int fd, ret; - - dbp = db185p->dbp; - - if ((ret = dbp->fd(dbp, &fd)) == 0) - return (fd); - - __os_set_errno(ret); - return (-1); -} - -static int -db185_get(db185p, key185, data185, flags) - const DB185 *db185p; - const DBT185 *key185; - DBT185 *data185; - u_int flags; -{ - DB *dbp; - DBT key, data; - int ret; - - dbp = db185p->dbp; - - memset(&key, 0, sizeof(key)); - key.data = key185->data; - key.size = key185->size; - memset(&data, 0, sizeof(data)); - data.data = data185->data; - data.size = data185->size; - - if (flags) - goto einval; - - switch (ret = dbp->get(dbp, NULL, &key, &data, 0)) { - case 0: - data185->data = data.data; - data185->size = data.size; - return (0); - case DB_NOTFOUND: - return (1); - } - - if (0) { -einval: ret = EINVAL; - } - __os_set_errno(ret); - return (-1); -} - -static int -db185_put(db185p, key185, data185, flags) - const DB185 *db185p; - DBT185 *key185; - const DBT185 *data185; - u_int flags; -{ - DB *dbp; - DBC *dbcp_put; - DBT key, data; - int ret, t_ret; - - dbp = db185p->dbp; - - memset(&key, 0, sizeof(key)); - key.data = key185->data; - key.size = key185->size; - memset(&data, 0, sizeof(data)); - data.data = data185->data; - data.size = data185->size; - - switch (flags) { - case 0: - ret = dbp->put(dbp, NULL, &key, &data, 0); - break; - case R_CURSOR: - ret = db185p->dbc->c_put(db185p->dbc, &key, &data, DB_CURRENT); - break; - case R_IAFTER: - case R_IBEFORE: - if (dbp->type != DB_RECNO) - goto einval; - - if ((ret = dbp->cursor(dbp, NULL, &dbcp_put, 0)) != 0) - break; - if ((ret = - dbcp_put->c_get(dbcp_put, &key, &data, DB_SET)) == 0) { - memset(&data, 0, sizeof(data)); - data.data = data185->data; - data.size = data185->size; - ret = dbcp_put->c_put(dbcp_put, &key, &data, - flags == R_IAFTER ? DB_AFTER : DB_BEFORE); - } - if ((t_ret = dbcp_put->c_close(dbcp_put)) != 0 && ret == 0) - ret = t_ret; - break; - case R_NOOVERWRITE: - ret = dbp->put(dbp, NULL, &key, &data, DB_NOOVERWRITE); - break; - case R_SETCURSOR: - if (dbp->type != DB_BTREE && dbp->type != DB_RECNO) - goto einval; - - if ((ret = dbp->put(dbp, NULL, &key, &data, 0)) != 0) - break; - ret = - db185p->dbc->c_get(db185p->dbc, &key, &data, DB_SET_RANGE); - break; - default: - goto einval; - } - - switch (ret) { - case 0: - key185->data = key.data; - key185->size = key.size; - return (0); - case DB_KEYEXIST: - return (1); - } - - if (0) { -einval: ret = EINVAL; - } - __os_set_errno(ret); - return (-1); -} - -static int -db185_seq(db185p, key185, data185, flags) - const DB185 *db185p; - DBT185 *key185, *data185; - u_int flags; -{ - DB *dbp; - DBT key, data; - int ret; - - dbp = db185p->dbp; - - memset(&key, 0, sizeof(key)); - key.data = key185->data; - key.size = key185->size; - memset(&data, 0, sizeof(data)); - data.data = data185->data; - data.size = data185->size; - - switch (flags) { - case R_CURSOR: - flags = DB_SET_RANGE; - break; - case R_FIRST: - flags = DB_FIRST; - break; - case R_LAST: - if (dbp->type != DB_BTREE && dbp->type != DB_RECNO) - goto einval; - flags = DB_LAST; - break; - case R_NEXT: - flags = DB_NEXT; - break; - case R_PREV: - if (dbp->type != DB_BTREE && dbp->type != DB_RECNO) - goto einval; - flags = DB_PREV; - break; - default: - goto einval; - } - switch (ret = db185p->dbc->c_get(db185p->dbc, &key, &data, flags)) { - case 0: - key185->data = key.data; - key185->size = key.size; - data185->data = data.data; - data185->size = data.size; - return (0); - case DB_NOTFOUND: - return (1); - } - - if (0) { -einval: ret = EINVAL; - } - __os_set_errno(ret); - return (-1); -} - -static int -db185_sync(db185p, flags) - const DB185 *db185p; - u_int flags; -{ - DB *dbp; - int ret; - - dbp = db185p->dbp; - - switch (flags) { - case 0: - break; - case R_RECNOSYNC: - /* - * !!! - * We can't support the R_RECNOSYNC flag. - */ -#define RSMSG \ - "Berkeley DB: DB 1.85's R_RECNOSYNC sync flag is not supported.\n" - dbp->errx(dbp, "%s", RSMSG); - /* FALLTHROUGH */ - default: - goto einval; - } - - if ((ret = dbp->sync(dbp, 0)) == 0) - return (0); - - if (0) { -einval: ret = EINVAL; - } - __os_set_errno(ret); - return (-1); -} - -/* - * db185_compare -- - * Cutout routine to call the user's Btree comparison function. - */ -static int -db185_compare(dbp, a, b) - DB *dbp; - const DBT *a, *b; -{ - DBT185 a185, b185; - - a185.data = a->data; - a185.size = a->size; - b185.data = b->data; - b185.size = b->size; - - return (((DB185 *)dbp->api_internal)->compare(&a185, &b185)); -} - -/* - * db185_prefix -- - * Cutout routine to call the user's Btree prefix function. - */ -static size_t -db185_prefix(dbp, a, b) - DB *dbp; - const DBT *a, *b; -{ - DBT185 a185, b185; - - a185.data = a->data; - a185.size = a->size; - b185.data = b->data; - b185.size = b->size; - - return (((DB185 *)dbp->api_internal)->prefix(&a185, &b185)); -} - -/* - * db185_hash -- - * Cutout routine to call the user's hash function. - */ -static u_int32_t -db185_hash(dbp, key, len) - DB *dbp; - const void *key; - u_int32_t len; -{ - return (((DB185 *)dbp->api_internal)->hash(key, (size_t)len)); -} diff --git a/storage/bdb/db185/db185_int.in b/storage/bdb/db185/db185_int.in deleted file mode 100644 index eba4fdb002d..00000000000 --- a/storage/bdb/db185/db185_int.in +++ /dev/null @@ -1,129 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994, 1995, 1996 - * Keith Bostic. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: db185_int.in,v 12.2 2005/10/06 14:36:52 bostic Exp $ - */ - -#ifndef _DB185_INT_H_ -#define _DB185_INT_H_ - -/* Routine flags. */ -#define R_CURSOR 1 /* del, put, seq */ -#define __R_UNUSED 2 /* UNUSED */ -#define R_FIRST 3 /* seq */ -#define R_IAFTER 4 /* put (RECNO) */ -#define R_IBEFORE 5 /* put (RECNO) */ -#define R_LAST 6 /* seq (BTREE, RECNO) */ -#define R_NEXT 7 /* seq */ -#define R_NOOVERWRITE 8 /* put */ -#define R_PREV 9 /* seq (BTREE, RECNO) */ -#define R_SETCURSOR 10 /* put (RECNO) */ -#define R_RECNOSYNC 11 /* sync (RECNO) */ - -typedef struct { - void *data; /* data */ - size_t size; /* data length */ -} DBT185; - -/* Access method description structure. */ -typedef struct __db185 { - DBTYPE type; /* Underlying db type. */ - int (*close) __P((struct __db185 *)); - int (*del) __P((const struct __db185 *, const DBT185 *, u_int)); - int (*get) - __P((const struct __db185 *, const DBT185 *, DBT185 *, u_int)); - int (*put) - __P((const struct __db185 *, DBT185 *, const DBT185 *, u_int)); - int (*seq) - __P((const struct __db185 *, DBT185 *, DBT185 *, u_int)); - int (*sync) __P((const struct __db185 *, u_int)); - DB *dbp; /* DB structure. Was void *internal. */ - int (*fd) __P((const struct __db185 *)); - - /* - * !!! - * The following elements added to the end of the DB 1.85 DB - * structure. - */ - DBC *dbc; /* DB cursor. */ - /* Various callback functions. */ - int (*compare) __P((const DBT185 *, const DBT185 *)); - size_t (*prefix) __P((const DBT185 *, const DBT185 *)); - u_int32_t (*hash) __P((const void *, size_t)); -} DB185; - -/* Structure used to pass parameters to the btree routines. */ -typedef struct { -#define R_DUP 0x01 /* duplicate keys */ - u_int32_t flags; - u_int32_t cachesize; /* bytes to cache */ - u_int32_t maxkeypage; /* maximum keys per page */ - u_int32_t minkeypage; /* minimum keys per page */ - u_int32_t psize; /* page size */ - int (*compare) /* comparison function */ - __P((const DBT185 *, const DBT185 *)); - size_t (*prefix) /* prefix function */ - __P((const DBT185 *, const DBT185 *)); - int lorder; /* byte order */ -} BTREEINFO; - -/* Structure used to pass parameters to the hashing routines. */ -typedef struct { - u_int32_t bsize; /* bucket size */ - u_int32_t ffactor; /* fill factor */ - u_int32_t nelem; /* number of elements */ - u_int32_t cachesize; /* bytes to cache */ - u_int32_t /* hash function */ - (*hash) __P((const void *, size_t)); - int lorder; /* byte order */ -} HASHINFO; - -/* Structure used to pass parameters to the record routines. */ -typedef struct { -#define R_FIXEDLEN 0x01 /* fixed-length records */ -#define R_NOKEY 0x02 /* key not required */ -#define R_SNAPSHOT 0x04 /* snapshot the input */ - u_int32_t flags; - u_int32_t cachesize; /* bytes to cache */ - u_int32_t psize; /* page size */ - int lorder; /* byte order */ - size_t reclen; /* record length (fixed-length records) */ - u_char bval; /* delimiting byte (variable-length records */ - char *bfname; /* btree file name */ -} RECNOINFO; -#endif /* !_DB185_INT_H_ */ diff --git a/storage/bdb/db_archive/db_archive.c b/storage/bdb/db_archive/db_archive.c deleted file mode 100644 index d00fc1bf9ea..00000000000 --- a/storage/bdb/db_archive/db_archive.c +++ /dev/null @@ -1,188 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_archive.c,v 12.4 2005/09/09 12:38:30 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef lint -static const char copyright[] = - "Copyright (c) 1996-2005\nSleepycat Software Inc. All rights reserved.\n"; -#endif - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#endif - -#include "db_int.h" - -int main __P((int, char *[])); -int usage __P((void)); -int version_check __P((void)); - -const char *progname; - -int -main(argc, argv) - int argc; - char *argv[]; -{ - extern char *optarg; - extern int optind; - DB_ENV *dbenv; - u_int32_t flags; - int ch, exitval, ret, verbose; - char **file, *home, **list, *passwd; - - if ((progname = strrchr(argv[0], '/')) == NULL) - progname = argv[0]; - else - ++progname; - - if ((ret = version_check()) != 0) - return (ret); - - dbenv = NULL; - flags = 0; - exitval = verbose = 0; - home = passwd = NULL; - file = list = NULL; - while ((ch = getopt(argc, argv, "adh:lP:sVv")) != EOF) - switch (ch) { - case 'a': - LF_SET(DB_ARCH_ABS); - break; - case 'd': - LF_SET(DB_ARCH_REMOVE); - break; - case 'h': - home = optarg; - break; - case 'l': - LF_SET(DB_ARCH_LOG); - break; - case 'P': - passwd = strdup(optarg); - memset(optarg, 0, strlen(optarg)); - if (passwd == NULL) { - fprintf(stderr, "%s: strdup: %s\n", - progname, strerror(errno)); - return (EXIT_FAILURE); - } - break; - case 's': - LF_SET(DB_ARCH_DATA); - break; - case 'V': - printf("%s\n", db_version(NULL, NULL, NULL)); - return (EXIT_SUCCESS); - case 'v': - verbose = 1; - break; - case '?': - default: - return (usage()); - } - argc -= optind; - argv += optind; - - if (argc != 0) - return (usage()); - - /* Handle possible interruptions. */ - __db_util_siginit(); - - /* - * Create an environment object and initialize it for error - * reporting. - */ - if ((ret = db_env_create(&dbenv, 0)) != 0) { - fprintf(stderr, - "%s: db_env_create: %s\n", progname, db_strerror(ret)); - goto shutdown; - } - - dbenv->set_errfile(dbenv, stderr); - dbenv->set_errpfx(dbenv, progname); - - if (passwd != NULL && (ret = dbenv->set_encrypt(dbenv, - passwd, DB_ENCRYPT_AES)) != 0) { - dbenv->err(dbenv, ret, "set_passwd"); - goto shutdown; - } - /* - * If attaching to a pre-existing environment fails, create a - * private one and try again. - */ - if ((ret = dbenv->open(dbenv, home, DB_USE_ENVIRON, 0)) != 0 && - (ret == DB_VERSION_MISMATCH || - (ret = dbenv->open(dbenv, home, DB_CREATE | - DB_INIT_LOG | DB_PRIVATE | DB_USE_ENVIRON, 0)) != 0)) { - dbenv->err(dbenv, ret, "DB_ENV->open"); - goto shutdown; - } - - /* Get the list of names. */ - if ((ret = dbenv->log_archive(dbenv, &list, flags)) != 0) { - dbenv->err(dbenv, ret, "DB_ENV->log_archive"); - goto shutdown; - } - - /* Print the list of names. */ - if (list != NULL) { - for (file = list; *file != NULL; ++file) - printf("%s\n", *file); - free(list); - } - - if (0) { -shutdown: exitval = 1; - } - if (dbenv != NULL && (ret = dbenv->close(dbenv, 0)) != 0) { - exitval = 1; - fprintf(stderr, - "%s: dbenv->close: %s\n", progname, db_strerror(ret)); - } - - if (passwd != NULL) - free(passwd); - - /* Resend any caught signal. */ - __db_util_sigresend(); - - return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE); -} - -int -usage() -{ - (void)fprintf(stderr, - "usage: %s [-adlsVv] [-h home] [-P password]\n", progname); - return (EXIT_FAILURE); -} - -int -version_check() -{ - int v_major, v_minor, v_patch; - - /* Make sure we're loaded with the right version of the DB library. */ - (void)db_version(&v_major, &v_minor, &v_patch); - if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) { - fprintf(stderr, - "%s: version %d.%d doesn't match library version %d.%d\n", - progname, DB_VERSION_MAJOR, DB_VERSION_MINOR, - v_major, v_minor); - return (EXIT_FAILURE); - } - return (0); -} diff --git a/storage/bdb/db_checkpoint/db_checkpoint.c b/storage/bdb/db_checkpoint/db_checkpoint.c deleted file mode 100644 index c1ee7b50596..00000000000 --- a/storage/bdb/db_checkpoint/db_checkpoint.c +++ /dev/null @@ -1,243 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_checkpoint.c,v 12.6 2005/09/09 12:38:30 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef lint -static const char copyright[] = - "Copyright (c) 1996-2005\nSleepycat Software Inc. All rights reserved.\n"; -#endif - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#if TIME_WITH_SYS_TIME -#include <sys/time.h> -#include <time.h> -#else -#if HAVE_SYS_TIME_H -#include <sys/time.h> -#else -#include <time.h> -#endif -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#endif - -#include "db_int.h" - -int main __P((int, char *[])); -int usage __P((void)); -int version_check __P((void)); - -const char *progname; - -int -main(argc, argv) - int argc; - char *argv[]; -{ - extern char *optarg; - extern int optind; - DB_ENV *dbenv; - time_t now; - long argval; - u_int32_t flags, kbytes, minutes, seconds; - int ch, exitval, once, ret, verbose; - char *home, *logfile, *passwd; - - if ((progname = strrchr(argv[0], '/')) == NULL) - progname = argv[0]; - else - ++progname; - - if ((ret = version_check()) != 0) - return (ret); - - /* - * !!! - * Don't allow a fully unsigned 32-bit number, some compilers get - * upset and require it to be specified in hexadecimal and so on. - */ -#define MAX_UINT32_T 2147483647 - - dbenv = NULL; - kbytes = minutes = 0; - exitval = once = verbose = 0; - flags = 0; - home = logfile = passwd = NULL; - while ((ch = getopt(argc, argv, "1h:k:L:P:p:Vv")) != EOF) - switch (ch) { - case '1': - once = 1; - flags = DB_FORCE; - break; - case 'h': - home = optarg; - break; - case 'k': - if (__db_getlong(NULL, progname, - optarg, 1, (long)MAX_UINT32_T, &argval)) - return (EXIT_FAILURE); - kbytes = (u_int32_t)argval; - break; - case 'L': - logfile = optarg; - break; - case 'P': - passwd = strdup(optarg); - memset(optarg, 0, strlen(optarg)); - if (passwd == NULL) { - fprintf(stderr, "%s: strdup: %s\n", - progname, strerror(errno)); - return (EXIT_FAILURE); - } - break; - case 'p': - if (__db_getlong(NULL, progname, - optarg, 1, (long)MAX_UINT32_T, &argval)) - return (EXIT_FAILURE); - minutes = (u_int32_t)argval; - break; - case 'V': - printf("%s\n", db_version(NULL, NULL, NULL)); - return (EXIT_SUCCESS); - case 'v': - verbose = 1; - break; - case '?': - default: - return (usage()); - } - argc -= optind; - argv += optind; - - if (argc != 0) - return (usage()); - - if (once == 0 && kbytes == 0 && minutes == 0) { - (void)fprintf(stderr, - "%s: at least one of -1, -k and -p must be specified\n", - progname); - return (EXIT_FAILURE); - } - - /* Handle possible interruptions. */ - __db_util_siginit(); - - /* Log our process ID. */ - if (logfile != NULL && __db_util_logset(progname, logfile)) - goto shutdown; - - /* - * Create an environment object and initialize it for error - * reporting. - */ - if ((ret = db_env_create(&dbenv, 0)) != 0) { - fprintf(stderr, - "%s: db_env_create: %s\n", progname, db_strerror(ret)); - goto shutdown; - } - - dbenv->set_errfile(dbenv, stderr); - dbenv->set_errpfx(dbenv, progname); - - if (passwd != NULL && (ret = dbenv->set_encrypt(dbenv, - passwd, DB_ENCRYPT_AES)) != 0) { - dbenv->err(dbenv, ret, "set_passwd"); - goto shutdown; - } - /* Initialize the environment. */ - if ((ret = dbenv->open(dbenv, home, DB_USE_ENVIRON, 0)) != 0) { - dbenv->err(dbenv, ret, "open"); - goto shutdown; - } - - /* - * If we have only a time delay, then we'll sleep the right amount - * to wake up when a checkpoint is necessary. If we have a "kbytes" - * field set, then we'll check every 30 seconds. - */ - seconds = kbytes != 0 ? 30 : minutes * 60; - while (!__db_util_interrupted()) { - if (verbose) { - (void)time(&now); - dbenv->errx(dbenv, "checkpoint begin: %s", ctime(&now)); - } - - if ((ret = dbenv->txn_checkpoint(dbenv, - kbytes, minutes, flags)) != 0) { - dbenv->err(dbenv, ret, "txn_checkpoint"); - goto shutdown; - } - - if (verbose) { - (void)time(&now); - dbenv->errx(dbenv, - "checkpoint complete: %s", ctime(&now)); - } - - if (once) - break; - - __os_sleep(dbenv, seconds, 0); - } - - if (0) { -shutdown: exitval = 1; - } - - /* Clean up the logfile. */ - if (logfile != NULL) - (void)remove(logfile); - - /* Clean up the environment. */ - if (dbenv != NULL && (ret = dbenv->close(dbenv, 0)) != 0) { - exitval = 1; - fprintf(stderr, - "%s: dbenv->close: %s\n", progname, db_strerror(ret)); - } - - if (passwd != NULL) - free(passwd); - - /* Resend any caught signal. */ - __db_util_sigresend(); - - return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE); -} - -int -usage() -{ - (void)fprintf(stderr, "usage: %s [-1Vv]\n\t%s\n", progname, - "[-h home] [-k kbytes] [-L file] [-P password] [-p min]"); - return (EXIT_FAILURE); -} - -int -version_check() -{ - int v_major, v_minor, v_patch; - - /* Make sure we're loaded with the right version of the DB library. */ - (void)db_version(&v_major, &v_minor, &v_patch); - if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) { - fprintf(stderr, - "%s: version %d.%d doesn't match library version %d.%d\n", - progname, DB_VERSION_MAJOR, DB_VERSION_MINOR, - v_major, v_minor); - return (EXIT_FAILURE); - } - return (0); -} diff --git a/storage/bdb/db_deadlock/db_deadlock.c b/storage/bdb/db_deadlock/db_deadlock.c deleted file mode 100644 index 67078a6937a..00000000000 --- a/storage/bdb/db_deadlock/db_deadlock.c +++ /dev/null @@ -1,257 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_deadlock.c,v 12.4 2005/10/03 16:00:16 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef lint -static const char copyright[] = - "Copyright (c) 1996-2005\nSleepycat Software Inc. All rights reserved.\n"; -#endif - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#if TIME_WITH_SYS_TIME -#include <sys/time.h> -#include <time.h> -#else -#if HAVE_SYS_TIME_H -#include <sys/time.h> -#else -#include <time.h> -#endif -#endif - -#include <limits.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#endif - -#include "db_int.h" - -int main __P((int, char *[])); -int usage __P((void)); -int version_check __P((void)); - -const char *progname; - -int -main(argc, argv) - int argc; - char *argv[]; -{ - extern char *optarg; - extern int optind; - DB_ENV *dbenv; - u_int32_t atype; - time_t now; - u_long secs, usecs; - int ch, exitval, ret, verbose; - char *home, *logfile, *passwd, *str; - - if ((progname = strrchr(argv[0], '/')) == NULL) - progname = argv[0]; - else - ++progname; - - if ((ret = version_check()) != 0) - return (ret); - - dbenv = NULL; - atype = DB_LOCK_DEFAULT; - home = logfile = passwd = NULL; - secs = usecs = 0; - exitval = verbose = 0; - while ((ch = getopt(argc, argv, "a:h:L:P:t:Vvw")) != EOF) - switch (ch) { - case 'a': - switch (optarg[0]) { - case 'e': - atype = DB_LOCK_EXPIRE; - break; - case 'm': - atype = DB_LOCK_MAXLOCKS; - break; - case 'n': - atype = DB_LOCK_MINLOCKS; - break; - case 'o': - atype = DB_LOCK_OLDEST; - break; - case 'W': - atype = DB_LOCK_MAXWRITE; - break; - case 'w': - atype = DB_LOCK_MINWRITE; - break; - case 'y': - atype = DB_LOCK_YOUNGEST; - break; - default: - return (usage()); - /* NOTREACHED */ - } - if (optarg[1] != '\0') - return (usage()); - break; - case 'h': - home = optarg; - break; - case 'L': - logfile = optarg; - break; - case 'P': - passwd = strdup(optarg); - memset(optarg, 0, strlen(optarg)); - if (passwd == NULL) { - fprintf(stderr, "%s: strdup: %s\n", - progname, strerror(errno)); - return (EXIT_FAILURE); - } - case 't': - if ((str = strchr(optarg, '.')) != NULL) { - *str++ = '\0'; - if (*str != '\0' && __db_getulong( - NULL, progname, str, 0, LONG_MAX, &usecs)) - return (EXIT_FAILURE); - } - if (*optarg != '\0' && __db_getulong( - NULL, progname, optarg, 0, LONG_MAX, &secs)) - return (EXIT_FAILURE); - if (secs == 0 && usecs == 0) - return (usage()); - - break; - - case 'V': - printf("%s\n", db_version(NULL, NULL, NULL)); - return (EXIT_SUCCESS); - case 'v': - verbose = 1; - break; - case 'w': /* Undocumented. */ - /* Detect every 100ms (100000 us) when polling. */ - secs = 0; - usecs = 100000; - break; - case '?': - default: - return (usage()); - } - argc -= optind; - argv += optind; - - if (argc != 0) - return (usage()); - - /* Handle possible interruptions. */ - __db_util_siginit(); - - /* Log our process ID. */ - if (logfile != NULL && __db_util_logset(progname, logfile)) - goto shutdown; - - /* - * Create an environment object and initialize it for error - * reporting. - */ - if ((ret = db_env_create(&dbenv, 0)) != 0) { - fprintf(stderr, - "%s: db_env_create: %s\n", progname, db_strerror(ret)); - goto shutdown; - } - - dbenv->set_errfile(dbenv, stderr); - dbenv->set_errpfx(dbenv, progname); - - if (passwd != NULL && (ret = dbenv->set_encrypt(dbenv, - passwd, DB_ENCRYPT_AES)) != 0) { - dbenv->err(dbenv, ret, "set_passwd"); - goto shutdown; - } - - if (verbose) { - (void)dbenv->set_verbose(dbenv, DB_VERB_DEADLOCK, 1); - (void)dbenv->set_verbose(dbenv, DB_VERB_WAITSFOR, 1); - } - - /* An environment is required. */ - if ((ret = dbenv->open(dbenv, home, DB_USE_ENVIRON, 0)) != 0) { - dbenv->err(dbenv, ret, "open"); - goto shutdown; - } - - while (!__db_util_interrupted()) { - if (verbose) { - (void)time(&now); - dbenv->errx(dbenv, "running at %.24s", ctime(&now)); - } - - if ((ret = dbenv->lock_detect(dbenv, 0, atype, NULL)) != 0) { - dbenv->err(dbenv, ret, "DB_ENV->lock_detect"); - goto shutdown; - } - - /* Make a pass every "secs" secs and "usecs" usecs. */ - if (secs == 0 && usecs == 0) - break; - __os_sleep(dbenv, secs, usecs); - } - - if (0) { -shutdown: exitval = 1; - } - - /* Clean up the logfile. */ - if (logfile != NULL) - (void)remove(logfile); - - /* Clean up the environment. */ - if (dbenv != NULL && (ret = dbenv->close(dbenv, 0)) != 0) { - exitval = 1; - fprintf(stderr, - "%s: dbenv->close: %s\n", progname, db_strerror(ret)); - } - - if (passwd != NULL) - free(passwd); - - /* Resend any caught signal. */ - __db_util_sigresend(); - - return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE); -} - -int -usage() -{ - (void)fprintf(stderr, - "usage: %s [-Vv] [-a e | m | n | o | W | w | y]\n\t%s\n", progname, - "[-h home] [-L file] [-P password] [-t sec.usec]"); - return (EXIT_FAILURE); -} - -int -version_check() -{ - int v_major, v_minor, v_patch; - - /* Make sure we're loaded with the right version of the DB library. */ - (void)db_version(&v_major, &v_minor, &v_patch); - if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) { - fprintf(stderr, - "%s: version %d.%d doesn't match library version %d.%d\n", - progname, DB_VERSION_MAJOR, DB_VERSION_MINOR, - v_major, v_minor); - return (EXIT_FAILURE); - } - return (0); -} diff --git a/storage/bdb/db_dump/db_dump.c b/storage/bdb/db_dump/db_dump.c deleted file mode 100644 index fbae7373004..00000000000 --- a/storage/bdb/db_dump/db_dump.c +++ /dev/null @@ -1,520 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_dump.c,v 12.4 2005/09/09 12:38:30 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef lint -static const char copyright[] = - "Copyright (c) 1996-2005\nSleepycat Software Inc. All rights reserved.\n"; -#endif - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_am.h" - -int db_init __P((DB_ENV *, char *, int, u_int32_t, int *)); -int dump_sub __P((DB_ENV *, DB *, char *, int, int)); -int is_sub __P((DB *, int *)); -int main __P((int, char *[])); -int show_subs __P((DB *)); -int usage __P((void)); -int version_check __P((void)); - -const char *progname; - -int -main(argc, argv) - int argc; - char *argv[]; -{ - extern char *optarg; - extern int optind; - DB_ENV *dbenv; - DB *dbp; - u_int32_t cache; - int ch; - int exitval, keyflag, lflag, nflag, pflag, private; - int ret, Rflag, rflag, resize, subs; - char *dopt, *home, *passwd, *subname; - - if ((progname = strrchr(argv[0], '/')) == NULL) - progname = argv[0]; - else - ++progname; - - if ((ret = version_check()) != 0) - return (ret); - - dbenv = NULL; - dbp = NULL; - exitval = lflag = nflag = pflag = rflag = Rflag = 0; - keyflag = 0; - cache = MEGABYTE; - private = 0; - dopt = home = passwd = subname = NULL; - while ((ch = getopt(argc, argv, "d:f:h:klNpP:rRs:V")) != EOF) - switch (ch) { - case 'd': - dopt = optarg; - break; - case 'f': - if (freopen(optarg, "w", stdout) == NULL) { - fprintf(stderr, "%s: %s: reopen: %s\n", - progname, optarg, strerror(errno)); - return (EXIT_FAILURE); - } - break; - case 'h': - home = optarg; - break; - case 'k': - keyflag = 1; - break; - case 'l': - lflag = 1; - break; - case 'N': - nflag = 1; - break; - case 'P': - passwd = strdup(optarg); - memset(optarg, 0, strlen(optarg)); - if (passwd == NULL) { - fprintf(stderr, "%s: strdup: %s\n", - progname, strerror(errno)); - return (EXIT_FAILURE); - } - break; - case 'p': - pflag = 1; - break; - case 's': - subname = optarg; - break; - case 'R': - Rflag = 1; - /* DB_AGGRESSIVE requires DB_SALVAGE */ - /* FALLTHROUGH */ - case 'r': - rflag = 1; - break; - case 'V': - printf("%s\n", db_version(NULL, NULL, NULL)); - return (EXIT_SUCCESS); - case '?': - default: - return (usage()); - } - argc -= optind; - argv += optind; - - if (argc != 1) - return (usage()); - - if (dopt != NULL && pflag) { - fprintf(stderr, - "%s: the -d and -p options may not both be specified\n", - progname); - return (EXIT_FAILURE); - } - if (lflag && subname != NULL) { - fprintf(stderr, - "%s: the -l and -s options may not both be specified\n", - progname); - return (EXIT_FAILURE); - } - - if (keyflag && rflag) { - fprintf(stderr, "%s: %s", - "the -k and -r or -R options may not both be specified\n", - progname); - return (EXIT_FAILURE); - } - - if (subname != NULL && rflag) { - fprintf(stderr, "%s: %s", - "the -s and -r or R options may not both be specified\n", - progname); - return (EXIT_FAILURE); - } - - /* Handle possible interruptions. */ - __db_util_siginit(); - - /* - * Create an environment object and initialize it for error - * reporting. - */ -retry: if ((ret = db_env_create(&dbenv, 0)) != 0) { - fprintf(stderr, - "%s: db_env_create: %s\n", progname, db_strerror(ret)); - goto err; - } - - dbenv->set_errfile(dbenv, stderr); - dbenv->set_errpfx(dbenv, progname); - if (nflag) { - if ((ret = dbenv->set_flags(dbenv, DB_NOLOCKING, 1)) != 0) { - dbenv->err(dbenv, ret, "set_flags: DB_NOLOCKING"); - goto err; - } - if ((ret = dbenv->set_flags(dbenv, DB_NOPANIC, 1)) != 0) { - dbenv->err(dbenv, ret, "set_flags: DB_NOPANIC"); - goto err; - } - } - if (passwd != NULL && (ret = dbenv->set_encrypt(dbenv, - passwd, DB_ENCRYPT_AES)) != 0) { - dbenv->err(dbenv, ret, "set_passwd"); - goto err; - } - - /* Initialize the environment. */ - if (db_init(dbenv, home, rflag, cache, &private) != 0) - goto err; - - /* Create the DB object and open the file. */ - if ((ret = db_create(&dbp, dbenv, 0)) != 0) { - dbenv->err(dbenv, ret, "db_create"); - goto err; - } - - /* - * If we're salvaging, don't do an open; it might not be safe. - * Dispatch now into the salvager. - */ - if (rflag) { - /* The verify method is a destructor. */ - ret = dbp->verify(dbp, argv[0], NULL, stdout, - DB_SALVAGE | - (Rflag ? DB_AGGRESSIVE : 0) | - (pflag ? DB_PRINTABLE : 0)); - dbp = NULL; - if (ret != 0) - goto err; - goto done; - } - - if ((ret = dbp->open(dbp, NULL, - argv[0], subname, DB_UNKNOWN, DB_RDONLY, 0)) != 0) { - dbp->err(dbp, ret, "open: %s", argv[0]); - goto err; - } - if (private != 0) { - if ((ret = __db_util_cache(dbp, &cache, &resize)) != 0) - goto err; - if (resize) { - (void)dbp->close(dbp, 0); - dbp = NULL; - - (void)dbenv->close(dbenv, 0); - dbenv = NULL; - goto retry; - } - } - - if (dopt != NULL) { - if ((ret = __db_dumptree(dbp, dopt, NULL)) != 0) { - dbp->err(dbp, ret, "__db_dumptree: %s", argv[0]); - goto err; - } - } else if (lflag) { - if (is_sub(dbp, &subs)) - goto err; - if (subs == 0) { - dbp->errx(dbp, - "%s: does not contain multiple databases", argv[0]); - goto err; - } - if (show_subs(dbp)) - goto err; - } else { - subs = 0; - if (subname == NULL && is_sub(dbp, &subs)) - goto err; - if (subs) { - if (dump_sub(dbenv, dbp, argv[0], pflag, keyflag)) - goto err; - } else - if (dbp->dump(dbp, NULL, - __db_pr_callback, stdout, pflag, keyflag)) - goto err; - } - - if (0) { -err: exitval = 1; - } -done: if (dbp != NULL && (ret = dbp->close(dbp, 0)) != 0) { - exitval = 1; - dbenv->err(dbenv, ret, "close"); - } - if (dbenv != NULL && (ret = dbenv->close(dbenv, 0)) != 0) { - exitval = 1; - fprintf(stderr, - "%s: dbenv->close: %s\n", progname, db_strerror(ret)); - } - - if (passwd != NULL) - free(passwd); - - /* Resend any caught signal. */ - __db_util_sigresend(); - - return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE); -} - -/* - * db_init -- - * Initialize the environment. - */ -int -db_init(dbenv, home, is_salvage, cache, is_privatep) - DB_ENV *dbenv; - char *home; - int is_salvage; - u_int32_t cache; - int *is_privatep; -{ - int ret; - - /* - * Try and use the underlying environment when opening a database. - * We wish to use the buffer pool so our information is as up-to-date - * as possible, even if the mpool cache hasn't been flushed. - * - * If we are not doing a salvage, we want to join the environment; - * if a locking system is present, this will let us use it and be - * safe to run concurrently with other threads of control. (We never - * need to use transactions explicitly, as we're read-only.) Note - * that in CDB, too, this will configure our environment - * appropriately, and our cursors will (correctly) do locking as CDB - * read cursors. - * - * If we are doing a salvage, the verification code will protest - * if we initialize transactions, logging, or locking; do an - * explicit DB_INIT_MPOOL to try to join any existing environment - * before we create our own. - */ - *is_privatep = 0; - if ((ret = dbenv->open(dbenv, home, - DB_USE_ENVIRON | (is_salvage ? DB_INIT_MPOOL : 0), 0)) == 0) - return (0); - if (ret == DB_VERSION_MISMATCH) - goto err; - - /* - * An environment is required because we may be trying to look at - * databases in directories other than the current one. We could - * avoid using an environment iff the -h option wasn't specified, - * but that seems like more work than it's worth. - * - * No environment exists (or, at least no environment that includes - * an mpool region exists). Create one, but make it private so that - * no files are actually created. - */ - *is_privatep = 1; - if ((ret = dbenv->set_cachesize(dbenv, 0, cache, 1)) == 0 && - (ret = dbenv->open(dbenv, home, - DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE | DB_USE_ENVIRON, 0)) == 0) - return (0); - - /* An environment is required. */ -err: dbenv->err(dbenv, ret, "DB_ENV->open"); - return (1); -} - -/* - * is_sub -- - * Return if the database contains subdatabases. - */ -int -is_sub(dbp, yesno) - DB *dbp; - int *yesno; -{ - DB_BTREE_STAT *btsp; - DB_HASH_STAT *hsp; - int ret; - - switch (dbp->type) { - case DB_BTREE: - case DB_RECNO: - if ((ret = dbp->stat(dbp, NULL, &btsp, DB_FAST_STAT)) != 0) { - dbp->err(dbp, ret, "DB->stat"); - return (ret); - } - *yesno = btsp->bt_metaflags & BTM_SUBDB ? 1 : 0; - free(btsp); - break; - case DB_HASH: - if ((ret = dbp->stat(dbp, NULL, &hsp, DB_FAST_STAT)) != 0) { - dbp->err(dbp, ret, "DB->stat"); - return (ret); - } - *yesno = hsp->hash_metaflags & DB_HASH_SUBDB ? 1 : 0; - free(hsp); - break; - case DB_QUEUE: - break; - case DB_UNKNOWN: - default: - dbp->errx(dbp, "unknown database type"); - return (1); - } - return (0); -} - -/* - * dump_sub -- - * Dump out the records for a DB containing subdatabases. - */ -int -dump_sub(dbenv, parent_dbp, parent_name, pflag, keyflag) - DB_ENV *dbenv; - DB *parent_dbp; - char *parent_name; - int pflag, keyflag; -{ - DB *dbp; - DBC *dbcp; - DBT key, data; - int ret; - char *subdb; - - /* - * Get a cursor and step through the database, dumping out each - * subdatabase. - */ - if ((ret = parent_dbp->cursor(parent_dbp, NULL, &dbcp, 0)) != 0) { - dbenv->err(dbenv, ret, "DB->cursor"); - return (1); - } - - memset(&key, 0, sizeof(key)); - memset(&data, 0, sizeof(data)); - while ((ret = dbcp->c_get(dbcp, &key, &data, DB_NEXT)) == 0) { - /* Nul terminate the subdatabase name. */ - if ((subdb = malloc(key.size + 1)) == NULL) { - dbenv->err(dbenv, ENOMEM, NULL); - return (1); - } - memcpy(subdb, key.data, key.size); - subdb[key.size] = '\0'; - - /* Create the DB object and open the file. */ - if ((ret = db_create(&dbp, dbenv, 0)) != 0) { - dbenv->err(dbenv, ret, "db_create"); - free(subdb); - return (1); - } - if ((ret = dbp->open(dbp, NULL, - parent_name, subdb, DB_UNKNOWN, DB_RDONLY, 0)) != 0) - dbp->err(dbp, ret, - "DB->open: %s:%s", parent_name, subdb); - if (ret == 0 && dbp->dump( - dbp, subdb, __db_pr_callback, stdout, pflag, keyflag)) - ret = 1; - (void)dbp->close(dbp, 0); - free(subdb); - if (ret != 0) - return (1); - } - if (ret != DB_NOTFOUND) { - parent_dbp->err(parent_dbp, ret, "DBcursor->get"); - return (1); - } - - if ((ret = dbcp->c_close(dbcp)) != 0) { - parent_dbp->err(parent_dbp, ret, "DBcursor->close"); - return (1); - } - - return (0); -} - -/* - * show_subs -- - * Display the subdatabases for a database. - */ -int -show_subs(dbp) - DB *dbp; -{ - DBC *dbcp; - DBT key, data; - int ret; - - /* - * Get a cursor and step through the database, printing out the key - * of each key/data pair. - */ - if ((ret = dbp->cursor(dbp, NULL, &dbcp, 0)) != 0) { - dbp->err(dbp, ret, "DB->cursor"); - return (1); - } - - memset(&key, 0, sizeof(key)); - memset(&data, 0, sizeof(data)); - while ((ret = dbcp->c_get(dbcp, &key, &data, DB_NEXT)) == 0) { - if ((ret = dbp->dbenv->prdbt( - &key, 1, NULL, stdout, __db_pr_callback, 0)) != 0) { - dbp->errx(dbp, NULL); - return (1); - } - } - if (ret != DB_NOTFOUND) { - dbp->err(dbp, ret, "DBcursor->get"); - return (1); - } - - if ((ret = dbcp->c_close(dbcp)) != 0) { - dbp->err(dbp, ret, "DBcursor->close"); - return (1); - } - return (0); -} - -/* - * usage -- - * Display the usage message. - */ -int -usage() -{ - (void)fprintf(stderr, "usage: %s [-klNprRV]\n\t%s\n", - progname, - "[-d ahr] [-f output] [-h home] [-P password] [-s database] db_file"); - return (EXIT_FAILURE); -} - -int -version_check() -{ - int v_major, v_minor, v_patch; - - /* Make sure we're loaded with the right version of the DB library. */ - (void)db_version(&v_major, &v_minor, &v_patch); - if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) { - fprintf(stderr, - "%s: version %d.%d doesn't match library version %d.%d\n", - progname, DB_VERSION_MAJOR, DB_VERSION_MINOR, - v_major, v_minor); - return (EXIT_FAILURE); - } - return (0); -} diff --git a/storage/bdb/db_dump185/db_dump185.c b/storage/bdb/db_dump185/db_dump185.c deleted file mode 100644 index 0e39c913dd6..00000000000 --- a/storage/bdb/db_dump185/db_dump185.c +++ /dev/null @@ -1,355 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_dump185.c,v 12.1 2005/06/16 20:21:22 bostic Exp $ - */ - -#ifndef lint -static char copyright[] = - "Copyright (c) 1996-2004\nSleepycat Software Inc. All rights reserved.\n"; -#endif - -#include <sys/types.h> - -#include <ctype.h> -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <db.h> - -/* Hash Table Information */ -typedef struct hashhdr185 { /* Disk resident portion */ - int magic; /* Magic NO for hash tables */ - int version; /* Version ID */ - u_int32_t lorder; /* Byte Order */ - int bsize; /* Bucket/Page Size */ - int bshift; /* Bucket shift */ - int dsize; /* Directory Size */ - int ssize; /* Segment Size */ - int sshift; /* Segment shift */ - int ovfl_point; /* Where overflow pages are being - * allocated */ - int last_freed; /* Last overflow page freed */ - int max_bucket; /* ID of Maximum bucket in use */ - int high_mask; /* Mask to modulo into entire table */ - int low_mask; /* Mask to modulo into lower half of - * table */ - int ffactor; /* Fill factor */ - int nkeys; /* Number of keys in hash table */ -} HASHHDR185; -typedef struct htab185 { /* Memory resident data structure */ - HASHHDR185 hdr; /* Header */ -} HTAB185; - -/* Hash Table Information */ -typedef struct hashhdr186 { /* Disk resident portion */ - int32_t magic; /* Magic NO for hash tables */ - int32_t version; /* Version ID */ - int32_t lorder; /* Byte Order */ - int32_t bsize; /* Bucket/Page Size */ - int32_t bshift; /* Bucket shift */ - int32_t ovfl_point; /* Where overflow pages are being allocated */ - int32_t last_freed; /* Last overflow page freed */ - int32_t max_bucket; /* ID of Maximum bucket in use */ - int32_t high_mask; /* Mask to modulo into entire table */ - int32_t low_mask; /* Mask to modulo into lower half of table */ - int32_t ffactor; /* Fill factor */ - int32_t nkeys; /* Number of keys in hash table */ - int32_t hdrpages; /* Size of table header */ - int32_t h_charkey; /* value of hash(CHARKEY) */ -#define NCACHED 32 /* number of bit maps and spare points */ - int32_t spares[NCACHED];/* spare pages for overflow */ - /* address of overflow page bitmaps */ - u_int16_t bitmaps[NCACHED]; -} HASHHDR186; -typedef struct htab186 { /* Memory resident data structure */ - void *unused[2]; - HASHHDR186 hdr; /* Header */ -} HTAB186; - -typedef struct _epgno { - u_int32_t pgno; /* the page number */ - u_int16_t index; /* the index on the page */ -} EPGNO; - -typedef struct _epg { - void *page; /* the (pinned) page */ - u_int16_t index; /* the index on the page */ -} EPG; - -typedef struct _cursor { - EPGNO pg; /* B: Saved tree reference. */ - DBT key; /* B: Saved key, or key.data == NULL. */ - u_int32_t rcursor; /* R: recno cursor (1-based) */ - -#define CURS_ACQUIRE 0x01 /* B: Cursor needs to be reacquired. */ -#define CURS_AFTER 0x02 /* B: Unreturned cursor after key. */ -#define CURS_BEFORE 0x04 /* B: Unreturned cursor before key. */ -#define CURS_INIT 0x08 /* RB: Cursor initialized. */ - u_int8_t flags; -} CURSOR; - -/* The in-memory btree/recno data structure. */ -typedef struct _btree { - void *bt_mp; /* memory pool cookie */ - - void *bt_dbp; /* pointer to enclosing DB */ - - EPG bt_cur; /* current (pinned) page */ - void *bt_pinned; /* page pinned across calls */ - - CURSOR bt_cursor; /* cursor */ - - EPGNO bt_stack[50]; /* stack of parent pages */ - EPGNO *bt_sp; /* current stack pointer */ - - DBT bt_rkey; /* returned key */ - DBT bt_rdata; /* returned data */ - - int bt_fd; /* tree file descriptor */ - - u_int32_t bt_free; /* next free page */ - u_int32_t bt_psize; /* page size */ - u_int16_t bt_ovflsize; /* cut-off for key/data overflow */ - int bt_lorder; /* byte order */ - /* sorted order */ - enum { NOT, BACK, FORWARD } bt_order; - EPGNO bt_last; /* last insert */ - - /* B: key comparison function */ - int (*bt_cmp) __P((DBT *, DBT *)); - /* B: prefix comparison function */ - size_t (*bt_pfx) __P((DBT *, DBT *)); - /* R: recno input function */ - int (*bt_irec) __P((struct _btree *, u_int32_t)); - - FILE *bt_rfp; /* R: record FILE pointer */ - int bt_rfd; /* R: record file descriptor */ - - void *bt_cmap; /* R: current point in mapped space */ - void *bt_smap; /* R: start of mapped space */ - void *bt_emap; /* R: end of mapped space */ - size_t bt_msize; /* R: size of mapped region. */ - - u_int32_t bt_nrecs; /* R: number of records */ - size_t bt_reclen; /* R: fixed record length */ - u_char bt_bval; /* R: delimiting byte/pad character */ - -/* - * NB: - * B_NODUPS and R_RECNO are stored on disk, and may not be changed. - */ -#define B_INMEM 0x00001 /* in-memory tree */ -#define B_METADIRTY 0x00002 /* need to write metadata */ -#define B_MODIFIED 0x00004 /* tree modified */ -#define B_NEEDSWAP 0x00008 /* if byte order requires swapping */ -#define B_RDONLY 0x00010 /* read-only tree */ - -#define B_NODUPS 0x00020 /* no duplicate keys permitted */ -#define R_RECNO 0x00080 /* record oriented tree */ - -#define R_CLOSEFP 0x00040 /* opened a file pointer */ -#define R_EOF 0x00100 /* end of input file reached. */ -#define R_FIXLEN 0x00200 /* fixed length records */ -#define R_MEMMAPPED 0x00400 /* memory mapped file. */ -#define R_INMEM 0x00800 /* in-memory file */ -#define R_MODIFIED 0x01000 /* modified file */ -#define R_RDONLY 0x02000 /* read-only file */ - -#define B_DB_LOCK 0x04000 /* DB_LOCK specified. */ -#define B_DB_SHMEM 0x08000 /* DB_SHMEM specified. */ -#define B_DB_TXN 0x10000 /* DB_TXN specified. */ - u_int32_t flags; -} BTREE; - -void db_btree __P((DB *, int)); -void db_hash __P((DB *, int)); -void dbt_dump __P((DBT *)); -void dbt_print __P((DBT *)); -int main __P((int, char *[])); -int usage __P((void)); - -int -main(argc, argv) - int argc; - char *argv[]; -{ - extern char *optarg; - extern int optind; - DB *dbp; - DBT key, data; - int ch, pflag, rval; - - pflag = 0; - while ((ch = getopt(argc, argv, "f:p")) != EOF) - switch (ch) { - case 'f': - if (freopen(optarg, "w", stdout) == NULL) { - fprintf(stderr, "db_dump185: %s: %s\n", - optarg, strerror(errno)); - return (EXIT_FAILURE); - } - break; - case 'p': - pflag = 1; - break; - case '?': - default: - return (usage()); - } - argc -= optind; - argv += optind; - - if (argc != 1) - return (usage()); - - if ((dbp = dbopen(argv[0], O_RDONLY, 0, DB_BTREE, NULL)) == NULL) { - if ((dbp = - dbopen(argv[0], O_RDONLY, 0, DB_HASH, NULL)) == NULL) { - fprintf(stderr, - "db_dump185: %s: %s\n", argv[0], strerror(errno)); - return (EXIT_FAILURE); - } - db_hash(dbp, pflag); - } else - db_btree(dbp, pflag); - - /* - * !!! - * DB 1.85 DBTs are a subset of DB 2.0 DBTs, so we just use the - * new dump/print routines. - */ - if (pflag) - while (!(rval = dbp->seq(dbp, &key, &data, R_NEXT))) { - dbt_print(&key); - dbt_print(&data); - } - else - while (!(rval = dbp->seq(dbp, &key, &data, R_NEXT))) { - dbt_dump(&key); - dbt_dump(&data); - } - - if (rval == -1) { - fprintf(stderr, "db_dump185: seq: %s\n", strerror(errno)); - return (EXIT_FAILURE); - } - return (EXIT_SUCCESS); -} - -/* - * db_hash -- - * Dump out hash header information. - */ -void -db_hash(dbp, pflag) - DB *dbp; - int pflag; -{ - HTAB185 *hash185p; - HTAB186 *hash186p; - - printf("format=%s\n", pflag ? "print" : "bytevalue"); - printf("type=hash\n"); - - /* DB 1.85 was version 2, DB 1.86 was version 3. */ - hash185p = dbp->internal; - if (hash185p->hdr.version > 2) { - hash186p = dbp->internal; - printf("h_ffactor=%lu\n", (u_long)hash186p->hdr.ffactor); - if (hash186p->hdr.lorder != 0) - printf("db_lorder=%lu\n", (u_long)hash186p->hdr.lorder); - printf("db_pagesize=%lu\n", (u_long)hash186p->hdr.bsize); - } else { - printf("h_ffactor=%lu\n", (u_long)hash185p->hdr.ffactor); - if (hash185p->hdr.lorder != 0) - printf("db_lorder=%lu\n", (u_long)hash185p->hdr.lorder); - printf("db_pagesize=%lu\n", (u_long)hash185p->hdr.bsize); - } - printf("HEADER=END\n"); -} - -/* - * db_btree -- - * Dump out btree header information. - */ -void -db_btree(dbp, pflag) - DB *dbp; - int pflag; -{ - BTREE *btp; - - btp = dbp->internal; - - printf("format=%s\n", pflag ? "print" : "bytevalue"); - printf("type=btree\n"); -#ifdef NOT_AVAILABLE_IN_185 - printf("bt_minkey=%lu\n", (u_long)XXX); - printf("bt_maxkey=%lu\n", (u_long)XXX); -#endif - if (btp->bt_lorder != 0) - printf("db_lorder=%lu\n", (u_long)btp->bt_lorder); - printf("db_pagesize=%lu\n", (u_long)btp->bt_psize); - if (!(btp->flags & B_NODUPS)) - printf("duplicates=1\n"); - printf("HEADER=END\n"); -} - -static char hex[] = "0123456789abcdef"; - -/* - * dbt_dump -- - * Write out a key or data item using byte values. - */ -void -dbt_dump(dbtp) - DBT *dbtp; -{ - size_t len; - u_int8_t *p; - - for (len = dbtp->size, p = dbtp->data; len--; ++p) - (void)printf("%c%c", - hex[(*p & 0xf0) >> 4], hex[*p & 0x0f]); - printf("\n"); -} - -/* - * dbt_print -- - * Write out a key or data item using printable characters. - */ -void -dbt_print(dbtp) - DBT *dbtp; -{ - size_t len; - u_int8_t *p; - - for (len = dbtp->size, p = dbtp->data; len--; ++p) - if (isprint((int)*p)) { - if (*p == '\\') - (void)printf("\\"); - (void)printf("%c", *p); - } else - (void)printf("\\%c%c", - hex[(*p & 0xf0) >> 4], hex[*p & 0x0f]); - printf("\n"); -} - -/* - * usage -- - * Display the usage message. - */ -int -usage() -{ - (void)fprintf(stderr, "usage: db_dump185 [-p] [-f file] db_file\n"); - return (EXIT_FAILURE); -} diff --git a/storage/bdb/db_hotbackup/db_hotbackup.c b/storage/bdb/db_hotbackup/db_hotbackup.c deleted file mode 100644 index b96de7a4165..00000000000 --- a/storage/bdb/db_hotbackup/db_hotbackup.c +++ /dev/null @@ -1,708 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_hotbackup.c,v 1.16 2005/10/27 01:25:54 mjc Exp $ - */ - -#include "db_config.h" - -#ifndef lint -static const char copyright[] = - "Copyright (c) 1996-2005\nSleepycat Software Inc. All rights reserved.\n"; -#endif - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#include <sys/stat.h> - -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <unistd.h> -#endif - -#include "db_int.h" -#include "dbinc/log.h" - -enum which_open { OPEN_ORIGINAL, OPEN_HOT_BACKUP }; - -int backup_dir_clean __P((DB_ENV *, char *, int *, int, int)); -int data_copy __P((DB_ENV *, char *, char *, char *, int)); -int env_init __P((DB_ENV **, char *, char *, char *, enum which_open)); -int main __P((int, char *[])); -int read_data_dir __P((DB_ENV *, char *, char *, int)); -int read_log_dir __P((DB_ENV *, char *, char *, int *, int, int)); -int usage __P((void)); -int version_check __P((void)); - -const char *progname; - -int -main(argc, argv) - int argc; - char *argv[]; -{ - extern char *optarg; - extern int optind; - time_t now; - DB_ENV *dbenv; - u_int data_cnt, data_next; - int ch, checkpoint, copy_min, exitval, remove_max, ret, update, verbose; - char *backup_dir, **data_dir, **dir, *home, *log_dir, *passwd; - - if ((progname = strrchr(argv[0], '/')) == NULL) - progname = argv[0]; - else - ++progname; - - if ((ret = version_check()) != 0) - return (ret); - - checkpoint = data_cnt = data_next = exitval = update = verbose = 0; - data_dir = NULL; - backup_dir = home = log_dir = passwd = NULL; - copy_min = remove_max = 0; - while ((ch = getopt(argc, argv, "b:cd:h:l:P:uVv")) != EOF) - switch (ch) { - case 'b': - backup_dir = optarg; - break; - case 'c': - checkpoint = 1; - break; - case 'd': - /* - * User can specify a list of directories -- keep an - * array, leaving room for the trailing NULL. - */ - if (data_dir == NULL || data_next >= data_cnt - 2) { - data_cnt = data_cnt == 0 ? 20 : data_cnt * 2; - if ((data_dir = realloc(data_dir, - data_cnt * sizeof(*data_dir))) == NULL) { - fprintf(stderr, "%s: %s\n", - progname, strerror(errno)); - return (EXIT_FAILURE); - } - } - data_dir[data_next++] = optarg; - break; - case 'h': - home = optarg; - break; - case 'l': - log_dir = optarg; - break; - case 'P': - passwd = strdup(optarg); - memset(optarg, 0, strlen(optarg)); - if (passwd == NULL) { - fprintf(stderr, "%s: strdup: %s\n", - progname, strerror(errno)); - return (EXIT_FAILURE); - } - break; - case 'u': - update = 1; - break; - case 'V': - printf("%s\n", db_version(NULL, NULL, NULL)); - return (EXIT_SUCCESS); - case 'v': - verbose = 1; - break; - case '?': - default: - return (usage()); - } - argc -= optind; - argv += optind; - - if (argc != 0) - return (usage()); - - /* Handle possible interruptions. */ - __db_util_siginit(); - - /* - * The home directory defaults to the environment variable DB_HOME. - * The log directory defaults to the home directory. - * - * We require a source database environment directory and a target - * backup directory. - */ - if (home == NULL) - home = getenv("DB_HOME"); - if (home == NULL) { - fprintf(stderr, - "%s: no source database environment specified\n", progname); - return (usage()); - } - if (log_dir == NULL) - log_dir = home; - if (backup_dir == NULL) { - fprintf(stderr, - "%s: no target backup directory specified\n", progname); - return (usage()); - } - - /* NULL-terminate any list of data directories. */ - if (data_dir != NULL) - data_dir[data_next] = NULL; - - if (verbose) { - (void)time(&now); - printf("%s: hot backup started at %s", progname, ctime(&now)); - } - - /* Open the source environment. */ - if ((ret = env_init(&dbenv, home, log_dir, passwd, OPEN_ORIGINAL)) != 0) - goto shutdown; - - /* - * If the -c option is specified, checkpoint the source home - * database environment, and remove any unnecessary log files. - */ - if (checkpoint) { - if (verbose) - printf("%s: %s: force checkpoint\n", progname, home); - if ((ret = - dbenv->txn_checkpoint(dbenv, 0, 0, DB_FORCE)) != 0) { - dbenv->err(dbenv, ret, "DB_ENV->txn_checkpoint"); - goto shutdown; - } - if (!update) { - if (verbose) - printf("%s: %s: remove unnecessary log files\n", - progname, home); - if ((ret = dbenv->log_archive(dbenv, - NULL, DB_ARCH_REMOVE)) != 0) { - dbenv->err(dbenv, ret, "DB_ENV->log_archive"); - goto shutdown; - } - } - } - - /* - * If the target directory for the backup does not exist, create it - * with mode read-write-execute for the owner. Ignore errors here, - * it's simpler and more portable to just always try the create. If - * there's a problem, we'll fail with reasonable errors later. - */ - (void)__os_mkdir(NULL, backup_dir, __db_omode("rwx------")); - - /* - * If the target directory for the backup does exist and the -u option - * was specified, all log files in the target directory are removed; - * if the -u option was not specified, all files in the target directory - * are removed. - */ - if ((ret = backup_dir_clean( - dbenv, backup_dir, &remove_max, update, verbose)) != 0) - goto shutdown; - - /* - * If the -u option was not specified, copy all database files found in - * the database environment home directory, or any directory specified - * using the -d option, into the target directory for the backup. - */ - if (!update) { - if (read_data_dir(dbenv, backup_dir, home, verbose) != 0) - goto shutdown; - if (data_dir != NULL) - for (dir = &data_dir[0]; *dir != NULL; ++dir) - if (read_data_dir( - dbenv, backup_dir, *dir, verbose) != 0) - goto shutdown; - } - - /* - * Copy all log files found in the directory specified by the -l option - * (or in the database environment home directory, if no -l option was - * specified), into the target directory for the backup. - * - * The log directory defaults to the home directory. - */ - if (read_log_dir(dbenv, - backup_dir, log_dir, ©_min, update, verbose) != 0) - goto shutdown; - - /* - * If we're updating a snapshot, the lowest-numbered log file copied - * into the backup directory should be less than, or equal to, the - * highest-numbered log file removed from the backup directory during - * cleanup. - */ - if (update && remove_max < copy_min && - !(remove_max == 0 && copy_min == 1)) { - fprintf(stderr, - "%s: the largest log file removed (%d) must be greater\n", - progname, remove_max); - fprintf(stderr, - "%s: than or equal the smallest log file copied (%d)\n", - progname, copy_min); - goto shutdown; - } - - /* Close the source environment. */ - if ((ret = dbenv->close(dbenv, 0)) != 0) { - fprintf(stderr, - "%s: dbenv->close: %s\n", progname, db_strerror(ret)); - dbenv = NULL; - goto shutdown; - } - /* Perform catastrophic recovery on the hot backup. */ - if (verbose) - printf("%s: %s: run catastrophic recovery\n", - progname, backup_dir); - if ((ret = env_init( - &dbenv, backup_dir, NULL, passwd, OPEN_HOT_BACKUP)) != 0) - goto shutdown; - - /* - * Remove any unnecessary log files from the hot backup. - */ - if (verbose) - printf("%s: %s: remove unnecessary log files\n", - progname, backup_dir); - if ((ret = - dbenv->log_archive(dbenv, NULL, DB_ARCH_REMOVE)) != 0) { - dbenv->err(dbenv, ret, "DB_ENV->log_archive"); - goto shutdown; - } - - if (0) { -shutdown: exitval = 1; - } - if (dbenv != NULL && (ret = dbenv->close(dbenv, 0)) != 0) { - exitval = 1; - fprintf(stderr, - "%s: dbenv->close: %s\n", progname, db_strerror(ret)); - } - - if (data_dir != NULL) - free(data_dir); - if (passwd != NULL) - free(passwd); - - if (exitval == 0) { - if (verbose) { - (void)time(&now); - printf("%s: hot backup completed at %s", - progname, ctime(&now)); - } - } else { - fprintf(stderr, "%s: HOT BACKUP FAILED!\n", progname); - } - - /* Resend any caught signal. */ - __db_util_sigresend(); - - return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE); - -} - -/* - * env_init -- - * Open a database environment. - */ -int -env_init(dbenvp, home, log_dir, passwd, which) - DB_ENV **dbenvp; - char *home, *log_dir, *passwd; - enum which_open which; -{ - DB_ENV *dbenv; - int ret; - - *dbenvp = NULL; - - /* - * Create an environment object and initialize it for error reporting. - */ - if ((ret = db_env_create(&dbenv, 0)) != 0) { - fprintf(stderr, - "%s: db_env_create: %s\n", progname, db_strerror(ret)); - return (1); - } - - dbenv->set_errfile(dbenv, stderr); - setbuf(stderr, NULL); - dbenv->set_errpfx(dbenv, progname); - setvbuf(stdout, NULL, _IOLBF, 0); - - /* - * If a log directory has been specified, and it's not the same as the - * home directory, set it for the environment. - */ - if (log_dir != NULL && log_dir != home && - (ret = dbenv->set_lg_dir(dbenv, log_dir)) != 0) { - dbenv->err(dbenv, ret, "DB_ENV->set_lg_dir: %s", log_dir); - return (1); - } - - /* Optionally set the password. */ - if (passwd != NULL && - (ret = dbenv->set_encrypt(dbenv, passwd, DB_ENCRYPT_AES)) != 0) { - dbenv->err(dbenv, ret, "DB_ENV->set_encrypt"); - return (1); - } - - switch (which) { - case OPEN_ORIGINAL: - /* - * Opening the database environment we're trying to back up. - * We try to attach to a pre-existing environment; if that - * fails, we create a private environment and try again. - */ - if ((ret = dbenv->open(dbenv, home, DB_USE_ENVIRON, 0)) != 0 && - (ret == DB_VERSION_MISMATCH || - (ret = dbenv->open(dbenv, home, DB_CREATE | - DB_INIT_LOG | DB_INIT_TXN | DB_PRIVATE | DB_USE_ENVIRON, - 0)) != 0)) { - dbenv->err(dbenv, ret, "DB_ENV->open: %s", home); - return (1); - } - break; - case OPEN_HOT_BACKUP: - /* - * Opening the backup copy of the database environment. We - * better be the only user, we're running recovery. - */ - if ((ret = dbenv->open(dbenv, home, DB_CREATE | - DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN | DB_PRIVATE | - DB_RECOVER_FATAL | DB_USE_ENVIRON, 0)) != 0) { - dbenv->err(dbenv, ret, "DB_ENV->open: %s", home); - return (1); - } - break; - } - - *dbenvp = dbenv; - return (0); -} - -/* - * backup_dir_clean -- - * Clean out the backup directory. - */ -int -backup_dir_clean(dbenv, backup_dir, remove_maxp, update, verbose) - DB_ENV *dbenv; - char *backup_dir; - int *remove_maxp, update, verbose; -{ - int cnt, fcnt, ret, v; - char **names; - char buf[2048]; /* MAXPATHLEN is too hard to find. */ - - /* Get a list of file names. */ - if ((ret = __os_dirlist(dbenv, backup_dir, &names, &fcnt)) != 0) { - dbenv->err(dbenv, ret, "%s: directory read", backup_dir); - return (1); - } - for (cnt = fcnt; --cnt >= 0;) { - /* - * Skip ".", ".." and log files (if update wasn't specified). - */ - if (!strcmp(names[cnt], ".") || !strcmp(names[cnt], "..")) - continue; - if (strncmp(names[cnt], LFPREFIX, sizeof(LFPREFIX) - 1)) { - if (update) - continue; - } else { - /* Track the highest-numbered log file removed. */ - v = atoi(names[cnt] + sizeof(LFPREFIX) - 1); - if (*remove_maxp < v) - *remove_maxp = v; - } - if ((size_t)snprintf(buf, sizeof(buf), - "%s/%s", backup_dir, names[cnt]) == sizeof(buf)) { - dbenv->err(dbenv, ret, - "%s/%s: path too long", backup_dir, names[cnt]); - return (1); - } - if (verbose) - printf("%s: removing %s\n", progname, buf); - if ((ret = remove(buf)) != 0) { - dbenv->err(dbenv, ret, "%s: remove", buf); - return (1); - } - } - - __os_dirfree(dbenv, names, fcnt); - - if (verbose && *remove_maxp != 0) - printf("%s: highest numbered log file removed: %d\n", - progname, *remove_maxp); - - return (0); -} - -/* - * read_data_dir -- - * Read a directory looking for databases to copy. - */ -int -read_data_dir(dbenv, backup_dir, dir, verbose) - DB_ENV *dbenv; - char *backup_dir, *dir; - int verbose; -{ - int cnt, fcnt, ret; - char **names; - char buf[2048]; /* MAXPATHLEN is too hard to find. */ - - /* Get a list of file names. */ - if ((ret = __os_dirlist(dbenv, dir, &names, &fcnt)) != 0) { - dbenv->err(dbenv, ret, "%s: directory read", dir); - return (1); - } - for (cnt = fcnt; --cnt >= 0;) { - /* - * Skip ".", ".." and files in DB's name space (but not Queue - * extent files, we need them). - */ - if (!strcmp(names[cnt], ".") || !strcmp(names[cnt], "..")) - continue; - if (!strncmp(names[cnt], LFPREFIX, sizeof(LFPREFIX) - 1)) - continue; - if (!strncmp(names[cnt], - DB_REGION_PREFIX, sizeof(DB_REGION_PREFIX) - 1)) - continue; - - /* Build a path name to the source. */ - if ((size_t)snprintf(buf, sizeof(buf), - "%s/%s", dir, names[cnt]) == sizeof(buf)) { - dbenv->errx(dbenv, - "%s/%s: path too long", dir, names[cnt]); - return (1); - } - - /* Copy the file. */ - if ((ret = data_copy( - dbenv, buf, backup_dir, names[cnt], verbose)) != 0) - return (1); - } - - __os_dirfree(dbenv, names, fcnt); - - return (0); -} - -/* - * read_log_dir -- - * Read a directory looking for log files to copy. - */ -int -read_log_dir(dbenv, backup_dir, log_dir, copy_minp, update, verbose) - DB_ENV *dbenv; - char *backup_dir, *log_dir; - int *copy_minp, update, verbose; -{ - int aflag, ret, v; - char **begin, **names; - char from[2048], to[2048]; /* MAXPATHLEN is too hard to find. */ - -again: aflag = DB_ARCH_LOG; - - /* - * If this is an update and we are deleting files, first process - * those files that can be removed, then repeat with the rest. - */ - if (update) - aflag = 0; - /* Get a list of file names to be copied. */ - if ((ret = dbenv->log_archive(dbenv, &names, aflag)) != 0) { - dbenv->err(dbenv, ret, "%s: log_archive", log_dir); - return (1); - } - if (names == NULL) - goto done; - begin = names; - for (; *names != NULL; names++) { - /* Track the lowest-numbered log file copied. */ - v = atoi(*names + sizeof(LFPREFIX) - 1); - if (*copy_minp == 0 || *copy_minp > v) - *copy_minp = v; - - /* Build a path name to the source. */ - if ((size_t)snprintf(from, sizeof(from), - "%s/%s", log_dir, *names) == sizeof(from)) { - dbenv->errx(dbenv, - "%s/%s: path too long", log_dir, *names); - return (1); - } - - /* - * If we're going to remove the file, attempt to rename the - * instead of copying and then removing. The likely failure - * is EXDEV (source and destination are on different volumes). - * Fall back to a copy, regardless of the error. We don't - * worry about partial contents, the copy truncates the file - * on open. - */ - if (update) { - if ((size_t)snprintf(to, sizeof(to), - "%s/%s", backup_dir, *names) == sizeof(to)) { - dbenv->errx(dbenv, - "%s/%s: path too long", backup_dir, *names); - return (1); - } - if (rename(from, to) == 0) { - if (verbose) - printf("%s: moving %s to %s\n", - progname, from, to); - continue; - } - } - - /* Copy the file. */ - if ((ret = data_copy(dbenv, - from, backup_dir, *names, verbose)) != 0) - return (1); - - if (update) { - if (verbose) - printf("%s: removing %s\n", progname, from); - if ((ret = __os_unlink(dbenv, from)) != 0) { - dbenv->err(dbenv, ret, - "unlink of %s failed", from); - return (1); - } - } - - } - - free(begin); -done: if (update) { - update = 0; - goto again; - } - - if (verbose && *copy_minp != 0) - printf("%s: lowest numbered log file copied: %d\n", - progname, *copy_minp); - - return (0); -} - -/* - * data_copy -- - * Copy a file into the backup directory. - */ -int -data_copy(dbenv, from, to_dir, to_file, verbose) - DB_ENV *dbenv; - char *from, *to_dir, *to_file; - int verbose; -{ - ssize_t nr, nw; - size_t offset; - int ret, rfd, wfd; - char *buf, *taddr; - - ret = 0; - rfd = wfd = -1; - - if (verbose) - printf("%s: copying %s to %s/%s\n", - progname, from, to_dir, to_file); - - /* - * We MUST copy multiples of the page size, atomically, to ensure a - * database page is not updated by another thread of control during - * the copy. - * - * !!! - * The current maximum page size for Berkeley DB is 64KB; we will have - * to increase this value if the maximum page size is ever more than a - * megabyte - */ - if ((buf = malloc(MEGABYTE)) == NULL) { - dbenv->err(dbenv, - errno, "%lu buffer allocation", (u_long)MEGABYTE); - return (1); - } - - /* Open the input file. */ - if ((rfd = open(from, O_RDONLY, 0)) == -1) { - dbenv->err(dbenv, errno, "%s", from); - goto err; - } - - /* Open the output file. */ - if ((u_int32_t)snprintf( - buf, MEGABYTE, "%s/%s", to_dir, to_file) == MEGABYTE) { - dbenv->errx(dbenv, "%s/%s: path too long", to_dir, to_file); - goto err; - } - if ((wfd = open( - buf, O_CREAT | O_TRUNC | O_WRONLY, __db_omode(OWNER_RW))) == -1) - goto err; - - /* Copy the data. */ - while ((nr = read(rfd, buf, MEGABYTE)) > 0) - for (taddr = buf, offset = 0; - offset < (size_t)nr; taddr += nw, offset += (size_t)nw) { - RETRY_CHK(((nw = write(wfd, - taddr, (u_int)(nr - offset))) < 0 ? 1 : 0), ret); - if (ret != 0) - break; - } - if (nr == -1) { - dbenv->err(dbenv, errno, "%s: read", from); - goto err; - } - - if (ret != 0) { - dbenv->err(dbenv, errno, "%s: write %s/%s", to_dir, to_file); - goto err; - } - - if (0) { -err: ret = 1; - } - if (buf != NULL) - free(buf); - - if (rfd != -1) - (void)close(rfd); - - /* We may be running on a remote filesystem; force the flush. */ - if (wfd != -1 && (fsync(wfd) != 0 || close(wfd) != 0)) { - dbenv->err(dbenv, - errno, "%s: fsync %s/%s", to_dir, to_file); - ret = 1; - } - return (ret); -} - -int -usage() -{ - (void)fprintf(stderr, "usage: %s [-cuVv]\n\t%s\n", progname, - "[-d data_dir ...] [-h home] [-l log_dir] [-P password] -b backup_dir"); - return (EXIT_FAILURE); -} - -int -version_check() -{ - int v_major, v_minor, v_patch; - - /* Make sure we're loaded with the right version of the DB library. */ - (void)db_version(&v_major, &v_minor, &v_patch); - if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) { - fprintf(stderr, - "%s: version %d.%d doesn't match library version %d.%d\n", - progname, DB_VERSION_MAJOR, DB_VERSION_MINOR, - v_major, v_minor); - return (EXIT_FAILURE); - } - return (0); -} diff --git a/storage/bdb/db_load/db_load.c b/storage/bdb/db_load/db_load.c deleted file mode 100644 index c47bd585452..00000000000 --- a/storage/bdb/db_load/db_load.c +++ /dev/null @@ -1,1321 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_load.c,v 12.8 2005/06/16 20:21:23 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef lint -static const char copyright[] = - "Copyright (c) 1996-2005\nSleepycat Software Inc. All rights reserved.\n"; -#endif - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <limits.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_am.h" - -typedef struct { /* XXX: Globals. */ - const char *progname; /* Program name. */ - char *hdrbuf; /* Input file header. */ - u_long lineno; /* Input file line number. */ - u_long origline; /* Original file line number. */ - int endodata; /* Reached the end of a database. */ - int endofile; /* Reached the end of the input. */ - int version; /* Input version. */ - char *home; /* Env home. */ - char *passwd; /* Env passwd. */ - int private; /* Private env. */ - u_int32_t cache; /* Env cache size. */ -} LDG; - -void badend __P((DB_ENV *)); -void badnum __P((DB_ENV *)); -int configure __P((DB_ENV *, DB *, char **, char **, int *)); -int convprintable __P((DB_ENV *, char *, char **)); -int db_init __P((DB_ENV *, char *, u_int32_t, int *)); -int dbt_rdump __P((DB_ENV *, DBT *)); -int dbt_rprint __P((DB_ENV *, DBT *)); -int dbt_rrecno __P((DB_ENV *, DBT *, int)); -int dbt_to_recno __P((DB_ENV *, DBT *, db_recno_t *)); -int digitize __P((DB_ENV *, int, int *)); -int env_create __P((DB_ENV **, LDG *)); -int load __P((DB_ENV *, char *, DBTYPE, char **, u_int, LDG *, int *)); -int main __P((int, char *[])); -int rheader __P((DB_ENV *, DB *, DBTYPE *, char **, int *, int *)); -int usage __P((void)); -int version_check __P((void)); - -const char *progname; - -#define G(f) ((LDG *)dbenv->app_private)->f - - /* Flags to the load function. */ -#define LDF_NOHEADER 0x01 /* No dump header. */ -#define LDF_NOOVERWRITE 0x02 /* Don't overwrite existing rows. */ -#define LDF_PASSWORD 0x04 /* Encrypt created databases. */ - -int -main(argc, argv) - int argc; - char *argv[]; -{ - enum { NOTSET, FILEID_RESET, LSN_RESET, STANDARD_LOAD } mode; - extern char *optarg; - extern int optind; - DBTYPE dbtype; - DB_ENV *dbenv; - LDG ldg; - u_int ldf; - int ch, existed, exitval, ret; - char **clist, **clp; - - if ((progname = strrchr(argv[0], '/')) == NULL) - progname = argv[0]; - else - ++progname; - - if ((ret = version_check()) != 0) - return (ret); - - ldg.progname = progname; - ldg.lineno = 0; - ldg.endodata = ldg.endofile = 0; - ldg.version = 1; - ldg.cache = MEGABYTE; - ldg.hdrbuf = NULL; - ldg.home = NULL; - ldg.passwd = NULL; - - mode = NOTSET; - ldf = 0; - exitval = existed = 0; - dbtype = DB_UNKNOWN; - - /* Allocate enough room for configuration arguments. */ - if ((clp = clist = - (char **)calloc((size_t)argc + 1, sizeof(char *))) == NULL) { - fprintf(stderr, "%s: %s\n", ldg.progname, strerror(ENOMEM)); - return (EXIT_FAILURE); - } - - /* - * There are two modes for db_load: -r and everything else. The -r - * option zeroes out the database LSN's or resets the file ID, it - * doesn't really "load" a new database. The functionality is in - * db_load because we don't have a better place to put it, and we - * don't want to create a new utility for just that functionality. - */ - while ((ch = getopt(argc, argv, "c:f:h:nP:r:Tt:V")) != EOF) - switch (ch) { - case 'c': - if (mode != NOTSET && mode != STANDARD_LOAD) - return (usage()); - mode = STANDARD_LOAD; - - *clp++ = optarg; - break; - case 'f': - if (mode != NOTSET && mode != STANDARD_LOAD) - return (usage()); - mode = STANDARD_LOAD; - - if (freopen(optarg, "r", stdin) == NULL) { - fprintf(stderr, "%s: %s: reopen: %s\n", - ldg.progname, optarg, strerror(errno)); - return (EXIT_FAILURE); - } - break; - case 'h': - ldg.home = optarg; - break; - case 'n': - if (mode != NOTSET && mode != STANDARD_LOAD) - return (usage()); - mode = STANDARD_LOAD; - - ldf |= LDF_NOOVERWRITE; - break; - case 'P': - ldg.passwd = strdup(optarg); - memset(optarg, 0, strlen(optarg)); - if (ldg.passwd == NULL) { - fprintf(stderr, "%s: strdup: %s\n", - ldg.progname, strerror(errno)); - return (EXIT_FAILURE); - } - ldf |= LDF_PASSWORD; - break; - case 'r': - if (mode == STANDARD_LOAD) - return (usage()); - if (strcmp(optarg, "lsn") == 0) - mode = LSN_RESET; - else if (strcmp(optarg, "fileid") == 0) - mode = FILEID_RESET; - else - return (usage()); - break; - case 'T': - if (mode != NOTSET && mode != STANDARD_LOAD) - return (usage()); - mode = STANDARD_LOAD; - - ldf |= LDF_NOHEADER; - break; - case 't': - if (mode != NOTSET && mode != STANDARD_LOAD) - return (usage()); - mode = STANDARD_LOAD; - - if (strcmp(optarg, "btree") == 0) { - dbtype = DB_BTREE; - break; - } - if (strcmp(optarg, "hash") == 0) { - dbtype = DB_HASH; - break; - } - if (strcmp(optarg, "recno") == 0) { - dbtype = DB_RECNO; - break; - } - if (strcmp(optarg, "queue") == 0) { - dbtype = DB_QUEUE; - break; - } - return (usage()); - case 'V': - printf("%s\n", db_version(NULL, NULL, NULL)); - return (EXIT_SUCCESS); - case '?': - default: - return (usage()); - } - argc -= optind; - argv += optind; - - if (argc != 1) - return (usage()); - - /* Handle possible interruptions. */ - __db_util_siginit(); - - /* - * Create an environment object initialized for error reporting, and - * then open it. - */ - if (env_create(&dbenv, &ldg) != 0) - goto shutdown; - - /* If we're resetting the LSNs, that's an entirely separate path. */ - switch (mode) { - case FILEID_RESET: - exitval = dbenv->fileid_reset( - dbenv, argv[0], ldf & LDF_PASSWORD ? DB_ENCRYPT : 0); - break; - case LSN_RESET: - exitval = dbenv->lsn_reset( - dbenv, argv[0], ldf & LDF_PASSWORD ? DB_ENCRYPT : 0); - break; - case NOTSET: - case STANDARD_LOAD: - while (!ldg.endofile) - if (load(dbenv, argv[0], dbtype, clist, ldf, - &ldg, &existed) != 0) - goto shutdown; - break; - } - - if (0) { -shutdown: exitval = 1; - } - if ((ret = dbenv->close(dbenv, 0)) != 0) { - exitval = 1; - fprintf(stderr, - "%s: dbenv->close: %s\n", ldg.progname, db_strerror(ret)); - } - - /* Resend any caught signal. */ - __db_util_sigresend(); - free(clist); - if (ldg.passwd != NULL) - free(ldg.passwd); - - /* - * Return 0 on success, 1 if keys existed already, and 2 on failure. - * - * Technically, this is wrong, because exit of anything other than - * 0 is implementation-defined by the ANSI C standard. I don't see - * any good solutions that don't involve API changes. - */ - return (exitval == 0 ? (existed == 0 ? 0 : 1) : 2); -} - -/* - * load -- - * Load a database. - */ -int -load(dbenv, name, argtype, clist, flags, ldg, existedp) - DB_ENV *dbenv; - char *name, **clist; - DBTYPE argtype; - u_int flags; - LDG *ldg; - int *existedp; -{ - DB *dbp; - DBT key, rkey, data, *readp, *writep; - DBTYPE dbtype; - DB_TXN *ctxn, *txn; - db_recno_t recno, datarecno; - u_int32_t put_flags; - int ascii_recno, checkprint, hexkeys, keyflag, keys, resize, ret, rval; - char *subdb; - - put_flags = LF_ISSET(LDF_NOOVERWRITE) ? DB_NOOVERWRITE : 0; - G(endodata) = 0; - - subdb = NULL; - ctxn = txn = NULL; - memset(&key, 0, sizeof(DBT)); - memset(&data, 0, sizeof(DBT)); - memset(&rkey, 0, sizeof(DBT)); - -retry_db: - dbtype = DB_UNKNOWN; - keys = -1; - hexkeys = -1; - keyflag = -1; - - /* Create the DB object. */ - if ((ret = db_create(&dbp, dbenv, 0)) != 0) { - dbenv->err(dbenv, ret, "db_create"); - goto err; - } - - /* Read the header -- if there's no header, we expect flat text. */ - if (LF_ISSET(LDF_NOHEADER)) { - checkprint = 1; - dbtype = argtype; - } else { - if (rheader(dbenv, - dbp, &dbtype, &subdb, &checkprint, &keys) != 0) - goto err; - if (G(endofile)) - goto done; - } - - /* - * Apply command-line configuration changes. (We apply command-line - * configuration changes to all databases that are loaded, e.g., all - * subdatabases.) - */ - if (configure(dbenv, dbp, clist, &subdb, &keyflag)) - goto err; - - if (keys != 1) { - if (keyflag == 1) { - dbp->err(dbp, EINVAL, "No keys specified in file"); - goto err; - } - } - else if (keyflag == 0) { - dbp->err(dbp, EINVAL, "Keys specified in file"); - goto err; - } - else - keyflag = 1; - - if (dbtype == DB_BTREE || dbtype == DB_HASH) { - if (keyflag == 0) - dbp->err(dbp, - EINVAL, "Btree and Hash must specify keys"); - else - keyflag = 1; - } - - if (argtype != DB_UNKNOWN) { - - if (dbtype == DB_RECNO || dbtype == DB_QUEUE) - if (keyflag != 1 && argtype != DB_RECNO && - argtype != DB_QUEUE) { - dbenv->errx(dbenv, - "improper database type conversion specified"); - goto err; - } - dbtype = argtype; - } - - if (dbtype == DB_UNKNOWN) { - dbenv->errx(dbenv, "no database type specified"); - goto err; - } - - if (keyflag == -1) - keyflag = 0; - - /* - * Recno keys have only been printed in hexadecimal starting - * with db_dump format version 3 (DB 3.2). - * - * !!! - * Note that version is set in rheader(), which must be called before - * this assignment. - */ - hexkeys = (G(version) >= 3 && keyflag == 1 && checkprint == 0); - - if (keyflag == 1 && (dbtype == DB_RECNO || dbtype == DB_QUEUE)) - ascii_recno = 1; - else - ascii_recno = 0; - - /* If configured with a password, encrypt databases we create. */ - if (LF_ISSET(LDF_PASSWORD) && - (ret = dbp->set_flags(dbp, DB_ENCRYPT)) != 0) { - dbp->err(dbp, ret, "DB->set_flags: DB_ENCRYPT"); - goto err; - } - -#if 0 - Set application-specific btree comparison or hash functions here. - For example: - - if ((ret = dbp->set_bt_compare(dbp, local_comparison_func)) != 0) { - dbp->err(dbp, ret, "DB->set_bt_compare"); - goto err; - } - if ((ret = dbp->set_h_hash(dbp, local_hash_func)) != 0) { - dbp->err(dbp, ret, "DB->set_h_hash"); - goto err; - } -#endif - - /* Open the DB file. */ - if ((ret = dbp->open(dbp, NULL, name, subdb, dbtype, - DB_CREATE | (TXN_ON(dbenv) ? DB_AUTO_COMMIT : 0), - __db_omode("rw-rw-rw-"))) != 0) { - dbp->err(dbp, ret, "DB->open: %s", name); - goto err; - } - if (ldg->private != 0) { - if ((ret = __db_util_cache(dbp, &ldg->cache, &resize)) != 0) - goto err; - if (resize) { - if ((ret = dbp->close(dbp, 0)) != 0) - goto err; - dbp = NULL; - if ((ret = dbenv->close(dbenv, 0)) != 0) - goto err; - if ((ret = env_create(&dbenv, ldg)) != 0) - goto err; - goto retry_db; - } - } - - /* Initialize the key/data pair. */ - readp = writep = &key; - if (dbtype == DB_RECNO || dbtype == DB_QUEUE) { - key.size = sizeof(recno); - if (keyflag) { - key.data = &datarecno; - if (checkprint) { - readp = &rkey; - goto key_data; - } - } else - key.data = &recno; - } else -key_data: if ((readp->data = malloc(readp->ulen = 1024)) == NULL) { - dbenv->err(dbenv, ENOMEM, NULL); - goto err; - } - if ((data.data = malloc(data.ulen = 1024)) == NULL) { - dbenv->err(dbenv, ENOMEM, NULL); - goto err; - } - - if (TXN_ON(dbenv) && - (ret = dbenv->txn_begin(dbenv, NULL, &txn, 0)) != 0) - goto err; - - /* Get each key/data pair and add them to the database. */ - for (recno = 1; !__db_util_interrupted(); ++recno) { - if (!keyflag) { - if (checkprint) { - if (dbt_rprint(dbenv, &data)) - goto err; - } else { - if (dbt_rdump(dbenv, &data)) - goto err; - } - } else { - if (checkprint) { - if (dbt_rprint(dbenv, readp)) - goto err; - if (ascii_recno && - dbt_to_recno(dbenv, readp, &datarecno) != 0) - goto err; - - if (!G(endodata) && dbt_rprint(dbenv, &data)) - goto odd_count; - } else { - if (ascii_recno) { - if (dbt_rrecno(dbenv, readp, hexkeys)) - goto err; - } else - if (dbt_rdump(dbenv, readp)) - goto err; - - if (!G(endodata) && dbt_rdump(dbenv, &data)) { -odd_count: dbenv->errx(dbenv, - "odd number of key/data pairs"); - goto err; - } - } - } - if (G(endodata)) - break; -retry: if (txn != NULL) - if ((ret = dbenv->txn_begin(dbenv, txn, &ctxn, 0)) != 0) - goto err; - switch (ret = dbp->put(dbp, ctxn, writep, &data, put_flags)) { - case 0: - if (ctxn != NULL) { - if ((ret = - ctxn->commit(ctxn, DB_TXN_NOSYNC)) != 0) - goto err; - ctxn = NULL; - } - break; - case DB_KEYEXIST: - *existedp = 1; - dbenv->errx(dbenv, - "%s: line %d: key already exists, not loaded:", - name, - !keyflag ? recno : recno * 2 - 1); - - (void)dbenv->prdbt(&key, - checkprint, 0, stderr, __db_pr_callback, 0); - break; - case DB_LOCK_DEADLOCK: - /* If we have a child txn, retry--else it's fatal. */ - if (ctxn != NULL) { - if ((ret = ctxn->abort(ctxn)) != 0) - goto err; - ctxn = NULL; - goto retry; - } - /* FALLTHROUGH */ - default: - dbenv->err(dbenv, ret, NULL); - if (ctxn != NULL) { - (void)ctxn->abort(ctxn); - ctxn = NULL; - } - goto err; - } - if (ctxn != NULL) { - if ((ret = ctxn->abort(ctxn)) != 0) - goto err; - ctxn = NULL; - } - } -done: rval = 0; - DB_ASSERT(ctxn == NULL); - if (txn != NULL && (ret = txn->commit(txn, 0)) != 0) { - txn = NULL; - goto err; - } - - if (0) { -err: rval = 1; - DB_ASSERT(ctxn == NULL); - if (txn != NULL) - (void)txn->abort(txn); - } - - /* Close the database. */ - if (dbp != NULL && (ret = dbp->close(dbp, 0)) != 0) { - dbenv->err(dbenv, ret, "DB->close"); - rval = 1; - } - - if (G(hdrbuf) != NULL) - free(G(hdrbuf)); - G(hdrbuf) = NULL; - /* Free allocated memory. */ - if (subdb != NULL) - free(subdb); - if (dbtype != DB_RECNO && dbtype != DB_QUEUE && key.data != NULL) - free(key.data); - if (rkey.data != NULL) - free(rkey.data); - free(data.data); - - return (rval); -} - -/* - * env_create -- - * Create the environment and initialize it for error reporting. - */ -int -env_create(dbenvp, ldg) - DB_ENV **dbenvp; - LDG *ldg; -{ - DB_ENV *dbenv; - int ret; - - if ((ret = db_env_create(dbenvp, 0)) != 0) { - fprintf(stderr, - "%s: db_env_create: %s\n", ldg->progname, db_strerror(ret)); - return (ret); - } - dbenv = *dbenvp; - dbenv->set_errfile(dbenv, stderr); - dbenv->set_errpfx(dbenv, ldg->progname); - if (ldg->passwd != NULL && (ret = dbenv->set_encrypt(dbenv, - ldg->passwd, DB_ENCRYPT_AES)) != 0) { - dbenv->err(dbenv, ret, "set_passwd"); - return (ret); - } - if ((ret = db_init(dbenv, ldg->home, ldg->cache, &ldg->private)) != 0) - return (ret); - dbenv->app_private = ldg; - - return (0); -} - -/* - * db_init -- - * Initialize the environment. - */ -int -db_init(dbenv, home, cache, is_private) - DB_ENV *dbenv; - char *home; - u_int32_t cache; - int *is_private; -{ - u_int32_t flags; - int ret; - - *is_private = 0; - /* We may be loading into a live environment. Try and join. */ - flags = DB_USE_ENVIRON | - DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN; - if ((ret = dbenv->open(dbenv, home, flags, 0)) == 0) - return (0); - if (ret == DB_VERSION_MISMATCH) - goto err; - - /* - * We're trying to load a database. - * - * An environment is required because we may be trying to look at - * databases in directories other than the current one. We could - * avoid using an environment iff the -h option wasn't specified, - * but that seems like more work than it's worth. - * - * No environment exists (or, at least no environment that includes - * an mpool region exists). Create one, but make it private so that - * no files are actually created. - */ - LF_CLR(DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_TXN); - LF_SET(DB_CREATE | DB_PRIVATE); - *is_private = 1; - if ((ret = dbenv->set_cachesize(dbenv, 0, cache, 1)) != 0) { - dbenv->err(dbenv, ret, "set_cachesize"); - return (1); - } - if ((ret = dbenv->open(dbenv, home, flags, 0)) == 0) - return (0); - - /* An environment is required. */ -err: dbenv->err(dbenv, ret, "DB_ENV->open"); - return (1); -} - -#define FLAG(name, value, keyword, flag) \ - if (strcmp(name, keyword) == 0) { \ - switch (*value) { \ - case '1': \ - if ((ret = dbp->set_flags(dbp, flag)) != 0) { \ - dbp->err(dbp, ret, "%s: set_flags: %s", \ - G(progname), name); \ - goto err; \ - } \ - break; \ - case '0': \ - break; \ - default: \ - badnum(dbenv); \ - goto err; \ - } \ - continue; \ - } -#define NUMBER(name, value, keyword, func, t) \ - if (strcmp(name, keyword) == 0) { \ - if ((ret = __db_getlong(dbenv, \ - NULL, value, 0, LONG_MAX, &val)) != 0 || \ - (ret = dbp->func(dbp, (t)val)) != 0) \ - goto nameerr; \ - continue; \ - } -#define STRING(name, value, keyword, func) \ - if (strcmp(name, keyword) == 0) { \ - if ((ret = dbp->func(dbp, value[0])) != 0) \ - goto nameerr; \ - continue; \ - } - -/* - * configure -- - * Handle command-line configuration options. - */ -int -configure(dbenv, dbp, clp, subdbp, keysp) - DB_ENV *dbenv; - DB *dbp; - char **clp, **subdbp; - int *keysp; -{ - long val; - int ret, savech; - char *name, *value; - - for (; (name = *clp) != NULL; *--value = savech, ++clp) { - if ((value = strchr(name, '=')) == NULL) { - dbp->errx(dbp, - "command-line configuration uses name=value format"); - return (1); - } - savech = *value; - *value++ = '\0'; - - if (strcmp(name, "database") == 0 || - strcmp(name, "subdatabase") == 0) { - if (*subdbp != NULL) - free(*subdbp); - if ((*subdbp = strdup(value)) == NULL) { - dbp->err(dbp, ENOMEM, NULL); - return (1); - } - continue; - } - if (strcmp(name, "keys") == 0) { - if (strcmp(value, "1") == 0) - *keysp = 1; - else if (strcmp(value, "0") == 0) - *keysp = 0; - else { - badnum(dbenv); - return (1); - } - continue; - } - - NUMBER(name, value, "bt_minkey", set_bt_minkey, u_int32_t); - NUMBER(name, value, "db_lorder", set_lorder, int); - NUMBER(name, value, "db_pagesize", set_pagesize, u_int32_t); - FLAG(name, value, "chksum", DB_CHKSUM); - FLAG(name, value, "duplicates", DB_DUP); - FLAG(name, value, "dupsort", DB_DUPSORT); - NUMBER(name, value, "h_ffactor", set_h_ffactor, u_int32_t); - NUMBER(name, value, "h_nelem", set_h_nelem, u_int32_t); - NUMBER(name, value, "re_len", set_re_len, u_int32_t); - STRING(name, value, "re_pad", set_re_pad); - FLAG(name, value, "recnum", DB_RECNUM); - FLAG(name, value, "renumber", DB_RENUMBER); - - dbp->errx(dbp, - "unknown command-line configuration keyword \"%s\"", name); - return (1); - } - return (0); - -nameerr: - dbp->err(dbp, ret, "%s: %s=%s", G(progname), name, value); -err: return (1); -} - -/* - * rheader -- - * Read the header message. - */ -int -rheader(dbenv, dbp, dbtypep, subdbp, checkprintp, keysp) - DB_ENV *dbenv; - DB *dbp; - DBTYPE *dbtypep; - char **subdbp; - int *checkprintp, *keysp; -{ - size_t buflen, linelen, start; - long val; - int ch, first, hdr, ret; - char *buf, *name, *p, *value; - - *dbtypep = DB_UNKNOWN; - *checkprintp = 0; - name = NULL; - - /* - * We start with a smallish buffer; most headers are small. - * We may need to realloc it for a large subdatabase name. - */ - buflen = 4096; - if (G(hdrbuf) == NULL) { - hdr = 0; - if ((buf = malloc(buflen)) == NULL) - goto memerr; - G(hdrbuf) = buf; - G(origline) = G(lineno); - } else { - hdr = 1; - buf = G(hdrbuf); - G(lineno) = G(origline); - } - - start = 0; - for (first = 1;; first = 0) { - ++G(lineno); - - /* Read a line, which may be of arbitrary length, into buf. */ - linelen = 0; - buf = &G(hdrbuf)[start]; - if (hdr == 0) { - for (;;) { - if ((ch = getchar()) == EOF) { - if (!first || ferror(stdin)) - goto badfmt; - G(endofile) = 1; - break; - } - - /* - * If the buffer is too small, double it. - */ - if (linelen + start == buflen) { - G(hdrbuf) = - realloc(G(hdrbuf), buflen *= 2); - if (G(hdrbuf) == NULL) - goto memerr; - buf = &G(hdrbuf)[start]; - } - - if (ch == '\n') - break; - - buf[linelen++] = ch; - } - if (G(endofile) == 1) - break; - buf[linelen++] = '\0'; - } else - linelen = strlen(buf) + 1; - start += linelen; - - if (name != NULL) { - free(name); - name = NULL; - } - /* If we don't see the expected information, it's an error. */ - if ((name = strdup(buf)) == NULL) - goto memerr; - if ((p = strchr(name, '=')) == NULL) - goto badfmt; - *p++ = '\0'; - - value = p--; - - if (name[0] == '\0' || value[0] == '\0') - goto badfmt; - - if (strcmp(name, "HEADER") == 0) - break; - if (strcmp(name, "VERSION") == 0) { - /* - * Version 1 didn't have a "VERSION" header line. We - * only support versions 1, 2, and 3 of the dump format. - */ - G(version) = atoi(value); - - if (G(version) > 3) { - dbp->errx(dbp, - "line %lu: VERSION %d is unsupported", - G(lineno), G(version)); - goto err; - } - continue; - } - if (strcmp(name, "format") == 0) { - if (strcmp(value, "bytevalue") == 0) { - *checkprintp = 0; - continue; - } - if (strcmp(value, "print") == 0) { - *checkprintp = 1; - continue; - } - goto badfmt; - } - if (strcmp(name, "type") == 0) { - if (strcmp(value, "btree") == 0) { - *dbtypep = DB_BTREE; - continue; - } - if (strcmp(value, "hash") == 0) { - *dbtypep = DB_HASH; - continue; - } - if (strcmp(value, "recno") == 0) { - *dbtypep = DB_RECNO; - continue; - } - if (strcmp(value, "queue") == 0) { - *dbtypep = DB_QUEUE; - continue; - } - dbp->errx(dbp, "line %lu: unknown type", G(lineno)); - goto err; - } - if (strcmp(name, "database") == 0 || - strcmp(name, "subdatabase") == 0) { - if ((ret = convprintable(dbenv, value, subdbp)) != 0) { - dbp->err(dbp, ret, "error reading db name"); - goto err; - } - continue; - } - if (strcmp(name, "keys") == 0) { - if (strcmp(value, "1") == 0) - *keysp = 1; - else if (strcmp(value, "0") == 0) - *keysp = 0; - else { - badnum(dbenv); - goto err; - } - continue; - } - -#ifdef notyet - NUMBER(name, value, "bt_maxkey", set_bt_maxkey, u_int32_t); -#endif - NUMBER(name, value, "bt_minkey", set_bt_minkey, u_int32_t); - NUMBER(name, value, "db_lorder", set_lorder, int); - NUMBER(name, value, "db_pagesize", set_pagesize, u_int32_t); - NUMBER(name, value, "extentsize", set_q_extentsize, u_int32_t); - FLAG(name, value, "chksum", DB_CHKSUM); - FLAG(name, value, "duplicates", DB_DUP); - FLAG(name, value, "dupsort", DB_DUPSORT); - NUMBER(name, value, "h_ffactor", set_h_ffactor, u_int32_t); - NUMBER(name, value, "h_nelem", set_h_nelem, u_int32_t); - NUMBER(name, value, "re_len", set_re_len, u_int32_t); - STRING(name, value, "re_pad", set_re_pad); - FLAG(name, value, "recnum", DB_RECNUM); - FLAG(name, value, "renumber", DB_RENUMBER); - - dbp->errx(dbp, - "unknown input-file header configuration keyword \"%s\"", - name); - goto err; - } - ret = 0; - - if (0) { -nameerr: dbp->err(dbp, ret, "%s: %s=%s", G(progname), name, value); - ret = 1; - } - if (0) { -badfmt: dbp->errx(dbp, "line %lu: unexpected format", G(lineno)); - ret = 1; - } - if (0) { -memerr: dbp->errx(dbp, "unable to allocate memory"); -err: ret = 1; - } - if (name != NULL) - free(name); - return (ret); -} - -/* - * convprintable -- - * Convert a printable-encoded string into a newly allocated string. - * - * In an ideal world, this would probably share code with dbt_rprint, but - * that's set up to read character-by-character (to avoid large memory - * allocations that aren't likely to be a problem here), and this has fewer - * special cases to deal with. - * - * Note that despite the printable encoding, the char * interface to this - * function (which is, not coincidentally, also used for database naming) - * means that outstr cannot contain any nuls. - */ -int -convprintable(dbenv, instr, outstrp) - DB_ENV *dbenv; - char *instr, **outstrp; -{ - char c, *outstr; - int e1, e2; - - /* - * Just malloc a string big enough for the whole input string; - * the output string will be smaller (or of equal length). - */ - if ((outstr = malloc(strlen(instr) + 1)) == NULL) - return (ENOMEM); - - *outstrp = outstr; - - e1 = e2 = 0; - for ( ; *instr != '\0'; instr++) - if (*instr == '\\') { - if (*++instr == '\\') { - *outstr++ = '\\'; - continue; - } - c = digitize(dbenv, *instr, &e1) << 4; - c |= digitize(dbenv, *++instr, &e2); - if (e1 || e2) { - badend(dbenv); - return (EINVAL); - } - - *outstr++ = c; - } else - *outstr++ = *instr; - - *outstr = '\0'; - - return (0); -} - -/* - * dbt_rprint -- - * Read a printable line into a DBT structure. - */ -int -dbt_rprint(dbenv, dbtp) - DB_ENV *dbenv; - DBT *dbtp; -{ - u_int32_t len; - u_int8_t *p; - int c1, c2, e, escape, first; - char buf[32]; - - ++G(lineno); - - first = 1; - e = escape = 0; - for (p = dbtp->data, len = 0; (c1 = getchar()) != '\n';) { - if (c1 == EOF) { - if (len == 0) { - G(endofile) = G(endodata) = 1; - return (0); - } - badend(dbenv); - return (1); - } - if (first) { - first = 0; - if (G(version) > 1) { - if (c1 != ' ') { - buf[0] = c1; - if (fgets(buf + 1, - sizeof(buf) - 1, stdin) == NULL || - strcmp(buf, "DATA=END\n") != 0) { - badend(dbenv); - return (1); - } - G(endodata) = 1; - return (0); - } - continue; - } - } - if (escape) { - if (c1 != '\\') { - if ((c2 = getchar()) == EOF) { - badend(dbenv); - return (1); - } - c1 = digitize(dbenv, - c1, &e) << 4 | digitize(dbenv, c2, &e); - if (e) - return (1); - } - escape = 0; - } else - if (c1 == '\\') { - escape = 1; - continue; - } - if (len >= dbtp->ulen - 10) { - dbtp->ulen *= 2; - if ((dbtp->data = - realloc(dbtp->data, dbtp->ulen)) == NULL) { - dbenv->err(dbenv, ENOMEM, NULL); - return (1); - } - p = (u_int8_t *)dbtp->data + len; - } - ++len; - *p++ = c1; - } - dbtp->size = len; - - return (0); -} - -/* - * dbt_rdump -- - * Read a byte dump line into a DBT structure. - */ -int -dbt_rdump(dbenv, dbtp) - DB_ENV *dbenv; - DBT *dbtp; -{ - u_int32_t len; - u_int8_t *p; - int c1, c2, e, first; - char buf[32]; - - ++G(lineno); - - first = 1; - e = 0; - for (p = dbtp->data, len = 0; (c1 = getchar()) != '\n';) { - if (c1 == EOF) { - if (len == 0) { - G(endofile) = G(endodata) = 1; - return (0); - } - badend(dbenv); - return (1); - } - if (first) { - first = 0; - if (G(version) > 1) { - if (c1 != ' ') { - buf[0] = c1; - if (fgets(buf + 1, - sizeof(buf) - 1, stdin) == NULL || - strcmp(buf, "DATA=END\n") != 0) { - badend(dbenv); - return (1); - } - G(endodata) = 1; - return (0); - } - continue; - } - } - if ((c2 = getchar()) == EOF) { - badend(dbenv); - return (1); - } - if (len >= dbtp->ulen - 10) { - dbtp->ulen *= 2; - if ((dbtp->data = - realloc(dbtp->data, dbtp->ulen)) == NULL) { - dbenv->err(dbenv, ENOMEM, NULL); - return (1); - } - p = (u_int8_t *)dbtp->data + len; - } - ++len; - *p++ = digitize(dbenv, c1, &e) << 4 | digitize(dbenv, c2, &e); - if (e) - return (1); - } - dbtp->size = len; - - return (0); -} - -/* - * dbt_rrecno -- - * Read a record number dump line into a DBT structure. - */ -int -dbt_rrecno(dbenv, dbtp, ishex) - DB_ENV *dbenv; - DBT *dbtp; - int ishex; -{ - char buf[32], *p, *q; - u_long recno; - - ++G(lineno); - - if (fgets(buf, sizeof(buf), stdin) == NULL) { - G(endofile) = G(endodata) = 1; - return (0); - } - - if (strcmp(buf, "DATA=END\n") == 0) { - G(endodata) = 1; - return (0); - } - - if (buf[0] != ' ') - goto bad; - - /* - * If we're expecting a hex key, do an in-place conversion - * of hex to straight ASCII before calling __db_getulong(). - */ - if (ishex) { - for (p = q = buf + 1; *q != '\0' && *q != '\n';) { - /* - * 0-9 in hex are 0x30-0x39, so this is easy. - * We should alternate between 3's and [0-9], and - * if the [0-9] are something unexpected, - * __db_getulong will fail, so we only need to catch - * end-of-string conditions. - */ - if (*q++ != '3') - goto bad; - if (*q == '\n' || *q == '\0') - goto bad; - *p++ = *q++; - } - *p = '\0'; - } - - if (__db_getulong(dbenv, G(progname), buf + 1, 0, 0, &recno)) { -bad: badend(dbenv); - return (1); - } - - *((db_recno_t *)dbtp->data) = recno; - dbtp->size = sizeof(db_recno_t); - return (0); -} - -int -dbt_to_recno(dbenv, dbt, recnop) - DB_ENV *dbenv; - DBT *dbt; - db_recno_t *recnop; -{ - char buf[32]; /* Large enough for 2^64. */ - - memcpy(buf, dbt->data, dbt->size); - buf[dbt->size] = '\0'; - - return (__db_getulong(dbenv, G(progname), buf, 0, 0, (u_long *)recnop)); -} - -/* - * digitize -- - * Convert a character to an integer. - */ -int -digitize(dbenv, c, errorp) - DB_ENV *dbenv; - int c, *errorp; -{ - switch (c) { /* Don't depend on ASCII ordering. */ - case '0': return (0); - case '1': return (1); - case '2': return (2); - case '3': return (3); - case '4': return (4); - case '5': return (5); - case '6': return (6); - case '7': return (7); - case '8': return (8); - case '9': return (9); - case 'a': return (10); - case 'b': return (11); - case 'c': return (12); - case 'd': return (13); - case 'e': return (14); - case 'f': return (15); - default: /* Not possible. */ - break; - } - - dbenv->errx(dbenv, "unexpected hexadecimal value"); - *errorp = 1; - - return (0); -} - -/* - * badnum -- - * Display the bad number message. - */ -void -badnum(dbenv) - DB_ENV *dbenv; -{ - dbenv->errx(dbenv, - "boolean name=value pairs require a value of 0 or 1"); -} - -/* - * badend -- - * Display the bad end to input message. - */ -void -badend(dbenv) - DB_ENV *dbenv; -{ - dbenv->errx(dbenv, "unexpected end of input data or key/data pair"); -} - -/* - * usage -- - * Display the usage message. - */ -int -usage() -{ - (void)fprintf(stderr, "usage: %s %s\n\t%s\n", progname, - "[-nTV] [-c name=value] [-f file]", - "[-h home] [-P password] [-t btree | hash | recno | queue] db_file"); - (void)fprintf(stderr, "usage: %s %s\n", - progname, "-r lsn | fileid [-h home] [-P password] db_file"); - return (EXIT_FAILURE); -} - -int -version_check() -{ - int v_major, v_minor, v_patch; - - /* Make sure we're loaded with the right version of the DB library. */ - (void)db_version(&v_major, &v_minor, &v_patch); - if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) { - fprintf(stderr, - "%s: version %d.%d doesn't match library version %d.%d\n", - progname, DB_VERSION_MAJOR, DB_VERSION_MINOR, - v_major, v_minor); - return (EXIT_FAILURE); - } - return (0); -} diff --git a/storage/bdb/db_printlog/README b/storage/bdb/db_printlog/README deleted file mode 100644 index eca5383cb58..00000000000 --- a/storage/bdb/db_printlog/README +++ /dev/null @@ -1,34 +0,0 @@ -# $Id: README,v 12.0 2004/11/17 03:43:23 bostic Exp $ - -Berkeley DB log dump utility. This utility dumps out a DB log in human -readable form, a record at a time, to assist in recovery and transaction -abort debugging. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -commit.awk Output transaction ID of committed transactions. - -count.awk Print out the number of log records for transactions - that we encountered. - -dbname.awk Take a comma-separated list of database names and spit - out all the log records that affect those databases. - -fileid.awk Take a comma-separated list of file numbers and spit out - all the log records that affect those file numbers. - -logstat.awk Display log record count/size statistics. - -pgno.awk Take a comma-separated list of page numbers and spit - out all the log records that affect those page numbers. - -range.awk Print out a range of the log. - -rectype.awk Print out a range of the log -- command line should - set RECTYPE to the a comma separated list of the - rectypes (or partial strings of rectypes) sought. - -status.awk Read through db_printlog output and list the transactions - encountered, and whether they committed or aborted. - -txn.awk Print out all the records for a comma-separated list of - transaction IDs. diff --git a/storage/bdb/db_printlog/commit.awk b/storage/bdb/db_printlog/commit.awk deleted file mode 100644 index 4f03fd2ce50..00000000000 --- a/storage/bdb/db_printlog/commit.awk +++ /dev/null @@ -1,7 +0,0 @@ -# $Id: commit.awk,v 12.0 2004/11/17 03:43:24 bostic Exp $ -# -# Output tid of committed transactions. - -/txn_regop/ { - print $5 -} diff --git a/storage/bdb/db_printlog/count.awk b/storage/bdb/db_printlog/count.awk deleted file mode 100644 index 6a80cbe1b60..00000000000 --- a/storage/bdb/db_printlog/count.awk +++ /dev/null @@ -1,9 +0,0 @@ -# $Id: count.awk,v 12.0 2004/11/17 03:43:24 bostic Exp $ -# -# Print out the number of log records for transactions that we -# encountered. - -/^\[/{ - if ($5 != 0) - print $5 -} diff --git a/storage/bdb/db_printlog/db_printlog.c b/storage/bdb/db_printlog/db_printlog.c deleted file mode 100644 index 4a96efd9073..00000000000 --- a/storage/bdb/db_printlog/db_printlog.c +++ /dev/null @@ -1,434 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_printlog.c,v 12.5 2005/09/09 12:38:33 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef lint -static const char copyright[] = - "Copyright (c) 1996-2005\nSleepycat Software Inc. All rights reserved.\n"; -#endif - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/btree.h" -#include "dbinc/fop.h" -#include "dbinc/hash.h" -#include "dbinc/log.h" -#include "dbinc/qam.h" -#include "dbinc/txn.h" - -int lsn_arg __P((char *, DB_LSN *)); -int main __P((int, char *[])); -int open_rep_db __P((DB_ENV *, DB **, DBC **)); -int print_app_record __P((DB_ENV *, DBT *, DB_LSN *, db_recops)); -int usage __P((void)); -int version_check __P((void)); - -const char *progname; - -int -main(argc, argv) - int argc; - char *argv[]; -{ - extern char *optarg; - extern int optind; - DB *dbp; - DBC *dbc; - DBT data, keydbt; - DB_ENV *dbenv; - DB_LOGC *logc; - DB_LSN key, start, stop; - size_t dtabsize; - u_int32_t logcflag; - int ch, cmp, exitval, nflag, rflag, ret, repflag; - int (**dtab) __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - char *home, *passwd; - - if ((progname = strrchr(argv[0], '/')) == NULL) - progname = argv[0]; - else - ++progname; - - if ((ret = version_check()) != 0) - return (ret); - - dbp = NULL; - dbc = NULL; - dbenv = NULL; - logc = NULL; - ZERO_LSN(start); - ZERO_LSN(stop); - dtabsize = 0; - exitval = nflag = rflag = repflag = 0; - dtab = NULL; - home = passwd = NULL; - - while ((ch = getopt(argc, argv, "b:e:h:NP:rRV")) != EOF) - switch (ch) { - case 'b': - if (lsn_arg(optarg, &start)) - return (usage()); - break; - case 'e': - if (lsn_arg(optarg, &stop)) - return (usage()); - break; - case 'h': - home = optarg; - break; - case 'N': - nflag = 1; - break; - case 'P': - passwd = strdup(optarg); - memset(optarg, 0, strlen(optarg)); - if (passwd == NULL) { - fprintf(stderr, "%s: strdup: %s\n", - progname, strerror(errno)); - return (EXIT_FAILURE); - } - break; - case 'r': - rflag = 1; - break; - case 'R': /* Undocumented */ - repflag = 1; - break; - case 'V': - printf("%s\n", db_version(NULL, NULL, NULL)); - return (EXIT_SUCCESS); - case '?': - default: - return (usage()); - } - argc -= optind; - argv += optind; - - if (argc > 0) - return (usage()); - - /* Handle possible interruptions. */ - __db_util_siginit(); - - /* - * Create an environment object and initialize it for error - * reporting. - */ - if ((ret = db_env_create(&dbenv, 0)) != 0) { - fprintf(stderr, - "%s: db_env_create: %s\n", progname, db_strerror(ret)); - goto shutdown; - } - - dbenv->set_errfile(dbenv, stderr); - dbenv->set_errpfx(dbenv, progname); - - if (nflag) { - if ((ret = dbenv->set_flags(dbenv, DB_NOLOCKING, 1)) != 0) { - dbenv->err(dbenv, ret, "set_flags: DB_NOLOCKING"); - goto shutdown; - } - if ((ret = dbenv->set_flags(dbenv, DB_NOPANIC, 1)) != 0) { - dbenv->err(dbenv, ret, "set_flags: DB_NOPANIC"); - goto shutdown; - } - } - - if (passwd != NULL && (ret = dbenv->set_encrypt(dbenv, - passwd, DB_ENCRYPT_AES)) != 0) { - dbenv->err(dbenv, ret, "set_passwd"); - goto shutdown; - } - - /* - * Set up an app-specific dispatch function so that we can gracefully - * handle app-specific log records. - */ - if ((ret = dbenv->set_app_dispatch(dbenv, print_app_record)) != 0) { - dbenv->err(dbenv, ret, "app_dispatch"); - goto shutdown; - } - - /* - * An environment is required, but as all we're doing is reading log - * files, we create one if it doesn't already exist. If we create - * it, create it private so it automatically goes away when we're done. - * If we are reading the replication database, do not open the env - * with logging, because we don't want to log the opens. - */ - if (repflag) { - if ((ret = dbenv->open(dbenv, home, - DB_INIT_MPOOL | DB_USE_ENVIRON, 0)) != 0 && - (ret == DB_VERSION_MISMATCH || - (ret = dbenv->open(dbenv, home, - DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE | DB_USE_ENVIRON, 0)) - != 0)) { - dbenv->err(dbenv, ret, "DB_ENV->open"); - goto shutdown; - } - } else if ((ret = dbenv->open(dbenv, home, DB_USE_ENVIRON, 0)) != 0 && - (ret == DB_VERSION_MISMATCH || - (ret = dbenv->open(dbenv, home, - DB_CREATE | DB_INIT_LOG | DB_PRIVATE | DB_USE_ENVIRON, 0)) != 0)) { - dbenv->err(dbenv, ret, "DB_ENV->open"); - goto shutdown; - } - - /* Initialize print callbacks. */ - if ((ret = __bam_init_print(dbenv, &dtab, &dtabsize)) != 0 || - (ret = __crdel_init_print(dbenv, &dtab, &dtabsize)) != 0 || - (ret = __db_init_print(dbenv, &dtab, &dtabsize)) != 0 || - (ret = __dbreg_init_print(dbenv, &dtab, &dtabsize)) != 0 || - (ret = __fop_init_print(dbenv, &dtab, &dtabsize)) != 0 || -#ifdef HAVE_HASH - (ret = __ham_init_print(dbenv, &dtab, &dtabsize)) != 0 || -#endif -#ifdef HAVE_QUEUE - (ret = __qam_init_print(dbenv, &dtab, &dtabsize)) != 0 || -#endif - (ret = __txn_init_print(dbenv, &dtab, &dtabsize)) != 0) { - dbenv->err(dbenv, ret, "callback: initialization"); - goto shutdown; - } - - /* Allocate a log cursor. */ - if (repflag) { - if ((ret = open_rep_db(dbenv, &dbp, &dbc)) != 0) - goto shutdown; - } else if ((ret = dbenv->log_cursor(dbenv, &logc, 0)) != 0) { - dbenv->err(dbenv, ret, "DB_ENV->log_cursor"); - goto shutdown; - } - - if (IS_ZERO_LSN(start)) { - memset(&keydbt, 0, sizeof(keydbt)); - logcflag = rflag ? DB_PREV : DB_NEXT; - } else { - key = start; - logcflag = DB_SET; - } - memset(&data, 0, sizeof(data)); - - for (; !__db_util_interrupted(); logcflag = rflag ? DB_PREV : DB_NEXT) { - if (repflag) { - ret = dbc->c_get(dbc, &keydbt, &data, logcflag); - if (ret == 0) - key = ((REP_CONTROL *)keydbt.data)->lsn; - } else - ret = logc->get(logc, &key, &data, logcflag); - if (ret != 0) { - if (ret == DB_NOTFOUND) - break; - dbenv->err(dbenv, - ret, repflag ? "DB_LOGC->get" : "DBC->get"); - goto shutdown; - } - - /* - * We may have reached the end of the range we're displaying. - */ - if (!IS_ZERO_LSN(stop)) { - cmp = log_compare(&key, &stop); - if ((rflag && cmp < 0) || (!rflag && cmp > 0)) - break; - } - - ret = __db_dispatch(dbenv, - dtab, dtabsize, &data, &key, DB_TXN_PRINT, NULL); - - /* - * XXX - * Just in case the underlying routines don't flush. - */ - (void)fflush(stdout); - - if (ret != 0) { - dbenv->err(dbenv, ret, "tx: dispatch"); - goto shutdown; - } - } - - if (0) { -shutdown: exitval = 1; - } - if (logc != NULL && (ret = logc->close(logc, 0)) != 0) - exitval = 1; - - if (dbc != NULL && (ret = dbc->c_close(dbc)) != 0) - exitval = 1; - - if (dbp != NULL && (ret = dbp->close(dbp, 0)) != 0) - exitval = 1; - - /* - * The dtab is allocated by __db_add_recovery (called by *_init_print) - * using the library malloc function (__os_malloc). It thus needs to be - * freed using the corresponding free (__os_free). - */ - if (dtab != NULL) - __os_free(dbenv, dtab); - if (dbenv != NULL && (ret = dbenv->close(dbenv, 0)) != 0) { - exitval = 1; - fprintf(stderr, - "%s: dbenv->close: %s\n", progname, db_strerror(ret)); - } - - if (passwd != NULL) - free(passwd); - - /* Resend any caught signal. */ - __db_util_sigresend(); - - return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE); -} - -int -usage() -{ - fprintf(stderr, "usage: %s %s\n", progname, - "[-NrV] [-b file/offset] [-e file/offset] [-h home] [-P password]"); - return (EXIT_FAILURE); -} - -int -version_check() -{ - int v_major, v_minor, v_patch; - - /* Make sure we're loaded with the right version of the DB library. */ - (void)db_version(&v_major, &v_minor, &v_patch); - if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) { - fprintf(stderr, - "%s: version %d.%d doesn't match library version %d.%d\n", - progname, DB_VERSION_MAJOR, DB_VERSION_MINOR, - v_major, v_minor); - return (EXIT_FAILURE); - } - return (0); -} - -/* Print an unknown, application-specific log record as best we can. */ -int -print_app_record(dbenv, dbt, lsnp, op) - DB_ENV *dbenv; - DBT *dbt; - DB_LSN *lsnp; - db_recops op; -{ - int ch; - u_int32_t i, rectype; - - DB_ASSERT(op == DB_TXN_PRINT); - - COMPQUIET(dbenv, NULL); - COMPQUIET(op, DB_TXN_PRINT); - - /* - * Fetch the rectype, which always must be at the beginning of the - * record (if dispatching is to work at all). - */ - memcpy(&rectype, dbt->data, sizeof(rectype)); - - /* - * Applications may wish to customize the output here based on the - * rectype. We just print the entire log record in the generic - * mixed-hex-and-printable format we use for binary data. - */ - printf("[%lu][%lu]application specific record: rec: %lu\n", - (u_long)lsnp->file, (u_long)lsnp->offset, (u_long)rectype); - printf("\tdata: "); - for (i = 0; i < dbt->size; i++) { - ch = ((u_int8_t *)dbt->data)[i]; - printf(isprint(ch) || ch == 0x0a ? "%c" : "%#x ", ch); - } - printf("\n\n"); - - return (0); -} - -int -open_rep_db(dbenv, dbpp, dbcp) - DB_ENV *dbenv; - DB **dbpp; - DBC **dbcp; -{ - int ret; - - DB *dbp; - *dbpp = NULL; - *dbcp = NULL; - - if ((ret = db_create(dbpp, dbenv, 0)) != 0) { - dbenv->err(dbenv, ret, "db_create"); - return (ret); - } - - dbp = *dbpp; - if ((ret = - dbp->open(dbp, NULL, "__db.rep.db", NULL, DB_BTREE, 0, 0)) != 0) { - dbenv->err(dbenv, ret, "DB->open"); - goto err; - } - - if ((ret = dbp->cursor(dbp, NULL, dbcp, 0)) != 0) { - dbenv->err(dbenv, ret, "DB->cursor"); - goto err; - } - - return (0); - -err: if (*dbpp != NULL) - (void)(*dbpp)->close(*dbpp, 0); - return (ret); -} - -/* - * lsn_arg -- - * Parse a LSN argument. - */ -int -lsn_arg(arg, lsnp) - char *arg; - DB_LSN *lsnp; -{ - char *p; - u_long uval; - - /* - * Expected format is: lsn.file/lsn.offset. - * - * Don't use getsubopt(3), some systems don't have it. - */ - if ((p = strchr(arg, '/')) == NULL) - return (1); - *p = '\0'; - - if (__db_getulong(NULL, progname, arg, 0, 0, &uval)) - return (1); - if (uval > UINT32_MAX) - return (1); - lsnp->file = uval; - if (__db_getulong(NULL, progname, p + 1, 0, 0, &uval)) - return (1); - if (uval > UINT32_MAX) - return (1); - lsnp->offset = uval; - return (0); -} diff --git a/storage/bdb/db_printlog/dbname.awk b/storage/bdb/db_printlog/dbname.awk deleted file mode 100644 index a864c95dd53..00000000000 --- a/storage/bdb/db_printlog/dbname.awk +++ /dev/null @@ -1,82 +0,0 @@ -# $Id: dbname.awk,v 12.1 2005/03/23 04:56:51 ubell Exp $ -# -# Take a comma-separated list of database names and spit out all the -# log records that affect those databases. - -NR == 1 { - nfiles = 0 - while ((ndx = index(DBNAME, ",")) != 0) { - filenames[nfiles] = substr(DBNAME, 1, ndx - 1) 0; - DBNAME = substr(DBNAME, ndx + 1, length(DBNAME) - ndx); - files[nfiles] = -1 - nfiles++ - } - filenames[nfiles] = DBNAME 0; - files[nfiles] = -1 - myfile = -1; - nreg = 0; -} - -/^\[.*dbreg_register/ { - register = 1; -} -/opcode:/ { - if (register == 1) { - if ($2 == 1) - register = 3; - else - register = $2; - } -} -/name:/ { - if (register >= 2) { - myfile = -2; - for (i = 0; i <= nfiles; i++) { - if ($2 == filenames[i]) { - if (register == 2) { - printme = 0; - myfile = -2; - } else { - myfile = i; - } - break; - } - } - } - register = 0; -} -/fileid:/{ - if (myfile == -2) - files[$2] = 0; - else if (myfile != -1) { - files[$2] = 1; - if ($2 > nreg) - nreg = $2; - printme = 1; - register = 0; - myfile = -1; - } else if ($2 <= nreg && files[$2] == 1) { - printme = 1 - } - myfile = -1; -} - -/^\[/{ - if (printme == 1) { - printf("%s\n", rec); - printme = 0 - } - rec = ""; - - rec = $0 -} - -TXN == 1 && /txn_regop/ {printme = 1} -/^ /{ - rec = sprintf("%s\n%s", rec, $0); -} - -END { - if (printme == 1) - printf("%s\n", rec); -} diff --git a/storage/bdb/db_printlog/fileid.awk b/storage/bdb/db_printlog/fileid.awk deleted file mode 100644 index 853ba866c99..00000000000 --- a/storage/bdb/db_printlog/fileid.awk +++ /dev/null @@ -1,37 +0,0 @@ -# $Id: fileid.awk,v 12.0 2004/11/17 03:43:25 bostic Exp $ -# -# Take a comma-separated list of file numbers and spit out all the -# log records that affect those file numbers. - -NR == 1 { - nfiles = 0 - while ((ndx = index(FILEID, ",")) != 0) { - files[nfiles] = substr(FILEID, 1, ndx - 1); - FILEID = substr(FILEID, ndx + 1, length(FILEID) - ndx); - nfiles++ - } - files[nfiles] = FILEID; -} - -/^\[/{ - if (printme == 1) { - printf("%s\n", rec); - printme = 0 - } - rec = ""; - - rec = $0 -} -/^ /{ - rec = sprintf("%s\n%s", rec, $0); -} -/fileid/{ - for (i = 0; i <= nfiles; i++) - if ($2 == files[i]) - printme = 1 -} - -END { - if (printme == 1) - printf("%s\n", rec); -} diff --git a/storage/bdb/db_printlog/logstat.awk b/storage/bdb/db_printlog/logstat.awk deleted file mode 100644 index 83386465375..00000000000 --- a/storage/bdb/db_printlog/logstat.awk +++ /dev/null @@ -1,36 +0,0 @@ -# $Id: logstat.awk,v 12.0 2004/11/17 03:43:25 bostic Exp $ -# -# Output accumulated log record count/size statistics. -BEGIN { - l_file = 0; - l_offset = 0; -} - -/^\[/{ - gsub("[][: ]", " ", $1) - split($1, a) - - if (a[1] == l_file) { - l[a[3]] += a[2] - l_offset - ++n[a[3]] - } else - ++s[a[3]] - - l_file = a[1] - l_offset = a[2] -} - -END { - # We can't figure out the size of the first record in each log file, - # use the average for other records we found as an estimate. - for (i in s) - if (s[i] != 0 && n[i] != 0) { - l[i] += s[i] * (l[i]/n[i]) - n[i] += s[i] - delete s[i] - } - for (i in l) - printf "%s: %d (n: %d, avg: %.2f)\n", i, l[i], n[i], l[i]/n[i] - for (i in s) - printf "%s: unknown (n: %d, unknown)\n", i, s[i] -} diff --git a/storage/bdb/db_printlog/pgno.awk b/storage/bdb/db_printlog/pgno.awk deleted file mode 100644 index f58713523f1..00000000000 --- a/storage/bdb/db_printlog/pgno.awk +++ /dev/null @@ -1,47 +0,0 @@ -# $Id: pgno.awk,v 12.0 2004/11/17 03:43:25 bostic Exp $ -# -# Take a comma-separated list of page numbers and spit out all the -# log records that affect those page numbers. - -NR == 1 { - npages = 0 - while ((ndx = index(PGNO, ",")) != 0) { - pgno[npages] = substr(PGNO, 1, ndx - 1); - PGNO = substr(PGNO, ndx + 1, length(PGNO) - ndx); - npages++ - } - pgno[npages] = PGNO; -} - -/^\[/{ - if (printme == 1) { - printf("%s\n", rec); - printme = 0 - } - rec = ""; - - rec = $0 -} -/^ /{ - rec = sprintf("%s\n%s", rec, $0); -} -/pgno/{ - for (i = 0; i <= npages; i++) - if ($2 == pgno[i]) - printme = 1 -} -/right/{ - for (i = 0; i <= npages; i++) - if ($2 == pgno[i]) - printme = 1 -} -/left/{ - for (i = 0; i <= npages; i++) - if ($2 == pgno[i]) - printme = 1 -} - -END { - if (printme == 1) - printf("%s\n", rec); -} diff --git a/storage/bdb/db_printlog/range.awk b/storage/bdb/db_printlog/range.awk deleted file mode 100644 index 045c7fb2070..00000000000 --- a/storage/bdb/db_printlog/range.awk +++ /dev/null @@ -1,27 +0,0 @@ -# $Id: range.awk,v 12.0 2004/11/17 03:43:25 bostic Exp $ -# -# Print out a range of the log - -/^\[/{ - l = length($1) - 1; - i = index($1, "]"); - file = substr($1, 2, i - 2); - file += 0; - start = i + 2; - offset = substr($1, start, l - start + 1); - i = index(offset, "]"); - offset = substr($1, start, i - 1); - offset += 0; - - if ((file == START_FILE && offset >= START_OFFSET || file > START_FILE)\ - && (file < END_FILE || (file == END_FILE && offset < END_OFFSET))) - printme = 1 - else if (file == END_FILE && offset > END_OFFSET || file > END_FILE) - exit - else - printme = 0 -} -{ - if (printme == 1) - print $0 -} diff --git a/storage/bdb/db_printlog/rectype.awk b/storage/bdb/db_printlog/rectype.awk deleted file mode 100644 index 25b28008561..00000000000 --- a/storage/bdb/db_printlog/rectype.awk +++ /dev/null @@ -1,27 +0,0 @@ -# $Id: rectype.awk,v 12.0 2004/11/17 03:43:25 bostic Exp $ -# -# Print out a range of the log. -# Command line should set RECTYPE to a comma separated list -# of the rectypes (or partial strings of rectypes) sought. -NR == 1 { - ntypes = 0 - while ((ndx = index(RECTYPE, ",")) != 0) { - types[ntypes] = substr(RECTYPE, 1, ndx - 1); - RECTYPE = substr(RECTYPE, ndx + 1, length(RECTYPE) - ndx); - ntypes++ - } - types[ntypes] = RECTYPE; -} - -/^\[/{ - printme = 0 - for (i = 0; i <= ntypes; i++) - if (index($1, types[i]) != 0) { - printme = 1 - break; - } -} -{ - if (printme == 1) - print $0 -} diff --git a/storage/bdb/db_printlog/status.awk b/storage/bdb/db_printlog/status.awk deleted file mode 100644 index 0433312debf..00000000000 --- a/storage/bdb/db_printlog/status.awk +++ /dev/null @@ -1,50 +0,0 @@ -# $Id: status.awk,v 12.0 2004/11/17 03:43:25 bostic Exp $ -# -# Read through db_printlog output and list all the transactions encountered -# and whether they committed or aborted. -# -# 1 = started -# 2 = committed -# 3 = explicitly aborted -# 4 = other -BEGIN { - cur_txn = 0 -} -/^\[/{ - in_regop = 0 - if (status[$5] == 0) { - status[$5] = 1; - txns[cur_txn] = $5; - cur_txn++; - } -} -/ child:/ { - txnid = substr($2, 3); - status[txnid] = 2; -} -/txn_regop/ { - txnid = $5 - in_regop = 1 -} -/opcode:/ { - if (in_regop == 1) { - if ($2 == 1) - status[txnid] = 2 - else if ($2 == 3) - status[txnid] = 3 - else - status[txnid] = 4 - } -} -END { - for (i = 0; i < cur_txn; i++) { - if (status[txns[i]] == 1) - printf("%s\tABORT\n", txns[i]); - else if (status[txns[i]] == 2) - printf("%s\tCOMMIT\n", txns[i]); - else if (status[txns[i]] == 3) - printf("%s\tABORT\n", txns[i]); - else if (status[txns[i]] == 4) - printf("%s\tOTHER\n", txns[i]); - } -} diff --git a/storage/bdb/db_printlog/txn.awk b/storage/bdb/db_printlog/txn.awk deleted file mode 100644 index 12f283ebf79..00000000000 --- a/storage/bdb/db_printlog/txn.awk +++ /dev/null @@ -1,34 +0,0 @@ -# $Id: txn.awk,v 12.0 2004/11/17 03:43:25 bostic Exp $ -# -# Print out all the records for a comma-separated list of transaction ids. -NR == 1 { - ntxns = 0 - while ((ndx = index(TXN, ",")) != 0) { - txn[ntxns] = substr(TXN, 1, ndx - 1); - TXN = substr(TXN, ndx + 1, length(TXN) - ndx); - ntxns++ - } - txn[ntxns] = TXN; -} - -/^\[/{ - if (printme == 1) { - printf("%s\n", rec); - printme = 0 - } - rec = ""; - - for (i = 0; i <= ntxns; i++) - if (txn[i] == $5) { - rec = $0 - printme = 1 - } -} -/^ /{ - rec = sprintf("%s\n%s", rec, $0); -} - -END { - if (printme == 1) - printf("%s\n", rec); -} diff --git a/storage/bdb/db_recover/db_recover.c b/storage/bdb/db_recover/db_recover.c deleted file mode 100644 index 5d9b5886b81..00000000000 --- a/storage/bdb/db_recover/db_recover.c +++ /dev/null @@ -1,303 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_recover.c,v 12.5 2005/06/16 20:21:29 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef lint -static const char copyright[] = - "Copyright (c) 1996-2005\nSleepycat Software Inc. All rights reserved.\n"; -#endif - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#if TIME_WITH_SYS_TIME -#include <sys/time.h> -#include <time.h> -#else -#if HAVE_SYS_TIME_H -#include <sys/time.h> -#else -#include <time.h> -#endif -#endif - -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#endif - -#include "db_int.h" - -int main __P((int, char *[])); -int read_timestamp __P((char *, time_t *)); -int usage __P((void)); -int version_check __P((void)); - -const char *progname; - -int -main(argc, argv) - int argc; - char *argv[]; -{ - extern char *optarg; - extern int optind; - DB_ENV *dbenv; - time_t timestamp; - u_int32_t flags; - int ch, exitval, fatal_recover, ret, retain_env, verbose; - char *home, *passwd; - - if ((progname = strrchr(argv[0], '/')) == NULL) - progname = argv[0]; - else - ++progname; - - if ((ret = version_check()) != 0) - return (ret); - - home = passwd = NULL; - timestamp = 0; - exitval = fatal_recover = retain_env = verbose = 0; - while ((ch = getopt(argc, argv, "ceh:P:t:Vv")) != EOF) - switch (ch) { - case 'c': - fatal_recover = 1; - break; - case 'e': - retain_env = 1; - break; - case 'h': - home = optarg; - break; - case 'P': - passwd = strdup(optarg); - memset(optarg, 0, strlen(optarg)); - if (passwd == NULL) { - fprintf(stderr, "%s: strdup: %s\n", - progname, strerror(errno)); - return (EXIT_FAILURE); - } - break; - case 't': - if ((ret = read_timestamp(optarg, ×tamp)) != 0) - return (ret); - break; - case 'V': - printf("%s\n", db_version(NULL, NULL, NULL)); - return (EXIT_SUCCESS); - case 'v': - verbose = 1; - break; - case '?': - default: - return (usage()); - } - argc -= optind; - argv += optind; - - if (argc != 0) - return (usage()); - - /* Handle possible interruptions. */ - __db_util_siginit(); - - /* - * Create an environment object and initialize it for error - * reporting. - */ - if ((ret = db_env_create(&dbenv, 0)) != 0) { - fprintf(stderr, - "%s: db_env_create: %s\n", progname, db_strerror(ret)); - return (EXIT_FAILURE); - } - dbenv->set_errfile(dbenv, stderr); - dbenv->set_errpfx(dbenv, progname); - if (verbose) - (void)dbenv->set_verbose(dbenv, DB_VERB_RECOVERY, 1); - if (timestamp && - (ret = dbenv->set_tx_timestamp(dbenv, ×tamp)) != 0) { - dbenv->err(dbenv, ret, "DB_ENV->set_timestamp"); - goto shutdown; - } - - if (passwd != NULL && (ret = dbenv->set_encrypt(dbenv, - passwd, DB_ENCRYPT_AES)) != 0) { - dbenv->err(dbenv, ret, "set_passwd"); - goto shutdown; - } - - /* - * Initialize the environment -- we don't actually do anything - * else, that all that's needed to run recovery. - * - * Note that unless the caller specified the -e option, we use a - * private environment, as we're about to create a region, and we - * don't want to to leave it around. If we leave the region around, - * the application that should create it will simply join it instead, - * and will then be running with incorrectly sized (and probably - * terribly small) caches. Applications that use -e should almost - * certainly use DB_CONFIG files in the directory. - */ - flags = 0; - LF_SET(DB_CREATE | DB_INIT_LOG | - DB_INIT_MPOOL | DB_INIT_TXN | DB_USE_ENVIRON); - LF_SET(fatal_recover ? DB_RECOVER_FATAL : DB_RECOVER); - LF_SET(retain_env ? DB_INIT_LOCK : DB_PRIVATE); - if ((ret = dbenv->open(dbenv, home, flags, 0)) != 0) { - dbenv->err(dbenv, ret, "DB_ENV->open"); - goto shutdown; - } - - if (0) { -shutdown: exitval = 1; - } - - /* Clean up the environment. */ - if ((ret = dbenv->close(dbenv, 0)) != 0) { - exitval = 1; - fprintf(stderr, - "%s: dbenv->close: %s\n", progname, db_strerror(ret)); - } - if (passwd != NULL) - free(passwd); - - /* Resend any caught signal. */ - __db_util_sigresend(); - - return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE); -} - -#define ATOI2(ar) ((ar)[0] - '0') * 10 + ((ar)[1] - '0'); (ar) += 2; - -/* - * read_timestamp -- - * Convert a time argument to Epoch seconds. - * - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -int -read_timestamp(arg, timep) - char *arg; - time_t *timep; -{ - struct tm *t; - time_t now; - int yearset; - char *p; - /* Start with the current time. */ - (void)time(&now); - if ((t = localtime(&now)) == NULL) { - fprintf(stderr, - "%s: localtime: %s\n", progname, strerror(errno)); - return (EXIT_FAILURE); - } - /* [[CC]YY]MMDDhhmm[.SS] */ - if ((p = strchr(arg, '.')) == NULL) - t->tm_sec = 0; /* Seconds defaults to 0. */ - else { - if (strlen(p + 1) != 2) - goto terr; - *p++ = '\0'; - t->tm_sec = ATOI2(p); - } - - yearset = 0; - switch (strlen(arg)) { - case 12: /* CCYYMMDDhhmm */ - t->tm_year = ATOI2(arg); - t->tm_year *= 100; - yearset = 1; - /* FALLTHROUGH */ - case 10: /* YYMMDDhhmm */ - if (yearset) { - yearset = ATOI2(arg); - t->tm_year += yearset; - } else { - yearset = ATOI2(arg); - if (yearset < 69) - t->tm_year = yearset + 2000; - else - t->tm_year = yearset + 1900; - } - t->tm_year -= 1900; /* Convert to UNIX time. */ - /* FALLTHROUGH */ - case 8: /* MMDDhhmm */ - t->tm_mon = ATOI2(arg); - --t->tm_mon; /* Convert from 01-12 to 00-11 */ - t->tm_mday = ATOI2(arg); - t->tm_hour = ATOI2(arg); - t->tm_min = ATOI2(arg); - break; - default: - goto terr; - } - - t->tm_isdst = -1; /* Figure out DST. */ - - *timep = mktime(t); - if (*timep == -1) { -terr: fprintf(stderr, - "%s: out of range or illegal time specification: [[CC]YY]MMDDhhmm[.SS]", - progname); - return (EXIT_FAILURE); - } - return (0); -} - -int -usage() -{ - (void)fprintf(stderr, "usage: %s %s\n", progname, - "[-ceVv] [-h home] [-P password] [-t [[CC]YY]MMDDhhmm[.SS]]"); - return (EXIT_FAILURE); -} - -int -version_check() -{ - int v_major, v_minor, v_patch; - - /* Make sure we're loaded with the right version of the DB library. */ - (void)db_version(&v_major, &v_minor, &v_patch); - if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) { - fprintf(stderr, - "%s: version %d.%d doesn't match library version %d.%d\n", - progname, DB_VERSION_MAJOR, DB_VERSION_MINOR, - v_major, v_minor); - return (EXIT_FAILURE); - } - return (0); -} diff --git a/storage/bdb/db_stat/db_stat.c b/storage/bdb/db_stat/db_stat.c deleted file mode 100644 index 9b6fff88f6c..00000000000 --- a/storage/bdb/db_stat/db_stat.c +++ /dev/null @@ -1,506 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_stat.c,v 12.6 2005/10/05 22:27:27 ubell Exp $ - */ - -#include "db_config.h" - -#ifndef lint -static const char copyright[] = - "Copyright (c) 1996-2005\nSleepycat Software Inc. All rights reserved.\n"; -#endif - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#if TIME_WITH_SYS_TIME -#include <sys/time.h> -#include <time.h> -#else -#if HAVE_SYS_TIME_H -#include <sys/time.h> -#else -#include <time.h> -#endif -#endif - -#include <ctype.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" - -typedef enum { T_NOTSET, - T_DB, T_ENV, T_LOCK, T_LOG, T_MPOOL, T_MUTEX, T_REP, T_TXN } test_t; - -int db_init __P((DB_ENV *, char *, test_t, u_int32_t, int *)); -int main __P((int, char *[])); -int usage __P((void)); -int version_check __P((void)); - -const char *progname; - -int -main(argc, argv) - int argc; - char *argv[]; -{ - extern char *optarg; - extern int optind; - DB_ENV *dbenv; - DB_BTREE_STAT *sp; - DB *alt_dbp, *dbp; - test_t ttype; - u_int32_t cache, env_flags, fast, flags; - int ch, exitval; - int nflag, private, resize, ret; - char *db, *home, *p, *passwd, *subdb; - - if ((progname = strrchr(argv[0], '/')) == NULL) - progname = argv[0]; - else - ++progname; - - if ((ret = version_check()) != 0) - return (ret); - - dbenv = NULL; - dbp = NULL; - ttype = T_NOTSET; - cache = MEGABYTE; - exitval = fast = flags = nflag = private = 0; - db = home = passwd = subdb = NULL; - env_flags = 0; - - while ((ch = getopt(argc, - argv, "C:cd:Eefh:L:lM:mNP:R:rs:tVxX:Z")) != EOF) - switch (ch) { - case 'C': case 'c': - if (ttype != T_NOTSET && ttype != T_LOCK) - goto argcombo; - ttype = T_LOCK; - if (ch != 'c') - for (p = optarg; *p; ++p) - switch (*p) { - case 'A': - LF_SET(DB_STAT_ALL); - break; - case 'c': - LF_SET(DB_STAT_LOCK_CONF); - break; - case 'l': - LF_SET(DB_STAT_LOCK_LOCKERS); - break; - case 'm': /* Backward compatible. */ - break; - case 'o': - LF_SET(DB_STAT_LOCK_OBJECTS); - break; - case 'p': - LF_SET(DB_STAT_LOCK_PARAMS); - break; - default: - return (usage()); - } - break; - case 'd': - if (ttype != T_NOTSET && ttype != T_DB) - goto argcombo; - ttype = T_DB; - db = optarg; - break; - case 'E': case 'e': - if (ttype != T_NOTSET && ttype != T_ENV) - goto argcombo; - ttype = T_ENV; - LF_SET(DB_STAT_SUBSYSTEM); - if (ch == 'E') - LF_SET(DB_STAT_ALL); - break; - case 'f': - fast = DB_FAST_STAT; - break; - case 'h': - home = optarg; - break; - case 'L': case 'l': - if (ttype != T_NOTSET && ttype != T_LOG) - goto argcombo; - ttype = T_LOG; - if (ch != 'l') - for (p = optarg; *p; ++p) - switch (*p) { - case 'A': - LF_SET(DB_STAT_ALL); - break; - default: - return (usage()); - } - break; - case 'M': case 'm': - if (ttype != T_NOTSET && ttype != T_MPOOL) - goto argcombo; - ttype = T_MPOOL; - if (ch != 'm') - for (p = optarg; *p; ++p) - switch (*p) { - case 'A': - LF_SET(DB_STAT_ALL); - break; - case 'h': - LF_SET(DB_STAT_MEMP_HASH); - break; - case 'm': /* Backward compatible. */ - break; - default: - return (usage()); - } - break; - case 'N': - nflag = 1; - break; - case 'P': - passwd = strdup(optarg); - memset(optarg, 0, strlen(optarg)); - if (passwd == NULL) { - fprintf(stderr, "%s: strdup: %s\n", - progname, strerror(errno)); - return (EXIT_FAILURE); - } - break; - case 'R': case 'r': - if (ttype != T_NOTSET && ttype != T_REP) - goto argcombo; - ttype = T_REP; - if (ch != 'r') - for (p = optarg; *p; ++p) - switch (*p) { - case 'A': - LF_SET(DB_STAT_ALL); - break; - default: - return (usage()); - } - break; - case 's': - if (ttype != T_NOTSET && ttype != T_DB) - goto argcombo; - ttype = T_DB; - subdb = optarg; - break; - case 't': - if (ttype != T_NOTSET) { -argcombo: fprintf(stderr, - "%s: illegal option combination\n", - progname); - return (EXIT_FAILURE); - } - ttype = T_TXN; - break; - case 'V': - printf("%s\n", db_version(NULL, NULL, NULL)); - return (EXIT_SUCCESS); - case 'X': case 'x': - if (ttype != T_NOTSET && ttype != T_MUTEX) - goto argcombo; - ttype = T_MUTEX; - if (ch != 'x') - for (p = optarg; *p; ++p) - switch (*p) { - case 'A': - LF_SET(DB_STAT_ALL); - break; - default: - return (usage()); - } - break; - case 'Z': - LF_SET(DB_STAT_CLEAR); - break; - case '?': - default: - return (usage()); - } - argc -= optind; - argv += optind; - - switch (ttype) { - case T_DB: - if (db == NULL) - return (usage()); - break; - case T_NOTSET: - return (usage()); - /* NOTREACHED */ - case T_ENV: - case T_LOCK: - case T_LOG: - case T_MPOOL: - case T_REP: - case T_TXN: - case T_MUTEX: - if (fast != 0) - return (usage()); - break; - } - - /* Handle possible interruptions. */ - __db_util_siginit(); - - /* - * Create an environment object and initialize it for error - * reporting. - */ -retry: if ((ret = db_env_create(&dbenv, env_flags)) != 0) { - fprintf(stderr, - "%s: db_env_create: %s\n", progname, db_strerror(ret)); - goto err; - } - - dbenv->set_errfile(dbenv, stderr); - dbenv->set_errpfx(dbenv, progname); - - if (nflag) { - if ((ret = dbenv->set_flags(dbenv, DB_NOLOCKING, 1)) != 0) { - dbenv->err(dbenv, ret, "set_flags: DB_NOLOCKING"); - goto err; - } - if ((ret = dbenv->set_flags(dbenv, DB_NOPANIC, 1)) != 0) { - dbenv->err(dbenv, ret, "set_flags: DB_NOPANIC"); - goto err; - } - } - - if (passwd != NULL && - (ret = dbenv->set_encrypt(dbenv, passwd, DB_ENCRYPT_AES)) != 0) { - dbenv->err(dbenv, ret, "set_passwd"); - goto err; - } - - /* Initialize the environment. */ - if (db_init(dbenv, home, ttype, cache, &private) != 0) - goto err; - - switch (ttype) { - case T_DB: - if (flags != 0) - return (usage()); - - /* Create the DB object and open the file. */ - if ((ret = db_create(&dbp, dbenv, 0)) != 0) { - dbenv->err(dbenv, ret, "db_create"); - goto err; - } - - if ((ret = dbp->open(dbp, - NULL, db, subdb, DB_UNKNOWN, DB_RDONLY, 0)) != 0) { - dbenv->err(dbenv, ret, "DB->open: %s", db); - goto err; - } - - /* Check if cache is too small for this DB's pagesize. */ - if (private) { - if ((ret = __db_util_cache(dbp, &cache, &resize)) != 0) - goto err; - if (resize) { - (void)dbp->close(dbp, DB_NOSYNC); - dbp = NULL; - - (void)dbenv->close(dbenv, 0); - dbenv = NULL; - goto retry; - } - } - - /* - * See if we can open this db read/write to update counts. - * If its a master-db then we cannot. So check to see, - * if its btree then it might be. - */ - if (subdb == NULL && dbp->type == DB_BTREE && - (ret = dbp->stat(dbp, NULL, &sp, DB_FAST_STAT)) != 0) { - dbenv->err(dbenv, ret, "DB->stat"); - goto err; - } - - if (subdb != NULL || - dbp->type != DB_BTREE || - (sp->bt_metaflags & BTM_SUBDB) == 0) { - if ((ret = db_create(&alt_dbp, dbenv, 0)) != 0) { - dbenv->err(dbenv, ret, "db_create"); - goto err; - } - if ((ret = dbp->open(alt_dbp, NULL, - db, subdb, DB_UNKNOWN, DB_RDONLY, 0)) != 0) { - if (subdb == NULL) - dbenv->err(dbenv, - ret, "DB->open: %s", db); - else - dbenv->err(dbenv, - ret, "DB->open: %s:%s", db, subdb); - (void)alt_dbp->close(alt_dbp, DB_NOSYNC); - goto err; - } - - (void)dbp->close(dbp, DB_NOSYNC); - dbp = alt_dbp; - } - - if (dbp->stat_print(dbp, flags)) - goto err; - break; - case T_ENV: - if (dbenv->stat_print(dbenv, flags)) - goto err; - break; - case T_LOCK: - if (dbenv->lock_stat_print(dbenv, flags)) - goto err; - break; - case T_LOG: - if (dbenv->log_stat_print(dbenv, flags)) - goto err; - break; - case T_MPOOL: - if (dbenv->memp_stat_print(dbenv, flags)) - goto err; - break; - case T_MUTEX: - if (dbenv->mutex_stat_print(dbenv, flags)) - goto err; - break; - case T_REP: - if (dbenv->rep_stat_print(dbenv, flags)) - goto err; - break; - case T_TXN: - if (dbenv->txn_stat_print(dbenv, flags)) - goto err; - break; - case T_NOTSET: - dbenv->errx(dbenv, "Unknown statistics flag"); - goto err; - } - - if (0) { -err: exitval = 1; - } - if (dbp != NULL && (ret = dbp->close(dbp, DB_NOSYNC)) != 0) { - exitval = 1; - dbenv->err(dbenv, ret, "close"); - } - if (dbenv != NULL && (ret = dbenv->close(dbenv, 0)) != 0) { - exitval = 1; - fprintf(stderr, - "%s: dbenv->close: %s\n", progname, db_strerror(ret)); - } - - if (passwd != NULL) - free(passwd); - - /* Resend any caught signal. */ - __db_util_sigresend(); - - return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE); -} - -/* - * db_init -- - * Initialize the environment. - */ -int -db_init(dbenv, home, ttype, cache, is_private) - DB_ENV *dbenv; - char *home; - test_t ttype; - u_int32_t cache; - int *is_private; -{ - u_int32_t oflags; - int ret; - - /* - * If our environment open fails, and we're trying to look at a - * shared region, it's a hard failure. - * - * We will probably just drop core if the environment we join does - * not include a memory pool. This is probably acceptable; trying - * to use an existing environment that does not contain a memory - * pool to look at a database can be safely construed as operator - * error, I think. - */ - *is_private = 0; - if ((ret = dbenv->open(dbenv, home, DB_USE_ENVIRON, 0)) == 0) - return (0); - if (ret == DB_VERSION_MISMATCH) - goto err; - if (ttype != T_DB && ttype != T_LOG) { - dbenv->err(dbenv, ret, "DB_ENV->open%s%s", - home == NULL ? "" : ": ", home == NULL ? "" : home); - return (1); - } - - /* - * We're looking at a database or set of log files and no environment - * exists. Create one, but make it private so no files are actually - * created. Declare a reasonably large cache so that we don't fail - * when reporting statistics on large databases. - * - * An environment is required to look at databases because we may be - * trying to look at databases in directories other than the current - * one. - */ - if ((ret = dbenv->set_cachesize(dbenv, 0, cache, 1)) != 0) { - dbenv->err(dbenv, ret, "set_cachesize"); - return (1); - } - *is_private = 1; - oflags = DB_CREATE | DB_PRIVATE | DB_USE_ENVIRON; - if (ttype == T_DB) - oflags |= DB_INIT_MPOOL; - if (ttype == T_LOG) - oflags |= DB_INIT_LOG; - if (ttype == T_REP) - oflags |= DB_INIT_REP; - if ((ret = dbenv->open(dbenv, home, oflags, 0)) == 0) - return (0); - - /* An environment is required. */ -err: dbenv->err(dbenv, ret, "DB_ENV->open"); - return (1); -} - -int -usage() -{ - fprintf(stderr, "usage: %s %s\n", progname, - "-d file [-fN] [-h home] [-P password] [-s database]"); - fprintf(stderr, "usage: %s %s\n\t%s\n", progname, - "[-cEelmNrtVxZ] [-C Aclop]", - "[-h home] [-L A] [-M A] [-P password] [-R A] [-X A]"); - return (EXIT_FAILURE); -} - -int -version_check() -{ - int v_major, v_minor, v_patch; - - /* Make sure we're loaded with the right version of the DB library. */ - (void)db_version(&v_major, &v_minor, &v_patch); - if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) { - fprintf(stderr, - "%s: version %d.%d doesn't match library version %d.%d\n", - progname, DB_VERSION_MAJOR, DB_VERSION_MINOR, - v_major, v_minor); - return (EXIT_FAILURE); - } - return (0); -} diff --git a/storage/bdb/db_stat/dd.sh b/storage/bdb/db_stat/dd.sh deleted file mode 100644 index 4e00c289a5a..00000000000 --- a/storage/bdb/db_stat/dd.sh +++ /dev/null @@ -1,79 +0,0 @@ -#! /bin/sh -# $Id: dd.sh,v 12.0 2004/11/17 03:43:25 bostic Exp $ -# -# Display environment's deadlocks based on "db_stat -Co" output. - -t1=__a -t2=__b - -trap 'rm -f $t1 $t2; exit 0' 0 1 2 3 13 15 - -if [ $# -ne 1 ]; then - echo "Usage: dd.sh [db_stat -Co output]" - exit 1 -fi - -if `egrep '\<WAIT\>.*\<page\>' $1 > /dev/null`; then - n=`egrep '\<WAIT\>.*\<page\>' $1 | wc -l | awk '{print $1}'` - echo "dd.sh: $1: $n page locks in a WAIT state." -else - echo "dd.sh: $1: No page locks in a WAIT state found." - exit 1 -fi - -# Print out list of node wait states, and output cycles in the graph. -egrep '\<WAIT\>.*\<page\>' $1 | awk '{print $1 " " $7}' | -while read l p; do - p=`egrep "\<HELD\>.*\<page\>[ ][ ]*$p$" $1 | awk '{print $1}'` - echo "$l $p" -done | tsort > /dev/null 2>$t1 - -# Display the locks in a single cycle. -display_one() { - if [ -s $1 ]; then - echo "Deadlock #$c ============" - c=`expr $c + 1` - cat $1 | sort -n +6 - :> $1 - fi -} - -# Display the locks in all of the cycles. -# -# Requires tsort output some text before each list of nodes in the cycle, -# and the actual node displayed on the line be the second (white-space) -# separated item on the line. For example: -# -# tsort: cycle in data -# tsort: 8000177f -# tsort: 80001792 -# tsort: 80001774 -# tsort: cycle in data -# tsort: 80001776 -# tsort: 80001793 -# tsort: cycle in data -# tsort: 8000176a -# tsort: 8000178a -# -# XXX -# Currently, db_stat doesn't display the implicit wait relationship between -# parent and child transactions, where the parent won't release a lock until -# the child commits/aborts. This means the deadlock where parent holds a -# lock, thread A waits on parent, child waits on thread A won't be shown. -if [ -s $t1 ]; then - c=1 - :>$t2 - while read a b; do - case $b in - [0-9]*) - egrep $b $1 >> $t2;; - *) - display_one $t2;; - esac - done < $t1 - display_one $t2 -else - echo 'No deadlocks found.' -fi - -exit 0 diff --git a/storage/bdb/db_upgrade/db_upgrade.c b/storage/bdb/db_upgrade/db_upgrade.c deleted file mode 100644 index 724034dc73c..00000000000 --- a/storage/bdb/db_upgrade/db_upgrade.c +++ /dev/null @@ -1,207 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_upgrade.c,v 12.5 2005/09/09 12:38:36 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef lint -static const char copyright[] = - "Copyright (c) 1996-2005\nSleepycat Software Inc. All rights reserved.\n"; -#endif - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#endif - -#include "db_int.h" - -int main __P((int, char *[])); -int usage __P((void)); -int version_check __P((void)); - -const char *progname; - -int -main(argc, argv) - int argc; - char *argv[]; -{ - extern char *optarg; - extern int optind; - DB *dbp; - DB_ENV *dbenv; - u_int32_t flags; - int ch, exitval, nflag, ret, t_ret, verbose; - char *home, *passwd; - - if ((progname = strrchr(argv[0], '/')) == NULL) - progname = argv[0]; - else - ++progname; - - if ((ret = version_check()) != 0) - return (ret); - - dbenv = NULL; - flags = nflag = verbose = 0; - exitval = 0; - home = passwd = NULL; - while ((ch = getopt(argc, argv, "h:NP:sVv")) != EOF) - switch (ch) { - case 'h': - home = optarg; - break; - case 'N': - nflag = 1; - break; - case 'P': - passwd = strdup(optarg); - memset(optarg, 0, strlen(optarg)); - if (passwd == NULL) { - fprintf(stderr, "%s: strdup: %s\n", - progname, strerror(errno)); - return (EXIT_FAILURE); - } - break; - case 's': - LF_SET(DB_DUPSORT); - break; - case 'V': - printf("%s\n", db_version(NULL, NULL, NULL)); - return (EXIT_SUCCESS); - case 'v': - verbose = 1; - break; - case '?': - default: - return (usage()); - } - argc -= optind; - argv += optind; - - if (argc <= 0) - return (usage()); - - /* Handle possible interruptions. */ - __db_util_siginit(); - - /* - * Create an environment object and initialize it for error - * reporting. - */ - if ((ret = db_env_create(&dbenv, 0)) != 0) { - fprintf(stderr, "%s: db_env_create: %s\n", - progname, db_strerror(ret)); - goto shutdown; - } - - dbenv->set_errfile(dbenv, stderr); - dbenv->set_errpfx(dbenv, progname); - - if (nflag) { - if ((ret = dbenv->set_flags(dbenv, DB_NOLOCKING, 1)) != 0) { - dbenv->err(dbenv, ret, "set_flags: DB_NOLOCKING"); - goto shutdown; - } - if ((ret = dbenv->set_flags(dbenv, DB_NOPANIC, 1)) != 0) { - dbenv->err(dbenv, ret, "set_flags: DB_NOPANIC"); - goto shutdown; - } - } - - if (passwd != NULL && (ret = dbenv->set_encrypt(dbenv, - passwd, DB_ENCRYPT_AES)) != 0) { - dbenv->err(dbenv, ret, "set_passwd"); - goto shutdown; - } - - /* - * If attaching to a pre-existing environment fails, create a - * private one and try again. - */ - if ((ret = dbenv->open(dbenv, home, DB_USE_ENVIRON, 0)) != 0 && - (ret == DB_VERSION_MISMATCH || - (ret = dbenv->open(dbenv, home, - DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE | DB_USE_ENVIRON, - 0)) != 0)) { - dbenv->err(dbenv, ret, "DB_ENV->open"); - goto shutdown; - } - - for (; !__db_util_interrupted() && argv[0] != NULL; ++argv) { - if ((ret = db_create(&dbp, dbenv, 0)) != 0) { - fprintf(stderr, - "%s: db_create: %s\n", progname, db_strerror(ret)); - goto shutdown; - } - dbp->set_errfile(dbp, stderr); - dbp->set_errpfx(dbp, progname); - if ((ret = dbp->upgrade(dbp, argv[0], flags)) != 0) - dbp->err(dbp, ret, "DB->upgrade: %s", argv[0]); - if ((t_ret = dbp->close(dbp, 0)) != 0 && ret == 0) { - dbenv->err(dbenv, ret, "DB->close: %s", argv[0]); - ret = t_ret; - } - if (ret != 0) - goto shutdown; - /* - * People get concerned if they don't see a success message. - * If verbose is set, give them one. - */ - if (verbose) - printf("%s: %s upgraded successfully\n", - progname, argv[0]); - } - - if (0) { -shutdown: exitval = 1; - } - if (dbenv != NULL && (ret = dbenv->close(dbenv, 0)) != 0) { - exitval = 1; - fprintf(stderr, - "%s: dbenv->close: %s\n", progname, db_strerror(ret)); - } - - if (passwd != NULL) - free(passwd); - - /* Resend any caught signal. */ - __db_util_sigresend(); - - return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE); -} - -int -usage() -{ - fprintf(stderr, "usage: %s %s\n", progname, - "[-NsVv] [-h home] [-P password] db_file ..."); - return (EXIT_FAILURE); -} - -int -version_check() -{ - int v_major, v_minor, v_patch; - - /* Make sure we're loaded with the right version of the DB library. */ - (void)db_version(&v_major, &v_minor, &v_patch); - if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) { - fprintf(stderr, - "%s: version %d.%d doesn't match library version %d.%d\n", - progname, DB_VERSION_MAJOR, DB_VERSION_MINOR, - v_major, v_minor); - return (EXIT_FAILURE); - } - return (0); -} diff --git a/storage/bdb/db_verify/db_verify.c b/storage/bdb/db_verify/db_verify.c deleted file mode 100644 index d2763429239..00000000000 --- a/storage/bdb/db_verify/db_verify.c +++ /dev/null @@ -1,259 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_verify.c,v 12.3 2005/06/16 20:21:37 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef lint -static const char copyright[] = - "Copyright (c) 1996-2005\nSleepycat Software Inc. All rights reserved.\n"; -#endif - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#endif - -#include "db_int.h" - -int main __P((int, char *[])); -int usage __P((void)); -int version_check __P((void)); - -const char *progname; - -int -main(argc, argv) - int argc; - char *argv[]; -{ - extern char *optarg; - extern int optind; - DB *dbp, *dbp1; - DB_ENV *dbenv; - u_int32_t flags, cache; - int ch, exitval, nflag, private; - int quiet, resize, ret; - char *home, *passwd; - - if ((progname = strrchr(argv[0], '/')) == NULL) - progname = argv[0]; - else - ++progname; - - if ((ret = version_check()) != 0) - return (ret); - - dbenv = NULL; - dbp = NULL; - cache = MEGABYTE; - exitval = nflag = quiet = 0; - flags = 0; - home = passwd = NULL; - while ((ch = getopt(argc, argv, "h:NoP:quV")) != EOF) - switch (ch) { - case 'h': - home = optarg; - break; - case 'N': - nflag = 1; - break; - case 'P': - passwd = strdup(optarg); - memset(optarg, 0, strlen(optarg)); - if (passwd == NULL) { - fprintf(stderr, "%s: strdup: %s\n", - progname, strerror(errno)); - return (EXIT_FAILURE); - } - break; - case 'o': - LF_SET(DB_NOORDERCHK); - break; - case 'q': - quiet = 1; - break; - case 'u': /* Undocumented. */ - LF_SET(DB_UNREF); - break; - case 'V': - printf("%s\n", db_version(NULL, NULL, NULL)); - return (EXIT_SUCCESS); - case '?': - default: - return (usage()); - } - argc -= optind; - argv += optind; - - if (argc <= 0) - return (usage()); - - /* Handle possible interruptions. */ - __db_util_siginit(); - - /* - * Create an environment object and initialize it for error - * reporting. - */ -retry: if ((ret = db_env_create(&dbenv, 0)) != 0) { - fprintf(stderr, - "%s: db_env_create: %s\n", progname, db_strerror(ret)); - goto shutdown; - } - - if (!quiet) { - dbenv->set_errfile(dbenv, stderr); - dbenv->set_errpfx(dbenv, progname); - } - - if (nflag) { - if ((ret = dbenv->set_flags(dbenv, DB_NOLOCKING, 1)) != 0) { - dbenv->err(dbenv, ret, "set_flags: DB_NOLOCKING"); - goto shutdown; - } - if ((ret = dbenv->set_flags(dbenv, DB_NOPANIC, 1)) != 0) { - dbenv->err(dbenv, ret, "set_flags: DB_NOPANIC"); - goto shutdown; - } - } - - if (passwd != NULL && - (ret = dbenv->set_encrypt(dbenv, passwd, DB_ENCRYPT_AES)) != 0) { - dbenv->err(dbenv, ret, "set_passwd"); - goto shutdown; - } - /* - * Attach to an mpool if it exists, but if that fails, attach to a - * private region. In the latter case, declare a reasonably large - * cache so that we don't fail when verifying large databases. - */ - private = 0; - if ((ret = - dbenv->open(dbenv, home, DB_INIT_MPOOL | DB_USE_ENVIRON, 0)) != 0) { - if (ret != DB_VERSION_MISMATCH) { - if ((ret = - dbenv->set_cachesize(dbenv, 0, cache, 1)) != 0) { - dbenv->err(dbenv, ret, "set_cachesize"); - goto shutdown; - } - private = 1; - ret = dbenv->open(dbenv, home, DB_CREATE | - DB_INIT_MPOOL | DB_PRIVATE | DB_USE_ENVIRON, 0); - } - if (ret != 0) { - dbenv->err(dbenv, ret, "DB_ENV->open"); - goto shutdown; - } - } - - for (; !__db_util_interrupted() && argv[0] != NULL; ++argv) { - if ((ret = db_create(&dbp, dbenv, 0)) != 0) { - dbenv->err(dbenv, ret, "%s: db_create", progname); - goto shutdown; - } - - /* - * We create a 2nd dbp to this database to get its pagesize - * because the dbp we're using for verify cannot be opened. - * - * If the database is corrupted, we may not be able to open - * it, of course. In that case, just continue, using the - * cache size we have. - */ - if (private) { - if ((ret = db_create(&dbp1, dbenv, 0)) != 0) { - dbenv->err( - dbenv, ret, "%s: db_create", progname); - goto shutdown; - } - - ret = dbp1->open(dbp1, - NULL, argv[0], NULL, DB_UNKNOWN, DB_RDONLY, 0); - - /* - * If we get here, we can check the cache/page. - * !!! - * If we have to retry with an env with a larger - * cache, we jump out of this loop. However, we - * will still be working on the same argv when we - * get back into the for-loop. - */ - if (ret == 0) { - if (__db_util_cache( - dbp1, &cache, &resize) == 0 && resize) { - (void)dbp1->close(dbp1, 0); - (void)dbp->close(dbp, 0); - dbp = NULL; - - (void)dbenv->close(dbenv, 0); - dbenv = NULL; - goto retry; - } - } - (void)dbp1->close(dbp1, 0); - } - - /* The verify method is a destructor. */ - ret = dbp->verify(dbp, argv[0], NULL, NULL, flags); - dbp = NULL; - if (ret != 0) - goto shutdown; - } - - if (0) { -shutdown: exitval = 1; - } - - if (dbp != NULL && (ret = dbp->close(dbp, 0)) != 0) { - exitval = 1; - dbenv->err(dbenv, ret, "close"); - } - if (dbenv != NULL && (ret = dbenv->close(dbenv, 0)) != 0) { - exitval = 1; - fprintf(stderr, - "%s: dbenv->close: %s\n", progname, db_strerror(ret)); - } - - if (passwd != NULL) - free(passwd); - - /* Resend any caught signal. */ - __db_util_sigresend(); - - return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE); -} - -int -usage() -{ - fprintf(stderr, "usage: %s %s\n", progname, - "[-NoqV] [-h home] [-P password] db_file ..."); - return (EXIT_FAILURE); -} - -int -version_check() -{ - int v_major, v_minor, v_patch; - - /* Make sure we're loaded with the right version of the DB library. */ - (void)db_version(&v_major, &v_minor, &v_patch); - if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) { - fprintf(stderr, - "%s: version %d.%d doesn't match library version %d.%d\n", - progname, DB_VERSION_MAJOR, DB_VERSION_MINOR, - v_major, v_minor); - return (EXIT_FAILURE); - } - return (0); -} diff --git a/storage/bdb/dbinc/btree.h b/storage/bdb/dbinc/btree.h deleted file mode 100644 index b5fe4f2bbca..00000000000 --- a/storage/bdb/dbinc/btree.h +++ /dev/null @@ -1,333 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994, 1995, 1996 - * Keith Bostic. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994, 1995 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Mike Olson. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: btree.h,v 12.8 2005/08/08 14:52:30 bostic Exp $ - */ -#ifndef _DB_BTREE_H_ -#define _DB_BTREE_H_ - -/* Forward structure declarations. */ -struct __btree; typedef struct __btree BTREE; -struct __cursor; typedef struct __cursor BTREE_CURSOR; -struct __epg; typedef struct __epg EPG; -struct __recno; typedef struct __recno RECNO; - -#define DEFMINKEYPAGE (2) - -/* - * A recno order of 0 indicates that we don't have an order, not that we've - * an order less than 1. - */ -#define INVALID_ORDER 0 - -#define ISINTERNAL(p) (TYPE(p) == P_IBTREE || TYPE(p) == P_IRECNO) -#define ISLEAF(p) (TYPE(p) == P_LBTREE || \ - TYPE(p) == P_LRECNO || TYPE(p) == P_LDUP) - -/* Flags for __bam_cadjust_log(). */ -#define CAD_UPDATEROOT 0x01 /* Root page count was updated. */ - -/* Flags for __bam_split_log(). */ -#define SPL_NRECS 0x01 /* Split tree has record count. */ - -/* Flags for __bam_iitem(). */ -#define BI_DELETED 0x01 /* Key/data pair only placeholder. */ - -/* Flags for __bam_stkrel(). */ -#define STK_CLRDBC 0x01 /* Clear dbc->page reference. */ -#define STK_NOLOCK 0x02 /* Don't retain locks. */ -#define STK_PGONLY 0x04 - -/* Flags for __ram_ca(). These get logged, so make the values explicit. */ -typedef enum { - CA_DELETE = 0, /* Delete the current record. */ - CA_IAFTER = 1, /* Insert before the current record. */ - CA_IBEFORE = 2, /* Insert after the current record. */ - CA_ICURRENT = 3 /* Overwrite the current record. */ -} ca_recno_arg; - -/* - * Flags for __bam_search() and __bam_rsearch(). - * - * Note, internal page searches must find the largest record less than key in - * the tree so that descents work. Leaf page searches must find the smallest - * record greater than key so that the returned index is the record's correct - * position for insertion. - * - * The flags parameter to the search routines describes three aspects of the - * search: the type of locking required (including if we're locking a pair of - * pages), the item to return in the presence of duplicates and whether or not - * to return deleted entries. To simplify both the mnemonic representation - * and the code that checks for various cases, we construct a set of bitmasks. - */ -#define S_READ 0x00001 /* Read locks. */ -#define S_WRITE 0x00002 /* Write locks. */ - -#define S_APPEND 0x00040 /* Append to the tree. */ -#define S_DELNO 0x00080 /* Don't return deleted items. */ -#define S_DUPFIRST 0x00100 /* Return first duplicate. */ -#define S_DUPLAST 0x00200 /* Return last duplicate. */ -#define S_EXACT 0x00400 /* Exact items only. */ -#define S_PARENT 0x00800 /* Lock page pair. */ -#define S_STACK 0x01000 /* Need a complete stack. */ -#define S_PAST_EOF 0x02000 /* If doing insert search (or keyfirst - * or keylast operations), or a split - * on behalf of an insert, it's okay to - * return an entry one past end-of-page. - */ -#define S_STK_ONLY 0x04000 /* Just return info in the stack */ -#define S_MAX 0x08000 /* Get the right most key */ -#define S_MIN 0x10000 /* Get the left most key */ -#define S_NEXT 0x20000 /* Get the page after this key */ -#define S_DEL 0x40000 /* Get the tree to delete this key. */ -#define S_START 0x80000 /* Level to start stack. */ - -#define S_DELETE (S_WRITE | S_DUPFIRST | S_DELNO | S_EXACT | S_STACK) -#define S_FIND (S_READ | S_DUPFIRST | S_DELNO) -#define S_FIND_WR (S_WRITE | S_DUPFIRST | S_DELNO) -#define S_INSERT (S_WRITE | S_DUPLAST | S_PAST_EOF | S_STACK) -#define S_KEYFIRST (S_WRITE | S_DUPFIRST | S_PAST_EOF | S_STACK) -#define S_KEYLAST (S_WRITE | S_DUPLAST | S_PAST_EOF | S_STACK) -#define S_WRPAIR (S_WRITE | S_DUPLAST | S_PAST_EOF | S_PARENT) - -/* - * Various routines pass around page references. A page reference is - * a pointer to the page, and the indx indicates an item on the page. - * Each page reference may include a lock. - */ -struct __epg { - PAGE *page; /* The page. */ - db_indx_t indx; /* The index on the page. */ - db_indx_t entries; /* The number of entries on page */ - DB_LOCK lock; /* The page's lock. */ - db_lockmode_t lock_mode; /* The lock mode. */ -}; - -/* - * We maintain a stack of the pages that we're locking in the tree. Grow - * the stack as necessary. - * - * XXX - * Temporary fix for #3243 -- clear the page and lock from the stack entry. - * The correct fix is to never release a stack that doesn't hold items. - */ -#define BT_STK_CLR(c) do { \ - (c)->csp = (c)->sp; \ - (c)->csp->page = NULL; \ - LOCK_INIT((c)->csp->lock); \ -} while (0) - -#define BT_STK_ENTER(dbenv, c, pagep, page_indx, l, mode, ret) do { \ - if ((ret = ((c)->csp == (c)->esp ? \ - __bam_stkgrow(dbenv, c) : 0)) == 0) { \ - (c)->csp->page = pagep; \ - (c)->csp->indx = (page_indx); \ - (c)->csp->entries = NUM_ENT(pagep); \ - (c)->csp->lock = l; \ - (c)->csp->lock_mode = mode; \ - } \ -} while (0) - -#define BT_STK_PUSH(dbenv, c, pagep, page_indx, lock, mode, ret) do { \ - BT_STK_ENTER(dbenv, c, pagep, page_indx, lock, mode, ret); \ - ++(c)->csp; \ -} while (0) - -#define BT_STK_NUM(dbenv, c, pagep, page_indx, ret) do { \ - if ((ret = ((c)->csp == \ - (c)->esp ? __bam_stkgrow(dbenv, c) : 0)) == 0) { \ - (c)->csp->page = NULL; \ - (c)->csp->indx = (page_indx); \ - (c)->csp->entries = NUM_ENT(pagep); \ - LOCK_INIT((c)->csp->lock); \ - (c)->csp->lock_mode = DB_LOCK_NG; \ - } \ -} while (0) - -#define BT_STK_NUMPUSH(dbenv, c, pagep, page_indx, ret) do { \ - BT_STK_NUM(dbenv, cp, pagep, page_indx, ret); \ - ++(c)->csp; \ -} while (0) - -#define BT_STK_POP(c) \ - ((c)->csp == (c)->sp ? NULL : --(c)->csp) - -/* Btree/Recno cursor. */ -struct __cursor { - /* struct __dbc_internal */ - __DBC_INTERNAL - - /* btree private part */ - EPG *sp; /* Stack pointer. */ - EPG *csp; /* Current stack entry. */ - EPG *esp; /* End stack pointer. */ - EPG stack[5]; - - db_indx_t ovflsize; /* Maximum key/data on-page size. */ - - db_recno_t recno; /* Current record number. */ - u_int32_t order; /* Relative order among deleted curs. */ - - /* - * Btree: - * We set a flag in the cursor structure if the underlying object has - * been deleted. It's not strictly necessary, we could get the same - * information by looking at the page itself, but this method doesn't - * require us to retrieve the page on cursor delete. - * - * Recno: - * When renumbering recno databases during deletes, cursors referencing - * "deleted" records end up positioned between two records, and so must - * be specially adjusted on the next operation. - */ -#define C_DELETED 0x0001 /* Record was deleted. */ - /* - * There are three tree types that require maintaining record numbers. - * Recno AM trees, Btree AM trees for which the DB_RECNUM flag was set, - * and Btree off-page duplicate trees. - */ -#define C_RECNUM 0x0002 /* Tree requires record counts. */ - /* - * Recno trees have immutable record numbers by default, but optionally - * support mutable record numbers. Off-page duplicate Recno trees have - * mutable record numbers. All Btrees with record numbers (including - * off-page duplicate trees) are mutable by design, no flag is needed. - */ -#define C_RENUMBER 0x0004 /* Tree records are mutable. */ - u_int32_t flags; -}; - -/* - * Threshhold value, as a function of bt_minkey, of the number of - * bytes a key/data pair can use before being placed on an overflow - * page. Assume every item requires the maximum alignment for - * padding, out of sheer paranoia. - */ -#define B_MINKEY_TO_OVFLSIZE(dbp, minkey, pgsize) \ - ((u_int16_t)(((pgsize) - P_OVERHEAD(dbp)) / ((minkey) * P_INDX) -\ - (BKEYDATA_PSIZE(0) + DB_ALIGN(1, sizeof(int32_t))))) - -/* - * The maximum space that a single item can ever take up on one page. - * Used by __bam_split to determine whether a split is still necessary. - */ -#define B_MAX(a,b) (((a) > (b)) ? (a) : (b)) -#define B_MAXSIZEONPAGE(ovflsize) \ - (B_MAX(BOVERFLOW_PSIZE, BKEYDATA_PSIZE(ovflsize))) - -/* - * The in-memory, per-tree btree/recno data structure. - */ -struct __btree { /* Btree access method. */ - /* - * !!! - * These fields are write-once (when the structure is created) and - * so are ignored as far as multi-threading is concerned. - */ - db_pgno_t bt_meta; /* Database meta-data page. */ - db_pgno_t bt_root; /* Database root page. */ - - u_int32_t bt_minkey; /* Minimum keys per page. */ - - /* Btree comparison function. */ - int (*bt_compare) __P((DB *, const DBT *, const DBT *)); - /* Btree prefix function. */ - size_t (*bt_prefix) __P((DB *, const DBT *, const DBT *)); - - /* Recno access method. */ - int re_pad; /* Fixed-length padding byte. */ - int re_delim; /* Variable-length delimiting byte. */ - u_int32_t re_len; /* Length for fixed-length records. */ - char *re_source; /* Source file name. */ - - /* - * !!! - * The bt_lpgno field is NOT protected by any mutex, and for this - * reason must be advisory only, so, while it is read/written by - * multiple threads, DB is completely indifferent to the quality - * of its information. - */ - db_pgno_t bt_lpgno; /* Last insert location. */ - DB_LSN bt_llsn; /* Last insert LSN. */ - - /* - * !!! - * The re_modified field is NOT protected by any mutex, and for this - * reason cannot be anything more complicated than a zero/non-zero - * value. The actual writing of the backing source file cannot be - * threaded, so clearing the flag isn't a problem. - */ - int re_modified; /* If the tree was modified. */ - - /* - * !!! - * These fields are ignored as far as multi-threading is concerned. - * There are no transaction semantics associated with backing files, - * nor is there any thread protection. - */ - FILE *re_fp; /* Source file handle. */ - int re_eof; /* Backing source file EOF reached. */ - db_recno_t re_last; /* Last record number read. */ - -}; - -/* - * Modes for the __bam_curadj recovery records (btree_curadj). - * These appear in log records, so we wire the values and - * do not leave it up to the compiler. - */ -typedef enum { - DB_CA_DI = 1, - DB_CA_DUP = 2, - DB_CA_RSPLIT = 3, - DB_CA_SPLIT = 4 -} db_ca_mode; - -/* - * Flags for __bam_pinsert. - */ -#define BPI_SPACEONLY 0x01 /* Only check for space to update. */ -#define BPI_NORECNUM 0x02 /* Not update the recnum on the left. */ - -#include "dbinc_auto/btree_auto.h" -#include "dbinc_auto/btree_ext.h" -#include "dbinc/db_am.h" -#endif /* !_DB_BTREE_H_ */ diff --git a/storage/bdb/dbinc/crypto.h b/storage/bdb/dbinc/crypto.h deleted file mode 100644 index 419c16ffe2c..00000000000 --- a/storage/bdb/dbinc/crypto.h +++ /dev/null @@ -1,78 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: crypto.h,v 12.2 2005/07/20 16:51:03 bostic Exp $ - */ - -#ifndef _DB_CRYPTO_H_ -#define _DB_CRYPTO_H_ - -/* - * !!! - * These are the internal representations of the algorithm flags. - * They are used in both the DB_CIPHER structure and the CIPHER - * structure so we can tell if users specified both passwd and alg - * correctly. - * - * CIPHER_ANY is used when an app joins an existing env but doesn't - * know the algorithm originally used. This is only valid in the - * DB_CIPHER structure until we open and can set the alg. - */ -/* - * We store the algorithm in an 8-bit field on the meta-page. So we - * use a numeric value, not bit fields. - * now we are limited to 8 algorithms before we cannot use bits and - * need numeric values. That should be plenty. It is okay for the - * CIPHER_ANY flag to go beyond that since that is never stored on disk. - */ - -/* - * This structure is per-process, not in shared memory. - */ -struct __db_cipher { - u_int (*adj_size) __P((size_t)); - int (*close) __P((DB_ENV *, void *)); - int (*decrypt) __P((DB_ENV *, void *, void *, u_int8_t *, size_t)); - int (*encrypt) __P((DB_ENV *, void *, void *, u_int8_t *, size_t)); - int (*init) __P((DB_ENV *, DB_CIPHER *)); - - u_int8_t mac_key[DB_MAC_KEY]; /* MAC key. */ - void *data; /* Algorithm-specific information */ - -#define CIPHER_AES 1 /* AES algorithm */ - u_int8_t alg; /* Algorithm used - See above */ - u_int8_t spare[3]; /* Spares */ - -#define CIPHER_ANY 0x00000001 /* Only for DB_CIPHER */ - u_int32_t flags; /* Other flags */ -}; - -#ifdef HAVE_CRYPTO - -#include "crypto/rijndael/rijndael-api-fst.h" - -/* - * Shared ciphering structure - * No mutex needed because all information is read-only after creation. - */ -typedef struct __cipher { - roff_t passwd; /* Offset to shared passwd */ - size_t passwd_len; /* Length of passwd */ - u_int32_t flags; /* Algorithm used - see above */ -} CIPHER; - -#define DB_AES_KEYLEN 128 /* AES key length */ -#define DB_AES_CHUNK 16 /* AES byte unit size */ - -typedef struct __aes_cipher { - keyInstance decrypt_ki; /* Decryption key instance */ - keyInstance encrypt_ki; /* Encryption key instance */ - u_int32_t flags; /* AES-specific flags */ -} AES_CIPHER; - -#include "dbinc_auto/crypto_ext.h" -#endif /* HAVE_CRYPTO */ -#endif /* !_DB_CRYPTO_H_ */ diff --git a/storage/bdb/dbinc/cxx_common.h b/storage/bdb/dbinc/cxx_common.h deleted file mode 100644 index e5cb3a9aef4..00000000000 --- a/storage/bdb/dbinc/cxx_common.h +++ /dev/null @@ -1,45 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2002 - * Sleepycat Software. All rights reserved. - * - * $Id: cxx_common.h,v 11.2 2002/01/11 15:52:23 bostic Exp $ - */ - -#ifndef _CXX_COMMON_H_ -#define _CXX_COMMON_H_ - -// -// Common definitions used by all of Berkeley DB's C++ include files. -// - -//////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////// -// -// Mechanisms for declaring classes -// - -// -// Every class defined in this file has an _exported next to the class name. -// This is needed for WinTel machines so that the class methods can -// be exported or imported in a DLL as appropriate. Users of the DLL -// use the define DB_USE_DLL. When the DLL is built, DB_CREATE_DLL -// must be defined. -// -#if defined(_MSC_VER) - -# if defined(DB_CREATE_DLL) -# define _exported __declspec(dllexport) // creator of dll -# elif defined(DB_USE_DLL) -# define _exported __declspec(dllimport) // user of dll -# else -# define _exported // static lib creator or user -# endif - -#else /* _MSC_VER */ - -# define _exported - -#endif /* _MSC_VER */ -#endif /* !_CXX_COMMON_H_ */ diff --git a/storage/bdb/dbinc/cxx_except.h b/storage/bdb/dbinc/cxx_except.h deleted file mode 100644 index f9bf4f859f8..00000000000 --- a/storage/bdb/dbinc/cxx_except.h +++ /dev/null @@ -1,141 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2002 - * Sleepycat Software. All rights reserved. - * - * $Id: cxx_except.h,v 11.5 2002/08/01 23:32:34 mjc Exp $ - */ - -#ifndef _CXX_EXCEPT_H_ -#define _CXX_EXCEPT_H_ - -#include "cxx_common.h" - -//////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////// -// -// Forward declarations -// - -class DbDeadlockException; // forward -class DbException; // forward -class DbLockNotGrantedException; // forward -class DbLock; // forward -class DbMemoryException; // forward -class DbRunRecoveryException; // forward -class Dbt; // forward - -//////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////// -// -// Exception classes -// - -// Almost any error in the DB library throws a DbException. -// Every exception should be considered an abnormality -// (e.g. bug, misuse of DB, file system error). -// -// NOTE: We would like to inherit from class exception and -// let it handle what(), but there are -// MSVC++ problems when <exception> is included. -// -class _exported DbException -{ -public: - virtual ~DbException(); - DbException(int err); - DbException(const char *description); - DbException(const char *prefix, int err); - DbException(const char *prefix1, const char *prefix2, int err); - int get_errno() const; - virtual const char *what() const; - - DbException(const DbException &); - DbException &operator = (const DbException &); - -private: - char *what_; - int err_; // errno -}; - -// -// A specific sort of exception that occurs when -// an operation is aborted to resolve a deadlock. -// -class _exported DbDeadlockException : public DbException -{ -public: - virtual ~DbDeadlockException(); - DbDeadlockException(const char *description); - - DbDeadlockException(const DbDeadlockException &); - DbDeadlockException &operator = (const DbDeadlockException &); -}; - -// -// A specific sort of exception that occurs when -// a lock is not granted, e.g. by lock_get or lock_vec. -// Note that the Dbt is only live as long as the Dbt used -// in the offending call. -// -class _exported DbLockNotGrantedException : public DbException -{ -public: - virtual ~DbLockNotGrantedException(); - DbLockNotGrantedException(const char *prefix, db_lockop_t op, - db_lockmode_t mode, const Dbt *obj, const DbLock lock, int index); - DbLockNotGrantedException(const DbLockNotGrantedException &); - DbLockNotGrantedException &operator = - (const DbLockNotGrantedException &); - - db_lockop_t get_op() const; - db_lockmode_t get_mode() const; - const Dbt* get_obj() const; - DbLock *get_lock() const; - int get_index() const; - -private: - db_lockop_t op_; - db_lockmode_t mode_; - const Dbt *obj_; - DbLock *lock_; - int index_; -}; - -// -// A specific sort of exception that occurs when -// user declared memory is insufficient in a Dbt. -// -class _exported DbMemoryException : public DbException -{ -public: - virtual ~DbMemoryException(); - DbMemoryException(Dbt *dbt); - DbMemoryException(const char *description); - DbMemoryException(const char *prefix, Dbt *dbt); - DbMemoryException(const char *prefix1, const char *prefix2, Dbt *dbt); - Dbt *get_dbt() const; - - DbMemoryException(const DbMemoryException &); - DbMemoryException &operator = (const DbMemoryException &); - -private: - Dbt *dbt_; -}; - -// -// A specific sort of exception that occurs when -// recovery is required before continuing DB activity. -// -class _exported DbRunRecoveryException : public DbException -{ -public: - virtual ~DbRunRecoveryException(); - DbRunRecoveryException(const char *description); - - DbRunRecoveryException(const DbRunRecoveryException &); - DbRunRecoveryException &operator = (const DbRunRecoveryException &); -}; - -#endif /* !_CXX_EXCEPT_H_ */ diff --git a/storage/bdb/dbinc/cxx_int.h b/storage/bdb/dbinc/cxx_int.h deleted file mode 100644 index 7686058e85f..00000000000 --- a/storage/bdb/dbinc/cxx_int.h +++ /dev/null @@ -1,77 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: cxx_int.h,v 12.1 2005/06/16 20:21:43 bostic Exp $ - */ - -#ifndef _CXX_INT_H_ -#define _CXX_INT_H_ - -// private data structures known to the implementation only - -// -// Using FooImp classes will allow the implementation to change in the -// future without any modification to user code or even to header files -// that the user includes. FooImp * is just like void * except that it -// provides a little extra protection, since you cannot randomly assign -// any old pointer to a FooImp* as you can with void *. Currently, a -// pointer to such an opaque class is always just a pointer to the -// appropriate underlying implementation struct. These are converted -// back and forth using the various overloaded wrap()/unwrap() methods. -// This is essentially a use of the "Bridge" Design Pattern. -// -// WRAPPED_CLASS implements the appropriate wrap() and unwrap() methods -// for a wrapper class that has an underlying pointer representation. -// -#define WRAPPED_CLASS(_WRAPPER_CLASS, _IMP_CLASS, _WRAPPED_TYPE) \ - \ - class _IMP_CLASS {}; \ - \ - inline _WRAPPED_TYPE *unwrap(_WRAPPER_CLASS *val) \ - { \ - if (!val) return (0); \ - return (val->get_##_WRAPPED_TYPE()); \ - } \ - \ - inline const _WRAPPED_TYPE *unwrapConst(const _WRAPPER_CLASS *val) \ - { \ - if (!val) return (0); \ - return (val->get_const_##_WRAPPED_TYPE()); \ - } - -WRAPPED_CLASS(Db, DbImp, DB) -WRAPPED_CLASS(DbEnv, DbEnvImp, DB_ENV) -WRAPPED_CLASS(DbMpoolFile, DbMpoolFileImp, DB_MPOOLFILE) -WRAPPED_CLASS(DbSequence, DbSequenceImp, DB_SEQUENCE) -WRAPPED_CLASS(DbTxn, DbTxnImp, DB_TXN) - -// A tristate integer value used by the DB_ERROR macro below. -// We chose not to make this an enumerated type so it can -// be kept private, even though methods that return the -// tristate int can be declared in db_cxx.h . -// -#define ON_ERROR_THROW 1 -#define ON_ERROR_RETURN 0 -#define ON_ERROR_UNKNOWN (-1) - -// Macros that handle detected errors, in case we want to -// change the default behavior. The 'policy' is one of -// the tristate values given above. If UNKNOWN is specified, -// the behavior is taken from the last initialized DbEnv. -// -#define DB_ERROR(env, caller, ecode, policy) \ - DbEnv::runtime_error(env, caller, ecode, policy) - -#define DB_ERROR_DBT(env, caller, dbt, policy) \ - DbEnv::runtime_error_dbt(env, caller, dbt, policy) - -#define DB_OVERFLOWED_DBT(dbt) \ - (F_ISSET(dbt, DB_DBT_USERMEM) && dbt->size > dbt->ulen) - -/* values for Db::flags_ */ -#define DB_CXX_PRIVATE_ENV 0x00000001 - -#endif /* !_CXX_INT_H_ */ diff --git a/storage/bdb/dbinc/db.in b/storage/bdb/dbinc/db.in deleted file mode 100644 index 741b2e259b6..00000000000 --- a/storage/bdb/dbinc/db.in +++ /dev/null @@ -1,2369 +0,0 @@ -/* - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db.in,v 12.67 2005/11/10 21:10:24 bostic Exp $ - * - * db.h include file layout: - * General. - * Database Environment. - * Locking subsystem. - * Logging subsystem. - * Shared buffer cache (mpool) subsystem. - * Transaction subsystem. - * Access methods. - * Access method cursors. - * Dbm/Ndbm, Hsearch historic interfaces. - */ - -#ifndef _DB_H_ -#define _DB_H_ - -#ifndef __NO_SYSTEM_INCLUDES -#include <sys/types.h> -@inttypes_h_decl@ -@stdint_h_decl@ -@stddef_h_decl@ -#include <stdio.h> -@unistd_h_decl@ -@thread_h_decl@ -#endif - -#if defined(__cplusplus) -extern "C" { -#endif - -@DB_CONST@ -@DB_PROTO1@ -@DB_PROTO2@ - -/* - * Berkeley DB version information. - */ -#define DB_VERSION_MAJOR @DB_VERSION_MAJOR@ -#define DB_VERSION_MINOR @DB_VERSION_MINOR@ -#define DB_VERSION_PATCH @DB_VERSION_PATCH@ -#define DB_VERSION_STRING @DB_VERSION_STRING@ - -/* - * !!! - * Berkeley DB uses specifically sized types. If they're not provided by - * the system, typedef them here. - * - * We protect them against multiple inclusion using __BIT_TYPES_DEFINED__, - * as does BIND and Kerberos, since we don't know for sure what #include - * files the user is using. - * - * !!! - * We also provide the standard u_int, u_long etc., if they're not provided - * by the system. - */ -#ifndef __BIT_TYPES_DEFINED__ -#define __BIT_TYPES_DEFINED__ -@u_int8_decl@ -@int16_decl@ -@u_int16_decl@ -@int32_decl@ -@u_int32_decl@ -@int64_decl@ -@u_int64_decl@ -#endif - -@u_char_decl@ -@u_short_decl@ -@u_int_decl@ -@u_long_decl@ -@ssize_t_decl@ - -/* - * uintmax_t -- - * Largest unsigned type, used to align structures in memory. We don't store - * floating point types in structures, so integral types should be sufficient - * (and we don't have to worry about systems that store floats in other than - * power-of-2 numbers of bytes). Additionally this fixes compilers that rewrite - * structure assignments and ANSI C memcpy calls to be in-line instructions - * that happen to require alignment. - * - * uintptr_t -- - * Unsigned type that's the same size as a pointer. There are places where - * DB modifies pointers by discarding the bottom bits to guarantee alignment. - * We can't use uintmax_t, it may be larger than the pointer, and compilers - * get upset about that. So far we haven't run on any machine where there's - * no unsigned type the same size as a pointer -- here's hoping. - */ -@uintmax_t_decl@ -@uintptr_t_decl@ - -/* - * Sequences are only available on machines with 64-bit integral types. - */ -@db_seq_decl@ - -/* Thread and process identification. */ -@db_threadid_t_decl@ -@pid_t_decl@ - -/* Basic types that are exported or quasi-exported. */ -typedef u_int32_t db_pgno_t; /* Page number type. */ -typedef u_int16_t db_indx_t; /* Page offset type. */ -#define DB_MAX_PAGES 0xffffffff /* >= # of pages in a file */ - -typedef u_int32_t db_recno_t; /* Record number type. */ -#define DB_MAX_RECORDS 0xffffffff /* >= # of records in a tree */ - -typedef u_int32_t db_timeout_t; /* Type of a timeout. */ - -/* - * Region offsets are the difference between a pointer in a region and the - * region's base address. With private environments, both addresses are the - * result of calling malloc, and we can't assume anything about what malloc - * will return, so region offsets have to be able to hold differences between - * arbitrary pointers. - */ -typedef uintptr_t roff_t; - -/* - * Forward structure declarations, so we can declare pointers and - * applications can get type checking. - */ -struct __db; typedef struct __db DB; -struct __db_bt_stat; typedef struct __db_bt_stat DB_BTREE_STAT; -struct __db_cipher; typedef struct __db_cipher DB_CIPHER; -struct __db_compact; typedef struct __db_compact DB_COMPACT; -struct __db_dbt; typedef struct __db_dbt DBT; -struct __db_env; typedef struct __db_env DB_ENV; -struct __db_h_stat; typedef struct __db_h_stat DB_HASH_STAT; -struct __db_ilock; typedef struct __db_ilock DB_LOCK_ILOCK; -struct __db_lock_stat; typedef struct __db_lock_stat DB_LOCK_STAT; -struct __db_lock_u; typedef struct __db_lock_u DB_LOCK; -struct __db_lockreq; typedef struct __db_lockreq DB_LOCKREQ; -struct __db_log_cursor; typedef struct __db_log_cursor DB_LOGC; -struct __db_log_stat; typedef struct __db_log_stat DB_LOG_STAT; -struct __db_lsn; typedef struct __db_lsn DB_LSN; -struct __db_mpool; typedef struct __db_mpool DB_MPOOL; -struct __db_mpool_fstat;typedef struct __db_mpool_fstat DB_MPOOL_FSTAT; -struct __db_mpool_stat; typedef struct __db_mpool_stat DB_MPOOL_STAT; -struct __db_mpoolfile; typedef struct __db_mpoolfile DB_MPOOLFILE; -struct __db_mutex_stat; typedef struct __db_mutex_stat DB_MUTEX_STAT; -struct __db_preplist; typedef struct __db_preplist DB_PREPLIST; -struct __db_qam_stat; typedef struct __db_qam_stat DB_QUEUE_STAT; -struct __db_rep; typedef struct __db_rep DB_REP; -struct __db_rep_stat; typedef struct __db_rep_stat DB_REP_STAT; -struct __db_seq_record; typedef struct __db_seq_record DB_SEQ_RECORD; -struct __db_seq_stat; typedef struct __db_seq_stat DB_SEQUENCE_STAT; -struct __db_sequence; typedef struct __db_sequence DB_SEQUENCE; -struct __db_txn; typedef struct __db_txn DB_TXN; -struct __db_txn_active; typedef struct __db_txn_active DB_TXN_ACTIVE; -struct __db_txn_stat; typedef struct __db_txn_stat DB_TXN_STAT; -struct __db_txnmgr; typedef struct __db_txnmgr DB_TXNMGR; -struct __dbc; typedef struct __dbc DBC; -struct __dbc_internal; typedef struct __dbc_internal DBC_INTERNAL; -struct __fh_t; typedef struct __fh_t DB_FH; -struct __fname; typedef struct __fname FNAME; -struct __key_range; typedef struct __key_range DB_KEY_RANGE; -struct __mpoolfile; typedef struct __mpoolfile MPOOLFILE; - -/* Key/data structure -- a Data-Base Thang. */ -struct __db_dbt { - void *data; /* Key/data */ - u_int32_t size; /* key/data length */ - - u_int32_t ulen; /* RO: length of user buffer. */ - u_int32_t dlen; /* RO: get/put record length. */ - u_int32_t doff; /* RO: get/put record offset. */ - - void *app_private; /* Application-private handle. */ - -#define DB_DBT_APPMALLOC 0x001 /* Callback allocated memory. */ -#define DB_DBT_ISSET 0x002 /* Lower level calls set value. */ -#define DB_DBT_MALLOC 0x004 /* Return in malloc'd memory. */ -#define DB_DBT_PARTIAL 0x008 /* Partial put/get. */ -#define DB_DBT_REALLOC 0x010 /* Return in realloc'd memory. */ -#define DB_DBT_USERMEM 0x020 /* Return in user's memory. */ -#define DB_DBT_DUPOK 0x040 /* Insert if duplicate. */ - u_int32_t flags; -}; - -/* - * Common flags -- - * Interfaces which use any of these common flags should never have - * interface specific flags in this range. - */ -#define DB_CREATE 0x0000001 /* Create file as necessary. */ -#define DB_DURABLE_UNKNOWN 0x0000002 /* Durability on open (internal). */ -#define DB_FORCE 0x0000004 /* Force (anything). */ -#define DB_NOMMAP 0x0000008 /* Don't mmap underlying file. */ -#define DB_RDONLY 0x0000010 /* Read-only (O_RDONLY). */ -#define DB_RECOVER 0x0000020 /* Run normal recovery. */ -#define DB_THREAD 0x0000040 /* Applications are threaded. */ -#define DB_TRUNCATE 0x0000080 /* Discard existing DB (O_TRUNC). */ -#define DB_TXN_NOSYNC 0x0000100 /* Do not sync log on commit. */ -#define DB_TXN_NOT_DURABLE 0x0000200 /* Do not log changes. */ -#define DB_TXN_WRITE_NOSYNC 0x0000400 /* Write the log but don't sync. */ -#define DB_USE_ENVIRON 0x0000800 /* Use the environment. */ -#define DB_USE_ENVIRON_ROOT 0x0001000 /* Use the environment if root. */ - -/* - * Common flags -- - * Interfaces which use any of these common flags should never have - * interface specific flags in this range. - * - * DB_AUTO_COMMIT: - * DB_ENV->set_flags, DB->open - * (Note: until the 4.3 release, legal to DB->associate, DB->del, - * DB->put, DB->remove, DB->rename and DB->truncate, and others.) - * DB_READ_COMMITTED: - * DB->cursor, DB->get, DB->join, DBcursor->c_get, DB_ENV->txn_begin - * DB_READ_UNCOMMITTED: - * DB->cursor, DB->get, DB->join, DB->open, DBcursor->c_get, - * DB_ENV->txn_begin - * - * !!! - * The DB_READ_COMMITTED and DB_READ_UNCOMMITTED bit masks can't be changed - * without also changing the masks for the flags that can be OR'd into DB - * access method and cursor operation values. - */ -#define DB_AUTO_COMMIT 0x01000000/* Implied transaction. */ - -#define DB_READ_COMMITTED 0x02000000/* Degree 2 isolation. */ -#define DB_DEGREE_2 0x02000000/* Historic name. */ - -#define DB_READ_UNCOMMITTED 0x04000000/* Degree 1 isolation. */ -#define DB_DIRTY_READ 0x04000000/* Historic name. */ - -/* - * Flags common to db_env_create and db_create. - */ -#define DB_CXX_NO_EXCEPTIONS 0x0000001 /* C++: return error values. */ - -/* - * Flags private to db_env_create. - * Shared flags up to 0x0000001 */ -#define DB_RPCCLIENT 0x0000002 /* An RPC client environment. */ - -/* - * Flags private to db_create. - * Shared flags up to 0x0000001 */ -#define DB_XA_CREATE 0x0000002 /* Open in an XA environment. */ - -/* - * Flags private to DB_ENV->open. - * Shared flags up to 0x0001000 */ -#define DB_INIT_CDB 0x0002000 /* Concurrent Access Methods. */ -#define DB_INIT_LOCK 0x0004000 /* Initialize locking. */ -#define DB_INIT_LOG 0x0008000 /* Initialize logging. */ -#define DB_INIT_MPOOL 0x0010000 /* Initialize mpool. */ -#define DB_INIT_REP 0x0020000 /* Initialize replication. */ -#define DB_INIT_TXN 0x0040000 /* Initialize transactions. */ -#define DB_LOCKDOWN 0x0080000 /* Lock memory into physical core. */ -#define DB_PRIVATE 0x0100000 /* DB_ENV is process local. */ -#define DB_RECOVER_FATAL 0x0200000 /* Run catastrophic recovery. */ -#define DB_REGISTER 0x0400000 /* Multi-process registry. */ -#define DB_SYSTEM_MEM 0x0800000 /* Use system-backed memory. */ - -#define DB_JOINENV 0x0 /* Compatibility. */ - -/* - * Flags private to DB->open. - * Shared flags up to 0x0001000 */ -#define DB_EXCL 0x0002000 /* Exclusive open (O_EXCL). */ -#define DB_FCNTL_LOCKING 0x0004000 /* UNDOC: fcntl(2) locking. */ -#define DB_NO_AUTO_COMMIT 0x0008000 /* Override env-wide AUTOCOMMIT. */ -#define DB_RDWRMASTER 0x0010000 /* UNDOC: allow subdb master open R/W */ -#define DB_WRITEOPEN 0x0020000 /* UNDOC: open with write lock. */ - -/* - * Flags private to DB->associate. - * Shared flags up to 0x0001000 */ -#define DB_IMMUTABLE_KEY 0x0002000 /* Secondary key is immutable. */ -/* Shared flags at 0x1000000 */ - -/* - * Flags private to DB_ENV->txn_begin. - * Shared flags up to 0x0001000 */ -#define DB_TXN_NOWAIT 0x0002000 /* Do not wait for locks in this TXN. */ -#define DB_TXN_SYNC 0x0004000 /* Always sync log on commit. */ - -/* - * Flags private to DB_ENV->set_encrypt. - */ -#define DB_ENCRYPT_AES 0x0000001 /* AES, assumes SHA1 checksum */ - -/* - * Flags private to DB_ENV->set_flags. - * Shared flags up to 0x00001000 */ -#define DB_CDB_ALLDB 0x00002000/* Set CDB locking per environment. */ -#define DB_DIRECT_DB 0x00004000/* Don't buffer databases in the OS. */ -#define DB_DIRECT_LOG 0x00008000/* Don't buffer log files in the OS. */ -#define DB_DSYNC_DB 0x00010000/* Set O_DSYNC on the databases. */ -#define DB_DSYNC_LOG 0x00020000/* Set O_DSYNC on the log. */ -#define DB_LOG_AUTOREMOVE 0x00040000/* Automatically remove log files. */ -#define DB_LOG_INMEMORY 0x00080000/* Store logs in buffers in memory. */ -#define DB_NOLOCKING 0x00100000/* Set locking/mutex behavior. */ -#define DB_NOPANIC 0x00200000/* Set panic state per DB_ENV. */ -#define DB_OVERWRITE 0x00400000/* Overwrite unlinked region files. */ -#define DB_PANIC_ENVIRONMENT 0x00800000/* Set panic state per environment. */ -/* Shared flags at 0x01000000 */ -/* Shared flags at 0x02000000 */ -/* Shared flags at 0x04000000 */ -#define DB_REGION_INIT 0x08000000/* Page-fault regions on open. */ -#define DB_TIME_NOTGRANTED 0x10000000/* Return NOTGRANTED on timeout. */ -#define DB_YIELDCPU 0x20000000/* Yield the CPU (a lot). */ - -/* - * Flags private to DB->set_feedback's callback. - */ -#define DB_UPGRADE 0x0000001 /* Upgrading. */ -#define DB_VERIFY 0x0000002 /* Verifying. */ - -/* - * Flags private to DB->compact. - * Shared flags up to 0x00001000 - */ -#define DB_FREELIST_ONLY 0x00002000 /* Just sort and truncate. */ -#define DB_FREE_SPACE 0x00004000 /* Free space . */ -#define DB_COMPACT_FLAGS \ - (DB_FREELIST_ONLY | DB_FREE_SPACE) - -/* - * Flags private to DB_MPOOLFILE->open. - * Shared flags up to 0x0001000 */ -#define DB_DIRECT 0x0002000 /* Don't buffer the file in the OS. */ -#define DB_EXTENT 0x0004000 /* internal: dealing with an extent. */ -#define DB_ODDFILESIZE 0x0008000 /* Truncate file to N * pgsize. */ - -/* - * Flags private to DB->set_flags. - * Shared flags up to 0x00001000 */ -#define DB_CHKSUM 0x00002000 /* Do checksumming */ -#define DB_DUP 0x00004000 /* Btree, Hash: duplicate keys. */ -#define DB_DUPSORT 0x00008000 /* Btree, Hash: duplicate keys. */ -#define DB_ENCRYPT 0x00010000 /* Btree, Hash: duplicate keys. */ -#define DB_INORDER 0x00020000 /* Queue: strict ordering on consume */ -#define DB_RECNUM 0x00040000 /* Btree: record numbers. */ -#define DB_RENUMBER 0x00080000 /* Recno: renumber on insert/delete. */ -#define DB_REVSPLITOFF 0x00100000 /* Btree: turn off reverse splits. */ -#define DB_SNAPSHOT 0x00200000 /* Recno: snapshot the input. */ - -/* - * Flags private to the DB_ENV->stat_print, DB->stat and DB->stat_print methods. - */ -#define DB_STAT_ALL 0x0000001 /* Print: Everything. */ -#define DB_STAT_CLEAR 0x0000002 /* Clear stat after returning values. */ -#define DB_STAT_LOCK_CONF 0x0000004 /* Print: Lock conflict matrix. */ -#define DB_STAT_LOCK_LOCKERS 0x0000008 /* Print: Lockers. */ -#define DB_STAT_LOCK_OBJECTS 0x0000010 /* Print: Lock objects. */ -#define DB_STAT_LOCK_PARAMS 0x0000020 /* Print: Lock parameters. */ -#define DB_STAT_MEMP_HASH 0x0000040 /* Print: Mpool hash buckets. */ -#define DB_STAT_SUBSYSTEM 0x0000080 /* Print: Subsystems too. */ - -/* - * Flags private to DB->join. - */ -#define DB_JOIN_NOSORT 0x0000001 /* Don't try to optimize join. */ - -/* - * Flags private to DB->verify. - */ -#define DB_AGGRESSIVE 0x0000001 /* Salvage whatever could be data.*/ -#define DB_NOORDERCHK 0x0000002 /* Skip sort order/hashing check. */ -#define DB_ORDERCHKONLY 0x0000004 /* Only perform the order check. */ -#define DB_PR_PAGE 0x0000008 /* Show page contents (-da). */ -#define DB_PR_RECOVERYTEST 0x0000010 /* Recovery test (-dr). */ -#define DB_PRINTABLE 0x0000020 /* Use printable format for salvage. */ -#define DB_SALVAGE 0x0000040 /* Salvage what looks like data. */ -#define DB_UNREF 0x0000080 /* Report unreferenced pages. */ -/* - * !!! - * These must not go over 0x8000, or they will collide with the flags - * used by __bam_vrfy_subtree. - */ - -/* - * Flags private to DB->set_rep_transport's send callback. - */ -#define DB_REP_ANYWHERE 0x0000001 /* Message can be serviced anywhere. */ -#define DB_REP_NOBUFFER 0x0000002 /* Do not buffer this message. */ -#define DB_REP_PERMANENT 0x0000004 /* Important--app. may want to flush. */ -#define DB_REP_REREQUEST 0x0000008 /* This msg already been requested. */ - -/******************************************************* - * Mutexes. - *******************************************************/ -typedef u_int32_t db_mutex_t; - -/* - * Flag arguments for DbEnv.mutex_alloc and for the DB_MUTEX structure. - */ -#define DB_MUTEX_ALLOCATED 0x01 /* Mutex currently allocated. */ -#define DB_MUTEX_LOCKED 0x02 /* Mutex currently locked. */ -#define DB_MUTEX_LOGICAL_LOCK 0x04 /* Mutex backs a database lock. */ -#define DB_MUTEX_SELF_BLOCK 0x08 /* Must be able to block self. */ -#define DB_MUTEX_THREAD 0x10 /* Thread-only mutex. */ - -struct __db_mutex_stat { - /* The following fields are maintained in the region's copy. */ - u_int32_t st_mutex_align; /* Mutex alignment */ - u_int32_t st_mutex_tas_spins; /* Mutex test-and-set spins */ - u_int32_t st_mutex_cnt; /* Mutex count */ - u_int32_t st_mutex_free; /* Available mutexes */ - u_int32_t st_mutex_inuse; /* Mutexes in use */ - u_int32_t st_mutex_inuse_max; /* Maximum mutexes ever in use */ - - /* The following fields are filled-in from other places. */ - u_int32_t st_region_wait; /* Region lock granted after wait. */ - u_int32_t st_region_nowait; /* Region lock granted without wait. */ - roff_t st_regsize; /* Region size. */ -}; - -/* This is the length of the buffer passed to DB_ENV->thread_id_string() */ -#define DB_THREADID_STRLEN 128 - -/******************************************************* - * Locking. - *******************************************************/ -#define DB_LOCKVERSION 1 - -#define DB_FILE_ID_LEN 20 /* Unique file ID length. */ - -/* - * Deadlock detector modes; used in the DB_ENV structure to configure the - * locking subsystem. - */ -#define DB_LOCK_NORUN 0 -#define DB_LOCK_DEFAULT 1 /* Default policy. */ -#define DB_LOCK_EXPIRE 2 /* Only expire locks, no detection. */ -#define DB_LOCK_MAXLOCKS 3 /* Select locker with max locks. */ -#define DB_LOCK_MAXWRITE 4 /* Select locker with max writelocks. */ -#define DB_LOCK_MINLOCKS 5 /* Select locker with min locks. */ -#define DB_LOCK_MINWRITE 6 /* Select locker with min writelocks. */ -#define DB_LOCK_OLDEST 7 /* Select oldest locker. */ -#define DB_LOCK_RANDOM 8 /* Select random locker. */ -#define DB_LOCK_YOUNGEST 9 /* Select youngest locker. */ - -/* Flag values for lock_vec(), lock_get(). */ -#define DB_LOCK_ABORT 0x001 /* Internal: Lock during abort. */ -#define DB_LOCK_NOWAIT 0x002 /* Don't wait on unavailable lock. */ -#define DB_LOCK_RECORD 0x004 /* Internal: record lock. */ -#define DB_LOCK_SET_TIMEOUT 0x008 /* Internal: set lock timeout. */ -#define DB_LOCK_SWITCH 0x010 /* Internal: switch existing lock. */ -#define DB_LOCK_UPGRADE 0x020 /* Internal: upgrade existing lock. */ - -/* - * Simple R/W lock modes and for multi-granularity intention locking. - * - * !!! - * These values are NOT random, as they are used as an index into the lock - * conflicts arrays, i.e., DB_LOCK_IWRITE must be == 3, and DB_LOCK_IREAD - * must be == 4. - */ -typedef enum { - DB_LOCK_NG=0, /* Not granted. */ - DB_LOCK_READ=1, /* Shared/read. */ - DB_LOCK_WRITE=2, /* Exclusive/write. */ - DB_LOCK_WAIT=3, /* Wait for event */ - DB_LOCK_IWRITE=4, /* Intent exclusive/write. */ - DB_LOCK_IREAD=5, /* Intent to share/read. */ - DB_LOCK_IWR=6, /* Intent to read and write. */ - DB_LOCK_READ_UNCOMMITTED=7, /* Degree 1 isolation. */ - DB_LOCK_WWRITE=8 /* Was Written. */ -} db_lockmode_t; - -/* - * Request types. - */ -typedef enum { - DB_LOCK_DUMP=0, /* Display held locks. */ - DB_LOCK_GET=1, /* Get the lock. */ - DB_LOCK_GET_TIMEOUT=2, /* Get lock with a timeout. */ - DB_LOCK_INHERIT=3, /* Pass locks to parent. */ - DB_LOCK_PUT=4, /* Release the lock. */ - DB_LOCK_PUT_ALL=5, /* Release locker's locks. */ - DB_LOCK_PUT_OBJ=6, /* Release locker's locks on obj. */ - DB_LOCK_PUT_READ=7, /* Release locker's read locks. */ - DB_LOCK_TIMEOUT=8, /* Force a txn to timeout. */ - DB_LOCK_TRADE=9, /* Trade locker ids on a lock. */ - DB_LOCK_UPGRADE_WRITE=10 /* Upgrade writes for dirty reads. */ -} db_lockop_t; - -/* - * Status of a lock. - */ -typedef enum { - DB_LSTAT_ABORTED=1, /* Lock belongs to an aborted txn. */ - DB_LSTAT_EXPIRED=2, /* Lock has expired. */ - DB_LSTAT_FREE=3, /* Lock is unallocated. */ - DB_LSTAT_HELD=4, /* Lock is currently held. */ - DB_LSTAT_PENDING=5, /* Lock was waiting and has been - * promoted; waiting for the owner - * to run and upgrade it to held. */ - DB_LSTAT_WAITING=6 /* Lock is on the wait queue. */ -}db_status_t; - -/* Lock statistics structure. */ -struct __db_lock_stat { - u_int32_t st_id; /* Last allocated locker ID. */ - u_int32_t st_cur_maxid; /* Current maximum unused ID. */ - u_int32_t st_maxlocks; /* Maximum number of locks in table. */ - u_int32_t st_maxlockers; /* Maximum num of lockers in table. */ - u_int32_t st_maxobjects; /* Maximum num of objects in table. */ - int st_nmodes; /* Number of lock modes. */ - u_int32_t st_nlocks; /* Current number of locks. */ - u_int32_t st_maxnlocks; /* Maximum number of locks so far. */ - u_int32_t st_nlockers; /* Current number of lockers. */ - u_int32_t st_maxnlockers; /* Maximum number of lockers so far. */ - u_int32_t st_nobjects; /* Current number of objects. */ - u_int32_t st_maxnobjects; /* Maximum number of objects so far. */ - u_int32_t st_nrequests; /* Number of lock gets. */ - u_int32_t st_nreleases; /* Number of lock puts. */ - u_int32_t st_nupgrade; /* Number of lock upgrades. */ - u_int32_t st_ndowngrade; /* Number of lock downgrades. */ - u_int32_t st_lock_wait; /* Lock conflicts w/ subsequent wait */ - u_int32_t st_lock_nowait; /* Lock conflicts w/o subsequent wait */ - u_int32_t st_ndeadlocks; /* Number of lock deadlocks. */ - db_timeout_t st_locktimeout; /* Lock timeout. */ - u_int32_t st_nlocktimeouts; /* Number of lock timeouts. */ - db_timeout_t st_txntimeout; /* Transaction timeout. */ - u_int32_t st_ntxntimeouts; /* Number of transaction timeouts. */ - u_int32_t st_region_wait; /* Region lock granted after wait. */ - u_int32_t st_region_nowait; /* Region lock granted without wait. */ - roff_t st_regsize; /* Region size. */ -}; - -/* - * DB_LOCK_ILOCK -- - * Internal DB access method lock. - */ -struct __db_ilock { - db_pgno_t pgno; /* Page being locked. */ - u_int8_t fileid[DB_FILE_ID_LEN];/* File id. */ -#define DB_HANDLE_LOCK 1 -#define DB_RECORD_LOCK 2 -#define DB_PAGE_LOCK 3 - u_int32_t type; /* Type of lock. */ -}; - -/* - * DB_LOCK -- - * The structure is allocated by the caller and filled in during a - * lock_get request (or a lock_vec/DB_LOCK_GET). - */ -struct __db_lock_u { - roff_t off; /* Offset of the lock in the region */ - u_int32_t ndx; /* Index of the object referenced by - * this lock; used for locking. */ - u_int32_t gen; /* Generation number of this lock. */ - db_lockmode_t mode; /* mode of this lock. */ -}; - -/* Lock request structure. */ -struct __db_lockreq { - db_lockop_t op; /* Operation. */ - db_lockmode_t mode; /* Requested mode. */ - db_timeout_t timeout; /* Time to expire lock. */ - DBT *obj; /* Object being locked. */ - DB_LOCK lock; /* Lock returned. */ -}; - -/******************************************************* - * Logging. - *******************************************************/ -#define DB_LOGVERSION 11 /* Current log version. */ -#define DB_LOGOLDVER 11 /* Oldest log version supported. */ -#define DB_LOGMAGIC 0x040988 - -/* Flag values for DB_ENV->log_archive(). */ -#define DB_ARCH_ABS 0x001 /* Absolute pathnames. */ -#define DB_ARCH_DATA 0x002 /* Data files. */ -#define DB_ARCH_LOG 0x004 /* Log files. */ -#define DB_ARCH_REMOVE 0x008 /* Remove log files. */ - -/* Flag values for DB_ENV->log_put(). */ -#define DB_FLUSH 0x001 /* Flush data to disk (public). */ -#define DB_LOG_CHKPNT 0x002 /* Flush supports a checkpoint */ -#define DB_LOG_COMMIT 0x004 /* Flush supports a commit */ -#define DB_LOG_NOCOPY 0x008 /* Don't copy data */ -#define DB_LOG_NOT_DURABLE 0x010 /* Do not log; keep in memory */ -#define DB_LOG_PERM 0x020 /* Flag record with REP_PERMANENT */ -#define DB_LOG_RESEND 0x040 /* Resent log record */ -#define DB_LOG_WRNOSYNC 0x080 /* Write, don't sync log_put */ - -/* - * A DB_LSN has two parts, a fileid which identifies a specific file, and an - * offset within that file. The fileid is an unsigned 4-byte quantity that - * uniquely identifies a file within the log directory -- currently a simple - * counter inside the log. The offset is also an unsigned 4-byte value. The - * log manager guarantees the offset is never more than 4 bytes by switching - * to a new log file before the maximum length imposed by an unsigned 4-byte - * offset is reached. - */ -struct __db_lsn { - u_int32_t file; /* File ID. */ - u_int32_t offset; /* File offset. */ -}; - -/* - * Application-specified log record types start at DB_user_BEGIN, and must not - * equal or exceed DB_debug_FLAG. - * - * DB_debug_FLAG is the high-bit of the u_int32_t that specifies a log record - * type. If the flag is set, it's a log record that was logged for debugging - * purposes only, even if it reflects a database change -- the change was part - * of a non-durable transaction. - */ -#define DB_user_BEGIN 10000 -#define DB_debug_FLAG 0x80000000 - -/* - * DB_LOGC -- - * Log cursor. - */ -struct __db_log_cursor { - DB_ENV *dbenv; /* Enclosing dbenv. */ - - DB_FH *c_fhp; /* File handle. */ - DB_LSN c_lsn; /* Cursor: LSN */ - u_int32_t c_len; /* Cursor: record length */ - u_int32_t c_prev; /* Cursor: previous record's offset */ - - DBT c_dbt; /* Return DBT. */ - -#define DB_LOGC_BUF_SIZE (32 * 1024) - u_int8_t *bp; /* Allocated read buffer. */ - u_int32_t bp_size; /* Read buffer length in bytes. */ - u_int32_t bp_rlen; /* Read buffer valid data length. */ - DB_LSN bp_lsn; /* Read buffer first byte LSN. */ - - u_int32_t bp_maxrec; /* Max record length in the log file. */ - - /* DB_LOGC PUBLIC HANDLE LIST BEGIN */ - int (*close) __P((DB_LOGC *, u_int32_t)); - int (*get) __P((DB_LOGC *, DB_LSN *, DBT *, u_int32_t)); - /* DB_LOGC PUBLIC HANDLE LIST END */ - -#define DB_LOG_DISK 0x01 /* Log record came from disk. */ -#define DB_LOG_LOCKED 0x02 /* Log region already locked */ -#define DB_LOG_SILENT_ERR 0x04 /* Turn-off error messages. */ - u_int32_t flags; -}; - -/* Log statistics structure. */ -struct __db_log_stat { - u_int32_t st_magic; /* Log file magic number. */ - u_int32_t st_version; /* Log file version number. */ - int st_mode; /* Log file permissions mode. */ - u_int32_t st_lg_bsize; /* Log buffer size. */ - u_int32_t st_lg_size; /* Log file size. */ - u_int32_t st_record; /* Records entered into the log. */ - u_int32_t st_w_bytes; /* Bytes to log. */ - u_int32_t st_w_mbytes; /* Megabytes to log. */ - u_int32_t st_wc_bytes; /* Bytes to log since checkpoint. */ - u_int32_t st_wc_mbytes; /* Megabytes to log since checkpoint. */ - u_int32_t st_wcount; /* Total I/O writes to the log. */ - u_int32_t st_wcount_fill; /* Overflow writes to the log. */ - u_int32_t st_rcount; /* Total I/O reads from the log. */ - u_int32_t st_scount; /* Total syncs to the log. */ - u_int32_t st_region_wait; /* Region lock granted after wait. */ - u_int32_t st_region_nowait; /* Region lock granted without wait. */ - u_int32_t st_cur_file; /* Current log file number. */ - u_int32_t st_cur_offset; /* Current log file offset. */ - u_int32_t st_disk_file; /* Known on disk log file number. */ - u_int32_t st_disk_offset; /* Known on disk log file offset. */ - roff_t st_regsize; /* Region size. */ - u_int32_t st_maxcommitperflush; /* Max number of commits in a flush. */ - u_int32_t st_mincommitperflush; /* Min number of commits in a flush. */ -}; - -/* - * We need to record the first log record of a transaction. For user - * defined logging this macro returns the place to put that information, - * if it is need in rlsnp, otherwise it leaves it unchanged. We also - * need to track the last record of the transaction, this returns the - * place to put that info. - */ -#define DB_SET_TXN_LSNP(txn, blsnp, llsnp) \ - ((txn)->set_txn_lsnp(txn, blsnp, llsnp)) - -/******************************************************* - * Shared buffer cache (mpool). - *******************************************************/ -/* Flag values for DB_MPOOLFILE->get. */ -#define DB_MPOOL_CREATE 0x001 /* Create a page. */ -#define DB_MPOOL_LAST 0x002 /* Return the last page. */ -#define DB_MPOOL_NEW 0x004 /* Create a new page. */ -#define DB_MPOOL_FREE 0x008 /* Free page if present. */ - -/* Flag values for DB_MPOOLFILE->put, DB_MPOOLFILE->set. */ -#define DB_MPOOL_CLEAN 0x001 /* Page is not modified. */ -#define DB_MPOOL_DIRTY 0x002 /* Page is modified. */ -#define DB_MPOOL_DISCARD 0x004 /* Don't cache the page. */ - -/* Flags values for DB_MPOOLFILE->set_flags. */ -#define DB_MPOOL_NOFILE 0x001 /* Never open a backing file. */ -#define DB_MPOOL_UNLINK 0x002 /* Unlink the file on last close. */ - -/* Priority values for DB_MPOOLFILE->set_priority. */ -typedef enum { - DB_PRIORITY_VERY_LOW=1, - DB_PRIORITY_LOW=2, - DB_PRIORITY_DEFAULT=3, - DB_PRIORITY_HIGH=4, - DB_PRIORITY_VERY_HIGH=5 -} DB_CACHE_PRIORITY; - -/* Per-process DB_MPOOLFILE information. */ -struct __db_mpoolfile { - DB_FH *fhp; /* Underlying file handle. */ - - /* - * !!! - * The ref, pinref and q fields are protected by the region lock. - */ - u_int32_t ref; /* Reference count. */ - - u_int32_t pinref; /* Pinned block reference count. */ - - /* - * !!! - * Explicit representations of structures from queue.h. - * TAILQ_ENTRY(__db_mpoolfile) q; - */ - struct { - struct __db_mpoolfile *tqe_next; - struct __db_mpoolfile **tqe_prev; - } q; /* Linked list of DB_MPOOLFILE's. */ - - /* - * !!! - * The rest of the fields (with the exception of the MP_FLUSH flag) - * are not thread-protected, even when they may be modified at any - * time by the application. The reason is the DB_MPOOLFILE handle - * is single-threaded from the viewpoint of the application, and so - * the only fields needing to be thread-protected are those accessed - * by checkpoint or sync threads when using DB_MPOOLFILE structures - * to flush buffers from the cache. - */ - DB_ENV *dbenv; /* Overlying DB_ENV. */ - MPOOLFILE *mfp; /* Underlying MPOOLFILE. */ - - u_int32_t clear_len; /* Cleared length on created pages. */ - u_int8_t /* Unique file ID. */ - fileid[DB_FILE_ID_LEN]; - int ftype; /* File type. */ - int32_t lsn_offset; /* LSN offset in page. */ - u_int32_t gbytes, bytes; /* Maximum file size. */ - DBT *pgcookie; /* Byte-string passed to pgin/pgout. */ - int32_t priority; /* Cache priority. */ - - void *addr; /* Address of mmap'd region. */ - size_t len; /* Length of mmap'd region. */ - - u_int32_t config_flags; /* Flags to DB_MPOOLFILE->set_flags. */ - - /* DB_MPOOLFILE PUBLIC HANDLE LIST BEGIN */ - int (*close) __P((DB_MPOOLFILE *, u_int32_t)); - int (*get) __P((DB_MPOOLFILE *, db_pgno_t *, u_int32_t, void *)); - int (*open) __P((DB_MPOOLFILE *, const char *, u_int32_t, int, size_t)); - int (*put) __P((DB_MPOOLFILE *, void *, u_int32_t)); - int (*set) __P((DB_MPOOLFILE *, void *, u_int32_t)); - int (*get_clear_len) __P((DB_MPOOLFILE *, u_int32_t *)); - int (*set_clear_len) __P((DB_MPOOLFILE *, u_int32_t)); - int (*get_fileid) __P((DB_MPOOLFILE *, u_int8_t *)); - int (*set_fileid) __P((DB_MPOOLFILE *, u_int8_t *)); - int (*get_flags) __P((DB_MPOOLFILE *, u_int32_t *)); - int (*set_flags) __P((DB_MPOOLFILE *, u_int32_t, int)); - int (*get_ftype) __P((DB_MPOOLFILE *, int *)); - int (*set_ftype) __P((DB_MPOOLFILE *, int)); - int (*get_lsn_offset) __P((DB_MPOOLFILE *, int32_t *)); - int (*set_lsn_offset) __P((DB_MPOOLFILE *, int32_t)); - int (*get_maxsize) __P((DB_MPOOLFILE *, u_int32_t *, u_int32_t *)); - int (*set_maxsize) __P((DB_MPOOLFILE *, u_int32_t, u_int32_t)); - int (*get_pgcookie) __P((DB_MPOOLFILE *, DBT *)); - int (*set_pgcookie) __P((DB_MPOOLFILE *, DBT *)); - int (*get_priority) __P((DB_MPOOLFILE *, DB_CACHE_PRIORITY *)); - int (*set_priority) __P((DB_MPOOLFILE *, DB_CACHE_PRIORITY)); - int (*sync) __P((DB_MPOOLFILE *)); - /* DB_MPOOLFILE PUBLIC HANDLE LIST END */ - - /* - * MP_FILEID_SET, MP_OPEN_CALLED and MP_READONLY do not need to be - * thread protected because they are initialized before the file is - * linked onto the per-process lists, and never modified. - * - * MP_FLUSH is thread protected because it is potentially read/set by - * multiple threads of control. - */ -#define MP_FILEID_SET 0x001 /* Application supplied a file ID. */ -#define MP_FLUSH 0x002 /* Was opened to flush a buffer. */ -#define MP_OPEN_CALLED 0x004 /* File opened. */ -#define MP_READONLY 0x008 /* File is readonly. */ - u_int32_t flags; -}; - -/* Mpool statistics structure. */ -struct __db_mpool_stat { - u_int32_t st_gbytes; /* Total cache size: GB. */ - u_int32_t st_bytes; /* Total cache size: B. */ - u_int32_t st_ncache; /* Number of caches. */ - roff_t st_regsize; /* Region size. */ - size_t st_mmapsize; /* Maximum file size for mmap. */ - int st_maxopenfd; /* Maximum number of open fd's. */ - int st_maxwrite; /* Maximum buffers to write. */ - int st_maxwrite_sleep; /* Sleep after writing max buffers. */ - u_int32_t st_map; /* Pages from mapped files. */ - u_int32_t st_cache_hit; /* Pages found in the cache. */ - u_int32_t st_cache_miss; /* Pages not found in the cache. */ - u_int32_t st_page_create; /* Pages created in the cache. */ - u_int32_t st_page_in; /* Pages read in. */ - u_int32_t st_page_out; /* Pages written out. */ - u_int32_t st_ro_evict; /* Clean pages forced from the cache. */ - u_int32_t st_rw_evict; /* Dirty pages forced from the cache. */ - u_int32_t st_page_trickle; /* Pages written by memp_trickle. */ - u_int32_t st_pages; /* Total number of pages. */ - u_int32_t st_page_clean; /* Clean pages. */ - u_int32_t st_page_dirty; /* Dirty pages. */ - u_int32_t st_hash_buckets; /* Number of hash buckets. */ - u_int32_t st_hash_searches; /* Total hash chain searches. */ - u_int32_t st_hash_longest; /* Longest hash chain searched. */ - u_int32_t st_hash_examined; /* Total hash entries searched. */ - u_int32_t st_hash_nowait; /* Hash lock granted with nowait. */ - u_int32_t st_hash_wait; /* Hash lock granted after wait. */ - u_int32_t st_hash_max_wait; /* Max hash lock granted after wait. */ - u_int32_t st_region_nowait; /* Region lock granted with nowait. */ - u_int32_t st_region_wait; /* Region lock granted after wait. */ - u_int32_t st_alloc; /* Number of page allocations. */ - u_int32_t st_alloc_buckets; /* Buckets checked during allocation. */ - u_int32_t st_alloc_max_buckets; /* Max checked during allocation. */ - u_int32_t st_alloc_pages; /* Pages checked during allocation. */ - u_int32_t st_alloc_max_pages; /* Max checked during allocation. */ -}; - -/* Mpool file statistics structure. */ -struct __db_mpool_fstat { - char *file_name; /* File name. */ - u_int32_t st_pagesize; /* Page size. */ - u_int32_t st_map; /* Pages from mapped files. */ - u_int32_t st_cache_hit; /* Pages found in the cache. */ - u_int32_t st_cache_miss; /* Pages not found in the cache. */ - u_int32_t st_page_create; /* Pages created in the cache. */ - u_int32_t st_page_in; /* Pages read in. */ - u_int32_t st_page_out; /* Pages written out. */ -}; - -/******************************************************* - * Transactions and recovery. - *******************************************************/ -#define DB_TXNVERSION 1 - -typedef enum { - DB_TXN_ABORT=0, /* Public. */ - DB_TXN_APPLY=1, /* Public. */ - DB_TXN_BACKWARD_ALLOC=2, /* Internal. */ - DB_TXN_BACKWARD_ROLL=3, /* Public. */ - DB_TXN_FORWARD_ROLL=4, /* Public. */ - DB_TXN_OPENFILES=5, /* Internal. */ - DB_TXN_POPENFILES=6, /* Internal. */ - DB_TXN_PRINT=7 /* Public. */ -} db_recops; - -/* - * BACKWARD_ALLOC is used during the forward pass to pick up any aborted - * allocations for files that were created during the forward pass. - * The main difference between _ALLOC and _ROLL is that the entry for - * the file not exist during the rollforward pass. - */ -#define DB_UNDO(op) ((op) == DB_TXN_ABORT || \ - (op) == DB_TXN_BACKWARD_ROLL || (op) == DB_TXN_BACKWARD_ALLOC) -#define DB_REDO(op) ((op) == DB_TXN_FORWARD_ROLL || (op) == DB_TXN_APPLY) - -struct __db_txn { - DB_TXNMGR *mgrp; /* Pointer to transaction manager. */ - DB_TXN *parent; /* Pointer to transaction's parent. */ - - u_int32_t txnid; /* Unique transaction id. */ - char *name; /* Transaction name */ - - db_threadid_t tid; /* Thread id for use in MT XA. */ - void *td; /* Detail structure within region. */ - db_timeout_t lock_timeout; /* Timeout for locks for this txn. */ - db_timeout_t expire; /* Time transaction expires. */ - void *txn_list; /* Undo information for parent. */ - - /* - * !!! - * Explicit representations of structures from queue.h. - * TAILQ_ENTRY(__db_txn) links; - * TAILQ_ENTRY(__db_txn) xalinks; - */ - struct { - struct __db_txn *tqe_next; - struct __db_txn **tqe_prev; - } links; /* Links transactions off manager. */ - struct { - struct __db_txn *tqe_next; - struct __db_txn **tqe_prev; - } xalinks; /* Links active XA transactions. */ - - /* - * !!! - * Explicit representations of structures from queue.h. - * TAILQ_HEAD(__kids, __db_txn) kids; - */ - struct __kids { - struct __db_txn *tqh_first; - struct __db_txn **tqh_last; - } kids; - - /* - * !!! - * Explicit representations of structures from queue.h. - * TAILQ_HEAD(__events, __txn_event) events; - */ - struct { - struct __txn_event *tqh_first; - struct __txn_event **tqh_last; - } events; - - /* - * !!! - * Explicit representations of structures from queue.h. - * STAILQ_HEAD(__logrec, __txn_logrec) logs; - */ - struct { - struct __txn_logrec *stqh_first; - struct __txn_logrec **stqh_last; - } logs; /* Links deferred events. */ - - /* - * !!! - * Explicit representations of structures from queue.h. - * TAILQ_ENTRY(__db_txn) klinks; - */ - struct { - struct __db_txn *tqe_next; - struct __db_txn **tqe_prev; - } klinks; - - void *api_internal; /* C++ API private. */ - void *xml_internal; /* XML API private. */ - - u_int32_t cursors; /* Number of cursors open for txn */ - - /* DB_TXN PUBLIC HANDLE LIST BEGIN */ - int (*abort) __P((DB_TXN *)); - int (*commit) __P((DB_TXN *, u_int32_t)); - int (*discard) __P((DB_TXN *, u_int32_t)); - int (*get_name) __P((DB_TXN *, const char **)); - u_int32_t (*id) __P((DB_TXN *)); - int (*prepare) __P((DB_TXN *, u_int8_t *)); - int (*set_name) __P((DB_TXN *, const char *)); - int (*set_timeout) __P((DB_TXN *, db_timeout_t, u_int32_t)); - /* DB_TXN PUBLIC HANDLE LIST END */ - - /* DB_TXN PRIVATE HANDLE LIST BEGIN */ - void (*set_txn_lsnp) __P((DB_TXN *txn, DB_LSN **, DB_LSN **)); - /* DB_TXN PRIVATE HANDLE LIST END */ - -#define TXN_CHILDCOMMIT 0x001 /* Txn has committed. */ -#define TXN_COMPENSATE 0x002 /* Compensating transaction. */ -#define TXN_DEADLOCK 0x004 /* Txn has deadlocked. */ -#define TXN_LOCKTIMEOUT 0x008 /* Txn has a lock timeout. */ -#define TXN_MALLOC 0x010 /* Structure allocated by TXN system. */ -#define TXN_NOSYNC 0x020 /* Do not sync on prepare and commit. */ -#define TXN_NOWAIT 0x040 /* Do not wait on locks. */ -#define TXN_READ_COMMITTED 0x080 /* Txn has degree 2 isolation. */ -#define TXN_READ_UNCOMMITTED 0x100 /* Txn has degree 1 isolation. */ -#define TXN_RESTORED 0x200 /* Txn has been restored. */ -#define TXN_SYNC 0x400 /* Write and sync on prepare/commit. */ -#define TXN_WRITE_NOSYNC 0x800 /* Write only on prepare/commit. */ - u_int32_t flags; -}; - -#define TXN_SYNC_FLAGS (TXN_SYNC | TXN_NOSYNC | TXN_WRITE_NOSYNC) - -/* - * Structure used for two phase commit interface. Berkeley DB support for two - * phase commit is compatible with the X/Open XA interface. - * - * The XA #define XIDDATASIZE defines the size of a global transaction ID. We - * have our own version here (for name space reasons) which must have the same - * value. - */ -#define DB_XIDDATASIZE 128 -struct __db_preplist { - DB_TXN *txn; - u_int8_t gid[DB_XIDDATASIZE]; -}; - -/* Transaction statistics structure. */ -struct __db_txn_active { - u_int32_t txnid; /* Transaction ID */ - u_int32_t parentid; /* Transaction ID of parent */ - pid_t pid; /* Process owning txn ID */ - db_threadid_t tid; /* Thread owning txn ID */ - DB_LSN lsn; /* LSN when transaction began */ - u_int32_t xa_status; /* XA status */ - u_int8_t xid[DB_XIDDATASIZE]; /* XA global transaction ID */ - char name[51]; /* 50 bytes of name, nul termination */ -}; - -struct __db_txn_stat { - DB_LSN st_last_ckp; /* lsn of the last checkpoint */ - time_t st_time_ckp; /* time of last checkpoint */ - u_int32_t st_last_txnid; /* last transaction id given out */ - u_int32_t st_maxtxns; /* maximum txns possible */ - u_int32_t st_naborts; /* number of aborted transactions */ - u_int32_t st_nbegins; /* number of begun transactions */ - u_int32_t st_ncommits; /* number of committed transactions */ - u_int32_t st_nactive; /* number of active transactions */ - u_int32_t st_nrestores; /* number of restored transactions - after recovery. */ - u_int32_t st_maxnactive; /* maximum active transactions */ - DB_TXN_ACTIVE *st_txnarray; /* array of active transactions */ - u_int32_t st_region_wait; /* Region lock granted after wait. */ - u_int32_t st_region_nowait; /* Region lock granted without wait. */ - roff_t st_regsize; /* Region size. */ -}; - -/******************************************************* - * Replication. - *******************************************************/ -/* Special, out-of-band environment IDs. */ -#define DB_EID_BROADCAST -1 -#define DB_EID_INVALID -2 - -/* rep_config flag values. */ -#define DB_REP_CONF_BULK 0x0001 /* Bulk transfer. */ -#define DB_REP_CONF_DELAYCLIENT 0x0002 /* Delay client synchronization. */ -#define DB_REP_CONF_NOAUTOINIT 0x0004 /* No automatic client init. */ -#define DB_REP_CONF_NOWAIT 0x0008 /* Don't wait, return error. */ - -/* rep_start flags values. */ -#define DB_REP_CLIENT 0x001 -#define DB_REP_MASTER 0x002 - -/* Replication statistics. */ -struct __db_rep_stat { - /* !!! - * Many replication statistics fields cannot be protected by a mutex - * without an unacceptable performance penalty, since most message - * processing is done without the need to hold a region-wide lock. - * Fields whose comments end with a '+' may be updated without holding - * the replication or log mutexes (as appropriate), and thus may be - * off somewhat (or, on unreasonable architectures under unlucky - * circumstances, garbaged). - */ - u_int32_t st_status; /* Current replication status. */ - DB_LSN st_next_lsn; /* Next LSN to use or expect. */ - DB_LSN st_waiting_lsn; /* LSN we're awaiting, if any. */ - db_pgno_t st_next_pg; /* Next pg we expect. */ - db_pgno_t st_waiting_pg; /* pg we're awaiting, if any. */ - - u_int32_t st_dupmasters; /* # of times a duplicate master - condition was detected.+ */ - int st_env_id; /* Current environment ID. */ - int st_env_priority; /* Current environment priority. */ - u_int32_t st_bulk_fills; /* Bulk buffer fills. */ - u_int32_t st_bulk_overflows; /* Bulk buffer overflows. */ - u_int32_t st_bulk_records; /* Bulk records stored. */ - u_int32_t st_bulk_transfers; /* Transfers of bulk buffers. */ - u_int32_t st_client_rerequests; /* Number of forced rerequests. */ - u_int32_t st_client_svc_req; /* Number of client service requests - received by this client. */ - u_int32_t st_client_svc_miss; /* Number of client service requests - missing on this client. */ - u_int32_t st_gen; /* Current generation number. */ - u_int32_t st_egen; /* Current election gen number. */ - u_int32_t st_log_duplicated; /* Log records received multiply.+ */ - u_int32_t st_log_queued; /* Log records currently queued.+ */ - u_int32_t st_log_queued_max; /* Max. log records queued at once.+ */ - u_int32_t st_log_queued_total; /* Total # of log recs. ever queued.+ */ - u_int32_t st_log_records; /* Log records received and put.+ */ - u_int32_t st_log_requested; /* Log recs. missed and requested.+ */ - int st_master; /* Env. ID of the current master. */ - u_int32_t st_master_changes; /* # of times we've switched masters. */ - u_int32_t st_msgs_badgen; /* Messages with a bad generation #.+ */ - u_int32_t st_msgs_processed; /* Messages received and processed.+ */ - u_int32_t st_msgs_recover; /* Messages ignored because this site - was a client in recovery.+ */ - u_int32_t st_msgs_send_failures;/* # of failed message sends.+ */ - u_int32_t st_msgs_sent; /* # of successful message sends.+ */ - u_int32_t st_newsites; /* # of NEWSITE msgs. received.+ */ - int st_nsites; /* Current number of sites we will - assume during elections. */ - u_int32_t st_nthrottles; /* # of times we were throttled. */ - u_int32_t st_outdated; /* # of times we detected and returned - an OUTDATED condition.+ */ - u_int32_t st_pg_duplicated; /* Pages received multiply.+ */ - u_int32_t st_pg_records; /* Pages received and stored.+ */ - u_int32_t st_pg_requested; /* Pages missed and requested.+ */ - u_int32_t st_startup_complete; /* Site completed client sync-up. */ - u_int32_t st_txns_applied; /* # of transactions applied.+ */ - - /* Elections generally. */ - u_int32_t st_elections; /* # of elections held.+ */ - u_int32_t st_elections_won; /* # of elections won by this site.+ */ - - /* Statistics about an in-progress election. */ - int st_election_cur_winner; /* Current front-runner. */ - u_int32_t st_election_gen; /* Election generation number. */ - DB_LSN st_election_lsn; /* Max. LSN of current winner. */ - int st_election_nsites; /* # of "registered voters". */ - int st_election_nvotes; /* # of "registered voters" needed. */ - int st_election_priority; /* Current election priority. */ - int st_election_status; /* Current election status. */ - u_int32_t st_election_tiebreaker;/* Election tiebreaker value. */ - int st_election_votes; /* Votes received in this round. */ - u_int32_t st_election_sec; /* Last election time seconds. */ - u_int32_t st_election_usec; /* Last election time useconds. */ -}; - -/******************************************************* - * Sequences. - *******************************************************/ -/* - * The storage record for a sequence. - */ -struct __db_seq_record { - u_int32_t seq_version; /* Version size/number. */ -#define DB_SEQ_DEC 0x00000001 /* Decrement sequence. */ -#define DB_SEQ_INC 0x00000002 /* Increment sequence. */ -#define DB_SEQ_RANGE_SET 0x00000004 /* Range set (internal). */ -#define DB_SEQ_WRAP 0x00000008 /* Wrap sequence at min/max. */ -#define DB_SEQ_WRAPPED 0x00000010 /* Just wrapped (internal). */ - u_int32_t flags; /* Flags. */ - db_seq_t seq_value; /* Current value. */ - db_seq_t seq_max; /* Max permitted. */ - db_seq_t seq_min; /* Min permitted. */ -}; - -/* - * Handle for a sequence object. - */ -struct __db_sequence { - DB *seq_dbp; /* DB handle for this sequence. */ - db_mutex_t mtx_seq; /* Mutex if sequence is threaded. */ - DB_SEQ_RECORD *seq_rp; /* Pointer to current data. */ - DB_SEQ_RECORD seq_record; /* Data from DB_SEQUENCE. */ - int32_t seq_cache_size; /* Number of values cached. */ - db_seq_t seq_last_value; /* Last value cached. */ - DBT seq_key; /* DBT pointing to sequence key. */ - DBT seq_data; /* DBT pointing to seq_record. */ - - /* API-private structure: used by C++ and Java. */ - void *api_internal; - - /* DB_SEQUENCE PUBLIC HANDLE LIST BEGIN */ - int (*close) __P((DB_SEQUENCE *, u_int32_t)); - int (*get) __P((DB_SEQUENCE *, - DB_TXN *, int32_t, db_seq_t *, u_int32_t)); - int (*get_cachesize) __P((DB_SEQUENCE *, int32_t *)); - int (*get_db) __P((DB_SEQUENCE *, DB **)); - int (*get_flags) __P((DB_SEQUENCE *, u_int32_t *)); - int (*get_key) __P((DB_SEQUENCE *, DBT *)); - int (*get_range) __P((DB_SEQUENCE *, - db_seq_t *, db_seq_t *)); - int (*initial_value) __P((DB_SEQUENCE *, db_seq_t)); - int (*open) __P((DB_SEQUENCE *, - DB_TXN *, DBT *, u_int32_t)); - int (*remove) __P((DB_SEQUENCE *, DB_TXN *, u_int32_t)); - int (*set_cachesize) __P((DB_SEQUENCE *, int32_t)); - int (*set_flags) __P((DB_SEQUENCE *, u_int32_t)); - int (*set_range) __P((DB_SEQUENCE *, db_seq_t, db_seq_t)); - int (*stat) __P((DB_SEQUENCE *, - DB_SEQUENCE_STAT **, u_int32_t)); - int (*stat_print) __P((DB_SEQUENCE *, u_int32_t)); - /* DB_SEQUENCE PUBLIC HANDLE LIST END */ -}; - -struct __db_seq_stat { - u_int32_t st_wait; /* Sequence lock granted w/o wait. */ - u_int32_t st_nowait; /* Sequence lock granted after wait. */ - db_seq_t st_current; /* Current value in db. */ - db_seq_t st_value; /* Current cached value. */ - db_seq_t st_last_value; /* Last cached value. */ - db_seq_t st_min; /* Minimum value. */ - db_seq_t st_max; /* Maximum value. */ - int32_t st_cache_size; /* Cache size. */ - u_int32_t st_flags; /* Flag value. */ -}; - -/******************************************************* - * Access methods. - *******************************************************/ -typedef enum { - DB_BTREE=1, - DB_HASH=2, - DB_RECNO=3, - DB_QUEUE=4, - DB_UNKNOWN=5 /* Figure it out on open. */ -} DBTYPE; - -#define DB_RENAMEMAGIC 0x030800 /* File has been renamed. */ - -#define DB_BTREEVERSION 9 /* Current btree version. */ -#define DB_BTREEOLDVER 8 /* Oldest btree version supported. */ -#define DB_BTREEMAGIC 0x053162 - -#define DB_HASHVERSION 8 /* Current hash version. */ -#define DB_HASHOLDVER 7 /* Oldest hash version supported. */ -#define DB_HASHMAGIC 0x061561 - -#define DB_QAMVERSION 4 /* Current queue version. */ -#define DB_QAMOLDVER 3 /* Oldest queue version supported. */ -#define DB_QAMMAGIC 0x042253 - -#define DB_SEQUENCE_VERSION 2 /* Current sequence version. */ -#define DB_SEQUENCE_OLDVER 1 /* Oldest sequence version supported. */ - -/* - * DB access method and cursor operation values. Each value is an operation - * code to which additional bit flags are added. - */ -#define DB_AFTER 1 /* c_put() */ -#define DB_APPEND 2 /* put() */ -#define DB_BEFORE 3 /* c_put() */ -#define DB_CACHED_COUNTS 4 /* stat() */ -#define DB_CONSUME 5 /* get() */ -#define DB_CONSUME_WAIT 6 /* get() */ -#define DB_CURRENT 7 /* c_get(), c_put(), DB_LOGC->get() */ -#define DB_FAST_STAT 8 /* stat() */ -#define DB_FIRST 9 /* c_get(), DB_LOGC->get() */ -#define DB_GET_BOTH 10 /* get(), c_get() */ -#define DB_GET_BOTHC 11 /* c_get() (internal) */ -#define DB_GET_BOTH_RANGE 12 /* get(), c_get() */ -#define DB_GET_RECNO 13 /* c_get() */ -#define DB_JOIN_ITEM 14 /* c_get(); do not do primary lookup */ -#define DB_KEYFIRST 15 /* c_put() */ -#define DB_KEYLAST 16 /* c_put() */ -#define DB_LAST 17 /* c_get(), DB_LOGC->get() */ -#define DB_NEXT 18 /* c_get(), DB_LOGC->get() */ -#define DB_NEXT_DUP 19 /* c_get() */ -#define DB_NEXT_NODUP 20 /* c_get() */ -#define DB_NODUPDATA 21 /* put(), c_put() */ -#define DB_NOOVERWRITE 22 /* put() */ -#define DB_NOSYNC 23 /* close() */ -#define DB_POSITION 24 /* c_dup() */ -#define DB_PREV 25 /* c_get(), DB_LOGC->get() */ -#define DB_PREV_NODUP 26 /* c_get(), DB_LOGC->get() */ -#define DB_RECORDCOUNT 27 /* stat() */ -#define DB_SET 28 /* c_get(), DB_LOGC->get() */ -#define DB_SET_LOCK_TIMEOUT 29 /* set_timout() */ -#define DB_SET_RANGE 30 /* c_get() */ -#define DB_SET_RECNO 31 /* get(), c_get() */ -#define DB_SET_TXN_NOW 32 /* set_timout() (internal) */ -#define DB_SET_TXN_TIMEOUT 33 /* set_timout() */ -#define DB_UPDATE_SECONDARY 34 /* c_get(), c_del() (internal) */ -#define DB_WRITECURSOR 35 /* cursor() */ -#define DB_WRITELOCK 36 /* cursor() (internal) */ - -/* This has to change when the max opcode hits 255. */ -#define DB_OPFLAGS_MASK 0x000000ff /* Mask for operations flags. */ - -/* - * Masks for flags that can be OR'd into DB access method and cursor - * operation values. Three top bits have already been taken: - * - * DB_AUTO_COMMIT 0x01000000 - * DB_READ_COMMITTED 0x02000000 - * DB_READ_UNCOMMITTED 0x04000000 - */ -#define DB_MULTIPLE 0x08000000 /* Return multiple data values. */ -#define DB_MULTIPLE_KEY 0x10000000 /* Return multiple data/key pairs. */ -#define DB_RMW 0x20000000 /* Acquire write lock immediately. */ - -/* - * DB (user visible) error return codes. - * - * !!! - * For source compatibility with DB 2.X deadlock return (EAGAIN), use the - * following: - * #include <errno.h> - * #define DB_LOCK_DEADLOCK EAGAIN - * - * !!! - * We don't want our error returns to conflict with other packages where - * possible, so pick a base error value that's hopefully not common. We - * document that we own the error name space from -30,800 to -30,999. - */ -/* DB (public) error return codes. */ -#define DB_BUFFER_SMALL (-30999)/* User memory too small for return. */ -#define DB_DONOTINDEX (-30998)/* "Null" return from 2ndary callbk. */ -#define DB_KEYEMPTY (-30997)/* Key/data deleted or never created. */ -#define DB_KEYEXIST (-30996)/* The key/data pair already exists. */ -#define DB_LOCK_DEADLOCK (-30995)/* Deadlock. */ -#define DB_LOCK_NOTGRANTED (-30994)/* Lock unavailable. */ -#define DB_LOG_BUFFER_FULL (-30993)/* In-memory log buffer full. */ -#define DB_NOSERVER (-30992)/* Server panic return. */ -#define DB_NOSERVER_HOME (-30991)/* Bad home sent to server. */ -#define DB_NOSERVER_ID (-30990)/* Bad ID sent to server. */ -#define DB_NOTFOUND (-30989)/* Key/data pair not found (EOF). */ -#define DB_OLD_VERSION (-30988)/* Out-of-date version. */ -#define DB_PAGE_NOTFOUND (-30987)/* Requested page not found. */ -#define DB_REP_DUPMASTER (-30986)/* There are two masters. */ -#define DB_REP_HANDLE_DEAD (-30985)/* Rolled back a commit. */ -#define DB_REP_HOLDELECTION (-30984)/* Time to hold an election. */ -#define DB_REP_IGNORE (-30983)/* This msg should be ignored.*/ -#define DB_REP_ISPERM (-30982)/* Cached not written perm written.*/ -#define DB_REP_JOIN_FAILURE (-30981)/* Unable to join replication group. */ -#define DB_REP_LOCKOUT (-30980)/* API/Replication lockout now. */ -#define DB_REP_NEWMASTER (-30979)/* We have learned of a new master. */ -#define DB_REP_NEWSITE (-30978)/* New site entered system. */ -#define DB_REP_NOTPERM (-30977)/* Permanent log record not written. */ -#define DB_REP_STARTUPDONE (-30976)/* Client startup complete. */ -#define DB_REP_UNAVAIL (-30975)/* Site cannot currently be reached. */ -#define DB_RUNRECOVERY (-30974)/* Panic return. */ -#define DB_SECONDARY_BAD (-30973)/* Secondary index corrupt. */ -#define DB_VERIFY_BAD (-30972)/* Verify failed; bad format. */ -#define DB_VERSION_MISMATCH (-30971)/* Environment version mismatch. */ - -/* DB (private) error return codes. */ -#define DB_ALREADY_ABORTED (-30899) -#define DB_DELETED (-30898)/* Recovery file marked deleted. */ -#define DB_NEEDSPLIT (-30897)/* Page needs to be split. */ -#define DB_REP_BULKOVF (-30896)/* Rep bulk buffer overflow. */ -#define DB_REP_EGENCHG (-30895)/* Egen changed while in election. */ -#define DB_REP_LOGREADY (-30894)/* Rep log ready for recovery. */ -#define DB_REP_PAGEDONE (-30893)/* This page was already done. */ -#define DB_SURPRISE_KID (-30892)/* Child commit where parent - didn't know it was a parent. */ -#define DB_SWAPBYTES (-30891)/* Database needs byte swapping. */ -#define DB_TIMEOUT (-30890)/* Timed out waiting for election. */ -#define DB_TXN_CKP (-30889)/* Encountered ckp record in log. */ -#define DB_VERIFY_FATAL (-30888)/* DB->verify cannot proceed. */ - -/* Database handle. */ -struct __db { - /******************************************************* - * Public: owned by the application. - *******************************************************/ - u_int32_t pgsize; /* Database logical page size. */ - - /* Callbacks. */ - int (*db_append_recno) __P((DB *, DBT *, db_recno_t)); - void (*db_feedback) __P((DB *, int, int)); - int (*dup_compare) __P((DB *, const DBT *, const DBT *)); - - void *app_private; /* Application-private handle. */ - - /******************************************************* - * Private: owned by DB. - *******************************************************/ - DB_ENV *dbenv; /* Backing environment. */ - - DBTYPE type; /* DB access method type. */ - - DB_MPOOLFILE *mpf; /* Backing buffer pool. */ - - db_mutex_t mutex; /* Synchronization for free threading */ - - char *fname, *dname; /* File/database passed to DB->open. */ - u_int32_t open_flags; /* Flags passed to DB->open. */ - - u_int8_t fileid[DB_FILE_ID_LEN];/* File's unique ID for locking. */ - - u_int32_t adj_fileid; /* File's unique ID for curs. adj. */ - -#define DB_LOGFILEID_INVALID -1 - FNAME *log_filename; /* File's naming info for logging. */ - - db_pgno_t meta_pgno; /* Meta page number */ - u_int32_t lid; /* Locker id for handle locking. */ - u_int32_t cur_lid; /* Current handle lock holder. */ - u_int32_t associate_lid; /* Locker id for DB->associate call. */ - DB_LOCK handle_lock; /* Lock held on this handle. */ - - u_int cl_id; /* RPC: remote client id. */ - - time_t timestamp; /* Handle timestamp for replication. */ - u_int32_t fid_gen; /* Rep generation number for fids. */ - - /* - * Returned data memory for DB->get() and friends. - */ - DBT my_rskey; /* Secondary key. */ - DBT my_rkey; /* [Primary] key. */ - DBT my_rdata; /* Data. */ - - /* - * !!! - * Some applications use DB but implement their own locking outside of - * DB. If they're using fcntl(2) locking on the underlying database - * file, and we open and close a file descriptor for that file, we will - * discard their locks. The DB_FCNTL_LOCKING flag to DB->open is an - * undocumented interface to support this usage which leaves any file - * descriptors we open until DB->close. This will only work with the - * DB->open interface and simple caches, e.g., creating a transaction - * thread may open/close file descriptors this flag doesn't protect. - * Locking with fcntl(2) on a file that you don't own is a very, very - * unsafe thing to do. 'Nuff said. - */ - DB_FH *saved_open_fhp; /* Saved file handle. */ - - /* - * Linked list of DBP's, linked from the DB_ENV, used to keep track - * of all open db handles for cursor adjustment. - * - * !!! - * Explicit representations of structures from queue.h. - * LIST_ENTRY(__db) dblistlinks; - */ - struct { - struct __db *le_next; - struct __db **le_prev; - } dblistlinks; - - /* - * Cursor queues. - * - * !!! - * Explicit representations of structures from queue.h. - * TAILQ_HEAD(__cq_fq, __dbc) free_queue; - * TAILQ_HEAD(__cq_aq, __dbc) active_queue; - * TAILQ_HEAD(__cq_jq, __dbc) join_queue; - */ - struct __cq_fq { - struct __dbc *tqh_first; - struct __dbc **tqh_last; - } free_queue; - struct __cq_aq { - struct __dbc *tqh_first; - struct __dbc **tqh_last; - } active_queue; - struct __cq_jq { - struct __dbc *tqh_first; - struct __dbc **tqh_last; - } join_queue; - - /* - * Secondary index support. - * - * Linked list of secondary indices -- set in the primary. - * - * !!! - * Explicit representations of structures from queue.h. - * LIST_HEAD(s_secondaries, __db); - */ - struct { - struct __db *lh_first; - } s_secondaries; - - /* - * List entries for secondaries, and reference count of how - * many threads are updating this secondary (see __db_c_put). - * - * !!! - * Note that these are synchronized by the primary's mutex, but - * filled in in the secondaries. - * - * !!! - * Explicit representations of structures from queue.h. - * LIST_ENTRY(__db) s_links; - */ - struct { - struct __db *le_next; - struct __db **le_prev; - } s_links; - u_int32_t s_refcnt; - - /* Secondary callback and free functions -- set in the secondary. */ - int (*s_callback) __P((DB *, const DBT *, const DBT *, DBT *)); - - /* Reference to primary -- set in the secondary. */ - DB *s_primary; - -#define DB_ASSOC_IMMUTABLE_KEY 0x00000001 /* Secondary key is immutable. */ - - /* Flags passed to associate -- set in the secondary. */ - u_int32_t s_assoc_flags; - - /* API-private structure: used by DB 1.85, C++, Java, Perl and Tcl */ - void *api_internal; - - /* Subsystem-private structure. */ - void *bt_internal; /* Btree/Recno access method. */ - void *h_internal; /* Hash access method. */ - void *q_internal; /* Queue access method. */ - void *xa_internal; /* XA. */ - - /* DB PUBLIC HANDLE LIST BEGIN */ - int (*associate) __P((DB *, DB_TXN *, DB *, - int (*)(DB *, const DBT *, const DBT *, DBT *), u_int32_t)); - int (*close) __P((DB *, u_int32_t)); - int (*compact) __P((DB *, - DB_TXN *, DBT *, DBT *, DB_COMPACT *, u_int32_t, DBT *)); - int (*cursor) __P((DB *, DB_TXN *, DBC **, u_int32_t)); - int (*del) __P((DB *, DB_TXN *, DBT *, u_int32_t)); - void (*err) __P((DB *, int, const char *, ...)); - void (*errx) __P((DB *, const char *, ...)); - int (*fd) __P((DB *, int *)); - int (*get) __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); - int (*get_bt_minkey) __P((DB *, u_int32_t *)); - int (*get_byteswapped) __P((DB *, int *)); - int (*get_cachesize) __P((DB *, u_int32_t *, u_int32_t *, int *)); - int (*get_dbname) __P((DB *, const char **, const char **)); - int (*get_encrypt_flags) __P((DB *, u_int32_t *)); - DB_ENV *(*get_env) __P((DB *)); - void (*get_errfile) __P((DB *, FILE **)); - void (*get_errpfx) __P((DB *, const char **)); - int (*get_flags) __P((DB *, u_int32_t *)); - int (*get_h_ffactor) __P((DB *, u_int32_t *)); - int (*get_h_nelem) __P((DB *, u_int32_t *)); - int (*get_lorder) __P((DB *, int *)); - DB_MPOOLFILE *(*get_mpf) __P((DB *)); - void (*get_msgfile) __P((DB *, FILE **)); - int (*get_open_flags) __P((DB *, u_int32_t *)); - int (*get_pagesize) __P((DB *, u_int32_t *)); - int (*get_q_extentsize) __P((DB *, u_int32_t *)); - int (*get_re_delim) __P((DB *, int *)); - int (*get_re_len) __P((DB *, u_int32_t *)); - int (*get_re_pad) __P((DB *, int *)); - int (*get_re_source) __P((DB *, const char **)); - int (*get_transactional) __P((DB *)); - int (*get_type) __P((DB *, DBTYPE *)); - int (*join) __P((DB *, DBC **, DBC **, u_int32_t)); - int (*key_range) - __P((DB *, DB_TXN *, DBT *, DB_KEY_RANGE *, u_int32_t)); - int (*open) __P((DB *, - DB_TXN *, const char *, const char *, DBTYPE, u_int32_t, int)); - int (*pget) __P((DB *, DB_TXN *, DBT *, DBT *, DBT *, u_int32_t)); - int (*put) __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); - int (*remove) __P((DB *, const char *, const char *, u_int32_t)); - int (*rename) __P((DB *, - const char *, const char *, const char *, u_int32_t)); - int (*set_alloc) __P((DB *, void *(*)(size_t), - void *(*)(void *, size_t), void (*)(void *))); - int (*set_append_recno) __P((DB *, int (*)(DB *, DBT *, db_recno_t))); - int (*set_bt_compare) - __P((DB *, int (*)(DB *, const DBT *, const DBT *))); - int (*set_bt_minkey) __P((DB *, u_int32_t)); - int (*set_bt_prefix) - __P((DB *, size_t (*)(DB *, const DBT *, const DBT *))); - int (*set_cachesize) __P((DB *, u_int32_t, u_int32_t, int)); - int (*set_dup_compare) - __P((DB *, int (*)(DB *, const DBT *, const DBT *))); - int (*set_encrypt) __P((DB *, const char *, u_int32_t)); - void (*set_errcall) __P((DB *, - void (*)(const DB_ENV *, const char *, const char *))); - void (*set_errfile) __P((DB *, FILE *)); - void (*set_errpfx) __P((DB *, const char *)); - int (*set_feedback) __P((DB *, void (*)(DB *, int, int))); - int (*set_flags) __P((DB *, u_int32_t)); - int (*set_h_ffactor) __P((DB *, u_int32_t)); - int (*set_h_hash) - __P((DB *, u_int32_t (*)(DB *, const void *, u_int32_t))); - int (*set_h_nelem) __P((DB *, u_int32_t)); - int (*set_lorder) __P((DB *, int)); - void (*set_msgcall) __P((DB *, void (*)(const DB_ENV *, const char *))); - void (*set_msgfile) __P((DB *, FILE *)); - int (*set_pagesize) __P((DB *, u_int32_t)); - int (*set_paniccall) __P((DB *, void (*)(DB_ENV *, int))); - int (*set_q_extentsize) __P((DB *, u_int32_t)); - int (*set_re_delim) __P((DB *, int)); - int (*set_re_len) __P((DB *, u_int32_t)); - int (*set_re_pad) __P((DB *, int)); - int (*set_re_source) __P((DB *, const char *)); - int (*stat) __P((DB *, DB_TXN *, void *, u_int32_t)); - int (*stat_print) __P((DB *, u_int32_t)); - int (*sync) __P((DB *, u_int32_t)); - int (*truncate) __P((DB *, DB_TXN *, u_int32_t *, u_int32_t)); - int (*upgrade) __P((DB *, const char *, u_int32_t)); - int (*verify) - __P((DB *, const char *, const char *, FILE *, u_int32_t)); - /* DB PUBLIC HANDLE LIST END */ - - /* DB PRIVATE HANDLE LIST BEGIN */ - int (*dump) __P((DB *, const char *, - int (*)(void *, const void *), void *, int, int)); - int (*db_am_remove) __P((DB *, DB_TXN *, const char *, const char *)); - int (*db_am_rename) __P((DB *, DB_TXN *, - const char *, const char *, const char *)); - /* DB PRIVATE HANDLE LIST END */ - - /* - * Never called; these are a place to save function pointers - * so that we can undo an associate. - */ - int (*stored_get) __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); - int (*stored_close) __P((DB *, u_int32_t)); - -#define DB_OK_BTREE 0x01 -#define DB_OK_HASH 0x02 -#define DB_OK_QUEUE 0x04 -#define DB_OK_RECNO 0x08 - u_int32_t am_ok; /* Legal AM choices. */ - - /* - * This field really ought to be an AM_FLAG, but we have - * have run out of bits. If/when we decide to split up - * the flags, we can incorporate it. - */ - int preserve_fid; /* Do not free fileid on close. */ - -#define DB_AM_CHKSUM 0x00000001 /* Checksumming */ -#define DB_AM_CL_WRITER 0x00000002 /* Allow writes in client replica */ -#define DB_AM_COMPENSATE 0x00000004 /* Created by compensating txn */ -#define DB_AM_CREATED 0x00000008 /* Database was created upon open */ -#define DB_AM_CREATED_MSTR 0x00000010 /* Encompassing file was created */ -#define DB_AM_DBM_ERROR 0x00000020 /* Error in DBM/NDBM database */ -#define DB_AM_DELIMITER 0x00000040 /* Variable length delimiter set */ -#define DB_AM_DISCARD 0x00000080 /* Discard any cached pages */ -#define DB_AM_DUP 0x00000100 /* DB_DUP */ -#define DB_AM_DUPSORT 0x00000200 /* DB_DUPSORT */ -#define DB_AM_ENCRYPT 0x00000400 /* Encryption */ -#define DB_AM_FIXEDLEN 0x00000800 /* Fixed-length records */ -#define DB_AM_INMEM 0x00001000 /* In-memory; no sync on close */ -#define DB_AM_INORDER 0x00002000 /* DB_INORDER */ -#define DB_AM_IN_RENAME 0x00004000 /* File is being renamed */ -#define DB_AM_NOT_DURABLE 0x00008000 /* Do not log changes */ -#define DB_AM_OPEN_CALLED 0x00010000 /* DB->open called */ -#define DB_AM_PAD 0x00020000 /* Fixed-length record pad */ -#define DB_AM_PGDEF 0x00040000 /* Page size was defaulted */ -#define DB_AM_RDONLY 0x00080000 /* Database is readonly */ -#define DB_AM_READ_UNCOMMITTED 0x00100000 /* Support degree 1 isolation */ -#define DB_AM_RECNUM 0x00200000 /* DB_RECNUM */ -#define DB_AM_RECOVER 0x00400000 /* DB opened by recovery routine */ -#define DB_AM_RENUMBER 0x00800000 /* DB_RENUMBER */ -#define DB_AM_REVSPLITOFF 0x01000000 /* DB_REVSPLITOFF */ -#define DB_AM_SECONDARY 0x02000000 /* Database is a secondary index */ -#define DB_AM_SNAPSHOT 0x04000000 /* DB_SNAPSHOT */ -#define DB_AM_SUBDB 0x08000000 /* Subdatabases supported */ -#define DB_AM_SWAP 0x10000000 /* Pages need to be byte-swapped */ -#define DB_AM_TXN 0x20000000 /* Opened in a transaction */ -#define DB_AM_VERIFYING 0x40000000 /* DB handle is in the verifier */ - u_int32_t orig_flags; /* Flags at open, for refresh */ - u_int32_t flags; -}; - -/* - * Macros for bulk get. These are only intended for the C API. - * For C++, use DbMultiple*Iterator. - */ -#define DB_MULTIPLE_INIT(pointer, dbt) \ - (pointer = (u_int8_t *)(dbt)->data + \ - (dbt)->ulen - sizeof(u_int32_t)) -#define DB_MULTIPLE_NEXT(pointer, dbt, retdata, retdlen) \ - do { \ - if (*((u_int32_t *)(pointer)) == (u_int32_t)-1) { \ - retdata = NULL; \ - pointer = NULL; \ - break; \ - } \ - retdata = (u_int8_t *) \ - (dbt)->data + *(u_int32_t *)(pointer); \ - (pointer) = (u_int32_t *)(pointer) - 1; \ - retdlen = *(u_int32_t *)(pointer); \ - (pointer) = (u_int32_t *)(pointer) - 1; \ - if (retdlen == 0 && \ - retdata == (u_int8_t *)(dbt)->data) \ - retdata = NULL; \ - } while (0) -#define DB_MULTIPLE_KEY_NEXT(pointer, dbt, retkey, retklen, retdata, retdlen) \ - do { \ - if (*((u_int32_t *)(pointer)) == (u_int32_t)-1) { \ - retdata = NULL; \ - retkey = NULL; \ - pointer = NULL; \ - break; \ - } \ - retkey = (u_int8_t *) \ - (dbt)->data + *(u_int32_t *)(pointer); \ - (pointer) = (u_int32_t *)(pointer) - 1; \ - retklen = *(u_int32_t *)(pointer); \ - (pointer) = (u_int32_t *)(pointer) - 1; \ - retdata = (u_int8_t *) \ - (dbt)->data + *(u_int32_t *)(pointer); \ - (pointer) = (u_int32_t *)(pointer) - 1; \ - retdlen = *(u_int32_t *)(pointer); \ - (pointer) = (u_int32_t *)(pointer) - 1; \ - } while (0) - -#define DB_MULTIPLE_RECNO_NEXT(pointer, dbt, recno, retdata, retdlen) \ - do { \ - if (*((u_int32_t *)(pointer)) == (u_int32_t)0) { \ - recno = 0; \ - retdata = NULL; \ - pointer = NULL; \ - break; \ - } \ - recno = *(u_int32_t *)(pointer); \ - (pointer) = (u_int32_t *)(pointer) - 1; \ - retdata = (u_int8_t *) \ - (dbt)->data + *(u_int32_t *)(pointer); \ - (pointer) = (u_int32_t *)(pointer) - 1; \ - retdlen = *(u_int32_t *)(pointer); \ - (pointer) = (u_int32_t *)(pointer) - 1; \ - } while (0) - -/******************************************************* - * Access method cursors. - *******************************************************/ -struct __dbc { - DB *dbp; /* Related DB access method. */ - DB_TXN *txn; /* Associated transaction. */ - - /* - * Active/free cursor queues. - * - * !!! - * Explicit representations of structures from queue.h. - * TAILQ_ENTRY(__dbc) links; - */ - struct { - DBC *tqe_next; - DBC **tqe_prev; - } links; - - /* - * The DBT *'s below are used by the cursor routines to return - * data to the user when DBT flags indicate that DB should manage - * the returned memory. They point at a DBT containing the buffer - * and length that will be used, and "belonging" to the handle that - * should "own" this memory. This may be a "my_*" field of this - * cursor--the default--or it may be the corresponding field of - * another cursor, a DB handle, a join cursor, etc. In general, it - * will be whatever handle the user originally used for the current - * DB interface call. - */ - DBT *rskey; /* Returned secondary key. */ - DBT *rkey; /* Returned [primary] key. */ - DBT *rdata; /* Returned data. */ - - DBT my_rskey; /* Space for returned secondary key. */ - DBT my_rkey; /* Space for returned [primary] key. */ - DBT my_rdata; /* Space for returned data. */ - - void *lref; /* Reference to default locker. */ - u_int32_t locker; /* Locker for this operation. */ - DBT lock_dbt; /* DBT referencing lock. */ - DB_LOCK_ILOCK lock; /* Object to be locked. */ - DB_LOCK mylock; /* CDB lock held on this cursor. */ - - u_int cl_id; /* Remote client id. */ - - DBTYPE dbtype; /* Cursor type. */ - - DBC_INTERNAL *internal; /* Access method private. */ - - /* DBC PUBLIC HANDLE LIST BEGIN */ - int (*c_close) __P((DBC *)); - int (*c_count) __P((DBC *, db_recno_t *, u_int32_t)); - int (*c_del) __P((DBC *, u_int32_t)); - int (*c_dup) __P((DBC *, DBC **, u_int32_t)); - int (*c_get) __P((DBC *, DBT *, DBT *, u_int32_t)); - int (*c_pget) __P((DBC *, DBT *, DBT *, DBT *, u_int32_t)); - int (*c_put) __P((DBC *, DBT *, DBT *, u_int32_t)); - /* DBC PUBLIC HANDLE LIST END */ - - /* DBC PRIVATE HANDLE LIST BEGIN */ - int (*c_am_bulk) __P((DBC *, DBT *, u_int32_t)); - int (*c_am_close) __P((DBC *, db_pgno_t, int *)); - int (*c_am_del) __P((DBC *)); - int (*c_am_destroy) __P((DBC *)); - int (*c_am_get) __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *)); - int (*c_am_put) __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *)); - int (*c_am_writelock) __P((DBC *)); - /* DBC PRIVATE HANDLE LIST END */ - -/* - * DBC_COMPENSATE and DBC_RECOVER are used during recovery and transaction - * abort. If a transaction is being aborted or recovered then DBC_RECOVER - * will be set and locking and logging will be disabled on this cursor. If - * we are performing a compensating transaction (e.g. free page processing) - * then DB_COMPENSATE will be set to inhibit locking, but logging will still - * be required. - */ -#define DBC_ACTIVE 0x0001 /* Cursor in use. */ -#define DBC_COMPENSATE 0x0002 /* Cursor compensating, don't lock. */ -#define DBC_MULTIPLE 0x0004 /* Return Multiple data. */ -#define DBC_MULTIPLE_KEY 0x0008 /* Return Multiple keys and data. */ -#define DBC_OPD 0x0010 /* Cursor references off-page dups. */ -#define DBC_OWN_LID 0x0020 /* Free lock id on destroy. */ -#define DBC_READ_COMMITTED 0x0040 /* Cursor has degree 2 isolation. */ -#define DBC_READ_UNCOMMITTED 0x0080 /* Cursor has degree 1 isolation. */ -#define DBC_RECOVER 0x0100 /* Recovery cursor; don't log/lock. */ -#define DBC_RMW 0x0200 /* Acquire write flag in read op. */ -#define DBC_TRANSIENT 0x0400 /* Cursor is transient. */ -#define DBC_WRITECURSOR 0x0800 /* Cursor may be used to write (CDB). */ -#define DBC_WRITER 0x1000 /* Cursor immediately writing (CDB). */ - u_int32_t flags; -}; - -/* Key range statistics structure */ -struct __key_range { - double less; - double equal; - double greater; -}; - -/* Btree/Recno statistics structure. */ -struct __db_bt_stat { - u_int32_t bt_magic; /* Magic number. */ - u_int32_t bt_version; /* Version number. */ - u_int32_t bt_metaflags; /* Metadata flags. */ - u_int32_t bt_nkeys; /* Number of unique keys. */ - u_int32_t bt_ndata; /* Number of data items. */ - u_int32_t bt_pagesize; /* Page size. */ - u_int32_t bt_minkey; /* Minkey value. */ - u_int32_t bt_re_len; /* Fixed-length record length. */ - u_int32_t bt_re_pad; /* Fixed-length record pad. */ - u_int32_t bt_levels; /* Tree levels. */ - u_int32_t bt_int_pg; /* Internal pages. */ - u_int32_t bt_leaf_pg; /* Leaf pages. */ - u_int32_t bt_dup_pg; /* Duplicate pages. */ - u_int32_t bt_over_pg; /* Overflow pages. */ - u_int32_t bt_empty_pg; /* Empty pages. */ - u_int32_t bt_free; /* Pages on the free list. */ - u_int32_t bt_int_pgfree; /* Bytes free in internal pages. */ - u_int32_t bt_leaf_pgfree; /* Bytes free in leaf pages. */ - u_int32_t bt_dup_pgfree; /* Bytes free in duplicate pages. */ - u_int32_t bt_over_pgfree; /* Bytes free in overflow pages. */ -}; - -struct __db_compact { - /* Input Parameters. */ - u_int32_t compact_fillpercent; /* Desired fillfactor: 1-100 */ - db_timeout_t compact_timeout; /* Lock timeout. */ - u_int32_t compact_pages; /* Max pages to process. */ - /* Output Stats. */ - u_int32_t compact_pages_free; /* Number of pages freed. */ - u_int32_t compact_pages_examine; /* Number of pages examine. */ - u_int32_t compact_levels; /* Number of levels removed. */ - u_int32_t compact_deadlock; /* Number of deadlocks. */ - db_pgno_t compact_pages_truncated; /* Pages truncated to OS. */ - /* Internal. */ - db_pgno_t compact_truncate; /* Page number for truncation */ -}; - -/* Hash statistics structure. */ -struct __db_h_stat { - u_int32_t hash_magic; /* Magic number. */ - u_int32_t hash_version; /* Version number. */ - u_int32_t hash_metaflags; /* Metadata flags. */ - u_int32_t hash_nkeys; /* Number of unique keys. */ - u_int32_t hash_ndata; /* Number of data items. */ - u_int32_t hash_pagesize; /* Page size. */ - u_int32_t hash_ffactor; /* Fill factor specified at create. */ - u_int32_t hash_buckets; /* Number of hash buckets. */ - u_int32_t hash_free; /* Pages on the free list. */ - u_int32_t hash_bfree; /* Bytes free on bucket pages. */ - u_int32_t hash_bigpages; /* Number of big key/data pages. */ - u_int32_t hash_big_bfree; /* Bytes free on big item pages. */ - u_int32_t hash_overflows; /* Number of overflow pages. */ - u_int32_t hash_ovfl_free; /* Bytes free on ovfl pages. */ - u_int32_t hash_dup; /* Number of dup pages. */ - u_int32_t hash_dup_free; /* Bytes free on duplicate pages. */ -}; - -/* Queue statistics structure. */ -struct __db_qam_stat { - u_int32_t qs_magic; /* Magic number. */ - u_int32_t qs_version; /* Version number. */ - u_int32_t qs_metaflags; /* Metadata flags. */ - u_int32_t qs_nkeys; /* Number of unique keys. */ - u_int32_t qs_ndata; /* Number of data items. */ - u_int32_t qs_pagesize; /* Page size. */ - u_int32_t qs_extentsize; /* Pages per extent. */ - u_int32_t qs_pages; /* Data pages. */ - u_int32_t qs_re_len; /* Fixed-length record length. */ - u_int32_t qs_re_pad; /* Fixed-length record pad. */ - u_int32_t qs_pgfree; /* Bytes free in data pages. */ - u_int32_t qs_first_recno; /* First not deleted record. */ - u_int32_t qs_cur_recno; /* Next available record number. */ -}; - -/******************************************************* - * Environment. - *******************************************************/ -#define DB_REGION_MAGIC 0x120897 /* Environment magic number. */ - -/* Database Environment handle. */ -struct __db_env { - /******************************************************* - * Public: owned by the application. - *******************************************************/ - /* Error message callback. */ - void (*db_errcall) __P((const DB_ENV *, const char *, const char *)); - FILE *db_errfile; /* Error message file stream. */ - const char *db_errpfx; /* Error message prefix. */ - - FILE *db_msgfile; /* Statistics message file stream. */ - /* Statistics message callback. */ - void (*db_msgcall) __P((const DB_ENV *, const char *)); - - /* Other Callbacks. */ - void (*db_feedback) __P((DB_ENV *, int, int)); - void (*db_paniccall) __P((DB_ENV *, int)); - - /* App-specified alloc functions. */ - void *(*db_malloc) __P((size_t)); - void *(*db_realloc) __P((void *, size_t)); - void (*db_free) __P((void *)); - - /* - * Currently, the verbose list is a bit field with room for 32 - * entries. There's no reason that it needs to be limited, if - * there are ever more than 32 entries, convert to a bit array. - */ -#define DB_VERB_DEADLOCK 0x0001 /* Deadlock detection information. */ -#define DB_VERB_RECOVERY 0x0002 /* Recovery information. */ -#define DB_VERB_REGISTER 0x0004 /* Dump waits-for table. */ -#define DB_VERB_REPLICATION 0x0008 /* Replication information. */ -#define DB_VERB_WAITSFOR 0x0010 /* Dump waits-for table. */ - u_int32_t verbose; /* Verbose output. */ - - void *app_private; /* Application-private handle. */ - - int (*app_dispatch) /* User-specified recovery dispatch. */ - __P((DB_ENV *, DBT *, DB_LSN *, db_recops)); - - /* Mutexes. */ - u_int32_t mutex_align; /* Mutex alignment */ - u_int32_t mutex_cnt; /* Number of mutexes to configure */ - u_int32_t mutex_inc; /* Number of mutexes to add */ - u_int32_t mutex_tas_spins;/* Test-and-set spin count */ - - struct { - int alloc_id; /* Allocation ID argument */ - u_int32_t flags; /* Flags argument */ - } *mutex_iq; /* Initial mutexes queue */ - u_int mutex_iq_next; /* Count of initial mutexes */ - u_int mutex_iq_max; /* Maximum initial mutexes */ - - /* Locking. */ - u_int8_t *lk_conflicts; /* Two dimensional conflict matrix. */ - int lk_modes; /* Number of lock modes in table. */ - u_int32_t lk_max; /* Maximum number of locks. */ - u_int32_t lk_max_lockers;/* Maximum number of lockers. */ - u_int32_t lk_max_objects;/* Maximum number of locked objects. */ - u_int32_t lk_detect; /* Deadlock detect on all conflicts. */ - db_timeout_t lk_timeout; /* Lock timeout period. */ - - /* Logging. */ - u_int32_t lg_bsize; /* Buffer size. */ - u_int32_t lg_size; /* Log file size. */ - u_int32_t lg_regionmax; /* Region size. */ - int lg_filemode; /* Log file permission mode. */ - - /* Memory pool. */ - u_int32_t mp_gbytes; /* Cachesize: GB. */ - u_int32_t mp_bytes; /* Cachesize: Bytes. */ - u_int mp_ncache; /* Number of cache regions. */ - size_t mp_mmapsize; /* Maximum file size for mmap. */ - int mp_maxopenfd; /* Maximum open file descriptors. */ - int mp_maxwrite; /* Maximum buffers to write. */ - int /* Sleep after writing max buffers. */ - mp_maxwrite_sleep; - - /* Replication */ - int rep_eid; /* environment id. */ - int (*rep_send) /* Send function. */ - __P((DB_ENV *, const DBT *, const DBT *, - const DB_LSN *, int, u_int32_t)); - - /* Transactions. */ - u_int32_t tx_max; /* Maximum number of transactions. */ - time_t tx_timestamp; /* Recover to specific timestamp. */ - db_timeout_t tx_timeout; /* Timeout for transactions. */ - - /* Thread tracking. */ - u_int32_t thr_nbucket; /* Number of hash buckets. */ - u_int32_t thr_max; /* Max before garbage collection. */ - void *thr_hashtab; /* Hash table of DB_THREAD_INFO. */ - - /******************************************************* - * Private: owned by DB. - *******************************************************/ - pid_t pid_cache; /* Cached process ID. */ - - /* User files, paths. */ - char *db_home; /* Database home. */ - char *db_abshome; /* Absolute path when started. */ - char *db_log_dir; /* Database log file directory. */ - char *db_tmp_dir; /* Database tmp file directory. */ - - char **db_data_dir; /* Database data file directories. */ - int data_cnt; /* Database data file slots. */ - int data_next; /* Next Database data file slot. */ - - int db_mode; /* Default open permissions. */ - int dir_mode; /* Intermediate directory perms. */ - void *env_lref; /* Locker in non-threaded handles. */ - u_int32_t open_flags; /* Flags passed to DB_ENV->open. */ - - void *reginfo; /* REGINFO structure reference. */ - DB_FH *lockfhp; /* fcntl(2) locking file handle. */ - - DB_FH *registry; /* DB_REGISTER file handle. */ - u_int32_t registry_off; /* - * Offset of our slot. We can't use - * off_t because its size depends on - * build settings. - */ - - /* Return ID, check if ID alive. */ - void (*thread_id) __P((DB_ENV *, pid_t *, db_threadid_t *)); - int (*is_alive) __P((DB_ENV *, pid_t, db_threadid_t)); - char *(*thread_id_string) - __P((DB_ENV *, pid_t, db_threadid_t, char *)); - - int (**recover_dtab) /* Dispatch table for recover funcs. */ - __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - size_t recover_dtab_size; - /* Slots in the dispatch table. */ - - void *cl_handle; /* RPC: remote client handle. */ - u_int cl_id; /* RPC: remote client env id. */ - - int db_ref; /* DB reference count. */ - - long shm_key; /* shmget(2) key. */ - - /* - * List of open DB handles for this DB_ENV, used for cursor - * adjustment. Must be protected for multi-threaded support. - * - * !!! - * As this structure is allocated in per-process memory, the - * mutex may need to be stored elsewhere on architectures unable - * to support mutexes in heap memory, e.g. HP/UX 9. - * - * !!! - * Explicit representation of structure in queue.h. - * LIST_HEAD(dblist, __db); - */ - db_mutex_t mtx_dblist; /* Mutex. */ - struct { - struct __db *lh_first; - } dblist; - - /* - * XA support. - * - * !!! - * Explicit representations of structures from queue.h. - * TAILQ_ENTRY(__db_env) links; - * TAILQ_HEAD(xa_txn, __db_txn); - */ - struct { - struct __db_env *tqe_next; - struct __db_env **tqe_prev; - } links; - struct __xa_txn { /* XA Active Transactions. */ - struct __db_txn *tqh_first; - struct __db_txn **tqh_last; - } xa_txn; - int xa_rmid; /* XA Resource Manager ID. */ - - char *passwd; /* Cryptography support. */ - size_t passwd_len; - void *crypto_handle; /* Primary handle. */ - db_mutex_t mtx_mt; /* Mersenne Twister mutex. */ - int mti; /* Mersenne Twister index. */ - u_long *mt; /* Mersenne Twister state vector. */ - - /* API-private structure. */ - void *api1_internal; /* C++, Perl API private */ - void *api2_internal; /* Java API private */ - - void *lg_handle; /* Log handle. */ - void *lk_handle; /* Lock handle. */ - void *mp_handle; /* Mpool handle. */ - void *mutex_handle; /* Mutex handle. */ - void *rep_handle; /* Replication handle. */ - void *tx_handle; /* Txn handle. */ - - /* DB_ENV PUBLIC HANDLE LIST BEGIN */ - int (*close) __P((DB_ENV *, u_int32_t)); - int (*dbremove) __P((DB_ENV *, - DB_TXN *, const char *, const char *, u_int32_t)); - int (*dbrename) __P((DB_ENV *, - DB_TXN *, const char *, const char *, const char *, u_int32_t)); - void (*err) __P((const DB_ENV *, int, const char *, ...)); - void (*errx) __P((const DB_ENV *, const char *, ...)); - int (*failchk) __P((DB_ENV *, u_int32_t)); - int (*fileid_reset) __P((DB_ENV *, const char *, u_int32_t)); - int (*get_cachesize) __P((DB_ENV *, u_int32_t *, u_int32_t *, int *)); - int (*get_data_dirs) __P((DB_ENV *, const char ***)); - int (*get_encrypt_flags) __P((DB_ENV *, u_int32_t *)); - void (*get_errfile) __P((DB_ENV *, FILE **)); - void (*get_errpfx) __P((DB_ENV *, const char **)); - int (*get_flags) __P((DB_ENV *, u_int32_t *)); - int (*get_home) __P((DB_ENV *, const char **)); - int (*get_lg_bsize) __P((DB_ENV *, u_int32_t *)); - int (*get_lg_dir) __P((DB_ENV *, const char **)); - int (*get_lg_filemode) __P((DB_ENV *, int *)); - int (*get_lg_max) __P((DB_ENV *, u_int32_t *)); - int (*get_lg_regionmax) __P((DB_ENV *, u_int32_t *)); - int (*get_lk_conflicts) __P((DB_ENV *, const u_int8_t **, int *)); - int (*get_lk_detect) __P((DB_ENV *, u_int32_t *)); - int (*get_lk_max_lockers) __P((DB_ENV *, u_int32_t *)); - int (*get_lk_max_locks) __P((DB_ENV *, u_int32_t *)); - int (*get_lk_max_objects) __P((DB_ENV *, u_int32_t *)); - int (*get_mp_max_openfd) __P((DB_ENV *, int *)); - int (*get_mp_max_write) __P((DB_ENV *, int *, int *)); - int (*get_mp_mmapsize) __P((DB_ENV *, size_t *)); - void (*get_msgfile) __P((DB_ENV *, FILE **)); - int (*get_open_flags) __P((DB_ENV *, u_int32_t *)); - int (*get_rep_limit) __P((DB_ENV *, u_int32_t *, u_int32_t *)); - int (*get_shm_key) __P((DB_ENV *, long *)); - int (*get_timeout) __P((DB_ENV *, db_timeout_t *, u_int32_t)); - int (*get_tmp_dir) __P((DB_ENV *, const char **)); - int (*get_tx_max) __P((DB_ENV *, u_int32_t *)); - int (*get_tx_timestamp) __P((DB_ENV *, time_t *)); - int (*get_verbose) __P((DB_ENV *, u_int32_t, int *)); - int (*is_bigendian) __P((void)); - int (*lock_detect) __P((DB_ENV *, u_int32_t, u_int32_t, int *)); - int (*lock_get) __P((DB_ENV *, - u_int32_t, u_int32_t, const DBT *, db_lockmode_t, DB_LOCK *)); - int (*lock_id) __P((DB_ENV *, u_int32_t *)); - int (*lock_id_free) __P((DB_ENV *, u_int32_t)); - int (*lock_put) __P((DB_ENV *, DB_LOCK *)); - int (*lock_stat) __P((DB_ENV *, DB_LOCK_STAT **, u_int32_t)); - int (*lock_stat_print) __P((DB_ENV *, u_int32_t)); - int (*lock_vec) __P((DB_ENV *, - u_int32_t, u_int32_t, DB_LOCKREQ *, int, DB_LOCKREQ **)); - int (*log_archive) __P((DB_ENV *, char **[], u_int32_t)); - int (*log_cursor) __P((DB_ENV *, DB_LOGC **, u_int32_t)); - int (*log_file) __P((DB_ENV *, const DB_LSN *, char *, size_t)); - int (*log_flush) __P((DB_ENV *, const DB_LSN *)); - int (*log_printf) __P((DB_ENV *, DB_TXN *, const char *, ...)); - int (*log_put) __P((DB_ENV *, DB_LSN *, const DBT *, u_int32_t)); - int (*log_stat) __P((DB_ENV *, DB_LOG_STAT **, u_int32_t)); - int (*log_stat_print) __P((DB_ENV *, u_int32_t)); - int (*lsn_reset) __P((DB_ENV *, const char *, u_int32_t)); - int (*memp_fcreate) __P((DB_ENV *, DB_MPOOLFILE **, u_int32_t)); - int (*memp_register) __P((DB_ENV *, int, int (*)(DB_ENV *, - db_pgno_t, void *, DBT *), int (*)(DB_ENV *, - db_pgno_t, void *, DBT *))); - int (*memp_stat) __P((DB_ENV *, - DB_MPOOL_STAT **, DB_MPOOL_FSTAT ***, u_int32_t)); - int (*memp_stat_print) __P((DB_ENV *, u_int32_t)); - int (*memp_sync) __P((DB_ENV *, DB_LSN *)); - int (*memp_trickle) __P((DB_ENV *, int, int *)); - int (*mutex_alloc) __P((DB_ENV *, u_int32_t, db_mutex_t *)); - int (*mutex_free) __P((DB_ENV *, db_mutex_t)); - int (*mutex_get_align) __P((DB_ENV *, u_int32_t *)); - int (*mutex_get_increment) __P((DB_ENV *, u_int32_t *)); - int (*mutex_get_max) __P((DB_ENV *, u_int32_t *)); - int (*mutex_get_tas_spins) __P((DB_ENV *, u_int32_t *)); - int (*mutex_lock) __P((DB_ENV *, db_mutex_t)); - int (*mutex_set_align) __P((DB_ENV *, u_int32_t)); - int (*mutex_set_increment) __P((DB_ENV *, u_int32_t)); - int (*mutex_set_max) __P((DB_ENV *, u_int32_t)); - int (*mutex_set_tas_spins) __P((DB_ENV *, u_int32_t)); - int (*mutex_stat) __P((DB_ENV *, DB_MUTEX_STAT **, u_int32_t)); - int (*mutex_stat_print) __P((DB_ENV *, u_int32_t)); - int (*mutex_unlock) __P((DB_ENV *, db_mutex_t)); - int (*open) __P((DB_ENV *, const char *, u_int32_t, int)); - int (*remove) __P((DB_ENV *, const char *, u_int32_t)); - int (*rep_elect) - __P((DB_ENV *, int, int, int, u_int32_t, int *, u_int32_t)); - int (*rep_flush) __P((DB_ENV *)); - int (*rep_get_config) __P((DB_ENV *, u_int32_t, int *)); - int (*rep_process_message) - __P((DB_ENV *, DBT *, DBT *, int *, DB_LSN *)); - int (*rep_set_config) __P((DB_ENV *, u_int32_t, int)); - int (*rep_start) __P((DB_ENV *, DBT *, u_int32_t)); - int (*rep_stat) __P((DB_ENV *, DB_REP_STAT **, u_int32_t)); - int (*rep_stat_print) __P((DB_ENV *, u_int32_t)); - int (*rep_sync) __P((DB_ENV *, u_int32_t)); - int (*set_alloc) __P((DB_ENV *, void *(*)(size_t), - void *(*)(void *, size_t), void (*)(void *))); - int (*set_app_dispatch) - __P((DB_ENV *, int (*)(DB_ENV *, DBT *, DB_LSN *, db_recops))); - int (*set_cachesize) __P((DB_ENV *, u_int32_t, u_int32_t, int)); - int (*set_data_dir) __P((DB_ENV *, const char *)); - int (*set_encrypt) __P((DB_ENV *, const char *, u_int32_t)); - void (*set_errcall) __P((DB_ENV *, - void (*)(const DB_ENV *, const char *, const char *))); - void (*set_errfile) __P((DB_ENV *, FILE *)); - void (*set_errpfx) __P((DB_ENV *, const char *)); - int (*set_feedback) __P((DB_ENV *, void (*)(DB_ENV *, int, int))); - int (*set_flags) __P((DB_ENV *, u_int32_t, int)); - int (*set_intermediate_dir) __P((DB_ENV *, int, u_int32_t)); - int (*set_isalive) __P((DB_ENV *, - int (*)(DB_ENV *, pid_t, db_threadid_t))); - int (*set_lg_bsize) __P((DB_ENV *, u_int32_t)); - int (*set_lg_dir) __P((DB_ENV *, const char *)); - int (*set_lg_filemode) __P((DB_ENV *, int)); - int (*set_lg_max) __P((DB_ENV *, u_int32_t)); - int (*set_lg_regionmax) __P((DB_ENV *, u_int32_t)); - int (*set_lk_conflicts) __P((DB_ENV *, u_int8_t *, int)); - int (*set_lk_detect) __P((DB_ENV *, u_int32_t)); - int (*set_lk_max) __P((DB_ENV *, u_int32_t)); - int (*set_lk_max_lockers) __P((DB_ENV *, u_int32_t)); - int (*set_lk_max_locks) __P((DB_ENV *, u_int32_t)); - int (*set_lk_max_objects) __P((DB_ENV *, u_int32_t)); - int (*set_mp_max_openfd) __P((DB_ENV *, int)); - int (*set_mp_max_write) __P((DB_ENV *, int, int)); - int (*set_mp_mmapsize) __P((DB_ENV *, size_t)); - void (*set_msgcall) - __P((DB_ENV *, void (*)(const DB_ENV *, const char *))); - void (*set_msgfile) __P((DB_ENV *, FILE *)); - int (*set_paniccall) __P((DB_ENV *, void (*)(DB_ENV *, int))); - int (*set_rep_limit) __P((DB_ENV *, u_int32_t, u_int32_t)); - int (*set_rep_request) __P((DB_ENV *, u_int32_t, u_int32_t)); - int (*set_rep_transport) __P((DB_ENV *, int, int (*)(DB_ENV *, - const DBT *, const DBT *, const DB_LSN *, int, u_int32_t))); - int (*set_rpc_server) - __P((DB_ENV *, void *, const char *, long, long, u_int32_t)); - int (*set_shm_key) __P((DB_ENV *, long)); - int (*set_thread_count) __P((DB_ENV *, u_int32_t)); - int (*set_thread_id) __P((DB_ENV *, - void (*)(DB_ENV *, pid_t *, db_threadid_t *))); - int (*set_thread_id_string) __P((DB_ENV *, - char *(*)(DB_ENV *, pid_t, db_threadid_t, char *))); - int (*set_timeout) __P((DB_ENV *, db_timeout_t, u_int32_t)); - int (*set_tmp_dir) __P((DB_ENV *, const char *)); - int (*set_tx_max) __P((DB_ENV *, u_int32_t)); - int (*set_tx_timestamp) __P((DB_ENV *, time_t *)); - int (*set_verbose) __P((DB_ENV *, u_int32_t, int)); - int (*stat_print) __P((DB_ENV *, u_int32_t)); - int (*txn_begin) __P((DB_ENV *, DB_TXN *, DB_TXN **, u_int32_t)); - int (*txn_checkpoint) __P((DB_ENV *, u_int32_t, u_int32_t, u_int32_t)); - int (*txn_recover) - __P((DB_ENV *, DB_PREPLIST *, long, long *, u_int32_t)); - int (*txn_stat) __P((DB_ENV *, DB_TXN_STAT **, u_int32_t)); - int (*txn_stat_print) __P((DB_ENV *, u_int32_t)); - /* DB_ENV PUBLIC HANDLE LIST END */ - - /* DB_ENV PRIVATE HANDLE LIST BEGIN */ - int (*prdbt) __P((DBT *, - int, const char *, void *, int (*)(void *, const void *), int)); - /* DB_ENV PRIVATE HANDLE LIST END */ - -#define DB_TEST_ELECTINIT 1 /* after __rep_elect_init */ -#define DB_TEST_ELECTVOTE1 2 /* after sending VOTE1 */ -#define DB_TEST_POSTDESTROY 3 /* after destroy op */ -#define DB_TEST_POSTLOG 4 /* after logging all pages */ -#define DB_TEST_POSTLOGMETA 5 /* after logging meta in btree */ -#define DB_TEST_POSTOPEN 6 /* after __os_open */ -#define DB_TEST_POSTSYNC 7 /* after syncing the log */ -#define DB_TEST_PREDESTROY 8 /* before destroy op */ -#define DB_TEST_PREOPEN 9 /* before __os_open */ -#define DB_TEST_SUBDB_LOCKS 10 /* subdb locking tests */ - int test_abort; /* Abort value for testing. */ - int test_check; /* Checkpoint value for testing. */ - int test_copy; /* Copy value for testing. */ - -#define DB_ENV_AUTO_COMMIT 0x0000001 /* DB_AUTO_COMMIT. */ -#define DB_ENV_CDB 0x0000002 /* DB_INIT_CDB. */ -#define DB_ENV_CDB_ALLDB 0x0000004 /* CDB environment wide locking. */ -#define DB_ENV_CREATE 0x0000008 /* DB_CREATE set. */ -#define DB_ENV_DBLOCAL 0x0000010 /* DB_ENV allocated for private DB. */ -#define DB_ENV_DIRECT_DB 0x0000020 /* DB_DIRECT_DB set. */ -#define DB_ENV_DIRECT_LOG 0x0000040 /* DB_DIRECT_LOG set. */ -#define DB_ENV_DSYNC_DB 0x0000080 /* DB_DSYNC_DB set. */ -#define DB_ENV_DSYNC_LOG 0x0000100 /* DB_DSYNC_LOG set. */ -#define DB_ENV_FATAL 0x0000200 /* Doing fatal recovery in env. */ -#define DB_ENV_LOCKDOWN 0x0000400 /* DB_LOCKDOWN set. */ -#define DB_ENV_LOG_AUTOREMOVE 0x0000800 /* DB_LOG_AUTOREMOVE set. */ -#define DB_ENV_LOG_INMEMORY 0x0001000 /* DB_LOG_INMEMORY set. */ -#define DB_ENV_NOLOCKING 0x0002000 /* DB_NOLOCKING set. */ -#define DB_ENV_NOMMAP 0x0004000 /* DB_NOMMAP set. */ -#define DB_ENV_NOPANIC 0x0008000 /* Okay if panic set. */ -#define DB_ENV_OPEN_CALLED 0x0010000 /* DB_ENV->open called. */ -#define DB_ENV_OVERWRITE 0x0020000 /* DB_OVERWRITE set. */ -#define DB_ENV_PRIVATE 0x0040000 /* DB_PRIVATE set. */ -#define DB_ENV_REGION_INIT 0x0080000 /* DB_REGION_INIT set. */ -#define DB_ENV_RPCCLIENT 0x0100000 /* DB_RPCCLIENT set. */ -#define DB_ENV_RPCCLIENT_GIVEN 0x0200000 /* User-supplied RPC client struct */ -#define DB_ENV_SYSTEM_MEM 0x0400000 /* DB_SYSTEM_MEM set. */ -#define DB_ENV_THREAD 0x0800000 /* DB_THREAD set. */ -#define DB_ENV_TIME_NOTGRANTED 0x1000000 /* DB_TIME_NOTGRANTED set. */ -#define DB_ENV_TXN_NOSYNC 0x2000000 /* DB_TXN_NOSYNC set. */ -#define DB_ENV_TXN_WRITE_NOSYNC 0x4000000 /* DB_TXN_WRITE_NOSYNC set. */ -#define DB_ENV_YIELDCPU 0x8000000 /* DB_YIELDCPU set. */ - u_int32_t flags; -}; - -#ifndef DB_DBM_HSEARCH -#define DB_DBM_HSEARCH 0 /* No historic interfaces by default. */ -#endif -#if DB_DBM_HSEARCH != 0 -/******************************************************* - * Dbm/Ndbm historic interfaces. - *******************************************************/ -typedef struct __db DBM; - -#define DBM_INSERT 0 /* Flags to dbm_store(). */ -#define DBM_REPLACE 1 - -/* - * The DB support for ndbm(3) always appends this suffix to the - * file name to avoid overwriting the user's original database. - */ -#define DBM_SUFFIX ".db" - -#if defined(_XPG4_2) -typedef struct { - char *dptr; - size_t dsize; -} datum; -#else -typedef struct { - char *dptr; - int dsize; -} datum; -#endif - -/* - * Translate NDBM calls into DB calls so that DB doesn't step on the - * application's name space. - */ -#define dbm_clearerr(a) __db_ndbm_clearerr@DB_VERSION_UNIQUE_NAME@(a) -#define dbm_close(a) __db_ndbm_close@DB_VERSION_UNIQUE_NAME@(a) -#define dbm_delete(a, b) __db_ndbm_delete@DB_VERSION_UNIQUE_NAME@(a, b) -#define dbm_dirfno(a) __db_ndbm_dirfno@DB_VERSION_UNIQUE_NAME@(a) -#define dbm_error(a) __db_ndbm_error@DB_VERSION_UNIQUE_NAME@(a) -#define dbm_fetch(a, b) __db_ndbm_fetch@DB_VERSION_UNIQUE_NAME@(a, b) -#define dbm_firstkey(a) __db_ndbm_firstkey@DB_VERSION_UNIQUE_NAME@(a) -#define dbm_nextkey(a) __db_ndbm_nextkey@DB_VERSION_UNIQUE_NAME@(a) -#define dbm_open(a, b, c) __db_ndbm_open@DB_VERSION_UNIQUE_NAME@(a, b, c) -#define dbm_pagfno(a) __db_ndbm_pagfno@DB_VERSION_UNIQUE_NAME@(a) -#define dbm_rdonly(a) __db_ndbm_rdonly@DB_VERSION_UNIQUE_NAME@(a) -#define dbm_store(a, b, c, d) \ - __db_ndbm_store@DB_VERSION_UNIQUE_NAME@(a, b, c, d) - -/* - * Translate DBM calls into DB calls so that DB doesn't step on the - * application's name space. - * - * The global variables dbrdonly, dirf and pagf were not retained when 4BSD - * replaced the dbm interface with ndbm, and are not supported here. - */ -#define dbminit(a) __db_dbm_init@DB_VERSION_UNIQUE_NAME@(a) -#define dbmclose __db_dbm_close@DB_VERSION_UNIQUE_NAME@ -#if !defined(__cplusplus) -#define delete(a) __db_dbm_delete@DB_VERSION_UNIQUE_NAME@(a) -#endif -#define fetch(a) __db_dbm_fetch@DB_VERSION_UNIQUE_NAME@(a) -#define firstkey __db_dbm_firstkey@DB_VERSION_UNIQUE_NAME@ -#define nextkey(a) __db_dbm_nextkey@DB_VERSION_UNIQUE_NAME@(a) -#define store(a, b) __db_dbm_store@DB_VERSION_UNIQUE_NAME@(a, b) - -/******************************************************* - * Hsearch historic interface. - *******************************************************/ -typedef enum { - FIND, ENTER -} ACTION; - -typedef struct entry { - char *key; - char *data; -} ENTRY; - -#define hcreate(a) __db_hcreate@DB_VERSION_UNIQUE_NAME@(a) -#define hdestroy __db_hdestroy@DB_VERSION_UNIQUE_NAME@ -#define hsearch(a, b) __db_hsearch@DB_VERSION_UNIQUE_NAME@(a, b) - -#endif /* DB_DBM_HSEARCH */ - -#if defined(__cplusplus) -} -#endif -#endif /* !_DB_H_ */ diff --git a/storage/bdb/dbinc/db_185.in b/storage/bdb/dbinc/db_185.in deleted file mode 100644 index 56b909cd934..00000000000 --- a/storage/bdb/dbinc/db_185.in +++ /dev/null @@ -1,169 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: db_185.in,v 12.2 2005/06/16 20:21:45 bostic Exp $ - */ - -#ifndef _DB_185_H_ -#define _DB_185_H_ - -#include <sys/types.h> - -#include <limits.h> - -/* - * XXX - * Handle function prototypes and the keyword "const". This steps on name - * space that DB doesn't control, but all of the other solutions are worse. - */ -#undef __P -#if defined(__STDC__) || defined(__cplusplus) -#define __P(protos) protos /* ANSI C prototypes */ -#else -#define const -#define __P(protos) () /* K&R C preprocessor */ -#endif - -#define RET_ERROR -1 /* Return values. */ -#define RET_SUCCESS 0 -#define RET_SPECIAL 1 - -#ifndef __BIT_TYPES_DEFINED__ -#define __BIT_TYPES_DEFINED__ -@u_int8_decl@ -@int16_decl@ -@u_int16_decl@ -@int32_decl@ -@u_int32_decl@ -#endif - -/* - * XXX - * SGI/IRIX already has a pgno_t. - */ -#ifdef __sgi -#define pgno_t db_pgno_t -#endif - -#define MAX_PAGE_NUMBER 0xffffffff /* >= # of pages in a file */ -typedef u_int32_t pgno_t; -#define MAX_PAGE_OFFSET 65535 /* >= # of bytes in a page */ -typedef u_int16_t indx_t; -#define MAX_REC_NUMBER 0xffffffff /* >= # of records in a tree */ -typedef u_int32_t recno_t; - -/* Key/data structure -- a Data-Base Thang. */ -typedef struct { - void *data; /* data */ - size_t size; /* data length */ -} DBT; - -/* Routine flags. */ -#define R_CURSOR 1 /* del, put, seq */ -#define __R_UNUSED 2 /* UNUSED */ -#define R_FIRST 3 /* seq */ -#define R_IAFTER 4 /* put (RECNO) */ -#define R_IBEFORE 5 /* put (RECNO) */ -#define R_LAST 6 /* seq (BTREE, RECNO) */ -#define R_NEXT 7 /* seq */ -#define R_NOOVERWRITE 8 /* put */ -#define R_PREV 9 /* seq (BTREE, RECNO) */ -#define R_SETCURSOR 10 /* put (RECNO) */ -#define R_RECNOSYNC 11 /* sync (RECNO) */ - -typedef enum { DB_BTREE, DB_HASH, DB_RECNO } DBTYPE; - -/* Access method description structure. */ -typedef struct __db { - DBTYPE type; /* Underlying db type. */ - int (*close) __P((struct __db *)); - int (*del) __P((const struct __db *, const DBT *, u_int)); - int (*get) __P((const struct __db *, const DBT *, DBT *, u_int)); - int (*put) __P((const struct __db *, DBT *, const DBT *, u_int)); - int (*seq) __P((const struct __db *, DBT *, DBT *, u_int)); - int (*sync) __P((const struct __db *, u_int)); - void *internal; /* Access method private. */ - int (*fd) __P((const struct __db *)); -} DB; - -#define BTREEMAGIC 0x053162 -#define BTREEVERSION 3 - -/* Structure used to pass parameters to the btree routines. */ -typedef struct { -#define R_DUP 0x01 /* duplicate keys */ - u_int32_t flags; - u_int32_t cachesize; /* bytes to cache */ - u_int32_t maxkeypage; /* maximum keys per page */ - u_int32_t minkeypage; /* minimum keys per page */ - u_int32_t psize; /* page size */ - int (*compare) /* comparison function */ - __P((const DBT *, const DBT *)); - size_t (*prefix) /* prefix function */ - __P((const DBT *, const DBT *)); - int lorder; /* byte order */ -} BTREEINFO; - -#define HASHMAGIC 0x061561 -#define HASHVERSION 2 - -/* Structure used to pass parameters to the hashing routines. */ -typedef struct { - u_int32_t bsize; /* bucket size */ - u_int32_t ffactor; /* fill factor */ - u_int32_t nelem; /* number of elements */ - u_int32_t cachesize; /* bytes to cache */ - u_int32_t /* hash function */ - (*hash) __P((const void *, size_t)); - int lorder; /* byte order */ -} HASHINFO; - -/* Structure used to pass parameters to the record routines. */ -typedef struct { -#define R_FIXEDLEN 0x01 /* fixed-length records */ -#define R_NOKEY 0x02 /* key not required */ -#define R_SNAPSHOT 0x04 /* snapshot the input */ - u_int32_t flags; - u_int32_t cachesize; /* bytes to cache */ - u_int32_t psize; /* page size */ - int lorder; /* byte order */ - size_t reclen; /* record length (fixed-length records) */ - u_char bval; /* delimiting byte (variable-length records */ - char *bfname; /* btree file name */ -} RECNOINFO; - -/* Re-define the user's dbopen calls. */ -#define dbopen __db185_open@DB_VERSION_UNIQUE_NAME@ - -#endif /* !_DB_185_H_ */ diff --git a/storage/bdb/dbinc/db_am.h b/storage/bdb/dbinc/db_am.h deleted file mode 100644 index d9d6c51700a..00000000000 --- a/storage/bdb/dbinc/db_am.h +++ /dev/null @@ -1,197 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_am.h,v 12.8 2005/09/28 17:44:24 margo Exp $ - */ -#ifndef _DB_AM_H_ -#define _DB_AM_H_ - -/* - * IS_ENV_AUTO_COMMIT -- - * Auto-commit test for enviroment operations: DbEnv::{open,remove,rename} - */ -#define IS_ENV_AUTO_COMMIT(dbenv, txn, flags) \ - (LF_ISSET(DB_AUTO_COMMIT) || \ - ((txn) == NULL && F_ISSET((dbenv), DB_ENV_AUTO_COMMIT) && \ - !LF_ISSET(DB_NO_AUTO_COMMIT))) - -/* - * IS_DB_AUTO_COMMIT -- - * Auto-commit test for database operations. - */ -#define IS_DB_AUTO_COMMIT(dbp, txn) \ - ((txn) == NULL && F_ISSET((dbp), DB_AM_TXN)) - -/* - * STRIP_AUTO_COMMIT -- - * Releases after 4.3 no longer requires DB operations to specify the - * AUTO_COMMIT flag, but the API continues to allow it to be specified. - */ -#define STRIP_AUTO_COMMIT(f) FLD_CLR((f), DB_AUTO_COMMIT) - -/* DB recovery operation codes. */ -#define DB_ADD_DUP 1 -#define DB_REM_DUP 2 -#define DB_ADD_BIG 3 -#define DB_REM_BIG 4 - -/* - * Standard initialization and shutdown macros for all recovery functions. - */ -#define REC_INTRO(func, inc_count, do_cursor) do { \ - argp = NULL; \ - file_dbp = NULL; \ - COMPQUIET(dbc, NULL); \ - /* mpf isn't used by all of the recovery functions. */ \ - COMPQUIET(mpf, NULL); \ - if ((ret = func(dbenv, dbtp->data, &argp)) != 0) \ - goto out; \ - if ((ret = __dbreg_id_to_db(dbenv, argp->txnid, \ - &file_dbp, argp->fileid, inc_count)) != 0) { \ - if (ret == DB_DELETED) { \ - ret = 0; \ - goto done; \ - } \ - goto out; \ - } \ - if (do_cursor) { \ - if ((ret = __db_cursor(file_dbp, NULL, &dbc, 0)) != 0) \ - goto out; \ - F_SET(dbc, DBC_RECOVER); \ - } \ - mpf = file_dbp->mpf; \ -} while (0) - -#define REC_CLOSE { \ - int __t_ret; \ - if (argp != NULL) \ - __os_free(dbenv, argp); \ - if (dbc != NULL && \ - (__t_ret = __db_c_close(dbc)) != 0 && ret == 0) \ - ret = __t_ret; \ - } \ - return (ret) - -/* - * No-op versions of the same macros. - */ -#define REC_NOOP_INTRO(func) do { \ - argp = NULL; \ - if ((ret = func(dbenv, dbtp->data, &argp)) != 0) \ - return (ret); \ -} while (0) -#define REC_NOOP_CLOSE \ - if (argp != NULL) \ - __os_free(dbenv, argp); \ - return (ret) - -/* - * Macro for reading pages during recovery. In most cases we - * want to avoid an error if the page is not found during rollback - * or if we are using truncate to remove pages from the file. - */ -#ifndef HAVE_FTRUNCATE -#define REC_FGET(mpf, pgno, pagep, cont) \ - if ((ret = __memp_fget(mpf, &(pgno), 0, pagep)) != 0) { \ - if (ret != DB_PAGE_NOTFOUND || DB_REDO(op)) { \ - ret = __db_pgerr(file_dbp, pgno, ret); \ - goto out; \ - } else \ - goto cont; \ - } -#else -#define REC_FGET(mpf, pgno, pagep, cont) \ - if ((ret = __memp_fget(mpf, &(pgno), 0, pagep)) != 0) { \ - if (ret != DB_PAGE_NOTFOUND) { \ - ret = __db_pgerr(file_dbp, pgno, ret); \ - goto out; \ - } else \ - goto cont; \ - } -#endif - -/* - * Standard debugging macro for all recovery functions. - */ -#ifdef DEBUG_RECOVER -#define REC_PRINT(func) \ - (void)func(dbenv, dbtp, lsnp, op, info); -#else -#define REC_PRINT(func) -#endif - -/* - * Actions to __db_lget - */ -#define LCK_ALWAYS 1 /* Lock even for off page dup cursors */ -#define LCK_COUPLE 2 /* Lock Couple */ -#define LCK_COUPLE_ALWAYS 3 /* Lock Couple even in txn. */ -#define LCK_DOWNGRADE 4 /* Downgrade the lock. (internal) */ -#define LCK_ROLLBACK 5 /* Lock even if in rollback */ - -/* - * If doing transactions we have to hold the locks associated with a data item - * from a page for the entire transaction. However, we don't have to hold the - * locks associated with walking the tree. Distinguish between the two so that - * we don't tie up the internal pages of the tree longer than necessary. - */ -#define __LPUT(dbc, lock) \ - __ENV_LPUT((dbc)->dbp->dbenv, lock) - -#define __ENV_LPUT(dbenv, lock) \ - (LOCK_ISSET(lock) ? __lock_put(dbenv, &(lock)) : 0) - -/* - * __TLPUT -- transactional lock put - * If the lock is valid then - * If we are not in a transaction put the lock. - * Else if the cursor is doing dirty reads and this was a read then - * put the lock. - * Else if the db is supporting dirty reads and this is a write then - * downgrade it. - * Else do nothing. - */ -#define __TLPUT(dbc, lock) \ - (LOCK_ISSET(lock) ? __db_lput(dbc, &(lock)) : 0) - -typedef struct { - DBC *dbc; - u_int32_t count; -} db_trunc_param; - -/* - * A database should be required to be readonly if it's been explicitly - * specified as such or if we're a client in a replicated environment and - * we don't have the special "client-writer" designation. - */ -#define DB_IS_READONLY(dbp) \ - (F_ISSET(dbp, DB_AM_RDONLY) || \ - (IS_REP_CLIENT((dbp)->dbenv) && \ - !F_ISSET((dbp), DB_AM_CL_WRITER))) - -/* - * For portability, primary keys that are record numbers are stored in - * secondaries in the same byte order as the secondary database. As a - * consequence, we need to swap the byte order of these keys before attempting - * to use them for lookups in the primary. We also need to swap user-supplied - * primary keys that are used in secondary lookups (for example, with the - * DB_GET_BOTH flag on a secondary get). - */ -#include "dbinc/db_swap.h" - -#define SWAP_IF_NEEDED(pdbp, sdbp, pkey) \ - do { \ - if (((pdbp)->type == DB_QUEUE || \ - (pdbp)->type == DB_RECNO) && \ - F_ISSET((sdbp), DB_AM_SWAP)) \ - P_32_SWAP((pkey)->data); \ - } while (0) - -#include "dbinc/db_dispatch.h" -#include "dbinc_auto/db_auto.h" -#include "dbinc_auto/crdel_auto.h" -#include "dbinc_auto/db_ext.h" -#endif /* !_DB_AM_H_ */ diff --git a/storage/bdb/dbinc/db_cxx.in b/storage/bdb/dbinc/db_cxx.in deleted file mode 100644 index b1a28d6f2bb..00000000000 --- a/storage/bdb/dbinc/db_cxx.in +++ /dev/null @@ -1,1147 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_cxx.in,v 12.13 2005/10/18 14:17:08 mjc Exp $ - */ - -#ifndef _DB_CXX_H_ -#define _DB_CXX_H_ -// -// C++ assumptions: -// -// To ensure portability to many platforms, both new and old, we make -// few assumptions about the C++ compiler and library. For example, -// we do not expect STL, templates or namespaces to be available. The -// "newest" C++ feature used is exceptions, which are used liberally -// to transmit error information. Even the use of exceptions can be -// disabled at runtime, to do so, use the DB_CXX_NO_EXCEPTIONS flags -// with the DbEnv or Db constructor. -// -// C++ naming conventions: -// -// - All top level class names start with Db. -// - All class members start with lower case letter. -// - All private data members are suffixed with underscore. -// - Use underscores to divide names into multiple words. -// - Simple data accessors are named with get_ or set_ prefix. -// - All method names are taken from names of functions in the C -// layer of db (usually by dropping a prefix like "db_"). -// These methods have the same argument types and order, -// other than dropping the explicit arg that acts as "this". -// -// As a rule, each DbFoo object has exactly one underlying DB_FOO struct -// (defined in db.h) associated with it. In some cases, we inherit directly -// from the DB_FOO structure to make this relationship explicit. Often, -// the underlying C layer allocates and deallocates these structures, so -// there is no easy way to add any data to the DbFoo class. When you see -// a comment about whether data is permitted to be added, this is what -// is going on. Of course, if we need to add data to such C++ classes -// in the future, we will arrange to have an indirect pointer to the -// DB_FOO struct (as some of the classes already have). -// - -//////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////// -// -// Forward declarations -// - -#include <stdarg.h> - -@cxx_have_stdheaders@ -#ifdef HAVE_CXX_STDHEADERS -#include <iostream> -#include <exception> -#define __DB_STD(x) std::x -#else -#include <iostream.h> -#include <exception.h> -#define __DB_STD(x) x -#endif - -#include "db.h" - -class Db; // forward -class Dbc; // forward -class DbEnv; // forward -class DbInfo; // forward -class DbLock; // forward -class DbLogc; // forward -class DbLsn; // forward -class DbMpoolFile; // forward -class DbPreplist; // forward -class Dbt; // forward -class DbTxn; // forward -class DbLock; // forward -class DbSequence; // forward -class Dbt; // forward - -class DbMultipleIterator; // forward -class DbMultipleKeyDataIterator; // forward -class DbMultipleRecnoDataIterator; // forward -class DbMultipleDataIterator; // forward - -class DbException; // forward -class DbDeadlockException; // forward -class DbLockNotGrantedException; // forward -class DbMemoryException; // forward -class DbRepHandleDeadException; // forward -class DbRunRecoveryException; // forward - -//////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////// -// -// Turn off inappropriate compiler warnings -// - -#ifdef _MSC_VER - -// These are level 4 warnings that are explicitly disabled. -// With Visual C++, by default you do not see above level 3 unless -// you use /W4. But we like to compile with the highest level -// warnings to catch other errors. -// -// 4201: nameless struct/union -// triggered by standard include file <winnt.h> -// -// 4514: unreferenced inline function has been removed -// certain include files in MSVC define methods that are not called -// -#pragma warning(disable: 4201 4514) - -#endif - -//////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////// -// -// Mechanisms for declaring classes -// - -// -// Every class defined in this file has an _exported next to the class name. -// This is needed for WinTel machines so that the class methods can -// be exported or imported in a DLL as appropriate. Users of the DLL -// use the define DB_USE_DLL. When the DLL is built, DB_CREATE_DLL -// must be defined. -// -#if defined(_MSC_VER) - -# if defined(DB_CREATE_DLL) -# define _exported __declspec(dllexport) // creator of dll -# elif defined(DB_USE_DLL) -# define _exported __declspec(dllimport) // user of dll -# else -# define _exported // static lib creator or user -# endif - -#else /* _MSC_VER */ - -# define _exported - -#endif /* _MSC_VER */ - -// Some interfaces can be customized by allowing users to define -// callback functions. For performance and logistical reasons, some -// callback functions must be declared in extern "C" blocks. For others, -// we allow you to declare the callbacks in C++ or C (or an extern "C" -// block) as you wish. See the set methods for the callbacks for -// the choices. -// -extern "C" { - typedef void * (*db_malloc_fcn_type) - (size_t); - typedef void * (*db_realloc_fcn_type) - (void *, size_t); - typedef void (*db_free_fcn_type) - (void *); - typedef int (*bt_compare_fcn_type) /*C++ version available*/ - (DB *, const DBT *, const DBT *); - typedef size_t (*bt_prefix_fcn_type) /*C++ version available*/ - (DB *, const DBT *, const DBT *); - typedef int (*dup_compare_fcn_type) /*C++ version available*/ - (DB *, const DBT *, const DBT *); - typedef u_int32_t (*h_hash_fcn_type) /*C++ version available*/ - (DB *, const void *, u_int32_t); - typedef int (*pgin_fcn_type) - (DB_ENV *dbenv, db_pgno_t pgno, void *pgaddr, DBT *pgcookie); - typedef int (*pgout_fcn_type) - (DB_ENV *dbenv, db_pgno_t pgno, void *pgaddr, DBT *pgcookie); -} - -// -// Represents a database table = a set of keys with associated values. -// -class _exported Db -{ - friend class DbEnv; - -public: - Db(DbEnv*, u_int32_t); // Create a Db object. - virtual ~Db(); // Calls close() if the user hasn't. - - // These methods exactly match those in the C interface. - // - virtual int associate(DbTxn *txn, Db *secondary, - int (*callback)(Db *, const Dbt *, const Dbt *, Dbt *), - u_int32_t flags); - virtual int close(u_int32_t flags); - virtual int compact(DbTxn *txnid, Dbt *start, Dbt *stop, - DB_COMPACT *c_data, u_int32_t flags, Dbt *end); - virtual int cursor(DbTxn *txnid, Dbc **cursorp, u_int32_t flags); - virtual int del(DbTxn *txnid, Dbt *key, u_int32_t flags); - virtual void err(int, const char *, ...); - virtual void errx(const char *, ...); - virtual int fd(int *fdp); - virtual int get(DbTxn *txnid, Dbt *key, Dbt *data, u_int32_t flags); - virtual void *get_app_private() const; - virtual int get_byteswapped(int *); - virtual int get_dbname(const char **, const char **); - virtual int get_open_flags(u_int32_t *); - virtual int get_type(DBTYPE *); - virtual int get_transactional(); - virtual int join(Dbc **curslist, Dbc **dbcp, u_int32_t flags); - virtual int key_range(DbTxn *, Dbt *, DB_KEY_RANGE *, u_int32_t); - virtual int open(DbTxn *txnid, - const char *, const char *subname, DBTYPE, u_int32_t, int); - virtual int pget(DbTxn *txnid, Dbt *key, Dbt *pkey, Dbt *data, - u_int32_t flags); - virtual int put(DbTxn *, Dbt *, Dbt *, u_int32_t); - virtual int remove(const char *, const char *, u_int32_t); - virtual int rename(const char *, const char *, const char *, u_int32_t); - virtual int set_alloc(db_malloc_fcn_type, db_realloc_fcn_type, - db_free_fcn_type); - virtual void set_app_private(void *); - virtual int set_append_recno(int (*)(Db *, Dbt *, db_recno_t)); - virtual int set_bt_compare(bt_compare_fcn_type); /*deprecated*/ - virtual int set_bt_compare(int (*)(Db *, const Dbt *, const Dbt *)); - virtual int get_bt_minkey(u_int32_t *); - virtual int set_bt_minkey(u_int32_t); - virtual int set_bt_prefix(bt_prefix_fcn_type); /*deprecated*/ - virtual int set_bt_prefix(size_t (*)(Db *, const Dbt *, const Dbt *)); - virtual int get_cachesize(u_int32_t *, u_int32_t *, int *); - virtual int set_cachesize(u_int32_t, u_int32_t, int); - virtual int set_dup_compare(dup_compare_fcn_type); /*deprecated*/ - virtual int set_dup_compare(int (*)(Db *, const Dbt *, const Dbt *)); - virtual int get_encrypt_flags(u_int32_t *); - virtual int set_encrypt(const char *, u_int32_t); - virtual void set_errcall( - void (*)(const DbEnv *, const char *, const char *)); - virtual void get_errfile(FILE **); - virtual void set_errfile(FILE *); - virtual void get_errpfx(const char **); - virtual void set_errpfx(const char *); - virtual int set_feedback(void (*)(Db *, int, int)); - virtual int get_flags(u_int32_t *); - virtual int set_flags(u_int32_t); - virtual int get_h_ffactor(u_int32_t *); - virtual int set_h_ffactor(u_int32_t); - virtual int set_h_hash(h_hash_fcn_type); /*deprecated*/ - virtual int set_h_hash(u_int32_t (*)(Db *, const void *, u_int32_t)); - virtual int get_h_nelem(u_int32_t *); - virtual int set_h_nelem(u_int32_t); - virtual int get_lorder(int *); - virtual int set_lorder(int); - virtual void set_msgcall(void (*)(const DbEnv *, const char *)); - virtual void get_msgfile(FILE **); - virtual void set_msgfile(FILE *); - virtual int get_pagesize(u_int32_t *); - virtual int set_pagesize(u_int32_t); - virtual int set_paniccall(void (*)(DbEnv *, int)); - virtual int get_re_delim(int *); - virtual int set_re_delim(int); - virtual int get_re_len(u_int32_t *); - virtual int set_re_len(u_int32_t); - virtual int get_re_pad(int *); - virtual int set_re_pad(int); - virtual int get_re_source(const char **); - virtual int set_re_source(const char *); - virtual int get_q_extentsize(u_int32_t *); - virtual int set_q_extentsize(u_int32_t); - virtual int stat(DbTxn *, void *sp, u_int32_t flags); - virtual int stat_print(u_int32_t flags); - virtual int sync(u_int32_t flags); - virtual int truncate(DbTxn *, u_int32_t *, u_int32_t); - virtual int upgrade(const char *name, u_int32_t flags); - virtual int verify(const char *, const char *, __DB_STD(ostream) *, - u_int32_t); - - // These additional methods are not in the C interface, and - // are only available for C++. - // - virtual __DB_STD(ostream) *get_error_stream(); - virtual void set_error_stream(__DB_STD(ostream) *); - virtual __DB_STD(ostream) *get_message_stream(); - virtual void set_message_stream(__DB_STD(ostream) *); - - virtual DbEnv *get_env(); - virtual DbMpoolFile *get_mpf(); - - virtual DB *get_DB() - { - return imp_; - } - - virtual const DB *get_const_DB() const - { - return imp_; - } - - static Db* get_Db(DB *db) - { - return (Db *)db->api_internal; - } - - static const Db* get_const_Db(const DB *db) - { - return (const Db *)db->api_internal; - } - -private: - // no copying - Db(const Db &); - Db &operator = (const Db &); - - void cleanup(); - int initialize(); - int error_policy(); - - // instance data - DB *imp_; - DbEnv *env_; - DbMpoolFile *mpf_; - int construct_error_; - u_int32_t flags_; - u_int32_t construct_flags_; - -public: - // These are public only because they need to be called - // via C callback functions. They should never be used by - // external users of this class. - // - int (*append_recno_callback_)(Db *, Dbt *, db_recno_t); - int (*associate_callback_)(Db *, const Dbt *, const Dbt *, Dbt *); - int (*bt_compare_callback_)(Db *, const Dbt *, const Dbt *); - size_t (*bt_prefix_callback_)(Db *, const Dbt *, const Dbt *); - int (*dup_compare_callback_)(Db *, const Dbt *, const Dbt *); - void (*feedback_callback_)(Db *, int, int); - u_int32_t (*h_hash_callback_)(Db *, const void *, u_int32_t); -}; - -// -// Cursor -// -class _exported Dbc : protected DBC -{ - friend class Db; - -public: - int close(); - int count(db_recno_t *countp, u_int32_t flags); - int del(u_int32_t flags); - int dup(Dbc** cursorp, u_int32_t flags); - int get(Dbt* key, Dbt *data, u_int32_t flags); - int pget(Dbt* key, Dbt* pkey, Dbt *data, u_int32_t flags); - int put(Dbt* key, Dbt *data, u_int32_t flags); - -private: - // No data is permitted in this class (see comment at top) - - // Note: use Db::cursor() to get pointers to a Dbc, - // and call Dbc::close() rather than delete to release them. - // - Dbc(); - ~Dbc(); - - // no copying - Dbc(const Dbc &); - Dbc &operator = (const Dbc &); -}; - -// -// Berkeley DB environment class. Provides functions for opening databases. -// User of this library can use this class as a starting point for -// developing a DB application - derive their application class from -// this one, add application control logic. -// -// Note that if you use the default constructor, you must explicitly -// call appinit() before any other db activity (e.g. opening files) -// -class _exported DbEnv -{ - friend class Db; - friend class DbLock; - friend class DbMpoolFile; - -public: - // After using this constructor, you can set any needed - // parameters for the environment using the set_* methods. - // Then call open() to finish initializing the environment - // and attaching it to underlying files. - // - DbEnv(u_int32_t flags); - - virtual ~DbEnv(); - - // These methods match those in the C interface. - // - virtual int close(u_int32_t); - virtual int dbremove(DbTxn *txn, const char *name, const char *subdb, - u_int32_t flags); - virtual int dbrename(DbTxn *txn, const char *name, const char *subdb, - const char *newname, u_int32_t flags); - virtual void err(int, const char *, ...); - virtual void errx(const char *, ...); - virtual int failchk(u_int32_t); - virtual int fileid_reset(const char *, u_int32_t); - virtual void *get_app_private() const; - virtual int get_home(const char **); - virtual int get_open_flags(u_int32_t *); - virtual int open(const char *, u_int32_t, int); - virtual int remove(const char *, u_int32_t); - virtual int stat_print(u_int32_t flags); - - virtual int set_alloc(db_malloc_fcn_type, db_realloc_fcn_type, - db_free_fcn_type); - virtual void set_app_private(void *); - virtual int get_cachesize(u_int32_t *, u_int32_t *, int *); - virtual int set_cachesize(u_int32_t, u_int32_t, int); - virtual int get_data_dirs(const char ***); - virtual int set_data_dir(const char *); - virtual int get_encrypt_flags(u_int32_t *); - virtual int set_intermediate_dir(int, u_int32_t); - virtual int set_isalive(int (*)(DbEnv *, pid_t, db_threadid_t)); - virtual int set_encrypt(const char *, u_int32_t); - virtual void set_errcall( - void (*)(const DbEnv *, const char *, const char *)); - virtual void get_errfile(FILE **); - virtual void set_errfile(FILE *); - virtual void get_errpfx(const char **); - virtual void set_errpfx(const char *); - virtual int get_flags(u_int32_t *); - virtual int set_flags(u_int32_t, int); - virtual bool is_bigendian(); - virtual int lsn_reset(const char *, u_int32_t); - virtual int set_feedback(void (*)(DbEnv *, int, int)); - virtual int get_lg_bsize(u_int32_t *); - virtual int set_lg_bsize(u_int32_t); - virtual int get_lg_dir(const char **); - virtual int set_lg_dir(const char *); - virtual int get_lg_filemode(int *); - virtual int set_lg_filemode(int); - virtual int get_lg_max(u_int32_t *); - virtual int set_lg_max(u_int32_t); - virtual int get_lg_regionmax(u_int32_t *); - virtual int set_lg_regionmax(u_int32_t); - virtual int get_lk_conflicts(const u_int8_t **, int *); - virtual int set_lk_conflicts(u_int8_t *, int); - virtual int get_lk_detect(u_int32_t *); - virtual int set_lk_detect(u_int32_t); - virtual int set_lk_max(u_int32_t); - virtual int get_lk_max_lockers(u_int32_t *); - virtual int set_lk_max_lockers(u_int32_t); - virtual int get_lk_max_locks(u_int32_t *); - virtual int set_lk_max_locks(u_int32_t); - virtual int get_lk_max_objects(u_int32_t *); - virtual int set_lk_max_objects(u_int32_t); - virtual int get_mp_mmapsize(size_t *); - virtual int set_mp_mmapsize(size_t); - virtual int get_mp_max_openfd(int *); - virtual int set_mp_max_openfd(int); - virtual int get_mp_max_write(int *, int *); - virtual int set_mp_max_write(int, int); - virtual void set_msgcall(void (*)(const DbEnv *, const char *)); - virtual void get_msgfile(FILE **); - virtual void set_msgfile(FILE *); - virtual int set_paniccall(void (*)(DbEnv *, int)); - virtual int set_rpc_server(void *, char *, long, long, u_int32_t); - virtual int get_shm_key(long *); - virtual int set_shm_key(long); - virtual int get_timeout(db_timeout_t *, u_int32_t); - virtual int set_timeout(db_timeout_t, u_int32_t); - virtual int get_tmp_dir(const char **); - virtual int set_tmp_dir(const char *); - virtual int get_tx_max(u_int32_t *); - virtual int set_tx_max(u_int32_t); - virtual int set_app_dispatch(int (*)(DbEnv *, - Dbt *, DbLsn *, db_recops)); - virtual int get_tx_timestamp(time_t *); - virtual int set_tx_timestamp(time_t *); - virtual int get_verbose(u_int32_t which, int *); - virtual int set_verbose(u_int32_t which, int); - - // Version information. A static method so it can be obtained anytime. - // - static char *version(int *major, int *minor, int *patch); - - // Convert DB errors to strings - static char *strerror(int); - - // If an error is detected and the error call function - // or stream is set, a message is dispatched or printed. - // If a prefix is set, each message is prefixed. - // - // You can use set_errcall() or set_errfile() above to control - // error functionality. Alternatively, you can call - // set_error_stream() to force all errors to a C++ stream. - // It is unwise to mix these approaches. - // - virtual __DB_STD(ostream) *get_error_stream(); - virtual void set_error_stream(__DB_STD(ostream) *); - virtual __DB_STD(ostream) *get_message_stream(); - virtual void set_message_stream(__DB_STD(ostream) *); - - // used internally - static void runtime_error(DbEnv *env, const char *caller, int err, - int error_policy); - static void runtime_error_dbt(DbEnv *env, const char *caller, Dbt *dbt, - int error_policy); - static void runtime_error_lock_get(DbEnv *env, const char *caller, - int err, db_lockop_t op, db_lockmode_t mode, - const Dbt *obj, DbLock lock, int index, - int error_policy); - - // Lock functions - // - virtual int lock_detect(u_int32_t flags, u_int32_t atype, int *aborted); - virtual int lock_get(u_int32_t locker, u_int32_t flags, const Dbt *obj, - db_lockmode_t lock_mode, DbLock *lock); - virtual int lock_id(u_int32_t *idp); - virtual int lock_id_free(u_int32_t id); - virtual int lock_put(DbLock *lock); - virtual int lock_stat(DB_LOCK_STAT **statp, u_int32_t flags); - virtual int lock_stat_print(u_int32_t flags); - virtual int lock_vec(u_int32_t locker, u_int32_t flags, - DB_LOCKREQ list[], int nlist, DB_LOCKREQ **elistp); - - // Log functions - // - virtual int log_archive(char **list[], u_int32_t flags); - static int log_compare(const DbLsn *lsn0, const DbLsn *lsn1); - virtual int log_cursor(DbLogc **cursorp, u_int32_t flags); - virtual int log_file(DbLsn *lsn, char *namep, size_t len); - virtual int log_flush(const DbLsn *lsn); - virtual int log_put(DbLsn *lsn, const Dbt *data, u_int32_t flags); - virtual int log_printf(DbTxn *, const char *, ...); - - virtual int log_stat(DB_LOG_STAT **spp, u_int32_t flags); - virtual int log_stat_print(u_int32_t flags); - - // Mpool functions - // - virtual int memp_fcreate(DbMpoolFile **dbmfp, u_int32_t flags); - virtual int memp_register(int ftype, - pgin_fcn_type pgin_fcn, - pgout_fcn_type pgout_fcn); - virtual int memp_stat(DB_MPOOL_STAT - **gsp, DB_MPOOL_FSTAT ***fsp, u_int32_t flags); - virtual int memp_stat_print(u_int32_t flags); - virtual int memp_sync(DbLsn *lsn); - virtual int memp_trickle(int pct, int *nwrotep); - - // Mpool functions - // - virtual int mutex_alloc(u_int32_t, db_mutex_t *); - virtual int mutex_free(db_mutex_t); - virtual int mutex_get_align(u_int32_t *); - virtual int mutex_get_increment(u_int32_t *); - virtual int mutex_get_max(u_int32_t *); - virtual int mutex_get_tas_spins(u_int32_t *); - virtual int mutex_lock(db_mutex_t); - virtual int mutex_set_align(u_int32_t); - virtual int mutex_set_increment(u_int32_t); - virtual int mutex_set_max(u_int32_t); - virtual int mutex_set_tas_spins(u_int32_t); - virtual int mutex_stat(DB_MUTEX_STAT **, u_int32_t); - virtual int mutex_stat_print(u_int32_t); - virtual int mutex_unlock(db_mutex_t); - - // Transaction functions - // - virtual int txn_begin(DbTxn *pid, DbTxn **tid, u_int32_t flags); - virtual int txn_checkpoint(u_int32_t kbyte, u_int32_t min, - u_int32_t flags); - virtual int txn_recover(DbPreplist *preplist, long count, - long *retp, u_int32_t flags); - virtual int txn_stat(DB_TXN_STAT **statp, u_int32_t flags); - virtual int txn_stat_print(u_int32_t flags); - - // Replication functions - // - virtual int rep_elect(int, int, int, u_int32_t, int *, u_int32_t); - virtual int rep_flush(); - virtual int rep_process_message(Dbt *, Dbt *, int *, DbLsn *); - virtual int rep_start(Dbt *, u_int32_t); - virtual int rep_stat(DB_REP_STAT **statp, u_int32_t flags); - virtual int rep_stat_print(u_int32_t flags); - virtual int get_rep_limit(u_int32_t *, u_int32_t *); - virtual int set_rep_limit(u_int32_t, u_int32_t); - virtual int set_rep_transport(int, int (*)(DbEnv *, - const Dbt *, const Dbt *, const DbLsn *, int, u_int32_t)); - virtual int set_rep_request(u_int32_t, u_int32_t); - virtual int set_thread_count(u_int32_t); - virtual int set_thread_id(void (*)(DbEnv *, pid_t *, db_threadid_t *)); - virtual int set_thread_id_string(char *(*)(DbEnv *, pid_t, db_threadid_t, char *)); - virtual int rep_set_config(u_int32_t which, int onoff); - virtual int rep_get_config(u_int32_t which, int *onoffp); - virtual int rep_sync(u_int32_t flags); - - // Conversion functions - // - virtual DB_ENV *get_DB_ENV() - { - return imp_; - } - - virtual const DB_ENV *get_const_DB_ENV() const - { - return imp_; - } - - static DbEnv* get_DbEnv(DB_ENV *dbenv) - { - return dbenv ? (DbEnv *)dbenv->api1_internal : 0; - } - - static const DbEnv* get_const_DbEnv(const DB_ENV *dbenv) - { - return dbenv ? (const DbEnv *)dbenv->api1_internal : 0; - } - - // For internal use only. - static DbEnv* wrap_DB_ENV(DB_ENV *dbenv); - - // These are public only because they need to be called - // via C functions. They should never be called by users - // of this class. - // - static int _app_dispatch_intercept(DB_ENV *env, DBT *dbt, DB_LSN *lsn, - db_recops op); - static void _paniccall_intercept(DB_ENV *env, int errval); - static void _feedback_intercept(DB_ENV *env, int opcode, int pct); - static int _isalive_intercept(DB_ENV *env, pid_t pid, - db_threadid_t thrid); - static int _rep_send_intercept(DB_ENV *env, const DBT *cntrl, - const DBT *data, const DB_LSN *lsn, int id, u_int32_t flags); - static void _stream_error_function(const DB_ENV *env, - const char *prefix, const char *message); - static void _stream_message_function(const DB_ENV *env, - const char *message); - static void _thread_id_intercept(DB_ENV *env, pid_t *pidp, - db_threadid_t *thridp); - static char *_thread_id_string_intercept(DB_ENV *env, pid_t pid, - db_threadid_t thrid, char *buf); - -private: - void cleanup(); - int initialize(DB_ENV *env); - int error_policy(); - - // For internal use only. - DbEnv(DB_ENV *, u_int32_t flags); - - // no copying - DbEnv(const DbEnv &); - void operator = (const DbEnv &); - - // instance data - DB_ENV *imp_; - int construct_error_; - u_int32_t construct_flags_; - __DB_STD(ostream) *error_stream_; - __DB_STD(ostream) *message_stream_; - - int (*app_dispatch_callback_)(DbEnv *, Dbt *, DbLsn *, db_recops); - int (*isalive_callback_)(DbEnv *, pid_t, db_threadid_t); - void (*error_callback_)(const DbEnv *, const char *, const char *); - void (*feedback_callback_)(DbEnv *, int, int); - void (*message_callback_)(const DbEnv *, const char *); - void (*paniccall_callback_)(DbEnv *, int); - int (*rep_send_callback_)(DbEnv *, const Dbt *, const Dbt *, - const DbLsn *, int, u_int32_t); - void (*thread_id_callback_)(DbEnv *, pid_t *, db_threadid_t *); - char *(*thread_id_string_callback_)(DbEnv *, pid_t, db_threadid_t, - char *); -}; - -// -// Lock -// -class _exported DbLock -{ - friend class DbEnv; - -public: - DbLock(); - DbLock(const DbLock &); - DbLock &operator = (const DbLock &); - -protected: - // We can add data to this class if needed - // since its contained class is not allocated by db. - // (see comment at top) - - DbLock(DB_LOCK); - DB_LOCK lock_; -}; - -// -// Log cursor -// -class _exported DbLogc : protected DB_LOGC -{ - friend class DbEnv; - -public: - int close(u_int32_t _flags); - int get(DbLsn *lsn, Dbt *data, u_int32_t _flags); - -private: - // No data is permitted in this class (see comment at top) - - // Note: use Db::cursor() to get pointers to a Dbc, - // and call Dbc::close() rather than delete to release them. - // - DbLogc(); - ~DbLogc(); - - // no copying - DbLogc(const Dbc &); - DbLogc &operator = (const Dbc &); -}; - -// -// Log sequence number -// -class _exported DbLsn : public DB_LSN -{ - friend class DbEnv; // friendship needed to cast to base class - friend class DbLogc; // friendship needed to cast to base class -}; - -// -// Memory pool file -// -class _exported DbMpoolFile -{ - friend class DbEnv; - friend class Db; - -public: - int close(u_int32_t flags); - int get(db_pgno_t *pgnoaddr, u_int32_t flags, void *pagep); - int open(const char *file, u_int32_t flags, int mode, size_t pagesize); - int get_transactional(void); - int put(void *pgaddr, u_int32_t flags); - int set(void *pgaddr, u_int32_t flags); - int get_clear_len(u_int32_t *len); - int set_clear_len(u_int32_t len); - int get_fileid(u_int8_t *fileid); - int set_fileid(u_int8_t *fileid); - int get_flags(u_int32_t *flagsp); - int set_flags(u_int32_t flags, int onoff); - int get_ftype(int *ftype); - int set_ftype(int ftype); - int get_lsn_offset(int32_t *offsetp); - int set_lsn_offset(int32_t offset); - int get_maxsize(u_int32_t *gbytes, u_int32_t *bytes); - int set_maxsize(u_int32_t gbytes, u_int32_t bytes); - int get_pgcookie(DBT *dbt); - int set_pgcookie(DBT *dbt); - int get_priority(DB_CACHE_PRIORITY *priorityp); - int set_priority(DB_CACHE_PRIORITY priority); - int sync(); - - virtual DB_MPOOLFILE *get_DB_MPOOLFILE() - { - return imp_; - } - - virtual const DB_MPOOLFILE *get_const_DB_MPOOLFILE() const - { - return imp_; - } - -private: - DB_MPOOLFILE *imp_; - - // We can add data to this class if needed - // since it is implemented via a pointer. - // (see comment at top) - - // Note: use DbEnv::memp_fcreate() to get pointers to a DbMpoolFile, - // and call DbMpoolFile::close() rather than delete to release them. - // - DbMpoolFile(); - - // Shut g++ up. -protected: - virtual ~DbMpoolFile(); - -private: - // no copying - DbMpoolFile(const DbMpoolFile &); - void operator = (const DbMpoolFile &); -}; - -// -// This is filled in and returned by the DbEnv::txn_recover() method. -// -class _exported DbPreplist -{ -public: - DbTxn *txn; - u_int8_t gid[DB_XIDDATASIZE]; -}; - -// -// A sequence record in a database -// -class _exported DbSequence -{ -public: - DbSequence(Db *db, u_int32_t flags); - virtual ~DbSequence(); - - int open(DbTxn *txnid, Dbt *key, u_int32_t flags); - int initial_value(db_seq_t value); - int close(u_int32_t flags); - int remove(DbTxn *txnid, u_int32_t flags); - int stat(DB_SEQUENCE_STAT **sp, u_int32_t flags); - int stat_print(u_int32_t flags); - - int get(DbTxn *txnid, int32_t delta, db_seq_t *retp, u_int32_t flags); - int get_cachesize(int32_t *sizep); - int set_cachesize(int32_t size); - int get_flags(u_int32_t *flagsp); - int set_flags(u_int32_t flags); - int get_range(db_seq_t *minp, db_seq_t *maxp); - int set_range(db_seq_t min, db_seq_t max); - - Db *get_db(); - Dbt *get_key(); - - virtual DB_SEQUENCE *get_DB_SEQUENCE() - { - return imp_; - } - - virtual const DB_SEQUENCE *get_const_DB_SEQUENCE() const - { - return imp_; - } - - static DbSequence* get_DbSequence(DB_SEQUENCE *seq) - { - return (DbSequence *)seq->api_internal; - } - - static const DbSequence* get_const_DbSequence(const DB_SEQUENCE *seq) - { - return (const DbSequence *)seq->api_internal; - } - - // For internal use only. - static DbSequence* wrap_DB_SEQUENCE(DB_SEQUENCE *seq); - -private: - DbSequence(DB_SEQUENCE *seq); - // no copying - DbSequence(const DbSequence &); - DbSequence &operator = (const DbSequence &); - - DB_SEQUENCE *imp_; - DBT key_; -}; - -// -// Transaction -// -class _exported DbTxn -{ - friend class DbEnv; - -public: - int abort(); - int commit(u_int32_t flags); - int discard(u_int32_t flags); - u_int32_t id(); - int get_name(const char **namep); - int prepare(u_int8_t *gid); - int set_name(const char *name); - int set_timeout(db_timeout_t timeout, u_int32_t flags); - - virtual DB_TXN *get_DB_TXN() - { - return imp_; - } - - virtual const DB_TXN *get_const_DB_TXN() const - { - return imp_; - } - - static DbTxn* get_DbTxn(DB_TXN *txn) - { - return (DbTxn *)txn->api_internal; - } - - static const DbTxn* get_const_DbTxn(const DB_TXN *txn) - { - return (const DbTxn *)txn->api_internal; - } - - // For internal use only. - static DbTxn* wrap_DB_TXN(DB_TXN *txn); - -private: - DB_TXN *imp_; - - // We can add data to this class if needed - // since it is implemented via a pointer. - // (see comment at top) - - // Note: use DbEnv::txn_begin() to get pointers to a DbTxn, - // and call DbTxn::abort() or DbTxn::commit rather than - // delete to release them. - // - DbTxn(); - // For internal use only. - DbTxn(DB_TXN *txn); - virtual ~DbTxn(); - - // no copying - DbTxn(const DbTxn &); - void operator = (const DbTxn &); -}; - -// -// A chunk of data, maybe a key or value. -// -class _exported Dbt : private DBT -{ - friend class Db; - friend class Dbc; - friend class DbEnv; - friend class DbLogc; - friend class DbSequence; - -public: - // key/data - void *get_data() const { return data; } - void set_data(void *value) { data = value; } - - // key/data length - u_int32_t get_size() const { return size; } - void set_size(u_int32_t value) { size = value; } - - // RO: length of user buffer. - u_int32_t get_ulen() const { return ulen; } - void set_ulen(u_int32_t value) { ulen = value; } - - // RO: get/put record length. - u_int32_t get_dlen() const { return dlen; } - void set_dlen(u_int32_t value) { dlen = value; } - - // RO: get/put record offset. - u_int32_t get_doff() const { return doff; } - void set_doff(u_int32_t value) { doff = value; } - - // flags - u_int32_t get_flags() const { return flags; } - void set_flags(u_int32_t value) { flags = value; } - - // Conversion functions - DBT *get_DBT() { return (DBT *)this; } - const DBT *get_const_DBT() const { return (const DBT *)this; } - - static Dbt* get_Dbt(DBT *dbt) { return (Dbt *)dbt; } - static const Dbt* get_const_Dbt(const DBT *dbt) - { return (const Dbt *)dbt; } - - Dbt(void *data, u_int32_t size); - Dbt(); - ~Dbt(); - Dbt(const Dbt &); - Dbt &operator = (const Dbt &); - -private: - // Note: no extra data appears in this class (other than - // inherited from DBT) since we need DBT and Dbt objects - // to have interchangable pointers. - // - // When subclassing this class, remember that callback - // methods like bt_compare, bt_prefix, dup_compare may - // internally manufacture DBT objects (which later are - // cast to Dbt), so such callbacks might receive objects - // not of your subclassed type. -}; - -//////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////// -// -// multiple key/data/reco iterator classes -// - -// DbMultipleIterator is a shared private base class for the three types -// of bulk-return Iterator; it should never be instantiated directly, -// but it handles the functionality shared by its subclasses. -class _exported DbMultipleIterator -{ -public: - DbMultipleIterator(const Dbt &dbt); -protected: - u_int8_t *data_; - u_int32_t *p_; -}; - -class _exported DbMultipleKeyDataIterator : private DbMultipleIterator -{ -public: - DbMultipleKeyDataIterator(const Dbt &dbt) : DbMultipleIterator(dbt) {} - bool next(Dbt &key, Dbt &data); -}; - -class _exported DbMultipleRecnoDataIterator : private DbMultipleIterator -{ -public: - DbMultipleRecnoDataIterator(const Dbt &dbt) : DbMultipleIterator(dbt) {} - bool next(db_recno_t &recno, Dbt &data); -}; - -class _exported DbMultipleDataIterator : private DbMultipleIterator -{ -public: - DbMultipleDataIterator(const Dbt &dbt) : DbMultipleIterator(dbt) {} - bool next(Dbt &data); -}; - -//////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////// -// -// Exception classes -// - -// Almost any error in the DB library throws a DbException. -// Every exception should be considered an abnormality -// (e.g. bug, misuse of DB, file system error). -// -class _exported DbException : public __DB_STD(exception) -{ -public: - virtual ~DbException() throw(); - DbException(int err); - DbException(const char *description); - DbException(const char *description, int err); - DbException(const char *prefix, const char *description, int err); - int get_errno() const; - virtual const char *what() const throw(); - DbEnv *get_env() const; - void set_env(DbEnv *env); - - DbException(const DbException &); - DbException &operator = (const DbException &); - -private: - void describe(const char *prefix, const char *description); - - char *what_; - int err_; // errno - DbEnv *env_; -}; - -// -// A specific sort of exception that occurs when -// an operation is aborted to resolve a deadlock. -// -class _exported DbDeadlockException : public DbException -{ -public: - virtual ~DbDeadlockException() throw(); - DbDeadlockException(const char *description); - - DbDeadlockException(const DbDeadlockException &); - DbDeadlockException &operator = (const DbDeadlockException &); -}; - -// -// A specific sort of exception that occurs when -// a lock is not granted, e.g. by lock_get or lock_vec. -// Note that the Dbt is only live as long as the Dbt used -// in the offending call. -// -class _exported DbLockNotGrantedException : public DbException -{ -public: - virtual ~DbLockNotGrantedException() throw(); - DbLockNotGrantedException(const char *prefix, db_lockop_t op, - db_lockmode_t mode, const Dbt *obj, const DbLock lock, int index); - DbLockNotGrantedException(const char *description); - - DbLockNotGrantedException(const DbLockNotGrantedException &); - DbLockNotGrantedException &operator = - (const DbLockNotGrantedException &); - - db_lockop_t get_op() const; - db_lockmode_t get_mode() const; - const Dbt* get_obj() const; - DbLock *get_lock() const; - int get_index() const; - -private: - db_lockop_t op_; - db_lockmode_t mode_; - const Dbt *obj_; - DbLock *lock_; - int index_; -}; - -// -// A specific sort of exception that occurs when -// user declared memory is insufficient in a Dbt. -// -class _exported DbMemoryException : public DbException -{ -public: - virtual ~DbMemoryException() throw(); - DbMemoryException(Dbt *dbt); - DbMemoryException(const char *prefix, Dbt *dbt); - - DbMemoryException(const DbMemoryException &); - DbMemoryException &operator = (const DbMemoryException &); - - Dbt *get_dbt() const; -private: - Dbt *dbt_; -}; - -// -// A specific sort of exception that occurs when a change of replication -// master requires that all handles be re-opened. -// -class _exported DbRepHandleDeadException : public DbException -{ -public: - virtual ~DbRepHandleDeadException() throw(); - DbRepHandleDeadException(const char *description); - - DbRepHandleDeadException(const DbRepHandleDeadException &); - DbRepHandleDeadException &operator = (const DbRepHandleDeadException &); -}; - -// -// A specific sort of exception that occurs when -// recovery is required before continuing DB activity. -// -class _exported DbRunRecoveryException : public DbException -{ -public: - virtual ~DbRunRecoveryException() throw(); - DbRunRecoveryException(const char *description); - - DbRunRecoveryException(const DbRunRecoveryException &); - DbRunRecoveryException &operator = (const DbRunRecoveryException &); -}; -#endif /* !_DB_CXX_H_ */ diff --git a/storage/bdb/dbinc/db_dispatch.h b/storage/bdb/dbinc/db_dispatch.h deleted file mode 100644 index eee9c59d2a8..00000000000 --- a/storage/bdb/dbinc/db_dispatch.h +++ /dev/null @@ -1,109 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1995, 1996 - * The President and Fellows of Harvard University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: db_dispatch.h,v 12.5 2005/10/19 15:10:44 bostic Exp $ - */ - -#ifndef _DB_DISPATCH_H_ -#define _DB_DISPATCH_H_ - -/* - * Declarations and typedefs for the list of transaction IDs used during - * recovery. This is a generic list used to pass along whatever information - * we need during recovery. - */ -typedef enum { - TXNLIST_DELETE, - TXNLIST_LSN, - TXNLIST_PGNO, - TXNLIST_TXNID -} db_txnlist_type; - -#define DB_TXNLIST_MASK(hp, n) (n % hp->nslots) -struct __db_txnhead { - u_int32_t maxid; /* Maximum transaction id. */ - DB_LSN maxlsn; /* Maximum commit lsn. */ - DB_LSN ckplsn; /* LSN of last retained checkpoint. */ - DB_LSN trunc_lsn; /* Lsn to which we are going to truncate; - * make sure we abort anyone after this. */ - u_int32_t generation; /* Current generation number. */ - u_int32_t gen_alloc; /* Number of generations allocated. */ - struct { - u_int32_t generation; - u_int32_t txn_min; - u_int32_t txn_max; - } *gen_array; /* Array of txnids associated with a gen. */ - u_int nslots; - LIST_HEAD(__db_headlink, __db_txnlist) head[1]; -}; - -#define DB_LSN_STACK_SIZE 4 -struct __db_txnlist { - db_txnlist_type type; - LIST_ENTRY(__db_txnlist) links; - union { - struct { - u_int32_t txnid; - u_int32_t generation; - u_int32_t status; - } t; - struct { - u_int32_t stack_size; - u_int32_t stack_indx; - DB_LSN *lsn_stack; - } l; - struct { - u_int32_t nentries; - u_int32_t maxentry; - int32_t locked; - char *fname; - int32_t fileid; - db_pgno_t *pgno_array; - u_int8_t uid[DB_FILE_ID_LEN]; - } p; - } u; -}; - -/* - * States for limbo list processing. - */ -typedef enum { - LIMBO_NORMAL, /* Normal processing. */ - LIMBO_PREPARE, /* We are preparing a transaction. */ - LIMBO_RECOVER, /* We are in recovery. */ - LIMBO_TIMESTAMP, /* We are recovering to a timestamp. */ - LIMBO_COMPENSATE /* After recover to ts, generate log records. */ -} db_limbo_state; - -#endif /* !_DB_DISPATCH_H_ */ diff --git a/storage/bdb/dbinc/db_int.in b/storage/bdb/dbinc/db_int.in deleted file mode 100644 index 55be4366326..00000000000 --- a/storage/bdb/dbinc/db_int.in +++ /dev/null @@ -1,670 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_int.in,v 12.15 2005/11/03 17:46:08 bostic Exp $ - */ - -#ifndef _DB_INTERNAL_H_ -#define _DB_INTERNAL_H_ - -/******************************************************* - * System includes, db.h, a few general DB includes. The DB includes are - * here because it's OK if db_int.h includes queue structure declarations. - *******************************************************/ -#ifndef NO_SYSTEM_INCLUDES -#if defined(STDC_HEADERS) || defined(__cplusplus) -#include <stdarg.h> -#else -#include <varargs.h> -#endif -#include <errno.h> -#endif - -#include "db.h" - -#include "dbinc/queue.h" -#include "dbinc/shqueue.h" - -#if defined(__cplusplus) -extern "C" { -#endif - -/******************************************************* - * General purpose constants and macros. - *******************************************************/ -#ifndef UINT16_MAX -#define UINT16_MAX 65535 /* Maximum 16-bit unsigned. */ -#endif -#ifndef UINT32_MAX -#ifdef __STDC__ -#define UINT32_MAX 4294967295U /* Maximum 32-bit unsigned. */ -#else -#define UINT32_MAX 0xffffffff /* Maximum 32-bit unsigned. */ -#endif -#endif - -#if defined(HAVE_64BIT_TYPES) -#undef INT64_MAX -#undef INT64_MIN -#undef UINT64_MAX - -#ifdef DB_WIN32 -#define INT64_MAX _I64_MAX -#define INT64_MIN _I64_MIN -#define UINT64_MAX _UI64_MAX - -#define INT64_FMT "%l64d" -#define UINT64_FMT "%l64u" -#else -/* - * Override the system's 64-bit min/max constants. AIX's 32-bit compiler can - * handle 64-bit values, but the system's constants don't include the LL/ULL - * suffix, and so can't be compiled using the 32-bit compiler. - */ -#define INT64_MAX 9223372036854775807LL -#define INT64_MIN (-INT64_MAX-1) -#define UINT64_MAX 18446744073709551615ULL - -@INT64_FMT@ -@UINT64_FMT@ -#endif /* DB_WIN32 */ -#endif /* HAVE_LONG_LONG && HAVE_UNSIGNED_LONG_LONG */ - -#define MEGABYTE 1048576 -#define GIGABYTE 1073741824 - -#define MS_PER_SEC 1000 /* Milliseconds in a second. */ -#define USEC_PER_MS 1000 /* Microseconds in a millisecond. */ - -#define RECNO_OOB 0 /* Illegal record number. */ - -/* Test for a power-of-two (tests true for zero, which doesn't matter here). */ -#define POWER_OF_TWO(x) (((x) & ((x) - 1)) == 0) - -/* Test for valid page sizes. */ -#define DB_MIN_PGSIZE 0x000200 /* Minimum page size (512). */ -#define DB_MAX_PGSIZE 0x010000 /* Maximum page size (65536). */ -#define IS_VALID_PAGESIZE(x) \ - (POWER_OF_TWO(x) && (x) >= DB_MIN_PGSIZE && ((x) <= DB_MAX_PGSIZE)) - -/* Minimum number of pages cached, by default. */ -#define DB_MINPAGECACHE 16 - -/* - * If we are unable to determine the underlying filesystem block size, use - * 8K on the grounds that most OS's use less than 8K for a VM page size. - */ -#define DB_DEF_IOSIZE (8 * 1024) - -/* Align an integer to a specific boundary. */ -#undef DB_ALIGN -#define DB_ALIGN(v, bound) \ - (((v) + (bound) - 1) & ~(((uintmax_t)(bound)) - 1)) - -/* Increment a pointer to a specific boundary. */ -#undef ALIGNP_INC -#define ALIGNP_INC(p, bound) \ - (void *)(((uintptr_t)(p) + (bound) - 1) & ~(((uintptr_t)(bound)) - 1)) - -/* Decrement a pointer to a specific boundary. */ -#undef ALIGNP_DEC -#define ALIGNP_DEC(p, bound) \ - (void *)((uintptr_t)(p) & ~(((uintptr_t)(bound)) - 1)) - -/* - * Print an address as a u_long (a u_long is the largest type we can print - * portably). Most 64-bit systems have made longs 64-bits, so this should - * work. - */ -#define P_TO_ULONG(p) ((u_long)(uintptr_t)(p)) - -/* - * Convert a pointer to a small integral value. - * - * The (u_int16_t)(uintptr_t) cast avoids warnings: the (uintptr_t) cast - * converts the value to an integral type, and the (u_int16_t) cast converts - * it to a small integral type so we don't get complaints when we assign the - * final result to an integral type smaller than uintptr_t. - */ -#define P_TO_UINT32(p) ((u_int32_t)(uintptr_t)(p)) -#define P_TO_UINT16(p) ((u_int16_t)(uintptr_t)(p)) - -/* - * There are several on-page structures that are declared to have a number of - * fields followed by a variable length array of items. The structure size - * without including the variable length array or the address of the first of - * those elements can be found using SSZ. - * - * This macro can also be used to find the offset of a structure element in a - * structure. This is used in various places to copy structure elements from - * unaligned memory references, e.g., pointers into a packed page. - * - * There are two versions because compilers object if you take the address of - * an array. - */ -#undef SSZ -#define SSZ(name, field) P_TO_UINT16(&(((name *)0)->field)) - -#undef SSZA -#define SSZA(name, field) P_TO_UINT16(&(((name *)0)->field[0])) - -/* Structure used to print flag values. */ -typedef struct __fn { - u_int32_t mask; /* Flag value. */ - const char *name; /* Flag name. */ -} FN; - -/* Set, clear and test flags. */ -#define FLD_CLR(fld, f) (fld) &= ~(f) -#define FLD_ISSET(fld, f) ((fld) & (f)) -#define FLD_SET(fld, f) (fld) |= (f) -#define F_CLR(p, f) (p)->flags &= ~(f) -#define F_ISSET(p, f) ((p)->flags & (f)) -#define F_SET(p, f) (p)->flags |= (f) -#define LF_CLR(f) ((flags) &= ~(f)) -#define LF_ISSET(f) ((flags) & (f)) -#define LF_SET(f) ((flags) |= (f)) - -/* - * Calculate a percentage. The values can overflow 32-bit integer arithmetic - * so we use floating point. - * - * When calculating a bytes-vs-page size percentage, we're getting the inverse - * of the percentage in all cases, that is, we want 100 minus the percentage we - * calculate. - */ -#define DB_PCT(v, total) \ - ((int)((total) == 0 ? 0 : ((double)(v) * 100) / (total))) -#define DB_PCT_PG(v, total, pgsize) \ - ((int)((total) == 0 ? 0 : \ - 100 - ((double)(v) * 100) / (((double)total) * (pgsize)))) - -/* - * Structure used for callback message aggregation. - * - * Display values in XXX_stat_print calls. - */ -typedef struct __db_msgbuf { - char *buf; /* Heap allocated buffer. */ - char *cur; /* Current end of message. */ - size_t len; /* Allocated length of buffer. */ -} DB_MSGBUF; -#define DB_MSGBUF_INIT(a) do { \ - (a)->buf = (a)->cur = NULL; \ - (a)->len = 0; \ -} while (0) -#define DB_MSGBUF_FLUSH(dbenv, a) do { \ - if ((a)->buf != NULL) { \ - if ((a)->cur != (a)->buf) \ - __db_msg(dbenv, "%s", (a)->buf); \ - __os_free(dbenv, (a)->buf); \ - DB_MSGBUF_INIT(a); \ - } \ -} while (0) -#define STAT_FMT(msg, fmt, type, v) do { \ - DB_MSGBUF __mb; \ - DB_MSGBUF_INIT(&__mb); \ - __db_msgadd(dbenv, &__mb, fmt, (type)(v)); \ - __db_msgadd(dbenv, &__mb, "\t%s", msg); \ - DB_MSGBUF_FLUSH(dbenv, &__mb); \ -} while (0) -#define STAT_HEX(msg, v) \ - __db_msg(dbenv, "%#lx\t%s", (u_long)(v), msg) -#define STAT_ISSET(msg, p) \ - __db_msg(dbenv, "%sSet\t%s", (p) == NULL ? "!" : " ", msg) -#define STAT_LONG(msg, v) \ - __db_msg(dbenv, "%ld\t%s", (long)(v), msg) -#define STAT_LSN(msg, lsnp) \ - __db_msg(dbenv, "%lu/%lu\t%s", \ - (u_long)(lsnp)->file, (u_long)(lsnp)->offset, msg) -#define STAT_POINTER(msg, v) \ - __db_msg(dbenv, "%#lx\t%s", P_TO_ULONG(v), msg) -#define STAT_STRING(msg, p) do { \ - const char *__p = p; /* p may be a function call. */ \ - __db_msg(dbenv, "%s\t%s", __p == NULL ? "!Set" : __p, msg); \ -} while (0) -#define STAT_ULONG(msg, v) \ - __db_msg(dbenv, "%lu\t%s", (u_long)(v), msg) - -/******************************************************* - * API return values - *******************************************************/ -/* - * Return values that are OK for each different call. Most calls have a - * standard 'return of 0 is only OK value', but some, like db->get have - * DB_NOTFOUND as a return value, but it really isn't an error. - */ -#define DB_RETOK_STD(ret) ((ret) == 0) -#define DB_RETOK_DBCDEL(ret) ((ret) == 0 || (ret) == DB_KEYEMPTY || \ - (ret) == DB_NOTFOUND) -#define DB_RETOK_DBCGET(ret) ((ret) == 0 || (ret) == DB_KEYEMPTY || \ - (ret) == DB_NOTFOUND) -#define DB_RETOK_DBCPUT(ret) ((ret) == 0 || (ret) == DB_KEYEXIST || \ - (ret) == DB_NOTFOUND) -#define DB_RETOK_DBDEL(ret) DB_RETOK_DBCDEL(ret) -#define DB_RETOK_DBGET(ret) DB_RETOK_DBCGET(ret) -#define DB_RETOK_DBPUT(ret) ((ret) == 0 || (ret) == DB_KEYEXIST) -#define DB_RETOK_LGGET(ret) ((ret) == 0 || (ret) == DB_NOTFOUND) -#define DB_RETOK_MPGET(ret) ((ret) == 0 || (ret) == DB_PAGE_NOTFOUND) -#define DB_RETOK_REPPMSG(ret) ((ret) == 0 || \ - (ret) == DB_REP_IGNORE || \ - (ret) == DB_REP_ISPERM || \ - (ret) == DB_REP_NEWMASTER || \ - (ret) == DB_REP_NEWSITE || \ - (ret) == DB_REP_NOTPERM || \ - (ret) == DB_REP_STARTUPDONE) - -/* Find a reasonable operation-not-supported error. */ -#ifdef EOPNOTSUPP -#define DB_OPNOTSUP EOPNOTSUPP -#else -#ifdef ENOTSUP -#define DB_OPNOTSUP ENOTSUP -#else -#define DB_OPNOTSUP EINVAL -#endif -#endif - -/******************************************************* - * Files. - *******************************************************/ -/* - * We use 1024 as the maximum path length. It's too hard to figure out what - * the real path length is, as it was traditionally stored in <sys/param.h>, - * and that file isn't always available. - */ -#undef MAXPATHLEN -#define MAXPATHLEN 1024 - -#define PATH_DOT "." /* Current working directory. */ - /* Path separator character(s). */ -#define PATH_SEPARATOR "@PATH_SEPARATOR@" - -/******************************************************* - * Environment. - *******************************************************/ -/* Type passed to __db_appname(). */ -typedef enum { - DB_APP_NONE=0, /* No type (region). */ - DB_APP_DATA, /* Data file. */ - DB_APP_LOG, /* Log file. */ - DB_APP_TMP /* Temporary file. */ -} APPNAME; - -/* - * ALIVE_ON The is_alive function is configured. - * CDB_LOCKING CDB product locking. - * CRYPTO_ON Security has been configured. - * LOCKING_ON Locking has been configured. - * LOGGING_ON Logging has been configured. - * MUTEX_ON Mutexes have been configured. - * MPOOL_ON Memory pool has been configured. - * REP_ON Replication has been configured. - * RPC_ON RPC has been configured. - * TXN_ON Transactions have been configured. - */ -#define ALIVE_ON(dbenv) ((dbenv)->is_alive != NULL) -#define CDB_LOCKING(dbenv) F_ISSET(dbenv, DB_ENV_CDB) -#define CRYPTO_ON(dbenv) ((dbenv)->crypto_handle != NULL) -#define LOCKING_ON(dbenv) ((dbenv)->lk_handle != NULL) -#define LOGGING_ON(dbenv) ((dbenv)->lg_handle != NULL) -#define MPOOL_ON(dbenv) ((dbenv)->mp_handle != NULL) -#define MUTEX_ON(dbenv) ((dbenv)->mutex_handle != NULL) -#define REP_ON(dbenv) ((dbenv)->rep_handle != NULL) -#define RPC_ON(dbenv) ((dbenv)->cl_handle != NULL) -#define TXN_ON(dbenv) ((dbenv)->tx_handle != NULL) - -/* - * STD_LOCKING Standard locking, that is, locking was configured and CDB - * was not. We do not do locking in off-page duplicate trees, - * so we check for that in the cursor first. - */ -#define STD_LOCKING(dbc) \ - (!F_ISSET(dbc, DBC_OPD) && \ - !CDB_LOCKING((dbc)->dbp->dbenv) && LOCKING_ON((dbc)->dbp->dbenv)) - -/* - * IS_RECOVERING: The system is running recovery. - */ -#define IS_RECOVERING(dbenv) \ - (LOGGING_ON(dbenv) && \ - F_ISSET((DB_LOG *)(dbenv)->lg_handle, DBLOG_RECOVER)) - -/* Initialization methods are often illegal before/after open is called. */ -#define ENV_ILLEGAL_AFTER_OPEN(dbenv, name) \ - if (F_ISSET((dbenv), DB_ENV_OPEN_CALLED)) \ - return (__db_mi_open(dbenv, name, 1)); -#define ENV_ILLEGAL_BEFORE_OPEN(dbenv, name) \ - if (!F_ISSET((dbenv), DB_ENV_OPEN_CALLED)) \ - return (__db_mi_open(dbenv, name, 0)); - -/* We're not actually user hostile, honest. */ -#define ENV_REQUIRES_CONFIG(dbenv, handle, i, flags) \ - if (handle == NULL) \ - return (__db_env_config(dbenv, i, flags)); -#define ENV_NOT_CONFIGURED(dbenv, handle, i, flags) \ - if (F_ISSET((dbenv), DB_ENV_OPEN_CALLED)) \ - ENV_REQUIRES_CONFIG(dbenv, handle, i, flags) - -#define ENV_ENTER(dbenv, ip) do { \ - int __ret; \ - if ((dbenv)->thr_hashtab == NULL) \ - ip = NULL; \ - else { \ - if ((__ret = \ - __env_set_state(dbenv, &(ip), THREAD_ACTIVE)) != 0) \ - return (__ret); \ - } \ -} while (0) - -#ifdef DIAGNOSTIC -#define ENV_LEAVE(dbenv, ip) do { \ - if ((ip) != NULL) { \ - DB_ASSERT(ip->dbth_state == THREAD_ACTIVE); \ - (ip)->dbth_state = THREAD_OUT; \ - } \ -} while (0) -#else -#define ENV_LEAVE(dbenv, ip) do { \ - if ((ip) != NULL) \ - (ip)->dbth_state = THREAD_OUT; \ -} while (0) -#endif -#ifdef DIAGNOSTIC -#define CHECK_THREAD(dbenv) do { \ - DB_THREAD_INFO *__ip; \ - if ((dbenv)->thr_hashtab != NULL) { \ - (void)__env_set_state(dbenv, &__ip, THREAD_DIAGNOSTIC); \ - DB_ASSERT(__ip != NULL && \ - __ip->dbth_state != THREAD_OUT); \ - } \ -} while (0) -#define CHECK_MTX_THREAD(dbenv, mtx) do { \ - if (mtx->alloc_id != MTX_MUTEX_REGION && \ - mtx->alloc_id != MTX_ENV_REGION && \ - mtx->alloc_id != MTX_APPLICATION) \ - CHECK_THREAD(dbenv); \ -} while (0) -#else -#define CHECK_THREAD(dbenv) -#define CHECK_MTX_THREAD(dbenv, mtx) -#endif - -typedef enum { - THREAD_SLOT_NOT_IN_USE=0, - THREAD_OUT, - THREAD_ACTIVE, - THREAD_BLOCKED -#ifdef DIAGNOSTIC - , THREAD_DIAGNOSTIC -#endif -} DB_THREAD_STATE; - -typedef struct __db_thread_info { - pid_t dbth_pid; - db_threadid_t dbth_tid; - DB_THREAD_STATE dbth_state; - SH_TAILQ_ENTRY dbth_links; -} DB_THREAD_INFO; - -typedef struct __env_thread_info { - u_int32_t thr_count; - u_int32_t thr_max; - u_int32_t thr_nbucket; - roff_t thr_hashoff; -} THREAD_INFO; - -/******************************************************* - * Database Access Methods. - *******************************************************/ -/* - * DB_IS_THREADED -- - * The database handle is free-threaded (was opened with DB_THREAD). - */ -#define DB_IS_THREADED(dbp) \ - ((dbp)->mutex != MUTEX_INVALID) - -/* Initialization methods are often illegal before/after open is called. */ -#define DB_ILLEGAL_AFTER_OPEN(dbp, name) \ - if (F_ISSET((dbp), DB_AM_OPEN_CALLED)) \ - return (__db_mi_open((dbp)->dbenv, name, 1)); -#define DB_ILLEGAL_BEFORE_OPEN(dbp, name) \ - if (!F_ISSET((dbp), DB_AM_OPEN_CALLED)) \ - return (__db_mi_open((dbp)->dbenv, name, 0)); -/* Some initialization methods are illegal if environment isn't local. */ -#define DB_ILLEGAL_IN_ENV(dbp, name) \ - if (!F_ISSET((dbp)->dbenv, DB_ENV_DBLOCAL)) \ - return (__db_mi_env((dbp)->dbenv, name)); -#define DB_ILLEGAL_METHOD(dbp, flags) { \ - int __ret; \ - if ((__ret = __dbh_am_chk(dbp, flags)) != 0) \ - return (__ret); \ -} - -/* - * Common DBC->internal fields. Each access method adds additional fields - * to this list, but the initial fields are common. - */ -#define __DBC_INTERNAL \ - DBC *opd; /* Off-page duplicate cursor. */\ - \ - void *page; /* Referenced page. */ \ - db_pgno_t root; /* Tree root. */ \ - db_pgno_t pgno; /* Referenced page number. */ \ - db_indx_t indx; /* Referenced key item index. */\ - \ - DB_LOCK lock; /* Cursor lock. */ \ - db_lockmode_t lock_mode; /* Lock mode. */ - -struct __dbc_internal { - __DBC_INTERNAL -}; - -/* Actions that __db_master_update can take. */ -typedef enum { MU_REMOVE, MU_RENAME, MU_OPEN } mu_action; - -/* - * Access-method-common macro for determining whether a cursor - * has been initialized. - */ -#define IS_INITIALIZED(dbc) ((dbc)->internal->pgno != PGNO_INVALID) - -/* Free the callback-allocated buffer, if necessary, hanging off of a DBT. */ -#define FREE_IF_NEEDED(sdbp, dbt) \ - if (F_ISSET((dbt), DB_DBT_APPMALLOC)) { \ - __os_ufree((sdbp)->dbenv, (dbt)->data); \ - F_CLR((dbt), DB_DBT_APPMALLOC); \ - } - -/* - * Use memory belonging to object "owner" to return the results of - * any no-DBT-flag get ops on cursor "dbc". - */ -#define SET_RET_MEM(dbc, owner) \ - do { \ - (dbc)->rskey = &(owner)->my_rskey; \ - (dbc)->rkey = &(owner)->my_rkey; \ - (dbc)->rdata = &(owner)->my_rdata; \ - } while (0) - -/* Use the return-data memory src is currently set to use in dest as well. */ -#define COPY_RET_MEM(src, dest) \ - do { \ - (dest)->rskey = (src)->rskey; \ - (dest)->rkey = (src)->rkey; \ - (dest)->rdata = (src)->rdata; \ - } while (0) - -/* Reset the returned-memory pointers to their defaults. */ -#define RESET_RET_MEM(dbc) \ - do { \ - (dbc)->rskey = &(dbc)->my_rskey; \ - (dbc)->rkey = &(dbc)->my_rkey; \ - (dbc)->rdata = &(dbc)->my_rdata; \ - } while (0) - -/******************************************************* - * Mpool. - *******************************************************/ -/* - * File types for DB access methods. Negative numbers are reserved to DB. - */ -#define DB_FTYPE_SET -1 /* Call pgin/pgout functions. */ -#define DB_FTYPE_NOTSET 0 /* Don't call... */ -#define DB_LSN_OFF_NOTSET -1 /* Not yet set. */ -#define DB_CLEARLEN_NOTSET UINT32_MAX /* Not yet set. */ - -/* Structure used as the DB pgin/pgout pgcookie. */ -typedef struct __dbpginfo { - size_t db_pagesize; /* Underlying page size. */ - u_int32_t flags; /* Some DB_AM flags needed. */ - DBTYPE type; /* DB type */ -} DB_PGINFO; - -/******************************************************* - * Log. - *******************************************************/ -/* Initialize an LSN to 'zero'. */ -#define ZERO_LSN(LSN) do { \ - (LSN).file = 0; \ - (LSN).offset = 0; \ -} while (0) -#define IS_ZERO_LSN(LSN) ((LSN).file == 0 && (LSN).offset == 0) - -#define IS_INIT_LSN(LSN) ((LSN).file == 1 && (LSN).offset == 0) -#define INIT_LSN(LSN) do { \ - (LSN).file = 1; \ - (LSN).offset = 0; \ -} while (0) - -#define MAX_LSN(LSN) do { \ - (LSN).file = UINT32_MAX; \ - (LSN).offset = UINT32_MAX; \ -} while (0) -#define IS_MAX_LSN(LSN) \ - ((LSN).file == UINT32_MAX && (LSN).offset == UINT32_MAX) - -/* If logging is turned off, smash the lsn. */ -#define LSN_NOT_LOGGED(LSN) do { \ - (LSN).file = 0; \ - (LSN).offset = 1; \ -} while (0) -#define IS_NOT_LOGGED_LSN(LSN) \ - ((LSN).file == 0 && (LSN).offset == 1) - -/******************************************************* - * Txn. - *******************************************************/ -#define DB_NONBLOCK(C) ((C)->txn != NULL && F_ISSET((C)->txn, TXN_NOWAIT)) -#define NOWAIT_FLAG(txn) \ - ((txn) != NULL && F_ISSET((txn), TXN_NOWAIT) ? DB_LOCK_NOWAIT : 0) -#define IS_SUBTRANSACTION(txn) \ - ((txn) != NULL && (txn)->parent != NULL) - -/******************************************************* - * Crypto. - *******************************************************/ -#define DB_IV_BYTES 16 /* Bytes per IV */ -#define DB_MAC_KEY 20 /* Bytes per MAC checksum */ - -/******************************************************* - * Secondaries over RPC. - *******************************************************/ -#ifdef CONFIG_TEST -/* - * These are flags passed to DB->associate calls by the Tcl API if running - * over RPC. The RPC server will mask out these flags before making the real - * DB->associate call. - * - * These flags must coexist with the valid flags to DB->associate (currently - * DB_AUTO_COMMIT and DB_CREATE). DB_AUTO_COMMIT is in the group of - * high-order shared flags (0xff000000), and DB_CREATE is in the low-order - * group (0x00000fff), so we pick a range in between. - */ -#define DB_RPC2ND_MASK 0x00f00000 /* Reserved bits. */ - -#define DB_RPC2ND_REVERSEDATA 0x00100000 /* callback_n(0) _s_reversedata. */ -#define DB_RPC2ND_NOOP 0x00200000 /* callback_n(1) _s_noop */ -#define DB_RPC2ND_CONCATKEYDATA 0x00300000 /* callback_n(2) _s_concatkeydata */ -#define DB_RPC2ND_CONCATDATAKEY 0x00400000 /* callback_n(3) _s_concatdatakey */ -#define DB_RPC2ND_REVERSECONCAT 0x00500000 /* callback_n(4) _s_reverseconcat */ -#define DB_RPC2ND_TRUNCDATA 0x00600000 /* callback_n(5) _s_truncdata */ -#define DB_RPC2ND_CONSTANT 0x00700000 /* callback_n(6) _s_constant */ -#define DB_RPC2ND_GETZIP 0x00800000 /* sj_getzip */ -#define DB_RPC2ND_GETNAME 0x00900000 /* sj_getname */ -#endif - -/******************************************************* - * Forward structure declarations. - *******************************************************/ -struct __db_reginfo_t; typedef struct __db_reginfo_t REGINFO; -struct __db_txnhead; typedef struct __db_txnhead DB_TXNHEAD; -struct __db_txnlist; typedef struct __db_txnlist DB_TXNLIST; -struct __vrfy_childinfo;typedef struct __vrfy_childinfo VRFY_CHILDINFO; -struct __vrfy_dbinfo; typedef struct __vrfy_dbinfo VRFY_DBINFO; -struct __vrfy_pageinfo; typedef struct __vrfy_pageinfo VRFY_PAGEINFO; - -#if defined(__cplusplus) -} -#endif - -/******************************************************* - * Remaining general DB includes. - *******************************************************/ -@db_int_def@ - -#include "dbinc/globals.h" -#include "dbinc/debug.h" -#include "dbinc/region.h" -#include "dbinc_auto/env_ext.h" -#include "dbinc/mutex.h" -#include "dbinc/os.h" -#include "dbinc/rep.h" -#include "dbinc_auto/clib_ext.h" -#include "dbinc_auto/common_ext.h" - -/******************************************************* - * Remaining Log. - * These need to be defined after the general includes - * because they need rep.h from above. - *******************************************************/ -/* - * Test if the environment is currently logging changes. If we're in recovery - * or we're a replication client, we don't need to log changes because they're - * already in the log, even though we have a fully functional log system. - */ -#define DBENV_LOGGING(dbenv) \ - (LOGGING_ON(dbenv) && !IS_REP_CLIENT(dbenv) && \ - (!IS_RECOVERING(dbenv))) - -/* - * Test if we need to log a change. By default, we don't log operations without - * associated transactions, unless DIAGNOSTIC, DEBUG_ROP or DEBUG_WOP are on. - * This is because we want to get log records for read/write operations, and, if - * we trying to debug something, more information is always better. - * - * The DBC_RECOVER flag is set when we're in abort, as well as during recovery; - * thus DBC_LOGGING may be false for a particular dbc even when DBENV_LOGGING - * is true. - * - * We explicitly use LOGGING_ON/IS_REP_CLIENT here because we don't want to pull - * in the log headers, which IS_RECOVERING (and thus DBENV_LOGGING) rely on, and - * because DBC_RECOVER should be set anytime IS_RECOVERING would be true. - * - * If we're not in recovery (master - doing an abort a client applying - * a txn), then a client's only path through here is on an internal - * operation, and a master's only path through here is a transactional - * operation. Detect if either is not the case. - */ -#if defined(DIAGNOSTIC) || defined(DEBUG_ROP) || defined(DEBUG_WOP) -#define DBC_LOGGING(dbc) __dbc_logging(dbc) -#else -#define DBC_LOGGING(dbc) \ - ((dbc)->txn != NULL && LOGGING_ON((dbc)->dbp->dbenv) && \ - !F_ISSET((dbc), DBC_RECOVER) && !IS_REP_CLIENT((dbc)->dbp->dbenv)) -#endif - -#endif /* !_DB_INTERNAL_H_ */ diff --git a/storage/bdb/dbinc/db_join.h b/storage/bdb/dbinc/db_join.h deleted file mode 100644 index ff43216479c..00000000000 --- a/storage/bdb/dbinc/db_join.h +++ /dev/null @@ -1,30 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1998-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_join.h,v 12.2 2005/06/16 20:21:47 bostic Exp $ - */ - -#ifndef _DB_JOIN_H_ -#define _DB_JOIN_H_ -/* - * Joins use a join cursor that is similar to a regular DB cursor except - * that it only supports c_get and c_close functionality. Also, it does - * not support the full range of flags for get. - */ -typedef struct __join_cursor { - u_int8_t *j_exhausted; /* Array of flags; is cursor i exhausted? */ - DBC **j_curslist; /* Array of cursors in the join: constant. */ - DBC **j_fdupcurs; /* Cursors w/ first instances of current dup. */ - DBC **j_workcurs; /* Scratch cursor copies to muck with. */ - DB *j_primary; /* Primary dbp. */ - DBT j_key; /* Used to do lookups. */ - DBT j_rdata; /* Memory used for data return. */ - u_int32_t j_ncurs; /* How many cursors do we have? */ -#define JOIN_RETRY 0x01 /* Error on primary get; re-return same key. */ - u_int32_t flags; -} JOIN_CURSOR; - -#endif /* !_DB_JOIN_H_ */ diff --git a/storage/bdb/dbinc/db_page.h b/storage/bdb/dbinc/db_page.h deleted file mode 100644 index 883b7d450fe..00000000000 --- a/storage/bdb/dbinc/db_page.h +++ /dev/null @@ -1,672 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_page.h,v 12.6 2005/08/08 14:52:30 bostic Exp $ - */ - -#ifndef _DB_PAGE_H_ -#define _DB_PAGE_H_ - -#if defined(__cplusplus) -extern "C" { -#endif - -/* - * DB page formats. - * - * !!! - * This implementation requires that values within the following structures - * NOT be padded -- note, ANSI C permits random padding within structures. - * If your compiler pads randomly you can just forget ever making DB run on - * your system. In addition, no data type can require larger alignment than - * its own size, e.g., a 4-byte data element may not require 8-byte alignment. - * - * Note that key/data lengths are often stored in db_indx_t's -- this is - * not accidental, nor does it limit the key/data size. If the key/data - * item fits on a page, it's guaranteed to be small enough to fit into a - * db_indx_t, and storing it in one saves space. - */ - -#define PGNO_INVALID 0 /* Invalid page number in any database. */ -#define PGNO_BASE_MD 0 /* Base database: metadata page number. */ - -/* Page types. */ -#define P_INVALID 0 /* Invalid page type. */ -#define __P_DUPLICATE 1 /* Duplicate. DEPRECATED in 3.1 */ -#define P_HASH 2 /* Hash. */ -#define P_IBTREE 3 /* Btree internal. */ -#define P_IRECNO 4 /* Recno internal. */ -#define P_LBTREE 5 /* Btree leaf. */ -#define P_LRECNO 6 /* Recno leaf. */ -#define P_OVERFLOW 7 /* Overflow. */ -#define P_HASHMETA 8 /* Hash metadata page. */ -#define P_BTREEMETA 9 /* Btree metadata page. */ -#define P_QAMMETA 10 /* Queue metadata page. */ -#define P_QAMDATA 11 /* Queue data page. */ -#define P_LDUP 12 /* Off-page duplicate leaf. */ -#define P_PAGETYPE_MAX 13 -/* Flag to __db_new */ -#define P_DONTEXTEND 0x8000 /* Don't allocate if there are no free pages. */ - -/* - * When we create pages in mpool, we ask mpool to clear some number of bytes - * in the header. This number must be at least as big as the regular page - * headers and cover enough of the btree and hash meta-data pages to obliterate - * the page type. - */ -#define DB_PAGE_DB_LEN 32 -#define DB_PAGE_QUEUE_LEN 0 - -/************************************************************************ - GENERIC METADATA PAGE HEADER - * - * !!! - * The magic and version numbers have to be in the same place in all versions - * of the metadata page as the application may not have upgraded the database. - ************************************************************************/ -typedef struct _dbmeta33 { - DB_LSN lsn; /* 00-07: LSN. */ - db_pgno_t pgno; /* 08-11: Current page number. */ - u_int32_t magic; /* 12-15: Magic number. */ - u_int32_t version; /* 16-19: Version. */ - u_int32_t pagesize; /* 20-23: Pagesize. */ - u_int8_t encrypt_alg; /* 24: Encryption algorithm. */ - u_int8_t type; /* 25: Page type. */ -#define DBMETA_CHKSUM 0x01 - u_int8_t metaflags; /* 26: Meta-only flags */ - u_int8_t unused1; /* 27: Unused. */ - u_int32_t free; /* 28-31: Free list page number. */ - db_pgno_t last_pgno; /* 32-35: Page number of last page in db. */ - u_int32_t unused3; /* 36-39: Unused. */ - u_int32_t key_count; /* 40-43: Cached key count. */ - u_int32_t record_count; /* 44-47: Cached record count. */ - u_int32_t flags; /* 48-51: Flags: unique to each AM. */ - /* 52-71: Unique file ID. */ - u_int8_t uid[DB_FILE_ID_LEN]; -} DBMETA33, DBMETA; - -/************************************************************************ - BTREE METADATA PAGE LAYOUT - ************************************************************************/ -typedef struct _btmeta33 { -#define BTM_DUP 0x001 /* Duplicates. */ -#define BTM_RECNO 0x002 /* Recno tree. */ -#define BTM_RECNUM 0x004 /* Btree: maintain record count. */ -#define BTM_FIXEDLEN 0x008 /* Recno: fixed length records. */ -#define BTM_RENUMBER 0x010 /* Recno: renumber on insert/delete. */ -#define BTM_SUBDB 0x020 /* Subdatabases. */ -#define BTM_DUPSORT 0x040 /* Duplicates are sorted. */ -#define BTM_MASK 0x07f - DBMETA dbmeta; /* 00-71: Generic meta-data header. */ - - u_int32_t unused1; /* 72-75: Unused space. */ - u_int32_t minkey; /* 76-79: Btree: Minkey. */ - u_int32_t re_len; /* 80-83: Recno: fixed-length record length. */ - u_int32_t re_pad; /* 84-87: Recno: fixed-length record pad. */ - u_int32_t root; /* 88-91: Root page. */ - u_int32_t unused2[92]; /* 92-459: Unused space. */ - u_int32_t crypto_magic; /* 460-463: Crypto magic number */ - u_int32_t trash[3]; /* 464-475: Trash space - Do not use */ - u_int8_t iv[DB_IV_BYTES]; /* 476-495: Crypto IV */ - u_int8_t chksum[DB_MAC_KEY]; /* 496-511: Page chksum */ - - /* - * Minimum page size is 512. - */ -} BTMETA33, BTMETA; - -/************************************************************************ - HASH METADATA PAGE LAYOUT - ************************************************************************/ -typedef struct _hashmeta33 { -#define DB_HASH_DUP 0x01 /* Duplicates. */ -#define DB_HASH_SUBDB 0x02 /* Subdatabases. */ -#define DB_HASH_DUPSORT 0x04 /* Duplicates are sorted. */ - DBMETA dbmeta; /* 00-71: Generic meta-data page header. */ - - u_int32_t max_bucket; /* 72-75: ID of Maximum bucket in use */ - u_int32_t high_mask; /* 76-79: Modulo mask into table */ - u_int32_t low_mask; /* 80-83: Modulo mask into table lower half */ - u_int32_t ffactor; /* 84-87: Fill factor */ - u_int32_t nelem; /* 88-91: Number of keys in hash table */ - u_int32_t h_charkey; /* 92-95: Value of hash(CHARKEY) */ -#define NCACHED 32 /* number of spare points */ - /* 96-223: Spare pages for overflow */ - u_int32_t spares[NCACHED]; - u_int32_t unused[59]; /* 224-459: Unused space */ - u_int32_t crypto_magic; /* 460-463: Crypto magic number */ - u_int32_t trash[3]; /* 464-475: Trash space - Do not use */ - u_int8_t iv[DB_IV_BYTES]; /* 476-495: Crypto IV */ - u_int8_t chksum[DB_MAC_KEY]; /* 496-511: Page chksum */ - - /* - * Minimum page size is 512. - */ -} HMETA33, HMETA; - -/************************************************************************ - QUEUE METADATA PAGE LAYOUT - ************************************************************************/ -/* - * QAM Meta data page structure - * - */ -typedef struct _qmeta33 { - DBMETA dbmeta; /* 00-71: Generic meta-data header. */ - - u_int32_t first_recno; /* 72-75: First not deleted record. */ - u_int32_t cur_recno; /* 76-79: Next recno to be allocated. */ - u_int32_t re_len; /* 80-83: Fixed-length record length. */ - u_int32_t re_pad; /* 84-87: Fixed-length record pad. */ - u_int32_t rec_page; /* 88-91: Records Per Page. */ - u_int32_t page_ext; /* 92-95: Pages per extent */ - - u_int32_t unused[91]; /* 96-459: Unused space */ - u_int32_t crypto_magic; /* 460-463: Crypto magic number */ - u_int32_t trash[3]; /* 464-475: Trash space - Do not use */ - u_int8_t iv[DB_IV_BYTES]; /* 476-495: Crypto IV */ - u_int8_t chksum[DB_MAC_KEY]; /* 496-511: Page chksum */ - /* - * Minimum page size is 512. - */ -} QMETA33, QMETA; - -/* - * DBMETASIZE is a constant used by __db_file_setup and DB->verify - * as a buffer which is guaranteed to be larger than any possible - * metadata page size and smaller than any disk sector. - */ -#define DBMETASIZE 512 - -/************************************************************************ - BTREE/HASH MAIN PAGE LAYOUT - ************************************************************************/ -/* - * +-----------------------------------+ - * | lsn | pgno | prev pgno | - * +-----------------------------------+ - * | next pgno | entries | hf offset | - * +-----------------------------------+ - * | level | type | chksum | - * +-----------------------------------+ - * | iv | index | free --> | - * +-----------+-----------------------+ - * | F R E E A R E A | - * +-----------------------------------+ - * | <-- free | item | - * +-----------------------------------+ - * | item | item | item | - * +-----------------------------------+ - * - * sizeof(PAGE) == 26 bytes + possibly 20 bytes of checksum and possibly - * 16 bytes of IV (+ 2 bytes for alignment), and the following indices - * are guaranteed to be two-byte aligned. If we aren't doing crypto or - * checksumming the bytes are reclaimed for data storage. - * - * For hash and btree leaf pages, index items are paired, e.g., inp[0] is the - * key for inp[1]'s data. All other types of pages only contain single items. - */ -typedef struct __pg_chksum { - u_int8_t unused[2]; /* 26-27: For alignment */ - u_int8_t chksum[4]; /* 28-31: Checksum */ -} PG_CHKSUM; - -typedef struct __pg_crypto { - u_int8_t unused[2]; /* 26-27: For alignment */ - u_int8_t chksum[DB_MAC_KEY]; /* 28-47: Checksum */ - u_int8_t iv[DB_IV_BYTES]; /* 48-63: IV */ - /* !!! - * Must be 16-byte aligned for crypto - */ -} PG_CRYPTO; - -typedef struct _db_page { - DB_LSN lsn; /* 00-07: Log sequence number. */ - db_pgno_t pgno; /* 08-11: Current page number. */ - db_pgno_t prev_pgno; /* 12-15: Previous page number. */ - db_pgno_t next_pgno; /* 16-19: Next page number. */ - db_indx_t entries; /* 20-21: Number of items on the page. */ - db_indx_t hf_offset; /* 22-23: High free byte page offset. */ - - /* - * The btree levels are numbered from the leaf to the root, starting - * with 1, so the leaf is level 1, its parent is level 2, and so on. - * We maintain this level on all btree pages, but the only place that - * we actually need it is on the root page. It would not be difficult - * to hide the byte on the root page once it becomes an internal page, - * so we could get this byte back if we needed it for something else. - */ -#define LEAFLEVEL 1 -#define MAXBTREELEVEL 255 - u_int8_t level; /* 24: Btree tree level. */ - u_int8_t type; /* 25: Page type. */ -} PAGE; - -/* - * With many compilers sizeof(PAGE) == 28, while SIZEOF_PAGE == 26. - * We add in other things directly after the page header and need - * the SIZEOF_PAGE. When giving the sizeof(), many compilers will - * pad it out to the next 4-byte boundary. - */ -#define SIZEOF_PAGE 26 -/* - * !!! - * DB_AM_ENCRYPT always implies DB_AM_CHKSUM so that must come first. - */ -#define P_INP(dbp, pg) \ - ((db_indx_t *)((u_int8_t *)(pg) + SIZEOF_PAGE + \ - (F_ISSET((dbp), DB_AM_ENCRYPT) ? sizeof(PG_CRYPTO) : \ - (F_ISSET((dbp), DB_AM_CHKSUM) ? sizeof(PG_CHKSUM) : 0)))) - -#define P_IV(dbp, pg) \ - (F_ISSET((dbp), DB_AM_ENCRYPT) ? ((u_int8_t *)(pg) + \ - SIZEOF_PAGE + SSZA(PG_CRYPTO, iv)) \ - : NULL) - -#define P_CHKSUM(dbp, pg) \ - (F_ISSET((dbp), DB_AM_ENCRYPT) ? ((u_int8_t *)(pg) + \ - SIZEOF_PAGE + SSZA(PG_CRYPTO, chksum)) : \ - (F_ISSET((dbp), DB_AM_CHKSUM) ? ((u_int8_t *)(pg) + \ - SIZEOF_PAGE + SSZA(PG_CHKSUM, chksum)) \ - : NULL)) - -/* PAGE element macros. */ -#define LSN(p) (((PAGE *)p)->lsn) -#define PGNO(p) (((PAGE *)p)->pgno) -#define PREV_PGNO(p) (((PAGE *)p)->prev_pgno) -#define NEXT_PGNO(p) (((PAGE *)p)->next_pgno) -#define NUM_ENT(p) (((PAGE *)p)->entries) -#define HOFFSET(p) (((PAGE *)p)->hf_offset) -#define LEVEL(p) (((PAGE *)p)->level) -#define TYPE(p) (((PAGE *)p)->type) - -/************************************************************************ - QUEUE MAIN PAGE LAYOUT - ************************************************************************/ -/* - * Sizes of page below. Used to reclaim space if not doing - * crypto or checksumming. If you change the QPAGE below you - * MUST adjust this too. - */ -#define QPAGE_NORMAL 28 -#define QPAGE_CHKSUM 48 -#define QPAGE_SEC 64 - -typedef struct _qpage { - DB_LSN lsn; /* 00-07: Log sequence number. */ - db_pgno_t pgno; /* 08-11: Current page number. */ - u_int32_t unused0[3]; /* 12-23: Unused. */ - u_int8_t unused1[1]; /* 24: Unused. */ - u_int8_t type; /* 25: Page type. */ - u_int8_t unused2[2]; /* 26-27: Unused. */ - u_int8_t chksum[DB_MAC_KEY]; /* 28-47: Checksum */ - u_int8_t iv[DB_IV_BYTES]; /* 48-63: IV */ -} QPAGE; - -#define QPAGE_SZ(dbp) \ - (F_ISSET((dbp), DB_AM_ENCRYPT) ? QPAGE_SEC : \ - F_ISSET((dbp), DB_AM_CHKSUM) ? QPAGE_CHKSUM : QPAGE_NORMAL) -/* - * !!! - * The next_pgno and prev_pgno fields are not maintained for btree and recno - * internal pages. Doing so only provides a minor performance improvement, - * it's hard to do when deleting internal pages, and it increases the chance - * of deadlock during deletes and splits because we have to re-link pages at - * more than the leaf level. - * - * !!! - * The btree/recno access method needs db_recno_t bytes of space on the root - * page to specify how many records are stored in the tree. (The alternative - * is to store the number of records in the meta-data page, which will create - * a second hot spot in trees being actively modified, or recalculate it from - * the BINTERNAL fields on each access.) Overload the PREV_PGNO field. - */ -#define RE_NREC(p) \ - ((TYPE(p) == P_IBTREE || TYPE(p) == P_IRECNO) ? PREV_PGNO(p) : \ - (db_pgno_t)(TYPE(p) == P_LBTREE ? NUM_ENT(p) / 2 : NUM_ENT(p))) -#define RE_NREC_ADJ(p, adj) \ - PREV_PGNO(p) += adj; -#define RE_NREC_SET(p, num) \ - PREV_PGNO(p) = (num); - -/* - * Initialize a page. - * - * !!! - * Don't modify the page's LSN, code depends on it being unchanged after a - * P_INIT call. - */ -#define P_INIT(pg, pg_size, n, pg_prev, pg_next, btl, pg_type) do { \ - PGNO(pg) = (n); \ - PREV_PGNO(pg) = (pg_prev); \ - NEXT_PGNO(pg) = (pg_next); \ - NUM_ENT(pg) = (0); \ - HOFFSET(pg) = (db_indx_t)(pg_size); \ - LEVEL(pg) = (btl); \ - TYPE(pg) = (pg_type); \ -} while (0) - -/* Page header length (offset to first index). */ -#define P_OVERHEAD(dbp) P_TO_UINT16(P_INP(dbp, 0)) - -/* First free byte. */ -#define LOFFSET(dbp, pg) \ - (P_OVERHEAD(dbp) + NUM_ENT(pg) * sizeof(db_indx_t)) - -/* Free space on a regular page. */ -#define P_FREESPACE(dbp, pg) (HOFFSET(pg) - LOFFSET(dbp, pg)) - -/* Get a pointer to the bytes at a specific index. */ -#define P_ENTRY(dbp, pg, indx) ((u_int8_t *)pg + P_INP(dbp, pg)[indx]) - -/************************************************************************ - OVERFLOW PAGE LAYOUT - ************************************************************************/ - -/* - * Overflow items are referenced by HOFFPAGE and BOVERFLOW structures, which - * store a page number (the first page of the overflow item) and a length - * (the total length of the overflow item). The overflow item consists of - * some number of overflow pages, linked by the next_pgno field of the page. - * A next_pgno field of PGNO_INVALID flags the end of the overflow item. - * - * Overflow page overloads: - * The amount of overflow data stored on each page is stored in the - * hf_offset field. - * - * The implementation reference counts overflow items as it's possible - * for them to be promoted onto btree internal pages. The reference - * count is stored in the entries field. - */ -#define OV_LEN(p) (((PAGE *)p)->hf_offset) -#define OV_REF(p) (((PAGE *)p)->entries) - -/* Maximum number of bytes that you can put on an overflow page. */ -#define P_MAXSPACE(dbp, psize) ((psize) - P_OVERHEAD(dbp)) - -/* Free space on an overflow page. */ -#define P_OVFLSPACE(dbp, psize, pg) (P_MAXSPACE(dbp, psize) - HOFFSET(pg)) - -/************************************************************************ - HASH PAGE LAYOUT - ************************************************************************/ - -/* Each index references a group of bytes on the page. */ -#define H_KEYDATA 1 /* Key/data item. */ -#define H_DUPLICATE 2 /* Duplicate key/data item. */ -#define H_OFFPAGE 3 /* Overflow key/data item. */ -#define H_OFFDUP 4 /* Overflow page of duplicates. */ - -/* - * !!! - * Items on hash pages are (potentially) unaligned, so we can never cast the - * (page + offset) pointer to an HKEYDATA, HOFFPAGE or HOFFDUP structure, as - * we do with B+tree on-page structures. Because we frequently want the type - * field, it requires no alignment, and it's in the same location in all three - * structures, there's a pair of macros. - */ -#define HPAGE_PTYPE(p) (*(u_int8_t *)p) -#define HPAGE_TYPE(dbp, pg, indx) (*P_ENTRY(dbp, pg, indx)) - -/* - * The first and second types are H_KEYDATA and H_DUPLICATE, represented - * by the HKEYDATA structure: - * - * +-----------------------------------+ - * | type | key/data ... | - * +-----------------------------------+ - * - * For duplicates, the data field encodes duplicate elements in the data - * field: - * - * +---------------------------------------------------------------+ - * | type | len1 | element1 | len1 | len2 | element2 | len2 | - * +---------------------------------------------------------------+ - * - * Thus, by keeping track of the offset in the element, we can do both - * backward and forward traversal. - */ -typedef struct _hkeydata { - u_int8_t type; /* 00: Page type. */ - u_int8_t data[1]; /* Variable length key/data item. */ -} HKEYDATA; -#define HKEYDATA_DATA(p) (((u_int8_t *)p) + SSZA(HKEYDATA, data)) - -/* - * The length of any HKEYDATA item. Note that indx is an element index, - * not a PAIR index. - */ -#define LEN_HITEM(dbp, pg, pgsize, indx) \ - (((indx) == 0 ? (pgsize) : \ - (P_INP(dbp, pg)[(indx) - 1])) - (P_INP(dbp, pg)[indx])) - -#define LEN_HKEYDATA(dbp, pg, psize, indx) \ - (db_indx_t)(LEN_HITEM(dbp, pg, psize, indx) - HKEYDATA_SIZE(0)) - -/* - * Page space required to add a new HKEYDATA item to the page, with and - * without the index value. - */ -#define HKEYDATA_SIZE(len) \ - ((len) + SSZA(HKEYDATA, data)) -#define HKEYDATA_PSIZE(len) \ - (HKEYDATA_SIZE(len) + sizeof(db_indx_t)) - -/* Put a HKEYDATA item at the location referenced by a page entry. */ -#define PUT_HKEYDATA(pe, kd, len, type) { \ - ((HKEYDATA *)pe)->type = type; \ - memcpy((u_int8_t *)pe + sizeof(u_int8_t), kd, len); \ -} - -/* - * Macros the describe the page layout in terms of key-data pairs. - */ -#define H_NUMPAIRS(pg) (NUM_ENT(pg) / 2) -#define H_KEYINDEX(indx) (indx) -#define H_DATAINDEX(indx) ((indx) + 1) -#define H_PAIRKEY(dbp, pg, indx) P_ENTRY(dbp, pg, H_KEYINDEX(indx)) -#define H_PAIRDATA(dbp, pg, indx) P_ENTRY(dbp, pg, H_DATAINDEX(indx)) -#define H_PAIRSIZE(dbp, pg, psize, indx) \ - (LEN_HITEM(dbp, pg, psize, H_KEYINDEX(indx)) + \ - LEN_HITEM(dbp, pg, psize, H_DATAINDEX(indx))) -#define LEN_HDATA(dbp, p, psize, indx) \ - LEN_HKEYDATA(dbp, p, psize, H_DATAINDEX(indx)) -#define LEN_HKEY(dbp, p, psize, indx) \ - LEN_HKEYDATA(dbp, p, psize, H_KEYINDEX(indx)) - -/* - * The third type is the H_OFFPAGE, represented by the HOFFPAGE structure: - */ -typedef struct _hoffpage { - u_int8_t type; /* 00: Page type and delete flag. */ - u_int8_t unused[3]; /* 01-03: Padding, unused. */ - db_pgno_t pgno; /* 04-07: Offpage page number. */ - u_int32_t tlen; /* 08-11: Total length of item. */ -} HOFFPAGE; - -#define HOFFPAGE_PGNO(p) (((u_int8_t *)p) + SSZ(HOFFPAGE, pgno)) -#define HOFFPAGE_TLEN(p) (((u_int8_t *)p) + SSZ(HOFFPAGE, tlen)) - -/* - * Page space required to add a new HOFFPAGE item to the page, with and - * without the index value. - */ -#define HOFFPAGE_SIZE (sizeof(HOFFPAGE)) -#define HOFFPAGE_PSIZE (HOFFPAGE_SIZE + sizeof(db_indx_t)) - -/* - * The fourth type is H_OFFDUP represented by the HOFFDUP structure: - */ -typedef struct _hoffdup { - u_int8_t type; /* 00: Page type and delete flag. */ - u_int8_t unused[3]; /* 01-03: Padding, unused. */ - db_pgno_t pgno; /* 04-07: Offpage page number. */ -} HOFFDUP; -#define HOFFDUP_PGNO(p) (((u_int8_t *)p) + SSZ(HOFFDUP, pgno)) - -/* - * Page space required to add a new HOFFDUP item to the page, with and - * without the index value. - */ -#define HOFFDUP_SIZE (sizeof(HOFFDUP)) - -/************************************************************************ - BTREE PAGE LAYOUT - ************************************************************************/ - -/* Each index references a group of bytes on the page. */ -#define B_KEYDATA 1 /* Key/data item. */ -#define B_DUPLICATE 2 /* Duplicate key/data item. */ -#define B_OVERFLOW 3 /* Overflow key/data item. */ - -/* - * We have to store a deleted entry flag in the page. The reason is complex, - * but the simple version is that we can't delete on-page items referenced by - * a cursor -- the return order of subsequent insertions might be wrong. The - * delete flag is an overload of the top bit of the type byte. - */ -#define B_DELETE (0x80) -#define B_DCLR(t) (t) &= ~B_DELETE -#define B_DSET(t) (t) |= B_DELETE -#define B_DISSET(t) ((t) & B_DELETE) - -#define B_TYPE(t) ((t) & ~B_DELETE) -#define B_TSET(t, type, deleted) { \ - (t) = (type); \ - if (deleted) \ - B_DSET(t); \ -} - -/* - * The first type is B_KEYDATA, represented by the BKEYDATA structure: - */ -typedef struct _bkeydata { - db_indx_t len; /* 00-01: Key/data item length. */ - u_int8_t type; /* 02: Page type AND DELETE FLAG. */ - u_int8_t data[1]; /* Variable length key/data item. */ -} BKEYDATA; - -/* Get a BKEYDATA item for a specific index. */ -#define GET_BKEYDATA(dbp, pg, indx) \ - ((BKEYDATA *)P_ENTRY(dbp, pg, indx)) - -/* - * Page space required to add a new BKEYDATA item to the page, with and - * without the index value. The (u_int16_t) cast avoids warnings: DB_ALIGN - * casts to uintmax_t, the cast converts it to a small integral type so we - * don't get complaints when we assign the final result to an integral type - * smaller than uintmax_t. - */ -#define BKEYDATA_SIZE(len) \ - (u_int16_t)DB_ALIGN((len) + SSZA(BKEYDATA, data), sizeof(u_int32_t)) -#define BKEYDATA_PSIZE(len) \ - (BKEYDATA_SIZE(len) + sizeof(db_indx_t)) - -/* - * The second and third types are B_DUPLICATE and B_OVERFLOW, represented - * by the BOVERFLOW structure. - */ -typedef struct _boverflow { - db_indx_t unused1; /* 00-01: Padding, unused. */ - u_int8_t type; /* 02: Page type AND DELETE FLAG. */ - u_int8_t unused2; /* 03: Padding, unused. */ - db_pgno_t pgno; /* 04-07: Next page number. */ - u_int32_t tlen; /* 08-11: Total length of item. */ -} BOVERFLOW; - -/* Get a BOVERFLOW item for a specific index. */ -#define GET_BOVERFLOW(dbp, pg, indx) \ - ((BOVERFLOW *)P_ENTRY(dbp, pg, indx)) - -/* - * Page space required to add a new BOVERFLOW item to the page, with and - * without the index value. - */ -#define BOVERFLOW_SIZE \ - ((u_int16_t)DB_ALIGN(sizeof(BOVERFLOW), sizeof(u_int32_t))) -#define BOVERFLOW_PSIZE \ - (BOVERFLOW_SIZE + sizeof(db_indx_t)) - -#define BITEM_SIZE(bk) \ - (B_TYPE((bk)->type) != B_KEYDATA ? BOVERFLOW_SIZE : \ - BKEYDATA_SIZE((bk)->len)) - -#define BITEM_PSIZE(bk) \ - (B_TYPE((bk)->type) != B_KEYDATA ? BOVERFLOW_PSIZE : \ - BKEYDATA_PSIZE((bk)->len)) - -/* - * Btree leaf and hash page layouts group indices in sets of two, one for the - * key and one for the data. Everything else does it in sets of one to save - * space. Use the following macros so that it's real obvious what's going on. - */ -#define O_INDX 1 -#define P_INDX 2 - -/************************************************************************ - BTREE INTERNAL PAGE LAYOUT - ************************************************************************/ - -/* - * Btree internal entry. - */ -typedef struct _binternal { - db_indx_t len; /* 00-01: Key/data item length. */ - u_int8_t type; /* 02: Page type AND DELETE FLAG. */ - u_int8_t unused; /* 03: Padding, unused. */ - db_pgno_t pgno; /* 04-07: Page number of referenced page. */ - db_recno_t nrecs; /* 08-11: Subtree record count. */ - u_int8_t data[1]; /* Variable length key item. */ -} BINTERNAL; - -/* Get a BINTERNAL item for a specific index. */ -#define GET_BINTERNAL(dbp, pg, indx) \ - ((BINTERNAL *)P_ENTRY(dbp, pg, indx)) - -/* - * Page space required to add a new BINTERNAL item to the page, with and - * without the index value. - */ -#define BINTERNAL_SIZE(len) \ - (u_int16_t)DB_ALIGN((len) + SSZA(BINTERNAL, data), sizeof(u_int32_t)) -#define BINTERNAL_PSIZE(len) \ - (BINTERNAL_SIZE(len) + sizeof(db_indx_t)) - -/************************************************************************ - RECNO INTERNAL PAGE LAYOUT - ************************************************************************/ - -/* - * The recno internal entry. - */ -typedef struct _rinternal { - db_pgno_t pgno; /* 00-03: Page number of referenced page. */ - db_recno_t nrecs; /* 04-07: Subtree record count. */ -} RINTERNAL; - -/* Get a RINTERNAL item for a specific index. */ -#define GET_RINTERNAL(dbp, pg, indx) \ - ((RINTERNAL *)P_ENTRY(dbp, pg, indx)) - -/* - * Page space required to add a new RINTERNAL item to the page, with and - * without the index value. - */ -#define RINTERNAL_SIZE \ - (u_int16_t)DB_ALIGN(sizeof(RINTERNAL), sizeof(u_int32_t)) -#define RINTERNAL_PSIZE \ - (RINTERNAL_SIZE + sizeof(db_indx_t)) - -struct pglist { - db_pgno_t pgno; - DB_LSN lsn; -}; - -#if defined(__cplusplus) -} -#endif - -#endif /* !_DB_PAGE_H_ */ diff --git a/storage/bdb/dbinc/db_server_int.h b/storage/bdb/dbinc/db_server_int.h deleted file mode 100644 index aee9ad194c7..00000000000 --- a/storage/bdb/dbinc/db_server_int.h +++ /dev/null @@ -1,153 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2000-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_server_int.h,v 12.4 2005/08/08 14:52:30 bostic Exp $ - */ - -#ifndef _DB_SERVER_INT_H_ -#define _DB_SERVER_INT_H_ - -#define DB_SERVER_TIMEOUT 300 /* 5 minutes */ -#define DB_SERVER_MAXTIMEOUT 1200 /* 20 minutes */ -#define DB_SERVER_IDLETIMEOUT 86400 /* 1 day */ - -/* - * Ignore/mask off the following env->open flags: - * Most are illegal for a client to specify as they would control - * server resource usage. We will just ignore them. - * DB_LOCKDOWN - * DB_PRIVATE - * DB_RECOVER - * DB_RECOVER_FATAL - * DB_SYSTEM_MEM - * DB_USE_ENVIRON, DB_USE_ENVIRON_ROOT - handled on client - */ -#define DB_SERVER_FLAGMASK ( \ -DB_LOCKDOWN | DB_PRIVATE | DB_RECOVER | DB_RECOVER_FATAL | \ -DB_SYSTEM_MEM | DB_USE_ENVIRON | DB_USE_ENVIRON_ROOT) - -#define CT_CURSOR 0x001 /* Cursor */ -#define CT_DB 0x002 /* Database */ -#define CT_ENV 0x004 /* Env */ -#define CT_TXN 0x008 /* Txn */ - -#define CT_JOIN 0x10000000 /* Join cursor component */ -#define CT_JOINCUR 0x20000000 /* Join cursor */ - -typedef struct home_entry home_entry; -struct home_entry { - LIST_ENTRY(home_entry) entries; - char *home; - char *dir; - char *name; - char *passwd; -}; - -/* - * Data needed for sharing handles. - * To share an env handle, on the open call, they must have matching - * env flags, and matching set_flags. - * - * To share a db handle on the open call, the db, subdb and flags must - * all be the same. - */ -#define DB_SERVER_ENVFLAGS ( \ -DB_INIT_CDB | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | \ -DB_INIT_TXN | DB_JOINENV) - -#define DB_SERVER_DBFLAGS (DB_NOMMAP | DB_RDONLY | DB_READ_UNCOMMITTED) -#define DB_SERVER_DBNOSHARE (DB_EXCL | DB_TRUNCATE) - -typedef struct ct_envdata ct_envdata; -typedef struct ct_dbdata ct_dbdata; -struct ct_envdata { - u_int32_t envflags; - u_int32_t onflags; - u_int32_t offflags; - home_entry *home; -}; - -struct ct_dbdata { - u_int32_t dbflags; - u_int32_t setflags; - char *db; - char *subdb; - DBTYPE type; -}; - -/* - * We maintain an activity timestamp for each handle. However, we - * set it to point, possibly to the ct_active field of its own handle - * or it may point to the ct_active field of a parent. In the case - * of nested transactions and any cursors within transactions it must - * point to the ct_active field of the ultimate parent of the transaction - * no matter how deeply it is nested. - */ -typedef struct ct_entry ct_entry; -struct ct_entry { - LIST_ENTRY(ct_entry) entries; /* List of entries */ - union { -#ifdef __cplusplus - DbEnv *envp; /* H_ENV */ - DbTxn *txnp; /* H_TXN */ - Db *dbp; /* H_DB */ - Dbc *dbc; /* H_CURSOR */ -#else - DB_ENV *envp; /* H_ENV */ - DB_TXN *txnp; /* H_TXN */ - DB *dbp; /* H_DB */ - DBC *dbc; /* H_CURSOR */ -#endif - void *anyp; - } handle_u; - union { /* Private data per type */ - ct_envdata envdp; /* Env info */ - ct_dbdata dbdp; /* Db info */ - } private_u; - long ct_id; /* Client ID */ - long *ct_activep; /* Activity timestamp pointer*/ - long *ct_origp; /* Original timestamp pointer*/ - long ct_active; /* Activity timestamp */ - long ct_timeout; /* Resource timeout */ - long ct_idle; /* Idle timeout */ - u_int32_t ct_refcount; /* Ref count for sharing */ - u_int32_t ct_type; /* This entry's type */ - struct ct_entry *ct_parent; /* Its parent */ - struct ct_entry *ct_envparent; /* Its environment */ -}; - -#define ct_envp handle_u.envp -#define ct_txnp handle_u.txnp -#define ct_dbp handle_u.dbp -#define ct_dbc handle_u.dbc -#define ct_anyp handle_u.anyp - -#define ct_envdp private_u.envdp -#define ct_dbdp private_u.dbdp - -extern int __dbsrv_verbose; - -/* - * Get ctp and activate it. - * Assumes local variable 'replyp'. - * NOTE: May 'return' from macro. - */ -#define ACTIVATE_CTP(ctp, id, type) { \ - (ctp) = get_tableent(id); \ - if ((ctp) == NULL) { \ - replyp->status = DB_NOSERVER_ID;\ - return; \ - } \ - DB_ASSERT((ctp)->ct_type & (type)); \ - __dbsrv_active(ctp); \ -} - -#define FREE_IF_CHANGED(dbenv, p, orig) do { \ - if ((p) != NULL && (p) != (orig)) \ - __os_ufree((dbenv), (p)); \ -} while (0) - -#endif /* !_DB_SERVER_INT_H_ */ diff --git a/storage/bdb/dbinc/db_shash.h b/storage/bdb/dbinc/db_shash.h deleted file mode 100644 index 89c544fcc91..00000000000 --- a/storage/bdb/dbinc/db_shash.h +++ /dev/null @@ -1,81 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_shash.h,v 12.1 2005/06/16 20:21:47 bostic Exp $ - */ - -#ifndef _DB_SHASH_H_ -#define _DB_SHASH_H_ - -/* Hash Headers */ -typedef SH_TAILQ_HEAD(__hash_head) DB_HASHTAB; - -/* - * HASHLOOKUP -- - * - * Look up something in a shared memory hash table. The "elt" argument - * should be a key, and cmp_func must know how to compare a key to whatever - * structure it is that appears in the hash table. The comparison function - * - * begin: address of the beginning of the hash table. - * ndx: index into table for this item. - * type: the structure type of the elements that are linked in each bucket. - * field: the name of the field by which the "type" structures are linked. - * elt: the item for which we are searching in the hash table. - * res: the variable into which we'll store the element if we find it. - * cmp: called as: cmp(lookup_elt, table_elt). - * - * If the element is not in the hash table, this macro exits with res set - * to NULL. - */ -#define HASHLOOKUP(begin, ndx, type, field, elt, res, cmp) do { \ - DB_HASHTAB *__bucket; \ - \ - __bucket = &begin[ndx]; \ - for (res = SH_TAILQ_FIRST(__bucket, type); \ - res != NULL; res = SH_TAILQ_NEXT(res, field, type)) \ - if (cmp(elt, res)) \ - break; \ -} while (0) - -/* - * HASHINSERT -- - * - * Insert a new entry into the hash table. This assumes that you already - * have the bucket locked and that lookup has failed; don't call it if you - * haven't already called HASHLOOKUP. If you do, you could get duplicate - * entries. - * - * begin: the beginning address of the hash table. - * ndx: the index for this element. - * type: the structure type of the elements that are linked in each bucket. - * field: the name of the field by which the "type" structures are linked. - * elt: the item to be inserted. - */ -#define HASHINSERT(begin, ndx, type, field, elt) do { \ - DB_HASHTAB *__bucket; \ - \ - __bucket = &begin[ndx]; \ - SH_TAILQ_INSERT_HEAD(__bucket, elt, field, type); \ -} while (0) - -/* - * HASHREMOVE_EL -- - * Given the object "obj" in the table, remove it. - * - * begin: address of the beginning of the hash table. - * ndx: index into hash table of where this element belongs. - * type: the structure type of the elements that are linked in each bucket. - * field: the name of the field by which the "type" structures are linked. - * obj: the object in the table that we with to delete. - */ -#define HASHREMOVE_EL(begin, ndx, type, field, obj) { \ - DB_HASHTAB *__bucket; \ - \ - __bucket = &begin[ndx]; \ - SH_TAILQ_REMOVE(__bucket, obj, field, type); \ -} -#endif /* !_DB_SHASH_H_ */ diff --git a/storage/bdb/dbinc/db_swap.h b/storage/bdb/dbinc/db_swap.h deleted file mode 100644 index 6350ae6a1b2..00000000000 --- a/storage/bdb/dbinc/db_swap.h +++ /dev/null @@ -1,170 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: db_swap.h,v 12.3 2005/06/16 20:21:47 bostic Exp $ - */ - -#ifndef _DB_SWAP_H_ -#define _DB_SWAP_H_ - -/* - * Little endian <==> big endian 64-bit swap macros. - * M_64_SWAP swap a memory location - * P_64_COPY copy potentially unaligned 4 byte quantities - * P_64_SWAP swap a referenced memory location - */ -#undef M_64_SWAP -#define M_64_SWAP(a) { \ - u_int64_t _tmp; \ - _tmp = (u_int64_t)a; \ - ((u_int8_t *)&a)[0] = ((u_int8_t *)&_tmp)[7]; \ - ((u_int8_t *)&a)[1] = ((u_int8_t *)&_tmp)[6]; \ - ((u_int8_t *)&a)[2] = ((u_int8_t *)&_tmp)[5]; \ - ((u_int8_t *)&a)[3] = ((u_int8_t *)&_tmp)[4]; \ - ((u_int8_t *)&a)[4] = ((u_int8_t *)&_tmp)[3]; \ - ((u_int8_t *)&a)[5] = ((u_int8_t *)&_tmp)[2]; \ - ((u_int8_t *)&a)[6] = ((u_int8_t *)&_tmp)[1]; \ - ((u_int8_t *)&a)[7] = ((u_int8_t *)&_tmp)[0]; \ -} -#undef P_64_COPY -#define P_64_COPY(a, b) { \ - ((u_int8_t *)b)[0] = ((u_int8_t *)a)[0]; \ - ((u_int8_t *)b)[1] = ((u_int8_t *)a)[1]; \ - ((u_int8_t *)b)[2] = ((u_int8_t *)a)[2]; \ - ((u_int8_t *)b)[3] = ((u_int8_t *)a)[3]; \ - ((u_int8_t *)b)[4] = ((u_int8_t *)a)[4]; \ - ((u_int8_t *)b)[5] = ((u_int8_t *)a)[5]; \ - ((u_int8_t *)b)[6] = ((u_int8_t *)a)[6]; \ - ((u_int8_t *)b)[7] = ((u_int8_t *)a)[7]; \ -} -#undef P_64_SWAP -#define P_64_SWAP(a) { \ - u_int64_t _tmp; \ - P_64_COPY(a, &_tmp); \ - ((u_int8_t *)a)[0] = ((u_int8_t *)&_tmp)[7]; \ - ((u_int8_t *)a)[1] = ((u_int8_t *)&_tmp)[6]; \ - ((u_int8_t *)a)[2] = ((u_int8_t *)&_tmp)[5]; \ - ((u_int8_t *)a)[3] = ((u_int8_t *)&_tmp)[4]; \ - ((u_int8_t *)a)[4] = ((u_int8_t *)&_tmp)[3]; \ - ((u_int8_t *)a)[5] = ((u_int8_t *)&_tmp)[2]; \ - ((u_int8_t *)a)[6] = ((u_int8_t *)&_tmp)[1]; \ - ((u_int8_t *)a)[7] = ((u_int8_t *)&_tmp)[0]; \ -} - -/* - * Little endian <==> big endian 32-bit swap macros. - * M_32_SWAP swap a memory location - * P_32_COPY copy potentially unaligned 4 byte quantities - * P_32_SWAP swap a referenced memory location - */ -#undef M_32_SWAP -#define M_32_SWAP(a) { \ - u_int32_t _tmp; \ - _tmp = (u_int32_t)a; \ - ((u_int8_t *)&a)[0] = ((u_int8_t *)&_tmp)[3]; \ - ((u_int8_t *)&a)[1] = ((u_int8_t *)&_tmp)[2]; \ - ((u_int8_t *)&a)[2] = ((u_int8_t *)&_tmp)[1]; \ - ((u_int8_t *)&a)[3] = ((u_int8_t *)&_tmp)[0]; \ -} -#undef P_32_COPY -#define P_32_COPY(a, b) { \ - ((u_int8_t *)b)[0] = ((u_int8_t *)a)[0]; \ - ((u_int8_t *)b)[1] = ((u_int8_t *)a)[1]; \ - ((u_int8_t *)b)[2] = ((u_int8_t *)a)[2]; \ - ((u_int8_t *)b)[3] = ((u_int8_t *)a)[3]; \ -} -#undef P_32_SWAP -#define P_32_SWAP(a) { \ - u_int32_t _tmp; \ - P_32_COPY(a, &_tmp); \ - ((u_int8_t *)a)[0] = ((u_int8_t *)&_tmp)[3]; \ - ((u_int8_t *)a)[1] = ((u_int8_t *)&_tmp)[2]; \ - ((u_int8_t *)a)[2] = ((u_int8_t *)&_tmp)[1]; \ - ((u_int8_t *)a)[3] = ((u_int8_t *)&_tmp)[0]; \ -} - -/* - * Little endian <==> big endian 16-bit swap macros. - * M_16_SWAP swap a memory location - * P_16_COPY copy potentially unaligned 2 byte quantities - * P_16_SWAP swap a referenced memory location - */ -#undef M_16_SWAP -#define M_16_SWAP(a) { \ - u_int16_t _tmp; \ - _tmp = (u_int16_t)a; \ - ((u_int8_t *)&a)[0] = ((u_int8_t *)&_tmp)[1]; \ - ((u_int8_t *)&a)[1] = ((u_int8_t *)&_tmp)[0]; \ -} -#undef P_16_COPY -#define P_16_COPY(a, b) { \ - ((u_int8_t *)b)[0] = ((u_int8_t *)a)[0]; \ - ((u_int8_t *)b)[1] = ((u_int8_t *)a)[1]; \ -} -#undef P_16_SWAP -#define P_16_SWAP(a) { \ - u_int16_t _tmp; \ - P_16_COPY(a, &_tmp); \ - ((u_int8_t *)a)[0] = ((u_int8_t *)&_tmp)[1]; \ - ((u_int8_t *)a)[1] = ((u_int8_t *)&_tmp)[0]; \ -} - -#undef SWAP32 -#define SWAP32(p) { \ - P_32_SWAP(p); \ - (p) += sizeof(u_int32_t); \ -} -#undef SWAP16 -#define SWAP16(p) { \ - P_16_SWAP(p); \ - (p) += sizeof(u_int16_t); \ -} - -/* - * Berkeley DB has local versions of htonl() and ntohl() that operate on - * pointers to the right size memory locations; the portability magic for - * finding the real system functions isn't worth the effort. - */ -#undef DB_HTONL -#define DB_HTONL(p) do { \ - if (!__db_isbigendian()) \ - P_32_SWAP(p); \ -} while (0) -#undef DB_NTOHL -#define DB_NTOHL(p) do { \ - if (!__db_isbigendian()) \ - P_32_SWAP(p); \ -} while (0) - -#endif /* !_DB_SWAP_H_ */ diff --git a/storage/bdb/dbinc/db_upgrade.h b/storage/bdb/dbinc/db_upgrade.h deleted file mode 100644 index e4081e9b6ef..00000000000 --- a/storage/bdb/dbinc/db_upgrade.h +++ /dev/null @@ -1,242 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_upgrade.h,v 12.1 2005/06/16 20:21:47 bostic Exp $ - */ - -#ifndef _DB_UPGRADE_H_ -#define _DB_UPGRADE_H_ - -/* - * This file defines the metadata pages from the previous release. - * These structures are only used to upgrade old versions of databases. - */ - -/* Structures from the 3.1 release */ -typedef struct _dbmeta31 { - DB_LSN lsn; /* 00-07: LSN. */ - db_pgno_t pgno; /* 08-11: Current page number. */ - u_int32_t magic; /* 12-15: Magic number. */ - u_int32_t version; /* 16-19: Version. */ - u_int32_t pagesize; /* 20-23: Pagesize. */ - u_int8_t unused1[1]; /* 24: Unused. */ - u_int8_t type; /* 25: Page type. */ - u_int8_t unused2[2]; /* 26-27: Unused. */ - u_int32_t free; /* 28-31: Free list page number. */ - DB_LSN unused3; /* 36-39: Unused. */ - u_int32_t key_count; /* 40-43: Cached key count. */ - u_int32_t record_count; /* 44-47: Cached record count. */ - u_int32_t flags; /* 48-51: Flags: unique to each AM. */ - /* 52-71: Unique file ID. */ - u_int8_t uid[DB_FILE_ID_LEN]; -} DBMETA31; - -typedef struct _btmeta31 { - DBMETA31 dbmeta; /* 00-71: Generic meta-data header. */ - - u_int32_t maxkey; /* 72-75: Btree: Maxkey. */ - u_int32_t minkey; /* 76-79: Btree: Minkey. */ - u_int32_t re_len; /* 80-83: Recno: fixed-length record length. */ - u_int32_t re_pad; /* 84-87: Recno: fixed-length record pad. */ - u_int32_t root; /* 88-92: Root page. */ - - /* - * Minimum page size is 128. - */ -} BTMETA31; - -/************************************************************************ - HASH METADATA PAGE LAYOUT - ************************************************************************/ -typedef struct _hashmeta31 { - DBMETA31 dbmeta; /* 00-71: Generic meta-data page header. */ - - u_int32_t max_bucket; /* 72-75: ID of Maximum bucket in use */ - u_int32_t high_mask; /* 76-79: Modulo mask into table */ - u_int32_t low_mask; /* 80-83: Modulo mask into table lower half */ - u_int32_t ffactor; /* 84-87: Fill factor */ - u_int32_t nelem; /* 88-91: Number of keys in hash table */ - u_int32_t h_charkey; /* 92-95: Value of hash(CHARKEY) */ -#define NCACHED 32 /* number of spare points */ - /* 96-223: Spare pages for overflow */ - u_int32_t spares[NCACHED]; - - /* - * Minimum page size is 256. - */ -} HMETA31; - -/* - * QAM Meta data page structure - * - */ -typedef struct _qmeta31 { - DBMETA31 dbmeta; /* 00-71: Generic meta-data header. */ - - u_int32_t start; /* 72-75: Start offset. */ - u_int32_t first_recno; /* 76-79: First not deleted record. */ - u_int32_t cur_recno; /* 80-83: Last recno allocated. */ - u_int32_t re_len; /* 84-87: Fixed-length record length. */ - u_int32_t re_pad; /* 88-91: Fixed-length record pad. */ - u_int32_t rec_page; /* 92-95: Records Per Page. */ - - /* - * Minimum page size is 128. - */ -} QMETA31; -/* Structures from the 3.2 release */ -typedef struct _qmeta32 { - DBMETA31 dbmeta; /* 00-71: Generic meta-data header. */ - - u_int32_t first_recno; /* 72-75: First not deleted record. */ - u_int32_t cur_recno; /* 76-79: Last recno allocated. */ - u_int32_t re_len; /* 80-83: Fixed-length record length. */ - u_int32_t re_pad; /* 84-87: Fixed-length record pad. */ - u_int32_t rec_page; /* 88-91: Records Per Page. */ - u_int32_t page_ext; /* 92-95: Pages per extent */ - - /* - * Minimum page size is 128. - */ -} QMETA32; - -/* Structures from the 3.0 release */ - -typedef struct _dbmeta30 { - DB_LSN lsn; /* 00-07: LSN. */ - db_pgno_t pgno; /* 08-11: Current page number. */ - u_int32_t magic; /* 12-15: Magic number. */ - u_int32_t version; /* 16-19: Version. */ - u_int32_t pagesize; /* 20-23: Pagesize. */ - u_int8_t unused1[1]; /* 24: Unused. */ - u_int8_t type; /* 25: Page type. */ - u_int8_t unused2[2]; /* 26-27: Unused. */ - u_int32_t free; /* 28-31: Free list page number. */ - u_int32_t flags; /* 32-35: Flags: unique to each AM. */ - /* 36-55: Unique file ID. */ - u_int8_t uid[DB_FILE_ID_LEN]; -} DBMETA30; - -/************************************************************************ - BTREE METADATA PAGE LAYOUT - ************************************************************************/ -typedef struct _btmeta30 { - DBMETA30 dbmeta; /* 00-55: Generic meta-data header. */ - - u_int32_t maxkey; /* 56-59: Btree: Maxkey. */ - u_int32_t minkey; /* 60-63: Btree: Minkey. */ - u_int32_t re_len; /* 64-67: Recno: fixed-length record length. */ - u_int32_t re_pad; /* 68-71: Recno: fixed-length record pad. */ - u_int32_t root; /* 72-75: Root page. */ - - /* - * Minimum page size is 128. - */ -} BTMETA30; - -/************************************************************************ - HASH METADATA PAGE LAYOUT - ************************************************************************/ -typedef struct _hashmeta30 { - DBMETA30 dbmeta; /* 00-55: Generic meta-data page header. */ - - u_int32_t max_bucket; /* 56-59: ID of Maximum bucket in use */ - u_int32_t high_mask; /* 60-63: Modulo mask into table */ - u_int32_t low_mask; /* 64-67: Modulo mask into table lower half */ - u_int32_t ffactor; /* 68-71: Fill factor */ - u_int32_t nelem; /* 72-75: Number of keys in hash table */ - u_int32_t h_charkey; /* 76-79: Value of hash(CHARKEY) */ -#define NCACHED30 32 /* number of spare points */ - /* 80-207: Spare pages for overflow */ - u_int32_t spares[NCACHED30]; - - /* - * Minimum page size is 256. - */ -} HMETA30; - -/************************************************************************ - QUEUE METADATA PAGE LAYOUT - ************************************************************************/ -/* - * QAM Meta data page structure - * - */ -typedef struct _qmeta30 { - DBMETA30 dbmeta; /* 00-55: Generic meta-data header. */ - - u_int32_t start; /* 56-59: Start offset. */ - u_int32_t first_recno; /* 60-63: First not deleted record. */ - u_int32_t cur_recno; /* 64-67: Last recno allocated. */ - u_int32_t re_len; /* 68-71: Fixed-length record length. */ - u_int32_t re_pad; /* 72-75: Fixed-length record pad. */ - u_int32_t rec_page; /* 76-79: Records Per Page. */ - - /* - * Minimum page size is 128. - */ -} QMETA30; - -/* Structures from Release 2.x */ - -/************************************************************************ - BTREE METADATA PAGE LAYOUT - ************************************************************************/ - -/* - * Btree metadata page layout: - */ -typedef struct _btmeta2X { - DB_LSN lsn; /* 00-07: LSN. */ - db_pgno_t pgno; /* 08-11: Current page number. */ - u_int32_t magic; /* 12-15: Magic number. */ - u_int32_t version; /* 16-19: Version. */ - u_int32_t pagesize; /* 20-23: Pagesize. */ - u_int32_t maxkey; /* 24-27: Btree: Maxkey. */ - u_int32_t minkey; /* 28-31: Btree: Minkey. */ - u_int32_t free; /* 32-35: Free list page number. */ - u_int32_t flags; /* 36-39: Flags. */ - u_int32_t re_len; /* 40-43: Recno: fixed-length record length. */ - u_int32_t re_pad; /* 44-47: Recno: fixed-length record pad. */ - /* 48-67: Unique file ID. */ - u_int8_t uid[DB_FILE_ID_LEN]; -} BTMETA2X; - -/************************************************************************ - HASH METADATA PAGE LAYOUT - ************************************************************************/ - -/* - * Hash metadata page layout: - */ -/* Hash Table Information */ -typedef struct hashhdr { /* Disk resident portion */ - DB_LSN lsn; /* 00-07: LSN of the header page */ - db_pgno_t pgno; /* 08-11: Page number (btree compatibility). */ - u_int32_t magic; /* 12-15: Magic NO for hash tables */ - u_int32_t version; /* 16-19: Version ID */ - u_int32_t pagesize; /* 20-23: Bucket/Page Size */ - u_int32_t ovfl_point; /* 24-27: Overflow page allocation location */ - u_int32_t last_freed; /* 28-31: Last freed overflow page pgno */ - u_int32_t max_bucket; /* 32-35: ID of Maximum bucket in use */ - u_int32_t high_mask; /* 36-39: Modulo mask into table */ - u_int32_t low_mask; /* 40-43: Modulo mask into table lower half */ - u_int32_t ffactor; /* 44-47: Fill factor */ - u_int32_t nelem; /* 48-51: Number of keys in hash table */ - u_int32_t h_charkey; /* 52-55: Value of hash(CHARKEY) */ - u_int32_t flags; /* 56-59: Allow duplicates. */ -#define NCACHED2X 32 /* number of spare points */ - /* 60-187: Spare pages for overflow */ - u_int32_t spares[NCACHED2X]; - /* 188-207: Unique file ID. */ - u_int8_t uid[DB_FILE_ID_LEN]; - - /* - * Minimum page size is 256. - */ -} HASHHDR; - -#endif /* !_DB_UPGRADE_H_ */ diff --git a/storage/bdb/dbinc/db_verify.h b/storage/bdb/dbinc/db_verify.h deleted file mode 100644 index 43bbff0c27b..00000000000 --- a/storage/bdb/dbinc/db_verify.h +++ /dev/null @@ -1,218 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_verify.h,v 12.4 2005/06/16 20:21:47 bostic Exp $ - */ - -#ifndef _DB_VERIFY_H_ -#define _DB_VERIFY_H_ - -/* - * Structures and macros for the storage and retrieval of all information - * needed for inter-page verification of a database. - */ - -/* - * EPRINT is the macro for error printing. Takes as an arg the arg set - * for DB->err. - */ -#define EPRINT(x) do { \ - if (!LF_ISSET(DB_SALVAGE)) \ - __db_err x; \ -} while (0) - -/* For fatal type errors--i.e., verifier bugs. */ -#define TYPE_ERR_PRINT(dbenv, func, pgno, ptype) \ - EPRINT(((dbenv), \ - "Page %lu: %s called on nonsensical page of type %lu", \ - (u_long)(pgno), (func), (u_long)(ptype))); - -/* Complain about a totally zeroed page where we don't expect one. */ -#define ZEROPG_ERR_PRINT(dbenv, pgno, str) do { \ - EPRINT(((dbenv), "Page %lu: %s is of inappropriate type %lu", \ - (u_long)(pgno), str, (u_long)P_INVALID)); \ - EPRINT(((dbenv), "Page %lu: totally zeroed page", \ - (u_long)(pgno))); \ -} while (0) - -/* - * Note that 0 is, in general, a valid pgno, despite equalling PGNO_INVALID; - * we have to test it separately where it's not appropriate. - */ -#define IS_VALID_PGNO(x) ((x) <= vdp->last_pgno) - -/* - * Flags understood by the btree structure checks (esp. __bam_vrfy_subtree). - * These share the same space as the global flags to __db_verify, and must not - * dip below 0x00010000. - */ -#define ST_DUPOK 0x00010000 /* Duplicates are acceptable. */ -#define ST_DUPSET 0x00020000 /* Subtree is in a duplicate tree. */ -#define ST_DUPSORT 0x00040000 /* Duplicates are sorted. */ -#define ST_IS_RECNO 0x00080000 /* Subtree is a recno. */ -#define ST_OVFL_LEAF 0x00100000 /* Overflow reffed from leaf page. */ -#define ST_RECNUM 0x00200000 /* Subtree has record numbering on. */ -#define ST_RELEN 0x00400000 /* Subtree has fixed-length records. */ -#define ST_TOPLEVEL 0x00800000 /* Subtree == entire tree */ - -/* - * Flags understood by __bam_salvage and __db_salvage. These need not share - * the same space with the __bam_vrfy_subtree flags, but must share with - * __db_verify. - */ -#define SA_SKIPFIRSTKEY 0x00080000 - -/* - * VRFY_DBINFO is the fundamental structure; it either represents the database - * of subdatabases, or the sole database if there are no subdatabases. - */ -struct __vrfy_dbinfo { - /* Info about this database in particular. */ - DBTYPE type; - - /* List of subdatabase meta pages, if any. */ - LIST_HEAD(__subdbs, __vrfy_childinfo) subdbs; - - /* File-global info--stores VRFY_PAGEINFOs for each page. */ - DB *pgdbp; - - /* Child database--stores VRFY_CHILDINFOs of each page. */ - DB *cdbp; - - /* Page info structures currently in use. */ - LIST_HEAD(__activepips, __vrfy_pageinfo) activepips; - - /* - * DB we use to keep track of which pages are linked somehow - * during verification. 0 is the default, "unseen"; 1 is seen. - */ - DB *pgset; - - /* - * This is a database we use during salvaging to keep track of which - * overflow and dup pages we need to come back to at the end and print - * with key "UNKNOWN". Pages which print with a good key get set - * to SALVAGE_IGNORE; others get set, as appropriate, to SALVAGE_LDUP, - * SALVAGE_LRECNODUP, SALVAGE_OVERFLOW for normal db overflow pages, - * and SALVAGE_BTREE, SALVAGE_LRECNO, and SALVAGE_HASH for subdb - * pages. - */ -#define SALVAGE_INVALID 0 -#define SALVAGE_IGNORE 1 -#define SALVAGE_LDUP 2 -#define SALVAGE_LRECNODUP 3 -#define SALVAGE_OVERFLOW 4 -#define SALVAGE_LBTREE 5 -#define SALVAGE_HASH 6 -#define SALVAGE_LRECNO 7 - DB *salvage_pages; - - db_pgno_t last_pgno; - db_pgno_t pgs_remaining; /* For dbp->db_feedback(). */ - - /* - * These are used during __bam_vrfy_subtree to keep track, while - * walking up and down the Btree structure, of the prev- and next-page - * chain of leaf pages and verify that it's intact. Also, make sure - * that this chain contains pages of only one type. - */ - db_pgno_t prev_pgno; - db_pgno_t next_pgno; - u_int8_t leaf_type; - - /* Queue needs these to verify data pages in the first pass. */ - u_int32_t re_pad; /* Record pad character. */ - u_int32_t re_len; /* Record length. */ - u_int32_t rec_page; - u_int32_t page_ext; - u_int32_t first_recno; - u_int32_t last_recno; - int nextents; - db_pgno_t *extents; - -#define SALVAGE_PRINTABLE 0x01 /* Output printable chars literally. */ -#define SALVAGE_PRINTHEADER 0x02 /* Print the unknown-key header. */ -#define SALVAGE_PRINTFOOTER 0x04 /* Print the unknown-key footer. */ -#define VRFY_LEAFCHAIN_BROKEN 0x08 /* Lost one or more Btree leaf pgs. */ -#define VRFY_QMETA_SET 0x10 /* We've seen a QUEUE meta page and - set things up for it. */ - u_int32_t flags; -}; /* VRFY_DBINFO */ - -/* - * The amount of state information we need per-page is small enough that - * it's not worth the trouble to define separate structures for each - * possible type of page, and since we're doing verification with these we - * have to be open to the possibility that page N will be of a completely - * unexpected type anyway. So we define one structure here with all the - * info we need for inter-page verification. - */ -struct __vrfy_pageinfo { - u_int8_t type; - u_int8_t bt_level; - u_int8_t unused1; - u_int8_t unused2; - db_pgno_t pgno; - db_pgno_t prev_pgno; - db_pgno_t next_pgno; - - /* meta pages */ - db_pgno_t root; - db_pgno_t free; /* Free list head. */ - - db_indx_t entries; /* Actual number of entries. */ - u_int16_t unused; - db_recno_t rec_cnt; /* Record count. */ - u_int32_t re_pad; /* Record pad character. */ - u_int32_t re_len; /* Record length. */ - u_int32_t bt_minkey; - u_int32_t h_ffactor; - u_int32_t h_nelem; - - /* overflow pages */ - /* - * Note that refcount is the refcount for an overflow page; pi_refcount - * is this structure's own refcount! - */ - u_int32_t refcount; - u_int32_t olen; - -#define VRFY_DUPS_UNSORTED 0x0001 /* Have to flag the negative! */ -#define VRFY_HAS_CHKSUM 0x0002 -#define VRFY_HAS_DUPS 0x0004 -#define VRFY_HAS_DUPSORT 0x0008 /* Has the flag set. */ -#define VRFY_HAS_RECNUMS 0x0010 -#define VRFY_HAS_SUBDBS 0x0020 -#define VRFY_INCOMPLETE 0x0040 /* Meta or item order checks incomp. */ -#define VRFY_IS_ALLZEROES 0x0080 /* Hash page we haven't touched? */ -#define VRFY_IS_FIXEDLEN 0x0100 -#define VRFY_IS_RECNO 0x0200 -#define VRFY_IS_RRECNO 0x0400 -#define VRFY_OVFL_LEAFSEEN 0x0800 - u_int32_t flags; - - LIST_ENTRY(__vrfy_pageinfo) links; - u_int32_t pi_refcount; -}; /* VRFY_PAGEINFO */ - -struct __vrfy_childinfo { - /* The following fields are set by the caller of __db_vrfy_childput. */ - db_pgno_t pgno; - -#define V_DUPLICATE 1 /* off-page dup metadata */ -#define V_OVERFLOW 2 /* overflow page */ -#define V_RECNO 3 /* btree internal or leaf page */ - u_int32_t type; - db_recno_t nrecs; /* record count on a btree subtree */ - u_int32_t tlen; /* ovfl. item total size */ - - /* The following field is maintained by __db_vrfy_childput. */ - u_int32_t refcnt; /* # of times parent points to child. */ - - LIST_ENTRY(__vrfy_childinfo) links; -}; /* VRFY_CHILDINFO */ - -#endif /* !_DB_VERIFY_H_ */ diff --git a/storage/bdb/dbinc/debug.h b/storage/bdb/dbinc/debug.h deleted file mode 100644 index 642920eb2f2..00000000000 --- a/storage/bdb/dbinc/debug.h +++ /dev/null @@ -1,264 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1998-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: debug.h,v 12.2 2005/06/16 20:21:47 bostic Exp $ - */ - -#ifndef _DB_DEBUG_H_ -#define _DB_DEBUG_H_ - -#if defined(__cplusplus) -extern "C" { -#endif - -/* - * Turn on additional error checking in gcc 3.X. - */ -#if !defined(__GNUC__) || __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) -#define __attribute__(s) -#endif - -/* - * When running with #DIAGNOSTIC defined, we smash memory and do memory - * guarding with a special byte value. - */ -#define CLEAR_BYTE 0xdb -#define GUARD_BYTE 0xdc - -/* - * DB assertions. - * - * Use __STDC__ rather than STDC_HEADERS, the #e construct is ANSI C specific. - */ -#if defined(__STDC__) && defined(DIAGNOSTIC) -#define DB_ASSERT(e) ((e) ? (void)0 : __db_assert(#e, __FILE__, __LINE__)) -#else -#define DB_ASSERT(e) -#endif - -/* - * "Shut that bloody compiler up!" - * - * Unused, or not-used-yet variable. We need to write and then read the - * variable, some compilers are too bloody clever by half. - */ -#define COMPQUIET(n, v) \ - (n) = (v); \ - (n) = (n) - -/* - * Purify and other run-time tools complain about uninitialized reads/writes - * of structure fields whose only purpose is padding, as well as when heap - * memory that was never initialized is written to disk. - */ -#ifdef UMRW -#define UMRW_SET(v) (v) = 0 -#else -#define UMRW_SET(v) -#endif - -/* - * Message handling. Use a macro instead of a function because va_list - * references to variadic arguments cannot be reset to the beginning of the - * variadic argument list (and then rescanned), by functions other than the - * original routine that took the variadic list of arguments. - */ -#if defined(STDC_HEADERS) || defined(__cplusplus) -#define DB_REAL_ERR(env, error, error_set, default_stream, fmt) { \ - va_list ap; \ - \ - /* Call the application's callback function, if specified. */ \ - va_start(ap, fmt); \ - if ((env) != NULL && (env)->db_errcall != NULL) \ - __db_errcall(env, error, error_set, fmt, ap); \ - va_end(ap); \ - \ - /* Write to the application's file descriptor, if specified. */\ - va_start(ap, fmt); \ - if ((env) != NULL && (env)->db_errfile != NULL) \ - __db_errfile(env, error, error_set, fmt, ap); \ - va_end(ap); \ - \ - /* \ - * If we have a default and we didn't do either of the above, \ - * write to the default. \ - */ \ - va_start(ap, fmt); \ - if ((default_stream) && ((env) == NULL || \ - ((env)->db_errcall == NULL && (env)->db_errfile == NULL))) \ - __db_errfile(env, error, error_set, fmt, ap); \ - va_end(ap); \ -} -#else -#define DB_REAL_ERR(env, error, error_set, default_stream, fmt) { \ - va_list ap; \ - \ - /* Call the application's callback function, if specified. */ \ - va_start(ap); \ - if ((env) != NULL && (env)->db_errcall != NULL) \ - __db_errcall(env, error, error_set, fmt, ap); \ - va_end(ap); \ - \ - /* Write to the application's file descriptor, if specified. */\ - va_start(ap); \ - if ((env) != NULL && (env)->db_errfile != NULL) \ - __db_errfile(env, error, error_set, fmt, ap); \ - va_end(ap); \ - \ - /* \ - * If we have a default and we didn't do either of the above, \ - * write to the default. \ - */ \ - va_start(ap); \ - if ((default_stream) && ((env) == NULL || \ - ((env)->db_errcall == NULL && (env)->db_errfile == NULL))) \ - __db_errfile(env, error, error_set, fmt, ap); \ - va_end(ap); \ -} -#endif -#if defined(STDC_HEADERS) || defined(__cplusplus) -#define DB_REAL_MSG(env, fmt) { \ - va_list ap; \ - \ - /* Call the application's callback function, if specified. */ \ - va_start(ap, fmt); \ - if ((env) != NULL && (env)->db_msgcall != NULL) \ - __db_msgcall(env, fmt, ap); \ - va_end(ap); \ - \ - /* \ - * If the application specified a file descriptor, or we wrote \ - * to neither the application's callback routine or to its file \ - * descriptor, write to stdout. \ - */ \ - va_start(ap, fmt); \ - if ((env) == NULL || \ - (env)->db_msgfile != NULL || (env)->db_msgcall == NULL) { \ - __db_msgfile(env, fmt, ap); \ - } \ - va_end(ap); \ -} -#else -#define DB_REAL_MSG(env, fmt) { \ - va_list ap; \ - \ - /* Call the application's callback function, if specified. */ \ - va_start(ap); \ - if ((env) != NULL && (env)->db_msgcall != NULL) \ - __db_msgcall(env, fmt, ap); \ - va_end(ap); \ - \ - /* \ - * If the application specified a file descriptor, or we wrote \ - * to neither the application's callback routine or to its file \ - * descriptor, write to stdout. \ - */ \ - va_start(ap); \ - if ((env) == NULL || \ - (env)->db_msgfile != NULL || (env)->db_msgcall == NULL) { \ - __db_msgfile(env, fmt, ap); \ - } \ - va_end(ap); \ -} -#endif - -/* - * Debugging macro to log operations. - * If DEBUG_WOP is defined, log operations that modify the database. - * If DEBUG_ROP is defined, log operations that read the database. - * - * D dbp - * T txn - * O operation (string) - * K key - * A data - * F flags - */ -#define LOG_OP(C, T, O, K, A, F) { \ - DB_LSN __lsn; \ - DBT __op; \ - if (DBC_LOGGING((C))) { \ - memset(&__op, 0, sizeof(__op)); \ - __op.data = O; \ - __op.size = strlen(O) + 1; \ - (void)__db_debug_log((C)->dbp->dbenv, T, &__lsn, 0, \ - &__op, (C)->dbp->log_filename->id, K, A, F); \ - } \ -} -#ifdef DEBUG_ROP -#define DEBUG_LREAD(C, T, O, K, A, F) LOG_OP(C, T, O, K, A, F) -#else -#define DEBUG_LREAD(C, T, O, K, A, F) -#endif -#ifdef DEBUG_WOP -#define DEBUG_LWRITE(C, T, O, K, A, F) LOG_OP(C, T, O, K, A, F) -#else -#define DEBUG_LWRITE(C, T, O, K, A, F) -#endif - -/* - * Hook for testing recovery at various places in the create/delete paths. - * Hook for testing subdb locks. - */ -#if CONFIG_TEST -#define DB_TEST_SUBLOCKS(env, flags) do { \ - if ((env)->test_abort == DB_TEST_SUBDB_LOCKS) \ - (flags) |= DB_LOCK_NOWAIT; \ -} while (0) - -#define DB_ENV_TEST_RECOVERY(env, val, ret, name) do { \ - int __ret; \ - PANIC_CHECK((env)); \ - if ((env)->test_copy == (val)) { \ - /* COPY the FILE */ \ - if ((__ret = __db_testcopy((env), NULL, (name))) != 0) \ - (ret) = __db_panic((env), __ret); \ - } \ - if ((env)->test_abort == (val)) { \ - /* ABORT the TXN */ \ - (env)->test_abort = 0; \ - (ret) = EINVAL; \ - goto db_tr_err; \ - } \ -} while (0) - -#define DB_TEST_RECOVERY(dbp, val, ret, name) do { \ - int __ret; \ - PANIC_CHECK((dbp)->dbenv); \ - if ((dbp)->dbenv->test_copy == (val)) { \ - /* Copy the file. */ \ - if (F_ISSET((dbp), \ - DB_AM_OPEN_CALLED) && (dbp)->mpf != NULL) \ - (void)__db_sync(dbp); \ - if ((__ret = \ - __db_testcopy((dbp)->dbenv, (dbp), (name))) != 0) \ - (ret) = __db_panic((dbp)->dbenv, __ret); \ - } \ - if ((dbp)->dbenv->test_abort == (val)) { \ - /* Abort the transaction. */ \ - (dbp)->dbenv->test_abort = 0; \ - (ret) = EINVAL; \ - goto db_tr_err; \ - } \ -} while (0) - -#define DB_TEST_RECOVERY_LABEL db_tr_err: - -#define DB_TEST_WAIT(env, val) \ - if ((val) != 0) \ - __os_sleep((env), (u_long)(val), 0) -#else -#define DB_TEST_SUBLOCKS(env, flags) -#define DB_ENV_TEST_RECOVERY(env, val, ret, name) -#define DB_TEST_RECOVERY(dbp, val, ret, name) -#define DB_TEST_RECOVERY_LABEL -#define DB_TEST_WAIT(env, val) -#endif - -#if defined(__cplusplus) -} -#endif -#endif /* !_DB_DEBUG_H_ */ diff --git a/storage/bdb/dbinc/fop.h b/storage/bdb/dbinc/fop.h deleted file mode 100644 index 98f7c59b362..00000000000 --- a/storage/bdb/dbinc/fop.h +++ /dev/null @@ -1,21 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2001-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: fop.h,v 12.3 2005/10/04 18:22:22 bostic Exp $ - */ - -#ifndef _FOP_H_ -#define _FOP_H_ - -#define MAKE_INMEM(D) do { \ - F_SET((D), DB_AM_INMEM); \ - (void)__memp_set_flags((D)->mpf, DB_MPOOL_NOFILE, 1); \ -} while (0) - -#include "dbinc_auto/fileops_auto.h" -#include "dbinc_auto/fileops_ext.h" - -#endif /* !_FOP_H_ */ diff --git a/storage/bdb/dbinc/globals.h b/storage/bdb/dbinc/globals.h deleted file mode 100644 index aaef6309fb1..00000000000 --- a/storage/bdb/dbinc/globals.h +++ /dev/null @@ -1,92 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: globals.h,v 12.1 2005/06/16 20:21:47 bostic Exp $ - */ - -/******************************************************* - * Global variables. - * - * Held in a single structure to minimize the name-space pollution. - *******************************************************/ -#ifdef HAVE_VXWORKS -#include "semLib.h" -#endif - -typedef struct __db_globals { -#ifdef HAVE_VXWORKS - u_int32_t db_global_init; /* VxWorks: inited */ - SEM_ID db_global_lock; /* VxWorks: global semaphore */ -#endif - /* XA: list of opened environments. */ - TAILQ_HEAD(__db_envq, __db_env) db_envq; - - char *db_line; /* DB display string. */ - - int (*j_close) __P((int)); /* Underlying OS interface jump table.*/ - void (*j_dirfree) __P((char **, int)); - int (*j_dirlist) __P((const char *, char ***, int *)); - int (*j_exists) __P((const char *, int *)); - void (*j_free) __P((void *)); - int (*j_fsync) __P((int)); - int (*j_ftruncate) __P((int, off_t)); - int (*j_ioinfo) __P((const char *, - int, u_int32_t *, u_int32_t *, u_int32_t *)); - void *(*j_malloc) __P((size_t)); - int (*j_map) __P((char *, size_t, int, int, void **)); - int (*j_open) __P((const char *, int, ...)); - ssize_t (*j_pread) __P((int, void *, size_t, off_t)); - ssize_t (*j_pwrite) __P((int, const void *, size_t, off_t)); - ssize_t (*j_read) __P((int, void *, size_t)); - void *(*j_realloc) __P((void *, size_t)); - int (*j_rename) __P((const char *, const char *)); - int (*j_seek) __P((int, off_t, int)); - int (*j_sleep) __P((u_long, u_long)); - int (*j_unlink) __P((const char *)); - int (*j_unmap) __P((void *, size_t)); - ssize_t (*j_write) __P((int, const void *, size_t)); - int (*j_yield) __P((void)); -} DB_GLOBALS; - -#ifdef DB_INITIALIZE_DB_GLOBALS -DB_GLOBALS __db_global_values = { -#ifdef HAVE_VXWORKS - 0, /* VxWorks: initialized */ - NULL, /* VxWorks: global semaphore */ -#endif - /* XA: list of opened environments. */ - {NULL, &__db_global_values.db_envq.tqh_first}, - - "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=", - - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL -}; -#else -extern DB_GLOBALS __db_global_values; -#endif - -#define DB_GLOBAL(v) __db_global_values.v diff --git a/storage/bdb/dbinc/hash.h b/storage/bdb/dbinc/hash.h deleted file mode 100644 index feb124cbab2..00000000000 --- a/storage/bdb/dbinc/hash.h +++ /dev/null @@ -1,147 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994 - * Margo Seltzer. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Margo Seltzer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: hash.h,v 12.1 2005/06/16 20:21:47 bostic Exp $ - */ - -#ifndef _DB_HASH_H_ -#define _DB_HASH_H_ - -/* Hash internal structure. */ -typedef struct hash_t { - db_pgno_t meta_pgno; /* Page number of the meta data page. */ - u_int32_t h_ffactor; /* Fill factor. */ - u_int32_t h_nelem; /* Number of elements. */ - /* Hash function. */ - u_int32_t (*h_hash) __P((DB *, const void *, u_int32_t)); -} HASH; - -/* Cursor structure definitions. */ -typedef struct cursor_t { - /* struct __dbc_internal */ - __DBC_INTERNAL - - /* Hash private part */ - - /* Per-thread information */ - DB_LOCK hlock; /* Metadata page lock. */ - HMETA *hdr; /* Pointer to meta-data page. */ - PAGE *split_buf; /* Temporary buffer for splits. */ - - /* Hash cursor information */ - db_pgno_t bucket; /* Bucket we are traversing. */ - db_pgno_t lbucket; /* Bucket for which we are locked. */ - db_indx_t dup_off; /* Offset within a duplicate set. */ - db_indx_t dup_len; /* Length of current duplicate. */ - db_indx_t dup_tlen; /* Total length of duplicate entry. */ - u_int32_t seek_size; /* Number of bytes we need for add. */ - db_pgno_t seek_found_page;/* Page on which we can insert. */ - u_int32_t order; /* Relative order among deleted curs. */ - -#define H_CONTINUE 0x0001 /* Join--search strictly fwd for data */ -#define H_DELETED 0x0002 /* Cursor item is deleted. */ -#define H_DIRTY 0x0004 /* Meta-data page needs to be written */ -#define H_DUPONLY 0x0008 /* Dups only; do not change key. */ -#define H_EXPAND 0x0010 /* Table expanded. */ -#define H_ISDUP 0x0020 /* Cursor is within duplicate set. */ -#define H_NEXT_NODUP 0x0040 /* Get next non-dup entry. */ -#define H_NOMORE 0x0080 /* No more entries in bucket. */ -#define H_OK 0x0100 /* Request succeeded. */ - u_int32_t flags; -} HASH_CURSOR; - -/* Test string. */ -#define CHARKEY "%$sniglet^&" - -/* Overflow management */ -/* - * The spares table indicates the page number at which each doubling begins. - * From this page number we subtract the number of buckets already allocated - * so that we can do a simple addition to calculate the page number here. - */ -#define BS_TO_PAGE(bucket, spares) \ - ((bucket) + (spares)[__db_log2((bucket) + 1)]) -#define BUCKET_TO_PAGE(I, B) (BS_TO_PAGE((B), (I)->hdr->spares)) - -/* Constraints about much data goes on a page. */ - -#define MINFILL 4 -#define ISBIG(I, N) (((N) > ((I)->hdr->dbmeta.pagesize / MINFILL)) ? 1 : 0) - -/* Shorthands for accessing structure */ -#define NDX_INVALID 0xFFFF -#define BUCKET_INVALID 0xFFFFFFFF - -/* On page duplicates are stored as a string of size-data-size triples. */ -#define DUP_SIZE(len) ((len) + 2 * sizeof(db_indx_t)) - -/* Log messages types (these are subtypes within a record type) */ -#define PAIR_KEYMASK 0x1 -#define PAIR_DATAMASK 0x2 -#define PAIR_DUPMASK 0x4 -#define PAIR_MASK 0xf -#define PAIR_ISKEYBIG(N) (N & PAIR_KEYMASK) -#define PAIR_ISDATABIG(N) (N & PAIR_DATAMASK) -#define PAIR_ISDATADUP(N) (N & PAIR_DUPMASK) -#define OPCODE_OF(N) (N & ~PAIR_MASK) - -#define PUTPAIR 0x20 -#define DELPAIR 0x30 -#define PUTOVFL 0x40 -#define DELOVFL 0x50 -#define HASH_UNUSED1 0x60 -#define HASH_UNUSED2 0x70 -#define SPLITOLD 0x80 -#define SPLITNEW 0x90 - -typedef enum { - DB_HAM_CHGPG = 1, - DB_HAM_DELFIRSTPG = 2, - DB_HAM_DELMIDPG = 3, - DB_HAM_DELLASTPG = 4, - DB_HAM_DUP = 5, - DB_HAM_SPLIT = 6 -} db_ham_mode; - -#include "dbinc_auto/hash_auto.h" -#include "dbinc_auto/hash_ext.h" -#include "dbinc/db_am.h" -#endif /* !_DB_HASH_H_ */ diff --git a/storage/bdb/dbinc/hmac.h b/storage/bdb/dbinc/hmac.h deleted file mode 100644 index a30756febcf..00000000000 --- a/storage/bdb/dbinc/hmac.h +++ /dev/null @@ -1,32 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: hmac.h,v 12.1 2005/06/16 20:21:48 bostic Exp $ - */ - -#ifndef _DB_HMAC_H_ -#define _DB_HMAC_H_ - -/* - * Algorithm specific information. - */ -/* - * SHA1 checksumming - */ -typedef struct { - u_int32_t state[5]; - u_int32_t count[2]; - unsigned char buffer[64]; -} SHA1_CTX; - -/* - * AES assumes the SHA1 checksumming (also called MAC) - */ -#define DB_MAC_MAGIC "mac derivation key magic value" -#define DB_ENC_MAGIC "encryption and decryption key value magic" - -#include "dbinc_auto/hmac_ext.h" -#endif /* !_DB_HMAC_H_ */ diff --git a/storage/bdb/dbinc/lock.h b/storage/bdb/dbinc/lock.h deleted file mode 100644 index b3b7186bf6c..00000000000 --- a/storage/bdb/dbinc/lock.h +++ /dev/null @@ -1,236 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: lock.h,v 12.7 2005/10/07 20:21:23 ubell Exp $ - */ - -#ifndef _DB_LOCK_H_ -#define _DB_LOCK_H_ - -#define DB_LOCK_DEFAULT_N 1000 /* Default # of locks in region. */ - -/* - * The locker id space is divided between the transaction manager and the lock - * manager. Lock IDs start at 1 and go to DB_LOCK_MAXID. Txn IDs start at - * DB_LOCK_MAXID + 1 and go up to TXN_MAXIMUM. - */ -#define DB_LOCK_INVALIDID 0 -#define DB_LOCK_MAXID 0x7fffffff - -/* - * Out of band value for a lock. Locks contain an offset into a lock region, - * so we use an invalid region offset to indicate an invalid or unset lock. - */ -#define LOCK_INVALID INVALID_ROFF -#define LOCK_ISSET(lock) ((lock).off != LOCK_INVALID) -#define LOCK_INIT(lock) ((lock).off = LOCK_INVALID) - -/* - * Macro to identify a write lock for the purpose of counting locks - * for the NUMWRITES option to deadlock detection. - */ -#define IS_WRITELOCK(m) \ - ((m) == DB_LOCK_WRITE || (m) == DB_LOCK_WWRITE || \ - (m) == DB_LOCK_IWRITE || (m) == DB_LOCK_IWR) - -/* - * Lock timers. - */ -typedef struct { - u_int32_t tv_sec; /* Seconds. */ - u_int32_t tv_usec; /* Microseconds. */ -} db_timeval_t; - -#define LOCK_TIME_ISVALID(time) ((time)->tv_sec != 0) -#define LOCK_SET_TIME_INVALID(time) ((time)->tv_sec = 0) -#define LOCK_TIME_ISMAX(time) ((time)->tv_sec == UINT32_MAX) -#define LOCK_SET_TIME_MAX(time) ((time)->tv_sec = UINT32_MAX) -#define LOCK_TIME_EQUAL(t1, t2) \ - ((t1)->tv_sec == (t2)->tv_sec && (t1)->tv_usec == (t2)->tv_usec) -#define LOCK_TIME_GREATER(t1, t2) \ - ((t1)->tv_sec > (t2)->tv_sec || \ - ((t1)->tv_sec == (t2)->tv_sec && (t1)->tv_usec > (t2)->tv_usec)) - -/* Macros to lock/unlock the lock region as a whole. */ -#define LOCK_SYSTEM_LOCK(dbenv) \ - MUTEX_LOCK(dbenv, ((DB_LOCKREGION *)((DB_LOCKTAB *) \ - (dbenv)->lk_handle)->reginfo.primary)->mtx_region) -#define LOCK_SYSTEM_UNLOCK(dbenv) \ - MUTEX_UNLOCK(dbenv, ((DB_LOCKREGION *)((DB_LOCKTAB *) \ - (dbenv)->lk_handle)->reginfo.primary)->mtx_region) - -/* - * DB_LOCKREGION -- - * The lock shared region. - */ -typedef struct __db_lockregion { - db_mutex_t mtx_region; /* Region mutex. */ - - u_int32_t need_dd; /* flag for deadlock detector */ - u_int32_t detect; /* run dd on every conflict */ - db_timeval_t next_timeout; /* next time to expire a lock */ - /* free lock header */ - SH_TAILQ_HEAD(__flock) free_locks; - /* free obj header */ - SH_TAILQ_HEAD(__fobj) free_objs; - /* free locker header */ - SH_TAILQ_HEAD(__flocker) free_lockers; - SH_TAILQ_HEAD(__dobj) dd_objs; /* objects with waiters */ - SH_TAILQ_HEAD(__lkrs) lockers; /* list of lockers */ - - db_timeout_t lk_timeout; /* timeout for locks. */ - db_timeout_t tx_timeout; /* timeout for txns. */ - - u_int32_t locker_t_size; /* size of locker hash table */ - u_int32_t object_t_size; /* size of object hash table */ - - roff_t conf_off; /* offset of conflicts array */ - roff_t obj_off; /* offset of object hash table */ - roff_t locker_off; /* offset of locker hash table */ - - DB_LOCK_STAT stat; /* stats about locking. */ -} DB_LOCKREGION; - -/* - * Since we will store DBTs in shared memory, we need the equivalent of a - * DBT that will work in shared memory. - */ -typedef struct __sh_dbt { - u_int32_t size; /* Byte length. */ - roff_t off; /* Region offset. */ -} SH_DBT; - -#define SH_DBT_PTR(p) ((void *)(((u_int8_t *)(p)) + (p)->off)) - -/* - * Object structures; these live in the object hash table. - */ -typedef struct __db_lockobj { - SH_DBT lockobj; /* Identifies object locked. */ - SH_TAILQ_ENTRY links; /* Links for free list or hash list. */ - SH_TAILQ_ENTRY dd_links; /* Links for dd list. */ - SH_TAILQ_HEAD(__waitl) waiters; /* List of waiting locks. */ - SH_TAILQ_HEAD(__holdl) holders; /* List of held locks. */ - /* Declare room in the object to hold - * typical DB lock structures so that - * we do not have to allocate them from - * shalloc at run-time. */ - u_int8_t objdata[sizeof(struct __db_ilock)]; -} DB_LOCKOBJ; - -/* - * Locker structures; these live in the locker hash table. - */ -typedef struct __db_locker { - u_int32_t id; /* Locker id. */ - - pid_t pid; /* Process owning locker ID */ - db_threadid_t tid; /* Thread owning locker ID */ - - u_int32_t dd_id; /* Deadlock detector id. */ - - u_int32_t nlocks; /* Number of locks held. */ - u_int32_t nwrites; /* Number of write locks held. */ - - roff_t master_locker; /* Locker of master transaction. */ - roff_t parent_locker; /* Parent of this child. */ - SH_LIST_HEAD(_child) child_locker; /* List of descendant txns; - only used in a "master" - txn. */ - SH_LIST_ENTRY child_link; /* Links transactions in the family; - elements of the child_locker - list. */ - SH_TAILQ_ENTRY links; /* Links for free and hash list. */ - SH_TAILQ_ENTRY ulinks; /* Links in-use list. */ - SH_LIST_HEAD(_held) heldby; /* Locks held by this locker. */ - db_timeval_t lk_expire; /* When current lock expires. */ - db_timeval_t tx_expire; /* When this txn expires. */ - db_timeout_t lk_timeout; /* How long do we let locks live. */ - -#define DB_LOCKER_DELETED 0x0001 -#define DB_LOCKER_DIRTY 0x0002 -#define DB_LOCKER_INABORT 0x0004 -#define DB_LOCKER_TIMEOUT 0x0008 - u_int32_t flags; -} DB_LOCKER; - -/* - * DB_LOCKTAB -- - * The primary library lock data structure (i.e., the one referenced - * by the environment, as opposed to the internal one laid out in the region.) - */ -typedef struct __db_locktab { - DB_ENV *dbenv; /* Environment. */ - REGINFO reginfo; /* Region information. */ - u_int8_t *conflicts; /* Pointer to conflict matrix. */ - DB_HASHTAB *obj_tab; /* Beginning of object hash table. */ - DB_HASHTAB *locker_tab; /* Beginning of locker hash table. */ -} DB_LOCKTAB; - -/* - * Test for conflicts. - * - * Cast HELD and WANTED to ints, they are usually db_lockmode_t enums. - */ -#define CONFLICTS(T, R, HELD, WANTED) \ - (T)->conflicts[((int)HELD) * (R)->stat.st_nmodes + ((int)WANTED)] - -#define OBJ_LINKS_VALID(L) ((L)->links.stqe_prev != -1) - -struct __db_lock { - /* - * Wait on mutex to wait on lock. You reference your own mutex with - * ID 0 and others reference your mutex with ID 1. - */ - db_mutex_t mtx_lock; - - u_int32_t holder; /* Who holds this lock. */ - u_int32_t gen; /* Generation count. */ - SH_TAILQ_ENTRY links; /* Free or holder/waiter list. */ - SH_LIST_ENTRY locker_links; /* List of locks held by a locker. */ - u_int32_t refcount; /* Reference count the lock. */ - db_lockmode_t mode; /* What sort of lock. */ - roff_t obj; /* Relative offset of object struct. */ - db_status_t status; /* Status of this lock. */ -}; - -/* - * Flag values for __lock_put_internal: - * DB_LOCK_DOALL: Unlock all references in this lock (instead of only 1). - * DB_LOCK_FREE: Free the lock (used in checklocker). - * DB_LOCK_NOPROMOTE: Don't bother running promotion when releasing locks - * (used by __lock_put_internal). - * DB_LOCK_UNLINK: Remove from the locker links (used in checklocker). - * Make sure that these do not conflict with the interface flags because - * we pass some of those around. - */ -#define DB_LOCK_DOALL 0x010000 -#define DB_LOCK_FREE 0x040000 -#define DB_LOCK_NOPROMOTE 0x080000 -#define DB_LOCK_UNLINK 0x100000 -#define DB_LOCK_NOREGION 0x200000 -#define DB_LOCK_NOWAITERS 0x400000 - -/* - * Macros to get/release different types of mutexes. - */ -#define OBJECT_LOCK(lt, reg, obj, ndx) \ - ndx = __lock_ohash(obj) % (reg)->object_t_size -#define SHOBJECT_LOCK(lt, reg, shobj, ndx) \ - ndx = __lock_lhash(shobj) % (reg)->object_t_size - -/* - * __lock_locker_hash -- - * Hash function for entering lockers into the locker hash table. - * Since these are simply 32-bit unsigned integers at the moment, - * just return the locker value. - */ -#define __lock_locker_hash(locker) (locker) -#define LOCKER_LOCK(lt, reg, locker, ndx) \ - ndx = __lock_locker_hash(locker) % (reg)->locker_t_size; - -#include "dbinc_auto/lock_ext.h" -#endif /* !_DB_LOCK_H_ */ diff --git a/storage/bdb/dbinc/log.h b/storage/bdb/dbinc/log.h deleted file mode 100644 index 6f97526441f..00000000000 --- a/storage/bdb/dbinc/log.h +++ /dev/null @@ -1,387 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: log.h,v 12.12 2005/10/20 18:57:05 bostic Exp $ - */ - -#ifndef _LOG_H_ -#define _LOG_H_ - -/******************************************************* - * DBREG: - * The DB file register code keeps track of open files. It's stored - * in the log subsystem's shared region, and so appears in the log.h - * header file, but is logically separate. - *******************************************************/ -/* - * The per-process table that maps log file-id's to DB structures. - */ -typedef struct __db_entry { - DB *dbp; /* Open dbp for this file id. */ - int deleted; /* File was not found during open. */ -} DB_ENTRY; - -/* - * FNAME -- - * File name and id. - */ -struct __fname { - SH_TAILQ_ENTRY q; /* File name queue. */ - - int32_t id; /* Logging file id. */ - DBTYPE s_type; /* Saved DB type. */ - - roff_t name_off; /* Name offset. */ - db_pgno_t meta_pgno; /* Page number of the meta page. */ - u_int8_t ufid[DB_FILE_ID_LEN]; /* Unique file id. */ - - u_int32_t create_txnid; /* - * Txn ID of the DB create, stored so - * we can log it at register time. - */ -#define DB_FNAME_NOTLOGGED 0x01 /* Log of close failed. */ -#define DB_FNAME_DURABLE 0x02 /* File is durable. */ - u_int32_t flags; -}; - -/* File open/close register log record opcodes. */ -#define DBREG_CHKPNT 1 /* Checkpoint: file name/id dump. */ -#define DBREG_CLOSE 2 /* File close. */ -#define DBREG_OPEN 3 /* File open. */ -#define DBREG_PREOPEN 4 /* Open in mpool only. */ -#define DBREG_RCLOSE 5 /* File close after recovery. */ -#define DBREG_REOPEN 6 /* Open for in-memory database. */ - -/******************************************************* - * LOG: - * The log subsystem information. - *******************************************************/ -struct __db_log; typedef struct __db_log DB_LOG; -struct __hdr; typedef struct __hdr HDR; -struct __log; typedef struct __log LOG; -struct __log_persist; typedef struct __log_persist LOGP; - -#define LFPREFIX "log." /* Log file name prefix. */ -#define LFNAME "log.%010d" /* Log file name template. */ -#define LFNAME_V1 "log.%05d" /* Log file name template, rev 1. */ - -#define LG_MAX_DEFAULT (10 * MEGABYTE) /* 10 MB. */ -#define LG_MAX_INMEM (256 * 1024) /* 256 KB. */ -#define LG_BSIZE_DEFAULT (32 * 1024) /* 32 KB. */ -#define LG_BSIZE_INMEM (1 * MEGABYTE) /* 1 MB. */ -#define LG_BASE_REGION_SIZE (60 * 1024) /* 60 KB. */ - -/* - * DB_LOG - * Per-process log structure. - */ -struct __db_log { - /* - * These fields need to be protected for multi-threaded support. - */ - db_mutex_t mtx_dbreg; /* Mutex for thread protection. */ - - DB_ENTRY *dbentry; /* Recovery file-id mapping. */ -#define DB_GROW_SIZE 64 - int32_t dbentry_cnt; /* Entries. Grows by DB_GROW_SIZE. */ - - /* - * These fields are only accessed when the region lock is held, so - * they do not have to be protected by the thread lock as well. - */ - u_int32_t lfname; /* Log file "name". */ - DB_FH *lfhp; /* Log file handle. */ - - u_int8_t *bufp; /* Region buffer. */ - - /* These fields are not thread protected. */ - DB_ENV *dbenv; /* Reference to error information. */ - REGINFO reginfo; /* Region information. */ - -#define DBLOG_RECOVER 0x01 /* We are in recovery. */ -#define DBLOG_FORCE_OPEN 0x02 /* Force the DB open even if it appears - * to be deleted. */ - u_int32_t flags; -}; - -/* - * HDR -- - * Log record header. - */ -struct __hdr { - u_int32_t prev; /* Previous offset. */ - u_int32_t len; /* Current length. */ - u_int8_t chksum[DB_MAC_KEY]; /* Current checksum. */ - u_int8_t iv[DB_IV_BYTES]; /* IV */ - u_int32_t orig_size; /* Original size of log record */ - /* !!! - 'size' is not written to log, must be last in hdr */ - size_t size; /* Size of header to use */ -}; - -/* - * We use HDR internally, and then when we write out, we write out - * prev, len, and then a 4-byte checksum if normal operation or - * a crypto-checksum and IV and original size if running in crypto - * mode. We must store the original size in case we pad. Set the - * size when we set up the header. We compute a DB_MAC_KEY size - * checksum regardless, but we can safely just use the first 4 bytes. - */ -#define HDR_NORMAL_SZ 12 -#define HDR_CRYPTO_SZ 12 + DB_MAC_KEY + DB_IV_BYTES - -struct __log_persist { - u_int32_t magic; /* DB_LOGMAGIC */ - u_int32_t version; /* DB_LOGVERSION */ - - u_int32_t log_size; /* Log file size. */ - u_int32_t notused; /* Historically the log file mode. */ -}; - -/* Macros to lock/unlock the log region as a whole. */ -#define LOG_SYSTEM_LOCK(dbenv) \ - MUTEX_LOCK(dbenv, ((LOG *)((DB_LOG *) \ - (dbenv)->lg_handle)->reginfo.primary)->mtx_region) -#define LOG_SYSTEM_UNLOCK(dbenv) \ - MUTEX_UNLOCK(dbenv, ((LOG *)((DB_LOG *) \ - (dbenv)->lg_handle)->reginfo.primary)->mtx_region) - -/* - * LOG -- - * Shared log region. One of these is allocated in shared memory, - * and describes the log. - */ -struct __log { - db_mutex_t mtx_region; /* Region mutex. */ - - db_mutex_t mtx_filelist; /* Mutex guarding file name list. */ - - LOGP persist; /* Persistent information. */ - - SH_TAILQ_HEAD(__fq1) fq; /* List of file names. */ - int32_t fid_max; /* Max fid allocated. */ - roff_t free_fid_stack; /* Stack of free file ids. */ - u_int free_fids; /* Height of free fid stack. */ - u_int free_fids_alloced; /* N free fid slots allocated. */ - - /* - * The lsn LSN is the file offset that we're about to write and which - * we will return to the user. - */ - DB_LSN lsn; /* LSN at current file offset. */ - - /* - * The f_lsn LSN is the LSN (returned to the user) that "owns" the - * first byte of the buffer. If the record associated with the LSN - * spans buffers, it may not reflect the physical file location of - * the first byte of the buffer. - */ - DB_LSN f_lsn; /* LSN of first byte in the buffer. */ - size_t b_off; /* Current offset in the buffer. */ - u_int32_t w_off; /* Current write offset in the file. */ - u_int32_t len; /* Length of the last record. */ - - DB_LSN active_lsn; /* Oldest active LSN in the buffer. */ - size_t a_off; /* Offset in the buffer of first active - file. */ - - /* - * The s_lsn LSN is the last LSN that we know is on disk, not just - * written, but synced. This field is protected by the flush mutex - * rather than by the region mutex. - */ - db_mutex_t mtx_flush; /* Mutex guarding flushing. */ - int in_flush; /* Log flush in progress. */ - DB_LSN s_lsn; /* LSN of the last sync. */ - - DB_LOG_STAT stat; /* Log statistics. */ - - /* - * !!! - * NOTE: the next 11 fields, waiting_lsn, verify_lsn, max_wait_lsn, - * maxperm_lsn, wait_recs, rcvd_recs, ready_lsn and bulk_* are NOT - * protected by the log region lock. They are protected by - * REP->mtx_clientdb. If you need access to both, you must acquire - * REP->mtx_clientdb before acquiring the log region lock. - * - * The waiting_lsn is used by the replication system. It is the - * first LSN that we are holding without putting in the log, because - * we received one or more log records out of order. Associated with - * the waiting_lsn is the number of log records that we still have to - * receive before we decide that we should request it again. - * - * The max_wait_lsn is used to control retransmission in the face - * of dropped messages. If we are requesting all records from the - * current gap (i.e., chunk of the log that we are missing), then - * the max_wait_lsn contains the first LSN that we are known to have - * in the __db.rep.db. If we requested only a single record, then - * the max_wait_lsn has the LSN of that record we requested. - */ - DB_LSN waiting_lsn; /* First log record after a gap. */ - DB_LSN verify_lsn; /* LSN we are waiting to verify. */ - DB_LSN max_wait_lsn; /* Maximum LSN requested. */ - DB_LSN max_perm_lsn; /* Maximum PERMANENT LSN processed. */ - u_int32_t wait_recs; /* Records to wait before requesting. */ - u_int32_t rcvd_recs; /* Records received while waiting. */ - /* - * The ready_lsn is also used by the replication system. It is the - * next LSN we expect to receive. It's normally equal to "lsn", - * except at the beginning of a log file, at which point it's set - * to the LSN of the first record of the new file (after the - * header), rather than to 0. - */ - DB_LSN ready_lsn; - /* - * The bulk_buf is used by replication for bulk transfer. While this - * is protected by REP->mtx_clientdb, this doesn't contend with the - * above fields because the above are used by clients and the bulk - * fields below are used by a master. - */ - roff_t bulk_buf; /* Bulk transfer buffer in region. */ - uintptr_t bulk_off; /* Current offset into bulk buffer. */ - u_int32_t bulk_len; /* Length of buffer. */ - u_int32_t bulk_flags; /* Bulk buffer flags. */ - - /* - * During initialization, the log system walks forward through the - * last log file to find its end. If it runs into a checkpoint - * while it's doing so, it caches it here so that the transaction - * system doesn't need to walk through the file again on its - * initialization. - */ - DB_LSN cached_ckp_lsn; - - u_int32_t regionmax; /* Configured size of the region. */ - - roff_t buffer_off; /* Log buffer offset in the region. */ - u_int32_t buffer_size; /* Log buffer size. */ - - u_int32_t log_size; /* Log file's size. */ - u_int32_t log_nsize; /* Next log file's size. */ - - int filemode; /* Log file permissions mode. */ - - /* - * DB_LOG_AUTOREMOVE and DB_LOG_INMEMORY: not protected by a mutex, - * all we care about is if they're zero or non-zero. - */ - int db_log_autoremove; - int db_log_inmemory; - - u_int32_t ncommit; /* Number of txns waiting to commit. */ - DB_LSN t_lsn; /* LSN of first commit */ - SH_TAILQ_HEAD(__commit) commits;/* list of txns waiting to commit. */ - SH_TAILQ_HEAD(__free) free_commits;/* free list of commit structs. */ - - /* - * In-memory logs maintain a list of the start positions of all log - * files currently active in the in-memory buffer. This is to make the - * lookup from LSN to log buffer offset efficient. - */ - SH_TAILQ_HEAD(__logfile) logfiles; - SH_TAILQ_HEAD(__free_logfile) free_logfiles; -}; - -/* - * __db_commit structure -- - * One of these is allocated for each transaction waiting to commit. - */ -struct __db_commit { - db_mutex_t mtx_txnwait; /* Mutex for txn to wait on. */ - DB_LSN lsn; /* LSN of commit record. */ - SH_TAILQ_ENTRY links; /* Either on free or waiting list. */ - -#define DB_COMMIT_FLUSH 0x0001 /* Flush the log when you wake up. */ - u_int32_t flags; -}; - -/* - * Check for the proper progression of Log Sequence Numbers. - * If we are rolling forward the LSN on the page must be greater - * than or equal to the previous LSN in log record. - * We ignore NOT LOGGED LSNs. The user did an unlogged update. - * We should eventually see a log record that matches and continue - * forward. - * If truncate is supported then a ZERO LSN implies a page that was - * allocated prior to the recovery start pont and then truncated - * later in the log. An allocation of a page after this - * page will extend the file, leaving a hole. We want to - * ignore this page until it is truncated again. - * - */ - -#ifdef HAVE_FTRUNCATE -#define CHECK_LSN(e, redo, cmp, lsn, prev) \ - if (DB_REDO(redo) && (cmp) < 0 && \ - ((!IS_NOT_LOGGED_LSN(*(lsn)) && !IS_ZERO_LSN(*(lsn))) || \ - IS_REP_CLIENT(e))) { \ - ret = __db_check_lsn(dbenv, lsn, prev); \ - goto out; \ - } -#else -#define CHECK_LSN(e, redo, cmp, lsn, prev) \ - if (DB_REDO(redo) && (cmp) < 0 && \ - (!IS_NOT_LOGGED_LSN(*(lsn)) || IS_REP_CLIENT(e))) { \ - ret = __db_check_lsn(dbenv, lsn, prev); \ - goto out; \ - } -#endif - -/* - * Helper for in-memory logs -- check whether an offset is in range - * in a ring buffer (inclusive of start, exclusive of end). - */ -struct __db_filestart { - u_int32_t file; - size_t b_off; - - SH_TAILQ_ENTRY links; /* Either on free or waiting list. */ -}; - -#define RINGBUF_LEN(lp, start, end) \ - ((start) < (end) ? \ - (end) - (start) : (lp)->buffer_size - ((start) - (end))) - -/* - * Internal macro to set pointer to the begin_lsn for generated - * logging routines. If begin_lsn is already set then do nothing. - * Return a pointer to the last lsn too. - */ -#undef DB_SET_TXN_LSNP -#define DB_SET_TXN_LSNP(txn, blsnp, llsnp) do { \ - DB_LSN *__lsnp; \ - TXN_DETAIL *__td; \ - __td = (txn)->td; \ - *(llsnp) = &__td->last_lsn; \ - while (__td->parent != INVALID_ROFF) \ - __td = R_ADDR(&(txn)->mgrp->reginfo, __td->parent); \ - __lsnp = &__td->begin_lsn; \ - if (IS_ZERO_LSN(*__lsnp)) \ - *(blsnp) = __lsnp; \ -} while (0) - -/* - * These are used in __log_backup to determine which LSN in the - * checkpoint record to compare and return. - */ -#define CKPLSN_CMP 0 -#define LASTCKP_CMP 1 - -/* - * Status codes indicating the validity of a log file examined by - * __log_valid(). - */ -typedef enum { - DB_LV_INCOMPLETE, - DB_LV_NONEXISTENT, - DB_LV_NORMAL, - DB_LV_OLD_READABLE, - DB_LV_OLD_UNREADABLE -} logfile_validity; - -#include "dbinc_auto/dbreg_auto.h" -#include "dbinc_auto/dbreg_ext.h" -#include "dbinc_auto/log_ext.h" -#endif /* !_LOG_H_ */ diff --git a/storage/bdb/dbinc/mp.h b/storage/bdb/dbinc/mp.h deleted file mode 100644 index 86e1905e950..00000000000 --- a/storage/bdb/dbinc/mp.h +++ /dev/null @@ -1,377 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: mp.h,v 12.5 2005/08/08 14:52:30 bostic Exp $ - */ - -#ifndef _DB_MP_H_ -#define _DB_MP_H_ - -struct __bh; typedef struct __bh BH; -struct __db_mpool_hash; typedef struct __db_mpool_hash DB_MPOOL_HASH; -struct __db_mpreg; typedef struct __db_mpreg DB_MPREG; -struct __mpool; typedef struct __mpool MPOOL; - - /* We require at least 20KB of cache. */ -#define DB_CACHESIZE_MIN (20 * 1024) - -/* - * DB_MPOOLFILE initialization methods cannot be called after open is called, - * other methods cannot be called before open is called - */ -#define MPF_ILLEGAL_AFTER_OPEN(dbmfp, name) \ - if (F_ISSET(dbmfp, MP_OPEN_CALLED)) \ - return (__db_mi_open((dbmfp)->dbenv, name, 1)); -#define MPF_ILLEGAL_BEFORE_OPEN(dbmfp, name) \ - if (!F_ISSET(dbmfp, MP_OPEN_CALLED)) \ - return (__db_mi_open((dbmfp)->dbenv, name, 0)); - -typedef enum { - DB_SYNC_ALLOC, /* Flush for allocation. */ - DB_SYNC_CACHE, /* Checkpoint or flush entire cache. */ - DB_SYNC_FILE, /* Flush file. */ - DB_SYNC_TRICKLE /* Trickle sync. */ -} db_sync_op; - -/* - * DB_MPOOL -- - * Per-process memory pool structure. - */ -struct __db_mpool { - /* These fields need to be protected for multi-threaded support. */ - db_mutex_t mutex; /* Thread mutex. */ - - /* - * DB_MPREG structure for the DB pgin/pgout routines. - * - * Linked list of application-specified pgin/pgout routines. - */ - DB_MPREG *pg_inout; - LIST_HEAD(__db_mpregh, __db_mpreg) dbregq; - - /* List of DB_MPOOLFILE's. */ - TAILQ_HEAD(__db_mpoolfileh, __db_mpoolfile) dbmfq; - - /* - * The dbenv, nreg and reginfo fields are not thread protected, - * as they are initialized during mpool creation, and not modified - * again. - */ - DB_ENV *dbenv; /* Enclosing environment. */ - - u_int32_t nreg; /* N underlying cache regions. */ - REGINFO *reginfo; /* Underlying cache regions. */ -}; - -/* - * DB_MPREG -- - * DB_MPOOL registry of pgin/pgout functions. - */ -struct __db_mpreg { - LIST_ENTRY(__db_mpreg) q; /* Linked list. */ - - int32_t ftype; /* File type. */ - /* Pgin, pgout routines. */ - int (*pgin) __P((DB_ENV *, db_pgno_t, void *, DBT *)); - int (*pgout) __P((DB_ENV *, db_pgno_t, void *, DBT *)); -}; - -/* - * NCACHE -- - * Select a cache based on the file and the page number. Assumes accesses - * are uniform across pages, which is probably OK. What we really want to - * avoid is anything that puts all pages from any single file in the same - * cache, as we expect that file access will be bursty, and to avoid - * putting all page number N pages in the same cache as we expect access - * to the metapages (page 0) and the root of a btree (page 1) to be much - * more frequent than a random data page. - */ -#define NCACHE(mp, mf_offset, pgno) \ - (((pgno) ^ ((u_int32_t)(mf_offset) >> 3)) % ((MPOOL *)mp)->nreg) - -/* - * NBUCKET -- - * We make the assumption that early pages of the file are more likely - * to be retrieved than the later pages, which means the top bits will - * be more interesting for hashing as they're less likely to collide. - * That said, as 512 8K pages represents a 4MB file, so only reasonably - * large files will have page numbers with any other than the bottom 9 - * bits set. We XOR in the MPOOL offset of the MPOOLFILE that backs the - * page, since that should also be unique for the page. We don't want - * to do anything very fancy -- speed is more important to us than using - * good hashing. - */ -#define NBUCKET(mc, mf_offset, pgno) \ - (((pgno) ^ ((mf_offset) << 9)) % (mc)->htab_buckets) - -/* Macros to lock/unlock the mpool region as a whole. */ -#define MPOOL_SYSTEM_LOCK(dbenv) \ - MUTEX_LOCK(dbenv, ((MPOOL *)((DB_MPOOL *) \ - (dbenv)->mp_handle)->reginfo[0].primary)->mtx_region) -#define MPOOL_SYSTEM_UNLOCK(dbenv) \ - MUTEX_UNLOCK(dbenv, ((MPOOL *)((DB_MPOOL *) \ - (dbenv)->mp_handle)->reginfo[0].primary)->mtx_region) - -/* Macros to lock/unlock a specific mpool region. */ -#define MPOOL_REGION_LOCK(dbenv, infop) \ - MUTEX_LOCK(dbenv, ((MPOOL *)(infop)->primary)->mtx_region) -#define MPOOL_REGION_UNLOCK(dbenv, infop) \ - MUTEX_UNLOCK(dbenv, ((MPOOL *)(infop)->primary)->mtx_region) - -/* - * MPOOL -- - * Shared memory pool region. - */ -struct __mpool { - /* - * The memory pool can be broken up into individual pieces/files. - * Not what we would have liked, but on Solaris you can allocate - * only a little more than 2GB of memory in a contiguous chunk, - * and I expect to see more systems with similar issues. - * - * While this structure is duplicated in each piece of the cache, - * the first of these pieces/files describes the entire pool, the - * second only describe a piece of the cache. - */ - db_mutex_t mtx_region; /* Region mutex. */ - - /* - * The lsn field and list of underlying MPOOLFILEs are thread protected - * by the region lock. - */ - DB_LSN lsn; /* Maximum checkpoint LSN. */ - - SH_TAILQ_HEAD(__mpfq) mpfq; /* List of MPOOLFILEs. */ - - /* Configuration information: protected by the region lock. */ - size_t mp_mmapsize; /* Maximum file size for mmap. */ - int mp_maxopenfd; /* Maximum open file descriptors. */ - int mp_maxwrite; /* Maximum buffers to write. */ - int mp_maxwrite_sleep; /* Sleep after writing max buffers. */ - - /* - * The nreg, regids and maint_off fields are not thread protected, - * as they are initialized during mpool creation, and not modified - * again. - */ - u_int32_t nreg; /* Number of underlying REGIONS. */ - roff_t regids; /* Array of underlying REGION Ids. */ - - /* - * The following structure fields only describe the per-cache portion - * of the region. - * - * The htab and htab_buckets fields are not thread protected as they - * are initialized during mpool creation, and not modified again. - * - * The last_checked and lru_count fields are thread protected by - * the region lock. - */ - u_int32_t htab_buckets; /* Number of hash table entries. */ - roff_t htab; /* Hash table offset. */ - u_int32_t last_checked; /* Last bucket checked for free. */ - u_int32_t lru_count; /* Counter for buffer LRU */ - - /* - * The stat fields are generally not thread protected, and cannot be - * trusted. Note that st_pages is an exception, and is always updated - * inside a region lock (although it is sometimes read outside of the - * region lock). - */ - DB_MPOOL_STAT stat; /* Per-cache mpool statistics. */ - - /* - * We track page puts so that we can decide when allocation is never - * going to succeed. We don't lock the field, all we care about is - * if it changes. - */ - u_int32_t put_counter; /* Count of page put calls. */ -}; - -struct __db_mpool_hash { - db_mutex_t mtx_hash; /* Per-bucket mutex. */ - - DB_HASHTAB hash_bucket; /* Head of bucket. */ - - u_int32_t hash_page_dirty;/* Count of dirty pages. */ - u_int32_t hash_priority; /* Minimum priority of bucket buffer. */ -}; - -/* - * The base mpool priority is 1/4th of the name space, or just under 2^30. - * When the LRU counter wraps, we shift everybody down to a base-relative - * value. - */ -#define MPOOL_BASE_DECREMENT (UINT32_MAX - (UINT32_MAX / 4)) - -/* - * Mpool priorities from low to high. Defined in terms of fractions of the - * buffers in the pool. - */ -#define MPOOL_PRI_VERY_LOW -1 /* Dead duck. Check and set to 0. */ -#define MPOOL_PRI_LOW -2 /* Low. */ -#define MPOOL_PRI_DEFAULT 0 /* No adjustment -- special case.*/ -#define MPOOL_PRI_HIGH 10 /* With the dirty buffers. */ -#define MPOOL_PRI_DIRTY 10 /* Dirty gets a 10% boost. */ -#define MPOOL_PRI_VERY_HIGH 1 /* Add number of buffers in pool. */ - -/* - * MPOOLFILE -- - * Shared DB_MPOOLFILE information. - */ -struct __mpoolfile { - db_mutex_t mutex; /* MPOOLFILE mutex. */ - - /* Protected by MPOOLFILE mutex. */ - u_int32_t mpf_cnt; /* Ref count: DB_MPOOLFILEs. */ - u_int32_t block_cnt; /* Ref count: blocks in cache. */ - - roff_t path_off; /* File name location. */ - - /* - * The following are used for file compaction processing. - * They are only used when a thread is in the process - * of trying to move free pages to the end of the file. - * Other threads may look here when freeing a page. - * Protected by a lock on the metapage. - */ - u_int32_t free_ref; /* Refcount to freelist. */ - u_int32_t free_cnt; /* Count of free pages. */ - size_t free_size; /* Allocated size of free list. */ - roff_t free_list; /* Offset to free list. */ - - /* - * We normally don't lock the deadfile field when we read it since we - * only care if the field is zero or non-zero. We do lock on read when - * searching for a matching MPOOLFILE -- see that code for more detail. - */ - int32_t deadfile; /* Dirty pages can be discarded. */ - - /* Protected by mpool cache 0 region lock. */ - SH_TAILQ_ENTRY q; /* List of MPOOLFILEs */ - db_pgno_t last_pgno; /* Last page in the file. */ - db_pgno_t orig_last_pgno; /* Original last page in the file. */ - db_pgno_t maxpgno; /* Maximum page number. */ - - /* - * None of the following fields are thread protected. - * - * There are potential races with the ftype field because it's read - * without holding a lock. However, it has to be set before adding - * any buffers to the cache that depend on it being set, so there - * would need to be incorrect operation ordering to have a problem. - */ - int32_t ftype; /* File type. */ - - /* - * There are potential races with the priority field because it's read - * without holding a lock. However, a collision is unlikely and if it - * happens is of little consequence. - */ - int32_t priority; /* Priority when unpinning buffer. */ - - /* - * There are potential races with the file_written field (many threads - * may be writing blocks at the same time), and with no_backing_file - * and unlink_on_close fields, as they may be set while other threads - * are reading them. However, we only care if the field value is zero - * or non-zero, so don't lock the memory. - * - * !!! - * Theoretically, a 64-bit architecture could put two of these fields - * in a single memory operation and we could race. I have never seen - * an architecture where that's a problem, and I believe Java requires - * that to never be the case. - * - * File_written is set whenever a buffer is marked dirty in the cache. - * It can be cleared in some cases, after all dirty buffers have been - * written AND the file has been flushed to disk. - */ - int32_t file_written; /* File was written. */ - int32_t no_backing_file; /* Never open a backing file. */ - int32_t unlink_on_close; /* Unlink file on last close. */ - - /* - * We do not protect the statistics in "stat" because of the cost of - * the mutex in the get/put routines. There is a chance that a count - * will get lost. - */ - DB_MPOOL_FSTAT stat; /* Per-file mpool statistics. */ - - /* - * The remaining fields are initialized at open and never subsequently - * modified. - */ - int32_t lsn_off; /* Page's LSN offset. */ - u_int32_t clear_len; /* Bytes to clear on page create. */ - - roff_t fileid_off; /* File ID string location. */ - - roff_t pgcookie_len; /* Pgin/pgout cookie length. */ - roff_t pgcookie_off; /* Pgin/pgout cookie location. */ - - /* - * The flags are initialized at open and never subsequently modified. - */ -#define MP_CAN_MMAP 0x001 /* If the file can be mmap'd. */ -#define MP_DIRECT 0x002 /* No OS buffering. */ -#define MP_DURABLE_UNKNOWN 0x004 /* We don't care about durability. */ -#define MP_EXTENT 0x008 /* Extent file. */ -#define MP_FAKE_DEADFILE 0x010 /* Deadfile field: fake flag. */ -#define MP_FAKE_FILEWRITTEN 0x020 /* File_written field: fake flag. */ -#define MP_FAKE_NB 0x040 /* No_backing_file field: fake flag. */ -#define MP_FAKE_UOC 0x080 /* Unlink_on_close field: fake flag. */ -#define MP_NOT_DURABLE 0x100 /* File is not durable. */ -#define MP_TEMP 0x200 /* Backing file is a temporary. */ - u_int32_t flags; -}; - -/* - * Flags to __memp_bh_free. - */ -#define BH_FREE_FREEMEM 0x01 -#define BH_FREE_UNLOCKED 0x02 - -/* - * BH -- - * Buffer header. - */ -struct __bh { - db_mutex_t mtx_bh; /* Buffer thread/process mutex. */ - - u_int16_t ref; /* Reference count. */ - u_int16_t ref_sync; /* Sync wait-for reference count. */ - -#define BH_CALLPGIN 0x001 /* Convert the page before use. */ -#define BH_DIRTY 0x002 /* Page was modified. */ -#define BH_DIRTY_CREATE 0x004 /* Page created, must be written. */ -#define BH_DISCARD 0x008 /* Page is useless. */ -#define BH_LOCKED 0x010 /* Page is locked (I/O in progress). */ -#define BH_TRASH 0x020 /* Page is garbage. */ - u_int16_t flags; - - u_int32_t priority; /* LRU priority. */ - SH_TAILQ_ENTRY hq; /* MPOOL hash bucket queue. */ - - db_pgno_t pgno; /* Underlying MPOOLFILE page number. */ - roff_t mf_offset; /* Associated MPOOLFILE offset. */ - - /* - * !!! - * This array must be at least size_t aligned -- the DB access methods - * put PAGE and other structures into it, and then access them directly. - * (We guarantee size_t alignment to applications in the documentation, - * too.) - */ - u_int8_t buf[1]; /* Variable length data. */ -}; -/* - * Flags to __memp_ftruncate. - */ -#define MP_TRUNC_RECOVER 0x01 - -#include "dbinc_auto/mp_ext.h" -#endif /* !_DB_MP_H_ */ diff --git a/storage/bdb/dbinc/mutex.h b/storage/bdb/dbinc/mutex.h deleted file mode 100644 index 4937e4f7d3a..00000000000 --- a/storage/bdb/dbinc/mutex.h +++ /dev/null @@ -1,142 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: mutex.h,v 12.14 2005/10/13 00:56:52 bostic Exp $ - */ - -#ifndef _DB_MUTEX_H_ -#define _DB_MUTEX_H_ - -/* - * Mutexes are represented by unsigned, 32-bit integral values. As the - * OOB value is 0, mutexes can be initialized by zero-ing out the memory - * in which they reside. - */ -#define MUTEX_INVALID 0 - -/* - * We track mutex allocations by ID. - */ -#define MTX_APPLICATION 1 -#define MTX_DB_HANDLE 2 -#define MTX_ENV_DBLIST 3 -#define MTX_ENV_REGION 4 -#define MTX_LOCK_REGION 5 -#define MTX_LOGICAL_LOCK 6 -#define MTX_LOG_FILENAME 7 -#define MTX_LOG_FLUSH 8 -#define MTX_LOG_HANDLE 9 -#define MTX_LOG_REGION 10 -#define MTX_MPOOLFILE_HANDLE 11 -#define MTX_MPOOL_BUFFER 12 -#define MTX_MPOOL_FH 13 -#define MTX_MPOOL_HANDLE 14 -#define MTX_MPOOL_HASH_BUCKET 15 -#define MTX_MPOOL_REGION 16 -#define MTX_MUTEX_REGION 17 -#define MTX_MUTEX_TEST 18 -#define MTX_REP_DATABASE 19 -#define MTX_REP_REGION 20 -#define MTX_SEQUENCE 21 -#define MTX_TWISTER 22 -#define MTX_TXN_ACTIVE 23 -#define MTX_TXN_CHKPT 24 -#define MTX_TXN_COMMIT 25 -#define MTX_TXN_REGION 26 -#define MTX_MAX_ENTRY 26 - -/* Redirect mutex calls to the correct functions. */ -#if defined(HAVE_MUTEX_PTHREADS) || \ - defined(HAVE_MUTEX_SOLARIS_LWP) || \ - defined(HAVE_MUTEX_UI_THREADS) -#define __mutex_init(a, b, c) __db_pthread_mutex_init(a, b, c) -#define __mutex_lock(a, b) __db_pthread_mutex_lock(a, b) -#define __mutex_unlock(a, b) __db_pthread_mutex_unlock(a, b) -#define __mutex_destroy(a, b) __db_pthread_mutex_destroy(a, b) -#endif - -#if defined(HAVE_MUTEX_WIN32) || defined(HAVE_MUTEX_WIN32_GCC) -#define __mutex_init(a, b, c) __db_win32_mutex_init(a, b, c) -#define __mutex_lock(a, b) __db_win32_mutex_lock(a, b) -#define __mutex_unlock(a, b) __db_win32_mutex_unlock(a, b) -#define __mutex_destroy(a, b) __db_win32_mutex_destroy(a, b) -#endif - -#if defined(HAVE_MUTEX_FCNTL) -#define __mutex_init(a, b, c) __db_fcntl_mutex_init(a, b, c) -#define __mutex_lock(a, b) __db_fcntl_mutex_lock(a, b) -#define __mutex_unlock(a, b) __db_fcntl_mutex_unlock(a, b) -#define __mutex_destroy(a, b) __db_fcntl_mutex_destroy(a, b) -#endif - -#ifndef __mutex_init /* Test-and-set is the default */ -#define __mutex_init(a, b, c) __db_tas_mutex_init(a, b, c) -#define __mutex_lock(a, b) __db_tas_mutex_lock(a, b) -#define __mutex_unlock(a, b) __db_tas_mutex_unlock(a, b) -#define __mutex_destroy(a, b) __db_tas_mutex_destroy(a, b) -#endif - -/* - * Lock/unlock a mutex. If the mutex was never required, the thread of - * control can proceed without it. - * - * We never fail to acquire or release a mutex without panicing. Simplify - * the macros to always return a panic value rather than saving the actual - * return value of the mutex routine. - */ -#define MUTEX_LOCK(dbenv, mutex) do { \ - if ((mutex) != MUTEX_INVALID && \ - __mutex_lock(dbenv, mutex) != 0) \ - return (DB_RUNRECOVERY); \ -} while (0) -#define MUTEX_UNLOCK(dbenv, mutex) do { \ - if ((mutex) != MUTEX_INVALID && \ - __mutex_unlock(dbenv, mutex) != 0) \ - return (DB_RUNRECOVERY); \ -} while (0) - -/* - * Berkeley DB ports may require single-threading at places in the code. - */ -#ifdef HAVE_MUTEX_VXWORKS -#include "taskLib.h" -/* - * Use the taskLock() mutex to eliminate a race where two tasks are - * trying to initialize the global lock at the same time. - */ -#define DB_BEGIN_SINGLE_THREAD do { \ - if (DB_GLOBAL(db_global_init)) \ - (void)semTake(DB_GLOBAL(db_global_lock), WAIT_FOREVER); \ - else { \ - taskLock(); \ - if (DB_GLOBAL(db_global_init)) { \ - taskUnlock(); \ - (void)semTake(DB_GLOBAL(db_global_lock), \ - WAIT_FOREVER); \ - continue; \ - } \ - DB_GLOBAL(db_global_lock) = \ - semBCreate(SEM_Q_FIFO, SEM_EMPTY); \ - if (DB_GLOBAL(db_global_lock) != NULL) \ - DB_GLOBAL(db_global_init) = 1; \ - taskUnlock(); \ - } \ -} while (DB_GLOBAL(db_global_init) == 0) -#define DB_END_SINGLE_THREAD (void)semGive(DB_GLOBAL(db_global_lock)) -#endif - -/* - * Single-threading defaults to a no-op. - */ -#ifndef DB_BEGIN_SINGLE_THREAD -#define DB_BEGIN_SINGLE_THREAD -#endif -#ifndef DB_END_SINGLE_THREAD -#define DB_END_SINGLE_THREAD -#endif - -#include "dbinc_auto/mutex_ext.h" -#endif /* !_DB_MUTEX_H_ */ diff --git a/storage/bdb/dbinc/mutex_int.h b/storage/bdb/dbinc/mutex_int.h deleted file mode 100644 index a99ff614a4c..00000000000 --- a/storage/bdb/dbinc/mutex_int.h +++ /dev/null @@ -1,844 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: mutex_int.h,v 12.17 2005/11/08 22:26:49 mjc Exp $ - */ - -#ifndef _DB_MUTEX_INT_H_ -#define _DB_MUTEX_INT_H_ - -/********************************************************************* - * POSIX.1 pthreads interface. - *********************************************************************/ -#ifdef HAVE_MUTEX_PTHREADS -#include <pthread.h> - -#define MUTEX_FIELDS \ - pthread_mutex_t mutex; /* Mutex. */ \ - pthread_cond_t cond; /* Condition variable. */ -#endif - -#ifdef HAVE_MUTEX_UI_THREADS -#include <thread.h> -#endif - -/********************************************************************* - * Solaris lwp threads interface. - * - * !!! - * We use LWP mutexes on Solaris instead of UI or POSIX mutexes (both of - * which are available), for two reasons. First, the Solaris C library - * includes versions of the both UI and POSIX thread mutex interfaces, but - * they are broken in that they don't support inter-process locking, and - * there's no way to detect it, e.g., calls to configure the mutexes for - * inter-process locking succeed without error. So, we use LWP mutexes so - * that we don't fail in fairly undetectable ways because the application - * wasn't linked with the appropriate threads library. Second, there were - * bugs in SunOS 5.7 (Solaris 7) where if an application loaded the C library - * before loading the libthread/libpthread threads libraries (e.g., by using - * dlopen to load the DB library), the pwrite64 interface would be translated - * into a call to pwrite and DB would drop core. - *********************************************************************/ -#ifdef HAVE_MUTEX_SOLARIS_LWP -/* - * XXX - * Don't change <synch.h> to <sys/lwp.h> -- although lwp.h is listed in the - * Solaris manual page as the correct include to use, it causes the Solaris - * compiler on SunOS 2.6 to fail. - */ -#include <synch.h> - -#define MUTEX_FIELDS \ - lwp_mutex_t mutex; /* Mutex. */ \ - lwp_cond_t cond; /* Condition variable. */ -#endif - -/********************************************************************* - * Solaris/Unixware threads interface. - *********************************************************************/ -#ifdef HAVE_MUTEX_UI_THREADS -#include <thread.h> -#include <synch.h> - -#define MUTEX_FIELDS \ - mutex_t mutex; /* Mutex. */ \ - cond_t cond; /* Condition variable. */ -#endif - -/********************************************************************* - * AIX C library functions. - *********************************************************************/ -#ifdef HAVE_MUTEX_AIX_CHECK_LOCK -#include <sys/atomic_op.h> -typedef int tsl_t; - -#ifdef LOAD_ACTUAL_MUTEX_CODE -#define MUTEX_INIT(x) 0 -#define MUTEX_SET(x) (!_check_lock(x, 0, 1)) -#define MUTEX_UNSET(x) _clear_lock(x, 0) -#endif -#endif - -/********************************************************************* - * Apple/Darwin library functions. - *********************************************************************/ -#ifdef HAVE_MUTEX_DARWIN_SPIN_LOCK_TRY -typedef u_int32_t tsl_t; - -#ifdef LOAD_ACTUAL_MUTEX_CODE -extern int _spin_lock_try(tsl_t *); -extern void _spin_unlock(tsl_t *); -#define MUTEX_SET(tsl) _spin_lock_try(tsl) -#define MUTEX_UNSET(tsl) _spin_unlock(tsl) -#define MUTEX_INIT(tsl) (MUTEX_UNSET(tsl), 0) -#endif -#endif - -/********************************************************************* - * General C library functions (msemaphore). - * - * !!! - * Check for HPPA as a special case, because it requires unusual alignment, - * and doesn't support semaphores in malloc(3) or shmget(2) memory. - * - * !!! - * Do not remove the MSEM_IF_NOWAIT flag. The problem is that if a single - * process makes two msem_lock() calls in a row, the second one returns an - * error. We depend on the fact that we can lock against ourselves in the - * locking subsystem, where we set up a mutex so that we can block ourselves. - * Tested on OSF1 v4.0. - *********************************************************************/ -#ifdef HAVE_MUTEX_HPPA_MSEM_INIT -#define MUTEX_ALIGN 16 -#endif - -#if defined(HAVE_MUTEX_MSEM_INIT) || defined(HAVE_MUTEX_HPPA_MSEM_INIT) -#include <sys/mman.h> -typedef msemaphore tsl_t; - -#ifdef LOAD_ACTUAL_MUTEX_CODE -#define MUTEX_INIT(x) (msem_init(x, MSEM_UNLOCKED) <= (msemaphore *)0) -#define MUTEX_SET(x) (!msem_lock(x, MSEM_IF_NOWAIT)) -#define MUTEX_UNSET(x) msem_unlock(x, 0) -#endif -#endif - -/********************************************************************* - * Plan 9 library functions. - *********************************************************************/ -#ifdef HAVE_MUTEX_PLAN9 -typedef Lock tsl_t; - -#define MUTEX_INIT(x) (memset(x, 0, sizeof(Lock)), 0) -#define MUTEX_SET(x) canlock(x) -#define MUTEX_UNSET(x) unlock(x) -#endif - -/********************************************************************* - * Reliant UNIX C library functions. - *********************************************************************/ -#ifdef HAVE_MUTEX_RELIANTUNIX_INITSPIN -#include <ulocks.h> -typedef spinlock_t tsl_t; - -#ifdef LOAD_ACTUAL_MUTEX_CODE -#define MUTEX_INIT(x) (initspin(x, 1), 0) -#define MUTEX_SET(x) (cspinlock(x) == 0) -#define MUTEX_UNSET(x) spinunlock(x) -#endif -#endif - -/********************************************************************* - * General C library functions (POSIX 1003.1 sema_XXX). - * - * !!! - * Never selected by autoconfig in this release (semaphore calls are known - * to not work in Solaris 5.5). - *********************************************************************/ -#ifdef HAVE_MUTEX_SEMA_INIT -#include <synch.h> -typedef sema_t tsl_t; - -#ifdef LOAD_ACTUAL_MUTEX_CODE -#define MUTEX_DESTROY(x) sema_destroy(x) -#define MUTEX_INIT(x) (sema_init(x, 1, USYNC_PROCESS, NULL) != 0) -#define MUTEX_SET(x) (sema_wait(x) == 0) -#define MUTEX_UNSET(x) sema_post(x) -#endif -#endif - -/********************************************************************* - * SGI C library functions. - *********************************************************************/ -#ifdef HAVE_MUTEX_SGI_INIT_LOCK -#include <abi_mutex.h> -typedef abilock_t tsl_t; - -#ifdef LOAD_ACTUAL_MUTEX_CODE -#define MUTEX_INIT(x) (init_lock(x) != 0) -#define MUTEX_SET(x) (!acquire_lock(x)) -#define MUTEX_UNSET(x) release_lock(x) -#endif -#endif - -/********************************************************************* - * Solaris C library functions. - * - * !!! - * These are undocumented functions, but they're the only ones that work - * correctly as far as we know. - *********************************************************************/ -#ifdef HAVE_MUTEX_SOLARIS_LOCK_TRY -#include <sys/machlock.h> -typedef lock_t tsl_t; - -#ifdef LOAD_ACTUAL_MUTEX_CODE -#define MUTEX_INIT(x) 0 -#define MUTEX_SET(x) _lock_try(x) -#define MUTEX_UNSET(x) _lock_clear(x) -#endif -#endif - -/********************************************************************* - * VMS. - *********************************************************************/ -#ifdef HAVE_MUTEX_VMS -#include <sys/mman.h>; -#include <builtins.h> -typedef volatile unsigned char tsl_t; - -#ifdef LOAD_ACTUAL_MUTEX_CODE -#ifdef __ALPHA -#define MUTEX_SET(tsl) (!__TESTBITSSI(tsl, 0)) -#else /* __VAX */ -#define MUTEX_SET(tsl) (!(int)_BBSSI(0, tsl)) -#endif -#define MUTEX_UNSET(tsl) (*(tsl) = 0) -#define MUTEX_INIT(tsl) MUTEX_UNSET(tsl) -#endif -#endif - -/********************************************************************* - * VxWorks - * Use basic binary semaphores in VxWorks, as we currently do not need - * any special features. We do need the ability to single-thread the - * entire system, however, because VxWorks doesn't support the open(2) - * flag O_EXCL, the mechanism we normally use to single thread access - * when we're first looking for a DB environment. - *********************************************************************/ -#ifdef HAVE_MUTEX_VXWORKS -#include "taskLib.h" -typedef SEM_ID tsl_t; - -#ifdef LOAD_ACTUAL_MUTEX_CODE -#define MUTEX_SET(tsl) (semTake((*tsl), WAIT_FOREVER) == OK) -#define MUTEX_UNSET(tsl) (semGive((*tsl))) -#define MUTEX_INIT(tsl) \ - ((*(tsl) = semBCreate(SEM_Q_FIFO, SEM_FULL)) == NULL) -#define MUTEX_DESTROY(tsl) semDelete(*tsl) -#endif -#endif - -/********************************************************************* - * Win16 - * - * Win16 spinlocks are simple because we cannot possibly be preempted. - * - * !!! - * We should simplify this by always returning a no-need-to-lock lock - * when we initialize the mutex. - *********************************************************************/ -#ifdef HAVE_MUTEX_WIN16 -typedef unsigned int tsl_t; - -#ifdef LOAD_ACTUAL_MUTEX_CODE -#define MUTEX_INIT(x) 0 -#define MUTEX_SET(tsl) (*(tsl) = 1) -#define MUTEX_UNSET(tsl) (*(tsl) = 0) -#endif -#endif - -/********************************************************************* - * Win32 - *********************************************************************/ -#if defined(HAVE_MUTEX_WIN32) || defined(HAVE_MUTEX_WIN32_GCC) -#define MUTEX_FIELDS \ - LONG volatile tas; \ - LONG nwaiters; \ - u_int32_t id; /* ID used for creating events */ \ - -#if defined(LOAD_ACTUAL_MUTEX_CODE) -#define MUTEX_SET(tsl) (!InterlockedExchange((PLONG)tsl, 1)) -#define MUTEX_UNSET(tsl) InterlockedExchange((PLONG)tsl, 0) -#define MUTEX_INIT(tsl) MUTEX_UNSET(tsl) - -/* - * From Intel's performance tuning documentation (and see SR #6975): - * ftp://download.intel.com/design/perftool/cbts/appnotes/sse2/w_spinlock.pdf - * - * "For this reason, it is highly recommended that you insert the PAUSE - * instruction into all spin-wait code immediately. Using the PAUSE - * instruction does not affect the correctness of programs on existing - * platforms, and it improves performance on Pentium 4 processor platforms." - */ -#ifdef HAVE_MUTEX_WIN32 -#ifndef _WIN64 -#define MUTEX_PAUSE {__asm{_emit 0xf3}; __asm{_emit 0x90}} -#endif -#endif -#ifdef HAVE_MUTEX_WIN32_GCC -#define MUTEX_PAUSE asm volatile ("rep; nop" : : ); -#endif -#endif -#endif - -/********************************************************************* - * 68K/gcc assembly. - *********************************************************************/ -#ifdef HAVE_MUTEX_68K_GCC_ASSEMBLY -typedef unsigned char tsl_t; - -#ifdef LOAD_ACTUAL_MUTEX_CODE -/* gcc/68K: 0 is clear, 1 is set. */ -#define MUTEX_SET(tsl) ({ \ - register tsl_t *__l = (tsl); \ - int __r; \ - asm volatile("tas %1; \n \ - seq %0" \ - : "=dm" (__r), "=m" (*__l) \ - : "1" (*__l) \ - ); \ - __r & 1; \ -}) - -#define MUTEX_UNSET(tsl) (*(tsl) = 0) -#define MUTEX_INIT(tsl) MUTEX_UNSET(tsl) -#endif -#endif - -/********************************************************************* - * ALPHA/gcc assembly. - *********************************************************************/ -#ifdef HAVE_MUTEX_ALPHA_GCC_ASSEMBLY -typedef u_int32_t tsl_t; - -#define MUTEX_ALIGN 4 - -#ifdef LOAD_ACTUAL_MUTEX_CODE -/* - * For gcc/alpha. Should return 0 if could not acquire the lock, 1 if - * lock was acquired properly. - */ -static inline int -MUTEX_SET(tsl_t *tsl) { - register tsl_t *__l = tsl; - register tsl_t __r; - asm volatile( - "1: ldl_l %0,%2\n" - " blbs %0,2f\n" - " or $31,1,%0\n" - " stl_c %0,%1\n" - " beq %0,3f\n" - " mb\n" - " br 3f\n" - "2: xor %0,%0\n" - "3:" - : "=&r"(__r), "=m"(*__l) : "1"(*__l) : "memory"); - return __r; -} - -/* - * Unset mutex. Judging by Alpha Architecture Handbook, the mb instruction - * might be necessary before unlocking - */ -static inline int -MUTEX_UNSET(tsl_t *tsl) { - asm volatile(" mb\n"); - return *tsl = 0; -} - -#define MUTEX_INIT(tsl) MUTEX_UNSET(tsl) -#endif -#endif - -/********************************************************************* - * Tru64/cc assembly. - *********************************************************************/ -#ifdef HAVE_MUTEX_TRU64_CC_ASSEMBLY -typedef volatile u_int32_t tsl_t; - -#define MUTEX_ALIGN 4 - -#ifdef LOAD_ACTUAL_MUTEX_CODE -#include <alpha/builtins.h> -#define MUTEX_SET(tsl) (__LOCK_LONG_RETRY((tsl), 1) != 0) -#define MUTEX_UNSET(tsl) (__UNLOCK_LONG(tsl)) - -#define MUTEX_INIT(tsl) (MUTEX_UNSET(tsl), 0) -#endif -#endif - -/********************************************************************* - * ARM/gcc assembly. - *********************************************************************/ -#ifdef HAVE_MUTEX_ARM_GCC_ASSEMBLY -typedef unsigned char tsl_t; - -#ifdef LOAD_ACTUAL_MUTEX_CODE -/* gcc/arm: 0 is clear, 1 is set. */ -#define MUTEX_SET(tsl) ({ \ - int __r; \ - asm volatile( \ - "swpb %0, %1, [%2]\n\t" \ - "eor %0, %0, #1\n\t" \ - : "=&r" (__r) \ - : "r" (1), "r" (tsl) \ - ); \ - __r & 1; \ -}) - -#define MUTEX_UNSET(tsl) (*(volatile tsl_t *)(tsl) = 0) -#define MUTEX_INIT(tsl) MUTEX_UNSET(tsl) -#endif -#endif - -/********************************************************************* - * HPPA/gcc assembly. - *********************************************************************/ -#ifdef HAVE_MUTEX_HPPA_GCC_ASSEMBLY -typedef u_int32_t tsl_t; - -#define MUTEX_ALIGN 16 - -#ifdef LOAD_ACTUAL_MUTEX_CODE -/* - * The PA-RISC has a "load and clear" instead of a "test and set" instruction. - * The 32-bit word used by that instruction must be 16-byte aligned. We could - * use the "aligned" attribute in GCC but that doesn't work for stack variables. - */ -#define MUTEX_SET(tsl) ({ \ - register tsl_t *__l = (tsl); \ - int __r; \ - asm volatile("ldcws 0(%1),%0" : "=r" (__r) : "r" (__l)); \ - __r & 1; \ -}) - -#define MUTEX_UNSET(tsl) (*(volatile tsl_t *)(tsl) = -1) -#define MUTEX_INIT(tsl) (MUTEX_UNSET(tsl), 0) -#endif -#endif - -/********************************************************************* - * IA64/gcc assembly. - *********************************************************************/ -#ifdef HAVE_MUTEX_IA64_GCC_ASSEMBLY -typedef volatile unsigned char tsl_t; - -#ifdef LOAD_ACTUAL_MUTEX_CODE -/* gcc/ia64: 0 is clear, 1 is set. */ -#define MUTEX_SET(tsl) ({ \ - register tsl_t *__l = (tsl); \ - long __r; \ - asm volatile("xchg1 %0=%1,%2" : \ - "=r"(__r), "+m"(*__l) : "r"(1)); \ - __r ^ 1; \ -}) - -/* - * Store through a "volatile" pointer so we get a store with "release" - * semantics. - */ -#define MUTEX_UNSET(tsl) (*(tsl_t *)(tsl) = 0) -#define MUTEX_INIT(tsl) MUTEX_UNSET(tsl) -#endif -#endif - -/********************************************************************* - * PowerPC/gcc assembly. - *********************************************************************/ -#if defined(HAVE_MUTEX_PPC_GCC_ASSEMBLY) -typedef u_int32_t tsl_t; - -#ifdef LOAD_ACTUAL_MUTEX_CODE -/* - * The PowerPC does a sort of pseudo-atomic locking. You set up a - * 'reservation' on a chunk of memory containing a mutex by loading the - * mutex value with LWARX. If the mutex has an 'unlocked' (arbitrary) - * value, you then try storing into it with STWCX. If no other process or - * thread broke your 'reservation' by modifying the memory containing the - * mutex, then the STCWX succeeds; otherwise it fails and you try to get - * a reservation again. - * - * While mutexes are explicitly 4 bytes, a 'reservation' applies to an - * entire cache line, normally 32 bytes, aligned naturally. If the mutex - * lives near data that gets changed a lot, there's a chance that you'll - * see more broken reservations than you might otherwise. The only - * situation in which this might be a problem is if one processor is - * beating on a variable in the same cache block as the mutex while another - * processor tries to acquire the mutex. That's bad news regardless - * because of the way it bashes caches, but if you can't guarantee that a - * mutex will reside in a relatively quiescent cache line, you might - * consider padding the mutex to force it to live in a cache line by - * itself. No, you aren't guaranteed that cache lines are 32 bytes. Some - * embedded processors use 16-byte cache lines, while some 64-bit - * processors use 128-bit cache lines. But assuming a 32-byte cache line - * won't get you into trouble for now. - * - * If mutex locking is a bottleneck, then you can speed it up by adding a - * regular LWZ load before the LWARX load, so that you can test for the - * common case of a locked mutex without wasting cycles making a reservation. - * - * gcc/ppc: 0 is clear, 1 is set. - */ -static inline int -MUTEX_SET(int *tsl) { - int __r; - asm volatile ( -"0: \n\t" -" lwarx %0,0,%1 \n\t" -" cmpwi %0,0 \n\t" -" bne- 1f \n\t" -" stwcx. %1,0,%1 \n\t" -" isync \n\t" -" beq+ 2f \n\t" -" b 0b \n\t" -"1: \n\t" -" li %1,0 \n\t" -"2: \n\t" - : "=&r" (__r), "+r" (tsl) - : - : "cr0", "memory"); - return (int)tsl; -} - -static inline int -MUTEX_UNSET(tsl_t *tsl) { - asm volatile("sync" : : : "memory"); - return *tsl = 0; -} -#define MUTEX_INIT(tsl) MUTEX_UNSET(tsl) -#endif -#endif - -/********************************************************************* - * OS/390 C - *********************************************************************/ -#ifdef HAVE_MUTEX_S390_CC_ASSEMBLY -typedef int tsl_t; - -#ifdef LOAD_ACTUAL_MUTEX_CODE -/* - * cs() is declared in <stdlib.h> but is built in to the compiler. - * Must use LANGLVL(EXTENDED) to get its declaration. - */ -#define MUTEX_SET(tsl) (!cs(&zero, (tsl), 1)) -#define MUTEX_UNSET(tsl) (*(tsl) = 0) -#define MUTEX_INIT(tsl) MUTEX_UNSET(tsl) -#endif -#endif - -/********************************************************************* - * S/390 32-bit assembly. - *********************************************************************/ -#ifdef HAVE_MUTEX_S390_GCC_ASSEMBLY -typedef int tsl_t; - -#ifdef LOAD_ACTUAL_MUTEX_CODE -/* gcc/S390: 0 is clear, 1 is set. */ -static inline int -MUTEX_SET(tsl_t *tsl) { \ - register tsl_t *__l = (tsl); \ - int __r; \ - asm volatile( \ - " la 1,%1\n" \ - " lhi 0,1\n" \ - " l %0,%1\n" \ - "0: cs %0,0,0(1)\n" \ - " jl 0b" \ - : "=&d" (__r), "+m" (*__l) \ - : : "0", "1", "cc"); \ - return !__r; \ -} - -#define MUTEX_UNSET(tsl) (*(tsl) = 0) -#define MUTEX_INIT(tsl) MUTEX_UNSET(tsl) -#endif -#endif - -/********************************************************************* - * SCO/cc assembly. - *********************************************************************/ -#ifdef HAVE_MUTEX_SCO_X86_CC_ASSEMBLY -typedef unsigned char tsl_t; - -#ifdef LOAD_ACTUAL_MUTEX_CODE -/* - * UnixWare has threads in libthread, but OpenServer doesn't (yet). - * - * cc/x86: 0 is clear, 1 is set. - */ -#if defined(__USLC__) -asm int -_tsl_set(void *tsl) -{ -%mem tsl - movl tsl, %ecx - movl $1, %eax - lock - xchgb (%ecx),%al - xorl $1,%eax -} -#endif - -#define MUTEX_SET(tsl) _tsl_set(tsl) -#define MUTEX_UNSET(tsl) (*(tsl) = 0) -#define MUTEX_INIT(tsl) MUTEX_UNSET(tsl) -#endif -#endif - -/********************************************************************* - * Sparc/gcc assembly. - *********************************************************************/ -#ifdef HAVE_MUTEX_SPARC_GCC_ASSEMBLY -typedef unsigned char tsl_t; - -#ifdef LOAD_ACTUAL_MUTEX_CODE -/* - * - * The ldstub instruction takes the location specified by its first argument - * (a register containing a memory address) and loads its contents into its - * second argument (a register) and atomically sets the contents the location - * specified by its first argument to a byte of 1s. (The value in the second - * argument is never read, but only overwritten.) - * - * The stbar is needed for v8, and is implemented as membar #sync on v9, - * so is functional there as well. For v7, stbar may generate an illegal - * instruction and we have no way to tell what we're running on. Some - * operating systems notice and skip this instruction in the fault handler. - * - * gcc/sparc: 0 is clear, 1 is set. - */ -#define MUTEX_SET(tsl) ({ \ - register tsl_t *__l = (tsl); \ - register tsl_t __r; \ - __asm__ volatile \ - ("ldstub [%1],%0; stbar" \ - : "=r"( __r) : "r" (__l)); \ - !__r; \ -}) - -#define MUTEX_UNSET(tsl) (*(tsl) = 0) -#define MUTEX_INIT(tsl) MUTEX_UNSET(tsl) -#endif -#endif - -/********************************************************************* - * UTS/cc assembly. - *********************************************************************/ -#ifdef HAVE_MUTEX_UTS_CC_ASSEMBLY -typedef int tsl_t; - -#ifdef LOAD_ACTUAL_MUTEX_CODE -#define MUTEX_INIT(x) 0 -#define MUTEX_SET(x) (!uts_lock(x, 1)) -#define MUTEX_UNSET(x) (*(x) = 0) -#endif -#endif - -/********************************************************************* - * MIPS/gcc assembly. - *********************************************************************/ -#ifdef HAVE_MUTEX_MIPS_GCC_ASSEMBLY -typedef u_int32_t tsl_t; - -#define MUTEX_ALIGN 4 - -#ifdef LOAD_ACTUAL_MUTEX_CODE -/* - * For gcc/MIPS. Should return 0 if could not acquire the lock, 1 if - * lock was acquired properly. - */ -static inline int -MUTEX_SET(tsl_t *tsl) { - register tsl_t *__l = tsl; - register tsl_t __r; - __asm__ __volatile__( - " .set push \n" - " .set mips2 \n" - " .set noreorder \n" - " .set nomacro \n" - "1: ll %0,%1 \n" - " bne %0,$0,1f \n" - " xori %0,%0,1 \n" - " sc %0,%1 \n" - " beql %0,$0,1b \n" - " xori %0,1 \n" - "1: .set pop " - : "=&r" (__r), "+R" (*__l)); - return __r; -} - -#define MUTEX_UNSET(tsl) (*(volatile tsl_t *)(tsl) = 0) -#define MUTEX_INIT(tsl) MUTEX_UNSET(tsl) -#endif -#endif - -/********************************************************************* - * x86/gcc assembly. - *********************************************************************/ -#ifdef HAVE_MUTEX_X86_GCC_ASSEMBLY -typedef unsigned char tsl_t; - -#ifdef LOAD_ACTUAL_MUTEX_CODE -/* gcc/x86: 0 is clear, 1 is set. */ -#define MUTEX_SET(tsl) ({ \ - register tsl_t *__l = (tsl); \ - int __r; \ - asm volatile("movl $1,%%eax\n" \ - "lock\n" \ - "xchgb %1,%%al\n" \ - "xorl $1,%%eax" \ - : "=&a" (__r), "=m" (*__l) \ - : "m1" (*__l) \ - ); \ - __r & 1; \ -}) - -#define MUTEX_UNSET(tsl) (*(volatile tsl_t *)(tsl) = 0) -#define MUTEX_INIT(tsl) MUTEX_UNSET(tsl) - -/* - * From Intel's performance tuning documentation (and see SR #6975): - * ftp://download.intel.com/design/perftool/cbts/appnotes/sse2/w_spinlock.pdf - * - * "For this reason, it is highly recommended that you insert the PAUSE - * instruction into all spin-wait code immediately. Using the PAUSE - * instruction does not affect the correctness of programs on existing - * platforms, and it improves performance on Pentium 4 processor platforms." - */ -#define MUTEX_PAUSE asm volatile ("rep; nop" : : ); -#endif -#endif - -/********************************************************************* - * x86_64/gcc assembly. - *********************************************************************/ -#ifdef HAVE_MUTEX_X86_64_GCC_ASSEMBLY -typedef unsigned char tsl_t; - -#ifdef LOAD_ACTUAL_MUTEX_CODE -/* gcc/x86_64: 0 is clear, 1 is set. */ -#define MUTEX_SET(tsl) ({ \ - register tsl_t *__l = (tsl); \ - int __r; \ - asm volatile("mov $1,%%rax\n" \ - "lock\n" \ - "xchgb %1,%%al\n" \ - "xor $1,%%rax" \ - : "=&a" (__r), "=m" (*__l) \ - : "1m" (*__l) \ - ); \ - __r & 1; \ -}) - -#define MUTEX_UNSET(tsl) (*(tsl) = 0) -#define MUTEX_INIT(tsl) MUTEX_UNSET(tsl) -#endif -#endif - -/* - * Mutex alignment defaults to sizeof(unsigned int). - * - * !!! - * Various systems require different alignments for mutexes (the worst we've - * seen so far is 16-bytes on some HP architectures). Malloc(3) is assumed - * to return reasonable alignment, all other mutex users must ensure proper - * alignment locally. - */ -#ifndef MUTEX_ALIGN -#define MUTEX_ALIGN sizeof(unsigned int) -#endif - -/* - * Mutex destruction defaults to a no-op. - */ -#ifndef MUTEX_DESTROY -#define MUTEX_DESTROY(x) -#endif - -/* - * DB_MUTEXMGR -- - * The mutex manager encapsulates the mutex system. - */ -typedef struct __db_mutexmgr { - /* These fields are never updated after creation, so not protected. */ - DB_ENV *dbenv; /* Environment */ - REGINFO reginfo; /* Region information */ - - void *mutex_array; /* Base of the mutex array */ -} DB_MUTEXMGR; - -/* Macros to lock/unlock the mutex region as a whole. */ -#define MUTEX_SYSTEM_LOCK(dbenv) \ - MUTEX_LOCK(dbenv, ((DB_MUTEXREGION *)((DB_MUTEXMGR *) \ - (dbenv)->mutex_handle)->reginfo.primary)->mtx_region) -#define MUTEX_SYSTEM_UNLOCK(dbenv) \ - MUTEX_UNLOCK(dbenv, ((DB_MUTEXREGION *)((DB_MUTEXMGR *) \ - (dbenv)->mutex_handle)->reginfo.primary)->mtx_region) - -/* - * DB_MUTEXREGION -- - * The primary mutex data structure in the shared memory region. - */ -typedef struct __db_mutexregion { - /* These fields are initialized at create time and never modified. */ - roff_t mutex_offset; /* Offset of mutex array */ - size_t mutex_size; /* Size of the aligned mutex */ - roff_t thread_off; /* Offset of the thread area. */ - - db_mutex_t mtx_region; /* Region mutex. */ - - /* Protected using the region mutex. */ - u_int32_t mutex_next; /* Next free mutex */ - - DB_MUTEX_STAT stat; /* Mutex statistics */ -} DB_MUTEXREGION; - -typedef struct __mutex_t { /* Mutex. */ -#ifdef MUTEX_FIELDS - MUTEX_FIELDS -#endif -#if !defined(MUTEX_FIELDS) && !defined(HAVE_MUTEX_FCNTL) - tsl_t tas; /* Test and set. */ -#endif - pid_t pid; /* Process owning mutex */ - db_threadid_t tid; /* Thread owning mutex */ - - u_int32_t mutex_next_link; /* Linked list of free mutexes. */ - -#ifdef HAVE_STATISTICS - int alloc_id; /* Allocation ID. */ - - u_int32_t mutex_set_wait; /* Granted after wait. */ - u_int32_t mutex_set_nowait; /* Granted without waiting. */ -#endif - - /* - * A subset of the flag arguments for __mutex_alloc(). - * - * Flags should be an unsigned integer even if it's not required by - * the possible flags values, getting a single byte on some machines - * is expensive, and the mutex structure is a MP hot spot. - */ - u_int32_t flags; /* MUTEX_XXX */ -} DB_MUTEX; - -/* Macro to get a reference to a specific mutex. */ -#define MUTEXP_SET(indx) \ - (DB_MUTEX *) \ - ((u_int8_t *)mtxmgr->mutex_array + (indx) * mtxregion->mutex_size); - -#endif /* !_DB_MUTEX_INT_H_ */ diff --git a/storage/bdb/dbinc/os.h b/storage/bdb/dbinc/os.h deleted file mode 100644 index 52013630908..00000000000 --- a/storage/bdb/dbinc/os.h +++ /dev/null @@ -1,123 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os.h,v 12.10 2005/10/31 02:22:24 bostic Exp $ - */ - -#ifndef _DB_OS_H_ -#define _DB_OS_H_ - -#if defined(__cplusplus) -extern "C" { -#endif - -/* Number of times to retry system calls that return EINTR or EBUSY. */ -#define DB_RETRY 100 - -#ifdef __TANDEM -/* - * OSS Tandem problem: fsync can return a Guardian file system error of 70, - * which has no symbolic name in OSS. HP says to retry the fsync. [#12957] - */ -#define RETRY_CHK(op, ret) do { \ - int __retries = DB_RETRY; \ - do { \ - (ret) = (op); \ - } while ((ret) != 0 && (((ret) = __os_get_errno()) == EAGAIN || \ - (ret) == EBUSY || (ret) == EINTR || (ret) == EIO || \ - (ret) == 70) && \ - --__retries > 0); \ -} while (0) -#else -#define RETRY_CHK(op, ret) do { \ - int __retries = DB_RETRY; \ - do { \ - (ret) = (op); \ - } while ((ret) != 0 && (((ret) = __os_get_errno()) == EAGAIN || \ - (ret) == EBUSY || (ret) == EINTR || (ret) == EIO) && \ - --__retries > 0); \ -} while (0) -#endif - -#define RETRY_CHK_EINTR_ONLY(op, ret) do { \ - int __retries = DB_RETRY; \ - do { \ - (ret) = (op); \ - } while ((ret) != 0 && \ - (((ret) = __os_get_errno()) == EINTR) && --__retries > 0); \ -} while (0) - -/* - * Flags understood by __os_open. - */ -#define DB_OSO_ABSMODE 0x0001 /* Absolute mode specified. */ -#define DB_OSO_CREATE 0x0002 /* POSIX: O_CREAT */ -#define DB_OSO_DIRECT 0x0004 /* Don't buffer the file in the OS. */ -#define DB_OSO_DSYNC 0x0008 /* POSIX: O_DSYNC. */ -#define DB_OSO_EXCL 0x0010 /* POSIX: O_EXCL */ -#define DB_OSO_RDONLY 0x0020 /* POSIX: O_RDONLY */ -#define DB_OSO_REGION 0x0040 /* Opening a region file. */ -#define DB_OSO_SEQ 0x0080 /* Expected sequential access. */ -#define DB_OSO_TEMP 0x0100 /* Remove after last close. */ -#define DB_OSO_TRUNC 0x0200 /* POSIX: O_TRUNC */ - -/* - * Seek options understood by __os_seek. - */ -typedef enum { - DB_OS_SEEK_CUR, /* POSIX: SEEK_CUR */ - DB_OS_SEEK_END, /* POSIX: SEEK_END */ - DB_OS_SEEK_SET /* POSIX: SEEK_SET */ -} DB_OS_SEEK; - -/* - * We group certain seek/write calls into a single function so that we - * can use pread(2)/pwrite(2) where they're available. - */ -#define DB_IO_READ 1 -#define DB_IO_WRITE 2 - -/* DB filehandle. */ -struct __fh_t { - /* - * The file-handle mutex is only used to protect the handle/fd - * across seek and read/write pairs, it does not protect the - * the reference count, or any other fields in the structure. - */ - db_mutex_t mtx_fh; /* Mutex to lock. */ - - int ref; /* Reference count. */ - -#if defined(DB_WIN32) - HANDLE handle; /* Windows/32 file handle. */ -#endif - int fd; /* POSIX file descriptor. */ - - char *name; /* File name (ref DB_FH_UNLINK) */ - - /* - * Last seek statistics, used for zero-filling on filesystems - * that don't support it directly. - */ - db_pgno_t pgno; - u_int32_t pgsize; - u_int32_t offset; - -#define DB_FH_NOSYNC 0x01 /* Handle doesn't need to be sync'd. */ -#define DB_FH_OPENED 0x02 /* Handle is valid. */ -#define DB_FH_UNLINK 0x04 /* Unlink on close */ - u_int8_t flags; -}; - -/* Standard 600 mode for __db_omode. */ -#define OWNER_RW "rw-------" - -#if defined(__cplusplus) -} -#endif - -#include "dbinc_auto/os_ext.h" -#endif /* !_DB_OS_H_ */ diff --git a/storage/bdb/dbinc/qam.h b/storage/bdb/dbinc/qam.h deleted file mode 100644 index fdf1aa96eec..00000000000 --- a/storage/bdb/dbinc/qam.h +++ /dev/null @@ -1,176 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: qam.h,v 12.3 2005/10/16 18:42:40 bostic Exp $ - */ - -#ifndef _DB_QAM_H_ -#define _DB_QAM_H_ - -/* - * QAM data elements: a status field and the data. - */ -typedef struct _qamdata { - u_int8_t flags; /* 00: delete bit. */ -#define QAM_VALID 0x01 -#define QAM_SET 0x02 - u_int8_t data[1]; /* Record. */ -} QAMDATA; - -struct __queue; typedef struct __queue QUEUE; -struct __qcursor; typedef struct __qcursor QUEUE_CURSOR; - -struct __qcursor { - /* struct __dbc_internal */ - __DBC_INTERNAL - - /* Queue private part */ - - /* Per-thread information: queue private. */ - db_recno_t recno; /* Current record number. */ - - u_int32_t flags; -}; - -typedef struct __mpfarray { - u_int32_t n_extent; /* Number of extents in table. */ - u_int32_t low_extent; /* First extent open. */ - u_int32_t hi_extent; /* Last extent open. */ - struct __qmpf { - int pinref; - DB_MPOOLFILE *mpf; - } *mpfarray; /* Array of open extents. */ -} MPFARRAY; - -/* - * The in-memory, per-tree queue data structure. - */ -struct __queue { - db_pgno_t q_meta; /* Database meta-data page. */ - db_pgno_t q_root; /* Database root page. */ - - int re_pad; /* Fixed-length padding byte. */ - u_int32_t re_len; /* Length for fixed-length records. */ - u_int32_t rec_page; /* records per page */ - u_int32_t page_ext; /* Pages per extent */ - MPFARRAY array1, array2; /* File arrays. */ - - /* Extent file configuration: */ - DBT pgcookie; /* Initialized pgcookie. */ - DB_PGINFO pginfo; /* Initialized pginfo struct. */ - - char *path; /* Space allocated to file pathname. */ - char *name; /* The name of the file. */ - char *dir; /* The dir of the file. */ - int mode; /* Mode to open extents. */ -}; - -/* Format for queue extent names. */ -#define QUEUE_EXTENT "%s%c__dbq.%s.%d" -#define QUEUE_EXTENT_HEAD "__dbq.%s." - -typedef struct __qam_filelist { - DB_MPOOLFILE *mpf; - u_int32_t id; -} QUEUE_FILELIST; - -/* - * Calculate the page number of a recno. - * - * Number of records per page = - * Divide the available space on the page by the record len + header. - * - * Page number for record = - * divide the physical record number by the records per page - * add the root page number - * For now the root page will always be 1, but we might want to change - * in the future (e.g. multiple fixed len queues per file). - * - * Index of record on page = - * physical record number, less the logical pno times records/page - */ -#define CALC_QAM_RECNO_PER_PAGE(dbp) \ - (((dbp)->pgsize - QPAGE_SZ(dbp)) / \ - (u_int32_t)DB_ALIGN((uintmax_t)SSZA(QAMDATA, data) + \ - ((QUEUE *)(dbp)->q_internal)->re_len, sizeof(u_int32_t))) - -#define QAM_RECNO_PER_PAGE(dbp) (((QUEUE*)(dbp)->q_internal)->rec_page) - -#define QAM_RECNO_PAGE(dbp, recno) \ - (((QUEUE *)(dbp)->q_internal)->q_root \ - + (((recno) - 1) / QAM_RECNO_PER_PAGE(dbp))) - -#define QAM_PAGE_EXTENT(dbp, pgno) \ - (((pgno) - 1) / ((QUEUE *)(dbp)->q_internal)->page_ext) - -#define QAM_RECNO_EXTENT(dbp, recno) \ - QAM_PAGE_EXTENT(dbp, QAM_RECNO_PAGE(dbp, recno)) - -#define QAM_RECNO_INDEX(dbp, pgno, recno) \ - (((recno) - 1) - (QAM_RECNO_PER_PAGE(dbp) \ - * (pgno - ((QUEUE *)(dbp)->q_internal)->q_root))) - -#define QAM_GET_RECORD(dbp, page, index) \ - ((QAMDATA *)((u_int8_t *)(page) + (QPAGE_SZ(dbp) + \ - (DB_ALIGN((uintmax_t)SSZA(QAMDATA, data) + \ - ((QUEUE *)(dbp)->q_internal)->re_len, sizeof(u_int32_t)) * index)))) - -#define QAM_AFTER_CURRENT(meta, recno) \ - ((recno) > (meta)->cur_recno && \ - ((meta)->first_recno <= (meta)->cur_recno || \ - ((recno) < (meta)->first_recno && \ - (recno) - (meta)->cur_recno < (meta)->first_recno - (recno)))) - -#define QAM_BEFORE_FIRST(meta, recno) \ - ((recno) < (meta)->first_recno && \ - ((meta->first_recno <= (meta)->cur_recno || \ - ((recno) > (meta)->cur_recno && \ - (recno) - (meta)->cur_recno > (meta)->first_recno - (recno))))) - -#define QAM_NOT_VALID(meta, recno) \ - (recno == RECNO_OOB || \ - QAM_BEFORE_FIRST(meta, recno) || QAM_AFTER_CURRENT(meta, recno)) - -/* - * Log opcodes for the mvptr routine. - */ -#define QAM_SETFIRST 0x01 -#define QAM_SETCUR 0x02 -#define QAM_TRUNCATE 0x04 - -/* - * Parameter to __qam_position. - */ -typedef enum { - QAM_READ, - QAM_WRITE, - QAM_CONSUME -} qam_position_mode; - -typedef enum { - QAM_PROBE_GET, - QAM_PROBE_PUT, - QAM_PROBE_MPF -} qam_probe_mode; - -/* - * Ops for __qam_nameop. - */ -typedef enum { - QAM_NAME_DISCARD, - QAM_NAME_RENAME, - QAM_NAME_REMOVE -} qam_name_op; - -#define __qam_fget(dbp, pgnoaddr, flags, addrp) \ - __qam_fprobe(dbp, *pgnoaddr, addrp, QAM_PROBE_GET, flags) - -#define __qam_fput(dbp, pageno, addrp, flags) \ - __qam_fprobe(dbp, pageno, addrp, QAM_PROBE_PUT, flags) - -#include "dbinc_auto/qam_auto.h" -#include "dbinc_auto/qam_ext.h" -#endif /* !_DB_QAM_H_ */ diff --git a/storage/bdb/dbinc/queue.h b/storage/bdb/dbinc/queue.h deleted file mode 100644 index d76f2019f6f..00000000000 --- a/storage/bdb/dbinc/queue.h +++ /dev/null @@ -1,563 +0,0 @@ -/* - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)queue.h 8.5 (Berkeley) 8/20/94 - * $FreeBSD: src/sys/sys/queue.h,v 1.54 2002/08/05 05:18:43 alfred Exp $ - */ - -#ifndef _DB_QUEUE_H_ -#define _DB_QUEUE_H_ - -#if defined(__cplusplus) -extern "C" { -#endif - -/* - * This file defines four types of data structures: singly-linked lists, - * singly-linked tail queues, lists and tail queues. - * - * A singly-linked list is headed by a single forward pointer. The elements - * are singly linked for minimum space and pointer manipulation overhead at - * the expense of O(n) removal for arbitrary elements. New elements can be - * added to the list after an existing element or at the head of the list. - * Elements being removed from the head of the list should use the explicit - * macro for this purpose for optimum efficiency. A singly-linked list may - * only be traversed in the forward direction. Singly-linked lists are ideal - * for applications with large datasets and few or no removals or for - * implementing a LIFO queue. - * - * A singly-linked tail queue is headed by a pair of pointers, one to the - * head of the list and the other to the tail of the list. The elements are - * singly linked for minimum space and pointer manipulation overhead at the - * expense of O(n) removal for arbitrary elements. New elements can be added - * to the list after an existing element, at the head of the list, or at the - * end of the list. Elements being removed from the head of the tail queue - * should use the explicit macro for this purpose for optimum efficiency. - * A singly-linked tail queue may only be traversed in the forward direction. - * Singly-linked tail queues are ideal for applications with large datasets - * and few or no removals or for implementing a FIFO queue. - * - * A list is headed by a single forward pointer (or an array of forward - * pointers for a hash table header). The elements are doubly linked - * so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before - * or after an existing element or at the head of the list. A list - * may only be traversed in the forward direction. - * - * A tail queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or - * after an existing element, at the head of the list, or at the end of - * the list. A tail queue may be traversed in either direction. - * - * For details on the use of these macros, see the queue(3) manual page. - * - * - * SLIST LIST STAILQ TAILQ - * _HEAD + + + + - * _HEAD_INITIALIZER + + + + - * _ENTRY + + + + - * _INIT + + + + - * _EMPTY + + + + - * _FIRST + + + + - * _NEXT + + + + - * _PREV - - - + - * _LAST - - + + - * _FOREACH + + + + - * _FOREACH_REVERSE - - - + - * _INSERT_HEAD + + + + - * _INSERT_BEFORE - + - + - * _INSERT_AFTER + + + + - * _INSERT_TAIL - - + + - * _CONCAT - - + + - * _REMOVE_HEAD + - + - - * _REMOVE + + + + - * - */ - -/* - * XXX - * We #undef all of the macros because there are incompatible versions of this - * file and these macros on various systems. What makes the problem worse is - * they are included and/or defined by system include files which we may have - * already loaded into Berkeley DB before getting here. For example, FreeBSD's - * <rpc/rpc.h> includes its system <sys/queue.h>, and VxWorks UnixLib.h defines - * several of the LIST_XXX macros. Visual C.NET 7.0 also defines some of these - * same macros in Vc7\PlatformSDK\Include\WinNT.h. Make sure we use ours. - */ -#undef LIST_EMPTY -#undef LIST_ENTRY -#undef LIST_FIRST -#undef LIST_FOREACH -#undef LIST_HEAD -#undef LIST_HEAD_INITIALIZER -#undef LIST_INIT -#undef LIST_INSERT_AFTER -#undef LIST_INSERT_BEFORE -#undef LIST_INSERT_HEAD -#undef LIST_NEXT -#undef LIST_REMOVE -#undef QMD_TRACE_ELEM -#undef QMD_TRACE_HEAD -#undef QUEUE_MACRO_DEBUG -#undef SLIST_EMPTY -#undef SLIST_ENTRY -#undef SLIST_FIRST -#undef SLIST_FOREACH -#undef SLIST_FOREACH_PREVPTR -#undef SLIST_HEAD -#undef SLIST_HEAD_INITIALIZER -#undef SLIST_INIT -#undef SLIST_INSERT_AFTER -#undef SLIST_INSERT_HEAD -#undef SLIST_NEXT -#undef SLIST_REMOVE -#undef SLIST_REMOVE_HEAD -#undef STAILQ_CONCAT -#undef STAILQ_EMPTY -#undef STAILQ_ENTRY -#undef STAILQ_FIRST -#undef STAILQ_FOREACH -#undef STAILQ_HEAD -#undef STAILQ_HEAD_INITIALIZER -#undef STAILQ_INIT -#undef STAILQ_INSERT_AFTER -#undef STAILQ_INSERT_HEAD -#undef STAILQ_INSERT_TAIL -#undef STAILQ_LAST -#undef STAILQ_NEXT -#undef STAILQ_REMOVE -#undef STAILQ_REMOVE_HEAD -#undef STAILQ_REMOVE_HEAD_UNTIL -#undef TAILQ_CONCAT -#undef TAILQ_EMPTY -#undef TAILQ_ENTRY -#undef TAILQ_FIRST -#undef TAILQ_FOREACH -#undef TAILQ_FOREACH_REVERSE -#undef TAILQ_HEAD -#undef TAILQ_HEAD_INITIALIZER -#undef TAILQ_INIT -#undef TAILQ_INSERT_AFTER -#undef TAILQ_INSERT_BEFORE -#undef TAILQ_INSERT_HEAD -#undef TAILQ_INSERT_TAIL -#undef TAILQ_LAST -#undef TAILQ_NEXT -#undef TAILQ_PREV -#undef TAILQ_REMOVE -#undef TRACEBUF -#undef TRASHIT - -#define QUEUE_MACRO_DEBUG 0 -#if QUEUE_MACRO_DEBUG -/* Store the last 2 places the queue element or head was altered */ -struct qm_trace { - char * lastfile; - int lastline; - char * prevfile; - int prevline; -}; - -#define TRACEBUF struct qm_trace trace; -#define TRASHIT(x) do {(x) = (void *)-1;} while (0) - -#define QMD_TRACE_HEAD(head) do { \ - (head)->trace.prevline = (head)->trace.lastline; \ - (head)->trace.prevfile = (head)->trace.lastfile; \ - (head)->trace.lastline = __LINE__; \ - (head)->trace.lastfile = __FILE__; \ -} while (0) - -#define QMD_TRACE_ELEM(elem) do { \ - (elem)->trace.prevline = (elem)->trace.lastline; \ - (elem)->trace.prevfile = (elem)->trace.lastfile; \ - (elem)->trace.lastline = __LINE__; \ - (elem)->trace.lastfile = __FILE__; \ -} while (0) - -#else -#define QMD_TRACE_ELEM(elem) -#define QMD_TRACE_HEAD(head) -#define TRACEBUF -#define TRASHIT(x) -#endif /* QUEUE_MACRO_DEBUG */ - -/* - * Singly-linked List declarations. - */ -#define SLIST_HEAD(name, type) \ -struct name { \ - struct type *slh_first; /* first element */ \ -} - -#define SLIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define SLIST_ENTRY(type) \ -struct { \ - struct type *sle_next; /* next element */ \ -} - -/* - * Singly-linked List functions. - */ -#define SLIST_EMPTY(head) ((head)->slh_first == NULL) - -#define SLIST_FIRST(head) ((head)->slh_first) - -#define SLIST_FOREACH(var, head, field) \ - for ((var) = SLIST_FIRST((head)); \ - (var); \ - (var) = SLIST_NEXT((var), field)) - -#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \ - for ((varp) = &SLIST_FIRST((head)); \ - ((var) = *(varp)) != NULL; \ - (varp) = &SLIST_NEXT((var), field)) - -#define SLIST_INIT(head) do { \ - SLIST_FIRST((head)) = NULL; \ -} while (0) - -#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ - SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \ - SLIST_NEXT((slistelm), field) = (elm); \ -} while (0) - -#define SLIST_INSERT_HEAD(head, elm, field) do { \ - SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \ - SLIST_FIRST((head)) = (elm); \ -} while (0) - -#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) - -#define SLIST_REMOVE(head, elm, type, field) do { \ - if (SLIST_FIRST((head)) == (elm)) { \ - SLIST_REMOVE_HEAD((head), field); \ - } \ - else { \ - struct type *curelm = SLIST_FIRST((head)); \ - while (SLIST_NEXT(curelm, field) != (elm)) \ - curelm = SLIST_NEXT(curelm, field); \ - SLIST_NEXT(curelm, field) = \ - SLIST_NEXT(SLIST_NEXT(curelm, field), field); \ - } \ -} while (0) - -#define SLIST_REMOVE_HEAD(head, field) do { \ - SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \ -} while (0) - -/* - * Singly-linked Tail queue declarations. - */ -#define STAILQ_HEAD(name, type) \ -struct name { \ - struct type *stqh_first;/* first element */ \ - struct type **stqh_last;/* addr of last next element */ \ -} - -#define STAILQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).stqh_first } - -#define STAILQ_ENTRY(type) \ -struct { \ - struct type *stqe_next; /* next element */ \ -} - -/* - * Singly-linked Tail queue functions. - */ -#define STAILQ_CONCAT(head1, head2) do { \ - if (!STAILQ_EMPTY((head2))) { \ - *(head1)->stqh_last = (head2)->stqh_first; \ - (head1)->stqh_last = (head2)->stqh_last; \ - STAILQ_INIT((head2)); \ - } \ -} while (0) - -#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) - -#define STAILQ_FIRST(head) ((head)->stqh_first) - -#define STAILQ_FOREACH(var, head, field) \ - for ((var) = STAILQ_FIRST((head)); \ - (var); \ - (var) = STAILQ_NEXT((var), field)) - -#define STAILQ_INIT(head) do { \ - STAILQ_FIRST((head)) = NULL; \ - (head)->stqh_last = &STAILQ_FIRST((head)); \ -} while (0) - -#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ - if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ - STAILQ_NEXT((tqelm), field) = (elm); \ -} while (0) - -#define STAILQ_INSERT_HEAD(head, elm, field) do { \ - if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ - STAILQ_FIRST((head)) = (elm); \ -} while (0) - -#define STAILQ_INSERT_TAIL(head, elm, field) do { \ - STAILQ_NEXT((elm), field) = NULL; \ - *(head)->stqh_last = (elm); \ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ -} while (0) - -#define STAILQ_LAST(head, type, field) \ - (STAILQ_EMPTY((head)) ? \ - NULL : \ - ((struct type *) \ - ((char *)((head)->stqh_last) - __offsetof(struct type, field)))) - -#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) - -#define STAILQ_REMOVE(head, elm, type, field) do { \ - if (STAILQ_FIRST((head)) == (elm)) { \ - STAILQ_REMOVE_HEAD((head), field); \ - } \ - else { \ - struct type *curelm = STAILQ_FIRST((head)); \ - while (STAILQ_NEXT(curelm, field) != (elm)) \ - curelm = STAILQ_NEXT(curelm, field); \ - if ((STAILQ_NEXT(curelm, field) = \ - STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\ - (head)->stqh_last = &STAILQ_NEXT((curelm), field);\ - } \ -} while (0) - -#define STAILQ_REMOVE_HEAD(head, field) do { \ - if ((STAILQ_FIRST((head)) = \ - STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \ - (head)->stqh_last = &STAILQ_FIRST((head)); \ -} while (0) - -#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \ - if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \ - (head)->stqh_last = &STAILQ_FIRST((head)); \ -} while (0) - -/* - * List declarations. - */ -#define LIST_HEAD(name, type) \ -struct name { \ - struct type *lh_first; /* first element */ \ -} - -#define LIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define LIST_ENTRY(type) \ -struct { \ - struct type *le_next; /* next element */ \ - struct type **le_prev; /* address of previous next element */ \ -} - -/* - * List functions. - */ - -#define LIST_EMPTY(head) ((head)->lh_first == NULL) - -#define LIST_FIRST(head) ((head)->lh_first) - -#define LIST_FOREACH(var, head, field) \ - for ((var) = LIST_FIRST((head)); \ - (var); \ - (var) = LIST_NEXT((var), field)) - -#define LIST_INIT(head) do { \ - LIST_FIRST((head)) = NULL; \ -} while (0) - -#define LIST_INSERT_AFTER(listelm, elm, field) do { \ - if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\ - LIST_NEXT((listelm), field)->field.le_prev = \ - &LIST_NEXT((elm), field); \ - LIST_NEXT((listelm), field) = (elm); \ - (elm)->field.le_prev = &LIST_NEXT((listelm), field); \ -} while (0) - -#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.le_prev = (listelm)->field.le_prev; \ - LIST_NEXT((elm), field) = (listelm); \ - *(listelm)->field.le_prev = (elm); \ - (listelm)->field.le_prev = &LIST_NEXT((elm), field); \ -} while (0) - -#define LIST_INSERT_HEAD(head, elm, field) do { \ - if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \ - LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\ - LIST_FIRST((head)) = (elm); \ - (elm)->field.le_prev = &LIST_FIRST((head)); \ -} while (0) - -#define LIST_NEXT(elm, field) ((elm)->field.le_next) - -#define LIST_REMOVE(elm, field) do { \ - if (LIST_NEXT((elm), field) != NULL) \ - LIST_NEXT((elm), field)->field.le_prev = \ - (elm)->field.le_prev; \ - *(elm)->field.le_prev = LIST_NEXT((elm), field); \ -} while (0) - -/* - * Tail queue declarations. - */ -#define TAILQ_HEAD(name, type) \ -struct name { \ - struct type *tqh_first; /* first element */ \ - struct type **tqh_last; /* addr of last next element */ \ - TRACEBUF \ -} - -#define TAILQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).tqh_first } - -#define TAILQ_ENTRY(type) \ -struct { \ - struct type *tqe_next; /* next element */ \ - struct type **tqe_prev; /* address of previous next element */ \ - TRACEBUF \ -} - -/* - * Tail queue functions. - */ -#define TAILQ_CONCAT(head1, head2, field) do { \ - if (!TAILQ_EMPTY(head2)) { \ - *(head1)->tqh_last = (head2)->tqh_first; \ - (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \ - (head1)->tqh_last = (head2)->tqh_last; \ - TAILQ_INIT((head2)); \ - QMD_TRACE_HEAD(head); \ - QMD_TRACE_HEAD(head2); \ - } \ -} while (0) - -#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) - -#define TAILQ_FIRST(head) ((head)->tqh_first) - -#define TAILQ_FOREACH(var, head, field) \ - for ((var) = TAILQ_FIRST((head)); \ - (var); \ - (var) = TAILQ_NEXT((var), field)) - -#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ - for ((var) = TAILQ_LAST((head), headname); \ - (var); \ - (var) = TAILQ_PREV((var), headname, field)) - -#define TAILQ_INIT(head) do { \ - TAILQ_FIRST((head)) = NULL; \ - (head)->tqh_last = &TAILQ_FIRST((head)); \ - QMD_TRACE_HEAD(head); \ -} while (0) - -#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ - if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\ - TAILQ_NEXT((elm), field)->field.tqe_prev = \ - &TAILQ_NEXT((elm), field); \ - else { \ - (head)->tqh_last = &TAILQ_NEXT((elm), field); \ - QMD_TRACE_HEAD(head); \ - } \ - TAILQ_NEXT((listelm), field) = (elm); \ - (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \ - QMD_TRACE_ELEM(&(elm)->field); \ - QMD_TRACE_ELEM(&listelm->field); \ -} while (0) - -#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ - TAILQ_NEXT((elm), field) = (listelm); \ - *(listelm)->field.tqe_prev = (elm); \ - (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \ - QMD_TRACE_ELEM(&(elm)->field); \ - QMD_TRACE_ELEM(&listelm->field); \ -} while (0) - -#define TAILQ_INSERT_HEAD(head, elm, field) do { \ - if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \ - TAILQ_FIRST((head))->field.tqe_prev = \ - &TAILQ_NEXT((elm), field); \ - else \ - (head)->tqh_last = &TAILQ_NEXT((elm), field); \ - TAILQ_FIRST((head)) = (elm); \ - (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \ - QMD_TRACE_HEAD(head); \ - QMD_TRACE_ELEM(&(elm)->field); \ -} while (0) - -#define TAILQ_INSERT_TAIL(head, elm, field) do { \ - TAILQ_NEXT((elm), field) = NULL; \ - (elm)->field.tqe_prev = (head)->tqh_last; \ - *(head)->tqh_last = (elm); \ - (head)->tqh_last = &TAILQ_NEXT((elm), field); \ - QMD_TRACE_HEAD(head); \ - QMD_TRACE_ELEM(&(elm)->field); \ -} while (0) - -#define TAILQ_LAST(head, headname) \ - (*(((struct headname *)((head)->tqh_last))->tqh_last)) - -#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) - -#define TAILQ_PREV(elm, headname, field) \ - (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) - -#define TAILQ_REMOVE(head, elm, field) do { \ - if ((TAILQ_NEXT((elm), field)) != NULL) \ - TAILQ_NEXT((elm), field)->field.tqe_prev = \ - (elm)->field.tqe_prev; \ - else { \ - (head)->tqh_last = (elm)->field.tqe_prev; \ - QMD_TRACE_HEAD(head); \ - } \ - *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \ - TRASHIT((elm)->field.tqe_next); \ - TRASHIT((elm)->field.tqe_prev); \ - QMD_TRACE_ELEM(&(elm)->field); \ -} while (0) - -#if defined(__cplusplus) -} -#endif -#endif /* !_DB_QUEUE_H_ */ diff --git a/storage/bdb/dbinc/region.h b/storage/bdb/dbinc/region.h deleted file mode 100644 index 5999893962a..00000000000 --- a/storage/bdb/dbinc/region.h +++ /dev/null @@ -1,274 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1998-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: region.h,v 12.7 2005/10/13 00:53:00 bostic Exp $ - */ - -#ifndef _DB_REGION_H_ -#define _DB_REGION_H_ - -/* - * The DB environment consists of some number of "regions", which are described - * by the following four structures: - * - * REGENV -- shared information about the environment - * REGENV_REF -- file describing system memory version of REGENV - * REGION -- shared information about a single region - * REGINFO -- per-process information about a REGION - * - * There are three types of memory that hold regions: - * per-process heap (malloc) - * file mapped into memory (mmap, MapViewOfFile) - * system memory (shmget, CreateFileMapping) - * - * By default, regions are created in filesystem-backed shared memory. They - * can also be created in system shared memory (DB_SYSTEM_MEM), or, if private - * to a process, in heap memory (DB_PRIVATE). - * - * Regions in the filesystem are named "__db.001", "__db.002" and so on. If - * we're not using a private environment allocated in heap, "__db.001" will - * always exist, as we use it to synchronize on the regions, whether they are - * in filesystem-backed memory or system memory. - * - * The file "__db.001" contains a REGENV structure and an array of REGION - * structures. Each REGION structures describes an underlying chunk of - * shared memory. - * - * __db.001 - * +---------+ - * |REGENV | - * +---------+ +----------+ - * |REGION |-> | __db.002 | - * | | +----------+ - * +---------+ +----------+ - * |REGION |-> | __db.003 | - * | | +----------+ - * +---------+ +----------+ - * |REGION |-> | __db.004 | - * | | +----------+ - * +---------+ - * - * The tricky part about manipulating the regions is creating or joining the - * database environment. We have to be sure only a single thread of control - * creates and/or recovers a database environment. All other threads should - * then join without seeing inconsistent data. - * - * We do this in two parts: first, we use the underlying O_EXCL flag to the - * open system call to serialize creation of the __db.001 file. The thread - * of control creating that file then proceeds to create the remaining - * regions in the environment, including the mutex region. Once the mutex - * region has been created, the creating thread of control fills in the - * __db.001 file's magic number. Other threads of control (the ones that - * didn't create the __db.001 file), wait on the initialization of the - * __db.001 file's magic number. After it has been initialized, all threads - * of control can proceed, using normal shared mutex locking procedures for - * exclusion. - * - * REGIONs are not moved or removed during the life of the environment, and - * so processes can have long-lived references to them. - * - * One of the REGION structures describes the environment region itself. - * - * The REGION array is not locked in any way. It's an array so we don't have - * to manipulate data structures after a crash -- on some systems, we have to - * join and clean up the mutex region after application failure. Using an - * array means we don't have to worry about broken links or other nastiness - * after the failure. - * - * All requests to create or join a region return a REGINFO structure, which - * is held by the caller and used to open and subsequently close the reference - * to the region. The REGINFO structure contains the per-process information - * that we need to access the region. - * - * The one remaining complication. If the regions (including the environment - * region) live in system memory, and the system memory isn't "named" somehow - * in the filesystem name space, we need some way of finding it. Do this by - * by writing the REGENV_REF structure into the "__db.001" file. When we find - * a __db.001 file that is too small to be a real, on-disk environment, we use - * the information it contains to redirect to the real "__db.001" file/memory. - * This currently only happens when the REGENV file is in shared system memory. - * - * Although DB does not currently grow regions when they run out of memory, it - * would be possible to do so. To grow a region, allocate a new region of the - * appropriate size, then copy the old region over it and insert the additional - * memory into the already existing shalloc arena. Region users must reset - * their base addresses and any local pointers into the memory, of course. - * This failed in historic versions of DB because the region mutexes lived in - * the mapped memory, and when it was unmapped and remapped (or copied), - * threads could lose track of it. Also, some systems didn't support mutex - * copying, e.g., from OSF1 V4.0: - * - * The address of an msemaphore structure may be significant. If the - * msemaphore structure contains any value copied from an msemaphore - * structure at a different address, the result is undefined. - * - * All mutexes are now maintained in a separate region which is never unmapped, - * so growing regions should be possible. - */ - -#if defined(__cplusplus) -extern "C" { -#endif - -#define DB_REGION_PREFIX "__db" /* DB file name prefix. */ -#define DB_REGION_FMT "__db.%03d" /* Region file name format. */ -#define DB_REGION_ENV "__db.001" /* Primary environment name. */ -#define DB_REGION_NAME_LENGTH 8 /* Length of file names. */ - -#define INVALID_REGION_ID 0 /* Out-of-band region ID. */ -#define REGION_ID_ENV 1 /* Primary environment ID. */ - -typedef enum { - INVALID_REGION_TYPE=0, /* Region type. */ - REGION_TYPE_ENV, - REGION_TYPE_LOCK, - REGION_TYPE_LOG, - REGION_TYPE_MPOOL, - REGION_TYPE_MUTEX, - REGION_TYPE_TXN } reg_type_t; - -#define INVALID_REGION_SEGID -1 /* Segment IDs are either shmget(2) or - * Win16 segment identifiers. They are - * both stored in a "long", and we need - * an out-of-band value. - */ -/* - * Nothing can live at region offset 0, because, in all cases, that's where - * we store *something*. Lots of code needs an out-of-band value for region - * offsets, so we use 0. - */ -#define INVALID_ROFF 0 - -/* Reference describing system memory version of REGENV. */ -typedef struct __db_reg_env_ref { - roff_t size; /* Region size. */ - long segid; /* UNIX shmget ID, VxWorks ID. */ -} REGENV_REF; - -/* Per-environment region information. */ -typedef struct __db_reg_env { - /* - * !!! - * The magic, panic, version and envid fields of the region are fixed - * in size, the timestamp field is the first field which is variable - * length. These fields must never change in order, to guarantee we - * can always read them, no matter what Berkeley DB release we have. - * - * !!! - * The magic and panic fields are NOT protected by any mutex, and for - * this reason cannot be anything more complicated than zero/non-zero. - */ - u_int32_t magic; /* Valid region magic number. */ - u_int32_t panic; /* Environment is dead. */ - - u_int32_t majver; /* Major DB version number. */ - u_int32_t minver; /* Minor DB version number. */ - u_int32_t patchver; /* Patch DB version number. */ - - u_int32_t envid; /* Unique environment ID. */ - - time_t timestamp; /* Creation time. */ - - u_int32_t init_flags; /* Flags environment initialized with.*/ - - /* - * The mtx_regenv mutex protects the environment reference count and - * memory allocation from the primary shared region (the crypto and - * replication implementations allocate memory from the primary shared - * region). The rest of the fields are initialized at creation time, - * and so don't need mutex protection. The flags, op_timestamp and - * rep_timestamp fields are used by replication only and are - * protected * by the replication mutex. The rep_timestamp is - * is not protected when it is used in recovery as that is already - * single threaded. - */ - db_mutex_t mtx_regenv; /* Refcnt, region allocation mutex. */ - u_int32_t refcnt; /* References to the environment. */ - - u_int32_t region_cnt; /* Number of REGIONs. */ - roff_t region_off; /* Offset of region array */ - - roff_t cipher_off; /* Offset of cipher area */ - - roff_t rep_off; /* Offset of the replication area. */ -#define DB_REGENV_REPLOCKED 0x0001 /* Env locked for rep backup. */ - u_int32_t flags; /* Shared environment flags. */ -#define DB_REGENV_TIMEOUT 30 /* Backup timeout. */ - time_t op_timestamp; /* Timestamp for operations. */ - time_t rep_timestamp; /* Timestamp for rep db handles. */ - - size_t pad; /* Guarantee that following memory is - * size_t aligned. This is necessary - * because we're going to store the - * allocation region information there. - */ -} REGENV; - -/* Per-region shared region information. */ -typedef struct __db_region { - u_int32_t id; /* Region id. */ - reg_type_t type; /* Region type. */ - - roff_t size_orig; /* Region size in bytes (original). */ - roff_t size; /* Region size in bytes (adjusted). */ - - roff_t primary; /* Primary data structure offset. */ - - long segid; /* UNIX shmget(2), Win16 segment ID. */ -} REGION; - -/* - * Per-process/per-attachment information about a single region. - */ -struct __db_reginfo_t { /* __db_r_attach IN parameters. */ - DB_ENV *dbenv; /* Enclosing environment. */ - reg_type_t type; /* Region type. */ - u_int32_t id; /* Region id. */ - - /* __db_r_attach OUT parameters. */ - REGION *rp; /* Shared region. */ - - char *name; /* Region file name. */ - - void *addr_orig; /* Region address (original). */ - void *addr; /* Region address (adjusted). */ - void *primary; /* Primary data structure address. */ - - size_t max_alloc; /* Maximum bytes allocated. */ - size_t allocated; /* Bytes allocated. */ - -#ifdef DB_WIN32 - HANDLE wnt_handle; /* Win/NT HANDLE. */ -#endif - -#define REGION_CREATE 0x01 /* Caller created region. */ -#define REGION_CREATE_OK 0x02 /* Caller willing to create region. */ -#define REGION_JOIN_OK 0x04 /* Caller is looking for a match. */ - u_int32_t flags; -}; - -/* - * R_ADDR Return a per-process address for a shared region offset. - * R_OFFSET Return a shared region offset for a per-process address. - */ -#define R_ADDR(reginfop, offset) \ - (F_ISSET((reginfop)->dbenv, DB_ENV_PRIVATE) ? (void *)(offset) :\ - (void *)((u_int8_t *)((reginfop)->addr) + (offset))) -#define R_OFFSET(reginfop, p) \ - (F_ISSET((reginfop)->dbenv, DB_ENV_PRIVATE) ? (roff_t)(p) : \ - (roff_t)((u_int8_t *)(p) - (u_int8_t *)(reginfop)->addr)) - -/* PANIC_CHECK: Check to see if the DB environment is dead. */ -#define PANIC_CHECK(dbenv) \ - if ((dbenv)->reginfo != NULL && ((REGENV *) \ - ((REGINFO *)(dbenv)->reginfo)->primary)->panic != 0 && \ - !F_ISSET((dbenv), DB_ENV_NOPANIC)) \ - return (__db_panic_msg(dbenv)); - -#if defined(__cplusplus) -} -#endif -#endif /* !_DB_REGION_H_ */ diff --git a/storage/bdb/dbinc/rep.h b/storage/bdb/dbinc/rep.h deleted file mode 100644 index effecaba8a1..00000000000 --- a/storage/bdb/dbinc/rep.h +++ /dev/null @@ -1,392 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2001-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: rep.h,v 12.22 2005/10/27 13:27:01 bostic Exp $ - */ - -#ifndef _REP_H_ -#define _REP_H_ - -#include "dbinc_auto/rep_auto.h" - -/* - * Message types - */ -#define REP_ALIVE 1 /* I am alive message. */ -#define REP_ALIVE_REQ 2 /* Request for alive messages. */ -#define REP_ALL_REQ 3 /* Request all log records greater than LSN. */ -#define REP_BULK_LOG 4 /* Bulk transfer of log records. */ -#define REP_BULK_PAGE 5 /* Bulk transfer of pages. */ -#define REP_DUPMASTER 6 /* Duplicate master detected; propagate. */ -#define REP_FILE 7 /* Page of a database file. NOTUSED */ -#define REP_FILE_FAIL 8 /* File requested does not exist. */ -#define REP_FILE_REQ 9 /* Request for a database file. NOTUSED */ -#define REP_LOG 10 /* Log record. */ -#define REP_LOG_MORE 11 /* There are more log records to request. */ -#define REP_LOG_REQ 12 /* Request for a log record. */ -#define REP_MASTER_REQ 13 /* Who is the master */ -#define REP_NEWCLIENT 14 /* Announces the presence of a new client. */ -#define REP_NEWFILE 15 /* Announce a log file change. */ -#define REP_NEWMASTER 16 /* Announces who the master is. */ -#define REP_NEWSITE 17 /* Announces that a site has heard from a new - * site; like NEWCLIENT, but indirect. A - * NEWCLIENT message comes directly from the new - * client while a NEWSITE comes indirectly from - * someone who heard about a NEWSITE. - */ -#define REP_PAGE 18 /* Database page. */ -#define REP_PAGE_FAIL 19 /* Requested page does not exist. */ -#define REP_PAGE_MORE 20 /* There are more pages to request. */ -#define REP_PAGE_REQ 21 /* Request for a database page. */ -#define REP_REREQUEST 22 /* Force rerequest. */ -#define REP_UPDATE 23 /* Environment hotcopy information. */ -#define REP_UPDATE_REQ 24 /* Request for hotcopy information. */ -#define REP_VERIFY 25 /* A log record for verification. */ -#define REP_VERIFY_FAIL 26 /* The client is outdated. */ -#define REP_VERIFY_REQ 27 /* Request for a log record to verify. */ -#define REP_VOTE1 28 /* Send out your information for an election. */ -#define REP_VOTE2 29 /* Send a "you are master" vote. */ - -/* - * REP_PRINT_MESSAGE - * A function to print a debugging message. - * - * RPRINT - * A macro for debug printing. Takes as an arg the arg set for __db_msg. - * - * !!! This function assumes a local DB_MSGBUF variable called 'mb'. - */ -#ifdef DIAGNOSTIC -#define REP_PRINT_MESSAGE(dbenv, eid, rp, str) \ - __rep_print_message(dbenv, eid, rp, str) -#define RPRINT(e, r, x) do { \ - if (FLD_ISSET((e)->verbose, DB_VERB_REPLICATION)) { \ - DB_MSGBUF_INIT(&mb); \ - if ((e)->db_errpfx == NULL) { \ - if (F_ISSET((r), REP_F_CLIENT)) \ - __db_msgadd((e), &mb, "CLIENT: "); \ - else if (F_ISSET((r), REP_F_MASTER)) \ - __db_msgadd((e), &mb, "MASTER: "); \ - else \ - __db_msgadd((e), &mb, "REP_UNDEF: "); \ - } else \ - __db_msgadd((e), &mb, "%s: ",(e)->db_errpfx); \ - __db_msgadd x; \ - DB_MSGBUF_FLUSH((e), &mb); \ - } \ -} while (0) -#else -#define REP_PRINT_MESSAGE(dbenv, eid, rp, str) -#define RPRINT(e, r, x) -#endif - -/* - * Election gen file name - * The file contains an egen number for an election this client has NOT - * participated in. I.e. it is the number of a future election. We - * create it when we create the rep region, if it doesn't already exist - * and initialize egen to 1. If it does exist, we read it when we create - * the rep region. We write it immediately before sending our VOTE1 in - * an election. That way, if a client has ever sent a vote for any - * election, the file is already going to be updated to reflect a future - * election, should it crash. - */ -#define REP_EGENNAME "__db.rep.egen" - -/* - * Database types for __rep_client_dbinit - */ -typedef enum { - REP_DB, /* Log record database. */ - REP_PG /* Pg database. */ -} repdb_t; - -/* Macros to lock/unlock the replication region as a whole. */ -#define REP_SYSTEM_LOCK(dbenv) \ - MUTEX_LOCK(dbenv, ((DB_REP *) \ - (dbenv)->rep_handle)->region->mtx_region) -#define REP_SYSTEM_UNLOCK(dbenv) \ - MUTEX_UNLOCK(dbenv, ((DB_REP *) \ - (dbenv)->rep_handle)->region->mtx_region) - -/* - * REP -- - * Shared replication structure. - */ -typedef struct __rep { - db_mutex_t mtx_region; /* Region mutex. */ - db_mutex_t mtx_clientdb; /* Client database mutex. */ - roff_t tally_off; /* Offset of the tally region. */ - roff_t v2tally_off; /* Offset of the vote2 tally region. */ - int eid; /* Environment id. */ - int master_id; /* ID of the master site. */ - u_int32_t egen; /* Replication election generation. */ - u_int32_t gen; /* Replication generation number. */ - u_int32_t recover_gen; /* Last generation number in log. */ - int asites; /* Space allocated for sites. */ - int nsites; /* Number of sites in group. */ - int nvotes; /* Number of votes needed. */ - int priority; /* My priority in an election. */ - u_int32_t gbytes; /* Limit on data sent in single... */ - u_int32_t bytes; /* __rep_process_message call. */ -#define DB_REP_REQUEST_GAP 4 -#define DB_REP_MAX_GAP 128 - u_int32_t request_gap; /* # of records to receive before we - * request a missing log record. */ - u_int32_t max_gap; /* Maximum number of records before - * requesting a missing log record. */ - /* Status change information */ - int elect_th; /* A thread is in rep_elect. */ - u_int32_t msg_th; /* Number of callers in rep_proc_msg. */ - int start_th; /* A thread is in rep_start. */ - u_int32_t handle_cnt; /* Count of handles in library. */ - u_int32_t op_cnt; /* Multi-step operation count.*/ - int in_recovery; /* Running recovery now. */ - - /* Backup information. */ - u_int32_t nfiles; /* Number of files we have info on. */ - u_int32_t curfile; /* Current file we're getting. */ - __rep_fileinfo_args *curinfo; /* Current file info ptr. */ - void *finfo; /* Current file info buffer. */ - void *nextinfo; /* Next file info buffer. */ - void *originfo; /* Original file info buffer. */ - DB_LSN first_lsn; /* Earliest LSN we need. */ - DB_LSN last_lsn; /* Latest LSN we need. */ - db_pgno_t ready_pg; /* Next pg expected. */ - db_pgno_t waiting_pg; /* First pg after gap. */ - db_pgno_t max_wait_pg; /* Maximum pg requested. */ - u_int32_t npages; /* Num of pages rcvd for this file. */ - DB_MPOOLFILE *file_mpf; /* Mpoolfile for in-mem database. */ - DB *file_dbp; /* This file's page info. */ - DB *queue_dbp; /* Dbp for a queue file. */ - - /* Vote tallying information. */ - int sites; /* Sites heard from. */ - int winner; /* Current winner. */ - int w_priority; /* Winner priority. */ - u_int32_t w_gen; /* Winner generation. */ - DB_LSN w_lsn; /* Winner LSN. */ - u_int32_t w_tiebreaker; /* Winner tiebreaking value. */ - int votes; /* Number of votes for this site. */ - u_int32_t esec; /* Election start seconds. */ - u_int32_t eusec; /* Election start useconds. */ - - /* Statistics. */ - DB_REP_STAT stat; - - /* Configuration. */ -#define REP_C_BULK 0x00001 /* Bulk transfer. */ -#define REP_C_DELAYCLIENT 0x00002 /* Delay client sync-up. */ -#define REP_C_NOAUTOINIT 0x00004 /* No auto initialization. */ -#define REP_C_NOWAIT 0x00008 /* Immediate error return. */ - u_int32_t config; /* Configuration flags. */ - -#define REP_F_CLIENT 0x00001 /* Client replica. */ -#define REP_F_DELAY 0x00002 /* Delaying client sync-up. */ -#define REP_F_EPHASE1 0x00004 /* In phase 1 of election. */ -#define REP_F_EPHASE2 0x00008 /* In phase 2 of election. */ -#define REP_F_MASTER 0x00010 /* Master replica. */ -#define REP_F_MASTERELECT 0x00020 /* Master elect */ -#define REP_F_NOARCHIVE 0x00040 /* Rep blocks log_archive */ -#define REP_F_READY 0x00080 /* Wait for txn_cnt to be 0. */ -#define REP_F_RECOVER_LOG 0x00100 /* In recovery - log. */ -#define REP_F_RECOVER_PAGE 0x00200 /* In recovery - pages. */ -#define REP_F_RECOVER_UPDATE 0x00400 /* In recovery - files. */ -#define REP_F_RECOVER_VERIFY 0x00800 /* In recovery - verify. */ -#define REP_F_TALLY 0x01000 /* Tallied vote before elect. */ - u_int32_t flags; -} REP; - -/* - * Recovery flag mask to easily check any/all recovery bits. That is - * REP_F_READY and all REP_F_RECOVER*. This must change if the values - * of the flags change. - */ -#define REP_F_RECOVER_MASK \ - (REP_F_READY | REP_F_RECOVER_LOG | REP_F_RECOVER_PAGE | \ - REP_F_RECOVER_UPDATE | REP_F_RECOVER_VERIFY) - -#define IN_ELECTION(R) F_ISSET((R), REP_F_EPHASE1 | REP_F_EPHASE2) -#define IN_ELECTION_TALLY(R) \ - F_ISSET((R), REP_F_EPHASE1 | REP_F_EPHASE2 | REP_F_TALLY) -#define IS_REP_MASTER(dbenv) \ - (REP_ON(dbenv) && ((DB_REP *)(dbenv)->rep_handle)->region && \ - F_ISSET(((REP *)((DB_REP *)(dbenv)->rep_handle)->region), \ - REP_F_MASTER)) - -#define IS_REP_CLIENT(dbenv) \ - (REP_ON(dbenv) && ((DB_REP *)(dbenv)->rep_handle)->region && \ - F_ISSET(((REP *)((DB_REP *)(dbenv)->rep_handle)->region), \ - REP_F_CLIENT)) - -#define IS_CLIENT_PGRECOVER(dbenv) \ - (IS_REP_CLIENT(dbenv) && \ - F_ISSET(((REP *)((DB_REP *)(dbenv)->rep_handle)->region), \ - REP_F_RECOVER_PAGE)) - -/* - * Macros to figure out if we need to do replication pre/post-amble processing. - * Skip for specific DB handles owned by the replication layer, either because - * replication is running recovery or because it's a handle entirely owned by - * the replication code (replication opens its own databases to track state). - */ -#define IS_ENV_REPLICATED(E) (REP_ON(E) && \ - ((DB_REP *)((E)->rep_handle))->region != NULL && \ - ((DB_REP *)((E)->rep_handle))->region->flags != 0) - -/* - * Gap processing flags. These provide control over the basic - * gap processing algorithm for some special cases. - */ -#define REP_GAP_FORCE 0x001 /* Force a request for a gap. */ -#define REP_GAP_REREQUEST 0x002 /* Gap request is a forced rerequest. */ - /* REREQUEST is a superset of FORCE. */ - -/* - * Basic pre/post-amble processing. - */ -#define REPLICATION_WRAP(dbenv, func_call, ret) do { \ - int __rep_check, __t_ret; \ - __rep_check = IS_ENV_REPLICATED(dbenv) ? 1 : 0; \ - if (__rep_check && ((ret) = __env_rep_enter(dbenv, 0)) != 0) \ - return ((ret)); \ - (ret) = func_call; \ - if (__rep_check && \ - (__t_ret = __env_db_rep_exit(dbenv)) != 0 && (ret) == 0) \ - (ret) = __t_ret; \ -} while (0) - -/* - * Per-process replication structure. - * - * There are 2 mutexes used in replication. - * 1. mtx_region - This protects the fields of the rep region above. - * 2. mtx_clientdb - This protects the per-process flags, and bookkeeping - * database and all of the components that maintain it. Those - * components include the following fields in the log region (see log.h): - * a. ready_lsn - * b. waiting_lsn - * c. verify_lsn - * d. wait_recs - * e. rcvd_recs - * f. max_wait_lsn - * These fields in the log region are NOT protected by the log region lock at - * all. - * - * Note that the per-process flags should truly be protected by a special - * per-process thread mutex, but it is currently set in so isolated a manner - * that it didn't make sense to do so and in most case we're already holding - * the mtx_clientdb anyway. - * - * The lock ordering protocol is that mtx_clientdb must be acquired first and - * then either REP->mtx_region, or the LOG->mtx_region mutex may be acquired if - * necessary. - */ -struct __db_rep { - DB *rep_db; /* Bookkeeping database. */ - - REP *region; /* In memory structure. */ - u_int8_t *bulk; /* Shared memory bulk area. */ -#define DBREP_OPENFILES 0x0001 /* This handle has opened files. */ - u_int32_t flags; /* per-process flags. */ -}; - -/* - * Control structure for replication communication infrastructure. - * - * Note that the version information should be at the beginning of the - * structure, so that we can rearrange the rest of it while letting the - * version checks continue to work. DB_REPVERSION should be revved any time - * the rest of the structure changes or when the message numbers change. - */ -typedef struct __rep_control { -#define DB_REPVERSION 3 - u_int32_t rep_version; /* Replication version number. */ - u_int32_t log_version; /* Log version number. */ - - DB_LSN lsn; /* Log sequence number. */ - u_int32_t rectype; /* Message type. */ - u_int32_t gen; /* Generation number. */ - u_int32_t flags; /* log_put flag value. */ -} REP_CONTROL; - -/* Election vote information. */ -typedef struct __rep_vote { - u_int32_t egen; /* Election generation. */ - int nsites; /* Number of sites I've been in - * communication with. */ - int nvotes; /* Number of votes needed to win. */ - int priority; /* My site's priority. */ - u_int32_t tiebreaker; /* Tie-breaking quasi-random value. */ -} REP_VOTE_INFO; - -typedef struct __rep_vtally { - u_int32_t egen; /* Voter's election generation. */ - int eid; /* Voter's ID. */ -} REP_VTALLY; - -/* - * The REP_THROTTLE_ONLY flag is used to do throttle processing only. - * If set, it will only allow sending the REP_*_MORE message, but not - * the normal, non-throttled message. It is used to support throttling - * with bulk transfer. - */ -/* Flags for __rep_send_throttle. */ -#define REP_THROTTLE_ONLY 0x0001 /* Send _MORE message only. */ - -/* Throttled message processing information. */ -typedef struct __rep_throttle { - DB_LSN lsn; /* LSN of this record. */ - DBT *data_dbt; /* DBT of this record. */ - u_int32_t gbytes; /* This call's max gbytes sent. */ - u_int32_t bytes; /* This call's max bytes sent. */ - u_int32_t type; /* Record type. */ -} REP_THROTTLE; - -/* Bulk processing information. */ -/* - * !!! - * We use a uintptr_t for the offset. We'd really like to use a ptrdiff_t - * since that really is what it is. But ptrdiff_t is not portable and - * doesn't exist everywhere. - */ -typedef struct __rep_bulk { - u_int8_t *addr; /* Address of bulk buffer. */ - uintptr_t *offp; /* Ptr to current offset into buffer. */ - u_int32_t len; /* Bulk buffer length. */ - u_int32_t type; /* Item type in buffer (log, page). */ - DB_LSN lsn; /* First LSN in buffer. */ - int eid; /* ID of potential recipients. */ -#define BULK_FORCE 0x001 /* Force buffer after this record. */ -#define BULK_XMIT 0x002 /* Buffer in transit. */ - u_int32_t *flagsp; /* Buffer flags. */ -} REP_BULK; - -/* - * This structure takes care of representing a transaction. - * It holds all the records, sorted by page number so that - * we can obtain locks and apply updates in a deadlock free - * order. - */ -typedef struct __lsn_collection { - u_int nlsns; - u_int nalloc; - DB_LSN *array; -} LSN_COLLECTION; - -/* - * This is used by the page-prep routines to do the lock_vec call to - * apply the updates for a single transaction or a collection of - * transactions. - */ -typedef struct _linfo { - int n; - DB_LOCKREQ *reqs; - DBT *objs; -} linfo_t; - -#include "dbinc_auto/rep_ext.h" -#endif /* !_REP_H_ */ diff --git a/storage/bdb/dbinc/shqueue.h b/storage/bdb/dbinc/shqueue.h deleted file mode 100644 index 55cba7fc179..00000000000 --- a/storage/bdb/dbinc/shqueue.h +++ /dev/null @@ -1,347 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: shqueue.h,v 12.2 2005/08/12 13:17:21 bostic Exp $ - */ - -#ifndef _SYS_SHQUEUE_H_ -#define _SYS_SHQUEUE_H_ - -/* - * This file defines two types of data structures: lists and tail queues - * similarly to the include file <sys/queue.h>. - * - * The difference is that this set of macros can be used for structures that - * reside in shared memory that may be mapped at different addresses in each - * process. In most cases, the macros for shared structures exactly mirror - * the normal macros, although the macro calls require an additional type - * parameter, only used by the HEAD and ENTRY macros of the standard macros. - * - * Since we use relative offsets of type ssize_t rather than pointers, 0 - * (aka NULL) is a valid offset and cannot be used to indicate the end - * of a list. Therefore, we use -1 to indicate end of list. - * - * The macros ending in "P" return pointers without checking for end or - * beginning of lists, the others check for end of list and evaluate to - * either a pointer or NULL. - * - * For details on the use of these macros, see the queue(3) manual page. - */ - -#if defined(__cplusplus) -extern "C" { -#endif - -/* - * Shared memory list definitions. - */ -#define SH_LIST_HEAD(name) \ -struct name { \ - ssize_t slh_first; /* first element */ \ -} - -#define SH_LIST_HEAD_INITIALIZER(head) \ - { -1 } - -#define SH_LIST_ENTRY \ -struct { \ - ssize_t sle_next; /* relative offset to next element */ \ - ssize_t sle_prev; /* relative offset of prev element */ \ -} - -/* - * Shared memory list functions. - */ - -#define SH_LIST_EMPTY(head) \ - ((head)->slh_first == -1) - -#define SH_LIST_FIRSTP(head, type) \ - ((struct type *)(((u_int8_t *)(head)) + (head)->slh_first)) - -#define SH_LIST_FIRST(head, type) \ - (SH_LIST_EMPTY(head) ? NULL : \ - ((struct type *)(((u_int8_t *)(head)) + (head)->slh_first))) - -#define SH_LIST_NEXTP(elm, field, type) \ - ((struct type *)(((u_int8_t *)(elm)) + (elm)->field.sle_next)) - -#define SH_LIST_NEXT(elm, field, type) \ - ((elm)->field.sle_next == -1 ? NULL : \ - ((struct type *)(((u_int8_t *)(elm)) + (elm)->field.sle_next))) - - /* - *__SH_LIST_PREV_OFF is private API. It calculates the address of - * the elm->field.sle_next member of a SH_LIST structure. All offsets - * between elements are relative to that point in SH_LIST structures. - */ -#define __SH_LIST_PREV_OFF(elm, field) \ - ((ssize_t *)(((u_int8_t *)(elm)) + (elm)->field.sle_prev)) - -#define SH_LIST_PREV(elm, field, type) \ - (struct type *)((ssize_t)elm - (*__SH_LIST_PREV_OFF(elm, field))) - -#define SH_LIST_FOREACH(var, head, field, type) \ - for ((var) = SH_LIST_FIRST((head), type); \ - (var); \ - (var) = SH_LIST_NEXT((var), field, type)) - -#define SH_PTR_TO_OFF(src, dest) \ - ((ssize_t)(((u_int8_t *)(dest)) - ((u_int8_t *)(src)))) - -/* - * Given correct A.next: B.prev = SH_LIST_NEXT_TO_PREV(A) - * in a list [A, B] - * The prev value is always the offset from an element to its preceding - * element's next location, not the beginning of the structure. To get - * to the beginning of an element structure in memory given an element - * do the following: - * A = B - (B.prev + (&B.next - B)) - * Take the element's next pointer and calculate what the corresponding - * Prev pointer should be -- basically it is the negation plus the offset - * of the next field in the structure. - */ -#define SH_LIST_NEXT_TO_PREV(elm, field) \ - (((elm)->field.sle_next == -1 ? 0 : -(elm)->field.sle_next) + \ - SH_PTR_TO_OFF(elm, &(elm)->field.sle_next)) - -#define SH_LIST_INIT(head) (head)->slh_first = -1 - -#define SH_LIST_INSERT_BEFORE(head, listelm, elm, field, type) do { \ - if (listelm == SH_LIST_FIRST(head, type)) { \ - SH_LIST_INSERT_HEAD(head, elm, field, type); \ - } else { \ - (elm)->field.sle_next = SH_PTR_TO_OFF(elm, listelm); \ - (elm)->field.sle_prev = SH_LIST_NEXT_TO_PREV( \ - SH_LIST_PREV((listelm), field, type), field) + \ - (elm)->field.sle_next; \ - (SH_LIST_PREV(listelm, field, type))->field.sle_next = \ - (SH_PTR_TO_OFF((SH_LIST_PREV(listelm, field, \ - type)), elm)); \ - (listelm)->field.sle_prev = SH_LIST_NEXT_TO_PREV(elm, field); \ - } \ -} while (0) - -#define SH_LIST_INSERT_AFTER(listelm, elm, field, type) do { \ - if ((listelm)->field.sle_next != -1) { \ - (elm)->field.sle_next = SH_PTR_TO_OFF(elm, \ - SH_LIST_NEXTP(listelm, field, type)); \ - SH_LIST_NEXTP(listelm, field, type)->field.sle_prev = \ - SH_LIST_NEXT_TO_PREV(elm, field); \ - } else \ - (elm)->field.sle_next = -1; \ - (listelm)->field.sle_next = SH_PTR_TO_OFF(listelm, elm); \ - (elm)->field.sle_prev = SH_LIST_NEXT_TO_PREV(listelm, field); \ -} while (0) - -#define SH_LIST_INSERT_HEAD(head, elm, field, type) do { \ - if ((head)->slh_first != -1) { \ - (elm)->field.sle_next = \ - (head)->slh_first - SH_PTR_TO_OFF(head, elm); \ - SH_LIST_FIRSTP(head, type)->field.sle_prev = \ - SH_LIST_NEXT_TO_PREV(elm, field); \ - } else \ - (elm)->field.sle_next = -1; \ - (head)->slh_first = SH_PTR_TO_OFF(head, elm); \ - (elm)->field.sle_prev = SH_PTR_TO_OFF(elm, &(head)->slh_first); \ -} while (0) - -#define SH_LIST_REMOVE(elm, field, type) do { \ - if ((elm)->field.sle_next != -1) { \ - SH_LIST_NEXTP(elm, field, type)->field.sle_prev = \ - (elm)->field.sle_prev - (elm)->field.sle_next; \ - *__SH_LIST_PREV_OFF(elm, field) += (elm)->field.sle_next;\ - } else \ - *__SH_LIST_PREV_OFF(elm, field) = -1; \ -} while (0) - -#define SH_LIST_REMOVE_HEAD(head, field, type) do { \ - if (!SH_LIST_EMPTY(head)) { \ - SH_LIST_REMOVE(SH_LIST_FIRSTP(head, type), field, type);\ - } \ -} while (0) - -/* - * Shared memory tail queue definitions. - */ -#define SH_TAILQ_HEAD(name) \ -struct name { \ - ssize_t stqh_first; /* relative offset of first element */ \ - ssize_t stqh_last; /* relative offset of last's next */ \ -} - -#define SH_TAILQ_HEAD_INITIALIZER(head) \ - { -1, 0 } - -#define SH_TAILQ_ENTRY \ -struct { \ - ssize_t stqe_next; /* relative offset of next element */ \ - ssize_t stqe_prev; /* relative offset of prev's next */ \ -} - -/* - * Shared memory tail queue functions. - */ - -#define SH_TAILQ_EMPTY(head) \ - ((head)->stqh_first == -1) - -#define SH_TAILQ_FIRSTP(head, type) \ - ((struct type *)((u_int8_t *)(head) + (head)->stqh_first)) - -#define SH_TAILQ_FIRST(head, type) \ - (SH_TAILQ_EMPTY(head) ? NULL : SH_TAILQ_FIRSTP(head, type)) - -#define SH_TAILQ_NEXTP(elm, field, type) \ - ((struct type *)((u_int8_t *)(elm) + (elm)->field.stqe_next)) - -#define SH_TAILQ_NEXT(elm, field, type) \ - ((elm)->field.stqe_next == -1 ? NULL : \ - ((struct type *)((u_int8_t *)(elm) + (elm)->field.stqe_next))) - - /* - * __SH_TAILQ_PREV_OFF is private API. It calculates the address of - * the elm->field.stqe_next member of a SH_TAILQ structure. All - * offsets between elements are relative to that point in SH_TAILQ - * structures. - */ -#define __SH_TAILQ_PREV_OFF(elm, field) \ - ((ssize_t *)(((u_int8_t *)(elm)) + (elm)->field.stqe_prev)) - -#define SH_TAILQ_PREVP(elm, field, type) \ - (struct type *)((ssize_t)elm - (*__SH_TAILQ_PREV_OFF(elm, field))) - -#define SH_TAILQ_PREV(head, elm, field, type) \ - (((elm) == SH_TAILQ_FIRST(head, type)) ? NULL : \ - (struct type *)((ssize_t)elm - (*__SH_TAILQ_PREV_OFF(elm, field)))) - - /* - * __SH_TAILQ_LAST_OFF is private API. It calculates the address of - * the stqe_next member of a SH_TAILQ structure in the last element - * of this list. All offsets between elements are relative to that - * point in SH_TAILQ structures. - */ -#define __SH_TAILQ_LAST_OFF(head) \ - ((ssize_t *)(((u_int8_t *)(head)) + (head)->stqh_last)) - -#define SH_TAILQ_LASTP(head, field, type) \ - ((struct type *)((ssize_t)(head) + \ - ((ssize_t)((head)->stqh_last) - \ - ((ssize_t)SH_PTR_TO_OFF(SH_TAILQ_FIRST(head, type), \ - &(SH_TAILQ_FIRSTP(head, type)->field.stqe_next)))))) - -#define SH_TAILQ_LAST(head, field, type) \ - (SH_TAILQ_EMPTY(head) ? NULL : SH_TAILQ_LASTP(head, field, type)) - -/* - * Given correct A.next: B.prev = SH_TAILQ_NEXT_TO_PREV(A) - * in a list [A, B] - * The prev value is always the offset from an element to its preceding - * element's next location, not the beginning of the structure. To get - * to the beginning of an element structure in memory given an element - * do the following: - * A = B - (B.prev + (&B.next - B)) - */ -#define SH_TAILQ_NEXT_TO_PREV(elm, field) \ - (((elm)->field.stqe_next == -1 ? 0 : \ - (-(elm)->field.stqe_next) + \ - SH_PTR_TO_OFF(elm, &(elm)->field.stqe_next))) - -#define SH_TAILQ_FOREACH(var, head, field, type) \ - for ((var) = SH_TAILQ_FIRST((head), type); \ - (var); \ - (var) = SH_TAILQ_NEXT((var), field, type)) - -#define SH_TAILQ_FOREACH_REVERSE(var, head, field, type) \ - for ((var) = SH_TAILQ_LAST((head), field, type); \ - (var); \ - (var) = SH_TAILQ_PREV((head), (var), field, type)) - -#define SH_TAILQ_INIT(head) { \ - (head)->stqh_first = -1; \ - (head)->stqh_last = SH_PTR_TO_OFF(head, &(head)->stqh_first); \ -} - -#define SH_TAILQ_INSERT_HEAD(head, elm, field, type) do { \ - if ((head)->stqh_first != -1) { \ - (elm)->field.stqe_next = \ - (head)->stqh_first - SH_PTR_TO_OFF(head, elm); \ - SH_TAILQ_FIRSTP(head, type)->field.stqe_prev = \ - SH_TAILQ_NEXT_TO_PREV(elm, field); \ - } else { \ - (head)->stqh_last = \ - SH_PTR_TO_OFF(head, &(elm)->field.stqe_next); \ - (elm)->field.stqe_next = -1; \ - } \ - (head)->stqh_first = SH_PTR_TO_OFF(head, elm); \ - (elm)->field.stqe_prev = \ - SH_PTR_TO_OFF(elm, &(head)->stqh_first); \ -} while (0) - -#define SH_TAILQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.stqe_next = -1; \ - (elm)->field.stqe_prev = \ - -SH_PTR_TO_OFF(head, elm) + (head)->stqh_last; \ - if ((head)->stqh_last == \ - SH_PTR_TO_OFF((head), &(head)->stqh_first)) \ - (head)->stqh_first = SH_PTR_TO_OFF(head, elm); \ - else \ - *__SH_TAILQ_LAST_OFF(head) = -(head)->stqh_last + \ - SH_PTR_TO_OFF((elm), &(elm)->field.stqe_next) + \ - SH_PTR_TO_OFF(head, elm); \ - (head)->stqh_last = \ - SH_PTR_TO_OFF(head, &((elm)->field.stqe_next)); \ -} while (0) - -#define SH_TAILQ_INSERT_BEFORE(head, listelm, elm, field, type) do { \ - if (listelm == SH_TAILQ_FIRST(head, type)) { \ - SH_TAILQ_INSERT_HEAD(head, elm, field, type); \ - } else { \ - (elm)->field.stqe_next = SH_PTR_TO_OFF(elm, listelm); \ - (elm)->field.stqe_prev = SH_TAILQ_NEXT_TO_PREV( \ - SH_TAILQ_PREVP((listelm), field, type), field) + \ - (elm)->field.stqe_next; \ - (SH_TAILQ_PREVP(listelm, field, type))->field.stqe_next =\ - (SH_PTR_TO_OFF((SH_TAILQ_PREVP(listelm, field, type)), \ - elm)); \ - (listelm)->field.stqe_prev = \ - SH_TAILQ_NEXT_TO_PREV(elm, field); \ - } \ -} while (0) - -#define SH_TAILQ_INSERT_AFTER(head, listelm, elm, field, type) do { \ - if ((listelm)->field.stqe_next != -1) { \ - (elm)->field.stqe_next = (listelm)->field.stqe_next - \ - SH_PTR_TO_OFF(listelm, elm); \ - SH_TAILQ_NEXTP(listelm, field, type)->field.stqe_prev = \ - SH_TAILQ_NEXT_TO_PREV(elm, field); \ - } else { \ - (elm)->field.stqe_next = -1; \ - (head)->stqh_last = \ - SH_PTR_TO_OFF(head, &elm->field.stqe_next); \ - } \ - (listelm)->field.stqe_next = SH_PTR_TO_OFF(listelm, elm); \ - (elm)->field.stqe_prev = SH_TAILQ_NEXT_TO_PREV(listelm, field); \ -} while (0) - -#define SH_TAILQ_REMOVE(head, elm, field, type) do { \ - if ((elm)->field.stqe_next != -1) { \ - SH_TAILQ_NEXTP(elm, field, type)->field.stqe_prev = \ - (elm)->field.stqe_prev + \ - SH_PTR_TO_OFF(SH_TAILQ_NEXTP(elm, \ - field, type), elm); \ - *__SH_TAILQ_PREV_OFF(elm, field) += elm->field.stqe_next;\ - } else { \ - (head)->stqh_last = (elm)->field.stqe_prev + \ - SH_PTR_TO_OFF(head, elm); \ - *__SH_TAILQ_PREV_OFF(elm, field) = -1; \ - } \ -} while (0) - -#if defined(__cplusplus) -} -#endif -#endif /* !_SYS_SHQUEUE_H_ */ diff --git a/storage/bdb/dbinc/tcl_db.h b/storage/bdb/dbinc/tcl_db.h deleted file mode 100644 index 4bc68ba12bb..00000000000 --- a/storage/bdb/dbinc/tcl_db.h +++ /dev/null @@ -1,241 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: tcl_db.h,v 12.4 2005/08/08 14:52:30 bostic Exp $ - */ - -#ifndef _DB_TCL_DB_H_ -#define _DB_TCL_DB_H_ - -#define MSG_SIZE 100 /* Message size */ - -enum INFOTYPE { - I_ENV, I_DB, I_DBC, I_TXN, I_MP, I_PG, I_LOCK, I_LOGC, I_NDBM, I_SEQ}; - -#define MAX_ID 8 /* Maximum number of sub-id's we need */ -#define DBTCL_PREP 64 /* Size of txn_recover preplist */ - -#define DBTCL_DBM 1 -#define DBTCL_NDBM 2 - -/* - * Why use a home grown package over the Tcl_Hash functions? - * - * We could have implemented the stuff below without maintaining our - * own list manipulation, efficiently hashing it with the available - * Tcl functions (Tcl_CreateHashEntry, Tcl_GetHashValue, etc). I chose - * not to do so for these reasons: - * - * We still need the information below. Using the hashing only removes - * us from needing the next/prev pointers. We still need the structure - * itself because we need more than one value associated with a widget. - * We need to keep track of parent pointers for sub-widgets (like cursors) - * so we can correctly close. We need to keep track of individual widget's - * id counters for any sub-widgets they may have. We need to be able to - * associate the name/client data outside the scope of the widget. - * - * So, is it better to use the hashing rather than - * the linear list we have now? I decided against it for the simple reason - * that to access the structure would require two calls. The first is - * Tcl_FindHashEntry(table, key) and then, once we have the entry, we'd - * have to do Tcl_GetHashValue(entry) to get the pointer of the structure. - * - * I believe the number of simultaneous DB widgets in existence at one time - * is not going to be that large (more than several dozen) such that - * linearly searching the list is not going to impact performance in a - * noticeable way. Should performance be impacted due to the size of the - * info list, then perhaps it is time to revisit this decision. - */ -typedef struct dbtcl_info { - LIST_ENTRY(dbtcl_info) entries; - Tcl_Interp *i_interp; - char *i_name; - enum INFOTYPE i_type; - union infop { - DB *dbp; - DBC *dbcp; - DB_ENV *envp; - DB_LOCK *lock; - DB_LOGC *logc; - DB_MPOOLFILE *mp; - DB_TXN *txnp; - void *anyp; - } un; - union data { - int anydata; - db_pgno_t pgno; - u_int32_t lockid; - } und; - union data2 { - int anydata; - int pagesz; - DB_COMPACT *c_data; - } und2; - DBT i_lockobj; - FILE *i_err; - char *i_errpfx; - - /* Callbacks--Tcl_Objs containing proc names */ - Tcl_Obj *i_btcompare; - Tcl_Obj *i_dupcompare; - Tcl_Obj *i_hashproc; - Tcl_Obj *i_rep_send; - Tcl_Obj *i_second_call; - - /* Environment ID for the i_rep_send callback. */ - Tcl_Obj *i_rep_eid; - - struct dbtcl_info *i_parent; - int i_otherid[MAX_ID]; -} DBTCL_INFO; - -#define i_anyp un.anyp -#define i_pagep un.anyp -#define i_envp un.envp -#define i_dbp un.dbp -#define i_dbcp un.dbcp -#define i_txnp un.txnp -#define i_mp un.mp -#define i_lock un.lock -#define i_logc un.logc - -#define i_data und.anydata -#define i_pgno und.pgno -#define i_locker und.lockid -#define i_data2 und2.anydata -#define i_pgsz und2.pagesz -#define i_cdata und2.c_data - -#define i_envtxnid i_otherid[0] -#define i_envmpid i_otherid[1] -#define i_envlockid i_otherid[2] -#define i_envlogcid i_otherid[3] - -#define i_mppgid i_otherid[0] - -#define i_dbdbcid i_otherid[0] - -extern int __debug_on, __debug_print, __debug_stop, __debug_test; - -typedef struct dbtcl_global { - LIST_HEAD(infohead, dbtcl_info) g_infohead; -} DBTCL_GLOBAL; -#define __db_infohead __dbtcl_global.g_infohead - -extern DBTCL_GLOBAL __dbtcl_global; - -/* - * Tcl_NewStringObj takes an "int" length argument, when the typical use is to - * call it with a size_t length (for example, returned by strlen). Tcl is in - * the wrong, but that doesn't help us much -- cast the argument. - */ -#define NewStringObj(a, b) \ - Tcl_NewStringObj(a, (int)b) - -#define NAME_TO_DB(name) (DB *)_NameToPtr((name)) -#define NAME_TO_DBC(name) (DBC *)_NameToPtr((name)) -#define NAME_TO_ENV(name) (DB_ENV *)_NameToPtr((name)) -#define NAME_TO_LOCK(name) (DB_LOCK *)_NameToPtr((name)) -#define NAME_TO_MP(name) (DB_MPOOLFILE *)_NameToPtr((name)) -#define NAME_TO_TXN(name) (DB_TXN *)_NameToPtr((name)) -#define NAME_TO_SEQUENCE(name) (DB_SEQUENCE *)_NameToPtr((name)) - -/* - * MAKE_STAT_LIST appends a {name value} pair to a result list that MUST be - * called 'res' that is a Tcl_Obj * in the local function. This macro also - * assumes a label "error" to go to in the event of a Tcl error. For stat - * functions this will typically go before the "free" function to free the - * stat structure returned by DB. - */ -#define MAKE_STAT_LIST(s, v) do { \ - result = _SetListElemInt(interp, res, (s), (long)(v)); \ - if (result != TCL_OK) \ - goto error; \ -} while (0) - -#define MAKE_WSTAT_LIST(s, v) do { \ - result = _SetListElemWideInt(interp, res, (s), (int64_t)(v)); \ - if (result != TCL_OK) \ - goto error; \ -} while (0) - -/* - * MAKE_STAT_LSN appends a {name {LSNfile LSNoffset}} pair to a result list - * that MUST be called 'res' that is a Tcl_Obj * in the local - * function. This macro also assumes a label "error" to go to - * in the even of a Tcl error. For stat functions this will - * typically go before the "free" function to free the stat structure - * returned by DB. - */ -#define MAKE_STAT_LSN(s, lsn) do { \ - myobjc = 2; \ - myobjv[0] = Tcl_NewLongObj((long)(lsn)->file); \ - myobjv[1] = Tcl_NewLongObj((long)(lsn)->offset); \ - lsnlist = Tcl_NewListObj(myobjc, myobjv); \ - myobjc = 2; \ - myobjv[0] = Tcl_NewStringObj((s), (int)strlen(s)); \ - myobjv[1] = lsnlist; \ - thislist = Tcl_NewListObj(myobjc, myobjv); \ - result = Tcl_ListObjAppendElement(interp, res, thislist); \ - if (result != TCL_OK) \ - goto error; \ -} while (0) - -/* - * MAKE_STAT_STRLIST appends a {name string} pair to a result list - * that MUST be called 'res' that is a Tcl_Obj * in the local - * function. This macro also assumes a label "error" to go to - * in the even of a Tcl error. For stat functions this will - * typically go before the "free" function to free the stat structure - * returned by DB. - */ -#define MAKE_STAT_STRLIST(s,s1) do { \ - result = _SetListElem(interp, res, (s), strlen(s), \ - (s1), strlen(s1)); \ - if (result != TCL_OK) \ - goto error; \ -} while (0) - -/* - * FLAG_CHECK checks that the given flag is not set yet. - * If it is, it sets up an error message. - */ -#define FLAG_CHECK(flag) do { \ - if ((flag) != 0) { \ - Tcl_SetResult(interp, \ - " Only 1 policy can be specified.\n", \ - TCL_STATIC); \ - result = TCL_ERROR; \ - break; \ - } \ -} while (0) - -/* - * FLAG_CHECK2 checks that the given flag is not set yet or is - * only set to the given allowed value. - * If it is, it sets up an error message. - */ -#define FLAG_CHECK2(flag, val) do { \ - if (((flag) & ~(val)) != 0) { \ - Tcl_SetResult(interp, \ - " Only 1 policy can be specified.\n", \ - TCL_STATIC); \ - result = TCL_ERROR; \ - break; \ - } \ -} while (0) - -/* - * IS_HELP checks whether the arg we bombed on is -?, which is a help option. - * If it is, we return TCL_OK (but leave the result set to whatever - * Tcl_GetIndexFromObj says, which lists all the valid options. Otherwise - * return TCL_ERROR. - */ -#define IS_HELP(s) \ - (strcmp(Tcl_GetStringFromObj(s,NULL), "-?") == 0) ? TCL_OK : TCL_ERROR - -#include "dbinc_auto/tcl_ext.h" -#endif /* !_DB_TCL_DB_H_ */ diff --git a/storage/bdb/dbinc/txn.h b/storage/bdb/dbinc/txn.h deleted file mode 100644 index 845cdee2349..00000000000 --- a/storage/bdb/dbinc/txn.h +++ /dev/null @@ -1,225 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: txn.h,v 12.7 2005/10/13 00:53:00 bostic Exp $ - */ - -#ifndef _TXN_H_ -#define _TXN_H_ - -#include "dbinc/xa.h" - -/* Operation parameters to the delayed commit processing code. */ -typedef enum { - TXN_CLOSE, /* Close a DB handle whose close had failed. */ - TXN_REMOVE, /* Remove a file. */ - TXN_TRADE, /* Trade lockers. */ - TXN_TRADED /* Already traded; downgrade lock. */ -} TXN_EVENT_T; - -struct __db_txnregion; typedef struct __db_txnregion DB_TXNREGION; -struct __txn_logrec; typedef struct __txn_logrec DB_TXNLOGREC; - -/* - * !!! - * TXN_MINIMUM = (DB_LOCK_MAXID + 1) but this makes compilers complain. - */ -#define TXN_MINIMUM 0x80000000 -#define TXN_MAXIMUM 0xffffffff /* Maximum number of txn ids. */ -#define TXN_INVALID 0 /* Invalid transaction ID. */ - -#define DEF_MAX_TXNS 20 /* Default max transactions. */ - -/* - * Internal data maintained in shared memory for each transaction. - */ -typedef struct __txn_detail { - u_int32_t txnid; /* current transaction id - used to link free list also */ - pid_t pid; /* Process owning txn */ - db_threadid_t tid; /* Thread owning txn */ - - DB_LSN last_lsn; /* last lsn written for this txn */ - DB_LSN begin_lsn; /* lsn of begin record */ - roff_t parent; /* Offset of transaction's parent. */ - roff_t name; /* Offset of txn name. */ - - SH_TAILQ_HEAD(__tdkids) kids; /* Linked list of child txn detail. */ - SH_TAILQ_ENTRY klinks; - -#define TXN_RUNNING 1 -#define TXN_ABORTED 2 -#define TXN_PREPARED 3 -#define TXN_COMMITTED 4 - u_int32_t status; /* status of the transaction */ -#define TXN_DTL_COLLECTED 0x1 /* collected during txn_recover */ -#define TXN_DTL_RESTORED 0x2 /* prepared txn restored */ -#define TXN_DTL_INMEMORY 0x4 /* uses in memory logs */ - u_int32_t flags; - - SH_TAILQ_ENTRY links; /* free/active list */ - -#define TXN_XA_ABORTED 1 -#define TXN_XA_DEADLOCKED 2 -#define TXN_XA_ENDED 3 -#define TXN_XA_PREPARED 4 -#define TXN_XA_STARTED 5 -#define TXN_XA_SUSPENDED 6 - u_int32_t xa_status; /* XA status */ - - /* - * XID (xid_t) structure: because these fields are logged, the - * sizes have to be explicit. - */ - u_int8_t xid[XIDDATASIZE]; /* XA global transaction id */ - u_int32_t bqual; /* bqual_length from XID */ - u_int32_t gtrid; /* gtrid_length from XID */ - int32_t format; /* XA format */ -} TXN_DETAIL; - -/* - * DB_TXNMGR -- - * The transaction manager encapsulates the transaction system. - */ -struct __db_txnmgr { - /* - * These fields need to be protected for multi-threaded support. - * - * Lock list of active transactions (including the content of each - * TXN_DETAIL structure on the list). - */ - db_mutex_t mutex; - /* List of active transactions. */ - TAILQ_HEAD(_chain, __db_txn) txn_chain; - - u_int32_t n_discards; /* Number of txns discarded. */ - - /* These fields are never updated after creation, so not protected. */ - DB_ENV *dbenv; /* Environment. */ - REGINFO reginfo; /* Region information. */ -}; - -/* Macros to lock/unlock the transaction region as a whole. */ -#define TXN_SYSTEM_LOCK(dbenv) \ - MUTEX_LOCK(dbenv, ((DB_TXNREGION *)((DB_TXNMGR *) \ - (dbenv)->tx_handle)->reginfo.primary)->mtx_region) -#define TXN_SYSTEM_UNLOCK(dbenv) \ - MUTEX_UNLOCK(dbenv, ((DB_TXNREGION *)((DB_TXNMGR *) \ - (dbenv)->tx_handle)->reginfo.primary)->mtx_region) - -/* - * DB_TXNREGION -- - * The primary transaction data structure in the shared memory region. - */ -struct __db_txnregion { - db_mutex_t mtx_region; /* Region mutex. */ - - u_int32_t maxtxns; /* maximum number of active TXNs */ - u_int32_t last_txnid; /* last transaction id given out */ - u_int32_t cur_maxid; /* current max unused id. */ - - db_mutex_t mtx_ckp; /* Single thread checkpoints. */ - DB_LSN last_ckp; /* lsn of the last checkpoint */ - time_t time_ckp; /* time of last checkpoint */ - - DB_TXN_STAT stat; /* Statistics for txns. */ - -#define TXN_IN_RECOVERY 0x01 /* environment is being recovered */ - u_int32_t flags; - /* active TXN list */ - SH_TAILQ_HEAD(__active) active_txn; -}; - -/* - * DB_TXNLOGREC -- - * An in-memory, linked-list copy of a log record. - */ -struct __txn_logrec { - STAILQ_ENTRY(__txn_logrec) links;/* Linked list. */ - - u_int8_t data[1]; /* Log record. */ -}; - -/* - * Log record types. Note that these are *not* alphabetical. This is - * intentional so that we don't change the meaning of values between - * software upgrades. - * - * EXPECTED, UNEXPECTED, IGNORE, and OK are used in the txnlist functions. - * Here is an explanation of how the statuses are used. - * - * TXN_OK - * BEGIN records for transactions found on the txnlist during - * OPENFILES (BEGIN records are those with a prev_lsn of 0,0) - * - * TXN_COMMIT - * Transaction committed and should be rolled forward. - * - * TXN_ABORT - * This transaction's changes must be undone. Either there was - * never a prepare or commit record for this transaction OR there - * was a commit, but we are recovering to a timestamp or particular - * LSN and that point is before this transaction's commit. - * - * TXN_PREPARE - * Prepare record, but no commit record is in the log. - * - * TXN_IGNORE - * Generic meaning is that this transaction should not be - * processed during later recovery passes. We use it in a - * number of different manners: - * - * 1. We never saw its BEGIN record. Therefore, the logs have - * been reclaimed and we *know* that this transaction doesn't - * need to be aborted, because in order for it to be - * reclaimed, there must have been a subsequent checkpoint - * (and any dirty pages for this transaction made it to - * disk). - * - * 2. This is a child transaction that created a database. - * For some reason, we don't want to recreate that database - * (i.e., it already exists or some other database created - * after it exists). - * - * 3. During recovery open of subdatabases, if the master check fails, - * we use a TXN_IGNORE on the create of the subdb in the nested - * transaction. - * - * 4. During a remove, the file with the name being removed isn't - * the file for which we are recovering a remove. - * - * TXN_EXPECTED - * After a successful open during recovery, we update the - * transaction's status to TXN_EXPECTED. The open was done - * in the parent, but in the open log record, we record the - * child transaction's ID if we also did a create. When there - * is a valid ID in that field, we use it and mark the child's - * status as TXN_EXPECTED (indicating that we don't need to redo - * a create for this file). - * - * When recovering a remove, if we don't find or can't open - * the file, the child (which does the remove) gets marked - * EXPECTED (indicating that we don't need to redo the remove). - * - * TXN_UNEXPECTED - * During recovery, we attempted an open that should have succeeded - * and we got ENOENT, so like with the EXPECTED case, we indicate - * in the child that we got the UNEXPECTED return so that we do redo - * the creating/deleting operation. - * - */ -#define TXN_OK 0 -#define TXN_COMMIT 1 -#define TXN_PREPARE 2 -#define TXN_ABORT 3 -#define TXN_IGNORE 4 -#define TXN_EXPECTED 5 -#define TXN_UNEXPECTED 6 - -#include "dbinc_auto/txn_auto.h" -#include "dbinc_auto/txn_ext.h" -#include "dbinc_auto/xa_ext.h" -#endif /* !_TXN_H_ */ diff --git a/storage/bdb/dbinc/xa.h b/storage/bdb/dbinc/xa.h deleted file mode 100644 index 80c4032d20d..00000000000 --- a/storage/bdb/dbinc/xa.h +++ /dev/null @@ -1,179 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1998-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: xa.h,v 12.1 2005/06/16 20:21:49 bostic Exp $ - */ -/* - * Start of xa.h header - * - * Define a symbol to prevent multiple inclusions of this header file - */ -#ifndef XA_H -#define XA_H - -/* - * Transaction branch identification: XID and NULLXID: - */ -#define XIDDATASIZE 128 /* size in bytes */ -#define MAXGTRIDSIZE 64 /* maximum size in bytes of gtrid */ -#define MAXBQUALSIZE 64 /* maximum size in bytes of bqual */ - -struct xid_t { - long formatID; /* format identifier */ - long gtrid_length; /* value from 1 through 64 */ - long bqual_length; /* value from 1 through 64 */ - char data[XIDDATASIZE]; -}; -typedef struct xid_t XID; -/* - * A value of -1 in formatID means that the XID is null. - */ - -/* - * Declarations of routines by which RMs call TMs: - */ -extern int ax_reg __P((int, XID *, long)); -extern int ax_unreg __P((int, long)); - -/* - * XA Switch Data Structure - */ -#define RMNAMESZ 32 /* length of resource manager name, */ - /* including the null terminator */ -#define MAXINFOSIZE 256 /* maximum size in bytes of xa_info */ - /* strings, including the null - terminator */ -struct xa_switch_t { - char name[RMNAMESZ]; /* name of resource manager */ - long flags; /* resource manager specific options */ - long version; /* must be 0 */ - int (*xa_open_entry) /* xa_open function pointer */ - __P((char *, int, long)); - int (*xa_close_entry) /* xa_close function pointer */ - __P((char *, int, long)); - int (*xa_start_entry) /* xa_start function pointer */ - __P((XID *, int, long)); - int (*xa_end_entry) /* xa_end function pointer */ - __P((XID *, int, long)); - int (*xa_rollback_entry) /* xa_rollback function pointer */ - __P((XID *, int, long)); - int (*xa_prepare_entry) /* xa_prepare function pointer */ - __P((XID *, int, long)); - int (*xa_commit_entry) /* xa_commit function pointer */ - __P((XID *, int, long)); - int (*xa_recover_entry) /* xa_recover function pointer */ - __P((XID *, long, int, long)); - int (*xa_forget_entry) /* xa_forget function pointer */ - __P((XID *, int, long)); - int (*xa_complete_entry) /* xa_complete function pointer */ - __P((int *, int *, int, long)); -}; - -/* - * Flag definitions for the RM switch - */ -#define TMNOFLAGS 0x00000000L /* no resource manager features - selected */ -#define TMREGISTER 0x00000001L /* resource manager dynamically - registers */ -#define TMNOMIGRATE 0x00000002L /* resource manager does not support - association migration */ -#define TMUSEASYNC 0x00000004L /* resource manager supports - asynchronous operations */ -/* - * Flag definitions for xa_ and ax_ routines - */ -/* use TMNOFLAGGS, defined above, when not specifying other flags */ -#define TMASYNC 0x80000000L /* perform routine asynchronously */ -#define TMONEPHASE 0x40000000L /* caller is using one-phase commit - optimisation */ -#define TMFAIL 0x20000000L /* dissociates caller and marks - transaction branch rollback-only */ -#define TMNOWAIT 0x10000000L /* return if blocking condition - exists */ -#define TMRESUME 0x08000000L /* caller is resuming association with - suspended transaction branch */ -#define TMSUCCESS 0x04000000L /* dissociate caller from transaction - branch */ -#define TMSUSPEND 0x02000000L /* caller is suspending, not ending, - association */ -#define TMSTARTRSCAN 0x01000000L /* start a recovery scan */ -#define TMENDRSCAN 0x00800000L /* end a recovery scan */ -#define TMMULTIPLE 0x00400000L /* wait for any asynchronous - operation */ -#define TMJOIN 0x00200000L /* caller is joining existing - transaction branch */ -#define TMMIGRATE 0x00100000L /* caller intends to perform - migration */ - -/* - * ax_() return codes (transaction manager reports to resource manager) - */ -#define TM_JOIN 2 /* caller is joining existing - transaction branch */ -#define TM_RESUME 1 /* caller is resuming association with - suspended transaction branch */ -#define TM_OK 0 /* normal execution */ -#define TMER_TMERR -1 /* an error occurred in the transaction - manager */ -#define TMER_INVAL -2 /* invalid arguments were given */ -#define TMER_PROTO -3 /* routine invoked in an improper - context */ - -/* - * xa_() return codes (resource manager reports to transaction manager) - */ -#define XA_RBBASE 100 /* The inclusive lower bound of the - rollback codes */ -#define XA_RBROLLBACK XA_RBBASE /* The rollback was caused by an - unspecified reason */ -#define XA_RBCOMMFAIL XA_RBBASE+1 /* The rollback was caused by a - communication failure */ -#define XA_RBDEADLOCK XA_RBBASE+2 /* A deadlock was detected */ -#define XA_RBINTEGRITY XA_RBBASE+3 /* A condition that violates the - integrity of the resources was - detected */ -#define XA_RBOTHER XA_RBBASE+4 /* The resource manager rolled back the - transaction branch for a reason not - on this list */ -#define XA_RBPROTO XA_RBBASE+5 /* A protocol error occurred in the - resource manager */ -#define XA_RBTIMEOUT XA_RBBASE+6 /* A transaction branch took too long */ -#define XA_RBTRANSIENT XA_RBBASE+7 /* May retry the transaction branch */ -#define XA_RBEND XA_RBTRANSIENT /* The inclusive upper bound of the - rollback codes */ -#define XA_NOMIGRATE 9 /* resumption must occur where - suspension occurred */ -#define XA_HEURHAZ 8 /* the transaction branch may have - been heuristically completed */ -#define XA_HEURCOM 7 /* the transaction branch has been - heuristically committed */ -#define XA_HEURRB 6 /* the transaction branch has been - heuristically rolled back */ -#define XA_HEURMIX 5 /* the transaction branch has been - heuristically committed and rolled - back */ -#define XA_RETRY 4 /* routine returned with no effect and - may be re-issued */ -#define XA_RDONLY 3 /* the transaction branch was read-only - and has been committed */ -#define XA_OK 0 /* normal execution */ -#define XAER_ASYNC -2 /* asynchronous operation already - outstanding */ -#define XAER_RMERR -3 /* a resource manager error occurred in - the transaction branch */ -#define XAER_NOTA -4 /* the XID is not valid */ -#define XAER_INVAL -5 /* invalid arguments were given */ -#define XAER_PROTO -6 /* routine invoked in an improper - context */ -#define XAER_RMFAIL -7 /* resource manager unavailable */ -#define XAER_DUPID -8 /* the XID already exists */ -#define XAER_OUTSIDE -9 /* resource manager doing work outside - transaction */ -#endif /* ifndef XA_H */ -/* - * End of xa.h header - */ diff --git a/storage/bdb/dbinc_auto/.empty b/storage/bdb/dbinc_auto/.empty deleted file mode 100644 index cb45fa6cd5a..00000000000 --- a/storage/bdb/dbinc_auto/.empty +++ /dev/null @@ -1 +0,0 @@ -this is here to force the directory to exist diff --git a/storage/bdb/dbm/dbm.c b/storage/bdb/dbm/dbm.c deleted file mode 100644 index a7f484b4357..00000000000 --- a/storage/bdb/dbm/dbm.c +++ /dev/null @@ -1,517 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993 - * Margo Seltzer. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Margo Seltzer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: dbm.c,v 12.2 2005/06/16 20:21:49 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <fcntl.h> -#include <string.h> -#endif - -#define DB_DBM_HSEARCH 1 -#include "db_int.h" - -/* - * - * This package provides dbm and ndbm compatible interfaces to DB. - * - * EXTERN: #if DB_DBM_HSEARCH != 0 - * - * EXTERN: int __db_ndbm_clearerr __P((DBM *)); - * EXTERN: void __db_ndbm_close __P((DBM *)); - * EXTERN: int __db_ndbm_delete __P((DBM *, datum)); - * EXTERN: int __db_ndbm_dirfno __P((DBM *)); - * EXTERN: int __db_ndbm_error __P((DBM *)); - * EXTERN: datum __db_ndbm_fetch __P((DBM *, datum)); - * EXTERN: datum __db_ndbm_firstkey __P((DBM *)); - * EXTERN: datum __db_ndbm_nextkey __P((DBM *)); - * EXTERN: DBM *__db_ndbm_open __P((const char *, int, int)); - * EXTERN: int __db_ndbm_pagfno __P((DBM *)); - * EXTERN: int __db_ndbm_rdonly __P((DBM *)); - * EXTERN: int __db_ndbm_store __P((DBM *, datum, datum, int)); - * - * EXTERN: int __db_dbm_close __P((void)); - * EXTERN: int __db_dbm_delete __P((datum)); - * EXTERN: datum __db_dbm_fetch __P((datum)); - * EXTERN: datum __db_dbm_firstkey __P((void)); - * EXTERN: int __db_dbm_init __P((char *)); - * EXTERN: datum __db_dbm_nextkey __P((datum)); - * EXTERN: int __db_dbm_store __P((datum, datum)); - * - * EXTERN: #endif - */ - -/* - * The DBM routines, which call the NDBM routines. - */ -static DBM *__cur_db; - -static void __db_no_open __P((void)); - -int -__db_dbm_init(file) - char *file; -{ - if (__cur_db != NULL) - dbm_close(__cur_db); - if ((__cur_db = - dbm_open(file, O_CREAT | O_RDWR, __db_omode(OWNER_RW))) != NULL) - return (0); - if ((__cur_db = dbm_open(file, O_RDONLY, 0)) != NULL) - return (0); - return (-1); -} - -int -__db_dbm_close() -{ - if (__cur_db != NULL) { - dbm_close(__cur_db); - __cur_db = NULL; - } - return (0); -} - -datum -__db_dbm_fetch(key) - datum key; -{ - datum item; - - if (__cur_db == NULL) { - __db_no_open(); - item.dptr = NULL; - item.dsize = 0; - return (item); - } - return (dbm_fetch(__cur_db, key)); -} - -datum -__db_dbm_firstkey() -{ - datum item; - - if (__cur_db == NULL) { - __db_no_open(); - item.dptr = NULL; - item.dsize = 0; - return (item); - } - return (dbm_firstkey(__cur_db)); -} - -datum -__db_dbm_nextkey(key) - datum key; -{ - datum item; - - COMPQUIET(key.dsize, 0); - - if (__cur_db == NULL) { - __db_no_open(); - item.dptr = NULL; - item.dsize = 0; - return (item); - } - return (dbm_nextkey(__cur_db)); -} - -int -__db_dbm_delete(key) - datum key; -{ - if (__cur_db == NULL) { - __db_no_open(); - return (-1); - } - return (dbm_delete(__cur_db, key)); -} - -int -__db_dbm_store(key, dat) - datum key, dat; -{ - if (__cur_db == NULL) { - __db_no_open(); - return (-1); - } - return (dbm_store(__cur_db, key, dat, DBM_REPLACE)); -} - -static void -__db_no_open() -{ - (void)fprintf(stderr, "dbm: no open database.\n"); -} - -/* - * This package provides dbm and ndbm compatible interfaces to DB. - * - * The NDBM routines, which call the DB routines. - */ -/* - * Returns: - * *DBM on success - * NULL on failure - */ -DBM * -__db_ndbm_open(file, oflags, mode) - const char *file; - int oflags, mode; -{ - DB *dbp; - DBC *dbc; - int ret; - char path[MAXPATHLEN]; - - /* - * !!! - * Don't use sprintf(3)/snprintf(3) -- the former is dangerous, and - * the latter isn't standard, and we're manipulating strings handed - * us by the application. - */ - if (strlen(file) + strlen(DBM_SUFFIX) + 1 > sizeof(path)) { - __os_set_errno(ENAMETOOLONG); - return (NULL); - } - (void)strcpy(path, file); - (void)strcat(path, DBM_SUFFIX); - if ((ret = db_create(&dbp, NULL, 0)) != 0) { - __os_set_errno(ret); - return (NULL); - } - - /* - * !!! - * The historic ndbm library corrected for opening O_WRONLY. - */ - if (oflags & O_WRONLY) { - oflags &= ~O_WRONLY; - oflags |= O_RDWR; - } - - if ((ret = dbp->set_pagesize(dbp, 4096)) != 0 || - (ret = dbp->set_h_ffactor(dbp, 40)) != 0 || - (ret = dbp->set_h_nelem(dbp, 1)) != 0 || - (ret = dbp->open(dbp, NULL, - path, NULL, DB_HASH, __db_oflags(oflags), mode)) != 0) { - __os_set_errno(ret); - return (NULL); - } - - if ((ret = dbp->cursor(dbp, NULL, &dbc, 0)) != 0) { - (void)dbp->close(dbp, 0); - __os_set_errno(ret); - return (NULL); - } - - return ((DBM *)dbc); -} - -/* - * Returns: - * Nothing. - */ -void -__db_ndbm_close(dbm) - DBM *dbm; -{ - DBC *dbc; - - dbc = (DBC *)dbm; - - (void)dbc->dbp->close(dbc->dbp, 0); -} - -/* - * Returns: - * DATUM on success - * NULL on failure - */ -datum -__db_ndbm_fetch(dbm, key) - DBM *dbm; - datum key; -{ - DBC *dbc; - DBT _key, _data; - datum data; - int ret; - - dbc = (DBC *)dbm; - - memset(&_key, 0, sizeof(DBT)); - memset(&_data, 0, sizeof(DBT)); - _key.size = (u_int32_t)key.dsize; - _key.data = key.dptr; - - /* - * Note that we can't simply use the dbc we have to do a c_get/SET, - * because that cursor is the one used for sequential iteration and - * it has to remain stable in the face of intervening gets and puts. - */ - if ((ret = dbc->dbp->get(dbc->dbp, NULL, &_key, &_data, 0)) == 0) { - data.dptr = _data.data; - data.dsize = (int)_data.size; - } else { - data.dptr = NULL; - data.dsize = 0; - if (ret == DB_NOTFOUND) - __os_set_errno(ENOENT); - else { - __os_set_errno(ret); - F_SET(dbc->dbp, DB_AM_DBM_ERROR); - } - } - return (data); -} - -/* - * Returns: - * DATUM on success - * NULL on failure - */ -datum -__db_ndbm_firstkey(dbm) - DBM *dbm; -{ - DBC *dbc; - DBT _key, _data; - datum key; - int ret; - - dbc = (DBC *)dbm; - - memset(&_key, 0, sizeof(DBT)); - memset(&_data, 0, sizeof(DBT)); - - if ((ret = dbc->c_get(dbc, &_key, &_data, DB_FIRST)) == 0) { - key.dptr = _key.data; - key.dsize = (int)_key.size; - } else { - key.dptr = NULL; - key.dsize = 0; - if (ret == DB_NOTFOUND) - __os_set_errno(ENOENT); - else { - __os_set_errno(ret); - F_SET(dbc->dbp, DB_AM_DBM_ERROR); - } - } - return (key); -} - -/* - * Returns: - * DATUM on success - * NULL on failure - */ -datum -__db_ndbm_nextkey(dbm) - DBM *dbm; -{ - DBC *dbc; - DBT _key, _data; - datum key; - int ret; - - dbc = (DBC *)dbm; - - memset(&_key, 0, sizeof(DBT)); - memset(&_data, 0, sizeof(DBT)); - - if ((ret = dbc->c_get(dbc, &_key, &_data, DB_NEXT)) == 0) { - key.dptr = _key.data; - key.dsize = (int)_key.size; - } else { - key.dptr = NULL; - key.dsize = 0; - if (ret == DB_NOTFOUND) - __os_set_errno(ENOENT); - else { - __os_set_errno(ret); - F_SET(dbc->dbp, DB_AM_DBM_ERROR); - } - } - return (key); -} - -/* - * Returns: - * 0 on success - * <0 failure - */ -int -__db_ndbm_delete(dbm, key) - DBM *dbm; - datum key; -{ - DBC *dbc; - DBT _key; - int ret; - - dbc = (DBC *)dbm; - - memset(&_key, 0, sizeof(DBT)); - _key.data = key.dptr; - _key.size = (u_int32_t)key.dsize; - - if ((ret = dbc->dbp->del(dbc->dbp, NULL, &_key, 0)) == 0) - return (0); - - if (ret == DB_NOTFOUND) - __os_set_errno(ENOENT); - else { - __os_set_errno(ret); - F_SET(dbc->dbp, DB_AM_DBM_ERROR); - } - return (-1); -} - -/* - * Returns: - * 0 on success - * <0 failure - * 1 if DBM_INSERT and entry exists - */ -int -__db_ndbm_store(dbm, key, data, flags) - DBM *dbm; - datum key, data; - int flags; -{ - DBC *dbc; - DBT _key, _data; - int ret; - - dbc = (DBC *)dbm; - - memset(&_key, 0, sizeof(DBT)); - _key.data = key.dptr; - _key.size = (u_int32_t)key.dsize; - - memset(&_data, 0, sizeof(DBT)); - _data.data = data.dptr; - _data.size = (u_int32_t)data.dsize; - - if ((ret = dbc->dbp->put(dbc->dbp, NULL, - &_key, &_data, flags == DBM_INSERT ? DB_NOOVERWRITE : 0)) == 0) - return (0); - - if (ret == DB_KEYEXIST) - return (1); - - __os_set_errno(ret); - F_SET(dbc->dbp, DB_AM_DBM_ERROR); - return (-1); -} - -int -__db_ndbm_error(dbm) - DBM *dbm; -{ - DBC *dbc; - - dbc = (DBC *)dbm; - - return (F_ISSET(dbc->dbp, DB_AM_DBM_ERROR)); -} - -int -__db_ndbm_clearerr(dbm) - DBM *dbm; -{ - DBC *dbc; - - dbc = (DBC *)dbm; - - F_CLR(dbc->dbp, DB_AM_DBM_ERROR); - return (0); -} - -/* - * Returns: - * 1 if read-only - * 0 if not read-only - */ -int -__db_ndbm_rdonly(dbm) - DBM *dbm; -{ - DBC *dbc; - - dbc = (DBC *)dbm; - - return (F_ISSET(dbc->dbp, DB_AM_RDONLY) ? 1 : 0); -} - -/* - * XXX - * We only have a single file descriptor that we can return, not two. Return - * the same one for both files. Hopefully, the user is using it for locking - * and picked one to use at random. - */ -int -__db_ndbm_dirfno(dbm) - DBM *dbm; -{ - return (dbm_pagfno(dbm)); -} - -int -__db_ndbm_pagfno(dbm) - DBM *dbm; -{ - DBC *dbc; - int fd; - - dbc = (DBC *)dbm; - - (void)dbc->dbp->fd(dbc->dbp, &fd); - return (fd); -} diff --git a/storage/bdb/dbreg/dbreg.c b/storage/bdb/dbreg/dbreg.c deleted file mode 100644 index eb3e75cc739..00000000000 --- a/storage/bdb/dbreg/dbreg.c +++ /dev/null @@ -1,736 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: dbreg.c,v 12.12 2005/10/14 14:40:41 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/log.h" -#include "dbinc/txn.h" -#include "dbinc/db_am.h" - -static int __dbreg_push_id __P((DB_ENV *, DB *, int32_t)); -static int __dbreg_pop_id __P((DB_ENV *, int32_t *)); -static int __dbreg_pluck_id __P((DB_ENV *, int32_t)); - -/* - * The dbreg subsystem, as its name implies, registers database handles so - * that we can associate log messages with them without logging a filename - * or a full, unique DB ID. Instead, we assign each dbp an int32_t which is - * easy and cheap to log, and use this subsystem to map back and forth. - * - * Overview of how dbreg ids are managed: - * - * OPEN - * dbreg_setup (Creates FNAME struct.) - * dbreg_new_id (Assigns new ID to dbp and logs it. May be postponed - * until we attempt to log something else using that dbp, if the dbp - * was opened on a replication client.) - * - * CLOSE - * dbreg_close_id (Logs closure of dbp/revocation of ID.) - * dbreg_revoke_id (As name implies, revokes ID.) - * dbreg_teardown (Destroys FNAME.) - * - * RECOVERY - * dbreg_setup - * dbreg_assign_id (Assigns a particular ID we have in the log to a dbp.) - * - * sometimes: dbreg_revoke_id; dbreg_teardown - * other times: normal close path - * - * A note about locking: - * - * FNAME structures are referenced only by their corresponding dbp's - * until they have a valid id. - * - * Once they have a valid id, they must get linked into the log - * region list so they can get logged on checkpoints. - * - * An FNAME that may/does have a valid id must be accessed under - * protection of the mtx_filelist, with the following exception: - * - * We don't want to have to grab the mtx_filelist on every log - * record, and it should be safe not to do so when we're just - * looking at the id, because once allocated, the id should - * not change under a handle until the handle is closed. - * - * If a handle is closed during an attempt by another thread to - * log with it, well, the application doing the close deserves to - * go down in flames and a lot else is about to fail anyway. - * - * When in the course of logging we encounter an invalid id - * and go to allocate it lazily, we *do* need to check again - * after grabbing the mutex, because it's possible to race with - * another thread that has also decided that it needs to allocate - * a id lazily. - * - * See SR #5623 for further discussion of the new dbreg design. - */ - -/* - * __dbreg_setup -- - * Allocate and initialize an FNAME structure. The FNAME structures - * live in the log shared region and map one-to-one with open database handles. - * When the handle needs to be logged, the FNAME should have a valid fid - * allocated. If the handle currently isn't logged, it still has an FNAME - * entry. If we later discover that the handle needs to be logged, we can - * allocate a id for it later. (This happens when the handle is on a - * replication client that later becomes a master.) - * - * PUBLIC: int __dbreg_setup __P((DB *, const char *, u_int32_t)); - */ -int -__dbreg_setup(dbp, name, create_txnid) - DB *dbp; - const char *name; - u_int32_t create_txnid; -{ - DB_ENV *dbenv; - DB_LOG *dblp; - FNAME *fnp; - REGINFO *infop; - int ret; - size_t len; - void *namep; - - dbenv = dbp->dbenv; - dblp = dbenv->lg_handle; - infop = &dblp->reginfo; - - fnp = NULL; - namep = NULL; - - /* Allocate an FNAME and, if necessary, a buffer for the name itself. */ - LOG_SYSTEM_LOCK(dbenv); - if ((ret = __db_shalloc(infop, sizeof(FNAME), 0, &fnp)) != 0) - goto err; - memset(fnp, 0, sizeof(FNAME)); - if (name != NULL) { - len = strlen(name) + 1; - if ((ret = __db_shalloc(infop, len, 0, &namep)) != 0) - goto err; - fnp->name_off = R_OFFSET(infop, namep); - memcpy(namep, name, len); - } else - fnp->name_off = INVALID_ROFF; - - LOG_SYSTEM_UNLOCK(dbenv); - - /* - * Fill in all the remaining info that we'll need later to register - * the file, if we use it for logging. - */ - fnp->id = DB_LOGFILEID_INVALID; - fnp->s_type = dbp->type; - memcpy(fnp->ufid, dbp->fileid, DB_FILE_ID_LEN); - fnp->meta_pgno = dbp->meta_pgno; - fnp->create_txnid = create_txnid; - - dbp->log_filename = fnp; - - return (0); - -err: LOG_SYSTEM_UNLOCK(dbenv); - if (ret == ENOMEM) - __db_err(dbenv, - "Logging region out of memory; you may need to increase its size"); - - return (ret); -} - -/* - * __dbreg_teardown -- - * Destroy a DB handle's FNAME struct. - * - * PUBLIC: int __dbreg_teardown __P((DB *)); - */ -int -__dbreg_teardown(dbp) - DB *dbp; -{ - DB_ENV *dbenv; - DB_LOG *dblp; - REGINFO *infop; - FNAME *fnp; - - dbenv = dbp->dbenv; - dblp = dbenv->lg_handle; - infop = &dblp->reginfo; - fnp = dbp->log_filename; - - /* - * We may not have an FNAME if we were never opened. This is not an - * error. - */ - if (fnp == NULL || F_ISSET(fnp, DB_FNAME_NOTLOGGED)) - return (0); - - DB_ASSERT(fnp->id == DB_LOGFILEID_INVALID); - - LOG_SYSTEM_LOCK(dbenv); - if (fnp->name_off != INVALID_ROFF) - __db_shalloc_free(infop, R_ADDR(infop, fnp->name_off)); - __db_shalloc_free(infop, fnp); - LOG_SYSTEM_UNLOCK(dbenv); - - dbp->log_filename = NULL; - - return (0); -} - -/* - * __dbreg_new_id -- - * Get an unused dbreg id to this database handle. - * Used as a wrapper to acquire the mutex and - * only set the id on success. - * - * PUBLIC: int __dbreg_new_id __P((DB *, DB_TXN *)); - */ -int -__dbreg_new_id(dbp, txn) - DB *dbp; - DB_TXN *txn; -{ - DB_ENV *dbenv; - DB_LOG *dblp; - FNAME *fnp; - LOG *lp; - int32_t id; - int ret; - - dbenv = dbp->dbenv; - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - fnp = dbp->log_filename; - - /* The mtx_filelist protects the FNAME list and id management. */ - MUTEX_LOCK(dbenv, lp->mtx_filelist); - if (fnp->id != DB_LOGFILEID_INVALID) { - MUTEX_UNLOCK(dbenv, lp->mtx_filelist); - return (0); - } - if ((ret = __dbreg_get_id(dbp, txn, &id)) == 0) - fnp->id = id; - MUTEX_UNLOCK(dbenv, lp->mtx_filelist); - return (ret); -} - -/* - * __dbreg_get_id -- - * Assign an unused dbreg id to this database handle. - * Assume the caller holds the mtx_filelist locked. Assume the - * caller will set the fnp->id field with the id we return. - * - * PUBLIC: int __dbreg_get_id __P((DB *, DB_TXN *, int32_t *)); - */ -int -__dbreg_get_id(dbp, txn, idp) - DB *dbp; - DB_TXN *txn; - int32_t *idp; -{ - DB_ENV *dbenv; - DB_LOG *dblp; - FNAME *fnp; - LOG *lp; - int32_t id; - int ret; - - dbenv = dbp->dbenv; - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - fnp = dbp->log_filename; - - /* - * It's possible that after deciding we needed to call this function, - * someone else allocated an ID before we grabbed the lock. Check - * to make sure there was no race and we have something useful to do. - */ - /* Get an unused ID from the free list. */ - if ((ret = __dbreg_pop_id(dbenv, &id)) != 0) - goto err; - - /* If no ID was found, allocate a new one. */ - if (id == DB_LOGFILEID_INVALID) - id = lp->fid_max++; - - /* If the file is durable (i.e., not, not-durable), mark it as such. */ - if (!F_ISSET(dbp, DB_AM_NOT_DURABLE)) - F_SET(fnp, DB_FNAME_DURABLE); - - /* Hook the FNAME into the list of open files. */ - SH_TAILQ_INSERT_HEAD(&lp->fq, fnp, q, __fname); - - /* - * Log the registry. We should only request a new ID in situations - * where logging is reasonable. - */ - DB_ASSERT(!F_ISSET(dbp, DB_AM_RECOVER)); - - if ((ret = __dbreg_log_id(dbp, txn, id, 0)) != 0) - goto err; - - /* - * Once we log the create_txnid, we need to make sure we never - * log it again (as might happen if this is a replication client - * that later upgrades to a master). - */ - fnp->create_txnid = TXN_INVALID; - - DB_ASSERT(dbp->type == fnp->s_type); - DB_ASSERT(dbp->meta_pgno == fnp->meta_pgno); - - if ((ret = __dbreg_add_dbentry(dbenv, dblp, dbp, id)) != 0) - goto err; - /* - * If we have a successful call, set the ID. Otherwise - * we have to revoke it and remove it from all the lists - * it has been added to, and return an invalid id. - */ -err: - if (ret != 0 && id != DB_LOGFILEID_INVALID) { - (void)__dbreg_revoke_id(dbp, 1, id); - id = DB_LOGFILEID_INVALID; - } - *idp = id; - return (ret); -} - -/* - * __dbreg_assign_id -- - * Assign a particular dbreg id to this database handle. - * - * PUBLIC: int __dbreg_assign_id __P((DB *, int32_t)); - */ -int -__dbreg_assign_id(dbp, id) - DB *dbp; - int32_t id; -{ - DB *close_dbp; - DB_ENV *dbenv; - DB_LOG *dblp; - FNAME *close_fnp, *fnp; - LOG *lp; - int ret; - - dbenv = dbp->dbenv; - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - fnp = dbp->log_filename; - - close_dbp = NULL; - close_fnp = NULL; - - /* The mtx_filelist protects the FNAME list and id management. */ - MUTEX_LOCK(dbenv, lp->mtx_filelist); - - /* We should only call this on DB handles that have no ID. */ - DB_ASSERT(fnp->id == DB_LOGFILEID_INVALID); - - /* - * Make sure there isn't already a file open with this ID. There can - * be in recovery, if we're recovering across a point where an ID got - * reused. - */ - if (__dbreg_id_to_fname(dblp, id, 1, &close_fnp) == 0) { - /* - * We want to save off any dbp we have open with this id. We - * can't safely close it now, because we hold the mtx_filelist, - * but we should be able to rely on it being open in this - * process, and we're running recovery, so no other thread - * should muck with it if we just put off closing it until - * we're ready to return. - * - * Once we have the dbp, revoke its id; we're about to - * reuse it. - */ - ret = __dbreg_id_to_db_int(dbenv, NULL, &close_dbp, id, 0, 0); - if (ret == ENOENT) { - ret = 0; - goto cont; - } else if (ret != 0) - goto err; - - if ((ret = __dbreg_revoke_id(close_dbp, 1, - DB_LOGFILEID_INVALID)) != 0) - goto err; - } - - /* - * Remove this ID from the free list, if it's there, and make sure - * we don't allocate it anew. - */ -cont: if ((ret = __dbreg_pluck_id(dbenv, id)) != 0) - goto err; - if (id >= lp->fid_max) - lp->fid_max = id + 1; - - /* Now go ahead and assign the id to our dbp. */ - fnp->id = id; - /* If the file is durable (i.e., not, not-durable), mark it as such. */ - if (!F_ISSET(dbp, DB_AM_NOT_DURABLE)) - F_SET(fnp, DB_FNAME_DURABLE); - SH_TAILQ_INSERT_HEAD(&lp->fq, fnp, q, __fname); - - /* - * If we get an error adding the dbentry, revoke the id. - * We void the return value since we want to retain and - * return the original error in ret anyway. - */ - if ((ret = __dbreg_add_dbentry(dbenv, dblp, dbp, id)) != 0) - (void)__dbreg_revoke_id(dbp, 1, id); - -err: MUTEX_UNLOCK(dbenv, lp->mtx_filelist); - - /* There's nothing useful that our caller can do if this close fails. */ - if (close_dbp != NULL) - (void)__db_close(close_dbp, NULL, DB_NOSYNC); - - return (ret); -} - -/* - * __dbreg_revoke_id -- - * Take a log id away from a dbp, in preparation for closing it, - * but without logging the close. - * - * PUBLIC: int __dbreg_revoke_id __P((DB *, int, int32_t)); - */ -int -__dbreg_revoke_id(dbp, have_lock, force_id) - DB *dbp; - int have_lock; - int32_t force_id; -{ - DB_ENV *dbenv; - DB_LOG *dblp; - FNAME *fnp; - LOG *lp; - int32_t id; - int ret; - - dbenv = dbp->dbenv; - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - fnp = dbp->log_filename; - - /* If we lack an ID, this is a null-op. */ - if (fnp == NULL) - return (0); - - /* - * If we have a force_id, we had an error after allocating - * the id, and putting it on the fq list, but before we - * finished setting up fnp. So, if we have a force_id use it. - */ - if (force_id != DB_LOGFILEID_INVALID) - id = force_id; - else if (fnp->id == DB_LOGFILEID_INVALID) - return (0); - else - id = fnp->id; - if (!have_lock) - MUTEX_LOCK(dbenv, lp->mtx_filelist); - - fnp->id = DB_LOGFILEID_INVALID; - - /* Remove the FNAME from the list of open files. */ - SH_TAILQ_REMOVE(&lp->fq, fnp, q, __fname); - - /* - * Remove this id from the dbentry table and push it onto the - * free list. - */ - if ((ret = __dbreg_rem_dbentry(dblp, id)) == 0) { - /* - * If we are not in recovery but the file was opened - * for a recovery operation, then this process aborted - * a transaction for another process and the id may - * still be in use, so don't reuse this id. - */ - if (!F_ISSET(dbp, DB_AM_RECOVER) || IS_RECOVERING(dbenv)) - ret = __dbreg_push_id(dbenv, dbp, id); - } - - if (!have_lock) - MUTEX_UNLOCK(dbenv, lp->mtx_filelist); - return (ret); -} - -/* - * __dbreg_close_id -- - * Take a dbreg id away from a dbp that we're closing, and log - * the unregistry. - * - * PUBLIC: int __dbreg_close_id __P((DB *, DB_TXN *, u_int32_t)); - */ -int -__dbreg_close_id(dbp, txn, op) - DB *dbp; - DB_TXN *txn; - u_int32_t op; -{ - DBT fid_dbt, r_name, *dbtp; - DB_ENV *dbenv; - DB_LOG *dblp; - DB_LSN r_unused; - FNAME *fnp; - LOG *lp; - int ret; - - dbenv = dbp->dbenv; - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - fnp = dbp->log_filename; - - /* If we lack an ID, this is a null-op. */ - if (fnp == NULL || fnp->id == DB_LOGFILEID_INVALID) - return (0); - - MUTEX_LOCK(dbenv, lp->mtx_filelist); - - if (fnp->name_off == INVALID_ROFF) - dbtp = NULL; - else { - memset(&r_name, 0, sizeof(r_name)); - r_name.data = R_ADDR(&dblp->reginfo, fnp->name_off); - r_name.size = - (u_int32_t)strlen((char *)r_name.data) + 1; - dbtp = &r_name; - } - memset(&fid_dbt, 0, sizeof(fid_dbt)); - fid_dbt.data = fnp->ufid; - fid_dbt.size = DB_FILE_ID_LEN; - if ((ret = __dbreg_register_log(dbenv, txn, &r_unused, - F_ISSET(dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0, - op, dbtp, &fid_dbt, fnp->id, - fnp->s_type, fnp->meta_pgno, TXN_INVALID)) != 0) { - /* - * We are trying to close, but the log write failed. - * Unfortunately, close needs to plow forward, because - * the application can't do anything with the handle. - * Make the entry in the shared memory region so that - * when we close the environment, we know that this - * happened. Also, make sure we remove this from the - * per-process table, so that we don't try to close it - * later. - */ - F_SET(fnp, DB_FNAME_NOTLOGGED); - (void)__dbreg_rem_dbentry(dblp, fnp->id); - goto err; - } - - ret = __dbreg_revoke_id(dbp, 1, DB_LOGFILEID_INVALID); - -err: MUTEX_UNLOCK(dbenv, lp->mtx_filelist); - return (ret); -} - -/* - * __dbreg_push_id and __dbreg_pop_id -- - * Dbreg ids from closed files are kept on a stack in shared memory - * for recycling. (We want to reuse them as much as possible because each - * process keeps open files in an array by ID.) Push them to the stack and - * pop them from it, managing memory as appropriate. - * - * The stack is protected by the mtx_filelist, and both functions assume it - * is already locked. - */ -static int -__dbreg_push_id(dbenv, dbp, id) - DB_ENV *dbenv; - DB *dbp; - int32_t id; -{ - DB_LOG *dblp; - DB_REP *db_rep; - LOG *lp; - REGINFO *infop; - int32_t *stack, *newstack; - int ret; - - dblp = dbenv->lg_handle; - infop = &dblp->reginfo; - lp = infop->primary; - db_rep = dbenv->rep_handle; - - /* - * If our fid generation in replication has changed, this fid should - * not be pushed back onto the stack. - */ - if (REP_ON(dbenv) && db_rep->region != NULL && - ((REP *)db_rep->region)->gen != dbp->fid_gen) - return (0); - /* Check if we have room on the stack. */ - if (lp->free_fid_stack == INVALID_ROFF || - lp->free_fids_alloced <= lp->free_fids + 1) { - LOG_SYSTEM_LOCK(dbenv); - if ((ret = __db_shalloc(infop, - (lp->free_fids_alloced + 20) * sizeof(u_int32_t), 0, - &newstack)) != 0) { - LOG_SYSTEM_UNLOCK(dbenv); - return (ret); - } - - if (lp->free_fid_stack != INVALID_ROFF) { - stack = R_ADDR(infop, lp->free_fid_stack); - memcpy(newstack, stack, - lp->free_fids_alloced * sizeof(u_int32_t)); - __db_shalloc_free(infop, stack); - } - lp->free_fid_stack = R_OFFSET(infop, newstack); - lp->free_fids_alloced += 20; - LOG_SYSTEM_UNLOCK(dbenv); - } - - stack = R_ADDR(infop, lp->free_fid_stack); - stack[lp->free_fids++] = id; - return (0); -} - -static int -__dbreg_pop_id(dbenv, id) - DB_ENV *dbenv; - int32_t *id; -{ - DB_LOG *dblp; - LOG *lp; - int32_t *stack; - - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - - /* Do we have anything to pop? */ - if (lp->free_fid_stack != INVALID_ROFF && lp->free_fids > 0) { - stack = R_ADDR(&dblp->reginfo, lp->free_fid_stack); - *id = stack[--lp->free_fids]; - } else - *id = DB_LOGFILEID_INVALID; - - return (0); -} - -/* - * __dbreg_pluck_id -- - * Remove a particular dbreg id from the stack of free ids. This is - * used when we open a file, as in recovery, with a specific ID that might - * be on the stack. - * - * Returns success whether or not the particular id was found, and like - * push and pop, assumes that the mtx_filelist is locked. - */ -static int -__dbreg_pluck_id(dbenv, id) - DB_ENV *dbenv; - int32_t id; -{ - DB_LOG *dblp; - LOG *lp; - int32_t *stack; - u_int i; - - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - - /* Do we have anything to look at? */ - if (lp->free_fid_stack != INVALID_ROFF) { - stack = R_ADDR(&dblp->reginfo, lp->free_fid_stack); - for (i = 0; i < lp->free_fids; i++) - if (id == stack[i]) { - /* - * Found it. Overwrite it with the top - * id (which may harmlessly be itself), - * and shorten the stack by one. - */ - stack[i] = stack[lp->free_fids - 1]; - lp->free_fids--; - return (0); - } - } - - return (0); -} - -/* - * __dbreg_log_id -- - * Used for in-memory named files. They are created in mpool and - * are given id's early in the open process so that we can read and - * create pages in the mpool for the files. However, at the time that - * the mpf is created, the file may not be fully created and/or its - * meta-data may not be fully known, so we can't do a full dbregister. - * This is a routine exported that will log a complete dbregister - * record that will allow for both recovery and replication. - * - * PUBLIC: int __dbreg_log_id __P((DB *, DB_TXN *, int32_t, int)); - */ -int -__dbreg_log_id(dbp, txn, id, needlock) - DB *dbp; - DB_TXN *txn; - int32_t id; - int needlock; -{ - DBT fid_dbt, r_name; - DB_ENV *dbenv; - DB_LOG *dblp; - DB_LSN unused; - FNAME *fnp; - LOG *lp; - u_int32_t op; - int ret; - - dbenv = dbp->dbenv; - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - fnp = dbp->log_filename; - - /* Verify that the fnp has been initialized. */ - if (fnp->s_type == DB_UNKNOWN) { - memcpy(fnp->ufid, dbp->fileid, DB_FILE_ID_LEN); - fnp->s_type = dbp->type; - } - - /* - * Log the registry. We should only request a new ID in situations - * where logging is reasonable. - */ - memset(&fid_dbt, 0, sizeof(fid_dbt)); - memset(&r_name, 0, sizeof(r_name)); - - if (needlock) - MUTEX_LOCK(dbenv, lp->mtx_filelist); - - if (fnp->name_off != INVALID_ROFF) { - r_name.data = R_ADDR(&dblp->reginfo, fnp->name_off); - r_name.size = (u_int32_t)strlen((char *)r_name.data) + 1; - } - - fid_dbt.data = dbp->fileid; - fid_dbt.size = DB_FILE_ID_LEN; - - op = !F_ISSET(dbp, DB_AM_OPEN_CALLED) ? DBREG_PREOPEN : - (F_ISSET(dbp, DB_AM_INMEM) ? DBREG_REOPEN : DBREG_OPEN); - ret = __dbreg_register_log(dbenv, txn, &unused, - F_ISSET(dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0, - op, r_name.size == 0 ? NULL : &r_name, &fid_dbt, id, - fnp->s_type, fnp->meta_pgno, fnp->create_txnid); - - if (needlock) - MUTEX_UNLOCK(dbenv, lp->mtx_filelist); - - return (ret); -} diff --git a/storage/bdb/dbreg/dbreg.src b/storage/bdb/dbreg/dbreg.src deleted file mode 100644 index 26793c1b916..00000000000 --- a/storage/bdb/dbreg/dbreg.src +++ /dev/null @@ -1,46 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: dbreg.src,v 12.1 2005/06/16 20:21:49 bostic Exp $ - */ - -PREFIX __dbreg -DBPRIVATE - -INCLUDE #ifndef NO_SYSTEM_INCLUDES -INCLUDE #include <sys/types.h> -INCLUDE -INCLUDE #include <ctype.h> -INCLUDE #include <string.h> -INCLUDE #endif -INCLUDE -INCLUDE #include "db_int.h" -INCLUDE #include "dbinc/crypto.h" -INCLUDE #include "dbinc/db_page.h" -INCLUDE #include "dbinc/db_dispatch.h" -INCLUDE #include "dbinc/db_am.h" -INCLUDE #include "dbinc/log.h" -INCLUDE #include "dbinc/txn.h" -INCLUDE - -/* - * Used for registering name/id translations at open or close. - * opcode: register or unregister - * name: file name - * fileid: unique file id - * ftype: file type - * ftype: database type - * id: transaction id of the subtransaction that created the fs object - */ -BEGIN register 2 -ARG opcode u_int32_t lu -DBT name DBT s -DBT uid DBT s -ARG fileid int32_t ld -ARG ftype DBTYPE lx -ARG meta_pgno db_pgno_t lu -ARG id u_int32_t lx -END diff --git a/storage/bdb/dbreg/dbreg_rec.c b/storage/bdb/dbreg/dbreg_rec.c deleted file mode 100644 index 44f663b3be9..00000000000 --- a/storage/bdb/dbreg/dbreg_rec.c +++ /dev/null @@ -1,421 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1995, 1996 - * The President and Fellows of Harvard University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: dbreg_rec.c,v 12.8 2005/11/09 14:20:32 margo Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/db_am.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" -#include "dbinc/txn.h" - -static int __dbreg_open_file __P((DB_ENV *, - DB_TXN *, __dbreg_register_args *, void *)); - -/* - * PUBLIC: int __dbreg_register_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__dbreg_register_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - DB_ENTRY *dbe; - DB_LOG *dblp; - DB *dbp; - __dbreg_register_args *argp; - int do_close, do_open, do_rem, ret, t_ret; - u_int32_t status; - - dblp = dbenv->lg_handle; - dbp = NULL; - -#ifdef DEBUG_RECOVER - REC_PRINT(__dbreg_register_print); -#endif - do_open = do_close = 0; - if ((ret = __dbreg_register_read(dbenv, dbtp->data, &argp)) != 0) - goto out; - - switch (argp->opcode) { - case DBREG_REOPEN: - case DBREG_PREOPEN: - case DBREG_OPEN: - /* - * In general, we redo the open on REDO and abort on UNDO. - * However, a reopen is a second instance of an open of - * in-memory files and we don't want to close them yet - * on abort, so just skip that here. - */ - if ((DB_REDO(op) || - op == DB_TXN_OPENFILES || op == DB_TXN_POPENFILES)) - do_open = 1; - else if (argp->opcode != DBREG_REOPEN) - do_close = 1; - break; - case DBREG_CLOSE: - if (DB_UNDO(op)) - do_open = 1; - else - do_close = 1; - break; - case DBREG_RCLOSE: - /* - * DBREG_RCLOSE was generated by recover because a file was - * left open. The POPENFILES pass, which is run to open - * files to abort prepared transactions, may not include the - * open for this file so we open it here. Note that a normal - * CLOSE is not legal before the prepared transaction is - * committed or aborted. - */ - if (DB_UNDO(op) || op == DB_TXN_POPENFILES) - do_open = 1; - else - do_close = 1; - break; - case DBREG_CHKPNT: - if (DB_UNDO(op) || - op == DB_TXN_OPENFILES || op == DB_TXN_POPENFILES) - do_open = 1; - break; - default: - DB_ASSERT(0); - ret = EINVAL; - break; - } - - if (do_open) { - /* - * We must open the db even if the meta page is not - * yet written as we may be creating subdatabase. - */ - if (op == DB_TXN_OPENFILES && argp->opcode != DBREG_CHKPNT) - F_SET(dblp, DBLOG_FORCE_OPEN); - - /* - * During an abort or an open pass to recover prepared txns, - * we need to make sure that we use the same locker id on the - * open. We pass the txnid along to ensure this. - */ - ret = __dbreg_open_file(dbenv, - op == DB_TXN_ABORT || op == DB_TXN_POPENFILES ? - argp->txnid : NULL, argp, info); - if (ret == DB_PAGE_NOTFOUND && argp->meta_pgno != PGNO_BASE_MD) - ret = ENOENT; - if (ret == ENOENT || ret == EINVAL) { - /* - * If this is an OPEN while rolling forward, it's - * possible that the file was recreated since last - * time we got here. In that case, we've got deleted - * set and probably shouldn't, so we need to check - * for that case and possibly retry. - */ - if (op == DB_TXN_FORWARD_ROLL && - argp->txnid != 0 && - dblp->dbentry[argp->fileid].deleted) { - dblp->dbentry[argp->fileid].deleted = 0; - ret = - __dbreg_open_file(dbenv, NULL, argp, info); - if (ret == DB_PAGE_NOTFOUND && - argp->meta_pgno != PGNO_BASE_MD) - ret = ENOENT; - } - /* - * We treat ENOENT as OK since it's possible that - * the file was renamed or deleted. - * All other errors, we return. - */ - if (ret == ENOENT) - ret = 0; - } - F_CLR(dblp, DBLOG_FORCE_OPEN); - } - - if (do_close) { - /* - * If we are undoing an open, or redoing a close, - * then we need to close the file. If we are simply - * revoking then we just need to grab the DBP and revoke - * the log id. - * - * If the file is deleted, then we can just ignore this close. - * Otherwise, we should usually have a valid dbp we should - * close or whose reference count should be decremented. - * However, if we shut down without closing a file, we may, in - * fact, not have the file open, and that's OK. - */ - do_rem = 0; - MUTEX_LOCK(dbenv, dblp->mtx_dbreg); - if (argp->fileid < dblp->dbentry_cnt) { - /* - * Typically, closes should match an open which means - * that if this is a close, there should be a valid - * entry in the dbentry table when we get here, - * however there are exceptions. 1. If this is an - * OPENFILES pass, then we may have started from - * a log file other than the first, and the - * corresponding open appears in an earlier file. - * 2. If we are undoing an open on an abort or - * recovery, it's possible that we failed after - * the log record, but before we actually entered - * a handle here. - * 3. If we aborted an open, then we wrote a non-txnal - * RCLOSE into the log. During the forward pass, the - * file won't be open, and that's OK. - */ - dbe = &dblp->dbentry[argp->fileid]; - if (dbe->dbp == NULL && !dbe->deleted) { - /* No valid entry here. */ - if ((DB_REDO(op) && - argp->opcode != DBREG_RCLOSE) || - argp->opcode == DBREG_CHKPNT) { - __db_err(dbenv, - "Warning: Improper file close at %lu/%lu", - (u_long)lsnp->file, - (u_long)lsnp->offset); - } - MUTEX_UNLOCK(dbenv, dblp->mtx_dbreg); - goto done; - } - - /* We have either an open entry or a deleted entry. */ - if ((dbp = dbe->dbp) != NULL) { - /* - * If we're a replication client, it's - * possible to get here with a dbp that - * the user opened, but which we later - * assigned a fileid to. Be sure that - * we only close dbps that we opened in - * the recovery code or that were opened - * inside a currently aborting transaction. - */ - do_rem = F_ISSET(dbp, DB_AM_RECOVER) || - op == DB_TXN_ABORT; - MUTEX_UNLOCK(dbenv, dblp->mtx_dbreg); - if (op == DB_TXN_ABORT) - (void)__dbreg_close_id(dbp, - NULL, DBREG_RCLOSE); - else - (void)__dbreg_revoke_id(dbp, 0, - DB_LOGFILEID_INVALID); - } else if (dbe->deleted) { - MUTEX_UNLOCK(dbenv, dblp->mtx_dbreg); - if ((ret = __dbreg_rem_dbentry( - dblp, argp->fileid)) != 0) - goto out; - } - } else - MUTEX_UNLOCK(dbenv, dblp->mtx_dbreg); - - /* - * During recovery, all files are closed. On an abort, we only - * close the file if we opened it during the abort - * (DB_AM_RECOVER set), otherwise we simply do a __db_refresh. - * For the close case, if remove or rename has closed the file, - * don't request a sync, because a NULL mpf would be a problem. - * - * If we are undoing a create we'd better discard any buffers - * from the memory pool. We identify creates because the - * argp->id field contains the transaction containing the file - * create; if that id is invalid, we are not creating. - * - * On the backward pass, we need to "undo" opens even if the - * transaction in which they appeared committed, because we have - * already undone the corresponding close. In that case, the - * id will be valid, but we do not want to discard buffers. - */ - if (do_rem && dbp != NULL) { - if (argp->id != TXN_INVALID) { - if ((ret = __db_txnlist_find(dbenv, - info, argp->txnid->txnid, &status)) - != DB_NOTFOUND && ret != 0) - goto out; - if (ret == DB_NOTFOUND || status != TXN_COMMIT) - F_SET(dbp, DB_AM_DISCARD); - ret = 0; - } - - if (op == DB_TXN_ABORT && - !F_ISSET(dbp, DB_AM_RECOVER)) { - if ((t_ret = __db_refresh(dbp, - NULL, DB_NOSYNC, NULL, 0)) != 0 && ret == 0) - ret = t_ret; - } else { - if (op == DB_TXN_APPLY && - (t_ret = __db_sync(dbp)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = __db_close( - dbp, NULL, DB_NOSYNC)) != 0 && ret == 0) - ret = t_ret; - } - } - } -done: if (ret == 0) - *lsnp = argp->prev_lsn; -out: if (argp != NULL) - __os_free(dbenv, argp); - return (ret); -} - -/* - * __dbreg_open_file -- - * Called during log_register recovery. Make sure that we have an - * entry in the dbentry table for this ndx. Returns 0 on success, - * non-zero on error. - */ -static int -__dbreg_open_file(dbenv, txn, argp, info) - DB_ENV *dbenv; - DB_TXN *txn; - __dbreg_register_args *argp; - void *info; -{ - DB_ENTRY *dbe; - DB_LOG *dblp; - DB *dbp; - u_int32_t id, status; - int ret; - - dblp = (DB_LOG *)dbenv->lg_handle; - - /* - * When we're opening, we have to check that the name we are opening - * is what we expect. If it's not, then we close the old file and - * open the new one. - */ - MUTEX_LOCK(dbenv, dblp->mtx_dbreg); - if (argp->fileid != DB_LOGFILEID_INVALID && - argp->fileid < dblp->dbentry_cnt) - dbe = &dblp->dbentry[argp->fileid]; - else - dbe = NULL; - - if (dbe != NULL) { - if (dbe->deleted) { - MUTEX_UNLOCK(dbenv, dblp->mtx_dbreg); - return (ENOENT); - } - - /* - * At the end of OPENFILES, we may have a file open. If this - * is a reopen, then we will always close and reopen. If the - * open was part of a committed transaction, so it doesn't - * get undone. However, if the fileid was previously used, - * we'll see a close that may need to get undone. There are - * three ways we can detect this. 1) the meta-pgno in the - * current file does not match that of the open file, 2) the - * file uid of the current file does not match that of the - * previously opened file, 3) the current file is unnamed, in - * which case it should never be opened during recovery. - */ - if ((dbp = dbe->dbp) != NULL) { - if (argp->opcode == DBREG_REOPEN || - dbp->meta_pgno != argp->meta_pgno || - argp->name.size == 0 || - memcmp(dbp->fileid, argp->uid.data, - DB_FILE_ID_LEN) != 0) { - MUTEX_UNLOCK(dbenv, dblp->mtx_dbreg); - (void)__dbreg_revoke_id(dbp, 0, - DB_LOGFILEID_INVALID); - if (F_ISSET(dbp, DB_AM_RECOVER)) - (void)__db_close(dbp, NULL, DB_NOSYNC); - goto reopen; - } - - /* - * We should only get here if we already have the - * dbp from an openfiles pass, in which case, what's - * here had better be the same dbp. - */ - DB_ASSERT(dbe->dbp == dbp); - MUTEX_UNLOCK(dbenv, dblp->mtx_dbreg); - - /* - * This is a successful open. We need to record that - * in the txnlist so that we know how to handle the - * subtransaction that created the file system object. - */ - if (argp->id != TXN_INVALID && - (ret = __db_txnlist_update(dbenv, info, - argp->id, TXN_EXPECTED, NULL, &status, 1)) != 0) - return (ret); - return (0); - } - } - - MUTEX_UNLOCK(dbenv, dblp->mtx_dbreg); - -reopen: - /* - * We never re-open temporary files. Temp files are only useful during - * aborts in which case the dbp was entered when the file was - * registered. During recovery, we treat temp files as properly deleted - * files, allowing the open to fail and not reporting any errors when - * recovery fails to get a valid dbp from __dbreg_id_to_db. - */ - if (argp->name.size == 0) { - (void)__dbreg_add_dbentry(dbenv, dblp, NULL, argp->fileid); - return (ENOENT); - } - - /* - * We are about to pass a recovery txn pointer into the main library. - * We need to make sure that any accessed fields are set appropriately. - */ - if (txn != NULL) { - id = txn->txnid; - memset(txn, 0, sizeof(DB_TXN)); - txn->txnid = id; - txn->mgrp = dbenv->tx_handle; - } - - return (__dbreg_do_open(dbenv, - txn, dblp, argp->uid.data, argp->name.data, argp->ftype, - argp->fileid, argp->meta_pgno, info, argp->id, argp->opcode)); -} diff --git a/storage/bdb/dbreg/dbreg_stat.c b/storage/bdb/dbreg/dbreg_stat.c deleted file mode 100644 index bdbb9b2604f..00000000000 --- a/storage/bdb/dbreg/dbreg_stat.c +++ /dev/null @@ -1,126 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: dbreg_stat.c,v 12.5 2005/10/12 15:01:47 margo Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_am.h" -#include "dbinc/log.h" -#include "dbinc/txn.h" - -#ifdef HAVE_STATISTICS -static int __dbreg_print_dblist __P((DB_ENV *, u_int32_t)); - -/* - * __dbreg_stat_print -- - * Print the dbreg statistics. - * - * PUBLIC: int __dbreg_stat_print __P((DB_ENV *, u_int32_t)); - */ -int -__dbreg_stat_print(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - int ret; - - if (LF_ISSET(DB_STAT_ALL) && - (ret = __dbreg_print_dblist(dbenv, flags)) != 0) - return (ret); - - return (0); -} - -/* - * __dbreg_print_fname -- - * Display the contents of an FNAME structure. - * - * PUBLIC: void __dbreg_print_fname __P((DB_ENV *, FNAME *)); - */ -void -__dbreg_print_fname(dbenv, fnp) - DB_ENV *dbenv; - FNAME *fnp; -{ - static const FN fn[] = { - { DB_FNAME_DURABLE, "DB_FNAME_DURABLE" }, - { DB_FNAME_NOTLOGGED, "DB_FNAME_NOTLOGGED" }, - { 0, NULL } - }; - - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_msg(dbenv, "DB handle FNAME contents:"); - STAT_LONG("log ID", fnp->id); - STAT_ULONG("Meta pgno", fnp->meta_pgno); - __db_print_fileid(dbenv, fnp->ufid, "\tFile ID"); - STAT_ULONG("create txn", fnp->create_txnid); - __db_prflags(dbenv, NULL, fnp->flags, fn, NULL, "\tFlags"); -} - -/* - * __dbreg_print_dblist -- - * Display the DB_ENV's list of files. - */ -static int -__dbreg_print_dblist(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - DB *dbp; - DB_LOG *dblp; - FNAME *fnp; - LOG *lp; - int del, first; - char *name; - - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_msg(dbenv, "LOG FNAME list:"); - __mutex_print_debug_single( - dbenv, "File name mutex", lp->mtx_filelist, flags); - - STAT_LONG("Fid max", lp->fid_max); - - MUTEX_LOCK(dbenv, lp->mtx_filelist); - for (first = 1, fnp = SH_TAILQ_FIRST(&lp->fq, __fname); - fnp != NULL; fnp = SH_TAILQ_NEXT(fnp, q, __fname)) { - if (first) { - first = 0; - __db_msg(dbenv, - "ID\tName\tType\tPgno\tTxnid\tDBP-info"); - } - if (fnp->name_off == INVALID_ROFF) - name = ""; - else - name = R_ADDR(&dblp->reginfo, fnp->name_off); - - dbp = fnp->id >= dblp->dbentry_cnt ? NULL : - dblp->dbentry[fnp->id].dbp; - del = fnp->id >= dblp->dbentry_cnt ? 0 : - dblp->dbentry[fnp->id].deleted; - __db_msg(dbenv, "%ld\t%s\t%s\t%lu\t%lx\t%s %d %lx %lx", - (long)fnp->id, name, - __db_dbtype_to_string(fnp->s_type), - (u_long)fnp->meta_pgno, (u_long)fnp->create_txnid, - dbp == NULL ? "No DBP" : "DBP", del, P_TO_ULONG(dbp), - (u_long)(dbp == NULL ? 0 : dbp->flags)); - } - MUTEX_UNLOCK(dbenv, lp->mtx_filelist); - - return (0); -} -#endif diff --git a/storage/bdb/dbreg/dbreg_util.c b/storage/bdb/dbreg/dbreg_util.c deleted file mode 100644 index 9c3082b1e9c..00000000000 --- a/storage/bdb/dbreg/dbreg_util.c +++ /dev/null @@ -1,672 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: dbreg_util.c,v 12.10 2005/10/12 15:01:47 margo Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_am.h" -#include "dbinc/db_shash.h" -#include "dbinc/fop.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" -#include "dbinc/txn.h" - -static int __dbreg_check_master __P((DB_ENV *, u_int8_t *, char *)); - -/* - * __dbreg_add_dbentry -- - * Adds a DB entry to the dbreg DB entry table. - * - * PUBLIC: int __dbreg_add_dbentry __P((DB_ENV *, DB_LOG *, DB *, int32_t)); - */ -int -__dbreg_add_dbentry(dbenv, dblp, dbp, ndx) - DB_ENV *dbenv; - DB_LOG *dblp; - DB *dbp; - int32_t ndx; -{ - int32_t i; - int ret; - - ret = 0; - - MUTEX_LOCK(dbenv, dblp->mtx_dbreg); - - /* - * Check if we need to grow the table. Note, ndx is 0-based (the - * index into the DB entry table) an dbentry_cnt is 1-based, the - * number of available slots. - */ - if (dblp->dbentry_cnt <= ndx) { - if ((ret = __os_realloc(dbenv, - (size_t)(ndx + DB_GROW_SIZE) * sizeof(DB_ENTRY), - &dblp->dbentry)) != 0) - goto err; - - /* Initialize the new entries. */ - for (i = dblp->dbentry_cnt; i < ndx + DB_GROW_SIZE; i++) { - dblp->dbentry[i].dbp = NULL; - dblp->dbentry[i].deleted = 0; - } - dblp->dbentry_cnt = i; - } - - DB_ASSERT(dblp->dbentry[ndx].dbp == NULL); - dblp->dbentry[ndx].deleted = dbp == NULL; - dblp->dbentry[ndx].dbp = dbp; - -err: MUTEX_UNLOCK(dbenv, dblp->mtx_dbreg); - return (ret); -} - -/* - * __dbreg_rem_dbentry - * Remove an entry from the DB entry table. - * - * PUBLIC: int __dbreg_rem_dbentry __P((DB_LOG *, int32_t)); - */ -int -__dbreg_rem_dbentry(dblp, ndx) - DB_LOG *dblp; - int32_t ndx; -{ - MUTEX_LOCK(dblp->dbenv, dblp->mtx_dbreg); - if (dblp->dbentry_cnt > ndx) { - dblp->dbentry[ndx].dbp = NULL; - dblp->dbentry[ndx].deleted = 0; - } - MUTEX_UNLOCK(dblp->dbenv, dblp->mtx_dbreg); - - return (0); -} - -/* - * __dbreg_log_files -- - * Put a DBREG_CHKPNT/CLOSE log record for each open database. - * - * PUBLIC: int __dbreg_log_files __P((DB_ENV *)); - */ -int -__dbreg_log_files(dbenv) - DB_ENV *dbenv; -{ - DB_LOG *dblp; - DB_LSN r_unused; - DBT *dbtp, fid_dbt, t; - FNAME *fnp; - LOG *lp; - int ret; - - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - - ret = 0; - - MUTEX_LOCK(dbenv, lp->mtx_filelist); - - for (fnp = SH_TAILQ_FIRST(&lp->fq, __fname); - fnp != NULL; fnp = SH_TAILQ_NEXT(fnp, q, __fname)) { - - if (fnp->name_off == INVALID_ROFF) - dbtp = NULL; - else { - memset(&t, 0, sizeof(t)); - t.data = R_ADDR(&dblp->reginfo, fnp->name_off); - t.size = (u_int32_t)strlen(t.data) + 1; - dbtp = &t; - } - memset(&fid_dbt, 0, sizeof(fid_dbt)); - fid_dbt.data = fnp->ufid; - fid_dbt.size = DB_FILE_ID_LEN; - /* - * Output DBREG_CHKPNT records which will be processed during - * the OPENFILES pass of recovery. At the end of recovery we - * want to output the files that were open so a future recovery - * run will have the correct files open during a backward pass. - * For this we output DBREG_RCLOSE records so the files will be - * closed on the forward pass. - */ - if ((ret = __dbreg_register_log(dbenv, - NULL, &r_unused, - F_ISSET(fnp, DB_FNAME_DURABLE) ? 0 : DB_LOG_NOT_DURABLE, - F_ISSET(dblp, DBLOG_RECOVER) ? DBREG_RCLOSE : DBREG_CHKPNT, - dbtp, &fid_dbt, fnp->id, fnp->s_type, fnp->meta_pgno, - TXN_INVALID)) != 0) - break; - } - - MUTEX_UNLOCK(dbenv, lp->mtx_filelist); - - return (ret); -} - -/* - * __dbreg_close_files -- - * Remove the id's of open files and actually close those - * files that were opened by the recovery daemon. We sync the - * file, unless its mpf pointer has been NULLed by a db_remove or - * db_rename. We may not have flushed the log_register record that - * closes the file. - * - * PUBLIC: int __dbreg_close_files __P((DB_ENV *)); - */ -int -__dbreg_close_files(dbenv) - DB_ENV *dbenv; -{ - DB_LOG *dblp; - DB *dbp; - int ret, t_ret; - int32_t i; - - /* If we haven't initialized logging, we have nothing to do. */ - if (!LOGGING_ON(dbenv)) - return (0); - - dblp = dbenv->lg_handle; - ret = 0; - MUTEX_LOCK(dbenv, dblp->mtx_dbreg); - for (i = 0; i < dblp->dbentry_cnt; i++) { - /* - * We only want to close dbps that recovery opened. Any - * dbps that weren't opened by recovery but show up here - * are about to be unconditionally removed from the table. - * Before doing so, we need to revoke their log fileids - * so that we don't end up leaving around FNAME entries - * for dbps that shouldn't have them. - * - * Any FNAME entries that were marked NOTLOGGED had the - * log write fail while they were being closed. Since it's - * too late to be logging now we flag that as a failure - * so recovery will be run. This will get returned by - * __dbreg_revoke_id. - */ - if ((dbp = dblp->dbentry[i].dbp) != NULL) { - /* - * It's unsafe to call DB->close or revoke_id - * while holding the thread lock, because - * we'll call __dbreg_rem_dbentry and grab it again. - * - * Just drop it. Since dbreg ids go monotonically - * upward, concurrent opens should be safe, and the - * user should have no business closing files while - * we're in this loop anyway--we're in the process of - * making all outstanding dbps invalid. - */ - MUTEX_UNLOCK(dbenv, dblp->mtx_dbreg); - if (F_ISSET(dbp, DB_AM_RECOVER)) - t_ret = __db_close(dbp, - NULL, dbp->mpf == NULL ? DB_NOSYNC : 0); - else - t_ret = __dbreg_revoke_id( - dbp, 0, DB_LOGFILEID_INVALID); - if (ret == 0) - ret = t_ret; - MUTEX_LOCK(dbenv, dblp->mtx_dbreg); - } - - dblp->dbentry[i].deleted = 0; - dblp->dbentry[i].dbp = NULL; - } - MUTEX_UNLOCK(dbenv, dblp->mtx_dbreg); - return (ret); -} - -/* - * __dbreg_id_to_db -- - * Return the DB corresponding to the specified dbreg id. - * - * PUBLIC: int __dbreg_id_to_db __P((DB_ENV *, DB_TXN *, DB **, int32_t, int)); - */ -int -__dbreg_id_to_db(dbenv, txn, dbpp, ndx, inc) - DB_ENV *dbenv; - DB_TXN *txn; - DB **dbpp; - int32_t ndx; - int inc; -{ - return (__dbreg_id_to_db_int(dbenv, txn, dbpp, ndx, inc, 1)); -} - -/* - * __dbreg_id_to_db_int -- - * Return the DB corresponding to the specified dbreg id. The internal - * version takes a final parameter that indicates whether we should attempt - * to open the file if no mapping is found. During recovery, the recovery - * routines all want to try to open the file (and this is called from - * __dbreg_id_to_db), however, if we have a multi-process environment where - * some processes may not have the files open (e.g., XA), then we also get - * called from __dbreg_assign_id and it's OK if there is no mapping. - * - * PUBLIC: int __dbreg_id_to_db_int __P((DB_ENV *, - * PUBLIC: DB_TXN *, DB **, int32_t, int, int)); - */ -int -__dbreg_id_to_db_int(dbenv, txn, dbpp, ndx, inc, tryopen) - DB_ENV *dbenv; - DB_TXN *txn; - DB **dbpp; - int32_t ndx; - int inc, tryopen; -{ - DB_LOG *dblp; - FNAME *fname; - int ret; - char *name; - - ret = 0; - dblp = dbenv->lg_handle; - COMPQUIET(inc, 0); - - MUTEX_LOCK(dbenv, dblp->mtx_dbreg); - - /* - * Under XA, a process different than the one issuing DB operations - * may abort a transaction. In this case, the "recovery" routines - * are run by a process that does not necessarily have the file open, - * so we we must open the file explicitly. - */ - if (ndx >= dblp->dbentry_cnt || - (!dblp->dbentry[ndx].deleted && dblp->dbentry[ndx].dbp == NULL)) { - if (!tryopen || F_ISSET(dblp, DBLOG_RECOVER)) { - ret = ENOENT; - goto err; - } - - /* - * __dbreg_id_to_fname acquires the mtx_filelist mutex, which - * we can't safely acquire while we hold the thread lock. We - * no longer need it anyway--the dbentry table didn't have what - * we needed. - */ - MUTEX_UNLOCK(dbenv, dblp->mtx_dbreg); - - if (__dbreg_id_to_fname(dblp, ndx, 0, &fname) != 0) - /* - * With transactional opens, we may actually have - * closed this file in the transaction in which - * case this will fail too. Then it's up to the - * caller to reopen the file. - */ - return (ENOENT); - - /* - * Note that we're relying on fname not to change, even though - * we released the mutex that protects it (mtx_filelist) inside - * __dbreg_id_to_fname. This should be a safe assumption, the - * other process that has the file open shouldn't be closing it - * while we're trying to abort. - */ - name = R_ADDR(&dblp->reginfo, fname->name_off); - - /* - * At this point, we are not holding the thread lock, so exit - * directly instead of going through the exit code at the - * bottom. If the __dbreg_do_open succeeded, then we don't need - * to do any of the remaining error checking at the end of this - * routine. - * XXX I am sending a NULL txnlist and 0 txnid which may be - * completely broken ;( - */ - if ((ret = __dbreg_do_open(dbenv, txn, dblp, - fname->ufid, name, fname->s_type, - ndx, fname->meta_pgno, NULL, 0, DBREG_OPEN)) != 0) - return (ret); - - *dbpp = dblp->dbentry[ndx].dbp; - return (0); - } - - /* - * Return DB_DELETED if the file has been deleted (it's not an error). - */ - if (dblp->dbentry[ndx].deleted) { - ret = DB_DELETED; - goto err; - } - - /* It's an error if we don't have a corresponding writeable DB. */ - if ((*dbpp = dblp->dbentry[ndx].dbp) == NULL) - ret = ENOENT; - else - /* - * If we are in recovery, then set that the file has - * been written. It is possible to run recovery, - * find all the pages in their post update state - * in the OS buffer pool, put a checkpoint in the log - * and then crash the system without forcing the pages - * to disk. If this is an in-memory file, we may not have - * an mpf yet. - */ - if ((*dbpp)->mpf != NULL && (*dbpp)->mpf->mfp != NULL) - (*dbpp)->mpf->mfp->file_written = 1; - -err: MUTEX_UNLOCK(dbenv, dblp->mtx_dbreg); - return (ret); -} - -/* - * __dbreg_id_to_fname -- - * Traverse the shared-memory region looking for the entry that - * matches the passed dbreg id. Returns 0 on success; -1 on error. - * - * PUBLIC: int __dbreg_id_to_fname __P((DB_LOG *, int32_t, int, FNAME **)); - */ -int -__dbreg_id_to_fname(dblp, id, have_lock, fnamep) - DB_LOG *dblp; - int32_t id; - int have_lock; - FNAME **fnamep; -{ - DB_ENV *dbenv; - FNAME *fnp; - LOG *lp; - int ret; - - dbenv = dblp->dbenv; - lp = dblp->reginfo.primary; - - ret = -1; - - if (!have_lock) - MUTEX_LOCK(dbenv, lp->mtx_filelist); - for (fnp = SH_TAILQ_FIRST(&lp->fq, __fname); - fnp != NULL; fnp = SH_TAILQ_NEXT(fnp, q, __fname)) { - if (fnp->id == id) { - *fnamep = fnp; - ret = 0; - break; - } - } - if (!have_lock) - MUTEX_UNLOCK(dbenv, lp->mtx_filelist); - - return (ret); -} -/* - * __dbreg_fid_to_fname -- - * Traverse the shared-memory region looking for the entry that - * matches the passed file unique id. Returns 0 on success; -1 on error. - * - * PUBLIC: int __dbreg_fid_to_fname __P((DB_LOG *, u_int8_t *, int, FNAME **)); - */ -int -__dbreg_fid_to_fname(dblp, fid, have_lock, fnamep) - DB_LOG *dblp; - u_int8_t *fid; - int have_lock; - FNAME **fnamep; -{ - DB_ENV *dbenv; - FNAME *fnp; - LOG *lp; - int ret; - - dbenv = dblp->dbenv; - lp = dblp->reginfo.primary; - - ret = -1; - - if (!have_lock) - MUTEX_LOCK(dbenv, lp->mtx_filelist); - for (fnp = SH_TAILQ_FIRST(&lp->fq, __fname); - fnp != NULL; fnp = SH_TAILQ_NEXT(fnp, q, __fname)) { - if (memcmp(fnp->ufid, fid, DB_FILE_ID_LEN) == 0) { - *fnamep = fnp; - ret = 0; - break; - } - } - if (!have_lock) - MUTEX_UNLOCK(dbenv, lp->mtx_filelist); - - return (ret); -} - -/* - * __dbreg_get_name - * - * Interface to get name of registered files. This is mainly diagnostic - * and the name passed could be transient unless there is something - * ensuring that the file cannot be closed. - * - * PUBLIC: int __dbreg_get_name __P((DB_ENV *, u_int8_t *, char **)); - */ -int -__dbreg_get_name(dbenv, fid, namep) - DB_ENV *dbenv; - u_int8_t *fid; - char **namep; -{ - DB_LOG *dblp; - FNAME *fnp; - - dblp = dbenv->lg_handle; - - if (dblp != NULL && __dbreg_fid_to_fname(dblp, fid, 0, &fnp) == 0) { - *namep = R_ADDR(&dblp->reginfo, fnp->name_off); - return (0); - } - - return (-1); -} - -/* - * __dbreg_do_open -- - * Open files referenced in the log. This is the part of the open that - * is not protected by the thread mutex. - * PUBLIC: int __dbreg_do_open __P((DB_ENV *, DB_TXN *, DB_LOG *, u_int8_t *, - * PUBLIC: char *, DBTYPE, int32_t, db_pgno_t, void *, u_int32_t, - * PUBLIC: u_int32_t)); - */ -int -__dbreg_do_open(dbenv, - txn, lp, uid, name, ftype, ndx, meta_pgno, info, id, opcode) - DB_ENV *dbenv; - DB_TXN *txn; - DB_LOG *lp; - u_int8_t *uid; - char *name; - DBTYPE ftype; - int32_t ndx; - db_pgno_t meta_pgno; - void *info; - u_int32_t id, opcode; -{ - DB *dbp; - u_int32_t cstat, ret_stat; - int ret; - char *dname, *fname; - - cstat = TXN_EXPECTED; - fname = name; - dname = NULL; - if ((ret = db_create(&dbp, lp->dbenv, 0)) != 0) - return (ret); - - /* - * We can open files under a number of different scenarios. - * First, we can open a file during a normal txn_abort, if that file - * was opened and closed during the transaction (as is the master - * database of a sub-database). - * Second, we might be aborting a transaction in XA and not have - * it open in the process that is actually doing the abort. - * Third, we might be in recovery. - * In case 3, there is no locking, so there is no issue. - * In cases 1 and 2, we are guaranteed to already hold any locks - * that we need, since we're still in the same transaction, so by - * setting DB_AM_RECOVER, we guarantee that we don't log and that - * we don't try to acquire locks on behalf of a different locker id. - */ - F_SET(dbp, DB_AM_RECOVER); - if (meta_pgno != PGNO_BASE_MD) { - memcpy(dbp->fileid, uid, DB_FILE_ID_LEN); - dbp->meta_pgno = meta_pgno; - } - if (opcode == DBREG_PREOPEN) { - dbp->type = ftype; - if ((ret = __dbreg_setup(dbp, name, id)) != 0) - goto err; - MAKE_INMEM(dbp); - goto skip_open; - } - - if (opcode == DBREG_REOPEN) { - MAKE_INMEM(dbp); - fname = NULL; - dname = name; - } - - if ((ret = __db_open(dbp, txn, fname, dname, ftype, - DB_DURABLE_UNKNOWN | DB_ODDFILESIZE, - __db_omode(OWNER_RW), meta_pgno)) == 0) { -skip_open: - /* - * Verify that we are opening the same file that we were - * referring to when we wrote this log record. - */ - if ((meta_pgno != PGNO_BASE_MD && - __dbreg_check_master(dbenv, uid, name) != 0) || - memcmp(uid, dbp->fileid, DB_FILE_ID_LEN) != 0) - cstat = TXN_UNEXPECTED; - else - cstat = TXN_EXPECTED; - - /* Assign the specific dbreg id to this dbp. */ - if ((ret = __dbreg_assign_id(dbp, ndx)) != 0) - goto err; - - /* - * If we successfully opened this file, then we need to - * convey that information to the txnlist so that we - * know how to handle the subtransaction that created - * the file system object. - */ - if (id != TXN_INVALID) - ret = __db_txnlist_update(dbenv, - info, id, cstat, NULL, &ret_stat, 1); - -err: if (cstat == TXN_UNEXPECTED) - goto not_right; - return (ret); - } else if (ret == ENOENT) { - /* Record that the open failed in the txnlist. */ - if (id != TXN_INVALID) - ret = __db_txnlist_update(dbenv, info, - id, TXN_UNEXPECTED, NULL, &ret_stat, 1); - } -not_right: - (void)__db_close(dbp, NULL, DB_NOSYNC); - /* Add this file as deleted. */ - (void)__dbreg_add_dbentry(dbenv, lp, NULL, ndx); - return (ret); -} - -static int -__dbreg_check_master(dbenv, uid, name) - DB_ENV *dbenv; - u_int8_t *uid; - char *name; -{ - DB *dbp; - int ret; - - ret = 0; - if ((ret = db_create(&dbp, dbenv, 0)) != 0) - return (ret); - F_SET(dbp, DB_AM_RECOVER); - ret = __db_open(dbp, NULL, - name, NULL, DB_BTREE, 0, __db_omode(OWNER_RW), PGNO_BASE_MD); - - if (ret == 0 && memcmp(uid, dbp->fileid, DB_FILE_ID_LEN) != 0) - ret = EINVAL; - - (void)__db_close(dbp, NULL, 0); - return (ret); -} - -/* - * __dbreg_lazy_id -- - * When a replication client gets upgraded to being a replication master, - * it may have database handles open that have not been assigned an ID, but - * which have become legal to use for logging. - * - * This function lazily allocates a new ID for such a function, in a - * new transaction created for the purpose. We need to do this in a new - * transaction because we definitely wish to commit the dbreg_register, but - * at this point we have no way of knowing whether the log record that incited - * us to call this will be part of a committed transaction. - * - * PUBLIC: int __dbreg_lazy_id __P((DB *)); - */ -int -__dbreg_lazy_id(dbp) - DB *dbp; -{ - DB_ENV *dbenv; - DB_LOG *dblp; - DB_TXN *txn; - FNAME *fnp; - LOG *lp; - int32_t id; - int ret; - - dbenv = dbp->dbenv; - - DB_ASSERT(IS_REP_MASTER(dbenv)); - - dbenv = dbp->dbenv; - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - fnp = dbp->log_filename; - - /* The mtx_filelist protects the FNAME list and id management. */ - MUTEX_LOCK(dbenv, lp->mtx_filelist); - if (fnp->id != DB_LOGFILEID_INVALID) { - MUTEX_UNLOCK(dbenv, lp->mtx_filelist); - return (0); - } - id = DB_LOGFILEID_INVALID; - if ((ret = __txn_begin(dbenv, NULL, &txn, 0)) != 0) - goto err; - - if ((ret = __dbreg_get_id(dbp, txn, &id)) != 0) { - (void)__txn_abort(txn); - goto err; - } - - if ((ret = __txn_commit(txn, DB_TXN_NOSYNC)) != 0) - goto err; - - /* - * All DB related logging routines check the id value *without* - * holding the mtx_filelist to know whether we need to call - * dbreg_lazy_id to begin with. We must set the ID after a - * *successful* commit so that there is no possibility of a second - * modification call finding a valid ID in the dbp before the - * dbreg_register and commit records are in the log. - * If there was an error, then we call __dbreg_revoke_id to - * remove the entry from the lists. - */ - fnp->id = id; -err: - if (ret != 0 && id != DB_LOGFILEID_INVALID) - (void)__dbreg_revoke_id(dbp, 1, id); - MUTEX_UNLOCK(dbenv, lp->mtx_filelist); - return (ret); -} diff --git a/storage/bdb/dist/Makefile.in b/storage/bdb/dist/Makefile.in deleted file mode 100644 index abd7dd93b17..00000000000 --- a/storage/bdb/dist/Makefile.in +++ /dev/null @@ -1,1919 +0,0 @@ -# $Id: Makefile.in,v 12.33 2005/11/03 17:43:46 bostic Exp $ - -srcdir= @srcdir@/.. -builddir=. - -################################################## -# Installation directories and permissions. -################################################## -prefix= @prefix@ -exec_prefix=@exec_prefix@ -bindir= @bindir@ -includedir=@includedir@ -libdir= @libdir@ -docdir= $(prefix)/docs - -dmode= 755 -emode= 555 -fmode= 444 - -transform=@program_transform_name@ - -################################################## -# Paths for standard user-level commands. -################################################## -SHELL= @db_cv_path_sh@ -ar= @db_cv_path_ar@ -chmod= @db_cv_path_chmod@ -cp= @db_cv_path_cp@ -ln= @db_cv_path_ln@ -mkdir= @db_cv_path_mkdir@ -ranlib= @db_cv_path_ranlib@ -rm= @db_cv_path_rm@ -strip= @db_cv_path_strip@ - -################################################## -# General library information. -################################################## -DEF_LIB= @DEFAULT_LIB@ -DEF_LIB_CXX= @DEFAULT_LIB_CXX@ -INSTALLER= @INSTALLER@ -LIBTOOL= @LIBTOOL@ - -POSTLINK= @POSTLINK@ -SOLINK= @MAKEFILE_SOLINK@ -SOFLAGS= @SOFLAGS@ -LIBMAJOR= @DB_VERSION_MAJOR@ -LIBVERSION= @DB_VERSION_MAJOR@.@DB_VERSION_MINOR@ - -CPPFLAGS= -I$(builddir) -I$(srcdir) @CPPFLAGS@ - -################################################## -# C API. -################################################## -CFLAGS= -c $(CPPFLAGS) @CFLAGS@ -CC= @MAKEFILE_CC@ -CCLINK= @MAKEFILE_CCLINK@ @CFLAGS@ - -LDFLAGS= @LDFLAGS@ -LIBS= @LIBS@ -TEST_LIBS= @TEST_LIBS@ -LIBCSO_LIBS= @LIBCSO_LIBS@ @LIBSO_LIBS@ - -libdb_base= libdb -libdb= $(libdb_base).a -libdb_version= $(libdb_base)-$(LIBVERSION).a -libso= $(libdb_base)-$(LIBVERSION)@SOSUFFIX@ -libso_target= $(libdb_base)-$(LIBVERSION).la -libso_default= $(libdb_base)@SOSUFFIX@ -libso_major= $(libdb_base)-$(LIBMAJOR)@SOSUFFIX@ - -################################################## -# C++ API. -# -# C++ support is optional, and can be built with static or shared libraries. -################################################## -CXXFLAGS= -c $(CPPFLAGS) @CXXFLAGS@ -CXX= @MAKEFILE_CXX@ -CXXLINK= @MAKEFILE_CXXLINK@ @CXXFLAGS@ -XSOLINK= @MAKEFILE_XSOLINK@ @CXXFLAGS@ -LIBXSO_LIBS= @LIBXSO_LIBS@ @LIBSO_LIBS@ - -libcxx_base= libdb_cxx -libcxx= $(libcxx_base).a -libcxx_version= $(libcxx_base)-$(LIBVERSION).a -libxso= $(libcxx_base)-$(LIBVERSION)@SOSUFFIX@ -libxso_target= $(libcxx_base)-$(LIBVERSION).la -libxso_default= $(libcxx_base)@SOSUFFIX@ -libxso_major= $(libcxx_base)-$(LIBMAJOR)@SOSUFFIX@ - -################################################## -# Java API. -# -# Java support is optional and requires shared librarires. -################################################## -CLASSPATH= $(JAVA_CLASSTOP) -LIBJSO_LIBS= @LIBJSO_LIBS@ @LIBSO_LIBS@ - -JAR= @JAR@ -JAVAC= env CLASSPATH="$(CLASSPATH)" @JAVAC@ -JAVACFLAGS= @JAVACFLAGS@ -JAVA_CLASSTOP= ./classes -JAVA_RPCCLASSTOP=./classes.rpc -JAVA_EXCLASSTOP=./classes.ex -JAVA_RPCREL= com/sleepycat/db/rpcserver -JAVA_SRCDIR= $(srcdir)/java/src -JAVA_EXDIR= $(srcdir)/examples_java/src -JAVA_RPCDIR= $(srcdir)/rpc_server/java -JAVA_SLEEPYCAT= $(srcdir)/java/src/com/sleepycat - -libj_jarfile= db.jar -libj_exjarfile= dbexamples.jar -rpc_jarfile= dbsvc.jar -libjso_base= libdb_java -libjso= $(libjso_base)-$(LIBVERSION)@JMODSUFFIX@ -libjso_static= $(libjso_base)-$(LIBVERSION).a -libjso_target= $(libjso_base)-$(LIBVERSION).la -libjso_default= $(libjso_base)@JMODSUFFIX@ -libjso_major= $(libjso_base)-$(LIBMAJOR)@JMODSUFFIX@ -libjso_g= $(libjso_base)-$(LIBVERSION)_g@JMODSUFFIX@ - -################################################## -# TCL API. -# -# Tcl support is optional and requires shared libraries. -################################################## -TCL_INCLUDE_SPEC= @TCL_INCLUDE_SPEC@ -LIBTSO_LIBS= @LIBTSO_LIBS@ @LIBSO_LIBS@ -libtso_base= libdb_tcl -libtso= $(libtso_base)-$(LIBVERSION)@MODSUFFIX@ -libtso_static= $(libtso_base)-$(LIBVERSION).a -libtso_target= $(libtso_base)-$(LIBVERSION).la -libtso_default= $(libtso_base)@MODSUFFIX@ -libtso_major= $(libtso_base)-$(LIBMAJOR)@MODSUFFIX@ - -################################################## -# db_dump185 UTILITY -# -# The db_dump185 application should be compiled using the system's db.h file -# (which should be a DB 1.85/1.86 include file), and the system's 1.85/1.86 -# object library. To include the right db.h, don't include -I$(builddir) on -# the compile line. You may also need to add a local include directory and -# local libraries, for example. Do that by adding -I options to the DB185INC -# line, and -l options to the DB185LIB line. -################################################## -DB185INC= -c @CFLAGS@ -I$(srcdir) @CPPFLAGS@ -DB185LIB= - -################################################## -# NOTHING BELOW THIS LINE SHOULD EVER NEED TO BE MODIFIED. -################################################## - -################################################## -# Object and utility lists. -################################################## -BTREE_OBJS=\ - bt_compare@o@ bt_conv@o@ bt_curadj@o@ bt_cursor@o@ bt_delete@o@ \ - bt_method@o@ bt_open@o@ bt_put@o@ bt_rec@o@ bt_reclaim@o@ \ - bt_recno@o@ bt_rsearch@o@ bt_search@o@ bt_split@o@ bt_stat@o@ \ - bt_compact@o@ bt_upgrade@o@ btree_auto@o@ -BTREE_VRFY_OBJS=\ - db_ovfl_vrfy@o@ db_vrfy@o@ db_vrfyutil@o@ bt_verify@o@ -HASH_OBJS=\ - hash@o@ hash_auto@o@ hash_conv@o@ hash_dup@o@ hash_meta@o@ \ - hash_method@o@ hash_open@o@ hash_page@o@ hash_rec@o@ \ - hash_reclaim@o@ hash_stat@o@ hash_upgrade@o@ -HASH_VRFY_OBJS=\ - hash_verify@o@ -QUEUE_OBJS=\ - qam@o@ qam_auto@o@ qam_conv@o@ qam_files@o@ qam_method@o@ \ - qam_open@o@ qam_rec@o@ qam_stat@o@ qam_upgrade@o@ -QUEUE_VRFY_OBJS=\ - qam_verify@o@ -REP_OBJS=\ - rep_auto@o@ rep_backup@o@ rep_elect@o@ rep_log@o@ rep_method@o@ \ - rep_record@o@ rep_region@o@ rep_stat@o@ rep_util@o@ rep_verify@o@ -PRINT_OBJS=\ - btree_autop@o@ crdel_autop@o@ db_autop@o@ dbreg_autop@o@ \ - fileops_autop@o@ hash_autop@o@ qam_autop@o@ rep_autop@o@ \ - txn_autop@o@ - -C_OBJS= @ADDITIONAL_OBJS@ @REPLACEMENT_OBJS@ @CRYPTO_OBJS@ @RPC_CLIENT_OBJS@ \ - crdel_auto@o@ crdel_rec@o@ db@o@ db_am@o@ db_auto@o@ \ - db_byteorder@o@ db_cam@o@ db_clock@o@ db_conv@o@ db_dispatch@o@ \ - db_dup@o@ db_err@o@ db_getlong@o@ db_idspace@o@ db_iface@o@ \ - db_join@o@ db_log2@o@ db_meta@o@ db_method@o@ db_open@o@ \ - db_overflow@o@ db_pr@o@ db_rec@o@ db_reclaim@o@ db_rename@o@ \ - db_remove@o@ db_ret@o@ db_salloc@o@ db_setid@o@ db_setlsn@o@ \ - db_shash@o@ db_stati@o@ db_truncate@o@ db_upg@o@ db_upg_opd@o@ \ - dbm@o@ dbreg@o@ dbreg_auto@o@ dbreg_rec@o@ dbreg_stat@o@ \ - dbreg_util@o@ env_failchk@o@ env_file@o@ env_method@o@ \ - env_open@o@ env_recover@o@ env_region@o@ env_register@o@ \ - env_stat@o@ fileops_auto@o@ fop_basic@o@ fop_rec@o@ fop_util@o@ \ - hash_func@o@ hmac@o@ hsearch@o@ lock@o@ lock_deadlock@o@ \ - lock_failchk@o@ lock_id@o@ lock_list@o@ lock_method@o@ \ - lock_region@o@ lock_stat@o@ lock_timer@o@ lock_util@o@ log@o@ \ - log_archive@o@ log_compare@o@ log_debug@o@ log_get@o@ log_method@o@ \ - log_put@o@ log_stat@o@ mp_alloc@o@ mp_bh@o@ mp_fget@o@ \ - mp_fmethod@o@ mp_fopen@o@ mp_fput@o@ mp_fset@o@ mp_method@o@ \ - mp_region@o@ mp_register@o@ mp_stat@o@ mp_sync@o@ mp_trickle@o@ \ - mut_alloc@o@ mut_method@o@ mut_region@o@ \ - mut_stat@o@ os_abs@o@ os_alloc@o@ os_clock@o@ os_config@o@ \ - os_dir@o@ os_errno@o@ os_fid@o@ os_flock@o@ os_fsync@o@ \ - os_handle@o@ os_id@o@ os_map@o@ os_method@o@ os_mkdir@o@ \ - os_oflags@o@ os_open@o@ os_region@o@ os_rename@o@ os_root@o@ \ - os_rpath@o@ os_rw@o@ os_seek@o@ os_sleep@o@ os_spin@o@ \ - os_stat@o@ os_tmpdir@o@ os_truncate@o@ os_unlink@o@ sha1@o@ \ - seq_stat@o@ sequence@o@ snprintf@o@ txn@o@ txn_auto@o@ \ - txn_chkpt@o@ txn_failchk@o@ txn_method@o@ txn_rec@o@ \ - txn_recover@o@ txn_region@o@ txn_stat@o@ txn_util@o@ xa@o@ \ - xa_db@o@ xa_map@o@ - -CXX_OBJS=\ - cxx_db@o@ cxx_dbc@o@ cxx_dbt@o@ cxx_env@o@ cxx_except@o@ cxx_lock@o@ \ - cxx_logc@o@ cxx_mpool@o@ cxx_multi@o@ cxx_seq@o@ cxx_txn@o@ - -CRYPTO_OBJS=\ - aes_method@o@ crypto@o@ mt19937db@o@ rijndael-alg-fst@o@ \ - rijndael-api-fst@o@ - -JAVA_OBJS=\ - db_java_wrap@o@ - -JAVA_DBSRCS=\ - $(JAVA_SLEEPYCAT)/bind/ByteArrayBinding.java \ - $(JAVA_SLEEPYCAT)/bind/EntityBinding.java \ - $(JAVA_SLEEPYCAT)/bind/EntryBinding.java \ - $(JAVA_SLEEPYCAT)/bind/RecordNumberBinding.java \ - $(JAVA_SLEEPYCAT)/bind/serial/ClassCatalog.java \ - $(JAVA_SLEEPYCAT)/bind/serial/SerialBase.java \ - $(JAVA_SLEEPYCAT)/bind/serial/SerialBinding.java \ - $(JAVA_SLEEPYCAT)/bind/serial/SerialInput.java \ - $(JAVA_SLEEPYCAT)/bind/serial/SerialOutput.java \ - $(JAVA_SLEEPYCAT)/bind/serial/SerialSerialBinding.java \ - $(JAVA_SLEEPYCAT)/bind/serial/SerialSerialKeyCreator.java \ - $(JAVA_SLEEPYCAT)/bind/serial/StoredClassCatalog.java \ - $(JAVA_SLEEPYCAT)/bind/serial/TupleSerialBinding.java \ - $(JAVA_SLEEPYCAT)/bind/serial/TupleSerialKeyCreator.java \ - $(JAVA_SLEEPYCAT)/bind/serial/TupleSerialMarshalledBinding.java \ - $(JAVA_SLEEPYCAT)/bind/serial/TupleSerialMarshalledKeyCreator.java \ - $(JAVA_SLEEPYCAT)/bind/tuple/BooleanBinding.java \ - $(JAVA_SLEEPYCAT)/bind/tuple/ByteBinding.java \ - $(JAVA_SLEEPYCAT)/bind/tuple/CharacterBinding.java \ - $(JAVA_SLEEPYCAT)/bind/tuple/DoubleBinding.java \ - $(JAVA_SLEEPYCAT)/bind/tuple/FloatBinding.java \ - $(JAVA_SLEEPYCAT)/bind/tuple/IntegerBinding.java \ - $(JAVA_SLEEPYCAT)/bind/tuple/LongBinding.java \ - $(JAVA_SLEEPYCAT)/bind/tuple/MarshalledTupleEntry.java \ - $(JAVA_SLEEPYCAT)/bind/tuple/MarshalledTupleKeyEntity.java \ - $(JAVA_SLEEPYCAT)/bind/tuple/ShortBinding.java \ - $(JAVA_SLEEPYCAT)/bind/tuple/StringBinding.java \ - $(JAVA_SLEEPYCAT)/bind/tuple/TupleBase.java \ - $(JAVA_SLEEPYCAT)/bind/tuple/TupleBinding.java \ - $(JAVA_SLEEPYCAT)/bind/tuple/TupleInput.java \ - $(JAVA_SLEEPYCAT)/bind/tuple/TupleInputBinding.java \ - $(JAVA_SLEEPYCAT)/bind/tuple/TupleMarshalledBinding.java \ - $(JAVA_SLEEPYCAT)/bind/tuple/TupleOutput.java \ - $(JAVA_SLEEPYCAT)/bind/tuple/TupleTupleBinding.java \ - $(JAVA_SLEEPYCAT)/bind/tuple/TupleTupleKeyCreator.java \ - $(JAVA_SLEEPYCAT)/bind/tuple/TupleTupleMarshalledBinding.java \ - $(JAVA_SLEEPYCAT)/bind/tuple/TupleTupleMarshalledKeyCreator.java \ - $(JAVA_SLEEPYCAT)/collections/CurrentTransaction.java \ - $(JAVA_SLEEPYCAT)/collections/DataCursor.java \ - $(JAVA_SLEEPYCAT)/collections/DataView.java \ - $(JAVA_SLEEPYCAT)/collections/KeyRange.java \ - $(JAVA_SLEEPYCAT)/collections/KeyRangeException.java \ - $(JAVA_SLEEPYCAT)/collections/MapEntryParameter.java \ - $(JAVA_SLEEPYCAT)/collections/PrimaryKeyAssigner.java \ - $(JAVA_SLEEPYCAT)/collections/RangeCursor.java \ - $(JAVA_SLEEPYCAT)/collections/StoredCollection.java \ - $(JAVA_SLEEPYCAT)/collections/StoredCollections.java \ - $(JAVA_SLEEPYCAT)/collections/StoredContainer.java \ - $(JAVA_SLEEPYCAT)/collections/StoredEntrySet.java \ - $(JAVA_SLEEPYCAT)/collections/StoredIterator.java \ - $(JAVA_SLEEPYCAT)/collections/StoredKeySet.java \ - $(JAVA_SLEEPYCAT)/collections/StoredList.java \ - $(JAVA_SLEEPYCAT)/collections/StoredMap.java \ - $(JAVA_SLEEPYCAT)/collections/StoredMapEntry.java \ - $(JAVA_SLEEPYCAT)/collections/StoredSortedEntrySet.java \ - $(JAVA_SLEEPYCAT)/collections/StoredSortedKeySet.java \ - $(JAVA_SLEEPYCAT)/collections/StoredSortedMap.java \ - $(JAVA_SLEEPYCAT)/collections/StoredSortedValueSet.java \ - $(JAVA_SLEEPYCAT)/collections/StoredValueSet.java \ - $(JAVA_SLEEPYCAT)/collections/TransactionRunner.java \ - $(JAVA_SLEEPYCAT)/collections/TransactionWorker.java \ - $(JAVA_SLEEPYCAT)/collections/TupleSerialFactory.java \ - $(JAVA_SLEEPYCAT)/compat/DbCompat.java \ - $(JAVA_SLEEPYCAT)/db/BtreePrefixCalculator.java \ - $(JAVA_SLEEPYCAT)/db/BtreeStats.java \ - $(JAVA_SLEEPYCAT)/db/CacheFile.java \ - $(JAVA_SLEEPYCAT)/db/CacheFilePriority.java \ - $(JAVA_SLEEPYCAT)/db/CacheFileStats.java \ - $(JAVA_SLEEPYCAT)/db/CacheStats.java \ - $(JAVA_SLEEPYCAT)/db/CheckpointConfig.java \ - $(JAVA_SLEEPYCAT)/db/CompactConfig.java \ - $(JAVA_SLEEPYCAT)/db/CompactStats.java \ - $(JAVA_SLEEPYCAT)/db/Cursor.java \ - $(JAVA_SLEEPYCAT)/db/CursorConfig.java \ - $(JAVA_SLEEPYCAT)/db/Database.java \ - $(JAVA_SLEEPYCAT)/db/DatabaseConfig.java \ - $(JAVA_SLEEPYCAT)/db/DatabaseEntry.java \ - $(JAVA_SLEEPYCAT)/db/DatabaseException.java \ - $(JAVA_SLEEPYCAT)/db/DatabaseStats.java \ - $(JAVA_SLEEPYCAT)/db/DatabaseType.java \ - $(JAVA_SLEEPYCAT)/db/DeadlockException.java \ - $(JAVA_SLEEPYCAT)/db/Environment.java \ - $(JAVA_SLEEPYCAT)/db/EnvironmentConfig.java \ - $(JAVA_SLEEPYCAT)/db/ErrorHandler.java \ - $(JAVA_SLEEPYCAT)/db/FeedbackHandler.java \ - $(JAVA_SLEEPYCAT)/db/HashStats.java \ - $(JAVA_SLEEPYCAT)/db/Hasher.java \ - $(JAVA_SLEEPYCAT)/db/JoinConfig.java \ - $(JAVA_SLEEPYCAT)/db/JoinCursor.java \ - $(JAVA_SLEEPYCAT)/db/KeyRange.java \ - $(JAVA_SLEEPYCAT)/db/Lock.java \ - $(JAVA_SLEEPYCAT)/db/LockDetectMode.java \ - $(JAVA_SLEEPYCAT)/db/LockMode.java \ - $(JAVA_SLEEPYCAT)/db/LockNotGrantedException.java \ - $(JAVA_SLEEPYCAT)/db/LockOperation.java \ - $(JAVA_SLEEPYCAT)/db/LockRequest.java \ - $(JAVA_SLEEPYCAT)/db/LockRequestMode.java \ - $(JAVA_SLEEPYCAT)/db/LockStats.java \ - $(JAVA_SLEEPYCAT)/db/LogCursor.java \ - $(JAVA_SLEEPYCAT)/db/LogRecordHandler.java \ - $(JAVA_SLEEPYCAT)/db/LogSequenceNumber.java \ - $(JAVA_SLEEPYCAT)/db/LogStats.java \ - $(JAVA_SLEEPYCAT)/db/MemoryException.java \ - $(JAVA_SLEEPYCAT)/db/MessageHandler.java \ - $(JAVA_SLEEPYCAT)/db/MultipleDataEntry.java \ - $(JAVA_SLEEPYCAT)/db/MultipleEntry.java \ - $(JAVA_SLEEPYCAT)/db/MultipleKeyDataEntry.java \ - $(JAVA_SLEEPYCAT)/db/MultipleRecnoDataEntry.java \ - $(JAVA_SLEEPYCAT)/db/MutexStats.java \ - $(JAVA_SLEEPYCAT)/db/OperationStatus.java \ - $(JAVA_SLEEPYCAT)/db/PanicHandler.java \ - $(JAVA_SLEEPYCAT)/db/PreparedTransaction.java \ - $(JAVA_SLEEPYCAT)/db/QueueStats.java \ - $(JAVA_SLEEPYCAT)/db/RecordNumberAppender.java \ - $(JAVA_SLEEPYCAT)/db/RecoveryOperation.java \ - $(JAVA_SLEEPYCAT)/db/ReplicationConfig.java \ - $(JAVA_SLEEPYCAT)/db/ReplicationDuplicateMasterException.java \ - $(JAVA_SLEEPYCAT)/db/ReplicationHandleDeadException.java \ - $(JAVA_SLEEPYCAT)/db/ReplicationHoldElectionException.java \ - $(JAVA_SLEEPYCAT)/db/ReplicationJoinFailureException.java \ - $(JAVA_SLEEPYCAT)/db/ReplicationLockoutException.java \ - $(JAVA_SLEEPYCAT)/db/ReplicationSiteUnavailableException.java \ - $(JAVA_SLEEPYCAT)/db/ReplicationStats.java \ - $(JAVA_SLEEPYCAT)/db/ReplicationStatus.java \ - $(JAVA_SLEEPYCAT)/db/ReplicationTransport.java \ - $(JAVA_SLEEPYCAT)/db/RunRecoveryException.java \ - $(JAVA_SLEEPYCAT)/db/SecondaryConfig.java \ - $(JAVA_SLEEPYCAT)/db/SecondaryCursor.java \ - $(JAVA_SLEEPYCAT)/db/SecondaryDatabase.java \ - $(JAVA_SLEEPYCAT)/db/SecondaryKeyCreator.java \ - $(JAVA_SLEEPYCAT)/db/Sequence.java \ - $(JAVA_SLEEPYCAT)/db/SequenceConfig.java \ - $(JAVA_SLEEPYCAT)/db/SequenceStats.java \ - $(JAVA_SLEEPYCAT)/db/StatsConfig.java \ - $(JAVA_SLEEPYCAT)/db/Transaction.java \ - $(JAVA_SLEEPYCAT)/db/TransactionConfig.java \ - $(JAVA_SLEEPYCAT)/db/TransactionStats.java \ - $(JAVA_SLEEPYCAT)/db/VerifyConfig.java \ - $(JAVA_SLEEPYCAT)/db/VersionMismatchException.java \ - $(JAVA_SLEEPYCAT)/db/internal/Db.java \ - $(JAVA_SLEEPYCAT)/db/internal/DbClient.java \ - $(JAVA_SLEEPYCAT)/db/internal/DbConstants.java \ - $(JAVA_SLEEPYCAT)/db/internal/DbEnv.java \ - $(JAVA_SLEEPYCAT)/db/internal/DbLock.java \ - $(JAVA_SLEEPYCAT)/db/internal/DbLogc.java \ - $(JAVA_SLEEPYCAT)/db/internal/DbMpoolFile.java \ - $(JAVA_SLEEPYCAT)/db/internal/DbSequence.java \ - $(JAVA_SLEEPYCAT)/db/internal/DbTxn.java \ - $(JAVA_SLEEPYCAT)/db/internal/DbUtil.java \ - $(JAVA_SLEEPYCAT)/db/internal/Dbc.java \ - $(JAVA_SLEEPYCAT)/db/internal/db_java.java \ - $(JAVA_SLEEPYCAT)/db/internal/db_javaJNI.java \ - $(JAVA_SLEEPYCAT)/util/ExceptionUnwrapper.java \ - $(JAVA_SLEEPYCAT)/util/ExceptionWrapper.java \ - $(JAVA_SLEEPYCAT)/util/FastInputStream.java \ - $(JAVA_SLEEPYCAT)/util/FastOutputStream.java \ - $(JAVA_SLEEPYCAT)/util/IOExceptionWrapper.java \ - $(JAVA_SLEEPYCAT)/util/RuntimeExceptionWrapper.java \ - $(JAVA_SLEEPYCAT)/util/UtfOps.java - -JAVA_EXSRCS=\ - $(JAVA_EXDIR)/collections/access/AccessExample.java \ - $(JAVA_EXDIR)/collections/hello/HelloDatabaseWorld.java \ - $(JAVA_EXDIR)/collections/ship/basic/PartData.java \ - $(JAVA_EXDIR)/collections/ship/basic/PartKey.java \ - $(JAVA_EXDIR)/collections/ship/basic/Sample.java \ - $(JAVA_EXDIR)/collections/ship/basic/SampleDatabase.java \ - $(JAVA_EXDIR)/collections/ship/basic/SampleViews.java \ - $(JAVA_EXDIR)/collections/ship/basic/ShipmentData.java \ - $(JAVA_EXDIR)/collections/ship/basic/ShipmentKey.java \ - $(JAVA_EXDIR)/collections/ship/basic/SupplierData.java \ - $(JAVA_EXDIR)/collections/ship/basic/SupplierKey.java \ - $(JAVA_EXDIR)/collections/ship/basic/Weight.java \ - $(JAVA_EXDIR)/collections/ship/entity/Part.java \ - $(JAVA_EXDIR)/collections/ship/entity/PartData.java \ - $(JAVA_EXDIR)/collections/ship/entity/PartKey.java \ - $(JAVA_EXDIR)/collections/ship/entity/Sample.java \ - $(JAVA_EXDIR)/collections/ship/entity/SampleDatabase.java \ - $(JAVA_EXDIR)/collections/ship/entity/SampleViews.java \ - $(JAVA_EXDIR)/collections/ship/entity/Shipment.java \ - $(JAVA_EXDIR)/collections/ship/entity/ShipmentData.java \ - $(JAVA_EXDIR)/collections/ship/entity/ShipmentKey.java \ - $(JAVA_EXDIR)/collections/ship/entity/Supplier.java \ - $(JAVA_EXDIR)/collections/ship/entity/SupplierData.java \ - $(JAVA_EXDIR)/collections/ship/entity/SupplierKey.java \ - $(JAVA_EXDIR)/collections/ship/entity/Weight.java \ - $(JAVA_EXDIR)/collections/ship/factory/Part.java \ - $(JAVA_EXDIR)/collections/ship/factory/PartKey.java \ - $(JAVA_EXDIR)/collections/ship/factory/Sample.java \ - $(JAVA_EXDIR)/collections/ship/factory/SampleDatabase.java \ - $(JAVA_EXDIR)/collections/ship/factory/SampleViews.java \ - $(JAVA_EXDIR)/collections/ship/factory/Shipment.java \ - $(JAVA_EXDIR)/collections/ship/factory/ShipmentKey.java \ - $(JAVA_EXDIR)/collections/ship/factory/Supplier.java \ - $(JAVA_EXDIR)/collections/ship/factory/SupplierKey.java \ - $(JAVA_EXDIR)/collections/ship/factory/Weight.java \ - $(JAVA_EXDIR)/collections/ship/index/PartData.java \ - $(JAVA_EXDIR)/collections/ship/index/PartKey.java \ - $(JAVA_EXDIR)/collections/ship/index/Sample.java \ - $(JAVA_EXDIR)/collections/ship/index/SampleDatabase.java \ - $(JAVA_EXDIR)/collections/ship/index/SampleViews.java \ - $(JAVA_EXDIR)/collections/ship/index/ShipmentData.java \ - $(JAVA_EXDIR)/collections/ship/index/ShipmentKey.java \ - $(JAVA_EXDIR)/collections/ship/index/SupplierData.java \ - $(JAVA_EXDIR)/collections/ship/index/SupplierKey.java \ - $(JAVA_EXDIR)/collections/ship/index/Weight.java \ - $(JAVA_EXDIR)/collections/ship/marshal/MarshalledEnt.java \ - $(JAVA_EXDIR)/collections/ship/marshal/MarshalledKey.java \ - $(JAVA_EXDIR)/collections/ship/marshal/Part.java \ - $(JAVA_EXDIR)/collections/ship/marshal/PartKey.java \ - $(JAVA_EXDIR)/collections/ship/marshal/Sample.java \ - $(JAVA_EXDIR)/collections/ship/marshal/SampleDatabase.java \ - $(JAVA_EXDIR)/collections/ship/marshal/SampleViews.java \ - $(JAVA_EXDIR)/collections/ship/marshal/Shipment.java \ - $(JAVA_EXDIR)/collections/ship/marshal/ShipmentKey.java \ - $(JAVA_EXDIR)/collections/ship/marshal/Supplier.java \ - $(JAVA_EXDIR)/collections/ship/marshal/SupplierKey.java \ - $(JAVA_EXDIR)/collections/ship/marshal/Weight.java \ - $(JAVA_EXDIR)/collections/ship/sentity/Part.java \ - $(JAVA_EXDIR)/collections/ship/sentity/PartKey.java \ - $(JAVA_EXDIR)/collections/ship/sentity/Sample.java \ - $(JAVA_EXDIR)/collections/ship/sentity/SampleDatabase.java \ - $(JAVA_EXDIR)/collections/ship/sentity/SampleViews.java \ - $(JAVA_EXDIR)/collections/ship/sentity/Shipment.java \ - $(JAVA_EXDIR)/collections/ship/sentity/ShipmentKey.java \ - $(JAVA_EXDIR)/collections/ship/sentity/Supplier.java \ - $(JAVA_EXDIR)/collections/ship/sentity/SupplierKey.java \ - $(JAVA_EXDIR)/collections/ship/sentity/Weight.java \ - $(JAVA_EXDIR)/collections/ship/tuple/Part.java \ - $(JAVA_EXDIR)/collections/ship/tuple/PartData.java \ - $(JAVA_EXDIR)/collections/ship/tuple/PartKey.java \ - $(JAVA_EXDIR)/collections/ship/tuple/Sample.java \ - $(JAVA_EXDIR)/collections/ship/tuple/SampleDatabase.java \ - $(JAVA_EXDIR)/collections/ship/tuple/SampleViews.java \ - $(JAVA_EXDIR)/collections/ship/tuple/Shipment.java \ - $(JAVA_EXDIR)/collections/ship/tuple/ShipmentData.java \ - $(JAVA_EXDIR)/collections/ship/tuple/ShipmentKey.java \ - $(JAVA_EXDIR)/collections/ship/tuple/Supplier.java \ - $(JAVA_EXDIR)/collections/ship/tuple/SupplierData.java \ - $(JAVA_EXDIR)/collections/ship/tuple/SupplierKey.java \ - $(JAVA_EXDIR)/collections/ship/tuple/Weight.java \ - $(JAVA_EXDIR)/db/AccessExample.java \ - $(JAVA_EXDIR)/db/BtRecExample.java \ - $(JAVA_EXDIR)/db/BulkAccessExample.java \ - $(JAVA_EXDIR)/db/EnvExample.java \ - $(JAVA_EXDIR)/db/GettingStarted/ExampleDatabaseLoad.java \ - $(JAVA_EXDIR)/db/GettingStarted/ExampleDatabaseRead.java \ - $(JAVA_EXDIR)/db/GettingStarted/Inventory.java \ - $(JAVA_EXDIR)/db/GettingStarted/InventoryBinding.java \ - $(JAVA_EXDIR)/db/GettingStarted/ItemNameKeyCreator.java \ - $(JAVA_EXDIR)/db/GettingStarted/MyDbs.java \ - $(JAVA_EXDIR)/db/GettingStarted/Vendor.java \ - $(JAVA_EXDIR)/db/LockExample.java \ - $(JAVA_EXDIR)/db/RPCExample.java \ - $(JAVA_EXDIR)/db/SequenceExample.java \ - $(JAVA_EXDIR)/db/TpcbExample.java \ - $(JAVA_EXDIR)/db/txn/DBWriter.java \ - $(JAVA_EXDIR)/db/txn/PayloadData.java \ - $(JAVA_EXDIR)/db/txn/TxnGuide.java \ - $(JAVA_EXDIR)/db/txn/TxnGuideInMemory.java - -TCL_OBJS=\ - tcl_compat@o@ tcl_db@o@ tcl_db_pkg@o@ tcl_dbcursor@o@ tcl_env@o@ \ - tcl_internal@o@ tcl_lock@o@ tcl_log@o@ tcl_mp@o@ tcl_rep@o@ \ - tcl_seq@o@ tcl_txn@o@ tcl_util@o@ - -RPC_CLIENT_OBJS=\ - client@o@ db_server_clnt@o@ db_server_xdr@o@ gen_client@o@ \ - gen_client_ret@o@ - -RPC_SRV_OBJS=\ - db_server_proc@o@ db_server_svc@o@ db_server_util@o@ \ - gen_db_server@o@ - -RPC_CXXSRV_OBJS=\ - db_server_cxxproc@o@ db_server_cxxutil@o@ db_server_svc@o@ \ - gen_db_server@o@ - -RPC_JAVASRV_SRCS=\ - $(JAVA_RPCDIR)/AssociateCallbacks.java \ - $(JAVA_RPCDIR)/Dispatcher.java \ - $(JAVA_RPCDIR)/FreeList.java \ - $(JAVA_RPCDIR)/JoinCursorAdapter.java \ - $(JAVA_RPCDIR)/LocalIterator.java \ - $(JAVA_RPCDIR)/RpcDb.java \ - $(JAVA_RPCDIR)/RpcDbEnv.java \ - $(JAVA_RPCDIR)/RpcDbTxn.java \ - $(JAVA_RPCDIR)/RpcDbc.java \ - $(JAVA_RPCDIR)/Server.java \ - $(JAVA_RPCDIR)/Timer.java \ - $(JAVA_RPCDIR)/Util.java \ - $(JAVA_RPCDIR)/gen/ServerStubs.java \ - $(JAVA_RPCDIR)/gen/__db_associate_msg.java \ - $(JAVA_RPCDIR)/gen/__db_associate_reply.java \ - $(JAVA_RPCDIR)/gen/__db_close_msg.java \ - $(JAVA_RPCDIR)/gen/__db_close_reply.java \ - $(JAVA_RPCDIR)/gen/__db_create_msg.java \ - $(JAVA_RPCDIR)/gen/__db_create_reply.java \ - $(JAVA_RPCDIR)/gen/__db_cursor_msg.java \ - $(JAVA_RPCDIR)/gen/__db_cursor_reply.java \ - $(JAVA_RPCDIR)/gen/__db_del_msg.java \ - $(JAVA_RPCDIR)/gen/__db_del_reply.java \ - $(JAVA_RPCDIR)/gen/__db_get_bt_minkey_msg.java \ - $(JAVA_RPCDIR)/gen/__db_get_bt_minkey_reply.java \ - $(JAVA_RPCDIR)/gen/__db_get_dbname_msg.java \ - $(JAVA_RPCDIR)/gen/__db_get_dbname_reply.java \ - $(JAVA_RPCDIR)/gen/__db_get_encrypt_flags_msg.java \ - $(JAVA_RPCDIR)/gen/__db_get_encrypt_flags_reply.java \ - $(JAVA_RPCDIR)/gen/__db_get_flags_msg.java \ - $(JAVA_RPCDIR)/gen/__db_get_flags_reply.java \ - $(JAVA_RPCDIR)/gen/__db_get_h_ffactor_msg.java \ - $(JAVA_RPCDIR)/gen/__db_get_h_ffactor_reply.java \ - $(JAVA_RPCDIR)/gen/__db_get_h_nelem_msg.java \ - $(JAVA_RPCDIR)/gen/__db_get_h_nelem_reply.java \ - $(JAVA_RPCDIR)/gen/__db_get_lorder_msg.java \ - $(JAVA_RPCDIR)/gen/__db_get_lorder_reply.java \ - $(JAVA_RPCDIR)/gen/__db_get_msg.java \ - $(JAVA_RPCDIR)/gen/__db_get_open_flags_msg.java \ - $(JAVA_RPCDIR)/gen/__db_get_open_flags_reply.java \ - $(JAVA_RPCDIR)/gen/__db_get_pagesize_msg.java \ - $(JAVA_RPCDIR)/gen/__db_get_pagesize_reply.java \ - $(JAVA_RPCDIR)/gen/__db_get_q_extentsize_msg.java \ - $(JAVA_RPCDIR)/gen/__db_get_q_extentsize_reply.java \ - $(JAVA_RPCDIR)/gen/__db_get_re_delim_msg.java \ - $(JAVA_RPCDIR)/gen/__db_get_re_delim_reply.java \ - $(JAVA_RPCDIR)/gen/__db_get_re_len_msg.java \ - $(JAVA_RPCDIR)/gen/__db_get_re_len_reply.java \ - $(JAVA_RPCDIR)/gen/__db_get_re_pad_msg.java \ - $(JAVA_RPCDIR)/gen/__db_get_re_pad_reply.java \ - $(JAVA_RPCDIR)/gen/__db_get_reply.java \ - $(JAVA_RPCDIR)/gen/__db_join_msg.java \ - $(JAVA_RPCDIR)/gen/__db_join_reply.java \ - $(JAVA_RPCDIR)/gen/__db_key_range_msg.java \ - $(JAVA_RPCDIR)/gen/__db_key_range_reply.java \ - $(JAVA_RPCDIR)/gen/__db_open_msg.java \ - $(JAVA_RPCDIR)/gen/__db_open_reply.java \ - $(JAVA_RPCDIR)/gen/__db_pget_msg.java \ - $(JAVA_RPCDIR)/gen/__db_pget_reply.java \ - $(JAVA_RPCDIR)/gen/__db_put_msg.java \ - $(JAVA_RPCDIR)/gen/__db_put_reply.java \ - $(JAVA_RPCDIR)/gen/__db_remove_msg.java \ - $(JAVA_RPCDIR)/gen/__db_remove_reply.java \ - $(JAVA_RPCDIR)/gen/__db_rename_msg.java \ - $(JAVA_RPCDIR)/gen/__db_rename_reply.java \ - $(JAVA_RPCDIR)/gen/__db_set_bt_minkey_msg.java \ - $(JAVA_RPCDIR)/gen/__db_set_bt_minkey_reply.java \ - $(JAVA_RPCDIR)/gen/__db_set_encrypt_msg.java \ - $(JAVA_RPCDIR)/gen/__db_set_encrypt_reply.java \ - $(JAVA_RPCDIR)/gen/__db_set_flags_msg.java \ - $(JAVA_RPCDIR)/gen/__db_set_flags_reply.java \ - $(JAVA_RPCDIR)/gen/__db_set_h_ffactor_msg.java \ - $(JAVA_RPCDIR)/gen/__db_set_h_ffactor_reply.java \ - $(JAVA_RPCDIR)/gen/__db_set_h_nelem_msg.java \ - $(JAVA_RPCDIR)/gen/__db_set_h_nelem_reply.java \ - $(JAVA_RPCDIR)/gen/__db_set_lorder_msg.java \ - $(JAVA_RPCDIR)/gen/__db_set_lorder_reply.java \ - $(JAVA_RPCDIR)/gen/__db_set_pagesize_msg.java \ - $(JAVA_RPCDIR)/gen/__db_set_pagesize_reply.java \ - $(JAVA_RPCDIR)/gen/__db_set_q_extentsize_msg.java \ - $(JAVA_RPCDIR)/gen/__db_set_q_extentsize_reply.java \ - $(JAVA_RPCDIR)/gen/__db_set_re_delim_msg.java \ - $(JAVA_RPCDIR)/gen/__db_set_re_delim_reply.java \ - $(JAVA_RPCDIR)/gen/__db_set_re_len_msg.java \ - $(JAVA_RPCDIR)/gen/__db_set_re_len_reply.java \ - $(JAVA_RPCDIR)/gen/__db_set_re_pad_msg.java \ - $(JAVA_RPCDIR)/gen/__db_set_re_pad_reply.java \ - $(JAVA_RPCDIR)/gen/__db_stat_msg.java \ - $(JAVA_RPCDIR)/gen/__db_stat_reply.java \ - $(JAVA_RPCDIR)/gen/__db_sync_msg.java \ - $(JAVA_RPCDIR)/gen/__db_sync_reply.java \ - $(JAVA_RPCDIR)/gen/__db_truncate_msg.java \ - $(JAVA_RPCDIR)/gen/__db_truncate_reply.java \ - $(JAVA_RPCDIR)/gen/__dbc_c_close_msg.java \ - $(JAVA_RPCDIR)/gen/__dbc_c_close_reply.java \ - $(JAVA_RPCDIR)/gen/__dbc_c_count_msg.java \ - $(JAVA_RPCDIR)/gen/__dbc_c_count_reply.java \ - $(JAVA_RPCDIR)/gen/__dbc_c_del_msg.java \ - $(JAVA_RPCDIR)/gen/__dbc_c_del_reply.java \ - $(JAVA_RPCDIR)/gen/__dbc_c_dup_msg.java \ - $(JAVA_RPCDIR)/gen/__dbc_c_dup_reply.java \ - $(JAVA_RPCDIR)/gen/__dbc_c_get_msg.java \ - $(JAVA_RPCDIR)/gen/__dbc_c_get_reply.java \ - $(JAVA_RPCDIR)/gen/__dbc_c_pget_msg.java \ - $(JAVA_RPCDIR)/gen/__dbc_c_pget_reply.java \ - $(JAVA_RPCDIR)/gen/__dbc_c_put_msg.java \ - $(JAVA_RPCDIR)/gen/__dbc_c_put_reply.java \ - $(JAVA_RPCDIR)/gen/__env_close_msg.java \ - $(JAVA_RPCDIR)/gen/__env_close_reply.java \ - $(JAVA_RPCDIR)/gen/__env_create_msg.java \ - $(JAVA_RPCDIR)/gen/__env_create_reply.java \ - $(JAVA_RPCDIR)/gen/__env_dbremove_msg.java \ - $(JAVA_RPCDIR)/gen/__env_dbremove_reply.java \ - $(JAVA_RPCDIR)/gen/__env_dbrename_msg.java \ - $(JAVA_RPCDIR)/gen/__env_dbrename_reply.java \ - $(JAVA_RPCDIR)/gen/__env_get_cachesize_msg.java \ - $(JAVA_RPCDIR)/gen/__env_get_cachesize_reply.java \ - $(JAVA_RPCDIR)/gen/__env_get_encrypt_flags_msg.java \ - $(JAVA_RPCDIR)/gen/__env_get_encrypt_flags_reply.java \ - $(JAVA_RPCDIR)/gen/__env_get_flags_msg.java \ - $(JAVA_RPCDIR)/gen/__env_get_flags_reply.java \ - $(JAVA_RPCDIR)/gen/__env_get_home_msg.java \ - $(JAVA_RPCDIR)/gen/__env_get_home_reply.java \ - $(JAVA_RPCDIR)/gen/__env_get_open_flags_msg.java \ - $(JAVA_RPCDIR)/gen/__env_get_open_flags_reply.java \ - $(JAVA_RPCDIR)/gen/__env_open_msg.java \ - $(JAVA_RPCDIR)/gen/__env_open_reply.java \ - $(JAVA_RPCDIR)/gen/__env_remove_msg.java \ - $(JAVA_RPCDIR)/gen/__env_remove_reply.java \ - $(JAVA_RPCDIR)/gen/__env_set_cachesize_msg.java \ - $(JAVA_RPCDIR)/gen/__env_set_cachesize_reply.java \ - $(JAVA_RPCDIR)/gen/__env_set_encrypt_msg.java \ - $(JAVA_RPCDIR)/gen/__env_set_encrypt_reply.java \ - $(JAVA_RPCDIR)/gen/__env_set_flags_msg.java \ - $(JAVA_RPCDIR)/gen/__env_set_flags_reply.java \ - $(JAVA_RPCDIR)/gen/__env_txn_begin_msg.java \ - $(JAVA_RPCDIR)/gen/__env_txn_begin_reply.java \ - $(JAVA_RPCDIR)/gen/__env_txn_recover_msg.java \ - $(JAVA_RPCDIR)/gen/__env_txn_recover_reply.java \ - $(JAVA_RPCDIR)/gen/__txn_abort_msg.java \ - $(JAVA_RPCDIR)/gen/__txn_abort_reply.java \ - $(JAVA_RPCDIR)/gen/__txn_commit_msg.java \ - $(JAVA_RPCDIR)/gen/__txn_commit_reply.java \ - $(JAVA_RPCDIR)/gen/__txn_discard_msg.java \ - $(JAVA_RPCDIR)/gen/__txn_discard_reply.java \ - $(JAVA_RPCDIR)/gen/__txn_prepare_msg.java \ - $(JAVA_RPCDIR)/gen/__txn_prepare_reply.java \ - $(JAVA_RPCDIR)/gen/db_server.java - -UTIL_PROGS=\ - @ADDITIONAL_PROGS@ \ - db_archive db_checkpoint db_deadlock db_dump db_hotbackup \ - db_load db_printlog db_recover db_stat db_upgrade db_verify - -################################################## -# List of files installed into the library directory. -################################################## -LIB_INSTALL_FILE_LIST=\ - $(libdb) \ - $(libso) \ - $(libso_default) \ - $(libso_major) \ - $(libdb_version) \ - $(libso_target) \ - $(libcxx) \ - $(libxso) \ - $(libxso_default) \ - $(libxso_major) \ - $(libcxx_version) \ - $(libxso_target) \ - $(libtso) \ - $(libtso_default) \ - $(libtso_major) \ - $(libtso_static) \ - $(libtso_target) \ - $(libjso) \ - $(libjso_default) \ - $(libjso_g) \ - $(libjso_major) \ - $(libjso_static) \ - $(libjso_target) \ - $(libj_exjarfile) \ - $(libj_jarfile) - -################################################## -# Note: "all" must be the first target in the Makefile. -################################################## -all: @BUILD_TARGET@ - -install-strip install: all @INSTALL_TARGET@ - -################################################## -# Library and standard utilities build. -################################################## -library_build: @INSTALL_LIBS@ @ADDITIONAL_LANG@ $(UTIL_PROGS) - -# Static C library named libdb.a. -$(libdb): $(DEF_LIB) - -# Real static C library. -$(libdb_version): $(C_OBJS) - $(ar) cr $@ $(C_OBJS) - test ! -f $(ranlib) || $(ranlib) $@ - $(rm) -f $(libdb) - $(ln) -s $(libdb_version) $(libdb) - -# Shared C library. -$(libso_target): $(C_OBJS) - $(SOLINK) $(SOFLAGS) $(LDFLAGS) -o $@ $(C_OBJS) $(LIBCSO_LIBS) - $(rm) -f $(libdb) - $(ln) -s .libs/$(libdb_version) $(libdb) - -# Static C++ library named libdb_cxx.a. -$(libcxx): $(DEF_LIB_CXX) - -# Real static C++ library. -$(libcxx_version): $(CXX_OBJS) $(C_OBJS) - $(ar) cr $@ $(CXX_OBJS) $(C_OBJS) - test ! -f $(ranlib) || $(ranlib) $@ - $(rm) -f $(libcxx) - $(ln) -s $(libcxx_version) $(libcxx) - -# Shared C++ library. -$(libxso_target): $(CXX_OBJS) $(C_OBJS) - $(XSOLINK) $(SOFLAGS) $(LDFLAGS) \ - -o $@ $(CXX_OBJS) $(C_OBJS) $(LIBXSO_LIBS) - $(rm) -f $(libcxx) - $(ln) -s .libs/$(libcxx_version) $(libcxx) - -# Shared Java library. -$(libjso_target): $(JAVA_OBJS) $(C_OBJS) - $(SOLINK) -shrext @JMODSUFFIX@ $(SOFLAGS) $(LDFLAGS) \ - -o $@ $(JAVA_OBJS) $(C_OBJS) $(LIBJSO_LIBS) - -# Shared Tcl library. -$(libtso_target): $(TCL_OBJS) $(C_OBJS) - $(SOLINK) @LIBTSO_MODULE@ $(SOFLAGS) $(LDFLAGS) \ - -o $@ $(TCL_OBJS) $(C_OBJS) $(LIBTSO_LIBS) - -################################################## -# Creating individual dependencies and actions for building class -# files is possible, but it is very messy and error prone. -################################################## -java: $(libj_jarfile) $(libj_exjarfile) - -$(libj_jarfile): $(JAVA_DBSRCS) - @test -d $(JAVA_CLASSTOP) || \ - ($(mkdir) -p $(JAVA_CLASSTOP) && $(chmod) $(dmode) $(JAVA_CLASSTOP)) - $(JAVAC) -d $(JAVA_CLASSTOP) $(JAVACFLAGS) $(JAVA_DBSRCS) - cd $(JAVA_CLASSTOP) && $(JAR) cf ../$(libj_jarfile) ./com/sleepycat - -$(libj_exjarfile): $(libj_jarfile) $(JAVA_EXSRCS) - @test -d $(JAVA_EXCLASSTOP) || \ - ($(mkdir) -p $(JAVA_EXCLASSTOP) && \ - $(chmod) $(dmode) $(JAVA_EXCLASSTOP)) - $(JAVAC) -classpath $(libj_jarfile) -d $(JAVA_EXCLASSTOP) \ - $(JAVACFLAGS) $(JAVA_EXSRCS) - cd $(JAVA_EXCLASSTOP) && $(JAR) cf ../$(libj_exjarfile) . - -$(rpc_jarfile): $(libj_jarfile) $(RPC_JAVASRV_SRCS) - @test -d $(JAVA_RPCCLASSTOP) || \ - ($(mkdir) -p $(JAVA_RPCCLASSTOP) && \ - $(chmod) $(dmode) $(JAVA_RPCCLASSTOP)) - env CLASSPATH=$(CLASSPATH):$(JAVA_RPCDIR)/oncrpc.jar \ - @JAVAC@ -d $(JAVA_RPCCLASSTOP) $(JAVACFLAGS) $(RPC_JAVASRV_SRCS) - cd $(JAVA_RPCCLASSTOP) && $(JAR) cf ../$(rpc_jarfile) $(JAVA_RPCREL) - -################################################## -# Utilities -################################################## -berkeley_db_svc: $(RPC_SRV_OBJS) util_log@o@ $(DEF_LIB) - $(CCLINK) -o $@ $(LDFLAGS) \ - $(RPC_SRV_OBJS) util_log@o@ $(DEF_LIB) $(LIBS) - $(POSTLINK) $@ - -berkeley_db_cxxsvc: $(RPC_CXXSRV_OBJS) util_log@o@ $(DEF_LIB_CXX) - $(CXXLINK) -o $@ $(LDFLAGS) \ - $(RPC_CXXSRV_OBJS) util_log@o@ $(DEF_LIB_CXX) $(LIBS) - $(POSTLINK) $@ - -berkeley_db_javasvc: $(rpc_jarfile) - echo "#!/bin/sh" > $@ - echo CLASSPATH="$(CLASSPATH):$(rpc_jarfile):$(JAVA_RPCDIR)/oncrpc.jar" >> $@ - echo LD_LIBRARY_PATH=.libs >> $@ - echo export CLASSPATH LD_LIBRARY_PATH >> $@ - echo exec java com.sleepycat.db.rpcserver.Server \$$@ >> $@ - chmod +x $@ - -db_archive: db_archive@o@ util_sig@o@ $(DEF_LIB) - $(CCLINK) -o $@ $(LDFLAGS) \ - db_archive@o@ util_sig@o@ $(DEF_LIB) $(LIBS) - $(POSTLINK) $@ - -db_checkpoint: db_checkpoint@o@ util_log@o@ util_sig@o@ $(DEF_LIB) - $(CCLINK) -o $@ $(LDFLAGS) \ - db_checkpoint@o@ util_log@o@ util_sig@o@ $(DEF_LIB) $(LIBS) - $(POSTLINK) $@ - -db_deadlock: db_deadlock@o@ util_log@o@ util_sig@o@ $(DEF_LIB) - $(CCLINK) -o $@ $(LDFLAGS) \ - db_deadlock@o@ util_log@o@ util_sig@o@ $(DEF_LIB) $(LIBS) - $(POSTLINK) $@ - -db_dump: db_dump@o@ util_cache@o@ util_sig@o@ $(DEF_LIB) - $(CCLINK) -o $@ $(LDFLAGS) \ - db_dump@o@ util_cache@o@ util_sig@o@ $(DEF_LIB) $(LIBS) - $(POSTLINK) $@ - -db_dump185: db_dump185@o@ @REPLACEMENT_OBJS@ - $(CCLINK) -o $@ $(LDFLAGS) db_dump185@o@ @REPLACEMENT_OBJS@ $(DB185LIB) - $(POSTLINK) $@ - -db_hotbackup: db_hotbackup@o@ util_sig@o@ $(DEF_LIB) - $(CCLINK) -o $@ $(LDFLAGS) \ - db_hotbackup@o@ util_sig@o@ $(DEF_LIB) $(LIBS) - $(POSTLINK) $@ - -db_load: db_load@o@ util_cache@o@ util_sig@o@ $(DEF_LIB) - $(CCLINK) -o $@ $(LDFLAGS) \ - db_load@o@ util_cache@o@ util_sig@o@ $(DEF_LIB) $(LIBS) - $(POSTLINK) $@ - -db_printlog: db_printlog@o@ $(PRINT_OBJS) util_sig@o@ $(DEF_LIB) - $(CCLINK) -o $@ $(LDFLAGS) \ - db_printlog@o@ $(PRINT_OBJS) util_sig@o@ $(DEF_LIB) $(LIBS) - $(POSTLINK) $@ - -db_recover: db_recover@o@ util_sig@o@ $(DEF_LIB) - $(CCLINK) -o $@ $(LDFLAGS) \ - db_recover@o@ util_sig@o@ $(DEF_LIB) $(LIBS) - $(POSTLINK) $@ - -db_stat: db_stat@o@ util_cache@o@ util_sig@o@ $(DEF_LIB) - $(CCLINK) -o $@ $(LDFLAGS) \ - db_stat@o@ util_cache@o@ util_sig@o@ $(DEF_LIB) $(LIBS) - $(POSTLINK) $@ - -db_upgrade: db_upgrade@o@ util_sig@o@ $(DEF_LIB) - $(CCLINK) -o $@ $(LDFLAGS) \ - db_upgrade@o@ util_sig@o@ $(DEF_LIB) $(LIBS) - $(POSTLINK) $@ - -db_verify: db_verify@o@ util_cache@o@ util_sig@o@ $(DEF_LIB) - $(CCLINK) -o $@ $(LDFLAGS) \ - db_verify@o@ util_cache@o@ util_sig@o@ $(DEF_LIB) $(LIBS) - $(POSTLINK) $@ - -################################################## -# Library and standard utilities install. -################################################## -library_install: install_setup -library_install: install_include install_lib install_utilities install_docs - -uninstall: uninstall_include uninstall_lib uninstall_utilities uninstall_docs - -install_setup: - @test -d $(DESTDIR)$(prefix) || \ - ($(mkdir) -p $(DESTDIR)$(prefix) && \ - $(chmod) $(dmode) $(DESTDIR)$(prefix)) - -INCDOT= db.h db_cxx.h @ADDITIONAL_INCS@ -install_include: - @echo "Installing DB include files: $(DESTDIR)$(includedir) ..." - @test -d $(DESTDIR)$(includedir) || \ - ($(mkdir) -p $(DESTDIR)$(includedir) && \ - $(chmod) $(dmode) $(DESTDIR)$(includedir)) - @cd $(DESTDIR)$(includedir) && $(rm) -f $(INCDOT) - @$(cp) -p $(INCDOT) $(DESTDIR)$(includedir) - @cd $(DESTDIR)$(includedir) && $(chmod) $(fmode) $(INCDOT) - -uninstall_include: - @cd $(DESTDIR)$(includedir) && $(rm) -f $(INCDOT) - -install_lib: - @echo "Installing DB library: $(DESTDIR)$(libdir) ..." - @test -d $(DESTDIR)$(libdir) || \ - ($(mkdir) -p $(DESTDIR)$(libdir) && \ - $(chmod) $(dmode) $(DESTDIR)$(libdir)) - @cd $(DESTDIR)$(libdir) && $(rm) -f $(LIB_INSTALL_FILE_LIST) - @$(INSTALLER) @INSTALL_LIBS@ $(DESTDIR)$(libdir) - @(cd $(DESTDIR)$(libdir) && \ - test -f $(libso) && $(ln) -s $(libso) $(libso_default); \ - test -f $(libso) && $(ln) -s $(libso) $(libso_major); \ - test -f $(libxso) && $(ln) -s $(libxso) $(libxso_default); \ - test -f $(libxso) && $(ln) -s $(libxso) $(libxso_major); \ - test -f $(libtso) && $(ln) -s $(libtso) $(libtso_default); \ - test -f $(libtso) && $(ln) -s $(libtso) $(libtso_major); \ - test -f $(libjso) && $(ln) -s $(libjso) $(libjso_default); \ - test -f $(libjso) && $(ln) -s $(libjso) $(libjso_major); \ - test -f $(libjso) && $(ln) -s $(libjso) $(libjso_g)) || true - @(test -f $(libj_jarfile) && \ - $(cp) $(libj_jarfile) $(DESTDIR)$(libdir) && \ - $(chmod) $(fmode) $(DESTDIR)$(libdir)/$(libj_jarfile)) || true - -uninstall_lib: - @cd $(DESTDIR)$(libdir) && $(rm) -f $(LIB_INSTALL_FILE_LIST) - -install_utilities: - @echo "Installing DB utilities: $(DESTDIR)$(bindir) ..." - @test -d $(DESTDIR)$(bindir) || \ - ($(mkdir) -p $(DESTDIR)$(bindir) && \ - $(chmod) $(dmode) $(DESTDIR)$(bindir)) - @for i in $(UTIL_PROGS); do \ - $(rm) -f $(DESTDIR)$(bindir)/$$i $(DESTDIR)$(bindir)/$$i.exe; \ - test -f $$i.exe && i=$$i.exe || true; \ - $(INSTALLER) $$i $(DESTDIR)$(bindir)/$$i; \ - test -f $(strip) && $(strip) $(DESTDIR)$(bindir)/$$i || true; \ - $(chmod) $(emode) $(DESTDIR)$(bindir)/$$i; \ - done - -uninstall_utilities: - @(cd $(DESTDIR)$(bindir); for i in $(UTIL_PROGS); do \ - $(rm) -f $$i $$i.exe; \ - done) - -DOCLIST=api_c api_cxx api_tcl collections gsg gsg_txn images index.html \ - java ref sleepycat utility - -install_docs: - @echo "Installing documentation: $(DESTDIR)$(docdir) ..." - @test -d $(DESTDIR)$(docdir) || \ - ($(mkdir) -p $(DESTDIR)$(docdir) && \ - $(chmod) $(dmode) $(DESTDIR)$(docdir)) - @cd $(DESTDIR)$(docdir) && $(rm) -rf $(DOCLIST) - @cd $(srcdir)/docs && $(cp) -pr $(DOCLIST) $(DESTDIR)$(docdir)/ - -uninstall_docs: - @cd $(DESTDIR)$(docdir) && $(rm) -rf $(DOCLIST) - -################################################## -# Remaining standard Makefile targets. -################################################## -CLEAN_LIST=\ - TxnGuide TxnGuideInMemory bench_001 berkeley_db_cxxsvc \ - berkeley_db_javasvc berkeley_db_svc db_dump185 db_perf \ - db_reptest dbs ex_access ex_apprec ex_btrec ex_dbclient ex_env \ - ex_lock ex_mpool ex_repquote ex_sequence ex_thread ex_tpcb \ \ - example_database_load example_database_read excxx_access \ - excxx_btrec excxx_env excxx_example_database_load \ - excxx_example_database_read excxx_lock excxx_mpool \ - excxx_sequence excxx_tpcb txn_guide txn_guide_inmemory - -mostly-clean clean: - $(rm) -rf $(C_OBJS) - $(rm) -rf $(CXX_OBJS) $(JAVA_OBJS) $(TCL_OBJS) - $(rm) -rf $(RPC_CLIENT_OBJS) $(RPC_SRV_OBJS) $(RPC_CXXSRV_OBJS) - $(rm) -rf $(UTIL_PROGS) *.exe $(CLEAN_LIST) - $(rm) -rf $(JAVA_CLASSTOP) $(JAVA_EXCLASSTOP) - $(rm) -rf $(JAVA_RPCCLASSES) $(rpc_jarfile) - $(rm) -rf tags *@o@ *.o *.o.lock *.lo core *.core - $(rm) -rf ALL.OUT.* PARALLEL_TESTDIR.* - $(rm) -rf RUN_LOG RUNQUEUE TESTDIR TESTDIR.A TEST.LIST - $(rm) -rf logtrack_seen.db tm .libs $(LIB_INSTALL_FILE_LIST) - -REALCLEAN_LIST=\ - Makefile confdefs.h config.cache config.log config.status \ - configure.lineno db.h db185_int.h db_185.h db_config.h \ - db_cxx.h db_int.h db_int_def.h include.tcl \ - db_server.h db_server_clnt.c db_server_svc.c db_server_xdr.c \ - gen_db_server.c win_db.h - -distclean maintainer-clean realclean: clean - $(rm) -rf $(REALCLEAN_LIST) - $(rm) -rf libtool - -check depend dvi info obj TAGS: - @echo "$@: make target not supported" && true - -dist rpm rpmbuild: - @echo "$@: make target not supported" && false - -################################################## -# Multi-threaded testers, benchmarks. -################################################## -dbs@o@: $(srcdir)/test_server/dbs.c - $(CC) $(CFLAGS) $? -dbs_am@o@: $(srcdir)/test_server/dbs_am.c - $(CC) $(CFLAGS) $? -dbs_checkpoint@o@: $(srcdir)/test_server/dbs_checkpoint.c - $(CC) $(CFLAGS) $? -dbs_debug@o@: $(srcdir)/test_server/dbs_debug.c - $(CC) $(CFLAGS) $? -dbs_handles@o@: $(srcdir)/test_server/dbs_handles.c - $(CC) $(CFLAGS) $? -dbs_log@o@: $(srcdir)/test_server/dbs_log.c - $(CC) $(CFLAGS) $? -dbs_qam@o@: $(srcdir)/test_server/dbs_qam.c - $(CC) $(CFLAGS) $? -dbs_spawn@o@: $(srcdir)/test_server/dbs_spawn.c - $(CC) $(CFLAGS) $? -dbs_trickle@o@: $(srcdir)/test_server/dbs_trickle.c - $(CC) $(CFLAGS) $? -dbs_util@o@: $(srcdir)/test_server/dbs_util.c - $(CC) $(CFLAGS) $? -dbs_yield@o@: $(srcdir)/test_server/dbs_yield.c - $(CC) $(CFLAGS) $? -DBS_OBJS=\ - dbs@o@ dbs_am@o@ dbs_checkpoint@o@ dbs_debug@o@ dbs_handles@o@ \ - dbs_log@o@ dbs_qam@o@ dbs_spawn@o@ dbs_trickle@o@ dbs_util@o@ \ - dbs_yield@o@ -dbs: $(DBS_OBJS) $(DEF_LIB) - $(CCLINK) -o $@ \ - $(LDFLAGS) $(DBS_OBJS) $(DEF_LIB) $(TEST_LIBS) $(LIBS) - $(POSTLINK) $@ - -db_perf@o@: $(srcdir)/test_perf/db_perf.c - $(CC) $(CFLAGS) $? -perf_checkpoint@o@: $(srcdir)/test_perf/perf_checkpoint.c - $(CC) $(CFLAGS) $? -perf_config@o@: $(srcdir)/test_perf/perf_config.c - $(CC) $(CFLAGS) $? -perf_dbs@o@: $(srcdir)/test_perf/perf_dbs.c - $(CC) $(CFLAGS) $? -perf_dead@o@: $(srcdir)/test_perf/perf_dead.c - $(CC) $(CFLAGS) $? -perf_debug@o@: $(srcdir)/test_perf/perf_debug.c - $(CC) $(CFLAGS) $? -perf_file@o@: $(srcdir)/test_perf/perf_file.c - $(CC) $(CFLAGS) $? -perf_key@o@: $(srcdir)/test_perf/perf_key.c - $(CC) $(CFLAGS) $? -perf_log@o@: $(srcdir)/test_perf/perf_log.c - $(CC) $(CFLAGS) $? -perf_misc@o@: $(srcdir)/test_perf/perf_misc.c - $(CC) $(CFLAGS) $? -perf_op@o@: $(srcdir)/test_perf/perf_op.c - $(CC) $(CFLAGS) $? -perf_parse@o@: $(srcdir)/test_perf/perf_parse.c - $(CC) $(CFLAGS) $? -perf_rand@o@: $(srcdir)/test_perf/perf_rand.c - $(CC) $(CFLAGS) $? -perf_spawn@o@: $(srcdir)/test_perf/perf_spawn.c - $(CC) $(CFLAGS) $? -perf_stat@o@: $(srcdir)/test_perf/perf_stat.c - $(CC) $(CFLAGS) $? -perf_sync@o@: $(srcdir)/test_perf/perf_sync.c - $(CC) $(CFLAGS) $? -perf_thread@o@: $(srcdir)/test_perf/perf_thread.c - $(CC) $(CFLAGS) $? -perf_trickle@o@: $(srcdir)/test_perf/perf_trickle.c - $(CC) $(CFLAGS) $? -perf_txn@o@: $(srcdir)/test_perf/perf_txn.c - $(CC) $(CFLAGS) $? -perf_util@o@: $(srcdir)/test_perf/perf_util.c - $(CC) $(CFLAGS) $? -perf_vx@o@: $(srcdir)/test_perf/perf_vx.c - $(CC) $(CFLAGS) $? -DBPERF_OBJS=\ - db_perf@o@ perf_checkpoint@o@ perf_config@o@ perf_dbs@o@ \ - perf_dead@o@ perf_debug@o@ perf_file@o@ perf_key@o@ perf_log@o@ \ - perf_misc@o@ perf_op@o@ perf_parse@o@ perf_rand@o@ perf_spawn@o@ \ - perf_stat@o@ perf_sync@o@ perf_thread@o@ perf_trickle@o@ \ - perf_txn@o@ perf_util@o@ perf_vx@o@ - -db_perf: $(DBPERF_OBJS) $(DEF_LIB) - $(CCLINK) -o $@ \ - $(LDFLAGS) $(DBPERF_OBJS) $(DEF_LIB) $(TEST_LIBS) $(LIBS) - $(POSTLINK) $@ - -db_reptest@o@: $(srcdir)/test_rep/db_reptest.c - $(CC) $(CFLAGS) $? -reptest_accept@o@: $(srcdir)/test_rep/reptest_accept.c - $(CC) $(CFLAGS) $? -reptest_client@o@: $(srcdir)/test_rep/reptest_client.c - $(CC) $(CFLAGS) $? -reptest_config@o@: $(srcdir)/test_rep/reptest_config.c - $(CC) $(CFLAGS) $? -reptest_dbs@o@: $(srcdir)/test_rep/reptest_dbs.c - $(CC) $(CFLAGS) $? -reptest_debug@o@: $(srcdir)/test_rep/reptest_debug.c - $(CC) $(CFLAGS) $? -reptest_elect@o@: $(srcdir)/test_rep/reptest_elect.c - $(CC) $(CFLAGS) $? -reptest_env@o@: $(srcdir)/test_rep/reptest_env.c - $(CC) $(CFLAGS) $? -reptest_exec@o@: $(srcdir)/test_rep/reptest_exec.c - $(CC) $(CFLAGS) $? -reptest_file@o@: $(srcdir)/test_rep/reptest_file.c - $(CC) $(CFLAGS) $? -reptest_key@o@: $(srcdir)/test_rep/reptest_key.c - $(CC) $(CFLAGS) $? -reptest_master@o@: $(srcdir)/test_rep/reptest_master.c - $(CC) $(CFLAGS) $? -reptest_misc@o@: $(srcdir)/test_rep/reptest_misc.c - $(CC) $(CFLAGS) $? -reptest_msg_thread@o@: $(srcdir)/test_rep/reptest_msg_thread.c - $(CC) $(CFLAGS) $? -reptest_op@o@: $(srcdir)/test_rep/reptest_op.c - $(CC) $(CFLAGS) $? -reptest_parse@o@: $(srcdir)/test_rep/reptest_parse.c - $(CC) $(CFLAGS) $? -reptest_rand@o@: $(srcdir)/test_rep/reptest_rand.c - $(CC) $(CFLAGS) $? -reptest_send@o@: $(srcdir)/test_rep/reptest_send.c - $(CC) $(CFLAGS) $? -reptest_site@o@: $(srcdir)/test_rep/reptest_site.c - $(CC) $(CFLAGS) $? -reptest_socket@o@: $(srcdir)/test_rep/reptest_socket.c - $(CC) $(CFLAGS) $? -reptest_spawn@o@: $(srcdir)/test_rep/reptest_spawn.c - $(CC) $(CFLAGS) $? -reptest_thread@o@: $(srcdir)/test_rep/reptest_thread.c - $(CC) $(CFLAGS) $? -reptest_txn@o@: $(srcdir)/test_rep/reptest_txn.c - $(CC) $(CFLAGS) $? -reptest_util@o@: $(srcdir)/test_rep/reptest_util.c - $(CC) $(CFLAGS) $? -DBREPTEST_OBJS=\ - db_reptest@o@ reptest_accept@o@ reptest_client@o@ reptest_config@o@ \ - reptest_dbs@o@ reptest_debug@o@ reptest_elect@o@ reptest_env@o@ \ - reptest_exec@o@ reptest_file@o@ reptest_key@o@ reptest_master@o@ \ - reptest_misc@o@ reptest_msg_thread@o@ reptest_op@o@ reptest_parse@o@ \ - reptest_rand@o@ reptest_send@o@ reptest_site@o@ reptest_socket@o@ \ - reptest_spawn@o@ reptest_thread@o@ reptest_txn@o@ reptest_util@o@ - -db_reptest: $(DBREPTEST_OBJS) $(DEF_LIB) - $(CCLINK) -o $@ \ - $(LDFLAGS) $(DBREPTEST_OBJS) $(DEF_LIB) $(TEST_LIBS) $(LIBS) - $(POSTLINK) $@ - -tm@o@: $(srcdir)/mutex/tm.c - $(CC) $(CFLAGS) $? -tm: tm@o@ $(DEF_LIB) - $(CCLINK) -o $@ $(LDFLAGS) tm@o@ $(DEF_LIB) $(TEST_LIBS) $(LIBS) - $(POSTLINK) $@ - -################################################## -# Example programs for C. -################################################## -bench_001@o@: $(srcdir)/examples_c/bench_001.c - $(CC) $(CFLAGS) $? -bench_001: bench_001@o@ $(DEF_LIB) - $(CCLINK) -o $@ $(LDFLAGS) bench_001@o@ $(DEF_LIB) $(LIBS) - $(POSTLINK) $@ - -ex_access@o@: $(srcdir)/examples_c/ex_access.c - $(CC) $(CFLAGS) $? -ex_access: ex_access@o@ $(DEF_LIB) - $(CCLINK) -o $@ $(LDFLAGS) ex_access@o@ $(DEF_LIB) $(LIBS) - $(POSTLINK) $@ - -ex_apprec@o@: $(srcdir)/examples_c/ex_apprec/ex_apprec.c - $(CC) $(CFLAGS) $? -ex_apprec_auto@o@: $(srcdir)/examples_c/ex_apprec/ex_apprec_auto.c - $(CC) $(CFLAGS) $? -ex_apprec_autop@o@: $(srcdir)/examples_c/ex_apprec/ex_apprec_autop.c - $(CC) $(CFLAGS) $? -ex_apprec_rec@o@: $(srcdir)/examples_c/ex_apprec/ex_apprec_rec.c - $(CC) $(CFLAGS) $? -EX_APPREC_OBJS=\ - ex_apprec@o@ ex_apprec_auto@o@ ex_apprec_autop@o@ ex_apprec_rec@o@ -ex_apprec: $(EX_APPREC_OBJS) $(DEF_LIB) - $(CCLINK) -o $@ \ - $(LDFLAGS) $(EX_APPREC_OBJS) $(DEF_LIB) $(TEST_LIBS) $(LIBS) - -ex_btrec@o@: $(srcdir)/examples_c/ex_btrec.c - $(CC) $(CFLAGS) $? -ex_btrec: ex_btrec@o@ $(DEF_LIB) - $(CCLINK) -o $@ $(LDFLAGS) ex_btrec@o@ $(DEF_LIB) $(LIBS) - $(POSTLINK) $@ - -ex_dbclient@o@: $(srcdir)/examples_c/ex_dbclient.c - $(CC) $(CFLAGS) $? -ex_dbclient: ex_dbclient@o@ $(DEF_LIB) - $(CCLINK) -o $@ $(LDFLAGS) ex_dbclient@o@ $(DEF_LIB) $(LIBS) - $(POSTLINK) $@ - -ex_env@o@: $(srcdir)/examples_c/ex_env.c - $(CC) $(CFLAGS) $? -ex_env: ex_env@o@ $(DEF_LIB) - $(CCLINK) -o $@ $(LDFLAGS) ex_env@o@ $(DEF_LIB) $(LIBS) - $(POSTLINK) $@ - -ex_lock@o@: $(srcdir)/examples_c/ex_lock.c - $(CC) $(CFLAGS) $? -ex_lock: ex_lock@o@ $(DEF_LIB) - $(CCLINK) -o $@ $(LDFLAGS) ex_lock@o@ $(DEF_LIB) $(LIBS) - $(POSTLINK) $@ - -ex_mpool@o@: $(srcdir)/examples_c/ex_mpool.c - $(CC) $(CFLAGS) $? -ex_mpool: ex_mpool@o@ $(DEF_LIB) - $(CCLINK) -o $@ $(LDFLAGS) ex_mpool@o@ $(DEF_LIB) $(LIBS) - $(POSTLINK) $@ - -ex_rq_client@o@: $(srcdir)/examples_c/ex_repquote/ex_rq_client.c - $(CC) $(CFLAGS) $? -ex_rq_main@o@: $(srcdir)/examples_c/ex_repquote/ex_rq_main.c - $(CC) $(CFLAGS) $? -ex_rq_master@o@: $(srcdir)/examples_c/ex_repquote/ex_rq_master.c - $(CC) $(CFLAGS) $? -ex_rq_net@o@: $(srcdir)/examples_c/ex_repquote/ex_rq_net.c - $(CC) $(CFLAGS) $? -ex_rq_util@o@: $(srcdir)/examples_c/ex_repquote/ex_rq_util.c - $(CC) $(CFLAGS) $? -EX_RQ_OBJS=\ - ex_rq_client@o@ ex_rq_main@o@ ex_rq_master@o@ ex_rq_net@o@ ex_rq_util@o@ -ex_repquote: $(EX_RQ_OBJS) $(DEF_LIB) - $(CCLINK) -o $@ \ - $(LDFLAGS) $(EX_RQ_OBJS) $(DEF_LIB) $(TEST_LIBS) $(LIBS) - $(POSTLINK) $@ - -ex_sequence@o@: $(srcdir)/examples_c/ex_sequence.c - $(CC) $(CFLAGS) $? -ex_sequence: ex_sequence@o@ $(DEF_LIB) - $(CCLINK) -o $@ $(LDFLAGS) ex_sequence@o@ $(DEF_LIB) $(LIBS) - $(POSTLINK) $@ - -ex_thread@o@: $(srcdir)/examples_c/ex_thread.c - $(CC) $(CFLAGS) $? -ex_thread: ex_thread@o@ $(DEF_LIB) - $(CCLINK) -o $@ \ - $(LDFLAGS) ex_thread@o@ $(DEF_LIB) $(TEST_LIBS) $(LIBS) - $(POSTLINK) $@ - -ex_tpcb@o@: $(srcdir)/examples_c/ex_tpcb.c - $(CC) $(CFLAGS) $? -ex_tpcb: ex_tpcb@o@ $(DEF_LIB) - $(CCLINK) -o $@ $(LDFLAGS) ex_tpcb@o@ $(DEF_LIB) $(LIBS) - $(POSTLINK) $@ - -gettingstarted_common@o@: \ - $(srcdir)/examples_c/getting_started/gettingstarted_common.c - $(CC) -I $(srcdir)/examples_c/getting_started $(CFLAGS) $? -example_database_load@o@: \ - $(srcdir)/examples_c/getting_started/example_database_load.c - $(CC) $(CFLAGS) $? -example_database_read@o@: \ - $(srcdir)/examples_c/getting_started/example_database_read.c - $(CC) $(CFLAGS) $? -example_database_load: example_database_load@o@ gettingstarted_common@o@ \ - $(DEF_LIB) - $(CCLINK) -o $@ $(LDFLAGS) \ - example_database_load@o@ gettingstarted_common@o@ $(DEF_LIB) $(LIBS) - $(POSTLINK) $@ -example_database_read: example_database_read@o@ gettingstarted_common@o@ \ - $(DEF_LIB) - $(CCLINK) -o $@ $(LDFLAGS) \ - example_database_read@o@ gettingstarted_common@o@ $(DEF_LIB) $(LIBS) - $(POSTLINK) $@ - -txn_guide_inmemory@o@: $(srcdir)/examples_c/txn_guide/txn_guide_inmemory.c - $(CC) $(CFLAGS) $? -txn_guide_inmemory: txn_guide_inmemory@o@ $(DEF_LIB) - $(CCLINK) -o $@ $(LDFLAGS) txn_guide_inmemory@o@ $(DEF_LIB) $(LIBS) - $(POSTLINK) $@ - -txn_guide@o@: $(srcdir)/examples_c/txn_guide/txn_guide.c - $(CC) $(CFLAGS) $? -txn_guide: txn_guide@o@ $(DEF_LIB) - $(CCLINK) -o $@ $(LDFLAGS) txn_guide@o@ $(DEF_LIB) $(LIBS) - $(POSTLINK) $@ - -################################################## -# Example programs for C++. -################################################## -AccessExample@o@: $(srcdir)/examples_cxx/AccessExample.cpp - $(CXX) $(CXXFLAGS) $? -excxx_access: AccessExample@o@ $(DEF_LIB_CXX) - $(CXXLINK) -o $@ $(LDFLAGS) AccessExample@o@ $(DEF_LIB_CXX) $(LIBS) - $(POSTLINK) $@ - -BtRecExample@o@: $(srcdir)/examples_cxx/BtRecExample.cpp - $(CXX) $(CXXFLAGS) $? -excxx_btrec: BtRecExample@o@ $(DEF_LIB_CXX) - $(CXXLINK) -o $@ $(LDFLAGS) BtRecExample@o@ $(DEF_LIB_CXX) $(LIBS) - $(POSTLINK) $@ - -EnvExample@o@: $(srcdir)/examples_cxx/EnvExample.cpp - $(CXX) $(CXXFLAGS) $? -excxx_env: EnvExample@o@ $(DEF_LIB_CXX) - $(CXXLINK) -o $@ $(LDFLAGS) EnvExample@o@ $(DEF_LIB_CXX) $(LIBS) - $(POSTLINK) $@ - -LockExample@o@: $(srcdir)/examples_cxx/LockExample.cpp - $(CXX) $(CXXFLAGS) $? -excxx_lock: LockExample@o@ $(DEF_LIB_CXX) - $(CXXLINK) -o $@ $(LDFLAGS) LockExample@o@ $(DEF_LIB_CXX) $(LIBS) - $(POSTLINK) $@ - -MpoolExample@o@: $(srcdir)/examples_cxx/MpoolExample.cpp - $(CXX) $(CXXFLAGS) $? -excxx_mpool: MpoolExample@o@ $(DEF_LIB_CXX) - $(CXXLINK) -o $@ $(LDFLAGS) MpoolExample@o@ $(DEF_LIB_CXX) $(LIBS) - $(POSTLINK) $@ - -SequenceExample@o@: $(srcdir)/examples_cxx/SequenceExample.cpp - $(CXX) $(CXXFLAGS) $? -excxx_sequence: SequenceExample@o@ $(DEF_LIB_CXX) - $(CXXLINK) -o $@ $(LDFLAGS) SequenceExample@o@ $(DEF_LIB_CXX) $(LIBS) - $(POSTLINK) $@ - -TpcbExample@o@: $(srcdir)/examples_cxx/TpcbExample.cpp - $(CXX) $(CXXFLAGS) $? -excxx_tpcb: TpcbExample@o@ $(DEF_LIB_CXX) - $(CXXLINK) -o $@ $(LDFLAGS) TpcbExample@o@ $(DEF_LIB_CXX) $(LIBS) - $(POSTLINK) $@ - -excxx_example_database_load@o@: \ - $(srcdir)/examples_cxx/getting_started/excxx_example_database_load.cpp - $(CXX) -I$(srcdir)/examples_cxx/getting_started $(CXXFLAGS) $? -excxx_example_database_read@o@: \ - $(srcdir)/examples_cxx/getting_started/excxx_example_database_read.cpp - $(CXX) -I$(srcdir)/examples_cxx/getting_started $(CXXFLAGS) $? -MyDb@o@: $(srcdir)/examples_cxx/getting_started/MyDb.cpp - $(CXX) -I$(srcdir)/examples_cxx/getting_started $(CXXFLAGS) $? -excxx_example_database_load: \ - excxx_example_database_load@o@ MyDb@o@ $(DEF_LIB_CXX) - $(CXXLINK) -o $@ $(LDFLAGS) \ - excxx_example_database_load@o@ MyDb@o@ $(DEF_LIB_CXX) $(LIBS) - $(POSTLINK) $@ -excxx_example_database_read: \ - excxx_example_database_read@o@ MyDb@o@ $(DEF_LIB_CXX) - $(CXXLINK) -o $@ $(LDFLAGS) \ - excxx_example_database_read@o@ MyDb@o@ $(DEF_LIB_CXX) $(LIBS) - $(POSTLINK) $@ - -TxnGuideInMemory@o@: $(srcdir)/examples_cxx/txn_guide/TxnGuideInMemory.cpp - $(CXX) $(CXXFLAGS) $? -TxnGuideInMemory: TxnGuideInMemory@o@ $(DEF_LIB_CXX) - $(CXXLINK) -o $@ $(LDFLAGS) TxnGuideInMemory@o@ $(DEF_LIB_CXX) $(LIBS) - $(POSTLINK) $@ - -TxnGuide@o@: $(srcdir)/examples_cxx/txn_guide/TxnGuide.cpp - $(CXX) $(CXXFLAGS) $? -TxnGuide: TxnGuide@o@ $(DEF_LIB_CXX) - $(CXXLINK) -o $@ $(LDFLAGS) TxnGuide@o@ $(DEF_LIB_CXX) $(LIBS) - $(POSTLINK) $@ - -################################################## -# C API build rules. -################################################## -aes_method@o@: $(srcdir)/crypto/aes_method.c - $(CC) $(CFLAGS) $? -bt_compare@o@: $(srcdir)/btree/bt_compare.c - $(CC) $(CFLAGS) $? -bt_conv@o@: $(srcdir)/btree/bt_conv.c - $(CC) $(CFLAGS) $? -bt_curadj@o@: $(srcdir)/btree/bt_curadj.c - $(CC) $(CFLAGS) $? -bt_cursor@o@: $(srcdir)/btree/bt_cursor.c - $(CC) $(CFLAGS) $? -bt_delete@o@: $(srcdir)/btree/bt_delete.c - $(CC) $(CFLAGS) $? -bt_method@o@: $(srcdir)/btree/bt_method.c - $(CC) $(CFLAGS) $? -bt_open@o@: $(srcdir)/btree/bt_open.c - $(CC) $(CFLAGS) $? -bt_put@o@: $(srcdir)/btree/bt_put.c - $(CC) $(CFLAGS) $? -bt_rec@o@: $(srcdir)/btree/bt_rec.c - $(CC) $(CFLAGS) $? -bt_reclaim@o@: $(srcdir)/btree/bt_reclaim.c - $(CC) $(CFLAGS) $? -bt_recno@o@: $(srcdir)/btree/bt_recno.c - $(CC) $(CFLAGS) $? -bt_rsearch@o@: $(srcdir)/btree/bt_rsearch.c - $(CC) $(CFLAGS) $? -bt_search@o@: $(srcdir)/btree/bt_search.c - $(CC) $(CFLAGS) $? -bt_split@o@: $(srcdir)/btree/bt_split.c - $(CC) $(CFLAGS) $? -bt_stat@o@: $(srcdir)/btree/bt_stat.c - $(CC) $(CFLAGS) $? -bt_compact@o@: $(srcdir)/btree/bt_compact.c - $(CC) $(CFLAGS) $? -bt_upgrade@o@: $(srcdir)/btree/bt_upgrade.c - $(CC) $(CFLAGS) $? -bt_verify@o@: $(srcdir)/btree/bt_verify.c - $(CC) $(CFLAGS) $? -btree_auto@o@: $(srcdir)/btree/btree_auto.c - $(CC) $(CFLAGS) $? -btree_autop@o@: $(srcdir)/btree/btree_autop.c - $(CC) $(CFLAGS) $? -crdel_auto@o@: $(srcdir)/db/crdel_auto.c - $(CC) $(CFLAGS) $? -crdel_autop@o@: $(srcdir)/db/crdel_autop.c - $(CC) $(CFLAGS) $? -crdel_rec@o@: $(srcdir)/db/crdel_rec.c - $(CC) $(CFLAGS) $? -crypto@o@: $(srcdir)/crypto/crypto.c - $(CC) $(CFLAGS) $? -crypto_stub@o@: $(srcdir)/common/crypto_stub.c - $(CC) $(CFLAGS) $? -db185@o@: $(srcdir)/db185/db185.c - $(CC) $(CFLAGS) $? -db@o@: $(srcdir)/db/db.c - $(CC) $(CFLAGS) $? -db_am@o@: $(srcdir)/db/db_am.c - $(CC) $(CFLAGS) $? -db_auto@o@: $(srcdir)/db/db_auto.c - $(CC) $(CFLAGS) $? -db_autop@o@: $(srcdir)/db/db_autop.c - $(CC) $(CFLAGS) $? -db_byteorder@o@: $(srcdir)/common/db_byteorder.c - $(CC) $(CFLAGS) $? -db_cam@o@: $(srcdir)/db/db_cam.c - $(CC) $(CFLAGS) $? -db_clock@o@: $(srcdir)/common/db_clock.c - $(CC) $(CFLAGS) $? -db_conv@o@: $(srcdir)/db/db_conv.c - $(CC) $(CFLAGS) $? -db_dispatch@o@: $(srcdir)/db/db_dispatch.c - $(CC) $(CFLAGS) $? -db_dup@o@: $(srcdir)/db/db_dup.c - $(CC) $(CFLAGS) $? -db_err@o@: $(srcdir)/common/db_err.c - $(CC) $(CFLAGS) $? -db_getlong@o@: $(srcdir)/common/db_getlong.c - $(CC) $(CFLAGS) $? -db_idspace@o@: $(srcdir)/common/db_idspace.c - $(CC) $(CFLAGS) $? -db_iface@o@: $(srcdir)/db/db_iface.c - $(CC) $(CFLAGS) $? -db_join@o@: $(srcdir)/db/db_join.c - $(CC) $(CFLAGS) $? -db_log2@o@: $(srcdir)/common/db_log2.c - $(CC) $(CFLAGS) $? -db_meta@o@: $(srcdir)/db/db_meta.c - $(CC) $(CFLAGS) $? -db_method@o@: $(srcdir)/db/db_method.c - $(CC) $(CFLAGS) $? -db_open@o@: $(srcdir)/db/db_open.c - $(CC) $(CFLAGS) $? -db_overflow@o@: $(srcdir)/db/db_overflow.c - $(CC) $(CFLAGS) $? -db_ovfl_vrfy@o@: $(srcdir)/db/db_ovfl_vrfy.c - $(CC) $(CFLAGS) $? -db_pr@o@: $(srcdir)/db/db_pr.c - $(CC) $(CFLAGS) $? -db_rec@o@: $(srcdir)/db/db_rec.c - $(CC) $(CFLAGS) $? -db_reclaim@o@: $(srcdir)/db/db_reclaim.c - $(CC) $(CFLAGS) $? -db_rename@o@: $(srcdir)/db/db_rename.c - $(CC) $(CFLAGS) $? -db_remove@o@: $(srcdir)/db/db_remove.c - $(CC) $(CFLAGS) $? -db_ret@o@: $(srcdir)/db/db_ret.c - $(CC) $(CFLAGS) $? -db_setid@o@: $(srcdir)/db/db_setid.c - $(CC) $(CFLAGS) $? -db_setlsn@o@: $(srcdir)/db/db_setlsn.c - $(CC) $(CFLAGS) $? -db_salloc@o@: $(srcdir)/env/db_salloc.c - $(CC) $(CFLAGS) $? -db_shash@o@: $(srcdir)/env/db_shash.c - $(CC) $(CFLAGS) $? -db_stati@o@: $(srcdir)/db/db_stati.c - $(CC) $(CFLAGS) $? -db_truncate@o@: $(srcdir)/db/db_truncate.c - $(CC) $(CFLAGS) $? -db_upg@o@: $(srcdir)/db/db_upg.c - $(CC) $(CFLAGS) $? -db_upg_opd@o@: $(srcdir)/db/db_upg_opd.c - $(CC) $(CFLAGS) $? -db_vrfy@o@: $(srcdir)/db/db_vrfy.c - $(CC) $(CFLAGS) $? -db_vrfyutil@o@: $(srcdir)/db/db_vrfyutil.c - $(CC) $(CFLAGS) $? -db_vrfy_stub@o@: $(srcdir)/db/db_vrfy_stub.c - $(CC) $(CFLAGS) $? -dbm@o@: $(srcdir)/dbm/dbm.c - $(CC) $(CFLAGS) $? -dbreg@o@: $(srcdir)/dbreg/dbreg.c - $(CC) $(CFLAGS) $? -dbreg_auto@o@: $(srcdir)/dbreg/dbreg_auto.c - $(CC) $(CFLAGS) $? -dbreg_autop@o@: $(srcdir)/dbreg/dbreg_autop.c - $(CC) $(CFLAGS) $? -dbreg_rec@o@: $(srcdir)/dbreg/dbreg_rec.c - $(CC) $(CFLAGS) $? -dbreg_stat@o@: $(srcdir)/dbreg/dbreg_stat.c - $(CC) $(CFLAGS) $? -dbreg_util@o@: $(srcdir)/dbreg/dbreg_util.c - $(CC) $(CFLAGS) $? -env_failchk@o@: $(srcdir)/env/env_failchk.c - $(CC) $(CFLAGS) $? -env_file@o@: $(srcdir)/env/env_file.c - $(CC) $(CFLAGS) $? -env_method@o@: $(srcdir)/env/env_method.c - $(CC) $(CFLAGS) $? -env_open@o@: $(srcdir)/env/env_open.c - $(CC) $(CFLAGS) $? -env_recover@o@: $(srcdir)/env/env_recover.c - $(CC) $(CFLAGS) $? -env_region@o@: $(srcdir)/env/env_region.c - $(CC) $(CFLAGS) $? -env_register@o@: $(srcdir)/env/env_register.c - $(CC) $(CFLAGS) $? -env_stat@o@: $(srcdir)/env/env_stat.c - $(CC) $(CFLAGS) $? -fileops_auto@o@: $(srcdir)/fileops/fileops_auto.c - $(CC) $(CFLAGS) $? -fileops_autop@o@: $(srcdir)/fileops/fileops_autop.c - $(CC) $(CFLAGS) $? -fop_basic@o@: $(srcdir)/fileops/fop_basic.c - $(CC) $(CFLAGS) $? -fop_rec@o@: $(srcdir)/fileops/fop_rec.c - $(CC) $(CFLAGS) $? -fop_util@o@: $(srcdir)/fileops/fop_util.c - $(CC) $(CFLAGS) $? -hash@o@: $(srcdir)/hash/hash.c - $(CC) $(CFLAGS) $? -hash_auto@o@: $(srcdir)/hash/hash_auto.c - $(CC) $(CFLAGS) $? -hash_autop@o@: $(srcdir)/hash/hash_autop.c - $(CC) $(CFLAGS) $? -hash_conv@o@: $(srcdir)/hash/hash_conv.c - $(CC) $(CFLAGS) $? -hash_dup@o@: $(srcdir)/hash/hash_dup.c - $(CC) $(CFLAGS) $? -hash_func@o@: $(srcdir)/hash/hash_func.c - $(CC) $(CFLAGS) $? -hash_meta@o@: $(srcdir)/hash/hash_meta.c - $(CC) $(CFLAGS) $? -hash_method@o@: $(srcdir)/hash/hash_method.c - $(CC) $(CFLAGS) $? -hash_open@o@: $(srcdir)/hash/hash_open.c - $(CC) $(CFLAGS) $? -hash_page@o@: $(srcdir)/hash/hash_page.c - $(CC) $(CFLAGS) $? -hash_rec@o@: $(srcdir)/hash/hash_rec.c - $(CC) $(CFLAGS) $? -hash_reclaim@o@: $(srcdir)/hash/hash_reclaim.c - $(CC) $(CFLAGS) $? -hash_stat@o@: $(srcdir)/hash/hash_stat.c - $(CC) $(CFLAGS) $? -hash_stub@o@: $(srcdir)/hash/hash_stub.c - $(CC) $(CFLAGS) $? -hash_upgrade@o@: $(srcdir)/hash/hash_upgrade.c - $(CC) $(CFLAGS) $? -hash_verify@o@: $(srcdir)/hash/hash_verify.c - $(CC) $(CFLAGS) $? -hmac@o@: $(srcdir)/hmac/hmac.c - $(CC) $(CFLAGS) $? -hsearch@o@: $(srcdir)/hsearch/hsearch.c - $(CC) $(CFLAGS) $? -lock@o@: $(srcdir)/lock/lock.c - $(CC) $(CFLAGS) $? -lock_deadlock@o@:$(srcdir)/lock/lock_deadlock.c - $(CC) $(CFLAGS) $? -lock_failchk@o@:$(srcdir)/lock/lock_failchk.c - $(CC) $(CFLAGS) $? -lock_id@o@:$(srcdir)/lock/lock_id.c - $(CC) $(CFLAGS) $? -lock_list@o@:$(srcdir)/lock/lock_list.c - $(CC) $(CFLAGS) $? -lock_method@o@:$(srcdir)/lock/lock_method.c - $(CC) $(CFLAGS) $? -lock_region@o@:$(srcdir)/lock/lock_region.c - $(CC) $(CFLAGS) $? -lock_stat@o@:$(srcdir)/lock/lock_stat.c - $(CC) $(CFLAGS) $? -lock_timer@o@:$(srcdir)/lock/lock_timer.c - $(CC) $(CFLAGS) $? -lock_util@o@:$(srcdir)/lock/lock_util.c - $(CC) $(CFLAGS) $? -log@o@: $(srcdir)/log/log.c - $(CC) $(CFLAGS) $? -log_archive@o@: $(srcdir)/log/log_archive.c - $(CC) $(CFLAGS) $? -log_compare@o@: $(srcdir)/log/log_compare.c - $(CC) $(CFLAGS) $? -log_debug@o@: $(srcdir)/log/log_debug.c - $(CC) $(CFLAGS) $? -log_get@o@: $(srcdir)/log/log_get.c - $(CC) $(CFLAGS) $? -log_method@o@: $(srcdir)/log/log_method.c - $(CC) $(CFLAGS) $? -log_put@o@: $(srcdir)/log/log_put.c - $(CC) $(CFLAGS) $? -log_stat@o@: $(srcdir)/log/log_stat.c - $(CC) $(CFLAGS) $? -mp_alloc@o@: $(srcdir)/mp/mp_alloc.c - $(CC) $(CFLAGS) $? -mp_bh@o@: $(srcdir)/mp/mp_bh.c - $(CC) $(CFLAGS) $? -mp_fget@o@: $(srcdir)/mp/mp_fget.c - $(CC) $(CFLAGS) $? -mp_fmethod@o@: $(srcdir)/mp/mp_fmethod.c - $(CC) $(CFLAGS) $? -mp_fopen@o@: $(srcdir)/mp/mp_fopen.c - $(CC) $(CFLAGS) $? -mp_fput@o@: $(srcdir)/mp/mp_fput.c - $(CC) $(CFLAGS) $? -mp_fset@o@: $(srcdir)/mp/mp_fset.c - $(CC) $(CFLAGS) $? -mp_method@o@: $(srcdir)/mp/mp_method.c - $(CC) $(CFLAGS) $? -mp_region@o@: $(srcdir)/mp/mp_region.c - $(CC) $(CFLAGS) $? -mp_register@o@: $(srcdir)/mp/mp_register.c - $(CC) $(CFLAGS) $? -mp_stat@o@: $(srcdir)/mp/mp_stat.c - $(CC) $(CFLAGS) $? -mp_sync@o@: $(srcdir)/mp/mp_sync.c - $(CC) $(CFLAGS) $? -mp_trickle@o@: $(srcdir)/mp/mp_trickle.c - $(CC) $(CFLAGS) $? -mt19937db@o@: $(srcdir)/crypto/mersenne/mt19937db.c - $(CC) $(CFLAGS) $? -mut_alloc@o@: $(srcdir)/mutex/mut_alloc.c - $(CC) $(CFLAGS) $? -mut_fcntl@o@: $(srcdir)/mutex/mut_fcntl.c - $(CC) $(CFLAGS) $? -mut_method@o@: $(srcdir)/mutex/mut_method.c - $(CC) $(CFLAGS) $? -mut_pthread@o@: $(srcdir)/mutex/mut_pthread.c - $(CC) $(CFLAGS) $? -mut_region@o@: $(srcdir)/mutex/mut_region.c - $(CC) $(CFLAGS) $? -mut_stat@o@: $(srcdir)/mutex/mut_stat.c - $(CC) $(CFLAGS) $? -mut_tas@o@: $(srcdir)/mutex/mut_tas.c - $(CC) $(CFLAGS) $? -mut_win32@o@: $(srcdir)/mutex/mut_win32.c - $(CC) $(CFLAGS) $? -os_abs@o@: $(srcdir)/@OSDIR@/os_abs.c - $(CC) $(CFLAGS) $? -os_alloc@o@: $(srcdir)/os/os_alloc.c - $(CC) $(CFLAGS) $? -os_clock@o@: $(srcdir)/@OSDIR@/os_clock.c - $(CC) $(CFLAGS) $? -os_config@o@: $(srcdir)/@OSDIR@/os_config.c - $(CC) $(CFLAGS) $? -os_dir@o@: $(srcdir)/@OSDIR@/os_dir.c - $(CC) $(CFLAGS) $? -os_errno@o@: $(srcdir)/@OSDIR@/os_errno.c - $(CC) $(CFLAGS) $? -os_fid@o@: $(srcdir)/@OSDIR@/os_fid.c - $(CC) $(CFLAGS) $? -os_flock@o@: $(srcdir)/@OSDIR@/os_flock.c - $(CC) $(CFLAGS) $? -os_fsync@o@: $(srcdir)/@OSDIR@/os_fsync.c - $(CC) $(CFLAGS) $? -os_id@o@: $(srcdir)/os/os_id.c - $(CC) $(CFLAGS) $? -os_handle@o@: $(srcdir)/@OSDIR@/os_handle.c - $(CC) $(CFLAGS) $? -os_map@o@: $(srcdir)/@OSDIR@/os_map.c - $(CC) $(CFLAGS) $? -os_method@o@: $(srcdir)/os/os_method.c - $(CC) $(CFLAGS) $? -os_mkdir@o@: $(srcdir)/os/os_mkdir.c - $(CC) $(CFLAGS) $? -os_oflags@o@: $(srcdir)/os/os_oflags.c - $(CC) $(CFLAGS) $? -os_open@o@: $(srcdir)/@OSDIR@/os_open.c - $(CC) $(CFLAGS) $? -os_region@o@: $(srcdir)/os/os_region.c - $(CC) $(CFLAGS) $? -os_rename@o@: $(srcdir)/@OSDIR@/os_rename.c - $(CC) $(CFLAGS) $? -os_root@o@: $(srcdir)/os/os_root.c - $(CC) $(CFLAGS) $? -os_rpath@o@: $(srcdir)/os/os_rpath.c - $(CC) $(CFLAGS) $? -os_rw@o@: $(srcdir)/@OSDIR@/os_rw.c - $(CC) $(CFLAGS) $? -os_seek@o@: $(srcdir)/@OSDIR@/os_seek.c - $(CC) $(CFLAGS) $? -os_sleep@o@: $(srcdir)/@OSDIR@/os_sleep.c - $(CC) $(CFLAGS) $? -os_spin@o@: $(srcdir)/@OSDIR@/os_spin.c - $(CC) $(CFLAGS) $? -os_stat@o@: $(srcdir)/@OSDIR@/os_stat.c - $(CC) $(CFLAGS) $? -os_tmpdir@o@: $(srcdir)/os/os_tmpdir.c - $(CC) $(CFLAGS) $? -os_truncate@o@: $(srcdir)/@OSDIR@/os_truncate.c - $(CC) $(CFLAGS) $? -os_unlink@o@: $(srcdir)/os/os_unlink.c - $(CC) $(CFLAGS) $? -qam@o@: $(srcdir)/qam/qam.c - $(CC) $(CFLAGS) $? -qam_auto@o@: $(srcdir)/qam/qam_auto.c - $(CC) $(CFLAGS) $? -qam_autop@o@: $(srcdir)/qam/qam_autop.c - $(CC) $(CFLAGS) $? -qam_conv@o@: $(srcdir)/qam/qam_conv.c - $(CC) $(CFLAGS) $? -qam_files@o@: $(srcdir)/qam/qam_files.c - $(CC) $(CFLAGS) $? -qam_method@o@: $(srcdir)/qam/qam_method.c - $(CC) $(CFLAGS) $? -qam_open@o@: $(srcdir)/qam/qam_open.c - $(CC) $(CFLAGS) $? -qam_rec@o@: $(srcdir)/qam/qam_rec.c - $(CC) $(CFLAGS) $? -qam_stat@o@: $(srcdir)/qam/qam_stat.c - $(CC) $(CFLAGS) $? -qam_stub@o@: $(srcdir)/qam/qam_stub.c - $(CC) $(CFLAGS) $? -qam_upgrade@o@: $(srcdir)/qam/qam_upgrade.c - $(CC) $(CFLAGS) $? -qam_verify@o@: $(srcdir)/qam/qam_verify.c - $(CC) $(CFLAGS) $? -rep_auto@o@: $(srcdir)/rep/rep_auto.c - $(CC) $(CFLAGS) $? -rep_autop@o@: $(srcdir)/rep/rep_autop.c - $(CC) $(CFLAGS) $? -rep_backup@o@: $(srcdir)/rep/rep_backup.c - $(CC) $(CFLAGS) $? -rep_elect@o@: $(srcdir)/rep/rep_elect.c - $(CC) $(CFLAGS) $? -rep_log@o@: $(srcdir)/rep/rep_log.c - $(CC) $(CFLAGS) $? -rep_method@o@: $(srcdir)/rep/rep_method.c - $(CC) $(CFLAGS) $? -rep_record@o@: $(srcdir)/rep/rep_record.c - $(CC) $(CFLAGS) $? -rep_region@o@: $(srcdir)/rep/rep_region.c - $(CC) $(CFLAGS) $? -rep_stub@o@: $(srcdir)/rep/rep_stub.c - $(CC) $(CFLAGS) $? -rep_stat@o@: $(srcdir)/rep/rep_stat.c - $(CC) $(CFLAGS) $? -rep_util@o@: $(srcdir)/rep/rep_util.c - $(CC) $(CFLAGS) $? -rep_verify@o@: $(srcdir)/rep/rep_verify.c - $(CC) $(CFLAGS) $? -rijndael-alg-fst@o@: $(srcdir)/crypto/rijndael/rijndael-alg-fst.c - $(CC) $(CFLAGS) $? -rijndael-api-fst@o@: $(srcdir)/crypto/rijndael/rijndael-api-fst.c - $(CC) $(CFLAGS) $? -seq_stat@o@: $(srcdir)/sequence/seq_stat.c - $(CC) $(CFLAGS) $? -sequence@o@: $(srcdir)/sequence/sequence.c - $(CC) $(CFLAGS) $? -sha1@o@: $(srcdir)/hmac/sha1.c - $(CC) $(CFLAGS) $? -stat_stub@o@: $(srcdir)/common/stat_stub.c - $(CC) $(CFLAGS) $? -txn@o@: $(srcdir)/txn/txn.c - $(CC) $(CFLAGS) $? -txn_auto@o@: $(srcdir)/txn/txn_auto.c - $(CC) $(CFLAGS) $? -txn_autop@o@: $(srcdir)/txn/txn_autop.c - $(CC) $(CFLAGS) $? -txn_chkpt@o@: $(srcdir)/txn/txn_chkpt.c - $(CC) $(CFLAGS) $? -txn_failchk@o@: $(srcdir)/txn/txn_failchk.c - $(CC) $(CFLAGS) $? -txn_method@o@: $(srcdir)/txn/txn_method.c - $(CC) $(CFLAGS) $? -txn_rec@o@: $(srcdir)/txn/txn_rec.c - $(CC) $(CFLAGS) $? -txn_recover@o@: $(srcdir)/txn/txn_recover.c - $(CC) $(CFLAGS) $? -txn_region@o@: $(srcdir)/txn/txn_region.c - $(CC) $(CFLAGS) $? -txn_stat@o@: $(srcdir)/txn/txn_stat.c - $(CC) $(CFLAGS) $? -txn_util@o@: $(srcdir)/txn/txn_util.c - $(CC) $(CFLAGS) $? -util_cache@o@: $(srcdir)/common/util_cache.c - $(CC) $(CFLAGS) $? -util_log@o@: $(srcdir)/common/util_log.c - $(CC) $(CFLAGS) $? -util_sig@o@: $(srcdir)/common/util_sig.c - $(CC) $(CFLAGS) $? -uts4_cc@o@: $(srcdir)/mutex/uts4_cc.s - $(AS) $(ASFLAGS) -o $@ $? -xa@o@: $(srcdir)/xa/xa.c - $(CC) $(CFLAGS) $? -xa_db@o@: $(srcdir)/xa/xa_db.c - $(CC) $(CFLAGS) $? -xa_map@o@: $(srcdir)/xa/xa_map.c - $(CC) $(CFLAGS) $? - -################################################## -# C++ API build rules. -################################################## -cxx_db@o@: $(srcdir)/cxx/cxx_db.cpp - $(CXX) $(CXXFLAGS) $? -cxx_dbc@o@: $(srcdir)/cxx/cxx_dbc.cpp - $(CXX) $(CXXFLAGS) $? -cxx_dbt@o@: $(srcdir)/cxx/cxx_dbt.cpp - $(CXX) $(CXXFLAGS) $? -cxx_env@o@: $(srcdir)/cxx/cxx_env.cpp - $(CXX) $(CXXFLAGS) $? -cxx_except@o@: $(srcdir)/cxx/cxx_except.cpp - $(CXX) $(CXXFLAGS) $? -cxx_lock@o@: $(srcdir)/cxx/cxx_lock.cpp - $(CXX) $(CXXFLAGS) $? -cxx_logc@o@: $(srcdir)/cxx/cxx_logc.cpp - $(CXX) $(CXXFLAGS) $? -cxx_mpool@o@: $(srcdir)/cxx/cxx_mpool.cpp - $(CXX) $(CXXFLAGS) $? -cxx_multi@o@: $(srcdir)/cxx/cxx_multi.cpp - $(CXX) $(CXXFLAGS) $? -cxx_seq@o@: $(srcdir)/cxx/cxx_seq.cpp - $(CXX) $(CXXFLAGS) $? -cxx_txn@o@: $(srcdir)/cxx/cxx_txn.cpp - $(CXX) $(CXXFLAGS) $? - -################################################## -# Java API build rules. -################################################## -db_java_wrap@o@: $(srcdir)/libdb_java/db_java_wrap.c - $(CC) $(CFLAGS) $? - -################################################## -# Tcl API build rules. -################################################## -tcl_compat@o@: $(srcdir)/tcl/tcl_compat.c - $(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $? -tcl_db@o@: $(srcdir)/tcl/tcl_db.c - $(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $? -tcl_db_pkg@o@: $(srcdir)/tcl/tcl_db_pkg.c - $(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $? -tcl_dbcursor@o@: $(srcdir)/tcl/tcl_dbcursor.c - $(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $? -tcl_env@o@: $(srcdir)/tcl/tcl_env.c - $(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $? -tcl_internal@o@: $(srcdir)/tcl/tcl_internal.c - $(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $? -tcl_lock@o@: $(srcdir)/tcl/tcl_lock.c - $(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $? -tcl_log@o@: $(srcdir)/tcl/tcl_log.c - $(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $? -tcl_mp@o@: $(srcdir)/tcl/tcl_mp.c - $(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $? -tcl_rep@o@: $(srcdir)/tcl/tcl_rep.c - $(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $? -tcl_seq@o@: $(srcdir)/tcl/tcl_seq.c - $(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $? -tcl_txn@o@: $(srcdir)/tcl/tcl_txn.c - $(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $? -tcl_util@o@: $(srcdir)/tcl/tcl_util.c - $(CC) $(CFLAGS) $(TCL_INCLUDE_SPEC) $? - -################################################## -# RPC build rules. -################################################## -# RPC client files -client@o@: $(srcdir)/rpc_client/client.c - $(CC) $(CFLAGS) $? -db_server_clnt@o@: db_server_clnt.c - $(CC) $(CFLAGS) $? -gen_client@o@: $(srcdir)/rpc_client/gen_client.c - $(CC) $(CFLAGS) $? -gen_client_ret@o@: $(srcdir)/rpc_client/gen_client_ret.c - $(CC) $(CFLAGS) $? - -# RPC server files -db_server_proc@o@: $(srcdir)/rpc_server/c/db_server_proc.c - $(CC) $(CFLAGS) $? -db_server_svc@o@: db_server_svc.c - $(CC) $(CFLAGS) $? -db_server_util@o@: $(srcdir)/rpc_server/c/db_server_util.c - $(CC) $(CFLAGS) $? -db_server_xdr@o@: db_server_xdr.c - $(CC) $(CFLAGS) $? -gen_db_server@o@: gen_db_server.c - $(CC) $(CFLAGS) $? -db_server_cxxproc@o@: $(srcdir)/rpc_server/cxx/db_server_cxxproc.cpp - $(CXX) $(CXXFLAGS) $? -db_server_cxxutil@o@: $(srcdir)/rpc_server/cxx/db_server_cxxutil.cpp - $(CXX) $(CXXFLAGS) $? - -################################################## -# Utility build rules. -################################################## -db_archive@o@: $(srcdir)/db_archive/db_archive.c - $(CC) $(CFLAGS) $? -db_checkpoint@o@: $(srcdir)/db_checkpoint/db_checkpoint.c - $(CC) $(CFLAGS) $? -db_deadlock@o@: $(srcdir)/db_deadlock/db_deadlock.c - $(CC) $(CFLAGS) $? -db_dump@o@: $(srcdir)/db_dump/db_dump.c - $(CC) $(CFLAGS) $? -db_dump185@o@: $(srcdir)/db_dump185/db_dump185.c - $(CC) $(DB185INC) $? -db_hotbackup@o@: $(srcdir)/db_hotbackup/db_hotbackup.c - $(CC) $(CFLAGS) $? -db_load@o@: $(srcdir)/db_load/db_load.c - $(CC) $(CFLAGS) $? -db_printlog@o@: $(srcdir)/db_printlog/db_printlog.c - $(CC) $(CFLAGS) $? -db_recover@o@: $(srcdir)/db_recover/db_recover.c - $(CC) $(CFLAGS) $? -db_stat@o@: $(srcdir)/db_stat/db_stat.c - $(CC) $(CFLAGS) $? -db_upgrade@o@: $(srcdir)/db_upgrade/db_upgrade.c - $(CC) $(CFLAGS) $? -db_verify@o@: $(srcdir)/db_verify/db_verify.c - $(CC) $(CFLAGS) $? - -################################################## -# C library replacement files. -################################################## -getcwd@o@: $(srcdir)/clib/getcwd.c - $(CC) $(CFLAGS) $? -getopt@o@: $(srcdir)/clib/getopt.c - $(CC) $(CFLAGS) $? -memcmp@o@: $(srcdir)/clib/memcmp.c - $(CC) $(CFLAGS) $? -memcpy@o@: $(srcdir)/clib/memmove.c - $(CC) -DMEMCOPY $(CFLAGS) $? -o $@ -memmove@o@: $(srcdir)/clib/memmove.c - $(CC) -DMEMMOVE $(CFLAGS) $? -raise@o@: $(srcdir)/clib/raise.c - $(CC) $(CFLAGS) $? -strcasecmp@o@: $(srcdir)/clib/strcasecmp.c - $(CC) $(CFLAGS) $? -strdup@o@: $(srcdir)/clib/strdup.c - $(CC) $(CFLAGS) $? -snprintf@o@: $(srcdir)/clib/snprintf.c - $(CC) $(CFLAGS) $? -strerror@o@: $(srcdir)/clib/strerror.c - $(CC) $(CFLAGS) $? -strtol@o@: $(srcdir)/clib/strtol.c - $(CC) $(CFLAGS) $? -strtoul@o@: $(srcdir)/clib/strtoul.c - $(CC) $(CFLAGS) $? diff --git a/storage/bdb/dist/RELEASE b/storage/bdb/dist/RELEASE deleted file mode 100644 index e20f91edeb2..00000000000 --- a/storage/bdb/dist/RELEASE +++ /dev/null @@ -1,11 +0,0 @@ -# $Id: RELEASE,v 12.17 2005/11/12 17:43:39 bostic Exp $ - -DB_VERSION_MAJOR=4 -DB_VERSION_MINOR=4 -DB_VERSION_PATCH=16 -DB_VERSION="$DB_VERSION_MAJOR.$DB_VERSION_MINOR.$DB_VERSION_PATCH" - -DB_VERSION_UNIQUE_NAME=`printf "_%d%03d" $DB_VERSION_MAJOR $DB_VERSION_MINOR` - -DB_RELEASE_DATE=`date "+%B %e, %Y"` -DB_VERSION_STRING="Sleepycat Software: Berkeley DB $DB_VERSION: ($DB_RELEASE_DATE)" diff --git a/storage/bdb/dist/aclocal/config.ac b/storage/bdb/dist/aclocal/config.ac deleted file mode 100644 index 717a0becc2f..00000000000 --- a/storage/bdb/dist/aclocal/config.ac +++ /dev/null @@ -1,62 +0,0 @@ -# Features we don't test for, but want the #defines to exist for -# other ports. -AH_TEMPLATE(DB_WIN32, - [We use DB_WIN32 much as one would use _WIN32 -- to specify that - we're using an operating system environment that supports Win32 - calls and semantics. We don't use _WIN32 because Cygwin/GCC also - defines _WIN32, even though Cygwin/GCC closely emulates the Unix - environment.]) - -AH_TEMPLATE(HAVE_VXWORKS, [Define to 1 if building VxWorks.]) - -AH_TEMPLATE(HAVE_FILESYSTEM_NOTZERO, - [Define to 1 if allocated filesystem blocks are not zeroed.]) - -AH_TEMPLATE(HAVE_UNLINK_WITH_OPEN_FAILURE, - [Define to 1 if unlink of file with open file descriptors will fail.]) - -AH_BOTTOM([/* - * Exit success/failure macros. - */ -#ifndef HAVE_EXIT_SUCCESS -#define EXIT_FAILURE 1 -#define EXIT_SUCCESS 0 -#endif - -/* - * Don't step on the namespace. Other libraries may have their own - * implementations of these functions, we don't want to use their - * implementations or force them to use ours based on the load order. - */ -#ifndef HAVE_GETCWD -#define getcwd __db_Cgetcwd -#endif -#ifndef HAVE_MEMCMP -#define memcmp __db_Cmemcmp -#endif -#ifndef HAVE_MEMCPY -#define memcpy __db_Cmemcpy -#endif -#ifndef HAVE_MEMMOVE -#define memmove __db_Cmemmove -#endif -#ifndef HAVE_RAISE -#define raise __db_Craise -#endif -#ifndef HAVE_SNPRINTF -#define snprintf __db_Csnprintf -#endif -#ifndef HAVE_STRCASECMP -#define strcasecmp __db_Cstrcasecmp -#define strncasecmp __db_Cstrncasecmp -#endif -#ifndef HAVE_STRERROR -#define strerror __db_Cstrerror -#endif -#ifndef HAVE_VSNPRINTF -#define vsnprintf __db_Cvsnprintf -#endif - -#ifdef DB_WIN32 -#include "win_db.h" -#endif]) diff --git a/storage/bdb/dist/aclocal/cxx.ac b/storage/bdb/dist/aclocal/cxx.ac deleted file mode 100644 index 49103cc661a..00000000000 --- a/storage/bdb/dist/aclocal/cxx.ac +++ /dev/null @@ -1,17 +0,0 @@ -# C++ checks to determine what style of headers to use and -# whether to use "using" clauses. - -AC_DEFUN(AC_CXX_HAVE_STDHEADERS, [ -AC_SUBST(cxx_have_stdheaders) -AC_CACHE_CHECK([whether C++ supports the ISO C++ standard includes], -db_cv_cxx_have_stdheaders, -[AC_LANG_SAVE - AC_LANG_CPLUSPLUS - AC_TRY_COMPILE([#include <iostream> -],[std::ostream *o; return 0;], - db_cv_cxx_have_stdheaders=yes, db_cv_cxx_have_stdheaders=no) - AC_LANG_RESTORE -]) -if test "$db_cv_cxx_have_stdheaders" = yes; then - cxx_have_stdheaders="#define HAVE_CXX_STDHEADERS 1" -fi]) diff --git a/storage/bdb/dist/aclocal/gcc.ac b/storage/bdb/dist/aclocal/gcc.ac deleted file mode 100644 index 0949d982f17..00000000000 --- a/storage/bdb/dist/aclocal/gcc.ac +++ /dev/null @@ -1,36 +0,0 @@ -# Version 2.96 of gcc (shipped with RedHat Linux 7.[01] and Mandrake) had -# serious problems. -AC_DEFUN(AC_GCC_CONFIG1, [ -AC_CACHE_CHECK([whether we are using gcc version 2.96], -db_cv_gcc_2_96, [ -db_cv_gcc_2_96=no -if test "$GCC" = "yes"; then - GCC_VERSION=`${MAKEFILE_CC} --version` - case ${GCC_VERSION} in - 2.96*) - db_cv_gcc_2_96=yes;; - esac -fi]) -if test "$db_cv_gcc_2_96" = "yes"; then - CFLAGS=`echo "$CFLAGS" | sed 's/-O2/-O/'` - CXXFLAGS=`echo "$CXXFLAGS" | sed 's/-O2/-O/'` - AC_MSG_WARN([INSTALLED GCC COMPILER HAS SERIOUS BUGS; PLEASE UPGRADE.]) - AC_MSG_WARN([GCC OPTIMIZATION LEVEL SET TO -O.]) -fi]) - -# Versions of g++ up to 2.8.0 required -fhandle-exceptions, but it is -# renamed as -fexceptions and is the default in versions 2.8.0 and after. -AC_DEFUN(AC_GCC_CONFIG2, [ -AC_CACHE_CHECK([whether g++ requires -fhandle-exceptions], -db_cv_gxx_except, [ -db_cv_gxx_except=no; -if test "$GXX" = "yes"; then - GXX_VERSION=`${MAKEFILE_CXX} --version` - case ${GXX_VERSION} in - 1.*|2.[[01234567]].*|*-1.*|*-2.[[01234567]].*) - db_cv_gxx_except=yes;; - esac -fi]) -if test "$db_cv_gxx_except" = "yes"; then - CXXFLAGS="$CXXFLAGS -fhandle-exceptions" -fi]) diff --git a/storage/bdb/dist/aclocal/libtool.ac b/storage/bdb/dist/aclocal/libtool.ac deleted file mode 100644 index 771b86f32dd..00000000000 --- a/storage/bdb/dist/aclocal/libtool.ac +++ /dev/null @@ -1,6184 +0,0 @@ -# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- -## Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005 -## Free Software Foundation, Inc. -## Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996 -## -## This file is free software; the Free Software Foundation gives -## unlimited permission to copy and/or distribute it, with or without -## modifications, as long as this notice is preserved. - -# serial 47 AC_PROG_LIBTOOL - - -# AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED) -# ----------------------------------------------------------- -# If this macro is not defined by Autoconf, define it here. -m4_ifdef([AC_PROVIDE_IFELSE], - [], - [m4_define([AC_PROVIDE_IFELSE], - [m4_ifdef([AC_PROVIDE_$1], - [$2], [$3])])]) - - -# AC_PROG_LIBTOOL -# --------------- -AC_DEFUN([AC_PROG_LIBTOOL], -[AC_REQUIRE([_AC_PROG_LIBTOOL])dnl -dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX -dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX. - AC_PROVIDE_IFELSE([AC_PROG_CXX], - [AC_LIBTOOL_CXX], - [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX - ])]) -dnl And a similar setup for Fortran 77 support - AC_PROVIDE_IFELSE([AC_PROG_F77], - [AC_LIBTOOL_F77], - [define([AC_PROG_F77], defn([AC_PROG_F77])[AC_LIBTOOL_F77 -])]) - -dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly. -dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run -dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both. - AC_PROVIDE_IFELSE([AC_PROG_GCJ], - [AC_LIBTOOL_GCJ], - [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], - [AC_LIBTOOL_GCJ], - [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ], - [AC_LIBTOOL_GCJ], - [ifdef([AC_PROG_GCJ], - [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ])]) - ifdef([A][M_PROG_GCJ], - [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ])]) - ifdef([LT_AC_PROG_GCJ], - [define([LT_AC_PROG_GCJ], - defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])])]) -])])# AC_PROG_LIBTOOL - - -# _AC_PROG_LIBTOOL -# ---------------- -AC_DEFUN([_AC_PROG_LIBTOOL], -[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl -AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl -AC_BEFORE([$0],[AC_LIBTOOL_F77])dnl -AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl - -# This can be used to rebuild libtool when needed -LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" - -# Always use our own libtool. -LIBTOOL='$(SHELL) $(top_builddir)/libtool' -AC_SUBST(LIBTOOL)dnl - -# Prevent multiple expansion -define([AC_PROG_LIBTOOL], []) -])# _AC_PROG_LIBTOOL - - -# AC_LIBTOOL_SETUP -# ---------------- -AC_DEFUN([AC_LIBTOOL_SETUP], -[AC_PREREQ(2.50)dnl -AC_REQUIRE([AC_ENABLE_SHARED])dnl -AC_REQUIRE([AC_ENABLE_STATIC])dnl -AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl -AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_PROG_LD])dnl -AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl -AC_REQUIRE([AC_PROG_NM])dnl - -AC_REQUIRE([AC_PROG_LN_S])dnl -AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl -# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! -AC_REQUIRE([AC_OBJEXT])dnl -AC_REQUIRE([AC_EXEEXT])dnl -dnl - -AC_LIBTOOL_SYS_MAX_CMD_LEN -AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE -AC_LIBTOOL_OBJDIR - -AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl -_LT_AC_PROG_ECHO_BACKSLASH - -case $host_os in -aix3*) - # AIX sometimes has problems with the GCC collect2 program. For some - # reason, if we set the COLLECT_NAMES environment variable, the problems - # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES - fi - ;; -esac - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -Xsed='sed -e 1s/^X//' -[sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'] - -# Same as above, but do not quote variable references. -[double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'] - -# Sed substitution to delay expansion of an escaped shell variable in a -# double_quote_subst'ed string. -delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' - -# Sed substitution to avoid accidental globbing in evaled expressions -no_glob_subst='s/\*/\\\*/g' - -# Constants: -rm="rm -f" - -# Global variables: -default_ofile=libtool -can_build_shared=yes - -# All known linkers require a `.a' archive for static linking (except MSVC, -# which needs '.lib'). -libext=a -ltmain="$ac_aux_dir/ltmain.sh" -ofile="$default_ofile" -with_gnu_ld="$lt_cv_prog_gnu_ld" - -AC_CHECK_TOOL(AR, ar, false) -AC_CHECK_TOOL(RANLIB, ranlib, :) -AC_CHECK_TOOL(STRIP, strip, :) - -old_CC="$CC" -old_CFLAGS="$CFLAGS" - -# Set sane defaults for various variables -test -z "$AR" && AR=ar -test -z "$AR_FLAGS" && AR_FLAGS=cru -test -z "$AS" && AS=as -test -z "$CC" && CC=cc -test -z "$LTCC" && LTCC=$CC -test -z "$DLLTOOL" && DLLTOOL=dlltool -test -z "$LD" && LD=ld -test -z "$LN_S" && LN_S="ln -s" -test -z "$MAGIC_CMD" && MAGIC_CMD=file -test -z "$NM" && NM=nm -test -z "$SED" && SED=sed -test -z "$OBJDUMP" && OBJDUMP=objdump -test -z "$RANLIB" && RANLIB=: -test -z "$STRIP" && STRIP=: -test -z "$ac_objext" && ac_objext=o - -# Determine commands to create old-style static archives. -old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' -old_postinstall_cmds='chmod 644 $oldlib' -old_postuninstall_cmds= - -if test -n "$RANLIB"; then - case $host_os in - openbsd*) - old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds" - ;; - *) - old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" - ;; - esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" -fi - -_LT_CC_BASENAME([$compiler]) - -# Only perform the check for file, if the check method requires it -case $deplibs_check_method in -file_magic*) - if test "$file_magic_cmd" = '$MAGIC_CMD'; then - AC_PATH_MAGIC - fi - ;; -esac - -AC_PROVIDE_IFELSE([AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no) -AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], -enable_win32_dll=yes, enable_win32_dll=no) - -AC_ARG_ENABLE([libtool-lock], - [AC_HELP_STRING([--disable-libtool-lock], - [avoid locking (might break parallel builds)])]) -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes - -AC_ARG_WITH([pic], - [AC_HELP_STRING([--with-pic], - [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], - [pic_mode="$withval"], - [pic_mode=default]) -test -z "$pic_mode" && pic_mode=default - -# Use C for the default configuration in the libtool script -tagname= -AC_LIBTOOL_LANG_C_CONFIG -_LT_AC_TAGCONFIG -])# AC_LIBTOOL_SETUP - - -# _LT_AC_SYS_COMPILER -# ------------------- -AC_DEFUN([_LT_AC_SYS_COMPILER], -[AC_REQUIRE([AC_PROG_CC])dnl - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# Allow CC to be a program name with arguments. -compiler=$CC -])# _LT_AC_SYS_COMPILER - - -# _LT_CC_BASENAME(CC) -# ------------------- -# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. -AC_DEFUN([_LT_CC_BASENAME], -[for cc_temp in $1""; do - case $cc_temp in - compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; - distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` -]) - - -# _LT_COMPILER_BOILERPLATE -# ------------------------ -# Check for compiler boilerplate output or warnings with -# the simple compiler test code. -AC_DEFUN([_LT_COMPILER_BOILERPLATE], -[ac_outfile=conftest.$ac_objext -printf "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err -_lt_compiler_boilerplate=`cat conftest.err` -$rm conftest* -])# _LT_COMPILER_BOILERPLATE - - -# _LT_LINKER_BOILERPLATE -# ---------------------- -# Check for linker boilerplate output or warnings with -# the simple link test code. -AC_DEFUN([_LT_LINKER_BOILERPLATE], -[ac_outfile=conftest.$ac_objext -printf "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err -_lt_linker_boilerplate=`cat conftest.err` -$rm conftest* -])# _LT_LINKER_BOILERPLATE - - -# _LT_AC_SYS_LIBPATH_AIX -# ---------------------- -# Links a minimal program and checks the executable -# for the system default hardcoded library path. In most cases, -# this is /usr/lib:/lib, but when the MPI compilers are used -# the location of the communication and MPI libs are included too. -# If we don't find anything, use the default library path according -# to the aix ld manual. -AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX], -[AC_LINK_IFELSE(AC_LANG_PROGRAM,[ -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'`; fi],[]) -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi -])# _LT_AC_SYS_LIBPATH_AIX - - -# _LT_AC_SHELL_INIT(ARG) -# ---------------------- -AC_DEFUN([_LT_AC_SHELL_INIT], -[ifdef([AC_DIVERSION_NOTICE], - [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], - [AC_DIVERT_PUSH(NOTICE)]) -$1 -AC_DIVERT_POP -])# _LT_AC_SHELL_INIT - - -# _LT_AC_PROG_ECHO_BACKSLASH -# -------------------------- -# Add some code to the start of the generated configure script which -# will find an echo command which doesn't interpret backslashes. -AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH], -[_LT_AC_SHELL_INIT([ -# Check that we are running under the correct shell. -SHELL=${CONFIG_SHELL-/bin/sh} - -case X$ECHO in -X*--fallback-echo) - # Remove one level of quotation (which was required for Make). - ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` - ;; -esac - -echo=${ECHO-echo} -if test "X[$]1" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift -elif test "X[$]1" = X--fallback-echo; then - # Avoid inline document here, it may be left over - : -elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then - # Yippee, $echo works! - : -else - # Restart under the correct shell. - exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} -fi - -if test "X[$]1" = X--fallback-echo; then - # used as fallback echo - shift - cat <<EOF -[$]* -EOF - exit 0 -fi - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -if test -z "$ECHO"; then -if test "X${echo_test_string+set}" != Xset; then -# find a string as large as possible, as long as the shell can cope with it - for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do - # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... - if (echo_test_string=`eval $cmd`) 2>/dev/null && - echo_test_string=`eval $cmd` && - (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null - then - break - fi - done -fi - -if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - : -else - # The Solaris, AIX, and Digital Unix default echo programs unquote - # backslashes. This makes it impossible to quote backslashes using - # echo "$something" | sed 's/\\/\\\\/g' - # - # So, first we look for a working echo in the user's PATH. - - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for dir in $PATH /usr/ucb; do - IFS="$lt_save_ifs" - if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && - test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - echo="$dir/echo" - break - fi - done - IFS="$lt_save_ifs" - - if test "X$echo" = Xecho; then - # We didn't find a better echo, so look for alternatives. - if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - # This shell has a builtin print -r that does the trick. - echo='print -r' - elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && - test "X$CONFIG_SHELL" != X/bin/ksh; then - # If we have ksh, try running configure again with it. - ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} - export ORIGINAL_CONFIG_SHELL - CONFIG_SHELL=/bin/ksh - export CONFIG_SHELL - exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} - else - # Try using printf. - echo='printf %s\n' - if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - # Cool, printf works - : - elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && - test "X$echo_testing_string" = 'X\t' && - echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL - export CONFIG_SHELL - SHELL="$CONFIG_SHELL" - export SHELL - echo="$CONFIG_SHELL [$]0 --fallback-echo" - elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && - test "X$echo_testing_string" = 'X\t' && - echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - echo="$CONFIG_SHELL [$]0 --fallback-echo" - else - # maybe with a smaller string... - prev=: - - for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do - if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null - then - break - fi - prev="$cmd" - done - - if test "$prev" != 'sed 50q "[$]0"'; then - echo_test_string=`eval $prev` - export echo_test_string - exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} - else - # Oops. We lost completely, so just stick with echo. - echo=echo - fi - fi - fi - fi -fi -fi - -# Copy echo and quote the copy suitably for passing to libtool from -# the Makefile, instead of quoting the original, which is used later. -ECHO=$echo -if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then - ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" -fi - -AC_SUBST(ECHO) -])])# _LT_AC_PROG_ECHO_BACKSLASH - - -# _LT_AC_LOCK -# ----------- -AC_DEFUN([_LT_AC_LOCK], -[AC_ARG_ENABLE([libtool-lock], - [AC_HELP_STRING([--disable-libtool-lock], - [avoid locking (might break parallel builds)])]) -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes - -# Some flags need to be propagated to the compiler or linker for good -# libtool support. -case $host in -ia64-*-hpux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.$ac_objext` in - *ELF-32*) - HPUX_IA64_MODE="32" - ;; - *ELF-64*) - HPUX_IA64_MODE="64" - ;; - esac - fi - rm -rf conftest* - ;; -*-*-irix6*) - # Find out which ABI we are using. - echo '[#]line __oline__ "configure"' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - if test "$lt_cv_prog_gnu_ld" = yes; then - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -melf32bsmip" - ;; - *N32*) - LD="${LD-ld} -melf32bmipn32" - ;; - *64-bit*) - LD="${LD-ld} -melf64bmip" - ;; - esac - else - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -32" - ;; - *N32*) - LD="${LD-ld} -n32" - ;; - *64-bit*) - LD="${LD-ld} -64" - ;; - esac - fi - fi - rm -rf conftest* - ;; - -x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in - *32-bit*) - case $host in - x86_64-*linux*) - LD="${LD-ld} -m elf_i386" - ;; - ppc64-*linux*|powerpc64-*linux*) - LD="${LD-ld} -m elf32ppclinux" - ;; - s390x-*linux*) - LD="${LD-ld} -m elf_s390" - ;; - sparc64-*linux*) - LD="${LD-ld} -m elf32_sparc" - ;; - esac - ;; - *64-bit*) - case $host in - x86_64-*linux*) - LD="${LD-ld} -m elf_x86_64" - ;; - ppc*-*linux*|powerpc*-*linux*) - LD="${LD-ld} -m elf64ppc" - ;; - s390*-*linux*) - LD="${LD-ld} -m elf64_s390" - ;; - sparc*-*linux*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; - -*-*-sco3.2v5*) - # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -belf" - AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, - [AC_LANG_PUSH(C) - AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) - AC_LANG_POP]) - if test x"$lt_cv_cc_needs_belf" != x"yes"; then - # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS="$SAVE_CFLAGS" - fi - ;; -AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], -[*-*-cygwin* | *-*-mingw* | *-*-pw32*) - AC_CHECK_TOOL(DLLTOOL, dlltool, false) - AC_CHECK_TOOL(AS, as, false) - AC_CHECK_TOOL(OBJDUMP, objdump, false) - ;; - ]) -esac - -need_locks="$enable_libtool_lock" - -])# _LT_AC_LOCK - - -# AC_LIBTOOL_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, -# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) -# ---------------------------------------------------------------- -# Check whether the given compiler option works -AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], -[AC_REQUIRE([LT_AC_PROG_SED]) -AC_CACHE_CHECK([$1], [$2], - [$2=no - ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$3" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&AS_MESSAGE_LOG_FD - echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $echo "X$_lt_compiler_boilerplate" | $Xsed >conftest.exp - $SED '/^$/d' conftest.err >conftest.er2 - if test ! -s conftest.err || diff conftest.exp conftest.er2 >/dev/null; then - $2=yes - fi - fi - $rm conftest* -]) - -if test x"[$]$2" = xyes; then - ifelse([$5], , :, [$5]) -else - ifelse([$6], , :, [$6]) -fi -])# AC_LIBTOOL_COMPILER_OPTION - - -# AC_LIBTOOL_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, -# [ACTION-SUCCESS], [ACTION-FAILURE]) -# ------------------------------------------------------------ -# Check whether the given compiler option works -AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], -[AC_CACHE_CHECK([$1], [$2], - [$2=no - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $3" - printf "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The linker can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&AS_MESSAGE_LOG_FD - $echo "X$_lt_linker_boilerplate" | $Xsed > conftest.exp - $SED '/^$/d' conftest.err >conftest.er2 - if diff conftest.exp conftest.er2 >/dev/null; then - $2=yes - fi - else - $2=yes - fi - fi - $rm conftest* - LDFLAGS="$save_LDFLAGS" -]) - -if test x"[$]$2" = xyes; then - ifelse([$4], , :, [$4]) -else - ifelse([$5], , :, [$5]) -fi -])# AC_LIBTOOL_LINKER_OPTION - - -# AC_LIBTOOL_SYS_MAX_CMD_LEN -# -------------------------- -AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], -[# find the maximum length of command line arguments -AC_MSG_CHECKING([the maximum length of command line arguments]) -AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl - i=0 - teststring="ABCD" - - case $build_os in - msdosdjgpp*) - # On DJGPP, this test can blow up pretty badly due to problems in libc - # (any single argument exceeding 2000 bytes causes a buffer overrun - # during glob expansion). Even if it were fixed, the result of this - # check would be larger than it should be. - lt_cv_sys_max_cmd_len=12288; # 12K is about right - ;; - - gnu*) - # Under GNU Hurd, this test is not required because there is - # no limit to the length of command line arguments. - # Libtool will interpret -1 as no limit whatsoever - lt_cv_sys_max_cmd_len=-1; - ;; - - cygwin* | mingw*) - # On Win9x/ME, this test blows up -- it succeeds, but takes - # about 5 minutes as the teststring grows exponentially. - # Worse, since 9x/ME are not pre-emptively multitasking, - # you end up with a "frozen" computer, even though with patience - # the test eventually succeeds (with a max line length of 256k). - # Instead, let's just punt: use the minimum linelength reported by - # all of the supported platforms: 8192 (on NT/2K/XP). - lt_cv_sys_max_cmd_len=8192; - ;; - - amigaos*) - # On AmigaOS with pdksh, this test takes hours, literally. - # So we just punt and use a minimum line length of 8192. - lt_cv_sys_max_cmd_len=8192; - ;; - - netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) - # This has been around since 386BSD, at least. Likely further. - if test -x /sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` - elif test -x /usr/sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` - else - lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs - fi - # And add a safety zone - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - ;; - osf*) - # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure - # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not - # nice to cause kernel panics so lets avoid the loop below. - # First set a reasonable default. - lt_cv_sys_max_cmd_len=16384 - # - if test -x /sbin/sysconfig; then - case `/sbin/sysconfig -q proc exec_disable_arg_limit` in - *1*) lt_cv_sys_max_cmd_len=-1 ;; - esac - fi - ;; - *) - # If test is not a shell built-in, we'll probably end up computing a - # maximum length that is only half of the actual maximum length, but - # we can't tell. - SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} - while (test "X"`$SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \ - = "XX$teststring") >/dev/null 2>&1 && - new_result=`expr "X$teststring" : ".*" 2>&1` && - lt_cv_sys_max_cmd_len=$new_result && - test $i != 17 # 1/2 MB should be enough - do - i=`expr $i + 1` - teststring=$teststring$teststring - done - teststring= - # Add a significant safety factor because C++ compilers can tack on massive - # amounts of additional arguments before passing them to the linker. - # It appears as though 1/2 is a usable value. - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` - ;; - esac -]) -if test -n $lt_cv_sys_max_cmd_len ; then - AC_MSG_RESULT($lt_cv_sys_max_cmd_len) -else - AC_MSG_RESULT(none) -fi -])# AC_LIBTOOL_SYS_MAX_CMD_LEN - - -# _LT_AC_CHECK_DLFCN -# -------------------- -AC_DEFUN([_LT_AC_CHECK_DLFCN], -[AC_CHECK_HEADERS(dlfcn.h)dnl -])# _LT_AC_CHECK_DLFCN - - -# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, -# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) -# ------------------------------------------------------------------ -AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF], -[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl -if test "$cross_compiling" = yes; then : - [$4] -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<EOF -[#line __oline__ "configure" -#include "confdefs.h" - -#if HAVE_DLFCN_H -#include <dlfcn.h> -#endif - -#include <stdio.h> - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -#ifdef __cplusplus -extern "C" void exit (int); -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - - exit (status); -}] -EOF - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) $1 ;; - x$lt_dlneed_uscore) $2 ;; - x$lt_unknown|x*) $3 ;; - esac - else : - # compilation failed - $3 - fi -fi -rm -fr conftest* -])# _LT_AC_TRY_DLOPEN_SELF - - -# AC_LIBTOOL_DLOPEN_SELF -# ------------------- -AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], -[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl -if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32*) - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen="dlopen" - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ - lt_cv_dlopen="dyld" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ]) - ;; - - *) - AC_CHECK_FUNC([shl_load], - [lt_cv_dlopen="shl_load"], - [AC_CHECK_LIB([dld], [shl_load], - [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"], - [AC_CHECK_FUNC([dlopen], - [lt_cv_dlopen="dlopen"], - [AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], - [AC_CHECK_LIB([svld], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], - [AC_CHECK_LIB([dld], [dld_link], - [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) - ]) - ]) - ]) - ]) - ]) - ;; - esac - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else - enable_dlopen=no - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS="$LDFLAGS" - eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS="$LIBS" - LIBS="$lt_cv_dlopen_libs $LIBS" - - AC_CACHE_CHECK([whether a program can dlopen itself], - lt_cv_dlopen_self, [dnl - _LT_AC_TRY_DLOPEN_SELF( - lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, - lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) - ]) - - if test "x$lt_cv_dlopen_self" = xyes; then - LDFLAGS="$LDFLAGS $link_static_flag" - AC_CACHE_CHECK([whether a statically linked program can dlopen itself], - lt_cv_dlopen_self_static, [dnl - _LT_AC_TRY_DLOPEN_SELF( - lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, - lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) - ]) - fi - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi -])# AC_LIBTOOL_DLOPEN_SELF - - -# AC_LIBTOOL_PROG_CC_C_O([TAGNAME]) -# --------------------------------- -# Check to see if options -c and -o are simultaneously supported by compiler -AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O], -[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl -AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], - [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)], - [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no - $rm -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&AS_MESSAGE_LOG_FD - echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $echo "X$_lt_compiler_boilerplate" | $Xsed > out/conftest.exp - $SED '/^$/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.err || diff out/conftest.exp out/conftest.er2 >/dev/null; then - _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes - fi - fi - chmod u+w . 2>&AS_MESSAGE_LOG_FD - $rm conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files - $rm out/* && rmdir out - cd .. - rmdir conftest - $rm conftest* -]) -])# AC_LIBTOOL_PROG_CC_C_O - - -# AC_LIBTOOL_SYS_HARD_LINK_LOCKS([TAGNAME]) -# ----------------------------------------- -# Check to see if we can do hard links to lock some files if needed -AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], -[AC_REQUIRE([_LT_AC_LOCK])dnl - -hard_links="nottested" -if test "$_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - AC_MSG_CHECKING([if we can lock with hard links]) - hard_links=yes - $rm conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - AC_MSG_RESULT([$hard_links]) - if test "$hard_links" = no; then - AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) - need_locks=warn - fi -else - need_locks=no -fi -])# AC_LIBTOOL_SYS_HARD_LINK_LOCKS - - -# AC_LIBTOOL_OBJDIR -# ----------------- -AC_DEFUN([AC_LIBTOOL_OBJDIR], -[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], -[rm -f .libs 2>/dev/null -mkdir .libs 2>/dev/null -if test -d .libs; then - lt_cv_objdir=.libs -else - # MS-DOS does not allow filenames that begin with a dot. - lt_cv_objdir=_libs -fi -rmdir .libs 2>/dev/null]) -objdir=$lt_cv_objdir -])# AC_LIBTOOL_OBJDIR - - -# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([TAGNAME]) -# ---------------------------------------------- -# Check hardcoding attributes. -AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], -[AC_MSG_CHECKING([how to hardcode library paths into programs]) -_LT_AC_TAGVAR(hardcode_action, $1)= -if test -n "$_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)" || \ - test -n "$_LT_AC_TAGVAR(runpath_var, $1)" || \ - test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then - - # We can hardcode non-existant directories. - if test "$_LT_AC_TAGVAR(hardcode_direct, $1)" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)" != no && - test "$_LT_AC_TAGVAR(hardcode_minus_L, $1)" != no; then - # Linking always hardcodes the temporary library directory. - _LT_AC_TAGVAR(hardcode_action, $1)=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - _LT_AC_TAGVAR(hardcode_action, $1)=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - _LT_AC_TAGVAR(hardcode_action, $1)=unsupported -fi -AC_MSG_RESULT([$_LT_AC_TAGVAR(hardcode_action, $1)]) - -if test "$_LT_AC_TAGVAR(hardcode_action, $1)" = relink; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi -])# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH - - -# AC_LIBTOOL_SYS_LIB_STRIP -# ------------------------ -AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP], -[striplib= -old_striplib= -AC_MSG_CHECKING([whether stripping libraries is possible]) -if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - AC_MSG_RESULT([yes]) -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) -fi - ;; - *) - AC_MSG_RESULT([no]) - ;; - esac -fi -])# AC_LIBTOOL_SYS_LIB_STRIP - - -# AC_LIBTOOL_SYS_DYNAMIC_LINKER -# ----------------------------- -# PORTME Fill in your ld.so characteristics -AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER], -[AC_MSG_CHECKING([dynamic linker characteristics]) -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext_cmds=".so" -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - -case $host_os in -aix3*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' - ;; - -aix4* | aix5*) - version_type=linux - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test "$host_cpu" = ia64; then - # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[[01]] | aix4.[[01]].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then - # If using run time linking (on AIX 4.2 or later) use lib<name>.so - # instead of lib<name>.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - -beos*) - library_names_spec='${libname}${shared_ext}' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi[[45]]*) - version_type=linux - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32*) - version_type=windows - shrext_cmds=".dll" - need_version=no - need_lib_prefix=no - - case $GCC,$host_os in - yes,cygwin* | yes,mingw* | yes,pw32*) - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $rm \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" - ;; - mingw*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if echo "$sys_lib_search_path_spec" | [grep ';[c-zC-Z]:/' >/dev/null]; then - # It is most probably a Windows format PATH printed by - # mingw gcc, but we are running on Cygwin. Gcc prints its search - # path with ; separators, and with drive letters. We can handle the - # drive letters (cygwin fileutils understands them), so leave them, - # especially as we might pass files found there to a mingw objdump, - # which wouldn't understand a cygwinified path. Ahh. - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - ;; - esac - ;; - - *) - library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' - ;; - esac - dynamic_linker='Win32 ld.exe' - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' - # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. - if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` - else - sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' - fi - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd1*) - dynamic_linker=no - ;; - -kfreebsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - -freebsd* | dragonfly*) - # DragonFly does not have aout. When/if they implement a new - # versioning mechanism, adjust this. - if test -x /usr/bin/objformat; then - objformat=`/usr/bin/objformat` - else - case $host_os in - freebsd[[123]]*) objformat=aout ;; - *) objformat=elf ;; - esac - fi - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.[[01]]* | freebsdelf3.[[01]]*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - *) # from 3.2 on - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - esac - ;; - -gnu*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case $host_cpu in - ia64*) - shrext_cmds='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - hppa*64*) - shrext_cmds='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext_cmds='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555. - postinstall_cmds='chmod 555 $lib' - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -# This must be Linux ELF. -linux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # Append ld.so.conf contents to the search path - if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -knetbsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -nto-qnx*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -openbsd*) - version_type=sunos - need_lib_prefix=no - # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. - case $host_os in - openbsd3.3 | openbsd3.3.*) need_version=yes ;; - *) need_version=no ;; - esac - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[[89]] | openbsd2.[[89]].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi - ;; - -os2*) - libname_spec='$name' - shrext_cmds=".dll" - need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - -sco3.2v5*) - version_type=osf - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - ;; - -solaris*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - export_dynamic_flag_spec='${wl}-Blargedynsym' - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -uts4*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -AC_MSG_RESULT([$dynamic_linker]) -test "$dynamic_linker" = no && can_build_shared=no -])# AC_LIBTOOL_SYS_DYNAMIC_LINKER - - -# _LT_AC_TAGCONFIG -# ---------------- -AC_DEFUN([_LT_AC_TAGCONFIG], -[AC_ARG_WITH([tags], - [AC_HELP_STRING([--with-tags@<:@=TAGS@:>@], - [include additional configurations @<:@automatic@:>@])], - [tagnames="$withval"]) - -if test -f "$ltmain" && test -n "$tagnames"; then - if test ! -f "${ofile}"; then - AC_MSG_WARN([output file `$ofile' does not exist]) - fi - - if test -z "$LTCC"; then - eval "`$SHELL ${ofile} --config | grep '^LTCC='`" - if test -z "$LTCC"; then - AC_MSG_WARN([output file `$ofile' does not look like a libtool script]) - else - AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile']) - fi - fi - - # Extract list of available tagged configurations in $ofile. - # Note that this assumes the entire list is on one line. - available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'` - - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for tagname in $tagnames; do - IFS="$lt_save_ifs" - # Check whether tagname contains only valid characters - case `$echo "X$tagname" | $Xsed -e 's:[[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]]::g'` in - "") ;; - *) AC_MSG_ERROR([invalid tag name: $tagname]) - ;; - esac - - if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null - then - AC_MSG_ERROR([tag name \"$tagname\" already exists]) - fi - - # Update the list of available tags. - if test -n "$tagname"; then - echo appending configuration tag \"$tagname\" to $ofile - - case $tagname in - CXX) - if test -n "$CXX" && ( test "X$CXX" != "Xno" && - ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || - (test "X$CXX" != "Xg++"))) ; then - AC_LIBTOOL_LANG_CXX_CONFIG - else - tagname="" - fi - ;; - - F77) - if test -n "$F77" && test "X$F77" != "Xno"; then - AC_LIBTOOL_LANG_F77_CONFIG - else - tagname="" - fi - ;; - - GCJ) - if test -n "$GCJ" && test "X$GCJ" != "Xno"; then - AC_LIBTOOL_LANG_GCJ_CONFIG - else - tagname="" - fi - ;; - - RC) - AC_LIBTOOL_LANG_RC_CONFIG - ;; - - *) - AC_MSG_ERROR([Unsupported tag name: $tagname]) - ;; - esac - - # Append the new tag name to the list of available tags. - if test -n "$tagname" ; then - available_tags="$available_tags $tagname" - fi - fi - done - IFS="$lt_save_ifs" - - # Now substitute the updated list of available tags. - if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then - mv "${ofile}T" "$ofile" - chmod +x "$ofile" - else - rm -f "${ofile}T" - AC_MSG_ERROR([unable to update list of available tagged configurations.]) - fi -fi -])# _LT_AC_TAGCONFIG - - -# AC_LIBTOOL_DLOPEN -# ----------------- -# enable checks for dlopen support -AC_DEFUN([AC_LIBTOOL_DLOPEN], - [AC_BEFORE([$0],[AC_LIBTOOL_SETUP]) -])# AC_LIBTOOL_DLOPEN - - -# AC_LIBTOOL_WIN32_DLL -# -------------------- -# declare package support for building win32 DLLs -AC_DEFUN([AC_LIBTOOL_WIN32_DLL], -[AC_BEFORE([$0], [AC_LIBTOOL_SETUP]) -])# AC_LIBTOOL_WIN32_DLL - - -# AC_ENABLE_SHARED([DEFAULT]) -# --------------------------- -# implement the --enable-shared flag -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. -AC_DEFUN([AC_ENABLE_SHARED], -[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl -AC_ARG_ENABLE([shared], - [AC_HELP_STRING([--enable-shared@<:@=PKGS@:>@], - [build shared libraries @<:@default=]AC_ENABLE_SHARED_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_shared=yes ;; - no) enable_shared=no ;; - *) - enable_shared=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_shared=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [enable_shared=]AC_ENABLE_SHARED_DEFAULT) -])# AC_ENABLE_SHARED - - -# AC_DISABLE_SHARED -# ----------------- -#- set the default shared flag to --disable-shared -AC_DEFUN([AC_DISABLE_SHARED], -[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl -AC_ENABLE_SHARED(no) -])# AC_DISABLE_SHARED - - -# AC_ENABLE_STATIC([DEFAULT]) -# --------------------------- -# implement the --enable-static flag -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. -AC_DEFUN([AC_ENABLE_STATIC], -[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl -AC_ARG_ENABLE([static], - [AC_HELP_STRING([--enable-static@<:@=PKGS@:>@], - [build static libraries @<:@default=]AC_ENABLE_STATIC_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_static=yes ;; - no) enable_static=no ;; - *) - enable_static=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_static=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [enable_static=]AC_ENABLE_STATIC_DEFAULT) -])# AC_ENABLE_STATIC - - -# AC_DISABLE_STATIC -# ----------------- -# set the default static flag to --disable-static -AC_DEFUN([AC_DISABLE_STATIC], -[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl -AC_ENABLE_STATIC(no) -])# AC_DISABLE_STATIC - - -# AC_ENABLE_FAST_INSTALL([DEFAULT]) -# --------------------------------- -# implement the --enable-fast-install flag -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. -AC_DEFUN([AC_ENABLE_FAST_INSTALL], -[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl -AC_ARG_ENABLE([fast-install], - [AC_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], - [optimize for fast installation @<:@default=]AC_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], - [p=${PACKAGE-default} - case $enableval in - yes) enable_fast_install=yes ;; - no) enable_fast_install=no ;; - *) - enable_fast_install=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_fast_install=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], - [enable_fast_install=]AC_ENABLE_FAST_INSTALL_DEFAULT) -])# AC_ENABLE_FAST_INSTALL - - -# AC_DISABLE_FAST_INSTALL -# ----------------------- -# set the default to --disable-fast-install -AC_DEFUN([AC_DISABLE_FAST_INSTALL], -[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl -AC_ENABLE_FAST_INSTALL(no) -])# AC_DISABLE_FAST_INSTALL - - -# AC_LIBTOOL_PICMODE([MODE]) -# -------------------------- -# implement the --with-pic flag -# MODE is either `yes' or `no'. If omitted, it defaults to `both'. -AC_DEFUN([AC_LIBTOOL_PICMODE], -[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl -pic_mode=ifelse($#,1,$1,default) -])# AC_LIBTOOL_PICMODE - - -# AC_PROG_EGREP -# ------------- -# This is predefined starting with Autoconf 2.54, so this conditional -# definition can be removed once we require Autoconf 2.54 or later. -m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP], -[AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep], - [if echo a | (grep -E '(a|b)') >/dev/null 2>&1 - then ac_cv_prog_egrep='grep -E' - else ac_cv_prog_egrep='egrep' - fi]) - EGREP=$ac_cv_prog_egrep - AC_SUBST([EGREP]) -])]) - - -# AC_PATH_TOOL_PREFIX -# ------------------- -# find a file program which can recognise shared library -AC_DEFUN([AC_PATH_TOOL_PREFIX], -[AC_REQUIRE([AC_PROG_EGREP])dnl -AC_MSG_CHECKING([for $1]) -AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, -[case $MAGIC_CMD in -[[\\/*] | ?:[\\/]*]) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR -dnl $ac_dummy forces splitting on constant user-supplied paths. -dnl POSIX.2 word splitting is done only on the output of word expansions, -dnl not every word. This closes a longstanding sh security hole. - ac_dummy="ifelse([$2], , $PATH, [$2])" - for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$1; then - lt_cv_path_MAGIC_CMD="$ac_dir/$1" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <<EOF 1>&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -EOF - fi ;; - esac - fi - break - fi - done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" - ;; -esac]) -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - AC_MSG_RESULT($MAGIC_CMD) -else - AC_MSG_RESULT(no) -fi -])# AC_PATH_TOOL_PREFIX - - -# AC_PATH_MAGIC -# ------------- -# find a file program which can recognise a shared library -AC_DEFUN([AC_PATH_MAGIC], -[AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) -if test -z "$lt_cv_path_MAGIC_CMD"; then - if test -n "$ac_tool_prefix"; then - AC_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) - else - MAGIC_CMD=: - fi -fi -])# AC_PATH_MAGIC - - -# AC_PROG_LD -# ---------- -# find the pathname to the GNU or non-GNU linker -AC_DEFUN([AC_PROG_LD], -[AC_ARG_WITH([gnu-ld], - [AC_HELP_STRING([--with-gnu-ld], - [assume the C compiler uses GNU ld @<:@default=no@:>@])], - [test "$withval" = no || with_gnu_ld=yes], - [with_gnu_ld=no]) -AC_REQUIRE([LT_AC_PROG_SED])dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - AC_MSG_CHECKING([for ld used by $CC]) - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [[\\/]]* | ?:[[\\/]]*) - re_direlt='/[[^/]][[^/]]*/\.\./' - # Canonicalize the pathname of ld - ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` - while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do - ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - AC_MSG_CHECKING([for GNU ld]) -else - AC_MSG_CHECKING([for non-GNU ld]) -fi -AC_CACHE_VAL(lt_cv_path_LD, -[if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some variants of GNU ld only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in - *GNU* | *'with BFD'*) - test "$with_gnu_ld" != no && break - ;; - *) - test "$with_gnu_ld" != yes && break - ;; - esac - fi - done - IFS="$lt_save_ifs" -else - lt_cv_path_LD="$LD" # Let the user override the test with a path. -fi]) -LD="$lt_cv_path_LD" -if test -n "$LD"; then - AC_MSG_RESULT($LD) -else - AC_MSG_RESULT(no) -fi -test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) -AC_PROG_LD_GNU -])# AC_PROG_LD - - -# AC_PROG_LD_GNU -# -------------- -AC_DEFUN([AC_PROG_LD_GNU], -[AC_REQUIRE([AC_PROG_EGREP])dnl -AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld, -[# I'd rather use --version here, but apparently some GNU lds only accept -v. -case `$LD -v 2>&1 </dev/null` in -*GNU* | *'with BFD'*) - lt_cv_prog_gnu_ld=yes - ;; -*) - lt_cv_prog_gnu_ld=no - ;; -esac]) -with_gnu_ld=$lt_cv_prog_gnu_ld -])# AC_PROG_LD_GNU - - -# AC_PROG_LD_RELOAD_FLAG -# ---------------------- -# find reload flag for linker -# -- PORTME Some linkers may need a different reload flag. -AC_DEFUN([AC_PROG_LD_RELOAD_FLAG], -[AC_CACHE_CHECK([for $LD option to reload object files], - lt_cv_ld_reload_flag, - [lt_cv_ld_reload_flag='-r']) -reload_flag=$lt_cv_ld_reload_flag -case $reload_flag in -"" | " "*) ;; -*) reload_flag=" $reload_flag" ;; -esac -reload_cmds='$LD$reload_flag -o $output$reload_objs' -case $host_os in - darwin*) - if test "$GCC" = yes; then - reload_cmds='$CC -nostdlib ${wl}-r -o $output$reload_objs' - else - reload_cmds='$LD$reload_flag -o $output$reload_objs' - fi - ;; -esac -])# AC_PROG_LD_RELOAD_FLAG - - -# AC_DEPLIBS_CHECK_METHOD -# ----------------------- -# how to check for library dependencies -# -- PORTME fill in with the dynamic library characteristics -AC_DEFUN([AC_DEPLIBS_CHECK_METHOD], -[AC_CACHE_CHECK([how to recognise dependent libraries], -lt_cv_deplibs_check_method, -[lt_cv_file_magic_cmd='$MAGIC_CMD' -lt_cv_file_magic_test_file= -lt_cv_deplibs_check_method='unknown' -# Need to set the preceding variable on all platforms that support -# interlibrary dependencies. -# 'none' -- dependencies not supported. -# `unknown' -- same as none, but documents that we really don't know. -# 'pass_all' -- all dependencies passed with no checks. -# 'test_compile' -- check by making test program. -# 'file_magic [[regex]]' -- check by looking for files in library path -# which responds to the $file_magic_cmd with a given extended regex. -# If you have `file' or equivalent on your system and you're not sure -# whether `pass_all' will *always* work, you probably want this one. - -case $host_os in -aix4* | aix5*) - lt_cv_deplibs_check_method=pass_all - ;; - -beos*) - lt_cv_deplibs_check_method=pass_all - ;; - -bsdi[[45]]*) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' - lt_cv_file_magic_cmd='/usr/bin/file -L' - lt_cv_file_magic_test_file=/shlib/libc.so - ;; - -cygwin*) - # func_win32_libid is a shell function defined in ltmain.sh - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - ;; - -mingw* | pw32*) - # Base MSYS/MinGW do not provide the 'file' command needed by - # func_win32_libid shell function, so use a weaker test based on 'objdump'. - lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' - ;; - -darwin* | rhapsody*) - lt_cv_deplibs_check_method=pass_all - ;; - -freebsd* | kfreebsd*-gnu | dragonfly*) - if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then - case $host_cpu in - i*86 ) - # Not sure whether the presence of OpenBSD here was a mistake. - # Let's accept both of them until this is cleared up. - lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` - ;; - esac - else - lt_cv_deplibs_check_method=pass_all - fi - ;; - -gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - -hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file - case $host_cpu in - ia64*) - lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' - lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so - ;; - hppa*64*) - [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] - lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl - ;; - *) - lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' - lt_cv_file_magic_test_file=/usr/lib/libc.sl - ;; - esac - ;; - -irix5* | irix6* | nonstopux*) - case $LD in - *-32|*"-32 ") libmagic=32-bit;; - *-n32|*"-n32 ") libmagic=N32;; - *-64|*"-64 ") libmagic=64-bit;; - *) libmagic=never-match;; - esac - lt_cv_deplibs_check_method=pass_all - ;; - -# This must be Linux ELF. -linux*) - lt_cv_deplibs_check_method=pass_all - ;; - -netbsd*) - if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' - fi - ;; - -newos6*) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=/usr/lib/libnls.so - ;; - -nto-qnx*) - lt_cv_deplibs_check_method=unknown - ;; - -openbsd*) - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' - fi - ;; - -osf3* | osf4* | osf5*) - lt_cv_deplibs_check_method=pass_all - ;; - -sco3.2v5*) - lt_cv_deplibs_check_method=pass_all - ;; - -solaris*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - case $host_vendor in - motorola) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` - ;; - ncr) - lt_cv_deplibs_check_method=pass_all - ;; - sequent) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' - ;; - sni) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" - lt_cv_file_magic_test_file=/lib/libc.so - ;; - siemens) - lt_cv_deplibs_check_method=pass_all - ;; - esac - ;; - -sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7* | sysv4*uw2*) - lt_cv_deplibs_check_method=pass_all - ;; -esac -]) -file_magic_cmd=$lt_cv_file_magic_cmd -deplibs_check_method=$lt_cv_deplibs_check_method -test -z "$deplibs_check_method" && deplibs_check_method=unknown -])# AC_DEPLIBS_CHECK_METHOD - - -# AC_PROG_NM -# ---------- -# find the pathname to a BSD-compatible name lister -AC_DEFUN([AC_PROG_NM], -[AC_CACHE_CHECK([for BSD-compatible nm], lt_cv_path_NM, -[if test -n "$NM"; then - # Let the user override the test. - lt_cv_path_NM="$NM" -else - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - tmp_nm="$ac_dir/${ac_tool_prefix}nm" - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - # Tru64's nm complains that /dev/null is an invalid object file - case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in - */dev/null* | *'Invalid file or object type'*) - lt_cv_path_NM="$tmp_nm -B" - break - ;; - *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in - */dev/null*) - lt_cv_path_NM="$tmp_nm -p" - break - ;; - *) - lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags - ;; - esac - esac - fi - done - IFS="$lt_save_ifs" - test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm -fi]) -NM="$lt_cv_path_NM" -])# AC_PROG_NM - - -# AC_CHECK_LIBM -# ------------- -# check for math library -AC_DEFUN([AC_CHECK_LIBM], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -LIBM= -case $host in -*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*) - # These system don't have libm, or don't need it - ;; -*-ncr-sysv4.3*) - AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") - AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") - ;; -*) - AC_CHECK_LIB(m, cos, LIBM="-lm") - ;; -esac -])# AC_CHECK_LIBM - - -# AC_LIBLTDL_CONVENIENCE([DIRECTORY]) -# ----------------------------------- -# sets LIBLTDL to the link flags for the libltdl convenience library and -# LTDLINCL to the include flags for the libltdl header and adds -# --enable-ltdl-convenience to the configure arguments. Note that -# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided, -# it is assumed to be `libltdl'. LIBLTDL will be prefixed with -# '${top_builddir}/' and LTDLINCL will be prefixed with '${top_srcdir}/' -# (note the single quotes!). If your package is not flat and you're not -# using automake, define top_builddir and top_srcdir appropriately in -# the Makefiles. -AC_DEFUN([AC_LIBLTDL_CONVENIENCE], -[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl - case $enable_ltdl_convenience in - no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; - "") enable_ltdl_convenience=yes - ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; - esac - LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la - LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) - # For backwards non-gettext consistent compatibility... - INCLTDL="$LTDLINCL" -])# AC_LIBLTDL_CONVENIENCE - - -# AC_LIBLTDL_INSTALLABLE([DIRECTORY]) -# ----------------------------------- -# sets LIBLTDL to the link flags for the libltdl installable library and -# LTDLINCL to the include flags for the libltdl header and adds -# --enable-ltdl-install to the configure arguments. Note that -# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided, -# and an installed libltdl is not found, it is assumed to be `libltdl'. -# LIBLTDL will be prefixed with '${top_builddir}/'# and LTDLINCL with -# '${top_srcdir}/' (note the single quotes!). If your package is not -# flat and you're not using automake, define top_builddir and top_srcdir -# appropriately in the Makefiles. -# In the future, this macro may have to be called after AC_PROG_LIBTOOL. -AC_DEFUN([AC_LIBLTDL_INSTALLABLE], -[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl - AC_CHECK_LIB(ltdl, lt_dlinit, - [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], - [if test x"$enable_ltdl_install" = xno; then - AC_MSG_WARN([libltdl not installed, but installation disabled]) - else - enable_ltdl_install=yes - fi - ]) - if test x"$enable_ltdl_install" = x"yes"; then - ac_configure_args="$ac_configure_args --enable-ltdl-install" - LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la - LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) - else - ac_configure_args="$ac_configure_args --enable-ltdl-install=no" - LIBLTDL="-lltdl" - LTDLINCL= - fi - # For backwards non-gettext consistent compatibility... - INCLTDL="$LTDLINCL" -])# AC_LIBLTDL_INSTALLABLE - - -# AC_LIBTOOL_CXX -# -------------- -# enable support for C++ libraries -AC_DEFUN([AC_LIBTOOL_CXX], -[AC_REQUIRE([_LT_AC_LANG_CXX]) -])# AC_LIBTOOL_CXX - - -# _LT_AC_LANG_CXX -# --------------- -AC_DEFUN([_LT_AC_LANG_CXX], -[AC_REQUIRE([AC_PROG_CXX]) -AC_REQUIRE([_LT_AC_PROG_CXXCPP]) -_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX]) -])# _LT_AC_LANG_CXX - -# _LT_AC_PROG_CXXCPP -# --------------- -AC_DEFUN([_LT_AC_PROG_CXXCPP], -[ -AC_REQUIRE([AC_PROG_CXX]) -if test -n "$CXX" && ( test "X$CXX" != "Xno" && - ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || - (test "X$CXX" != "Xg++"))) ; then - AC_PROG_CXXCPP -fi -])# _LT_AC_PROG_CXXCPP - -# AC_LIBTOOL_F77 -# -------------- -# enable support for Fortran 77 libraries -AC_DEFUN([AC_LIBTOOL_F77], -[AC_REQUIRE([_LT_AC_LANG_F77]) -])# AC_LIBTOOL_F77 - - -# _LT_AC_LANG_F77 -# --------------- -AC_DEFUN([_LT_AC_LANG_F77], -[AC_REQUIRE([AC_PROG_F77]) -_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}F77]) -])# _LT_AC_LANG_F77 - - -# AC_LIBTOOL_GCJ -# -------------- -# enable support for GCJ libraries -AC_DEFUN([AC_LIBTOOL_GCJ], -[AC_REQUIRE([_LT_AC_LANG_GCJ]) -])# AC_LIBTOOL_GCJ - - -# _LT_AC_LANG_GCJ -# --------------- -AC_DEFUN([_LT_AC_LANG_GCJ], -[AC_PROVIDE_IFELSE([AC_PROG_GCJ],[], - [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[], - [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[], - [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])], - [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])], - [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])]) -_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}GCJ]) -])# _LT_AC_LANG_GCJ - - -# AC_LIBTOOL_RC -# -------------- -# enable support for Windows resource files -AC_DEFUN([AC_LIBTOOL_RC], -[AC_REQUIRE([LT_AC_PROG_RC]) -_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}RC]) -])# AC_LIBTOOL_RC - - -# AC_LIBTOOL_LANG_C_CONFIG -# ------------------------ -# Ensure that the configuration vars for the C compiler are -# suitably defined. Those variables are subsequently used by -# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. -AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG], [_LT_AC_LANG_C_CONFIG]) -AC_DEFUN([_LT_AC_LANG_C_CONFIG], -[lt_save_CC="$CC" -AC_LANG_PUSH(C) - -# Source file extension for C test sources. -ac_ext=c - -# Object file extension for compiled C test sources. -objext=o -_LT_AC_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;\n" - -# Code to be used in simple link tests -lt_simple_link_test_code='int main(){return(0);}\n' - -_LT_AC_SYS_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# -# Check for any special shared library compilation flags. -# -_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)= -if test "$GCC" = no; then - case $host_os in - sco3.2v5*) - _LT_AC_TAGVAR(lt_prog_cc_shlib, $1)='-belf' - ;; - esac -fi -if test -n "$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)"; then - AC_MSG_WARN([`$CC' requires `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to build shared libraries]) - if echo "$old_CC $old_CFLAGS " | grep "[[ ]]$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)[[ ]]" >/dev/null; then : - else - AC_MSG_WARN([add `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to the CC or CFLAGS env variable and reconfigure]) - _LT_AC_TAGVAR(lt_cv_prog_cc_can_build_shared, $1)=no - fi -fi - - -# -# Check to make sure the static flag actually works. -# -AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $_LT_AC_TAGVAR(lt_prog_compiler_static, $1) works], - _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1), - $_LT_AC_TAGVAR(lt_prog_compiler_static, $1), - [], - [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=]) - - -## CAVEAT EMPTOR: -## There is no encapsulation within the following macros, do not change -## the running order or otherwise move them around unless you know exactly -## what you are doing... -AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1) -AC_LIBTOOL_PROG_COMPILER_PIC($1) -AC_LIBTOOL_PROG_CC_C_O($1) -AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) -AC_LIBTOOL_PROG_LD_SHLIBS($1) -AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) -AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) -AC_LIBTOOL_SYS_LIB_STRIP -AC_LIBTOOL_DLOPEN_SELF($1) - -# Report which librarie types wil actually be built -AC_MSG_CHECKING([if libtool supports shared libraries]) -AC_MSG_RESULT([$can_build_shared]) - -AC_MSG_CHECKING([whether to build shared libraries]) -test "$can_build_shared" = "no" && enable_shared=no - -# On AIX, shared libraries and static libraries use the same namespace, and -# are all built from PIC. -case $host_os in -aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - -aix4* | aix5*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; -esac -AC_MSG_RESULT([$enable_shared]) - -AC_MSG_CHECKING([whether to build static libraries]) -# Make sure either enable_shared or enable_static is yes. -test "$enable_shared" = yes || enable_static=yes -AC_MSG_RESULT([$enable_static]) - -AC_LIBTOOL_CONFIG($1) - -AC_LANG_POP -CC="$lt_save_CC" -])# AC_LIBTOOL_LANG_C_CONFIG - - -# AC_LIBTOOL_LANG_CXX_CONFIG -# -------------------------- -# Ensure that the configuration vars for the C compiler are -# suitably defined. Those variables are subsequently used by -# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. -AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG], [_LT_AC_LANG_CXX_CONFIG(CXX)]) -AC_DEFUN([_LT_AC_LANG_CXX_CONFIG], -[AC_LANG_PUSH(C++) -AC_REQUIRE([AC_PROG_CXX]) -AC_REQUIRE([_LT_AC_PROG_CXXCPP]) - -_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_AC_TAGVAR(allow_undefined_flag, $1)= -_LT_AC_TAGVAR(always_export_symbols, $1)=no -_LT_AC_TAGVAR(archive_expsym_cmds, $1)= -_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_AC_TAGVAR(hardcode_direct, $1)=no -_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= -_LT_AC_TAGVAR(hardcode_libdir_separator, $1)= -_LT_AC_TAGVAR(hardcode_minus_L, $1)=no -_LT_AC_TAGVAR(hardcode_automatic, $1)=no -_LT_AC_TAGVAR(module_cmds, $1)= -_LT_AC_TAGVAR(module_expsym_cmds, $1)= -_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown -_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_AC_TAGVAR(no_undefined_flag, $1)= -_LT_AC_TAGVAR(whole_archive_flag_spec, $1)= -_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Dependencies to place before and after the object being linked: -_LT_AC_TAGVAR(predep_objects, $1)= -_LT_AC_TAGVAR(postdep_objects, $1)= -_LT_AC_TAGVAR(predeps, $1)= -_LT_AC_TAGVAR(postdeps, $1)= -_LT_AC_TAGVAR(compiler_lib_search_path, $1)= - -# Source file extension for C++ test sources. -ac_ext=cpp - -# Object file extension for compiled C++ test sources. -objext=o -_LT_AC_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;\n" - -# Code to be used in simple link tests -lt_simple_link_test_code='int main(int, char *[]) { return(0); }\n' - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_AC_SYS_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC=$CC -lt_save_LD=$LD -lt_save_GCC=$GCC -GCC=$GXX -lt_save_with_gnu_ld=$with_gnu_ld -lt_save_path_LD=$lt_cv_path_LD -if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then - lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx -else - unset lt_cv_prog_gnu_ld -fi -if test -n "${lt_cv_path_LDCXX+set}"; then - lt_cv_path_LD=$lt_cv_path_LDCXX -else - unset lt_cv_path_LD -fi -test -z "${LDCXX+set}" || LD=$LDCXX -CC=${CXX-"c++"} -compiler=$CC -_LT_AC_TAGVAR(compiler, $1)=$CC -_LT_CC_BASENAME([$compiler]) - -# We don't want -fno-exception wen compiling C++ code, so set the -# no_builtin_flag separately -if test "$GXX" = yes; then - _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' -else - _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= -fi - -if test "$GXX" = yes; then - # Set up default GNU C++ configuration - - AC_PROG_LD - - # Check if GNU C++ uses GNU ld as the underlying linker, since the - # archiving commands below assume that GNU ld is being used. - if test "$with_gnu_ld" = yes; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - - # If archive_cmds runs LD, not CC, wlarc should be empty - # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to - # investigate it a little bit more. (MM) - wlarc='${wl}' - - # ancient GNU ld didn't support --whole-archive et. al. - if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ - grep 'no-whole-archive' > /dev/null; then - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= - fi - else - with_gnu_ld=no - wlarc= - - # A generic and very simple default shared library creation - # command for GNU C++ for the case where it uses the native - # linker, instead of GNU ld. If possible, this setting should - # overridden to take advantage of the native linker features on - # the platform it is being used on. - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - fi - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' - -else - GXX=no - with_gnu_ld=no - wlarc= -fi - -# PORTME: fill in a description of your system's C++ link characteristics -AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) -_LT_AC_TAGVAR(ld_shlibs, $1)=yes -case $host_os in - aix3*) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - aix4* | aix5*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) - for ld_flag in $LDFLAGS; do - case $ld_flag in - *-brtl*) - aix_use_runtimelinking=yes - break - ;; - esac - done - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - _LT_AC_TAGVAR(archive_cmds, $1)='' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - - if test "$GXX" = yes; then - case $host_os in aix4.[[012]]|aix4.[[012]].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && \ - strings "$collect2name" | grep resolve_lib_name >/dev/null - then - # We have reworked collect2 - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - else - # We have old collect2 - _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= - fi - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - _LT_AC_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' - # Determine the default libpath from the value encoded in an empty executable. - _LT_AC_SYS_LIBPATH_AIX - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' - _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an empty executable. - _LT_AC_SYS_LIBPATH_AIX - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - # -bexpall does not export symbols beginning with underscore (_) - _LT_AC_TAGVAR(always_export_symbols, $1)=yes - # Exported symbols can be pulled into shared objects from archives - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' ' - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds its shared libraries. - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - chorus*) - case $cc_basename in - *) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - - - cygwin* | mingw* | pw32*) - # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, - # as there is no search path for DLLs. - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_AC_TAGVAR(always_export_symbols, $1)=no - _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - - if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' - else - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - darwin* | rhapsody*) - case $host_os in - rhapsody* | darwin1.[[012]]) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' - ;; - *) # Darwin 1.3 on - if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then - _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' - else - case ${MACOSX_DEPLOYMENT_TARGET} in - 10.[[012]]) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' - ;; - 10.*) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' - ;; - esac - fi - ;; - esac - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_AC_TAGVAR(hardcode_direct, $1)=no - _LT_AC_TAGVAR(hardcode_automatic, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' - _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - - if test "$GXX" = yes ; then - lt_int_apple_cc_single_mod=no - output_verbose_link_cmd='echo' - if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then - lt_int_apple_cc_single_mod=yes - fi - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - else - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - fi - _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - else - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - else - case $cc_basename in - xlc*) - output_verbose_link_cmd='echo' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' - _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - ;; - *) - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - esac - fi - ;; - - dgux*) - case $cc_basename in - ec++*) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - ghcx*) - # Green Hills C++ Compiler - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - freebsd[[12]]*) - # C++ shared libraries reported to be fairly broken before switch to ELF - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - freebsd-elf*) - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no - ;; - freebsd* | kfreebsd*-gnu | dragonfly*) - # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF - # conventions - _LT_AC_TAGVAR(ld_shlibs, $1)=yes - ;; - gnu*) - ;; - hpux9*) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - aCC*) - _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[[-]]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - ;; - *) - if test "$GXX" = yes; then - _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - hpux10*|hpux11*) - if test $with_gnu_ld = no; then - case $host_cpu in - hppa*64*) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - ia64*) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - ;; - *) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - ;; - esac - fi - case $host_cpu in - hppa*64*) - _LT_AC_TAGVAR(hardcode_direct, $1)=no - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - ia64*) - _LT_AC_TAGVAR(hardcode_direct, $1)=no - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - ;; - *) - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - ;; - esac - - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - aCC*) - case $host_cpu in - hppa*64*|ia64*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' - ;; - *) - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - ;; - *) - if test "$GXX" = yes; then - if test $with_gnu_ld = no; then - case $host_cpu in - ia64*|hppa*64*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' - ;; - *) - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - ;; - esac - fi - else - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - irix5* | irix6*) - case $cc_basename in - CC*) - # SGI C++ - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - - # Archives containing C++ object files must be created using - # "CC -ar", where "CC" is the IRIX C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' - ;; - *) - if test "$GXX" = yes; then - if test "$with_gnu_ld" = no; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' - fi - fi - _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - ;; - esac - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - linux*) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath,$libdir' - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - - # Archives containing C++ object files must be created using - # "CC -Bstatic", where "CC" is the KAI C++ compiler. - _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' - ;; - icpc*) - # Intel C++ - with_gnu_ld=yes - # version 8.0 and above of icpc choke on multiply defined symbols - # if we add $predep_objects and $postdep_objects, however 7.1 and - # earlier do not add the objects themselves. - case `$CC -V 2>&1` in - *"Version 7."*) - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - ;; - *) # Version 8.0 or newer - tmp_idyn= - case $host_cpu in - ia64*) tmp_idyn=' -i_dynamic';; - esac - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - ;; - esac - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' - ;; - pgCC*) - # Portland Group C++ compiler - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' - ;; - cxx*) - # Compaq C++ - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' - - runpath_var=LD_RUN_PATH - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - ;; - esac - ;; - lynxos*) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - m88k*) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - mvs*) - case $cc_basename in - cxx*) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - netbsd*) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' - wlarc= - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - fi - # Workaround some broken pre-1.5 toolchains - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' - ;; - openbsd2*) - # C++ shared libraries are fairly broken - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - openbsd*) - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - fi - output_verbose_link_cmd='echo' - ;; - osf3*) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - - # Archives containing C++ object files must be created using - # "CC -Bstatic", where "CC" is the KAI C++ compiler. - _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' - - ;; - RCC*) - # Rational C++ 2.4.1 - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - cxx*) - _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - ;; - *) - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' - - else - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - osf4* | osf5*) - case $cc_basename in - KCC*) - # Kuck and Associates, Inc. (KAI) C++ Compiler - - # KCC will only create a shared library if the output file - # ends with ".so" (or ".sl" for HP-UX), so rename the library - # to its proper name (with version) after linking. - _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - - # Archives containing C++ object files must be created using - # the KAI C++ compiler. - _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' - ;; - RCC*) - # Rational C++ 2.4.1 - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - cxx*) - _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ - echo "-hidden">> $lib.exp~ - $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~ - $rm $lib.exp' - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' - ;; - *) - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' - - else - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - ;; - psos*) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - sco*) - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - lcc*) - # Lucid - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - solaris*) - case $cc_basename in - CC*) - # Sun C++ 4.2, 5.x and Centerline C++ - _LT_AC_TAGVAR(archive_cmds_need_lc,$1)=yes - _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - # The C++ compiler is used as linker so we must use $wl - # flag to pass the commands to the underlying system - # linker. We must also pass each convience library through - # to the system linker between allextract/defaultextract. - # The C++ compiler will combine linker options so we - # cannot just pass the convience library names through - # without $wl. - # Supported since Solaris 2.6 (maybe 2.5.1?) - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' - ;; - esac - _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - - output_verbose_link_cmd='echo' - - # Archives containing C++ object files must be created using - # "CC -xar", where "CC" is the Sun C++ compiler. This is - # necessary to make sure instantiated templates are included - # in the archive. - _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' - ;; - gcx*) - # Green Hills C++ Compiler - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - - # The C++ compiler must be used to create the archive. - _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' - ;; - *) - # GNU C++ compiler with Solaris linker - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' - if $CC --version | grep -v '^2\.7' > /dev/null; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" - else - # g++ 2.7 appears to require `-G' NOT `-shared' on this - # platform. - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' - - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" - fi - - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' - fi - ;; - esac - ;; - sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7*) - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no - ;; - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; - vxworks*) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; -esac -AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) -test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no - -_LT_AC_TAGVAR(GCC, $1)="$GXX" -_LT_AC_TAGVAR(LD, $1)="$LD" - -## CAVEAT EMPTOR: -## There is no encapsulation within the following macros, do not change -## the running order or otherwise move them around unless you know exactly -## what you are doing... -AC_LIBTOOL_POSTDEP_PREDEP($1) -AC_LIBTOOL_PROG_COMPILER_PIC($1) -AC_LIBTOOL_PROG_CC_C_O($1) -AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) -AC_LIBTOOL_PROG_LD_SHLIBS($1) -AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) -AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) -AC_LIBTOOL_SYS_LIB_STRIP -AC_LIBTOOL_DLOPEN_SELF($1) - -AC_LIBTOOL_CONFIG($1) - -AC_LANG_POP -CC=$lt_save_CC -LDCXX=$LD -LD=$lt_save_LD -GCC=$lt_save_GCC -with_gnu_ldcxx=$with_gnu_ld -with_gnu_ld=$lt_save_with_gnu_ld -lt_cv_path_LDCXX=$lt_cv_path_LD -lt_cv_path_LD=$lt_save_path_LD -lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld -lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld -])# AC_LIBTOOL_LANG_CXX_CONFIG - -# AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME]) -# ------------------------ -# Figure out "hidden" library dependencies from verbose -# compiler output when linking a shared library. -# Parse the compiler output and extract the necessary -# objects, libraries and library flags. -AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP],[ -dnl we can't use the lt_simple_compile_test_code here, -dnl because it contains code intended for an executable, -dnl not a library. It's possible we should let each -dnl tag define a new lt_????_link_test_code variable, -dnl but it's only used here... -ifelse([$1],[],[cat > conftest.$ac_ext <<EOF -int a; -void foo (void) { a = 0; } -EOF -],[$1],[CXX],[cat > conftest.$ac_ext <<EOF -class Foo -{ -public: - Foo (void) { a = 0; } -private: - int a; -}; -EOF -],[$1],[F77],[cat > conftest.$ac_ext <<EOF - subroutine foo - implicit none - integer*4 a - a=0 - return - end -EOF -],[$1],[GCJ],[cat > conftest.$ac_ext <<EOF -public class foo { - private int a; - public void bar (void) { - a = 0; - } -}; -EOF -]) -dnl Parse the compiler output and extract the necessary -dnl objects, libraries and library flags. -if AC_TRY_EVAL(ac_compile); then - # Parse the compiler output and extract the necessary - # objects, libraries and library flags. - - # Sentinel used to keep track of whether or not we are before - # the conftest object file. - pre_test_object_deps_done=no - - # The `*' in the case matches for architectures that use `case' in - # $output_verbose_cmd can trigger glob expansion during the loop - # eval without this substitution. - output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"` - - for p in `eval $output_verbose_link_cmd`; do - case $p in - - -L* | -R* | -l*) - # Some compilers place space between "-{L,R}" and the path. - # Remove the space. - if test $p = "-L" \ - || test $p = "-R"; then - prev=$p - continue - else - prev= - fi - - if test "$pre_test_object_deps_done" = no; then - case $p in - -L* | -R*) - # Internal compiler library paths should come after those - # provided the user. The postdeps already come after the - # user supplied libs so there is no need to process them. - if test -z "$_LT_AC_TAGVAR(compiler_lib_search_path, $1)"; then - _LT_AC_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" - else - _LT_AC_TAGVAR(compiler_lib_search_path, $1)="${_LT_AC_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" - fi - ;; - # The "-l" case would never come before the object being - # linked, so don't bother handling this case. - esac - else - if test -z "$_LT_AC_TAGVAR(postdeps, $1)"; then - _LT_AC_TAGVAR(postdeps, $1)="${prev}${p}" - else - _LT_AC_TAGVAR(postdeps, $1)="${_LT_AC_TAGVAR(postdeps, $1)} ${prev}${p}" - fi - fi - ;; - - *.$objext) - # This assumes that the test object file only shows up - # once in the compiler output. - if test "$p" = "conftest.$objext"; then - pre_test_object_deps_done=yes - continue - fi - - if test "$pre_test_object_deps_done" = no; then - if test -z "$_LT_AC_TAGVAR(predep_objects, $1)"; then - _LT_AC_TAGVAR(predep_objects, $1)="$p" - else - _LT_AC_TAGVAR(predep_objects, $1)="$_LT_AC_TAGVAR(predep_objects, $1) $p" - fi - else - if test -z "$_LT_AC_TAGVAR(postdep_objects, $1)"; then - _LT_AC_TAGVAR(postdep_objects, $1)="$p" - else - _LT_AC_TAGVAR(postdep_objects, $1)="$_LT_AC_TAGVAR(postdep_objects, $1) $p" - fi - fi - ;; - - *) ;; # Ignore the rest. - - esac - done - - # Clean up. - rm -f a.out a.exe -else - echo "libtool.m4: error: problem compiling $1 test program" -fi - -$rm -f confest.$objext - -# PORTME: override above test on systems where it is broken -ifelse([$1],[CXX], -[case $host_os in -solaris*) - case $cc_basename in - CC*) - # Adding this requires a known-good setup of shared libraries for - # Sun compiler versions before 5.6, else PIC objects from an old - # archive will be linked into the output, leading to subtle bugs. - _LT_AC_TAGVAR(postdeps,$1)='-lCstd -lCrun' - ;; - esac -esac -]) - -case " $_LT_AC_TAGVAR(postdeps, $1) " in -*" -lc "*) _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ;; -esac -])# AC_LIBTOOL_POSTDEP_PREDEP - -# AC_LIBTOOL_LANG_F77_CONFIG -# ------------------------ -# Ensure that the configuration vars for the C compiler are -# suitably defined. Those variables are subsequently used by -# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. -AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG], [_LT_AC_LANG_F77_CONFIG(F77)]) -AC_DEFUN([_LT_AC_LANG_F77_CONFIG], -[AC_REQUIRE([AC_PROG_F77]) -AC_LANG_PUSH(Fortran 77) - -_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no -_LT_AC_TAGVAR(allow_undefined_flag, $1)= -_LT_AC_TAGVAR(always_export_symbols, $1)=no -_LT_AC_TAGVAR(archive_expsym_cmds, $1)= -_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= -_LT_AC_TAGVAR(hardcode_direct, $1)=no -_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= -_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= -_LT_AC_TAGVAR(hardcode_libdir_separator, $1)= -_LT_AC_TAGVAR(hardcode_minus_L, $1)=no -_LT_AC_TAGVAR(hardcode_automatic, $1)=no -_LT_AC_TAGVAR(module_cmds, $1)= -_LT_AC_TAGVAR(module_expsym_cmds, $1)= -_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown -_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_AC_TAGVAR(no_undefined_flag, $1)= -_LT_AC_TAGVAR(whole_archive_flag_spec, $1)= -_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no - -# Source file extension for f77 test sources. -ac_ext=f - -# Object file extension for compiled f77 test sources. -objext=o -_LT_AC_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code=" subroutine t\n return\n end\n" - -# Code to be used in simple link tests -lt_simple_link_test_code=" program t\n end\n" - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_AC_SYS_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC="$CC" -CC=${F77-"f77"} -compiler=$CC -_LT_AC_TAGVAR(compiler, $1)=$CC -_LT_CC_BASENAME([$compiler]) - -AC_MSG_CHECKING([if libtool supports shared libraries]) -AC_MSG_RESULT([$can_build_shared]) - -AC_MSG_CHECKING([whether to build shared libraries]) -test "$can_build_shared" = "no" && enable_shared=no - -# On AIX, shared libraries and static libraries use the same namespace, and -# are all built from PIC. -case $host_os in -aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; -aix4* | aix5*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; -esac -AC_MSG_RESULT([$enable_shared]) - -AC_MSG_CHECKING([whether to build static libraries]) -# Make sure either enable_shared or enable_static is yes. -test "$enable_shared" = yes || enable_static=yes -AC_MSG_RESULT([$enable_static]) - -test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no - -_LT_AC_TAGVAR(GCC, $1)="$G77" -_LT_AC_TAGVAR(LD, $1)="$LD" - -AC_LIBTOOL_PROG_COMPILER_PIC($1) -AC_LIBTOOL_PROG_CC_C_O($1) -AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) -AC_LIBTOOL_PROG_LD_SHLIBS($1) -AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) -AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) -AC_LIBTOOL_SYS_LIB_STRIP - - -AC_LIBTOOL_CONFIG($1) - -AC_LANG_POP -CC="$lt_save_CC" -])# AC_LIBTOOL_LANG_F77_CONFIG - - -# AC_LIBTOOL_LANG_GCJ_CONFIG -# -------------------------- -# Ensure that the configuration vars for the C compiler are -# suitably defined. Those variables are subsequently used by -# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. -AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG], [_LT_AC_LANG_GCJ_CONFIG(GCJ)]) -AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG], -[AC_LANG_SAVE - -# Source file extension for Java test sources. -ac_ext=java - -# Object file extension for compiled Java test sources. -objext=o -_LT_AC_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="class foo {}\n" - -# Code to be used in simple link tests -lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }\n' - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_AC_SYS_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC="$CC" -CC=${GCJ-"gcj"} -compiler=$CC -_LT_AC_TAGVAR(compiler, $1)=$CC -_LT_CC_BASENAME([$compiler]) - -# GCJ did not exist at the time GCC didn't implicitly link libc in. -_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no - -_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds - -## CAVEAT EMPTOR: -## There is no encapsulation within the following macros, do not change -## the running order or otherwise move them around unless you know exactly -## what you are doing... -AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1) -AC_LIBTOOL_PROG_COMPILER_PIC($1) -AC_LIBTOOL_PROG_CC_C_O($1) -AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) -AC_LIBTOOL_PROG_LD_SHLIBS($1) -AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) -AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) -AC_LIBTOOL_SYS_LIB_STRIP -AC_LIBTOOL_DLOPEN_SELF($1) - -AC_LIBTOOL_CONFIG($1) - -AC_LANG_RESTORE -CC="$lt_save_CC" -])# AC_LIBTOOL_LANG_GCJ_CONFIG - - -# AC_LIBTOOL_LANG_RC_CONFIG -# -------------------------- -# Ensure that the configuration vars for the Windows resource compiler are -# suitably defined. Those variables are subsequently used by -# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. -AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG], [_LT_AC_LANG_RC_CONFIG(RC)]) -AC_DEFUN([_LT_AC_LANG_RC_CONFIG], -[AC_LANG_SAVE - -# Source file extension for RC test sources. -ac_ext=rc - -# Object file extension for compiled RC test sources. -objext=o -_LT_AC_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }\n' - -# Code to be used in simple link tests -lt_simple_link_test_code="$lt_simple_compile_test_code" - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_AC_SYS_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC="$CC" -CC=${RC-"windres"} -compiler=$CC -_LT_AC_TAGVAR(compiler, $1)=$CC -_LT_CC_BASENAME([$compiler]) -_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes - -AC_LIBTOOL_CONFIG($1) - -AC_LANG_RESTORE -CC="$lt_save_CC" -])# AC_LIBTOOL_LANG_RC_CONFIG - - -# AC_LIBTOOL_CONFIG([TAGNAME]) -# ---------------------------- -# If TAGNAME is not passed, then create an initial libtool script -# with a default configuration from the untagged config vars. Otherwise -# add code to config.status for appending the configuration named by -# TAGNAME from the matching tagged config vars. -AC_DEFUN([AC_LIBTOOL_CONFIG], -[# The else clause should only fire when bootstrapping the -# libtool distribution, otherwise you forgot to ship ltmain.sh -# with your package, and you will get complaints that there are -# no rules to generate ltmain.sh. -if test -f "$ltmain"; then - # See if we are running on zsh, and set the options which allow our commands through - # without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST - fi - # Now quote all the things that may contain metacharacters while being - # careful not to overquote the AC_SUBSTed values. We take copies of the - # variables and quote the copies for generation of the libtool script. - for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \ - SED SHELL STRIP \ - libname_spec library_names_spec soname_spec extract_expsyms_cmds \ - old_striplib striplib file_magic_cmd finish_cmds finish_eval \ - deplibs_check_method reload_flag reload_cmds need_locks \ - lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ - lt_cv_sys_global_symbol_to_c_name_address \ - sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ - old_postinstall_cmds old_postuninstall_cmds \ - _LT_AC_TAGVAR(compiler, $1) \ - _LT_AC_TAGVAR(CC, $1) \ - _LT_AC_TAGVAR(LD, $1) \ - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1) \ - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1) \ - _LT_AC_TAGVAR(lt_prog_compiler_static, $1) \ - _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) \ - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1) \ - _LT_AC_TAGVAR(thread_safe_flag_spec, $1) \ - _LT_AC_TAGVAR(whole_archive_flag_spec, $1) \ - _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) \ - _LT_AC_TAGVAR(old_archive_cmds, $1) \ - _LT_AC_TAGVAR(old_archive_from_new_cmds, $1) \ - _LT_AC_TAGVAR(predep_objects, $1) \ - _LT_AC_TAGVAR(postdep_objects, $1) \ - _LT_AC_TAGVAR(predeps, $1) \ - _LT_AC_TAGVAR(postdeps, $1) \ - _LT_AC_TAGVAR(compiler_lib_search_path, $1) \ - _LT_AC_TAGVAR(archive_cmds, $1) \ - _LT_AC_TAGVAR(archive_expsym_cmds, $1) \ - _LT_AC_TAGVAR(postinstall_cmds, $1) \ - _LT_AC_TAGVAR(postuninstall_cmds, $1) \ - _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) \ - _LT_AC_TAGVAR(allow_undefined_flag, $1) \ - _LT_AC_TAGVAR(no_undefined_flag, $1) \ - _LT_AC_TAGVAR(export_symbols_cmds, $1) \ - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) \ - _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) \ - _LT_AC_TAGVAR(hardcode_libdir_separator, $1) \ - _LT_AC_TAGVAR(hardcode_automatic, $1) \ - _LT_AC_TAGVAR(module_cmds, $1) \ - _LT_AC_TAGVAR(module_expsym_cmds, $1) \ - _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) \ - _LT_AC_TAGVAR(exclude_expsyms, $1) \ - _LT_AC_TAGVAR(include_expsyms, $1); do - - case $var in - _LT_AC_TAGVAR(old_archive_cmds, $1) | \ - _LT_AC_TAGVAR(old_archive_from_new_cmds, $1) | \ - _LT_AC_TAGVAR(archive_cmds, $1) | \ - _LT_AC_TAGVAR(archive_expsym_cmds, $1) | \ - _LT_AC_TAGVAR(module_cmds, $1) | \ - _LT_AC_TAGVAR(module_expsym_cmds, $1) | \ - _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) | \ - _LT_AC_TAGVAR(export_symbols_cmds, $1) | \ - extract_expsyms_cmds | reload_cmds | finish_cmds | \ - postinstall_cmds | postuninstall_cmds | \ - old_postinstall_cmds | old_postuninstall_cmds | \ - sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) - # Double-quote double-evaled strings. - eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" - ;; - *) - eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" - ;; - esac - done - - case $lt_echo in - *'\[$]0 --fallback-echo"') - lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\[$]0 --fallback-echo"[$]/[$]0 --fallback-echo"/'` - ;; - esac - -ifelse([$1], [], - [cfgfile="${ofile}T" - trap "$rm \"$cfgfile\"; exit 1" 1 2 15 - $rm -f "$cfgfile" - AC_MSG_NOTICE([creating $ofile])], - [cfgfile="$ofile"]) - - cat <<__EOF__ >> "$cfgfile" -ifelse([$1], [], -[#! $SHELL - -# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) -# NOTE: Changes made to this file will be lost: look at ltmain.sh. -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 -# Free Software Foundation, Inc. -# -# This file is part of GNU Libtool: -# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996 -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# A sed program that does not truncate output. -SED=$lt_SED - -# Sed that helps us avoid accidentally triggering echo(1) options like -n. -Xsed="$SED -e 1s/^X//" - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -# The names of the tagged configurations supported by this script. -available_tags= - -# ### BEGIN LIBTOOL CONFIG], -[# ### BEGIN LIBTOOL TAG CONFIG: $tagname]) - -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: - -# Shell to use when invoking shell scripts. -SHELL=$lt_SHELL - -# Whether or not to build shared libraries. -build_libtool_libs=$enable_shared - -# Whether or not to build static libraries. -build_old_libs=$enable_static - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=$_LT_AC_TAGVAR(archive_cmds_need_lc, $1) - -# Whether or not to disallow shared libs when runtime libs are static -allow_libtool_libs_with_static_runtimes=$_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) - -# Whether or not to optimize for fast installation. -fast_install=$enable_fast_install - -# The host system. -host_alias=$host_alias -host=$host -host_os=$host_os - -# The build system. -build_alias=$build_alias -build=$build -build_os=$build_os - -# An echo program that does not interpret backslashes. -echo=$lt_echo - -# The archiver. -AR=$lt_AR -AR_FLAGS=$lt_AR_FLAGS - -# A C compiler. -LTCC=$lt_LTCC - -# A language-specific compiler. -CC=$lt_[]_LT_AC_TAGVAR(compiler, $1) - -# Is the compiler the GNU C compiler? -with_gcc=$_LT_AC_TAGVAR(GCC, $1) - -# An ERE matcher. -EGREP=$lt_EGREP - -# The linker used to build libraries. -LD=$lt_[]_LT_AC_TAGVAR(LD, $1) - -# Whether we need hard or soft links. -LN_S=$lt_LN_S - -# A BSD-compatible nm program. -NM=$lt_NM - -# A symbol stripping program -STRIP=$lt_STRIP - -# Used to examine libraries when file_magic_cmd begins "file" -MAGIC_CMD=$MAGIC_CMD - -# Used on cygwin: DLL creation program. -DLLTOOL="$DLLTOOL" - -# Used on cygwin: object dumper. -OBJDUMP="$OBJDUMP" - -# Used on cygwin: assembler. -AS="$AS" - -# The name of the directory that contains temporary libtool files. -objdir=$objdir - -# How to create reloadable object files. -reload_flag=$lt_reload_flag -reload_cmds=$lt_reload_cmds - -# How to pass a linker flag through the compiler. -wl=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) - -# Object file suffix (normally "o"). -objext="$ac_objext" - -# Old archive suffix (normally "a"). -libext="$libext" - -# Shared library suffix (normally ".so"). -shrext_cmds='$shrext_cmds' - -# Executable file suffix (normally ""). -exeext="$exeext" - -# Additional compiler flags for building library objects. -pic_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) -pic_mode=$pic_mode - -# What is the maximum length of a command? -max_cmd_len=$lt_cv_sys_max_cmd_len - -# Does compiler simultaneously support -c and -o options? -compiler_c_o=$lt_[]_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) - -# Must we lock files when doing compilation? -need_locks=$lt_need_locks - -# Do we need the lib prefix for modules? -need_lib_prefix=$need_lib_prefix - -# Do we need a version for libraries? -need_version=$need_version - -# Whether dlopen is supported. -dlopen_support=$enable_dlopen - -# Whether dlopen of programs is supported. -dlopen_self=$enable_dlopen_self - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=$enable_dlopen_self_static - -# Compiler flag to prevent dynamic linking. -link_static_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_static, $1) - -# Compiler flag to turn off builtin functions. -no_builtin_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec=$lt_[]_LT_AC_TAGVAR(export_dynamic_flag_spec, $1) - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec=$lt_[]_LT_AC_TAGVAR(whole_archive_flag_spec, $1) - -# Compiler flag to generate thread-safe objects. -thread_safe_flag_spec=$lt_[]_LT_AC_TAGVAR(thread_safe_flag_spec, $1) - -# Library versioning type. -version_type=$version_type - -# Format of library name prefix. -libname_spec=$lt_libname_spec - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME. -library_names_spec=$lt_library_names_spec - -# The coded name of the library, if different from the real name. -soname_spec=$lt_soname_spec - -# Commands used to build and install an old-style archive. -RANLIB=$lt_RANLIB -old_archive_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_cmds, $1) -old_postinstall_cmds=$lt_old_postinstall_cmds -old_postuninstall_cmds=$lt_old_postuninstall_cmds - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_new_cmds, $1) - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) - -# Commands used to build and install a shared archive. -archive_cmds=$lt_[]_LT_AC_TAGVAR(archive_cmds, $1) -archive_expsym_cmds=$lt_[]_LT_AC_TAGVAR(archive_expsym_cmds, $1) -postinstall_cmds=$lt_postinstall_cmds -postuninstall_cmds=$lt_postuninstall_cmds - -# Commands used to build a loadable module (assumed same as above if empty) -module_cmds=$lt_[]_LT_AC_TAGVAR(module_cmds, $1) -module_expsym_cmds=$lt_[]_LT_AC_TAGVAR(module_expsym_cmds, $1) - -# Commands to strip libraries. -old_striplib=$lt_old_striplib -striplib=$lt_striplib - -# Dependencies to place before the objects being linked to create a -# shared library. -predep_objects=$lt_[]_LT_AC_TAGVAR(predep_objects, $1) - -# Dependencies to place after the objects being linked to create a -# shared library. -postdep_objects=$lt_[]_LT_AC_TAGVAR(postdep_objects, $1) - -# Dependencies to place before the objects being linked to create a -# shared library. -predeps=$lt_[]_LT_AC_TAGVAR(predeps, $1) - -# Dependencies to place after the objects being linked to create a -# shared library. -postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1) - -# The library search path used internally by the compiler when linking -# a shared library. -compiler_lib_search_path=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1) - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method=$lt_deplibs_check_method - -# Command to use when deplibs_check_method == file_magic. -file_magic_cmd=$lt_file_magic_cmd - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag=$lt_[]_LT_AC_TAGVAR(allow_undefined_flag, $1) - -# Flag that forces no undefined symbols. -no_undefined_flag=$lt_[]_LT_AC_TAGVAR(no_undefined_flag, $1) - -# Commands used to finish a libtool library installation in a directory. -finish_cmds=$lt_finish_cmds - -# Same as above, but a single script fragment to be evaled but not shown. -finish_eval=$lt_finish_eval - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe - -# Transform the output of nm in a proper C declaration -global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl - -# Transform the output of nm in a C name address pair -global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address - -# This is the shared library runtime path variable. -runpath_var=$runpath_var - -# This is the shared library path variable. -shlibpath_var=$shlibpath_var - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=$shlibpath_overrides_runpath - -# How to hardcode a shared library path into an executable. -hardcode_action=$_LT_AC_TAGVAR(hardcode_action, $1) - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=$hardcode_into_libs - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist. -hardcode_libdir_flag_spec=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) - -# If ld is used when linking, flag to hardcode \$libdir into -# a binary during linking. This must work even if \$libdir does -# not exist. -hardcode_libdir_flag_spec_ld=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) - -# Whether we need a single -rpath flag with a separated argument. -hardcode_libdir_separator=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_separator, $1) - -# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the -# resulting binary. -hardcode_direct=$_LT_AC_TAGVAR(hardcode_direct, $1) - -# Set to yes if using the -LDIR flag during linking hardcodes DIR into the -# resulting binary. -hardcode_minus_L=$_LT_AC_TAGVAR(hardcode_minus_L, $1) - -# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into -# the resulting binary. -hardcode_shlibpath_var=$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1) - -# Set to yes if building a shared library automatically hardcodes DIR into the library -# and all subsequent libraries and executables linked against it. -hardcode_automatic=$_LT_AC_TAGVAR(hardcode_automatic, $1) - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at relink time. -variables_saved_for_relink="$variables_saved_for_relink" - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=$_LT_AC_TAGVAR(link_all_deplibs, $1) - -# Compile-time system search path for libraries -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec - -# Run-time system search path for libraries -sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec - -# Fix the shell variable \$srcfile for the compiler. -fix_srcfile_path="$_LT_AC_TAGVAR(fix_srcfile_path, $1)" - -# Set to yes if exported symbols are required. -always_export_symbols=$_LT_AC_TAGVAR(always_export_symbols, $1) - -# The commands to list exported symbols. -export_symbols_cmds=$lt_[]_LT_AC_TAGVAR(export_symbols_cmds, $1) - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds=$lt_extract_expsyms_cmds - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms=$lt_[]_LT_AC_TAGVAR(exclude_expsyms, $1) - -# Symbols that must always be exported. -include_expsyms=$lt_[]_LT_AC_TAGVAR(include_expsyms, $1) - -ifelse([$1],[], -[# ### END LIBTOOL CONFIG], -[# ### END LIBTOOL TAG CONFIG: $tagname]) - -__EOF__ - -ifelse([$1],[], [ - case $host_os in - aix3*) - cat <<\EOF >> "$cfgfile" - -# AIX sometimes has problems with the GCC collect2 program. For some -# reason, if we set the COLLECT_NAMES environment variable, the problems -# vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -EOF - ;; - esac - - # We use sed instead of cat because bash on DJGPP gets confused if - # if finds mixed CR/LF and LF-only lines. Since sed operates in - # text mode, it properly converts lines to CR/LF. This bash problem - # is reportedly fixed, but why not run on old versions too? - sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1) - - mv -f "$cfgfile" "$ofile" || \ - (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") - chmod +x "$ofile" -]) -else - # If there is no Makefile yet, we rely on a make rule to execute - # `config.status --recheck' to rerun these tests and create the - # libtool script then. - ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` - if test -f "$ltmain_in"; then - test -f Makefile && make "$ltmain" - fi -fi -])# AC_LIBTOOL_CONFIG - - -# AC_LIBTOOL_PROG_COMPILER_NO_RTTI([TAGNAME]) -# ------------------------------------------- -AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], -[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl - -_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= - -if test "$GCC" = yes; then - _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' - - AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], - lt_cv_prog_compiler_rtti_exceptions, - [-fno-rtti -fno-exceptions], [], - [_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) -fi -])# AC_LIBTOOL_PROG_COMPILER_NO_RTTI - - -# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE -# --------------------------------- -AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], -[AC_REQUIRE([AC_CANONICAL_HOST]) -AC_REQUIRE([AC_PROG_NM]) -AC_REQUIRE([AC_OBJEXT]) -# Check for command to grab the raw symbol name followed by C symbol from nm. -AC_MSG_CHECKING([command to parse $NM output from $compiler object]) -AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], -[ -# These are sane defaults that work on at least a few old systems. -# [They come from Ultrix. What could be older than Ultrix?!! ;)] - -# Character class describing NM global symbol codes. -symcode='[[BCDEGRST]]' - -# Regexp to match symbols that can be accessed directly from C. -sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' - -# Transform an extracted symbol line into a proper C declaration -lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'" - -# Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" - -# Define system-specific variables. -case $host_os in -aix*) - symcode='[[BCDT]]' - ;; -cygwin* | mingw* | pw32*) - symcode='[[ABCDGISTW]]' - ;; -hpux*) # Its linker distinguishes data from code symbols - if test "$host_cpu" = ia64; then - symcode='[[ABCDEGRST]]' - fi - lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" - lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" - ;; -linux*) - if test "$host_cpu" = ia64; then - symcode='[[ABCDGIRSTW]]' - lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" - lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" - fi - ;; -irix* | nonstopux*) - symcode='[[BCDEGRST]]' - ;; -osf*) - symcode='[[BCDEGQRST]]' - ;; -solaris* | sysv5*) - symcode='[[BDRT]]' - ;; -sysv4) - symcode='[[DFNSTU]]' - ;; -esac - -# Handle CRLF in mingw tool chain -opt_cr= -case $build_os in -mingw*) - opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp - ;; -esac - -# If we're using GNU nm, then use its standard symbol codes. -case `$NM -V 2>&1` in -*GNU* | *'with BFD'*) - symcode='[[ABCDGIRSTW]]' ;; -esac - -# Try without a prefix undercore, then with it. -for ac_symprfx in "" "_"; do - - # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. - symxfrm="\\1 $ac_symprfx\\2 \\2" - - # Write the raw and C identifiers. - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" - - # Check to see that the pipe works correctly. - pipe_works=no - - rm -f conftest* - cat > conftest.$ac_ext <<EOF -#ifdef __cplusplus -extern "C" { -#endif -char nm_test_var; -void nm_test_func(){} -#ifdef __cplusplus -} -#endif -int main(){nm_test_var='a';nm_test_func();return(0);} -EOF - - if AC_TRY_EVAL(ac_compile); then - # Now try to grab the symbols. - nlist=conftest.nm - if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then - # Try sorting and uniquifying the output. - if sort "$nlist" | uniq > "$nlist"T; then - mv -f "$nlist"T "$nlist" - else - rm -f "$nlist"T - fi - - # Make sure that we snagged all the symbols we need. - if grep ' nm_test_var$' "$nlist" >/dev/null; then - if grep ' nm_test_func$' "$nlist" >/dev/null; then - cat <<EOF > conftest.$ac_ext -#ifdef __cplusplus -extern "C" { -#endif - -EOF - # Now generate the symbol file. - eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext' - - cat <<EOF >> conftest.$ac_ext -#if defined (__STDC__) && __STDC__ -# define lt_ptr_t void * -#else -# define lt_ptr_t char * -# define const -#endif - -/* The mapping between symbol names and symbols. */ -const struct { - const char *name; - lt_ptr_t address; -} -lt_preloaded_symbols[[]] = -{ -EOF - $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext - cat <<\EOF >> conftest.$ac_ext - {0, (lt_ptr_t) 0} -}; - -#ifdef __cplusplus -} -#endif -EOF - # Now try linking the two files. - mv conftest.$ac_objext conftstm.$ac_objext - lt_save_LIBS="$LIBS" - lt_save_CFLAGS="$CFLAGS" - LIBS="conftstm.$ac_objext" - CFLAGS="$CFLAGS$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then - pipe_works=yes - fi - LIBS="$lt_save_LIBS" - CFLAGS="$lt_save_CFLAGS" - else - echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD - fi - else - echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD - fi - else - echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD - fi - else - echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD - cat conftest.$ac_ext >&5 - fi - rm -f conftest* conftst* - - # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then - break - else - lt_cv_sys_global_symbol_pipe= - fi -done -]) -if test -z "$lt_cv_sys_global_symbol_pipe"; then - lt_cv_sys_global_symbol_to_cdecl= -fi -if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then - AC_MSG_RESULT(failed) -else - AC_MSG_RESULT(ok) -fi -]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE - - -# AC_LIBTOOL_PROG_COMPILER_PIC([TAGNAME]) -# --------------------------------------- -AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC], -[_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)= -_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= -_LT_AC_TAGVAR(lt_prog_compiler_static, $1)= - -AC_MSG_CHECKING([for $compiler option to produce PIC]) - ifelse([$1],[CXX],[ - # C++ specific cases for pic, static, wl, etc. - if test "$GXX" = yes; then - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - amigaos*) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' - ;; - beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - mingw* | os2* | pw32*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' - ;; - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' - ;; - *djgpp*) - # DJGPP does not support shared libraries at all - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= - ;; - sysv4*MP*) - if test -d /usr/nec; then - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic - fi - ;; - hpux*) - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - ;; - *) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - ;; - *) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - else - case $host_os in - aix4* | aix5*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - else - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' - fi - ;; - chorus*) - case $cc_basename in - cxch68*) - # Green Hills C++ Compiler - # _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" - ;; - esac - ;; - darwin*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - case $cc_basename in - xlc*) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - ;; - esac - ;; - dgux*) - case $cc_basename in - ec++*) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - ;; - ghcx*) - # Green Hills C++ Compiler - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - *) - ;; - esac - ;; - freebsd* | kfreebsd*-gnu | dragonfly*) - # FreeBSD uses GNU C++ - ;; - hpux9* | hpux10* | hpux11*) - case $cc_basename in - CC*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" - if test "$host_cpu" != ia64; then - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - fi - ;; - aCC*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - ;; - esac - ;; - *) - ;; - esac - ;; - irix5* | irix6* | nonstopux*) - case $cc_basename in - CC*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - # CC pic flag -KPIC is the default. - ;; - *) - ;; - esac - ;; - linux*) - case $cc_basename in - KCC*) - # KAI C++ Compiler - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - icpc* | ecpc*) - # Intel C++ - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - pgCC*) - # Portland Group C++ compiler. - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - cxx*) - # Compaq C++ - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - *) - ;; - esac - ;; - lynxos*) - ;; - m88k*) - ;; - mvs*) - case $cc_basename in - cxx*) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' - ;; - *) - ;; - esac - ;; - netbsd*) - ;; - osf3* | osf4* | osf5*) - case $cc_basename in - KCC*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' - ;; - RCC*) - # Rational C++ 2.4.1 - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - cxx*) - # Digital/Compaq C++ - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # Make sure the PIC flag is empty. It appears that all Alpha - # Linux and Compaq Tru64 Unix objects are PIC. - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - *) - ;; - esac - ;; - psos*) - ;; - sco*) - case $cc_basename in - CC*) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - *) - ;; - esac - ;; - solaris*) - case $cc_basename in - CC*) - # Sun C++ 4.2, 5.x and Centerline C++ - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - ;; - gcx*) - # Green Hills C++ Compiler - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - ;; - *) - ;; - esac - ;; - sunos4*) - case $cc_basename in - CC*) - # Sun C++ 4.x - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - lcc*) - # Lucid - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - ;; - *) - ;; - esac - ;; - tandem*) - case $cc_basename in - NCC*) - # NonStop-UX NCC 3.20 - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - ;; - *) - ;; - esac - ;; - unixware*) - ;; - vxworks*) - ;; - *) - _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - esac - fi -], -[ - if test "$GCC" = yes; then - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - amigaos*) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' - ;; - - beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - - mingw* | pw32* | os2*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' - ;; - - msdosdjgpp*) - # Just because we use GCC doesn't mean we suddenly get shared libraries - # on systems that don't support them. - _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - enable_shared=no - ;; - - sysv4*MP*) - if test -d /usr/nec; then - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic - fi - ;; - - hpux*) - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - ;; - - *) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - esac - else - # PORTME Check for flag to pass linker flags through the system compiler. - case $host_os in - aix*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - else - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' - fi - ;; - darwin*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - case $cc_basename in - xlc*) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - ;; - esac - ;; - - mingw* | pw32* | os2*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' - ;; - - hpux9* | hpux10* | hpux11*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' - ;; - esac - # Is there a better lt_prog_compiler_static that works with the bundled CC? - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - ;; - - irix5* | irix6* | nonstopux*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # PIC (with -KPIC) is the default. - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - newsos6) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - linux*) - case $cc_basename in - icc* | ecc*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - pgcc* | pgf77* | pgf90* | pgf95*) - # Portland Group compilers (*not* the Pentium gcc compiler, - # which looks to be a dead project) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - ccc*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # All Alpha code is PIC. - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - esac - ;; - - osf3* | osf4* | osf5*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - # All OSF/1 code is PIC. - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' - ;; - - sco3.2v5*) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kpic' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-dn' - ;; - - solaris*) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - case $cc_basename in - f77* | f90* | f95*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; - *) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; - esac - ;; - - sunos4*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - sysv4*MP*) - if test -d /usr/nec ;then - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - fi - ;; - - unicos*) - _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - - uts4*) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; - - *) - _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no - ;; - esac - fi -]) -AC_MSG_RESULT([$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)]) - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then - AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) works], - _LT_AC_TAGVAR(lt_prog_compiler_pic_works, $1), - [$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])], [], - [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) in - "" | " "*) ;; - *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)" ;; - esac], - [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= - _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) -fi -case $host_os in - # For platforms which do not support PIC, -DPIC is meaningless: - *djgpp*) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= - ;; - *) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])" - ;; -esac -]) - - -# AC_LIBTOOL_PROG_LD_SHLIBS([TAGNAME]) -# ------------------------------------ -# See if the linker supports building shared libraries. -AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS], -[AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) -ifelse([$1],[CXX],[ - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - case $host_os in - aix4* | aix5*) - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - if $NM -V 2>&1 | grep 'GNU' > /dev/null; then - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' - else - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' - fi - ;; - pw32*) - _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" - ;; - cygwin* | mingw*) - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([[^ ]]*\) [[^ ]]*/\1 DATA/;/^I /d;/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' - ;; - *) - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - ;; - esac -],[ - runpath_var= - _LT_AC_TAGVAR(allow_undefined_flag, $1)= - _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no - _LT_AC_TAGVAR(archive_cmds, $1)= - _LT_AC_TAGVAR(archive_expsym_cmds, $1)= - _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)= - _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)= - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= - _LT_AC_TAGVAR(thread_safe_flag_spec, $1)= - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= - _LT_AC_TAGVAR(hardcode_direct, $1)=no - _LT_AC_TAGVAR(hardcode_minus_L, $1)=no - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - _LT_AC_TAGVAR(link_all_deplibs, $1)=unknown - _LT_AC_TAGVAR(hardcode_automatic, $1)=no - _LT_AC_TAGVAR(module_cmds, $1)= - _LT_AC_TAGVAR(module_expsym_cmds, $1)= - _LT_AC_TAGVAR(always_export_symbols, $1)=no - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - # include_expsyms should be a list of space-separated symbols to be *always* - # included in the symbol list - _LT_AC_TAGVAR(include_expsyms, $1)= - # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ` (' and `)$', so one must not match beginning or - # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', - # as well as any symbol that contains `d'. - _LT_AC_TAGVAR(exclude_expsyms, $1)="_GLOBAL_OFFSET_TABLE_" - # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out - # platforms (ab)use it in PIC code, but their linkers get confused if - # the symbol is explicitly referenced. Since portable code cannot - # rely on this symbol name, it's probably fine to never include it in - # preloaded symbol tables. - extract_expsyms_cmds= - # Just being paranoid about ensuring that cc_basename is set. - _LT_CC_BASENAME([$compiler]) - case $host_os in - cygwin* | mingw* | pw32*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; - openbsd*) - with_gnu_ld=no - ;; - esac - - _LT_AC_TAGVAR(ld_shlibs, $1)=yes - if test "$with_gnu_ld" = yes; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' - - # Set some defaults for GNU ld with shared library support. These - # are reset later if shared libraries are not supported. Putting them - # here allows them to be overridden if necessary. - runpath_var=LD_RUN_PATH - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= - fi - supports_anon_versioning=no - case `$LD -v 2>/dev/null` in - *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - - # See if GNU ld supports shared libraries. - case $host_os in - aix3* | aix4* | aix5*) - # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then - _LT_AC_TAGVAR(ld_shlibs, $1)=no - cat <<EOF 1>&2 - -*** Warning: the GNU linker, at least up to release 2.9.1, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to modify your PATH -*** so that a non-GNU linker is found, and then restart. - -EOF - fi - ;; - - amigaos*) - _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - - # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports - # that the semantics of dynamic libraries on AmigaOS, at least up - # to version 4, is to share data among multiple programs linked - # with the same dynamic library. Since this doesn't match the - # behavior of shared libraries on other platforms, we can't use - # them. - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - - beos*) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported - # Joseph Beckenbach <jrb3@best.com> says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - cygwin* | mingw* | pw32*) - # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, - # as there is no search path for DLLs. - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_AC_TAGVAR(always_export_symbols, $1)=no - _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' - - if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' - else - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - linux*) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - tmp_addflag= - case $cc_basename,$host_cpu in - pgcc*) # Portland Group C compiler - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag' - ;; - pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag -Mnomain' ;; - ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 - tmp_addflag=' -i_dynamic' ;; - efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 - tmp_addflag=' -i_dynamic -nofor_main' ;; - ifc* | ifort*) # Intel Fortran compiler - tmp_addflag=' -nofor_main' ;; - esac - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - - if test $supports_anon_versioning = yes; then - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - $echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - fi - else - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' - wlarc= - else - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - fi - ;; - - solaris* | sysv5*) - if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then - _LT_AC_TAGVAR(ld_shlibs, $1)=no - cat <<EOF 1>&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -EOF - elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - - sunos4*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' - wlarc= - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *) - if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - _LT_AC_TAGVAR(ld_shlibs, $1)=no - fi - ;; - esac - - if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no; then - runpath_var= - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= - fi - else - # PORTME fill in a description of your system's linker (not GNU ld) - case $host_os in - aix3*) - _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_AC_TAGVAR(always_export_symbols, $1)=yes - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - if test "$GCC" = yes && test -z "$link_static_flag"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported - fi - ;; - - aix4* | aix5*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - if $NM -V 2>&1 | grep 'GNU' > /dev/null; then - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' - else - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' - fi - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) - for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then - aix_use_runtimelinking=yes - break - fi - done - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - _LT_AC_TAGVAR(archive_cmds, $1)='' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' - _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - - if test "$GCC" = yes; then - case $host_os in aix4.[[012]]|aix4.[[012]].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && \ - strings "$collect2name" | grep resolve_lib_name >/dev/null - then - # We have reworked collect2 - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - else - # We have old collect2 - _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= - fi - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - _LT_AC_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' - # Determine the default libpath from the value encoded in an empty executable. - _LT_AC_SYS_LIBPATH_AIX - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' - _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an empty executable. - _LT_AC_SYS_LIBPATH_AIX - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - # -bexpall does not export symbols beginning with underscore (_) - _LT_AC_TAGVAR(always_export_symbols, $1)=yes - # Exported symbols can be pulled into shared objects from archives - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' ' - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds its shared libraries. - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - amigaos*) - _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - # see comment about different semantics on the GNU ld section - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - - bsdi[[45]]*) - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic - ;; - - cygwin* | mingw* | pw32*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' - _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true' - # FIXME: Should let the user specify the lib program. - _LT_AC_TAGVAR(old_archive_cmds, $1)='lib /OUT:$oldlib$oldobjs$old_deplibs' - _LT_AC_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' - _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - ;; - - darwin* | rhapsody*) - case $host_os in - rhapsody* | darwin1.[[012]]) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' - ;; - *) # Darwin 1.3 on - if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then - _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' - else - case ${MACOSX_DEPLOYMENT_TARGET} in - 10.[[012]]) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' - ;; - 10.*) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' - ;; - esac - fi - ;; - esac - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_AC_TAGVAR(hardcode_direct, $1)=no - _LT_AC_TAGVAR(hardcode_automatic, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' - _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - if test "$GCC" = yes ; then - output_verbose_link_cmd='echo' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - else - case $cc_basename in - xlc*) - output_verbose_link_cmd='echo' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' - _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - ;; - *) - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - esac - fi - ;; - - dgux*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - freebsd1*) - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | kfreebsd*-gnu | dragonfly*) - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - hpux9*) - if test "$GCC" = yes; then - _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - fi - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - ;; - - hpux10* | hpux11*) - if test "$GCC" = yes -a "$with_gnu_ld" = no; then - case $host_cpu in - hppa*64*|ia64*) - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - else - case $host_cpu in - hppa*64*|ia64*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags' - ;; - *) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' - ;; - esac - fi - if test "$with_gnu_ld" = no; then - case $host_cpu in - hppa*64*) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_AC_TAGVAR(hardcode_direct, $1)=no - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - ia64*) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(hardcode_direct, $1)=no - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - ;; - *) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - ;; - esac - fi - ;; - - irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' - fi - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out - else - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF - fi - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - newsos6) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - openbsd*) - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - else - case $host_os in - openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - ;; - *) - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - ;; - esac - fi - ;; - - os2*) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_AC_TAGVAR(archive_cmds, $1)='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' - _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' - ;; - - osf3*) - if test "$GCC" = yes; then - _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - fi - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - - osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - else - _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ - $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' - - # Both c and cxx compiler support -rpath directly - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' - fi - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - - sco3.2v5*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ;; - - solaris*) - _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' - if test "$GCC" = yes; then - wlarc='${wl}' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' - else - wlarc='' - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - fi - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) - # The compiler driver will combine linker options so we - # cannot just pass the convience library names through - # without $wl, iff we do not link with $LD. - # Luckily, gcc supports the same syntax we need for Sun Studio. - # Supported since Solaris 2.6 (maybe 2.5.1?) - case $wlarc in - '') - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; - *) - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; - esac ;; - esac - _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - ;; - - sunos4*) - if test "x$host_vendor" = xsequent; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' - fi - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - sysv4) - case $host_vendor in - sni) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes # is this really true??? - ;; - siemens) - ## LD is ld it makes a PLAMLIB - ## CC just makes a GrossModule. - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' - _LT_AC_TAGVAR(hardcode_direct, $1)=no - ;; - motorola) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie - ;; - esac - runpath_var='LD_RUN_PATH' - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - sysv4.3*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - _LT_AC_TAGVAR(ld_shlibs, $1)=yes - fi - ;; - - sysv4.2uw2*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_minus_L, $1)=no - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - hardcode_runpath_var=yes - runpath_var=LD_RUN_PATH - ;; - - sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7*) - _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z ${wl}text' - if test "$GCC" = yes; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - else - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - runpath_var='LD_RUN_PATH' - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - sysv5*) - _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' - # $CC -shared without GNU ld will not create a library from C++ - # object files and a static libstdc++, better avoid it by now - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - runpath_var='LD_RUN_PATH' - ;; - - uts4*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - - *) - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - esac - fi -]) -AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) -test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -# -# Do we need to explicitly link libc? -# -case "x$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)" in -x|xyes) - # Assume -lc should be added - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes - - if test "$enable_shared" = yes && test "$GCC" = yes; then - case $_LT_AC_TAGVAR(archive_cmds, $1) in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - AC_MSG_CHECKING([whether -lc should be explicitly linked in]) - $rm conftest* - printf "$lt_simple_compile_test_code" > conftest.$ac_ext - - if AC_TRY_EVAL(ac_compile) 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$_LT_AC_TAGVAR(allow_undefined_flag, $1) - _LT_AC_TAGVAR(allow_undefined_flag, $1)= - if AC_TRY_EVAL(_LT_AC_TAGVAR(archive_cmds, $1) 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) - then - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no - else - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes - fi - _LT_AC_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $rm conftest* - AC_MSG_RESULT([$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)]) - ;; - esac - fi - ;; -esac -])# AC_LIBTOOL_PROG_LD_SHLIBS - - -# _LT_AC_FILE_LTDLL_C -# ------------------- -# Be careful that the start marker always follows a newline. -AC_DEFUN([_LT_AC_FILE_LTDLL_C], [ -# /* ltdll.c starts here */ -# #define WIN32_LEAN_AND_MEAN -# #include <windows.h> -# #undef WIN32_LEAN_AND_MEAN -# #include <stdio.h> -# -# #ifndef __CYGWIN__ -# # ifdef __CYGWIN32__ -# # define __CYGWIN__ __CYGWIN32__ -# # endif -# #endif -# -# #ifdef __cplusplus -# extern "C" { -# #endif -# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); -# #ifdef __cplusplus -# } -# #endif -# -# #ifdef __CYGWIN__ -# #include <cygwin/cygwin_dll.h> -# DECLARE_CYGWIN_DLL( DllMain ); -# #endif -# HINSTANCE __hDllInstance_base; -# -# BOOL APIENTRY -# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) -# { -# __hDllInstance_base = hInst; -# return TRUE; -# } -# /* ltdll.c ends here */ -])# _LT_AC_FILE_LTDLL_C - - -# _LT_AC_TAGVAR(VARNAME, [TAGNAME]) -# --------------------------------- -AC_DEFUN([_LT_AC_TAGVAR], [ifelse([$2], [], [$1], [$1_$2])]) - - -# old names -AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) -AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) -AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) -AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) -AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) -AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) -AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) - -# This is just to silence aclocal about the macro not being used -ifelse([AC_DISABLE_FAST_INSTALL]) - -AC_DEFUN([LT_AC_PROG_GCJ], -[AC_CHECK_TOOL(GCJ, gcj, no) - test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" - AC_SUBST(GCJFLAGS) -]) - -AC_DEFUN([LT_AC_PROG_RC], -[AC_CHECK_TOOL(RC, windres, no) -]) - -############################################################ -# NOTE: This macro has been submitted for inclusion into # -# GNU Autoconf as AC_PROG_SED. When it is available in # -# a released version of Autoconf we should remove this # -# macro and use it instead. # -############################################################ -# LT_AC_PROG_SED -# -------------- -# Check for a fully-functional sed program, that truncates -# as few characters as possible. Prefer GNU sed if found. -AC_DEFUN([LT_AC_PROG_SED], -[AC_MSG_CHECKING([for a sed that does not truncate output]) -AC_CACHE_VAL(lt_cv_path_SED, -[# Loop through the user's path and test for sed and gsed. -# Then use that list of sed's as ones to test for truncation. -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for lt_ac_prog in sed gsed; do - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then - lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" - fi - done - done -done -lt_ac_max=0 -lt_ac_count=0 -# Add /usr/xpg4/bin/sed as it is typically found on Solaris -# along with /bin/sed that truncates output. -for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do - test ! -f $lt_ac_sed && continue - cat /dev/null > conftest.in - lt_ac_count=0 - echo $ECHO_N "0123456789$ECHO_C" >conftest.in - # Check for GNU sed and select it if it is found. - if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then - lt_cv_path_SED=$lt_ac_sed - break - fi - while true; do - cat conftest.in conftest.in >conftest.tmp - mv conftest.tmp conftest.in - cp conftest.in conftest.nl - echo >>conftest.nl - $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break - cmp -s conftest.out conftest.nl || break - # 10000 chars as input seems more than enough - test $lt_ac_count -gt 10 && break - lt_ac_count=`expr $lt_ac_count + 1` - if test $lt_ac_count -gt $lt_ac_max; then - lt_ac_max=$lt_ac_count - lt_cv_path_SED=$lt_ac_sed - fi - done -done -]) -SED=$lt_cv_path_SED -AC_MSG_RESULT([$SED]) -]) diff --git a/storage/bdb/dist/aclocal/mutex.ac b/storage/bdb/dist/aclocal/mutex.ac deleted file mode 100644 index 149bda737b2..00000000000 --- a/storage/bdb/dist/aclocal/mutex.ac +++ /dev/null @@ -1,706 +0,0 @@ -# $Id: mutex.ac,v 12.6 2005/11/04 20:19:29 bostic Exp $ - -# POSIX pthreads tests: inter-process safe and intra-process only. -AC_DEFUN(AM_PTHREADS_SHARED, [ -AC_TRY_RUN([ -#include <pthread.h> -main() { - pthread_cond_t cond; - pthread_mutex_t mutex; - pthread_condattr_t condattr; - pthread_mutexattr_t mutexattr; - exit ( - pthread_condattr_init(&condattr) || - pthread_condattr_setpshared(&condattr, PTHREAD_PROCESS_SHARED) || - pthread_mutexattr_init(&mutexattr) || - pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED) || - pthread_cond_init(&cond, &condattr) || - pthread_mutex_init(&mutex, &mutexattr) || - pthread_mutex_lock(&mutex) || - pthread_mutex_unlock(&mutex) || - pthread_mutex_destroy(&mutex) || - pthread_cond_destroy(&cond) || - pthread_condattr_destroy(&condattr) || - pthread_mutexattr_destroy(&mutexattr)); -}], [db_cv_mutex="$1"],, -AC_TRY_LINK([ -#include <pthread.h>],[ - pthread_cond_t cond; - pthread_mutex_t mutex; - pthread_condattr_t condattr; - pthread_mutexattr_t mutexattr; - exit ( - pthread_condattr_init(&condattr) || - pthread_condattr_setpshared(&condattr, PTHREAD_PROCESS_SHARED) || - pthread_mutexattr_init(&mutexattr) || - pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED) || - pthread_cond_init(&cond, &condattr) || - pthread_mutex_init(&mutex, &mutexattr) || - pthread_mutex_lock(&mutex) || - pthread_mutex_unlock(&mutex) || - pthread_mutex_destroy(&mutex) || - pthread_cond_destroy(&cond) || - pthread_condattr_destroy(&condattr) || - pthread_mutexattr_destroy(&mutexattr)); -], [db_cv_mutex="$1"]))]) -AC_DEFUN(AM_PTHREADS_PRIVATE, [ -AC_TRY_RUN([ -#include <pthread.h> -main() { - pthread_cond_t cond; - pthread_mutex_t mutex; - pthread_condattr_t condattr; - pthread_mutexattr_t mutexattr; - exit ( - pthread_condattr_init(&condattr) || - pthread_mutexattr_init(&mutexattr) || - pthread_cond_init(&cond, &condattr) || - pthread_mutex_init(&mutex, &mutexattr) || - pthread_mutex_lock(&mutex) || - pthread_mutex_unlock(&mutex) || - pthread_mutex_destroy(&mutex) || - pthread_cond_destroy(&cond) || - pthread_condattr_destroy(&condattr) || - pthread_mutexattr_destroy(&mutexattr)); -}], [db_cv_mutex="$1"],, -AC_TRY_LINK([ -#include <pthread.h>],[ - pthread_cond_t cond; - pthread_mutex_t mutex; - pthread_condattr_t condattr; - pthread_mutexattr_t mutexattr; - exit ( - pthread_condattr_init(&condattr) || - pthread_mutexattr_init(&mutexattr) || - pthread_cond_init(&cond, &condattr) || - pthread_mutex_init(&mutex, &mutexattr) || - pthread_mutex_lock(&mutex) || - pthread_mutex_unlock(&mutex) || - pthread_mutex_destroy(&mutex) || - pthread_cond_destroy(&cond) || - pthread_condattr_destroy(&condattr) || - pthread_mutexattr_destroy(&mutexattr)); -], [db_cv_mutex="$1"]))]) - -# Figure out mutexes for this compiler/architecture. -AC_DEFUN(AM_DEFINE_MUTEXES, [ - -# Mutexes we don't test for, but want the #defines to exist for -# other ports. -AH_TEMPLATE(HAVE_MUTEX_VMS, [Define to 1 to use VMS mutexes.]) -AH_TEMPLATE(HAVE_MUTEX_VXWORKS, [Define to 1 to use VxWorks mutexes.]) - -AC_CACHE_CHECK([for mutexes], db_cv_mutex, [ -db_cv_mutex=no - -orig_libs=$LIBS - -# User-specified POSIX or UI mutexes. -# -# There are two different reasons to specify mutexes: First, the application -# is already using one type of mutex and doesn't want to mix-and-match (for -# example, on Solaris, which has POSIX, UI and LWP mutexes). Second, the -# applications POSIX pthreads mutexes don't support inter-process locking, -# but the application wants to use them anyway (for example, some Linux and -# *BSD systems). -# -# Test for LWP threads before testing for UI/POSIX threads, we prefer them -# on Solaris. There's a bug in SunOS 5.7 where applications get pwrite, not -# pwrite64, if they load the C library before the appropriate threads library, -# e.g., tclsh using dlopen to load the DB library. By using LWP threads we -# avoid answering lots of user questions, not to mention the bugs. -# -# Otherwise, test for POSIX threads before UI threads. There are Linux systems -# that support a UI compatibility mode, and applications are more likely to be -# written for POSIX threads than UI threads. -# -# Try and link with a threads library if possible. The problem is the Solaris -# C library has UI/POSIX interface stubs, but they're broken, configuring them -# for inter-process mutexes doesn't return an error, but it doesn't work either. -if test "$db_cv_posixmutexes" = yes; then - db_cv_mutex="posix_only"; -fi -if test "$db_cv_uimutexes" = yes; then - db_cv_mutex="ui_only"; -fi - -# User-specified Win32 mutexes (MinGW build) -if test "$db_cv_mingw" = "yes"; then - db_cv_mutex=win32/gcc -fi - -# LWP threads: _lwp_XXX -if test "$db_cv_mutex" = no; then -AC_TRY_LINK([ -#include <synch.h>],[ - static lwp_mutex_t mi = SHAREDMUTEX; - static lwp_cond_t ci = SHAREDCV; - lwp_mutex_t mutex = mi; - lwp_cond_t cond = ci; - exit ( - _lwp_mutex_lock(&mutex) || - _lwp_mutex_unlock(&mutex)); -], [db_cv_mutex="Solaris/lwp"]) -fi - -# POSIX.1 pthreads: pthread_XXX -# -# If the user specified we use POSIX pthreads mutexes, and we fail to find the -# full interface, try and configure for just intra-process support. -if test "$db_cv_mutex" = no -o "$db_cv_mutex" = "posix_only"; then - LIBS="$LIBS -lpthread" - AM_PTHREADS_SHARED("POSIX/pthreads/library") - LIBS="$orig_libs" -fi -if test "$db_cv_mutex" = no -o "$db_cv_mutex" = "posix_only"; then - AM_PTHREADS_SHARED("POSIX/pthreads") -fi -if test "$db_cv_mutex" = "posix_only"; then - AM_PTHREADS_PRIVATE("POSIX/pthreads/private") -fi -if test "$db_cv_mutex" = "posix_only"; then - LIBS="$LIBS -lpthread" - AM_PTHREADS_PRIVATE("POSIX/pthreads/library/private") - LIBS="$orig_libs" -fi -if test "$db_cv_mutex" = "posix_only"; then - AC_MSG_ERROR([unable to find POSIX 1003.1 mutex interfaces]) -fi - -# UI threads: thr_XXX -if test "$db_cv_mutex" = no -o "$db_cv_mutex" = "ui_only"; then -LIBS="$LIBS -lthread" -AC_TRY_LINK([ -#include <thread.h> -#include <synch.h>],[ - mutex_t mutex; - cond_t cond; - int type = USYNC_PROCESS; - exit ( - mutex_init(&mutex, type, NULL) || - cond_init(&cond, type, NULL) || - mutex_lock(&mutex) || - mutex_unlock(&mutex)); -], [db_cv_mutex="UI/threads/library"]) -LIBS="$orig_libs" -fi -if test "$db_cv_mutex" = no -o "$db_cv_mutex" = "ui_only"; then -AC_TRY_LINK([ -#include <thread.h> -#include <synch.h>],[ - mutex_t mutex; - cond_t cond; - int type = USYNC_PROCESS; - exit ( - mutex_init(&mutex, type, NULL) || - cond_init(&cond, type, NULL) || - mutex_lock(&mutex) || - mutex_unlock(&mutex)); -], [db_cv_mutex="UI/threads"]) -fi -if test "$db_cv_mutex" = "ui_only"; then - AC_MSG_ERROR([unable to find UI mutex interfaces]) -fi - -# msemaphore: HPPA only -# Try HPPA before general msem test, it needs special alignment. -if test "$db_cv_mutex" = no; then -AC_TRY_LINK([ -#include <sys/mman.h>],[ -#if defined(__hppa) - typedef msemaphore tsl_t; - msemaphore x; - msem_init(&x, 0); - msem_lock(&x, 0); - msem_unlock(&x, 0); - exit(0); -#else - FAIL TO COMPILE/LINK -#endif -], [db_cv_mutex="HP/msem_init"]) -fi - -# msemaphore: AIX, OSF/1 -if test "$db_cv_mutex" = no; then -AC_TRY_LINK([ -#include <sys/types.h> -#include <sys/mman.h>],[ - typedef msemaphore tsl_t; - msemaphore x; - msem_init(&x, 0); - msem_lock(&x, 0); - msem_unlock(&x, 0); - exit(0); -], [db_cv_mutex="UNIX/msem_init"]) -fi - -# ReliantUNIX -if test "$db_cv_mutex" = no; then -LIBS="$LIBS -lmproc" -AC_TRY_LINK([ -#include <ulocks.h>],[ - typedef spinlock_t tsl_t; - spinlock_t x; - initspin(&x, 1); - cspinlock(&x); - spinunlock(&x); -], [db_cv_mutex="ReliantUNIX/initspin"]) -LIBS="$orig_libs" -fi - -# SCO: UnixWare has threads in libthread, but OpenServer doesn't. -if test "$db_cv_mutex" = no; then -AC_TRY_COMPILE(,[ -#if defined(__USLC__) - exit(0); -#else - FAIL TO COMPILE/LINK -#endif -], [db_cv_mutex="SCO/x86/cc-assembly"]) -fi - -# abilock_t: SGI -if test "$db_cv_mutex" = no; then -AC_TRY_LINK([ -#include <abi_mutex.h>],[ - typedef abilock_t tsl_t; - abilock_t x; - init_lock(&x); - acquire_lock(&x); - release_lock(&x); -], [db_cv_mutex="SGI/init_lock"]) -fi - -# sema_t: Solaris -# The sema_XXX calls do not work on Solaris 5.5. I see no reason to ever -# turn this test on, unless we find some other platform that uses the old -# POSIX.1 interfaces. (I plan to move directly to pthreads on Solaris.) -if test "$db_cv_mutex" = DOESNT_WORK; then -AC_TRY_LINK([ -#include <synch.h>],[ - typedef sema_t tsl_t; - sema_t x; - sema_init(&x, 1, USYNC_PROCESS, NULL); - sema_wait(&x); - sema_post(&x); -], [db_cv_mutex="UNIX/sema_init"]) -fi - -# _lock_try/_lock_clear: Solaris -# On Solaris systems without Pthread or UI mutex interfaces, DB uses the -# undocumented _lock_try _lock_clear function calls instead of either the -# sema_trywait(3T) or sema_wait(3T) function calls. This is because of -# problems in those interfaces in some releases of the Solaris C library. -if test "$db_cv_mutex" = no; then -AC_TRY_LINK([ -#include <sys/machlock.h>],[ - typedef lock_t tsl_t; - lock_t x; - _lock_try(&x); - _lock_clear(&x); -], [db_cv_mutex="Solaris/_lock_try"]) -fi - -# _check_lock/_clear_lock: AIX -if test "$db_cv_mutex" = no; then -AC_TRY_LINK([ -#include <sys/atomic_op.h>],[ - int x; - _check_lock(&x,0,1); - _clear_lock(&x,0); -], [db_cv_mutex="AIX/_check_lock"]) -fi - -# _spin_lock_try/_spin_unlock: Apple/Darwin -if test "$db_cv_mutex" = no; then -AC_TRY_LINK(,[ - int x; - _spin_lock_try(&x); - _spin_unlock(&x); -], [db_cv_mutex="Darwin/_spin_lock_try"]) -fi - -# Tru64/cc -if test "$db_cv_mutex" = no; then -AC_TRY_COMPILE(,[ -#if defined(__alpha) && defined(__DECC) - exit(0); -#else - FAIL TO COMPILE/LINK -#endif -], [db_cv_mutex="Tru64/cc-assembly"]) -fi - -# Alpha/gcc -if test "$db_cv_mutex" = no; then -AC_TRY_COMPILE(,[ -#if defined(__alpha) && defined(__GNUC__) - exit(0); -#else - FAIL TO COMPILE/LINK -#endif -], [db_cv_mutex="ALPHA/gcc-assembly"]) -fi - -# ARM/gcc: Linux -if test "$db_cv_mutex" = no; then -AC_TRY_COMPILE(,[ -#if defined(__arm__) && defined(__GNUC__) - exit(0); -#else - FAIL TO COMPILE/LINK -#endif -], [db_cv_mutex="ARM/gcc-assembly"]) -fi - -# MIPS/gcc: Linux -if test "$db_cv_mutex" = no; then -AC_TRY_COMPILE(,[ -#if (defined(__mips) || defined(__mips__)) && defined(__GNUC__) - exit(0); -#else - FAIL TO COMPILE/LINK -#endif -], [db_cv_mutex="MIPS/gcc-assembly"]) -fi - -# MIPS/gcc: Linux -if test "$db_cv_mutex" = no; then -AC_TRY_COMPILE(,[ -#if (defined(__mips) || defined(__mips__)) && defined(__GNUC__) - exit(0); -#else - FAIL TO COMPILE/LINK -#endif -], [db_cv_mutex="MIPS/gcc-assembly"]) -fi - -# PaRisc/gcc: HP/UX -if test "$db_cv_mutex" = no; then -AC_TRY_COMPILE(,[ -#if (defined(__hppa) || defined(__hppa__)) && defined(__GNUC__) - exit(0); -#else - FAIL TO COMPILE/LINK -#endif -], [db_cv_mutex="HPPA/gcc-assembly"]) -fi - -# PPC/gcc: -if test "$db_cv_mutex" = no; then -AC_TRY_COMPILE(,[ -#if (defined(__powerpc__) || defined(__ppc__)) && defined(__GNUC__) - exit(0); -#else - FAIL TO COMPILE/LINK -#endif -], [db_cv_mutex="PPC/gcc-assembly"]) -fi - -# Sparc/gcc: SunOS, Solaris -if test "$db_cv_mutex" = no; then -AC_TRY_COMPILE(,[ -#if defined(__sparc__) && defined(__GNUC__) - exit(0); -#else - FAIL TO COMPILE/LINK -#endif -], [db_cv_mutex="Sparc/gcc-assembly"]) -fi - -# 68K/gcc: SunOS -if test "$db_cv_mutex" = no; then -AC_TRY_COMPILE(,[ -#if (defined(mc68020) || defined(sun3)) && defined(__GNUC__) - exit(0); -#else - FAIL TO COMPILE/LINK -#endif -], [db_cv_mutex="68K/gcc-assembly"]) -fi - -# x86/gcc: FreeBSD, NetBSD, BSD/OS, Linux -if test "$db_cv_mutex" = no; then -AC_TRY_COMPILE(,[ -#if (defined(i386) || defined(__i386__)) && defined(__GNUC__) - exit(0); -#else - FAIL TO COMPILE/LINK -#endif -], [db_cv_mutex="x86/gcc-assembly"]) -fi - -# x86_64/gcc: FreeBSD, NetBSD, BSD/OS, Linux -if test "$db_cv_mutex" = no; then -AC_TRY_COMPILE(,[ -#if (defined(x86_64) || defined(__x86_64__)) && defined(__GNUC__) - exit(0); -#else - FAIL TO COMPILE/LINK -#endif -], [db_cv_mutex="x86_64/gcc-assembly"]) -fi - -# S390/cc: IBM OS/390 Unix -if test "$db_cv_mutex" = no; then -AC_TRY_COMPILE(,[ -#if defined(__MVS__) && defined(__IBMC__) - exit(0); -#else - FAIL TO COMPILE/LINK -#endif -], [db_cv_mutex="S390/cc-assembly"]) -fi - -# S390/gcc: Linux -if test "$db_cv_mutex" = no; then -AC_TRY_COMPILE(,[ -#if defined(__s390__) && defined(__GNUC__) - exit(0); -#else - FAIL TO COMPILE/LINK -#endif -], [db_cv_mutex="S390/gcc-assembly"]) -fi - -# ia64/gcc: Linux -if test "$db_cv_mutex" = no; then -AC_TRY_COMPILE(,[ -#if defined(__ia64) && defined(__GNUC__) - exit(0); -#else - FAIL TO COMPILE/LINK -#endif -], [db_cv_mutex="ia64/gcc-assembly"]) -fi - -# uts/cc: UTS -if test "$db_cv_mutex" = no; then -AC_TRY_COMPILE(,[ -#if defined(_UTS) - exit(0); -#else - FAIL TO COMPILE/LINK -#endif -], [db_cv_mutex="UTS/cc-assembly"]) -fi - -# default to UNIX fcntl system call mutexes. -if test "$db_cv_mutex" = no; then - db_cv_mutex="UNIX/fcntl" -fi -]) - -AC_SUBST(thread_h_decl) -AC_SUBST(db_threadid_t_decl) -db_threadid_t_decl=notset - -case "$db_cv_mutex" in -68K/gcc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" - AC_DEFINE(HAVE_MUTEX_68K_GCC_ASSEMBLY) - AH_TEMPLATE(HAVE_MUTEX_68K_GCC_ASSEMBLY, - [Define to 1 to use the GCC compiler and 68K assembly language mutexes.]);; -AIX/_check_lock) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" - AC_DEFINE(HAVE_MUTEX_AIX_CHECK_LOCK) - AH_TEMPLATE(HAVE_MUTEX_AIX_CHECK_LOCK, - [Define to 1 to use the AIX _check_lock mutexes.]);; -Darwin/_spin_lock_try) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" - AC_DEFINE(HAVE_MUTEX_DARWIN_SPIN_LOCK_TRY) - AH_TEMPLATE(HAVE_MUTEX_DARWIN_SPIN_LOCK_TRY, - [Define to 1 to use the Apple/Darwin _spin_lock_try mutexes.]);; -ALPHA/gcc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" - AC_DEFINE(HAVE_MUTEX_ALPHA_GCC_ASSEMBLY) - AH_TEMPLATE(HAVE_MUTEX_ALPHA_GCC_ASSEMBLY, - [Define to 1 to use the GCC compiler and Alpha assembly language mutexes.]);; -ARM/gcc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" - AC_DEFINE(HAVE_MUTEX_ARM_GCC_ASSEMBLY) - AH_TEMPLATE(HAVE_MUTEX_ARM_GCC_ASSEMBLY, - [Define to 1 to use the GCC compiler and ARM assembly language mutexes.]);; -HP/msem_init) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" - AC_DEFINE(HAVE_MUTEX_HPPA_MSEM_INIT) - AH_TEMPLATE(HAVE_MUTEX_HPPA_MSEM_INIT, - [Define to 1 to use the msem_XXX mutexes on HP-UX.]);; -HPPA/gcc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" - AC_DEFINE(HAVE_MUTEX_HPPA_GCC_ASSEMBLY) - AH_TEMPLATE(HAVE_MUTEX_HPPA_GCC_ASSEMBLY, - [Define to 1 to use the GCC compiler and PaRisc assembly language mutexes.]);; -ia64/gcc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" - AC_DEFINE(HAVE_MUTEX_IA64_GCC_ASSEMBLY) - AH_TEMPLATE(HAVE_MUTEX_IA64_GCC_ASSEMBLY, - [Define to 1 to use the GCC compiler and IA64 assembly language mutexes.]);; -POSIX/pthreads) ADDITIONAL_OBJS="mut_pthread${o} $ADDITIONAL_OBJS" - thread_h_decl="#include <pthread.h>" - db_threadid_t_decl="typedef pthread_t db_threadid_t;" - AC_DEFINE(HAVE_MUTEX_PTHREADS) - AH_TEMPLATE(HAVE_MUTEX_PTHREADS, - [Define to 1 to use POSIX 1003.1 pthread_XXX mutexes.]);; -POSIX/pthreads/private) ADDITIONAL_OBJS="mut_pthread${o} $ADDITIONAL_OBJS" - thread_h_decl="#include <pthread.h>" - db_threadid_t_decl="typedef pthread_t db_threadid_t;" - AC_DEFINE(HAVE_MUTEX_PTHREADS) - AH_TEMPLATE(HAVE_MUTEX_PTHREADS, - [Define to 1 to use POSIX 1003.1 pthread_XXX mutexes.]) - AC_DEFINE(HAVE_MUTEX_THREAD_ONLY) - AH_TEMPLATE(HAVE_MUTEX_THREAD_ONLY, - [Define to 1 to configure mutexes intra-process only.]);; -POSIX/pthreads/library) LIBS="$LIBS -lpthread" - LIBSO_LIBS="$LIBSO_LIBS -lpthread" - ADDITIONAL_OBJS="mut_pthread${o} $ADDITIONAL_OBJS" - thread_h_decl="#include <pthread.h>" - db_threadid_t_decl="typedef pthread_t db_threadid_t;" - AC_DEFINE(HAVE_MUTEX_PTHREADS) - AH_TEMPLATE(HAVE_MUTEX_PTHREADS, - [Define to 1 to use POSIX 1003.1 pthread_XXX mutexes.]);; -POSIX/pthreads/library/private) - LIBS="$LIBS -lpthread" - LIBSO_LIBS="$LIBSO_LIBS -lpthread" - ADDITIONAL_OBJS="mut_pthread${o} $ADDITIONAL_OBJS" - thread_h_decl="#include <pthread.h>" - db_threadid_t_decl="typedef pthread_t db_threadid_t;" - AC_DEFINE(HAVE_MUTEX_PTHREADS) - AH_TEMPLATE(HAVE_MUTEX_PTHREADS, - [Define to 1 to use POSIX 1003.1 pthread_XXX mutexes.]) - AC_DEFINE(HAVE_MUTEX_THREAD_ONLY) - AH_TEMPLATE(HAVE_MUTEX_THREAD_ONLY, - [Define to 1 to configure mutexes intra-process only.]);; -PPC/gcc-assembly) - ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" - AC_DEFINE(HAVE_MUTEX_PPC_GCC_ASSEMBLY) - AH_TEMPLATE(HAVE_MUTEX_PPC_GCC_ASSEMBLY, - [Define to 1 to use the GCC compiler and PowerPC assembly language mutexes.]);; -ReliantUNIX/initspin) LIBS="$LIBS -lmproc" - ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" - AC_DEFINE(HAVE_MUTEX_RELIANTUNIX_INITSPIN) - AH_TEMPLATE(HAVE_MUTEX_RELIANTUNIX_INITSPIN, - [Define to 1 to use Reliant UNIX initspin mutexes.]);; -S390/cc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" - AC_DEFINE(HAVE_MUTEX_S390_CC_ASSEMBLY) - AH_TEMPLATE(HAVE_MUTEX_S390_CC_ASSEMBLY, - [Define to 1 to use the IBM C compiler and S/390 assembly language mutexes.]);; -S390/gcc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" - AC_DEFINE(HAVE_MUTEX_S390_GCC_ASSEMBLY) - AH_TEMPLATE(HAVE_MUTEX_S390_GCC_ASSEMBLY, - [Define to 1 to use the GCC compiler and S/390 assembly language mutexes.]);; -SCO/x86/cc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" - AC_DEFINE(HAVE_MUTEX_SCO_X86_CC_ASSEMBLY) - AH_TEMPLATE(HAVE_MUTEX_SCO_X86_CC_ASSEMBLY, - [Define to 1 to use the SCO compiler and x86 assembly language mutexes.]);; -SGI/init_lock) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" - AC_DEFINE(HAVE_MUTEX_SGI_INIT_LOCK) - AH_TEMPLATE(HAVE_MUTEX_SGI_INIT_LOCK, - [Define to 1 to use the SGI XXX_lock mutexes.]);; -Solaris/_lock_try) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" - AC_DEFINE(HAVE_MUTEX_SOLARIS_LOCK_TRY) - AH_TEMPLATE(HAVE_MUTEX_SOLARIS_LOCK_TRY, - [Define to 1 to use the Solaris _lock_XXX mutexes.]);; -Solaris/lwp) ADDITIONAL_OBJS="mut_pthread${o} $ADDITIONAL_OBJS" - thread_h_decl="#include <pthread.h>" - db_threadid_t_decl="typedef pthread_t db_threadid_t;" - AC_DEFINE(HAVE_MUTEX_SOLARIS_LWP) - AH_TEMPLATE(HAVE_MUTEX_SOLARIS_LWP, - [Define to 1 to use the Solaris lwp threads mutexes.]);; -Sparc/gcc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" - AC_DEFINE(HAVE_MUTEX_SPARC_GCC_ASSEMBLY) - AH_TEMPLATE(HAVE_MUTEX_SPARC_GCC_ASSEMBLY, - [Define to 1 to use the GCC compiler and Sparc assembly language mutexes.]);; -Tru64/cc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" - AC_DEFINE(HAVE_MUTEX_TRU64_CC_ASSEMBLY) - AH_TEMPLATE(HAVE_MUTEX_TRU64_CC_ASSEMBLY, - [Define to 1 to use the CC compiler and Tru64 assembly language mutexes.]);; -UI/threads) ADDITIONAL_OBJS="mut_pthread${o} $ADDITIONAL_OBJS" - thread_h_decl="#include <thread.h>" - db_threadid_t_decl="typedef thread_t db_threadid_t;" - AC_DEFINE(HAVE_MUTEX_UI_THREADS) - AH_TEMPLATE(HAVE_MUTEX_UI_THREADS, - [Define to 1 to use the UNIX International mutexes.]);; -UI/threads/library) LIBS="$LIBS -lthread" - LIBSO_LIBS="$LIBSO_LIBS -lthread" - ADDITIONAL_OBJS="mut_pthread${o} $ADDITIONAL_OBJS" - thread_h_decl="#include <thread.h>" - db_threadid_t_decl="typedef thread_t db_threadid_t;" - AC_DEFINE(HAVE_MUTEX_UI_THREADS) - AH_TEMPLATE(HAVE_MUTEX_UI_THREADS, - [Define to 1 to use the UNIX International mutexes.]);; -UNIX/msem_init) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" - AC_DEFINE(HAVE_MUTEX_MSEM_INIT) - AH_TEMPLATE(HAVE_MUTEX_MSEM_INIT, - [Define to 1 to use the msem_XXX mutexes on systems other than HP-UX.]);; -UNIX/sema_init) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" - AC_DEFINE(HAVE_MUTEX_SEMA_INIT) - AH_TEMPLATE(HAVE_MUTEX_SEMA_INIT, - [Define to 1 to use the obsolete POSIX 1003.1 sema_XXX mutexes.]);; -UTS/cc-assembly) ADDITIONAL_OBJS="uts4.cc${o} $ADDITIONAL_OBJS" - AC_DEFINE(HAVE_MUTEX_UTS_CC_ASSEMBLY) - AH_TEMPLATE(HAVE_MUTEX_UTS_CC_ASSEMBLY, - [Define to 1 to use the UTS compiler and assembly language mutexes.]);; -win32) ADDITIONAL_OBJS="mut_win32${o} $ADDITIONAL_OBJS" - AC_DEFINE(HAVE_MUTEX_WIN32) - AH_TEMPLATE(HAVE_MUTEX_WIN32, [Define to 1 to use the MSVC compiler and Windows mutexes.]);; -win32/gcc) ADDITIONAL_OBJS="mut_win32${o} $ADDITIONAL_OBJS" - AC_DEFINE(HAVE_MUTEX_WIN32_GCC) - AH_TEMPLATE(HAVE_MUTEX_WIN32_GCC, [Define to 1 to use the GCC compiler and Windows mutexes.]);; -MIPS/gcc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" - AC_DEFINE(HAVE_MUTEX_MIPS_GCC_ASSEMBLY) - AH_TEMPLATE(HAVE_MUTEX_MIPS_GCC_ASSEMBLY, - [Define to 1 to use the GCC compiler and MIPS assembly language mutexes.]);; -x86/gcc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" - AC_DEFINE(HAVE_MUTEX_X86_GCC_ASSEMBLY) - AH_TEMPLATE(HAVE_MUTEX_X86_GCC_ASSEMBLY, - [Define to 1 to use the GCC compiler and x86 assembly language mutexes.]);; -x86_64/gcc-assembly) ADDITIONAL_OBJS="mut_tas${o} $ADDITIONAL_OBJS" - AC_DEFINE(HAVE_MUTEX_X86_64_GCC_ASSEMBLY) - AH_TEMPLATE(HAVE_MUTEX_X86_64_GCC_ASSEMBLY, - [Define to 1 to use the GCC compiler and amd64 assembly language mutexes.]);; -UNIX/fcntl) AC_MSG_WARN( - [NO FAST MUTEXES FOUND FOR THIS COMPILER/ARCHITECTURE.]) - ADDITIONAL_OBJS="mut_fcntl${o} $ADDITIONAL_OBJS" - AC_DEFINE(HAVE_MUTEX_FCNTL) - AH_TEMPLATE(HAVE_MUTEX_FCNTL, - [Define to 1 to use the UNIX fcntl system call mutexes.]);; -*) AC_MSG_ERROR([Unknown mutex interface: $db_cv_mutex]);; -esac - -# The mutex selection often tells us what kind of thread package we're using. -# We need to know if the thread ID type will fit into an integral type and we -# can compare it for equality and generally treat it like an int, or if it's a -# non-integral type and we have to treat it like a structure or other untyped -# block of bytes. For example, MVS typedef's pthread_t to a structure. -AH_TEMPLATE(HAVE_INTEGRAL_THREAD_TYPE, - [Define to 1 if thread identifier type db_threadid_t is integral.]) -if test "$db_threadid_t_decl" = "notset"; then - db_threadid_t_decl="typedef uintmax_t db_threadid_t;" - AC_DEFINE(HAVE_INTEGRAL_THREAD_TYPE) -else - AC_TRY_COMPILE( - #include <sys/types.h> - $thread_h_decl, [ - $db_threadid_t_decl - db_threadid_t a; - a = 0; - ], AC_DEFINE(HAVE_INTEGRAL_THREAD_TYPE)) -fi - -# There are 3 classes of mutexes: -# -# 1: Mutexes requiring no cleanup, for example, test-and-set mutexes. -# 2: Mutexes that must be destroyed, but which don't hold permanent system -# resources, for example, pthread mutexes on MVS aka OS/390 aka z/OS. -# 3: Mutexes that must be destroyed, even after the process is gone, for -# example, pthread mutexes on QNX and binary semaphores on VxWorks. -# -# DB cannot currently distinguish between #2 and #3 because DB does not know -# if the application is running environment recovery as part of startup and -# does not need to do cleanup, or if the environment is being removed and/or -# recovered in a loop in the application, and so does need to clean up. If -# we get it wrong, we're going to call the mutex destroy routine on a random -# piece of memory, which usually works, but just might drop core. For now, -# we group #2 and #3 into the HAVE_MUTEX_SYSTEM_RESOURCES define, until we -# have a better solution or reason to solve this in a general way -- so far, -# the places we've needed to handle this are few. -AH_TEMPLATE(HAVE_MUTEX_SYSTEM_RESOURCES, - [Define to 1 if mutexes hold system resources.]) - -case "$host_os$db_cv_mutex" in -*qnx*POSIX/pthread*|openedition*POSIX/pthread*) - AC_DEFINE(HAVE_MUTEX_SYSTEM_RESOURCES);; -esac]) diff --git a/storage/bdb/dist/aclocal/options.ac b/storage/bdb/dist/aclocal/options.ac deleted file mode 100644 index 2697c030b86..00000000000 --- a/storage/bdb/dist/aclocal/options.ac +++ /dev/null @@ -1,292 +0,0 @@ -# $Id: options.ac,v 12.2 2005/10/12 14:45:42 bostic Exp $ - -# Process user-specified options. -AC_DEFUN(AM_OPTIONS_SET, [ - -# --enable-bigfile was the configuration option that Berkeley DB used before -# autoconf 2.50 was released (which had --enable-largefile integrated in). -AC_ARG_ENABLE(bigfile, - [AC_HELP_STRING([--disable-bigfile], - [Obsolete; use --disable-largefile instead.])], - [AC_MSG_ERROR( - [--enable-bigfile no longer supported, use --enable-largefile])]) - -AC_MSG_CHECKING(if --disable-cryptography option specified) -AC_ARG_ENABLE(cryptography, - AC_HELP_STRING([--disable-cryptography], - [Do not build database cryptography support.]),, enableval="yes") -db_cv_build_cryptography="$enableval" -case "$enableval" in - no) AC_MSG_RESULT(yes);; -yes) AC_MSG_RESULT(no);; -esac - -AC_MSG_CHECKING(if --disable-hash option specified) -AC_ARG_ENABLE(hash, - AC_HELP_STRING([--disable-hash], - [Do not build Hash access method.]),, enableval="yes") -db_cv_build_hash="$enableval" -case "$enableval" in - no) AC_MSG_RESULT(yes);; -yes) AC_MSG_RESULT(no);; -esac - -AC_MSG_CHECKING(if --disable-queue option specified) -AC_ARG_ENABLE(queue, - AC_HELP_STRING([--disable-queue], - [Do not build Queue access method.]),, enableval="yes") -db_cv_build_queue="$enableval" -case "$enableval" in - no) AC_MSG_RESULT(yes);; -yes) AC_MSG_RESULT(no);; -esac - -AC_MSG_CHECKING(if --disable-replication option specified) -AC_ARG_ENABLE(replication, - AC_HELP_STRING([--disable-replication], - [Do not build database replication support.]),, enableval="yes") -db_cv_build_replication="$enableval" -case "$enableval" in - no) AC_MSG_RESULT(yes);; -yes) AC_MSG_RESULT(no);; -esac - -AC_MSG_CHECKING(if --disable-statistics option specified) -AC_ARG_ENABLE(statistics, - AC_HELP_STRING([--disable-statistics], - [Do not build statistics support.]),, enableval="yes") -db_cv_build_statistics="$enableval" -case "$enableval" in - no) AC_MSG_RESULT(yes);; -yes) AC_MSG_RESULT(no);; -esac - -AC_MSG_CHECKING(if --disable-verify option specified) -AC_ARG_ENABLE(verify, - AC_HELP_STRING([--disable-verify], - [Do not build database verification support.]),, enableval="yes") -db_cv_build_verify="$enableval" -case "$enableval" in - no) AC_MSG_RESULT(yes);; -yes) AC_MSG_RESULT(no);; -esac - -AC_MSG_CHECKING(if --enable-compat185 option specified) -AC_ARG_ENABLE(compat185, - [AC_HELP_STRING([--enable-compat185], - [Build DB 1.85 compatibility API.])], - [db_cv_compat185="$enable_compat185"], [db_cv_compat185="no"]) -AC_MSG_RESULT($db_cv_compat185) - -AC_MSG_CHECKING(if --enable-cxx option specified) -AC_ARG_ENABLE(cxx, - [AC_HELP_STRING([--enable-cxx], - [Build C++ API.])], - [db_cv_cxx="$enable_cxx"], [db_cv_cxx="no"]) -AC_MSG_RESULT($db_cv_cxx) - -AC_MSG_CHECKING(if --enable-debug option specified) -AC_ARG_ENABLE(debug, - [AC_HELP_STRING([--enable-debug], - [Build a debugging version.])], - [db_cv_debug="$enable_debug"], [db_cv_debug="no"]) -AC_MSG_RESULT($db_cv_debug) - -AC_MSG_CHECKING(if --enable-debug_rop option specified) -AC_ARG_ENABLE(debug_rop, - [AC_HELP_STRING([--enable-debug_rop], - [Build a version that logs read operations.])], - [db_cv_debug_rop="$enable_debug_rop"], [db_cv_debug_rop="no"]) -AC_MSG_RESULT($db_cv_debug_rop) - -AC_MSG_CHECKING(if --enable-debug_wop option specified) -AC_ARG_ENABLE(debug_wop, - [AC_HELP_STRING([--enable-debug_wop], - [Build a version that logs write operations.])], - [db_cv_debug_wop="$enable_debug_wop"], [db_cv_debug_wop="no"]) -AC_MSG_RESULT($db_cv_debug_wop) - -AC_MSG_CHECKING(if --enable-diagnostic option specified) -AC_ARG_ENABLE(diagnostic, - [AC_HELP_STRING([--enable-diagnostic], - [Build a version with run-time diagnostics.])], - [db_cv_diagnostic="$enable_diagnostic"], [db_cv_diagnostic="no"]) -if test "$db_cv_diagnostic" = "yes"; then - AC_MSG_RESULT($db_cv_diagnostic) -fi -if test "$db_cv_diagnostic" = "no" -a "$db_cv_debug_rop" = "yes"; then - db_cv_diagnostic="yes" - AC_MSG_RESULT([by --enable-debug_rop]) -fi -if test "$db_cv_diagnostic" = "no" -a "$db_cv_debug_wop" = "yes"; then - db_cv_diagnostic="yes" - AC_MSG_RESULT([by --enable-debug_wop]) -fi -if test "$db_cv_diagnostic" = "no"; then - AC_MSG_RESULT($db_cv_diagnostic) -fi - -AC_MSG_CHECKING(if --enable-dump185 option specified) -AC_ARG_ENABLE(dump185, - [AC_HELP_STRING([--enable-dump185], - [Build db_dump185(1) to dump 1.85 databases.])], - [db_cv_dump185="$enable_dump185"], [db_cv_dump185="no"]) -AC_MSG_RESULT($db_cv_dump185) - -AC_MSG_CHECKING(if --enable-java option specified) -AC_ARG_ENABLE(java, - [AC_HELP_STRING([--enable-java], - [Build Java API.])], - [db_cv_java="$enable_java"], [db_cv_java="no"]) -AC_MSG_RESULT($db_cv_java) - -AC_MSG_CHECKING(if --enable-mingw option specified) -AC_ARG_ENABLE(mingw, - [AC_HELP_STRING([--enable-mingw], - [Build Berkeley DB for MinGW.])], - [db_cv_mingw="$enable_mingw"], [db_cv_mingw="no"]) -AC_MSG_RESULT($db_cv_mingw) - -AC_MSG_CHECKING(if --enable-o_direct option specified) -AC_ARG_ENABLE(o_direct, - [AC_HELP_STRING([--enable-o_direct], - [Enable the O_DIRECT flag for direct I/O.])], - [db_cv_o_direct="$enable_o_direct"], [db_cv_o_direct="no"]) -AC_MSG_RESULT($db_cv_o_direct) - -AC_MSG_CHECKING(if --enable-posixmutexes option specified) -AC_ARG_ENABLE(posixmutexes, - [AC_HELP_STRING([--enable-posixmutexes], - [Force use of POSIX standard mutexes.])], - [db_cv_posixmutexes="$enable_posixmutexes"], [db_cv_posixmutexes="no"]) -AC_MSG_RESULT($db_cv_posixmutexes) - -AC_MSG_CHECKING(if --enable-pthread_self option specified) -AC_ARG_ENABLE(pthread_self, - [AC_HELP_STRING([--enable-pthread_self], - [Force use of pthread_self to identify threads.])], - [db_cv_pthread_self="$enable_pthread_self"], [db_cv_pthread_self="no"]) -AC_MSG_RESULT($db_cv_pthread_self) - -AC_MSG_CHECKING(if --enable-rpc option specified) -AC_ARG_ENABLE(rpc, - [AC_HELP_STRING([--enable-rpc], - [Build RPC client/server.])], - [db_cv_rpc="$enable_rpc"], [db_cv_rpc="no"]) -AC_MSG_RESULT($db_cv_rpc) - -AC_MSG_CHECKING(if --enable-smallbuild option specified) -AC_ARG_ENABLE(smallbuild, - [AC_HELP_STRING([--enable-smallbuild], - [Build small footprint version of the library.])], - [db_cv_smallbuild="$enable_smallbuild"], [db_cv_smallbuild="no"]) -if test "$db_cv_smallbuild" = "yes"; then - db_cv_build_cryptography="no" - db_cv_build_hash="no" - db_cv_build_queue="no" - db_cv_build_replication="no" - db_cv_build_statistics="no" - db_cv_build_verify="no" -fi -AC_MSG_RESULT($db_cv_smallbuild) - -AC_MSG_CHECKING(if --enable-tcl option specified) -AC_ARG_ENABLE(tcl, - [AC_HELP_STRING([--enable-tcl], - [Build Tcl API.])], - [db_cv_tcl="$enable_tcl"], [db_cv_tcl="no"]) -AC_MSG_RESULT($db_cv_tcl) - -AC_MSG_CHECKING(if --enable-test option specified) -AC_ARG_ENABLE(test, - [AC_HELP_STRING([--enable-test], - [Configure to run the test suite.])], - [db_cv_test="$enable_test"], [db_cv_test="no"]) -AC_MSG_RESULT($db_cv_test) - -AC_MSG_CHECKING(if --enable-uimutexes option specified) -AC_ARG_ENABLE(uimutexes, - [AC_HELP_STRING([--enable-uimutexes], - [Force use of Unix International mutexes.])], - [db_cv_uimutexes="$enable_uimutexes"], [db_cv_uimutexes="no"]) -AC_MSG_RESULT($db_cv_uimutexes) - -AC_MSG_CHECKING(if --enable-umrw option specified) -AC_ARG_ENABLE(umrw, - [AC_HELP_STRING([--enable-umrw], - [Mask harmless uninitialized memory read/writes.])], - [db_cv_umrw="$enable_umrw"], [db_cv_umrw="no"]) -AC_MSG_RESULT($db_cv_umrw) - -AC_MSG_CHECKING(if --with-mutex=MUTEX option specified) -AC_ARG_WITH(mutex, - [AC_HELP_STRING([--with-mutex=MUTEX], - [Selection of non-standard mutexes.])], - [with_mutex="$withval"], [with_mutex="no"]) -if test "$with_mutex" = "yes"; then - AC_MSG_ERROR([--with-mutex requires a mutex name argument]) -fi -if test "$with_mutex" != "no"; then - db_cv_mutex="$with_mutex" -fi -AC_MSG_RESULT($with_mutex) - -# --with-mutexalign=ALIGNMENT was the configuration option that Berkeley DB -# used before the DbEnv::mutex_set_align method was added. -AC_ARG_WITH(mutexalign, - [AC_HELP_STRING([--with-mutexalign=ALIGNMENT], - [Obsolete; use DbEnv::mutex_set_align instead.])], - [AC_MSG_ERROR( - [--with-mutexalign no longer supported, use DbEnv::mutex_set_align])]) - -AC_MSG_CHECKING([if --with-tcl=DIR option specified]) -AC_ARG_WITH(tcl, - [AC_HELP_STRING([--with-tcl=DIR], - [Directory location of tclConfig.sh.])], - [with_tclconfig="$withval"], [with_tclconfig="no"]) -AC_MSG_RESULT($with_tclconfig) -if test "$with_tclconfig" != "no"; then - db_cv_tcl="yes" -fi - -AC_MSG_CHECKING([if --with-uniquename=NAME option specified]) -AC_ARG_WITH(uniquename, - [AC_HELP_STRING([--with-uniquename=NAME], - [Build a uniquely named library.])], - [with_uniquename="$withval"], [with_uniquename="no"]) -if test "$with_uniquename" = "no"; then - db_cv_uniquename="no" - DB_VERSION_UNIQUE_NAME="" - AC_MSG_RESULT($with_uniquename) -else - db_cv_uniquename="yes" - if test "$with_uniquename" = "yes"; then - DB_VERSION_UNIQUE_NAME="__EDIT_DB_VERSION_UNIQUE_NAME__" - else - DB_VERSION_UNIQUE_NAME="$with_uniquename" - fi - AC_MSG_RESULT($DB_VERSION_UNIQUE_NAME) -fi - -# Test requires Tcl -if test "$db_cv_test" = "yes"; then - if test "$db_cv_tcl" = "no"; then - AC_MSG_ERROR([--enable-test requires --enable-tcl]) - fi -fi - -# Uniquename excludes C++, Java, RPC. -if test "$db_cv_uniquename" = "yes"; then - if test "$db_cv_rpc" = "yes"; then - AC_MSG_ERROR( - [--with-uniquename is not compatible with --enable-rpc]) - fi - if test "$db_cv_cxx" = "yes"; then - AC_MSG_ERROR( - [--with-uniquename is not compatible with --enable-cxx]) - fi - if test "$db_cv_java" = "yes"; then - AC_MSG_ERROR( - [--with-uniquename is not compatible with --enable-java]) - fi -fi]) diff --git a/storage/bdb/dist/aclocal/programs.ac b/storage/bdb/dist/aclocal/programs.ac deleted file mode 100644 index 76ce0ded66a..00000000000 --- a/storage/bdb/dist/aclocal/programs.ac +++ /dev/null @@ -1,76 +0,0 @@ -# $Id: programs.ac,v 12.1 2005/04/07 06:47:03 mjc Exp $ - -# Check for programs used in building/installation. -AC_DEFUN(AM_PROGRAMS_SET, [ - -AC_CHECK_TOOL(db_cv_path_ar, ar, missing_ar) -if test "$db_cv_path_ar" = missing_ar; then - AC_MSG_ERROR([No ar utility found.]) -fi - -AC_CHECK_TOOL(db_cv_path_chmod, chmod, missing_chmod) -if test "$db_cv_path_chmod" = missing_chmod; then - AC_MSG_ERROR([No chmod utility found.]) -fi - -AC_CHECK_TOOL(db_cv_path_cp, cp, missing_cp) -if test "$db_cv_path_cp" = missing_cp; then - AC_MSG_ERROR([No cp utility found.]) -fi - -AC_CHECK_TOOL(db_cv_path_ln, ln, missing_ln) -if test "$db_cv_path_ln" = missing_ln; then - AC_MSG_ERROR([No ln utility found.]) -fi - -AC_CHECK_TOOL(db_cv_path_mkdir, mkdir, missing_mkdir) -if test "$db_cv_path_mkdir" = missing_mkdir; then - AC_MSG_ERROR([No mkdir utility found.]) -fi - -# We need a complete path for ranlib, because it doesn't exist on some -# architectures because the ar utility packages the library itself. -AC_CHECK_TOOL(path_ranlib, ranlib, missing_ranlib) -AC_PATH_PROG(db_cv_path_ranlib, $path_ranlib, missing_ranlib) - -AC_CHECK_TOOL(db_cv_path_rm, rm, missing_rm) -if test "$db_cv_path_rm" = missing_rm; then - AC_MSG_ERROR([No rm utility found.]) -fi - -if test "$db_cv_rpc" = "yes"; then - AC_CHECK_TOOL(db_cv_path_rpcgen, rpcgen, missing_rpcgen) - if test "$db_cv_path_rpcgen" = missing_rpcgen; then - AC_MSG_ERROR([No rpcgen utility found.]) - fi -fi - -# We need a complete path for sh, because some implementations of make -# get upset if SHELL is set to just the command name. -AC_CHECK_TOOL(path_sh, sh, missing_sh) -AC_PATH_PROG(db_cv_path_sh, $path_sh, missing_sh) -if test "$db_cv_path_sh" = missing_sh; then - AC_MSG_ERROR([No sh utility found.]) -fi - -AC_CHECK_TOOL(db_cv_path_true, true, missing_true) -if test "$db_cv_path_true" = missing_true; then - AC_MSG_ERROR([No true utility found.]) -fi - -# Don't strip the binaries if --enable-debug was specified. -if test "$db_cv_debug" = yes; then - db_cv_path_strip=debug_build_no_strip -else - AC_CHECK_TOOL(path_strip, strip, missing_strip) - AC_PATH_PROG(db_cv_path_strip, $path_strip, missing_strip) -fi - -if test "$db_cv_test" = "yes"; then - AC_CHECK_TOOL(db_cv_path_kill, kill, missing_kill) - if test "$db_cv_path_kill" = missing_kill; then - AC_MSG_ERROR([No kill utility found.]) - fi -fi - -]) diff --git a/storage/bdb/dist/aclocal/rpc.ac b/storage/bdb/dist/aclocal/rpc.ac deleted file mode 100644 index 7e7198bc0fe..00000000000 --- a/storage/bdb/dist/aclocal/rpc.ac +++ /dev/null @@ -1,83 +0,0 @@ -# $Id: rpc.ac,v 12.0 2004/11/17 03:43:37 bostic Exp $ - -# Try and configure RPC support. -AC_DEFUN(AM_RPC_CONFIGURE, [ - AC_DEFINE(HAVE_RPC) - AH_TEMPLATE(HAVE_RPC, [Define to 1 if building RPC client/server.]) - - # We use the target's rpcgen utility because it may be architecture - # specific, for example, 32- or 64-bit specific. - XDR_FILE=$srcdir/../rpc_server/db_server.x - - # Prefer the -C option to rpcgen which generates ANSI C-conformant - # code. - RPCGEN="rpcgen -C" - AC_MSG_CHECKING(["$RPCGEN" build of db_server.h]) - $RPCGEN -h $XDR_FILE > db_server.h 2>/dev/null - if test $? -ne 0; then - AC_MSG_RESULT([no]) - - # Try rpcgen without the -C option. - RPCGEN="rpcgen" - AC_MSG_CHECKING(["$RPCGEN" build of db_server.h]) - $RPCGEN -h $XDR_FILE > db_server.h 2>/dev/null - if test $? -ne 0; then - AC_MSG_RESULT([no]) - AC_MSG_ERROR( - [Unable to build RPC support: $RPCGEN failed.]) - fi - fi - - # Some rpcgen programs generate a set of client stubs called something - # like __db_env_create_4003 and functions on the server to handle the - # request called something like __db_env_create_4003_svc. Others - # expect client and server stubs to both be called __db_env_create_4003. - # - # We have to generate code in whichever format rpcgen expects, and the - # only reliable way to do that is to check what is in the db_server.h - # file we just created. - if grep "env_create_[[0-9]]*_svc" db_server.h >/dev/null 2>&1 ; then - sed 's/__SVCSUFFIX__/_svc/' \ - < $srcdir/../rpc_server/c/gen_db_server.c > gen_db_server.c - else - sed 's/__SVCSUFFIX__//' \ - < $srcdir/../rpc_server/c/gen_db_server.c > gen_db_server.c - fi - - AC_MSG_RESULT([yes]) - - $RPCGEN -l $XDR_FILE | - sed -e 's/^#include.*db_server.h.*/#include "db_server.h"/' \ - -e '1,/^#include/s/^#include/#include "db_config.h"\ -&/' > db_server_clnt.c - - $RPCGEN -s tcp $XDR_FILE | - sed -e 's/^#include.*db_server.h.*/#include "db_server.h"/' \ - -e 's/^main *()/__dbsrv_main()/' \ - -e 's/^main *(.*argc.*argv.*)/__dbsrv_main(int argc, char *argv[])/' \ - -e '/^db_rpc_serverprog/,/^}/{' \ - -e 's/return;//' \ - -e 's/^}/__dbsrv_timeout(0);}/' \ - -e '}' \ - -e '1,/^#include/s/^#include/#include "db_config.h"\ -&/' > db_server_svc.c - - $RPCGEN -c $XDR_FILE | - sed -e 's/^#include.*db_server.h.*/#include "db_server.h"/' \ - -e '1,/^#include/s/^#include/#include "db_config.h"\ -&/' > db_server_xdr.c - - RPC_SERVER_H=db_server.h - RPC_CLIENT_OBJS="\$(RPC_CLIENT_OBJS)" - ADDITIONAL_PROGS="berkeley_db_svc $ADDITIONAL_PROGS" - - case "$host_os" in - hpux*) - AC_CHECK_FUNC(svc_run,, - AC_CHECK_LIB(nsl, svc_run, - LIBS="-lnsl $LIBS"; LIBTSO_LIBS="-lnsl $LIBTSO_LIBS"; - LIBJSO_LIBS="-lnsl $LIBJSO_LIBS"));; - solaris*) - AC_CHECK_FUNC(svc_run,, AC_CHECK_LIB(nsl, svc_run));; - esac -]) diff --git a/storage/bdb/dist/aclocal/sequence.ac b/storage/bdb/dist/aclocal/sequence.ac deleted file mode 100644 index 5c491eeb1cf..00000000000 --- a/storage/bdb/dist/aclocal/sequence.ac +++ /dev/null @@ -1,95 +0,0 @@ -# $Id: sequence.ac,v 12.2 2005/11/03 17:46:14 bostic Exp $ - -# Try and configure sequence support. -AC_DEFUN(AM_SEQUENCE_CONFIGURE, [ - AC_MSG_CHECKING([for 64-bit integral type support for sequences]) - - db_cv_build_sequence="yes" - - # Have to have found 64-bit types to support sequences. If we don't - # find the native types, we try and create our own. - if test "$ac_cv_type_int64_t" = "no" -a -z "$int64_decl"; then - db_cv_build_sequence="no" - fi - if test "$ac_cv_type_uint64_t" = "no" -a -z "$u_int64_decl"; then - db_cv_build_sequence="no" - fi - - # Figure out what type is the right size, and set the format. - AC_SUBST(INT64_FMT) - AC_SUBST(UINT64_FMT) - db_cv_seq_type="no" - if test "$db_cv_build_sequence" = "yes" -a\ - "$ac_cv_sizeof_long" -eq "8"; then - db_cv_seq_type="long" - db_cv_seq_fmt='"%ld"' - db_cv_seq_ufmt='"%lu"' - INT64_FMT='#define INT64_FMT "%ld"' - UINT64_FMT='#define UINT64_FMT "%lu"' - else if test "$db_cv_build_sequence" = "yes" -a\ - "$ac_cv_sizeof_long_long" -eq "8"; then - db_cv_seq_type="long long" - db_cv_seq_fmt='"%lld"' - db_cv_seq_ufmt='"%llu"' - INT64_FMT='#define INT64_FMT "%lld"' - UINT64_FMT='#define UINT64_FMT "%llu"' - else - db_cv_build_sequence="no" - fi - fi - - # Test to see if we can declare variables of the appropriate size - # and format them. If we're cross-compiling, all we get is a link - # test, which won't test for the appropriate printf format strings. - if test "$db_cv_build_sequence" = "yes"; then - AC_TRY_RUN([ - main() { - $db_cv_seq_type l; - unsigned $db_cv_seq_type u; - char buf@<:@100@:>@; - - buf@<:@0@:>@ = 'a'; - l = 9223372036854775807LL; - (void)snprintf(buf, sizeof(buf), $db_cv_seq_fmt, l); - if (strcmp(buf, "9223372036854775807")) - return (1); - u = 18446744073709551615ULL; - (void)snprintf(buf, sizeof(buf), $db_cv_seq_ufmt, u); - if (strcmp(buf, "18446744073709551615")) - return (1); - return (0); - }],, [db_cv_build_sequence="no"], - AC_TRY_LINK(,[ - $db_cv_seq_type l; - unsigned $db_cv_seq_type u; - char buf@<:@100@:>@; - - buf@<:@0@:>@ = 'a'; - l = 9223372036854775807LL; - (void)snprintf(buf, sizeof(buf), $db_cv_seq_fmt, l); - if (strcmp(buf, "9223372036854775807")) - return (1); - u = 18446744073709551615ULL; - (void)snprintf(buf, sizeof(buf), $db_cv_seq_ufmt, u); - if (strcmp(buf, "18446744073709551615")) - return (1); - return (0); - ],, [db_cv_build_sequence="no"])) - fi - if test "$db_cv_build_sequence" = "yes"; then - AC_DEFINE(HAVE_SEQUENCE) - AH_TEMPLATE(HAVE_SEQUENCE, - [Define to 1 if building sequence support.]) - - AC_SUBST(db_seq_decl) - db_seq_decl="typedef int64_t db_seq_t;"; - - AC_DEFINE(HAVE_64BIT_TYPES) - AH_TEMPLATE(HAVE_64BIT_TYPES, - [Define to 1 if 64-bit types are available.]) - else - # It still has to compile, but it won't run. - db_seq_decl="typedef int db_seq_t;"; - fi - AC_MSG_RESULT($db_cv_build_sequence) -]) diff --git a/storage/bdb/dist/aclocal/sosuffix.ac b/storage/bdb/dist/aclocal/sosuffix.ac deleted file mode 100644 index bd391e248a0..00000000000 --- a/storage/bdb/dist/aclocal/sosuffix.ac +++ /dev/null @@ -1,76 +0,0 @@ -# $Id: sosuffix.ac,v 12.0 2004/11/17 03:43:38 bostic Exp $ -# Determine shared object suffixes. -# -# Our method is to use the libtool variable $library_names_spec, -# set by using AC_PROG_LIBTOOL. This variable is a snippet of shell -# defined in terms of $versuffix, $release, $libname and $module -# We want to eval it and grab the suffix used for shared objects. -# By setting $module to yes/no, we obtain the suffixes -# used to create dlloadable, or java loadable modules. -# On many (*nix) systems, these all evaluate to .so, but there -# are some notable exceptions. -# Before calling this macro, $LIBTOOL_PROG must be set to -# the correct method of invoking libtool (e.g. $SHELL ./libtool) - -# This macro is used internally to discover the suffix for the current -# settings of $module. The result is stored in $_SOSUFFIX. -AC_DEFUN(_SOSUFFIX_INTERNAL, [ - versuffix="" - release="" - libname=libfoo - eval _SOSUFFIX=\"$shrext_cmds\" - if test "$_SOSUFFIX" = "" ; then - _SOSUFFIX=".so" - if test `$LIBTOOL_PROG --config | grep build_libtool_libs | grep no` 2>/dev/null; then - if test "$_SOSUFFIX_MESSAGE" = ""; then - _SOSUFFIX_MESSAGE=yes - AC_MSG_WARN([libtool may not know about this architecture.]) - AC_MSG_WARN([assuming $_SUFFIX suffix for dynamic libraries.]) - fi - fi - fi -]) - -# SOSUFFIX_CONFIG will set the variable SOSUFFIX to be the -# shared library extension used for general linking, not dlopen. -AC_DEFUN(SOSUFFIX_CONFIG, [ - AC_MSG_CHECKING([SOSUFFIX from libtool]) - module=no - _SOSUFFIX_INTERNAL - SOSUFFIX=$_SOSUFFIX - AC_MSG_RESULT($SOSUFFIX) - AC_SUBST(SOSUFFIX) -]) - -# MODSUFFIX_CONFIG will set the variable MODSUFFIX to be the -# shared library extension used for dlopen'ed modules. -# To discover this, we set $module, simulating libtool's -module option. -AC_DEFUN(MODSUFFIX_CONFIG, [ - AC_MSG_CHECKING([MODSUFFIX from libtool]) - module=yes - _SOSUFFIX_INTERNAL - MODSUFFIX=$_SOSUFFIX - AC_MSG_RESULT($MODSUFFIX) - AC_SUBST(MODSUFFIX) -]) - -# JMODSUFFIX_CONFIG will set the variable JMODSUFFIX to be the -# shared library extension used JNI modules opened by Java. -# To discover this, we set $jnimodule, simulating libtool's -shrext option. -########################################################################## -# Robert Boehne: Not much point in this macro any more because apparently -# Darwin is the only OS that wants or needs the .jnilib extension. -########################################################################## -AC_DEFUN(JMODSUFFIX_CONFIG, [ - AC_MSG_CHECKING([JMODSUFFIX from libtool]) - module=yes - _SOSUFFIX_INTERNAL - if test `uname` = "Darwin"; then - JMODSUFFIX=".jnilib" - else - JMODSUFFIX=$_SOSUFFIX - fi - AC_MSG_RESULT($JMODSUFFIX) - AC_SUBST(JMODSUFFIX) -]) - diff --git a/storage/bdb/dist/aclocal/tcl.ac b/storage/bdb/dist/aclocal/tcl.ac deleted file mode 100644 index 360cf62b185..00000000000 --- a/storage/bdb/dist/aclocal/tcl.ac +++ /dev/null @@ -1,135 +0,0 @@ -# $Id: tcl.ac,v 12.2 2005/06/28 20:45:25 gmf Exp $ - -# The SC_* macros in this file are from the unix/tcl.m4 files in the Tcl -# 8.3.0 distribution, with some minor changes. For this reason, license -# terms for the Berkeley DB distribution dist/aclocal/tcl.m4 file are as -# follows (copied from the license.terms file in the Tcl 8.3 distribution): -# -# This software is copyrighted by the Regents of the University of -# California, Sun Microsystems, Inc., Scriptics Corporation, -# and other parties. The following terms apply to all files associated -# with the software unless explicitly disclaimed in individual files. -# -# The authors hereby grant permission to use, copy, modify, distribute, -# and license this software and its documentation for any purpose, provided -# that existing copyright notices are retained in all copies and that this -# notice is included verbatim in any distributions. No written agreement, -# license, or royalty fee is required for any of the authorized uses. -# Modifications to this software may be copyrighted by their authors -# and need not follow the licensing terms described here, provided that -# the new terms are clearly indicated on the first page of each file where -# they apply. -# -# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY -# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES -# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY -# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, -# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE -# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE -# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR -# MODIFICATIONS. -# -# GOVERNMENT USE: If you are acquiring this software on behalf of the -# U.S. government, the Government shall have only "Restricted Rights" -# in the software and related documentation as defined in the Federal -# Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you -# are acquiring the software on behalf of the Department of Defense, the -# software shall be classified as "Commercial Computer Software" and the -# Government shall have only "Restricted Rights" as defined in Clause -# 252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the -# authors grant the U.S. Government and others acting in its behalf -# permission to use and distribute the software in accordance with the -# terms specified in this license. - -AC_DEFUN(SC_PATH_TCLCONFIG, [ - AC_CACHE_VAL(ac_cv_c_tclconfig,[ - - # First check to see if --with-tclconfig was specified. - if test "${with_tclconfig}" != no; then - if test -f "${with_tclconfig}/tclConfig.sh" ; then - ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)` - else - AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh]) - fi - fi - - # check in a few common install locations - if test x"${ac_cv_c_tclconfig}" = x ; then - for i in `ls -d /usr/local/lib 2>/dev/null` ; do - if test -f "$i/tclConfig.sh" ; then - ac_cv_c_tclconfig=`(cd $i; pwd)` - break - fi - done - fi - - ]) - - if test x"${ac_cv_c_tclconfig}" = x ; then - TCL_BIN_DIR="# no Tcl configs found" - AC_MSG_ERROR(can't find Tcl configuration definitions) - else - TCL_BIN_DIR=${ac_cv_c_tclconfig} - fi -]) - -AC_DEFUN(SC_LOAD_TCLCONFIG, [ - AC_MSG_CHECKING([for existence of $TCL_BIN_DIR/tclConfig.sh]) - - if test -f "$TCL_BIN_DIR/tclConfig.sh" ; then - AC_MSG_RESULT([loading]) - . $TCL_BIN_DIR/tclConfig.sh - else - AC_MSG_RESULT([file not found]) - fi - - # DB requires at least version 8.4. - if test ${TCL_MAJOR_VERSION} -lt 8 \ - -o ${TCL_MAJOR_VERSION} -eq 8 -a ${TCL_MINOR_VERSION} -lt 4; then - AC_MSG_ERROR([Berkeley DB requires Tcl version 8.4 or better.]) - fi - - # The eval is required to do substitution (for example, the TCL_DBGX - # substitution in the TCL_LIB_FILE variable. - eval "TCL_INCLUDE_SPEC=\"${TCL_INCLUDE_SPEC}\"" - eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\"" - eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\"" - eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\"" - - # - # If the DB Tcl library isn't loaded with the Tcl spec and library - # flags on AIX, the resulting libdb_tcl-X.Y.so.0 will drop core at - # load time. [#4843] Furthermore, with Tcl 8.3, the link flags - # given by the Tcl spec are insufficient for our use. [#5779] - # - case "$host_os" in - aix4.[[2-9]].*) - LIBTSO_LIBS="$LIBTSO_LIBS $TCL_LIB_SPEC $TCL_LIB_FLAG" - LIBTSO_LIBS="$LIBTSO_LIBS -L$TCL_EXEC_PREFIX/lib -ltcl$TCL_VERSION";; - aix*) - LIBTSO_LIBS="$LIBTSO_LIBS $TCL_LIB_SPEC $TCL_LIB_FLAG";; - esac - AC_SUBST(TCL_BIN_DIR) - AC_SUBST(TCL_INCLUDE_SPEC) - AC_SUBST(TCL_LIB_FILE) - AC_SUBST(TCL_SRC_DIR) - - AC_SUBST(TCL_TCLSH) - TCL_TCLSH="${TCL_PREFIX}/bin/tclsh${TCL_VERSION}" -]) - -# Optional Tcl API. -AC_DEFUN(AM_TCL_LOAD, [ - if test `$LIBTOOL_PROG --config | grep build_libtool_libs | grep no` 2>/dev/null; then - AC_MSG_ERROR([Tcl requires shared libraries]) - fi - - SC_PATH_TCLCONFIG - SC_LOAD_TCLCONFIG - - INSTALL_LIBS="${INSTALL_LIBS} \$(libtso_target)" -]) diff --git a/storage/bdb/dist/aclocal/types.ac b/storage/bdb/dist/aclocal/types.ac deleted file mode 100644 index f9291386dc3..00000000000 --- a/storage/bdb/dist/aclocal/types.ac +++ /dev/null @@ -1,167 +0,0 @@ -# $Id: types.ac,v 12.3 2005/11/03 17:46:14 bostic Exp $ - -# Check the sizes we know about, and see if any of them match what's needed. -# -# Prefer ints to anything else, because read, write and others historically -# returned an int. -AC_DEFUN(AM_SEARCH_USIZES, [ - case "$3" in - "$ac_cv_sizeof_unsigned_int") - $1="typedef unsigned int $2;";; - "$ac_cv_sizeof_unsigned_char") - $1="typedef unsigned char $2;";; - "$ac_cv_sizeof_unsigned_short") - $1="typedef unsigned short $2;";; - "$ac_cv_sizeof_unsigned_long") - $1="typedef unsigned long $2;";; - "$ac_cv_sizeof_unsigned_long_long") - $1="typedef unsigned long long $2;";; - *) - if test "$4" != "notfatal"; then - AC_MSG_ERROR([No unsigned $3-byte integral type]) - fi;; - esac]) -AC_DEFUN(AM_SEARCH_SSIZES, [ - case "$3" in - "$ac_cv_sizeof_int") - $1="typedef int $2;";; - "$ac_cv_sizeof_char") - $1="typedef char $2;";; - "$ac_cv_sizeof_short") - $1="typedef short $2;";; - "$ac_cv_sizeof_long") - $1="typedef long $2;";; - "$ac_cv_sizeof_long_long") - $1="typedef long long $2;";; - *) - if test "$4" != "notfatal"; then - AC_MSG_ERROR([No signed $3-byte integral type]) - fi;; - esac]) - -# Check for the standard system types. -AC_DEFUN(AM_TYPES, [ - -# db.h includes <sys/types.h> and <stdio.h>, not the other default includes -# autoconf usually includes. For that reason, we specify a set of includes -# for all type checking tests. [#5060] -# -# C99 says types should be in <stdint.h>; include <stdint.h> if it exists. -# -# Some systems have types in <stddef.h>; include <stddef.h> if it exists. -# -# IBM's OS/390 and z/OS releases have types in <inttypes.h> not also found -# in <sys/types.h>; include <inttypes.h> if it exists. -db_includes="#include <sys/types.h>" -AC_SUBST(inttypes_h_decl) -AC_CHECK_HEADER(inttypes.h, [ - db_includes="$db_includes -#include <inttypes.h>" - inttypes_h_decl="#include <inttypes.h>"]) -AC_SUBST(stdint_h_decl) -AC_CHECK_HEADER(stdint.h, [ - db_includes="$db_includes -#include <stdint.h>" - stdint_h_decl="#include <stdint.h>"]) -AC_SUBST(stddef_h_decl) -AC_CHECK_HEADER(stddef.h, [ - db_includes="$db_includes -#include <stddef.h>" - stddef_h_decl="#include <stddef.h>"]) -AC_SUBST(unistd_h_decl) -AC_CHECK_HEADER(unistd.h, [ - db_includes="$db_includes -#include <unistd.h>" - unistd_h_decl="#include <unistd.h>"]) -db_includes="$db_includes -#include <stdio.h>" - -# We require off_t and size_t, and we don't try to substitute our own -# if we can't find them. -AC_CHECK_TYPE(off_t,, AC_MSG_ERROR([No off_t type.]), $db_includes) -AC_CHECK_TYPE(size_t,, AC_MSG_ERROR([No size_t type.]), $db_includes) - -# We need to know the sizes of various objects on this system. -AC_CHECK_SIZEOF(char,, $db_includes) -AC_CHECK_SIZEOF(unsigned char,, $db_includes) -AC_CHECK_SIZEOF(short,, $db_includes) -AC_CHECK_SIZEOF(unsigned short,, $db_includes) -AC_CHECK_SIZEOF(int,, $db_includes) -AC_CHECK_SIZEOF(unsigned int,, $db_includes) -AC_CHECK_SIZEOF(long,, $db_includes) -AC_CHECK_SIZEOF(unsigned long,, $db_includes) -AC_CHECK_SIZEOF(long long,, $db_includes) -AC_CHECK_SIZEOF(unsigned long long,, $db_includes) -AC_CHECK_SIZEOF(size_t,, $db_includes) -AC_CHECK_SIZEOF(char *,, $db_includes) - -# We look for u_char, u_short, u_int, u_long -- if we can't find them, -# we create our own. -AC_SUBST(u_char_decl) -AC_CHECK_TYPE(u_char,, - [u_char_decl="typedef unsigned char u_char;"], $db_includes) - -AC_SUBST(u_short_decl) -AC_CHECK_TYPE(u_short,, - [u_short_decl="typedef unsigned short u_short;"], $db_includes) - -AC_SUBST(u_int_decl) -AC_CHECK_TYPE(u_int,, - [u_int_decl="typedef unsigned int u_int;"], $db_includes) - -AC_SUBST(u_long_decl) -AC_CHECK_TYPE(u_long,, - [u_long_decl="typedef unsigned long u_long;"], $db_includes) - -# We look for fixed-size variants of u_char, u_short, u_int, u_long as well. -AC_SUBST(u_int8_decl) -AC_CHECK_TYPE(u_int8_t,, - [AM_SEARCH_USIZES(u_int8_decl, u_int8_t, 1)], $db_includes) - -AC_SUBST(u_int16_decl) -AC_CHECK_TYPE(u_int16_t,, - [AM_SEARCH_USIZES(u_int16_decl, u_int16_t, 2)], $db_includes) - -AC_SUBST(int16_decl) -AC_CHECK_TYPE(int16_t,, - [AM_SEARCH_SSIZES(int16_decl, int16_t, 2)], $db_includes) - -AC_SUBST(u_int32_decl) -AC_CHECK_TYPE(u_int32_t,, - [AM_SEARCH_USIZES(u_int32_decl, u_int32_t, 4)], $db_includes) - -AC_SUBST(int32_decl) -AC_CHECK_TYPE(int32_t,, - [AM_SEARCH_SSIZES(int32_decl, int32_t, 4)], $db_includes) - -AC_SUBST(u_int64_decl) -AC_CHECK_TYPE(u_int64_t,, - [AM_SEARCH_USIZES(u_int64_decl, u_int64_t, 8, notfatal)], $db_includes) - -AC_SUBST(int64_decl) -AC_CHECK_TYPE(int64_t,, - [AM_SEARCH_SSIZES(int64_decl, int64_t, 8, notfatal)], $db_includes) - -# Check for ssize_t -- if none exists, find a signed integral type that's -# the same size as a size_t. -AC_SUBST(ssize_t_decl) -AC_CHECK_TYPE(ssize_t,, - [AM_SEARCH_SSIZES(ssize_t_decl, ssize_t, $ac_cv_sizeof_size_t)], - $db_includes) - -# So far, no autoconf'd systems lack pid_t. -AC_SUBST(pid_t_decl) - -# Check for uintmax_t -- if none exists, first the largest unsigned integral -# type available. -AC_SUBST(uintmax_t_decl) -AC_CHECK_TYPE(uintmax_t,, [AC_CHECK_TYPE(unsigned long long, - [uintmax_t_decl="typedef unsigned long long uintmax_t;"], - [uintmax_t_decl="typedef unsigned long uintmax_t;"], $db_includes)]) - -# Check for uintptr_t -- if none exists, find an integral type which is -# the same size as a pointer. -AC_SUBST(uintptr_t_decl) -AC_CHECK_TYPE(uintptr_t,, - [AM_SEARCH_USIZES(uintptr_t_decl, uintptr_t, $ac_cv_sizeof_char_p)]) -]) diff --git a/storage/bdb/dist/aclocal_java/ac_check_class.ac b/storage/bdb/dist/aclocal_java/ac_check_class.ac deleted file mode 100644 index b12e7f02f9a..00000000000 --- a/storage/bdb/dist/aclocal_java/ac_check_class.ac +++ /dev/null @@ -1,107 +0,0 @@ -dnl @synopsis AC_CHECK_CLASS -dnl -dnl AC_CHECK_CLASS tests the existence of a given Java class, either in -dnl a jar or in a '.class' file. -dnl -dnl *Warning*: its success or failure can depend on a proper setting of the -dnl CLASSPATH env. variable. -dnl -dnl Note: This is part of the set of autoconf M4 macros for Java programs. -dnl It is VERY IMPORTANT that you download the whole set, some -dnl macros depend on other. Unfortunately, the autoconf archive does not -dnl support the concept of set of macros, so I had to break it for -dnl submission. -dnl The general documentation, as well as the sample configure.in, is -dnl included in the AC_PROG_JAVA macro. -dnl -dnl @author Stephane Bortzmeyer <bortzmeyer@pasteur.fr> -dnl @version $Id: ac_check_class.ac,v 12.0 2004/11/17 03:43:38 bostic Exp $ -dnl -AC_DEFUN([AC_CHECK_CLASS],[ -AC_REQUIRE([AC_PROG_JAVA]) -ac_var_name=`echo $1 | sed 's/\./_/g'` -dnl Normaly I'd use a AC_CACHE_CHECK here but since the variable name is -dnl dynamic I need an extra level of extraction -AC_MSG_CHECKING([for $1 class]) -AC_CACHE_VAL(ac_cv_class_$ac_var_name, [ -if test x$ac_cv_prog_uudecode_base64 = xyes; then -dnl /** -dnl * Test.java: used to test dynamicaly if a class exists. -dnl */ -dnl public class Test -dnl { -dnl -dnl public static void -dnl main( String[] argv ) -dnl { -dnl Class lib; -dnl if (argv.length < 1) -dnl { -dnl System.err.println ("Missing argument"); -dnl System.exit (77); -dnl } -dnl try -dnl { -dnl lib = Class.forName (argv[0]); -dnl } -dnl catch (ClassNotFoundException e) -dnl { -dnl System.exit (1); -dnl } -dnl lib = null; -dnl System.exit (0); -dnl } -dnl -dnl } -cat << \EOF > Test.uue -begin-base64 644 Test.class -yv66vgADAC0AKQcAAgEABFRlc3QHAAQBABBqYXZhL2xhbmcvT2JqZWN0AQAE -bWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYBAARDb2RlAQAPTGluZU51 -bWJlclRhYmxlDAAKAAsBAANlcnIBABVMamF2YS9pby9QcmludFN0cmVhbTsJ -AA0ACQcADgEAEGphdmEvbGFuZy9TeXN0ZW0IABABABBNaXNzaW5nIGFyZ3Vt -ZW50DAASABMBAAdwcmludGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWCgAV -ABEHABYBABNqYXZhL2lvL1ByaW50U3RyZWFtDAAYABkBAARleGl0AQAEKEkp -VgoADQAXDAAcAB0BAAdmb3JOYW1lAQAlKExqYXZhL2xhbmcvU3RyaW5nOylM -amF2YS9sYW5nL0NsYXNzOwoAHwAbBwAgAQAPamF2YS9sYW5nL0NsYXNzBwAi -AQAgamF2YS9sYW5nL0NsYXNzTm90Rm91bmRFeGNlcHRpb24BAAY8aW5pdD4B -AAMoKVYMACMAJAoAAwAlAQAKU291cmNlRmlsZQEACVRlc3QuamF2YQAhAAEA -AwAAAAAAAgAJAAUABgABAAcAAABtAAMAAwAAACkqvgSiABCyAAwSD7YAFBBN -uAAaKgMyuAAeTKcACE0EuAAaAUwDuAAasQABABMAGgAdACEAAQAIAAAAKgAK -AAAACgAAAAsABgANAA4ADgATABAAEwASAB4AFgAiABgAJAAZACgAGgABACMA -JAABAAcAAAAhAAEAAQAAAAUqtwAmsQAAAAEACAAAAAoAAgAAAAQABAAEAAEA -JwAAAAIAKA== -==== -EOF - if uudecode$EXEEXT Test.uue; then - : - else - echo "configure: __oline__: uudecode had trouble decoding base 64 file 'Test.uue'" >&AC_FD_CC - echo "configure: failed file was:" >&AC_FD_CC - cat Test.uue >&AC_FD_CC - ac_cv_prog_uudecode_base64=no - fi - rm -f Test.uue - if AC_TRY_COMMAND($JAVA $JAVAFLAGS Test $1) >/dev/null 2>&1; then - eval "ac_cv_class_$ac_var_name=yes" - else - eval "ac_cv_class_$ac_var_name=no" - fi - rm -f Test.class -else - AC_TRY_COMPILE_JAVA([$1], , [eval "ac_cv_class_$ac_var_name=yes"], - [eval "ac_cv_class_$ac_var_name=no"]) -fi -eval "ac_var_val=$`eval echo ac_cv_class_$ac_var_name`" -eval "HAVE_$ac_var_name=$`echo ac_cv_class_$ac_var_val`" -HAVE_LAST_CLASS=$ac_var_val -if test x$ac_var_val = xyes; then - ifelse([$2], , :, [$2]) -else - ifelse([$3], , :, [$3]) -fi -]) -dnl for some reason the above statment didn't fall though here? -dnl do scripts have variable scoping? -eval "ac_var_val=$`eval echo ac_cv_class_$ac_var_name`" -AC_MSG_RESULT($ac_var_val) -]) diff --git a/storage/bdb/dist/aclocal_java/ac_check_classpath.ac b/storage/bdb/dist/aclocal_java/ac_check_classpath.ac deleted file mode 100644 index b18d479b3f1..00000000000 --- a/storage/bdb/dist/aclocal_java/ac_check_classpath.ac +++ /dev/null @@ -1,23 +0,0 @@ -dnl @synopsis AC_CHECK_CLASSPATH -dnl -dnl AC_CHECK_CLASSPATH just displays the CLASSPATH, for the edification -dnl of the user. -dnl -dnl Note: This is part of the set of autoconf M4 macros for Java programs. -dnl It is VERY IMPORTANT that you download the whole set, some -dnl macros depend on other. Unfortunately, the autoconf archive does not -dnl support the concept of set of macros, so I had to break it for -dnl submission. -dnl The general documentation, as well as the sample configure.in, is -dnl included in the AC_PROG_JAVA macro. -dnl -dnl @author Stephane Bortzmeyer <bortzmeyer@pasteur.fr> -dnl @version $Id: ac_check_classpath.ac,v 12.0 2004/11/17 03:43:38 bostic Exp $ -dnl -AC_DEFUN([AC_CHECK_CLASSPATH],[ -if test "x$CLASSPATH" = x; then - echo "You have no CLASSPATH, I hope it is good" -else - echo "You have CLASSPATH $CLASSPATH, hope it is correct" -fi -]) diff --git a/storage/bdb/dist/aclocal_java/ac_check_junit.ac b/storage/bdb/dist/aclocal_java/ac_check_junit.ac deleted file mode 100644 index cc02e327662..00000000000 --- a/storage/bdb/dist/aclocal_java/ac_check_junit.ac +++ /dev/null @@ -1,54 +0,0 @@ -dnl @synopsis AC_CHECK_JUNIT -dnl -dnl AC_CHECK_JUNIT tests the availability of the Junit testing -dnl framework, and set some variables for conditional compilation -dnl of the test suite by automake. -dnl -dnl If available, JUNIT is set to a command launching the text -dnl based user interface of Junit, @JAVA_JUNIT@ is set to $JAVA_JUNIT -dnl and @TESTS_JUNIT@ is set to $TESTS_JUNIT, otherwise they are set -dnl to empty values. -dnl -dnl You can use these variables in your Makefile.am file like this : -dnl -dnl # Some of the following classes are built only if junit is available -dnl JAVA_JUNIT = Class1Test.java Class2Test.java AllJunitTests.java -dnl -dnl noinst_JAVA = Example1.java Example2.java @JAVA_JUNIT@ -dnl -dnl EXTRA_JAVA = $(JAVA_JUNIT) -dnl -dnl TESTS_JUNIT = AllJunitTests -dnl -dnl TESTS = StandaloneTest1 StandaloneTest2 @TESTS_JUNIT@ -dnl -dnl EXTRA_TESTS = $(TESTS_JUNIT) -dnl -dnl AllJunitTests : -dnl echo "#! /bin/sh" > $@ -dnl echo "exec @JUNIT@ my.package.name.AllJunitTests" >> $@ -dnl chmod +x $@ -dnl -dnl @author Luc Maisonobe -dnl @version $Id: ac_check_junit.ac,v 12.0 2004/11/17 03:43:38 bostic Exp $ -dnl -AC_DEFUN([AC_CHECK_JUNIT],[ -AC_CACHE_VAL(ac_cv_prog_JUNIT,[ -AC_CHECK_CLASS(junit.textui.TestRunner) -if test x"`eval 'echo $ac_cv_class_junit_textui_TestRunner'`" != xno ; then - ac_cv_prog_JUNIT='$(CLASSPATH_ENV) $(JAVA) $(JAVAFLAGS) junit.textui.TestRunner' -fi]) -AC_MSG_CHECKING([for junit]) -if test x"`eval 'echo $ac_cv_prog_JUNIT'`" != x ; then - JUNIT="$ac_cv_prog_JUNIT" - JAVA_JUNIT='$(JAVA_JUNIT)' - TESTS_JUNIT='$(TESTS_JUNIT)' -else - JUNIT= - JAVA_JUNIT= - TESTS_JUNIT= -fi -AC_MSG_RESULT($JAVA_JUNIT) -AC_SUBST(JUNIT) -AC_SUBST(JAVA_JUNIT) -AC_SUBST(TESTS_JUNIT)]) diff --git a/storage/bdb/dist/aclocal_java/ac_check_rqrd_class.ac b/storage/bdb/dist/aclocal_java/ac_check_rqrd_class.ac deleted file mode 100644 index c7c26b87741..00000000000 --- a/storage/bdb/dist/aclocal_java/ac_check_rqrd_class.ac +++ /dev/null @@ -1,26 +0,0 @@ -dnl @synopsis AC_CHECK_RQRD_CLASS -dnl -dnl AC_CHECK_RQRD_CLASS tests the existence of a given Java class, either in -dnl a jar or in a '.class' file and fails if it doesn't exist. -dnl Its success or failure can depend on a proper setting of the -dnl CLASSPATH env. variable. -dnl -dnl Note: This is part of the set of autoconf M4 macros for Java programs. -dnl It is VERY IMPORTANT that you download the whole set, some -dnl macros depend on other. Unfortunately, the autoconf archive does not -dnl support the concept of set of macros, so I had to break it for -dnl submission. -dnl The general documentation, as well as the sample configure.in, is -dnl included in the AC_PROG_JAVA macro. -dnl -dnl @author Stephane Bortzmeyer <bortzmeyer@pasteur.fr> -dnl @version $Id: ac_check_rqrd_class.ac,v 12.0 2004/11/17 03:43:38 bostic Exp $ -dnl - -AC_DEFUN([AC_CHECK_RQRD_CLASS],[ -CLASS=`echo $1|sed 's/\./_/g'` -AC_CHECK_CLASS($1) -if test "$HAVE_LAST_CLASS" = "no"; then - AC_MSG_ERROR([Required class $1 missing, exiting.]) -fi -]) diff --git a/storage/bdb/dist/aclocal_java/ac_java_options.ac b/storage/bdb/dist/aclocal_java/ac_java_options.ac deleted file mode 100644 index e71adfe68b5..00000000000 --- a/storage/bdb/dist/aclocal_java/ac_java_options.ac +++ /dev/null @@ -1,32 +0,0 @@ -dnl @synopsis AC_JAVA_OPTIONS -dnl -dnl AC_JAVA_OPTIONS adds configure command line options used for Java m4 -dnl macros. This Macro is optional. -dnl -dnl Note: This is part of the set of autoconf M4 macros for Java programs. -dnl It is VERY IMPORTANT that you download the whole set, some -dnl macros depend on other. Unfortunately, the autoconf archive does not -dnl support the concept of set of macros, so I had to break it for -dnl submission. -dnl The general documentation, as well as the sample configure.in, is -dnl included in the AC_PROG_JAVA macro. -dnl -dnl @author Devin Weaver <ktohg@tritarget.com> -dnl @version $Id: ac_java_options.ac,v 12.0 2004/11/17 03:43:38 bostic Exp $ -dnl -AC_DEFUN([AC_JAVA_OPTIONS],[ -AC_ARG_WITH(java-prefix, - [ --with-java-prefix=PFX prefix where Java runtime is installed (optional)]) -AC_ARG_WITH(javac-flags, - [ --with-javac-flags=FLAGS flags to pass to the Java compiler (optional)]) -AC_ARG_WITH(java-flags, - [ --with-java-flags=FLAGS flags to pass to the Java VM (optional)]) -JAVAPREFIX=$with_java_prefix -JAVACFLAGS=$with_javac_flags -JAVAFLAGS=$with_java_flags -AC_SUBST(JAVAPREFIX)dnl -AC_SUBST(JAVACFLAGS)dnl -AC_SUBST(JAVAFLAGS)dnl -AC_SUBST(JAVA)dnl -AC_SUBST(JAVAC)dnl -]) diff --git a/storage/bdb/dist/aclocal_java/ac_jni_include_dirs.ac b/storage/bdb/dist/aclocal_java/ac_jni_include_dirs.ac deleted file mode 100644 index 35cdda383c3..00000000000 --- a/storage/bdb/dist/aclocal_java/ac_jni_include_dirs.ac +++ /dev/null @@ -1,114 +0,0 @@ -dnl @synopsis AC_JNI_INCLUDE_DIR -dnl -dnl AC_JNI_INCLUDE_DIR finds include directories needed -dnl for compiling programs using the JNI interface. -dnl -dnl JNI include directories are usually in the java distribution -dnl This is deduced from the value of JAVAC. When this macro -dnl completes, a list of directories is left in the variable -dnl JNI_INCLUDE_DIRS. -dnl -dnl Example usage follows: -dnl -dnl AC_JNI_INCLUDE_DIR -dnl -dnl for JNI_INCLUDE_DIR in $JNI_INCLUDE_DIRS -dnl do -dnl CPPFLAGS="$CPPFLAGS -I$JNI_INCLUDE_DIR" -dnl done -dnl -dnl If you want to force a specific compiler: -dnl -dnl - at the configure.in level, set JAVAC=yourcompiler before calling -dnl AC_JNI_INCLUDE_DIR -dnl -dnl - at the configure level, setenv JAVAC -dnl -dnl Note: This macro can work with the autoconf M4 macros for Java programs. -dnl This particular macro is not part of the original set of macros. -dnl -dnl @author Don Anderson <dda@sleepycat.com> -dnl @version $Id: ac_jni_include_dirs.ac,v 12.0 2004/11/17 03:43:38 bostic Exp $ -dnl -AC_DEFUN(AC_JNI_INCLUDE_DIR,[ - -JNI_INCLUDE_DIRS="" - -test "x$JAVAC" = x && AC_MSG_ERROR(['$JAVAC' undefined]) -AC_PATH_PROG(_ACJNI_JAVAC, $JAVAC, $JAVAC) -test ! -x "$_ACJNI_JAVAC" && AC_MSG_ERROR([$JAVAC could not be found in path]) -AC_MSG_CHECKING(absolute path of $JAVAC) -case "$_ACJNI_JAVAC" in -/*) AC_MSG_RESULT($_ACJNI_JAVAC);; -*) AC_MSG_ERROR([$_ACJNI_JAVAC is not an absolute path name]);; -esac - -_ACJNI_FOLLOW_SYMLINKS("$_ACJNI_JAVAC") -_JTOPDIR=`echo "$_ACJNI_FOLLOWED" | sed -e 's://*:/:g' -e 's:/[[^/]]*$::'` -case "$host_os" in - darwin*) _JTOPDIR=`echo "$_JTOPDIR" | sed -e 's:/[[^/]]*$::'` - _JINC="$_JTOPDIR/Headers";; - *) _JINC="$_JTOPDIR/include";; -esac - -# If we find jni.h in /usr/include, then it's not a java-only tree, so -# don't add /usr/include or subdirectories to the list of includes. -# An extra -I/usr/include can foul things up with newer gcc's. -# -# If we don't find jni.h, just keep going. Hopefully javac knows where -# to find its include files, even if we can't. -if test -r "$_JINC/jni.h"; then - if test "$_JINC" != "/usr/include"; then - JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $_JINC" - fi -else - _JTOPDIR=`echo "$_JTOPDIR" | sed -e 's:/[[^/]]*$::'` - if test -r "$_JTOPDIR/include/jni.h"; then - if test "$_JTOPDIR" != "/usr"; then - JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $_JTOPDIR/include" - fi - fi -fi - -# get the likely subdirectories for system specific java includes -if test "$_JTOPDIR" != "/usr"; then - case "$host_os" in - aix*) _JNI_INC_SUBDIRS="aix";; - bsdi*) _JNI_INC_SUBDIRS="bsdos";; - freebsd*) _JNI_INC_SUBDIRS="freebsd";; - hp*) _JNI_INC_SUBDIRS="hp-ux";; - linux*) _JNI_INC_SUBDIRS="linux genunix";; - osf*) _JNI_INC_SUBDIRS="alpha";; - solaris*) _JNI_INC_SUBDIRS="solaris";; - *) _JNI_INC_SUBDIRS="genunix";; - esac -fi - -# add any subdirectories that are present -for _JINCSUBDIR in $_JNI_INC_SUBDIRS -do - if test -d "$_JTOPDIR/include/$_JINCSUBDIR"; then - JNI_INCLUDE_DIRS="$JNI_INCLUDE_DIRS $_JTOPDIR/include/$_JINCSUBDIR" - fi -done -]) - -# _ACJNI_FOLLOW_SYMLINKS <path> -# Follows symbolic links on <path>, -# finally setting variable _ACJNI_FOLLOWED -# -------------------- -AC_DEFUN(_ACJNI_FOLLOW_SYMLINKS,[ -# find the include directory relative to the javac executable -_cur="$1" -while ls -ld "$_cur" 2>/dev/null | grep " -> " >/dev/null; do - AC_MSG_CHECKING(symlink for $_cur) - _slink=`ls -ld "$_cur" | sed 's/.* -> //'` - case "$_slink" in - /*) _cur="$_slink";; - # 'X' avoids triggering unwanted echo options. - *) _cur=`echo "X$_cur" | sed -e 's/^X//' -e 's:[[^/]]*$::'`"$_slink";; - esac - AC_MSG_RESULT($_cur) -done -_ACJNI_FOLLOWED="$_cur" -])# _ACJNI diff --git a/storage/bdb/dist/aclocal_java/ac_prog_jar.ac b/storage/bdb/dist/aclocal_java/ac_prog_jar.ac deleted file mode 100644 index c60a79a859d..00000000000 --- a/storage/bdb/dist/aclocal_java/ac_prog_jar.ac +++ /dev/null @@ -1,36 +0,0 @@ -dnl @synopsis AC_PROG_JAR -dnl -dnl AC_PROG_JAR tests for an existing jar program. It uses the environment -dnl variable JAR then tests in sequence various common jar programs. -dnl -dnl If you want to force a specific compiler: -dnl -dnl - at the configure.in level, set JAR=yourcompiler before calling -dnl AC_PROG_JAR -dnl -dnl - at the configure level, setenv JAR -dnl -dnl You can use the JAR variable in your Makefile.in, with @JAR@. -dnl -dnl Note: This macro depends on the autoconf M4 macros for Java programs. -dnl It is VERY IMPORTANT that you download that whole set, some -dnl macros depend on other. Unfortunately, the autoconf archive does not -dnl support the concept of set of macros, so I had to break it for -dnl submission. -dnl -dnl The general documentation of those macros, as well as the sample -dnl configure.in, is included in the AC_PROG_JAVA macro. -dnl -dnl @author Egon Willighagen <egonw@sci.kun.nl> -dnl @version $Id: ac_prog_jar.ac,v 12.0 2004/11/17 03:43:38 bostic Exp $ -dnl -AC_DEFUN([AC_PROG_JAR],[ -AC_REQUIRE([AC_EXEEXT])dnl -if test "x$JAVAPREFIX" = x; then - test "x$JAR" = x && AC_CHECK_PROGS(JAR, jar$EXEEXT) -else - test "x$JAR" = x && AC_CHECK_PROGS(JAR, jar, $JAVAPREFIX) -fi -test "x$JAR" = x && AC_MSG_ERROR([no acceptable jar program found in \$PATH]) -AC_PROVIDE([$0])dnl -]) diff --git a/storage/bdb/dist/aclocal_java/ac_prog_java.ac b/storage/bdb/dist/aclocal_java/ac_prog_java.ac deleted file mode 100644 index a011b0a9f5a..00000000000 --- a/storage/bdb/dist/aclocal_java/ac_prog_java.ac +++ /dev/null @@ -1,79 +0,0 @@ -dnl @synopsis AC_PROG_JAVA -dnl -dnl Here is a summary of the main macros: -dnl -dnl AC_PROG_JAVAC: finds a Java compiler. -dnl -dnl AC_PROG_JAVA: finds a Java virtual machine. -dnl -dnl AC_CHECK_CLASS: finds if we have the given class (beware of CLASSPATH!). -dnl -dnl AC_CHECK_RQRD_CLASS: finds if we have the given class and stops otherwise. -dnl -dnl AC_TRY_COMPILE_JAVA: attempt to compile user given source. -dnl -dnl AC_TRY_RUN_JAVA: attempt to compile and run user given source. -dnl -dnl AC_JAVA_OPTIONS: adds Java configure options. -dnl -dnl AC_PROG_JAVA tests an existing Java virtual machine. It uses the -dnl environment variable JAVA then tests in sequence various common Java -dnl virtual machines. For political reasons, it starts with the free ones. -dnl You *must* call [AC_PROG_JAVAC] before. -dnl -dnl If you want to force a specific VM: -dnl -dnl - at the configure.in level, set JAVA=yourvm before calling AC_PROG_JAVA -dnl (but after AC_INIT) -dnl -dnl - at the configure level, setenv JAVA -dnl -dnl You can use the JAVA variable in your Makefile.in, with @JAVA@. -dnl -dnl *Warning*: its success or failure can depend on a proper setting of the -dnl CLASSPATH env. variable. -dnl -dnl TODO: allow to exclude virtual machines (rationale: most Java programs -dnl cannot run with some VM like kaffe). -dnl -dnl Note: This is part of the set of autoconf M4 macros for Java programs. -dnl It is VERY IMPORTANT that you download the whole set, some -dnl macros depend on other. Unfortunately, the autoconf archive does not -dnl support the concept of set of macros, so I had to break it for -dnl submission. -dnl -dnl A Web page, with a link to the latest CVS snapshot is at -dnl <http://www.internatif.org/bortzmeyer/autoconf-Java/>. -dnl -dnl This is a sample configure.in -dnl Process this file with autoconf to produce a configure script. -dnl -dnl AC_INIT(UnTag.java) -dnl -dnl dnl Checks for programs. -dnl AC_CHECK_CLASSPATH -dnl AC_PROG_JAVAC -dnl AC_PROG_JAVA -dnl -dnl dnl Checks for classes -dnl AC_CHECK_RQRD_CLASS(org.xml.sax.Parser) -dnl AC_CHECK_RQRD_CLASS(com.jclark.xml.sax.Driver) -dnl -dnl AC_OUTPUT(Makefile) -dnl -dnl @author Stephane Bortzmeyer <bortzmeyer@pasteur.fr> -dnl @version $Id: ac_prog_java.ac,v 12.0 2004/11/17 03:43:38 bostic Exp $ -dnl -dnl Note: Modified by dda@sleepycat.com to prefer java over kaffe. [#8059] -dnl -AC_DEFUN([AC_PROG_JAVA],[ -AC_REQUIRE([AC_EXEEXT])dnl -if test x$JAVAPREFIX = x; then - test x$JAVA = x && AC_CHECK_PROGS(JAVA, java$EXEEXT kaffe$EXEEXT) -else - test x$JAVA = x && AC_CHECK_PROGS(JAVA, java$EXEEXT kaffe$EXEEXT, $JAVAPREFIX) -fi -test x$JAVA = x && AC_MSG_ERROR([no acceptable Java virtual machine found in \$PATH]) -AC_PROG_JAVA_WORKS -AC_PROVIDE([$0])dnl -]) diff --git a/storage/bdb/dist/aclocal_java/ac_prog_java_works.ac b/storage/bdb/dist/aclocal_java/ac_prog_java_works.ac deleted file mode 100644 index f0ff8c57f2f..00000000000 --- a/storage/bdb/dist/aclocal_java/ac_prog_java_works.ac +++ /dev/null @@ -1,97 +0,0 @@ -dnl @synopsis AC_PROG_JAVA_WORKS -dnl -dnl Internal use ONLY. -dnl -dnl Note: This is part of the set of autoconf M4 macros for Java programs. -dnl It is VERY IMPORTANT that you download the whole set, some -dnl macros depend on other. Unfortunately, the autoconf archive does not -dnl support the concept of set of macros, so I had to break it for -dnl submission. -dnl The general documentation, as well as the sample configure.in, is -dnl included in the AC_PROG_JAVA macro. -dnl -dnl @author Stephane Bortzmeyer <bortzmeyer@pasteur.fr> -dnl @version $Id: ac_prog_java_works.ac,v 12.0 2004/11/17 03:43:38 bostic Exp $ -dnl -AC_DEFUN([AC_PROG_JAVA_WORKS], [ -AC_CHECK_PROG(uudecode, uudecode$EXEEXT, yes) -if test x$uudecode = xyes; then -AC_CACHE_CHECK([if uudecode can decode base 64 file], ac_cv_prog_uudecode_base64, [ -dnl /** -dnl * Test.java: used to test if java compiler works. -dnl */ -dnl public class Test -dnl { -dnl -dnl public static void -dnl main( String[] argv ) -dnl { -dnl System.exit (0); -dnl } -dnl -dnl } -cat << \EOF > Test.uue -begin-base64 644 Test.class -yv66vgADAC0AFQcAAgEABFRlc3QHAAQBABBqYXZhL2xhbmcvT2JqZWN0AQAE -bWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYBAARDb2RlAQAPTGluZU51 -bWJlclRhYmxlDAAKAAsBAARleGl0AQAEKEkpVgoADQAJBwAOAQAQamF2YS9s -YW5nL1N5c3RlbQEABjxpbml0PgEAAygpVgwADwAQCgADABEBAApTb3VyY2VG -aWxlAQAJVGVzdC5qYXZhACEAAQADAAAAAAACAAkABQAGAAEABwAAACEAAQAB -AAAABQO4AAyxAAAAAQAIAAAACgACAAAACgAEAAsAAQAPABAAAQAHAAAAIQAB -AAEAAAAFKrcAErEAAAABAAgAAAAKAAIAAAAEAAQABAABABMAAAACABQ= -==== -EOF -if uudecode$EXEEXT Test.uue; then - ac_cv_prog_uudecode_base64=yes -else - echo "configure: __oline__: uudecode had trouble decoding base 64 file 'Test.uue'" >&AC_FD_CC - echo "configure: failed file was:" >&AC_FD_CC - cat Test.uue >&AC_FD_CC - ac_cv_prog_uudecode_base64=no -fi -rm -f Test.uue]) -fi -if test x$ac_cv_prog_uudecode_base64 != xyes; then - rm -f Test.class - AC_MSG_WARN([I have to compile Test.class from scratch]) - if test x$ac_cv_prog_javac_works = xno; then - AC_MSG_ERROR([Cannot compile java source. $JAVAC does not work properly]) - fi - if test x$ac_cv_prog_javac_works = x; then - AC_PROG_JAVAC - fi -fi -AC_CACHE_CHECK(if $JAVA works, ac_cv_prog_java_works, [ -JAVA_TEST=Test.java -CLASS_TEST=Test.class -TEST=Test -changequote(, )dnl -cat << \EOF > $JAVA_TEST -/* [#]line __oline__ "configure" */ -public class Test { -public static void main (String args[]) { - System.exit (0); -} } -EOF -changequote([, ])dnl -if test x$ac_cv_prog_uudecode_base64 != xyes; then - if AC_TRY_COMMAND($JAVAC $JAVACFLAGS $JAVA_TEST) && test -s $CLASS_TEST; then - : - else - echo "configure: failed program was:" >&AC_FD_CC - cat $JAVA_TEST >&AC_FD_CC - AC_MSG_ERROR(The Java compiler $JAVAC failed (see config.log, check the CLASSPATH?)) - fi -fi -if AC_TRY_COMMAND($JAVA $JAVAFLAGS $TEST) >/dev/null 2>&1; then - ac_cv_prog_java_works=yes -else - echo "configure: failed program was:" >&AC_FD_CC - cat $JAVA_TEST >&AC_FD_CC - AC_MSG_ERROR(The Java VM $JAVA failed (see config.log, check the CLASSPATH?)) -fi -rm -fr $JAVA_TEST $CLASS_TEST Test.uue -]) -AC_PROVIDE([$0])dnl -] -) diff --git a/storage/bdb/dist/aclocal_java/ac_prog_javac.ac b/storage/bdb/dist/aclocal_java/ac_prog_javac.ac deleted file mode 100644 index b3607dcf842..00000000000 --- a/storage/bdb/dist/aclocal_java/ac_prog_javac.ac +++ /dev/null @@ -1,43 +0,0 @@ -dnl @synopsis AC_PROG_JAVAC -dnl -dnl AC_PROG_JAVAC tests an existing Java compiler. It uses the environment -dnl variable JAVAC then tests in sequence various common Java compilers. For -dnl political reasons, it starts with the free ones. -dnl -dnl If you want to force a specific compiler: -dnl -dnl - at the configure.in level, set JAVAC=yourcompiler before calling -dnl AC_PROG_JAVAC -dnl -dnl - at the configure level, setenv JAVAC -dnl -dnl You can use the JAVAC variable in your Makefile.in, with @JAVAC@. -dnl -dnl *Warning*: its success or failure can depend on a proper setting of the -dnl CLASSPATH env. variable. -dnl -dnl TODO: allow to exclude compilers (rationale: most Java programs cannot compile -dnl with some compilers like guavac). -dnl -dnl Note: This is part of the set of autoconf M4 macros for Java programs. -dnl It is VERY IMPORTANT that you download the whole set, some -dnl macros depend on other. Unfortunately, the autoconf archive does not -dnl support the concept of set of macros, so I had to break it for -dnl submission. -dnl The general documentation, as well as the sample configure.in, is -dnl included in the AC_PROG_JAVA macro. -dnl -dnl @author Stephane Bortzmeyer <bortzmeyer@pasteur.fr> -dnl @version $Id: ac_prog_javac.ac,v 12.0 2004/11/17 03:43:38 bostic Exp $ -dnl -AC_DEFUN([AC_PROG_JAVAC],[ -AC_REQUIRE([AC_EXEEXT])dnl -if test "x$JAVAPREFIX" = x; then - test "x$JAVAC" = x && AC_CHECK_PROGS(JAVAC, javac$EXEEXT "gcj$EXEEXT -C" guavac$EXEEXT jikes$EXEEXT) -else - test "x$JAVAC" = x && AC_CHECK_PROGS(JAVAC, javac$EXEEXT "gcj$EXEEXT -C" guavac$EXEEXT jikes$EXEEXT, $JAVAPREFIX) -fi -test "x$JAVAC" = x && AC_MSG_ERROR([no acceptable Java compiler found in \$PATH]) -AC_PROG_JAVAC_WORKS -AC_PROVIDE([$0])dnl -]) diff --git a/storage/bdb/dist/aclocal_java/ac_prog_javac_works.ac b/storage/bdb/dist/aclocal_java/ac_prog_javac_works.ac deleted file mode 100644 index 0cfd1f2137f..00000000000 --- a/storage/bdb/dist/aclocal_java/ac_prog_javac_works.ac +++ /dev/null @@ -1,35 +0,0 @@ -dnl @synopsis AC_PROG_JAVAC_WORKS -dnl -dnl Internal use ONLY. -dnl -dnl Note: This is part of the set of autoconf M4 macros for Java programs. -dnl It is VERY IMPORTANT that you download the whole set, some -dnl macros depend on other. Unfortunately, the autoconf archive does not -dnl support the concept of set of macros, so I had to break it for -dnl submission. -dnl The general documentation, as well as the sample configure.in, is -dnl included in the AC_PROG_JAVA macro. -dnl -dnl @author Stephane Bortzmeyer <bortzmeyer@pasteur.fr> -dnl @version $Id: ac_prog_javac_works.ac,v 12.0 2004/11/17 03:43:38 bostic Exp $ -dnl -AC_DEFUN([AC_PROG_JAVAC_WORKS],[ -AC_CACHE_CHECK([if $JAVAC works], ac_cv_prog_javac_works, [ -JAVA_TEST=Test.java -CLASS_TEST=Test.class -cat << \EOF > $JAVA_TEST -/* [#]line __oline__ "configure" */ -public class Test { -} -EOF -if AC_TRY_COMMAND($JAVAC $JAVACFLAGS $JAVA_TEST) >/dev/null 2>&1; then - ac_cv_prog_javac_works=yes -else - AC_MSG_ERROR([The Java compiler $JAVAC failed (see config.log, check the CLASSPATH?)]) - echo "configure: failed program was:" >&AC_FD_CC - cat $JAVA_TEST >&AC_FD_CC -fi -rm -f $JAVA_TEST $CLASS_TEST -]) -AC_PROVIDE([$0])dnl -]) diff --git a/storage/bdb/dist/aclocal_java/ac_prog_javadoc.ac b/storage/bdb/dist/aclocal_java/ac_prog_javadoc.ac deleted file mode 100644 index 36b95bd00a3..00000000000 --- a/storage/bdb/dist/aclocal_java/ac_prog_javadoc.ac +++ /dev/null @@ -1,37 +0,0 @@ -dnl @synopsis AC_PROG_JAVADOC -dnl -dnl AC_PROG_JAVADOC tests for an existing javadoc generator. It uses the environment -dnl variable JAVADOC then tests in sequence various common javadoc generator. -dnl -dnl If you want to force a specific compiler: -dnl -dnl - at the configure.in level, set JAVADOC=yourgenerator before calling -dnl AC_PROG_JAVADOC -dnl -dnl - at the configure level, setenv JAVADOC -dnl -dnl You can use the JAVADOC variable in your Makefile.in, with @JAVADOC@. -dnl -dnl Note: This macro depends on the autoconf M4 macros for Java programs. -dnl It is VERY IMPORTANT that you download that whole set, some -dnl macros depend on other. Unfortunately, the autoconf archive does not -dnl support the concept of set of macros, so I had to break it for -dnl submission. -dnl -dnl The general documentation of those macros, as well as the sample -dnl configure.in, is included in the AC_PROG_JAVA macro. -dnl -dnl @author Egon Willighagen <egonw@sci.kun.nl> -dnl @version $Id: ac_prog_javadoc.ac,v 12.0 2004/11/17 03:43:38 bostic Exp $ -dnl -AC_DEFUN([AC_PROG_JAVADOC],[ -AC_REQUIRE([AC_EXEEXT])dnl -if test "x$JAVAPREFIX" = x; then - test "x$JAVADOC" = x && AC_CHECK_PROGS(JAVADOC, javadoc$EXEEXT) -else - test "x$JAVADOC" = x && AC_CHECK_PROGS(JAVADOC, javadoc, $JAVAPREFIX) -fi -test "x$JAVADOC" = x && AC_MSG_ERROR([no acceptable javadoc generator found in \$PATH]) -AC_PROVIDE([$0])dnl -]) - diff --git a/storage/bdb/dist/aclocal_java/ac_prog_javah.ac b/storage/bdb/dist/aclocal_java/ac_prog_javah.ac deleted file mode 100644 index 7563036c091..00000000000 --- a/storage/bdb/dist/aclocal_java/ac_prog_javah.ac +++ /dev/null @@ -1,26 +0,0 @@ -dnl @synopsis AC_PROG_JAVAH -dnl -dnl AC_PROG_JAVAH tests the availability of the javah header generator -dnl and looks for the jni.h header file. If available, JAVAH is set to -dnl the full path of javah and CPPFLAGS is updated accordingly. -dnl -dnl @author Luc Maisonobe -dnl @version $Id: ac_prog_javah.ac,v 12.0 2004/11/17 03:43:38 bostic Exp $ -dnl -AC_DEFUN([AC_PROG_JAVAH],[ -AC_REQUIRE([AC_CANONICAL_SYSTEM])dnl -AC_REQUIRE([AC_PROG_CPP])dnl -AC_PATH_PROG(JAVAH,javah) -if test x"`eval 'echo $ac_cv_path_JAVAH'`" != x ; then - AC_TRY_CPP([#include <jni.h>],,[ - ac_save_CPPFLAGS="$CPPFLAGS" -changequote(, )dnl - ac_dir=`echo $ac_cv_path_JAVAH | sed 's,\(.*\)/[^/]*/[^/]*$,\1/include,'` - ac_machdep=`echo $build_os | sed 's,[-0-9].*,,'` -changequote([, ])dnl - CPPFLAGS="$ac_save_CPPFLAGS -I$ac_dir -I$ac_dir/$ac_machdep" - AC_TRY_CPP([#include <jni.h>], - ac_save_CPPFLAGS="$CPPFLAGS", - AC_MSG_WARN([unable to include <jni.h>])) - CPPFLAGS="$ac_save_CPPFLAGS"]) -fi]) diff --git a/storage/bdb/dist/aclocal_java/ac_try_compile_java.ac b/storage/bdb/dist/aclocal_java/ac_try_compile_java.ac deleted file mode 100644 index d22aeab42f1..00000000000 --- a/storage/bdb/dist/aclocal_java/ac_try_compile_java.ac +++ /dev/null @@ -1,39 +0,0 @@ -dnl @synopsis AC_TRY_COMPILE_JAVA -dnl -dnl AC_TRY_COMPILE_JAVA attempt to compile user given source. -dnl -dnl *Warning*: its success or failure can depend on a proper setting of the -dnl CLASSPATH env. variable. -dnl -dnl Note: This is part of the set of autoconf M4 macros for Java programs. -dnl It is VERY IMPORTANT that you download the whole set, some -dnl macros depend on other. Unfortunately, the autoconf archive does not -dnl support the concept of set of macros, so I had to break it for -dnl submission. -dnl The general documentation, as well as the sample configure.in, is -dnl included in the AC_PROG_JAVA macro. -dnl -dnl @author Devin Weaver <ktohg@tritarget.com> -dnl @version $Id: ac_try_compile_java.ac,v 12.0 2004/11/17 03:43:38 bostic Exp $ -dnl -AC_DEFUN([AC_TRY_COMPILE_JAVA],[ -AC_REQUIRE([AC_PROG_JAVAC])dnl -cat << \EOF > Test.java -/* [#]line __oline__ "configure" */ -ifelse([$1], , , [import $1;]) -public class Test { -[$2] -} -EOF -if AC_TRY_COMMAND($JAVAC $JAVACFLAGS Test.java) && test -s Test.class -then -dnl Don't remove the temporary files here, so they can be examined. - ifelse([$3], , :, [$3]) -else - echo "configure: failed program was:" >&AC_FD_CC - cat Test.java >&AC_FD_CC -ifelse([$4], , , [ rm -fr Test* - $4 -])dnl -fi -rm -fr Test*]) diff --git a/storage/bdb/dist/aclocal_java/ac_try_run_javac.ac b/storage/bdb/dist/aclocal_java/ac_try_run_javac.ac deleted file mode 100644 index 01249358883..00000000000 --- a/storage/bdb/dist/aclocal_java/ac_try_run_javac.ac +++ /dev/null @@ -1,40 +0,0 @@ -dnl @synopsis AC_TRY_RUN_JAVA -dnl -dnl AC_TRY_RUN_JAVA attempt to compile and run user given source. -dnl -dnl *Warning*: its success or failure can depend on a proper setting of the -dnl CLASSPATH env. variable. -dnl -dnl Note: This is part of the set of autoconf M4 macros for Java programs. -dnl It is VERY IMPORTANT that you download the whole set, some -dnl macros depend on other. Unfortunately, the autoconf archive does not -dnl support the concept of set of macros, so I had to break it for -dnl submission. -dnl The general documentation, as well as the sample configure.in, is -dnl included in the AC_PROG_JAVA macro. -dnl -dnl @author Devin Weaver <ktohg@tritarget.com> -dnl @version $Id: ac_try_run_javac.ac,v 12.0 2004/11/17 03:43:38 bostic Exp $ -dnl -AC_DEFUN([AC_TRY_RUN_JAVA],[ -AC_REQUIRE([AC_PROG_JAVAC])dnl -AC_REQUIRE([AC_PROG_JAVA])dnl -cat << \EOF > Test.java -/* [#]line __oline__ "configure" */ -ifelse([$1], , , [include $1;]) -public class Test { -[$2] -} -EOF -if AC_TRY_COMMAND($JAVAC $JAVACFLAGS Test.java) && test -s Test.class && ($JAVA $JAVAFLAGS Test; exit) 2>/dev/null -then -dnl Don't remove the temporary files here, so they can be examined. - ifelse([$3], , :, [$3]) -else - echo "configure: failed program was:" >&AC_FD_CC - cat Test.java >&AC_FD_CC -ifelse([$4], , , [ rm -fr Test* - $4 -])dnl -fi -rm -fr Test*]) diff --git a/storage/bdb/dist/buildrel b/storage/bdb/dist/buildrel deleted file mode 100644 index 3d4121f902a..00000000000 --- a/storage/bdb/dist/buildrel +++ /dev/null @@ -1,128 +0,0 @@ -# $Id: buildrel,v 12.1 2005/10/25 00:27:35 bostic Exp $ -# -# Build the distribution package. -# -# A set of commands intended to be cut and pasted into a csh window. - -# Development tree, release home. -setenv D `pwd` - -# Update the release number. -cd $D/dist -cvs -q update RELEASE -vi RELEASE -setenv VERSION `sh -c '. RELEASE; echo $DB_VERSION'` -echo "Version: $VERSION" - -# Make sure the source tree is up-to-date -cd $D && cvs -q update - -# Build auto-generated files. -cd $D/dist && sh s_all - -# Commit all of the changes. -cd $D && cvs -q commit - -# Copy a development tree into a release tree. -setenv R /var/tmp/db-$VERSION -rm -rf $R && mkdir -p $R -cd $D && cvs -q status | \ - grep "Repository revision" | \ - sed -e 's;.*CVSROOT/db/;;' \ - -e 's;.*CVSROOT/;;' \ - -e 's;,v$;;' | pax -rw $R/ - -# Build the documentation, copy it into place. -cd db_docs && cvs -q update -cd db_docs && sh build $D clean && sh build $D |& sed '/.html$/d' -cd je/docs_src && sh build db ../../db -rm -rf $R/docs && cp -r $D/docs $R/docs - -# Remove source directories we don't distribute. -cd $R && rm -rf docs_src docs/api_java -cd $R && rm -rf test/TODO test/upgrade test_perf test_purify -cd $R && rm -rf test_rep test_server test_thread test_vxworks test_xa -cd $R && rm -rf java/src/com/sleepycat/xa - -# Fix symbolic links and permissions. -cd $R/dist && sh s_perm -cd $R/dist && sh s_symlink - -# Build a version and smoke test. -cd $R && rm -rf build_run && mkdir build_run -cd $R/build_run && ~bostic/bin/dbconf && make >& mklog -cd $R/build_run && make ex_access && ./ex_access - -# Check the install -cd $R/build_run && make prefix=`pwd`/BDB install - -# Build a small-footprint version and smoke test. -cd $R && rm -rf build_run && mkdir build_run -cd $R/build_run && ../dist/configure --enable-smallbuild && make >& mklog -cd $R/build_run && make ex_access && ./ex_access - -# Remove the build directory -cd $R && rm -rf build_run - -# ACQUIRE ROOT PRIVILEGES -cd $R && find . -type d | xargs chmod 775 -cd $R && find . -type f | xargs chmod 444 -cd $R && chmod 664 build_win32/*.dsp -cd $R/dist && sh s_perm -chown -R 100 $R -chgrp -R 100 $R -# DISCARD ROOT PRIVILEGES - -# Check for file names differing only in case. -cd $R && find . | sort -f | uniq -ic | sed '/1 /d' - -# Create the crypto tar archive release. -setenv T "$R/../db-$VERSION.tar.gz" -cd $R/.. && tar cf - db-$VERSION | gzip --best > $T -chmod 444 $T - -# Check the path length. -gzcat $T | tar tf - |\ -awk '{ if (length() > 99) print "Path length: " length() " bytes: " $0;}' - -# Create the non-crypto tree. -setenv RNC "$R/../db-$VERSION.NC" -rm -rf $RNC $R/../__TMP && mkdir $R/../__TMP -cd $R/../__TMP && gzcat $T | tar xpf - && mv -i db-$VERSION $RNC -cd $R && rm -rf $R/../__TMP -cd $RNC/dist && sh s_crypto - -# ACQUIRE ROOT PRIVILEGES -cd $RNC && find . -type d | xargs chmod 775 -cd $RNC && find . -type f | xargs chmod 444 -cd $RNC && chmod 664 build_win32/*.dsp -cd $RNC/dist && sh s_perm -chown -R 100 $RNC -chgrp -R 100 $RNC -# DISCARD ROOT PRIVILEGES - -# Create the non-crypto tar archive release. -setenv T "$R/../db-$VERSION.NC.tar.gz" -cd $RNC/.. && tar cf - db-$VERSION.NC | gzip --best > $T -chmod 444 $T - -# Check the path length. -gzcat $T | tar tf - |\ -awk '{ if (length() > 99) print "Path length: " length() " bytes: " $0;}' - -# Remove tags files. They're large and we don't want to store symbolic links -# in the zip archive for portability reasons. -# ACQUIRE ROOT PRIVILEGES -cd $R && rm -f `find . -name 'tags'` -cd $RNC && rm -f `find . -name 'tags'` -# DISCARD ROOT PRIVILEGES - -# Create the crypto zip archive release. -setenv T "$R/../db-$VERSION.zip" -cd $R/.. && zip -r - db-$VERSION > $T -chmod 444 $T - -# Create the non-crypto zip archive release. -setenv T "$R/../db-$VERSION.NC.zip" -cd $RNC/.. && zip -r - db-$VERSION.NC > $T -chmod 444 $T diff --git a/storage/bdb/dist/config.guess b/storage/bdb/dist/config.guess deleted file mode 100755 index d0d57f6945f..00000000000 --- a/storage/bdb/dist/config.guess +++ /dev/null @@ -1,1465 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. - -timestamp='2005-09-19' - -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Originally written by Per Bothner <per@bothner.com>. -# Please send patches to <config-patches@gnu.org>. Submit a context -# diff and a properly formatted ChangeLog entry. -# -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. -# -# The plan is that this can be called by configure scripts if you -# don't specify an explicit build system type. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system \`$me' is run on. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to <config-patches@gnu.org>." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - -trap 'exit 1' 1 2 15 - -# CC_FOR_BUILD -- compiler used by this script. Note that the use of a -# compiler to aid in system detection is discouraged as it requires -# temporary files to be created and, as you can see below, it is a -# headache to deal with in a portable fashion. - -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. - -# Portable tmp directory creation inspired by the Autoconf team. - -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; - for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; set_cc_for_build= ;' - -# This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -# Note: order is significant - the case branches are not exclusive. - -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - *:NetBSD:*:*) - # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # Note: NetBSD doesn't particularly care about the vendor - # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in - armeb) machine=armeb-unknown ;; - arm*) machine=arm-unknown ;; - sh3el) machine=shl-unknown ;; - sh3eb) machine=sh-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep __ELF__ >/dev/null - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - # Debian GNU/NetBSD machines have a different userland, and - # thus, need a distinct triplet. However, they do not need - # kernel version information, so it can be replaced with a - # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in - Debian*) - release='-gnu' - ;; - *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - ;; - esac - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit ;; - *:OpenBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} - exit ;; - *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} - exit ;; - macppc:MirBSD:*:*) - echo powerppc-unknown-mirbsd${UNAME_RELEASE} - exit ;; - *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} - exit ;; - alpha:OSF1:*:*) - case $UNAME_RELEASE in - *4.0) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - ;; - *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` - ;; - esac - # According to Compaq, /usr/sbin/psrinfo has been available on - # OSF/1 and Tru64 systems produced since 1995. I hope that - # covers most systems running today. This code pipes the CPU - # types through head -n 1, so we only detect the type of CPU 0. - ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` - case "$ALPHA_CPU_TYPE" in - "EV4 (21064)") - UNAME_MACHINE="alpha" ;; - "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; - "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; - "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; - "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; - "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; - "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; - "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; - "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; - "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; - "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; - "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; - "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; - esac - # A Pn.n version is a patched version. - # A Vn.n version is a released version. - # A Tn.n version is a released field test version. - # A Xn.n version is an unreleased experimental baselevel. - # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - exit ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit ;; - Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit ;; - *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos - exit ;; - *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos - exit ;; - *:OS/390:*:*) - echo i370-ibm-openedition - exit ;; - *:z/VM:*:*) - echo s390-ibm-zvmoe - exit ;; - *:OS400:*:*) - echo powerpc-ibm-os400 - exit ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit ;; - arm:riscos:*:*|arm:RISCOS:*:*) - echo arm-unknown-riscos - exit ;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit ;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit ;; - NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit ;; - DRS?6000:unix:4.0:6*) - echo sparc-icl-nx6 - exit ;; - DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) - case `/usr/bin/uname -p` in - sparc) echo sparc-icl-nx7; exit ;; - esac ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - i86pc:SunOS:5.*:*) - echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit ;; - m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} - exit ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include <stdio.h> /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); - #endif - #endif - exit (-1); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && - dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`$dummy $dummyarg` && - { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} - exit ;; - Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit ;; - Motorola:*:4.3:PL8-*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit ;; - m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit ;; - m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit ;; - m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] - then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] - then - echo m88k-dg-dgux${UNAME_RELEASE} - else - echo m88k-dg-dguxbcs${UNAME_RELEASE} - fi - else - echo i586-dg-dgux${UNAME_RELEASE} - fi - exit ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit ;; - *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit ;; - ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i*86:AIX:*:*) - echo i386-ibm-aix - exit ;; - ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit ;; - *:AIX:2:3) - if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include <sys/systemcfg.h> - - main() - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` - then - echo "$SYSTEM_NAME" - else - echo rs6000-ibm-aix3.2.5 - fi - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 - else - echo rs6000-ibm-aix3.2 - fi - exit ;; - *:AIX:*:[45]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit ;; - *:AIX:*:*) - echo rs6000-ibm-aix - exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) - echo romp-ibm-bsd4.4 - exit ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - echo rs6000-bull-bosx - exit ;; - DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit ;; - 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit ;; - 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; - 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac - fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - - #define _HPUX_SOURCE - #include <stdlib.h> - #include <unistd.h> - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` - test -z "$HP_ARCH" && HP_ARCH=hppa - fi ;; - esac - if [ ${HP_ARCH} = "hppa2.0w" ] - then - eval $set_cc_for_build - - # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating - # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler - # generating 64-bit code. GNU and HP use different nomenclature: - # - # $ CC_FOR_BUILD=cc ./config.guess - # => hppa2.0w-hp-hpux11.23 - # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess - # => hppa64-hp-hpux11.23 - - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | - grep __LP64__ >/dev/null - then - HP_ARCH="hppa2.0w" - else - HP_ARCH="hppa64" - fi - fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit ;; - 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include <unistd.h> - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - echo unknown-hitachi-hiuxwe2 - exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) - echo hppa1.1-hp-bsd - exit ;; - 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit ;; - *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) - echo hppa1.1-hp-osf - exit ;; - hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit ;; - i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk - else - echo ${UNAME_MACHINE}-unknown-osf1 - fi - exit ;; - parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit ;; - CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ - | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ - -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ - -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit ;; - sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:FreeBSD:*:*) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit ;; - i*:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 - exit ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit ;; - x86:Interix*:[34]*) - echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' - exit ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; - i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit ;; - amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin - exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - *:GNU:*:*) - # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit ;; - *:GNU/*:*:*) - # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu - exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit ;; - arm*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - cris:Linux:*:*) - echo cris-axis-linux-gnu - exit ;; - crisv32:Linux:*:*) - echo crisv32-axis-linux-gnu - exit ;; - frv:Linux:*:*) - echo frv-unknown-linux-gnu - exit ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - mips:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips - #undef mipsel - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mipsel - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips64 - #undef mips64el - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mips64el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips64 - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - or32:Linux:*:*) - echo or32-unknown-linux-gnu - exit ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; - esac - exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - exit ;; - s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux - exit ;; - sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu - exit ;; - i*86:Linux:*:*) - # The BFD linker knows what the default object file format is, so - # first see if it will tell us. cd to the root directory to prevent - # problems with other programs or directories called `ld' in the path. - # Set LC_ALL=C to ensure ld outputs messages in English. - ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ - | sed -ne '/supported targets:/!d - s/[ ][ ]*/ /g - s/.*supported targets: *// - s/ .*// - p'` - case "$ld_supported_targets" in - elf32-i386) - TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" - ;; - a.out-i386-linux) - echo "${UNAME_MACHINE}-pc-linux-gnuaout" - exit ;; - coff-i386) - echo "${UNAME_MACHINE}-pc-linux-gnucoff" - exit ;; - "") - # Either a pre-BFD a.out linker (linux-gnuoldld) or - # one that does not give us useful --help. - echo "${UNAME_MACHINE}-pc-linux-gnuoldld" - exit ;; - esac - # Determine whether the default compiler is a.out or elf - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include <features.h> - #ifdef __ELF__ - # ifdef __GLIBC__ - # if __GLIBC__ >= 2 - LIBC=gnu - # else - LIBC=gnulibc1 - # endif - # else - LIBC=gnulibc1 - # endif - #else - #ifdef __INTEL_COMPILER - LIBC=gnu - #else - LIBC=gnuaout - #endif - #endif - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` - test x"${LIBC}" != x && { - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" - exit - } - test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } - ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit ;; - i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit ;; - i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable - exit ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit ;; - i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` - echo ${UNAME_MACHINE}-pc-isc$UNAME_REL - elif /bin/uname -X 2>/dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` - (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL - else - echo ${UNAME_MACHINE}-pc-sysv32 - fi - exit ;; - pc:*:*:*) - # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i386. - echo i386-pc-msdosdjgpp - exit ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit ;; - mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit ;; - M680?0:D-NIX:5.3:*) - echo m68k-diab-dnix - exit ;; - M68*:*:R3V[5678]*:*) - test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; - 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says <Richard.M.Bartel@ccMail.Census.GOV> - echo i586-unisys-sysv4 - exit ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes <hewes@openmarket.com>. - # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit ;; - *:*:*:FTX*) - # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit ;; - i*86:VOS:*:*) - # From Paul.Green@stratus.com. - echo ${UNAME_MACHINE}-stratus-vos - exit ;; - *:VOS:*:*) - # From Paul.Green@stratus.com. - echo hppa1.1-stratus-vos - exit ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} - else - echo mips-unknown-sysv${UNAME_RELEASE} - fi - exit ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit ;; - SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} - exit ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - case $UNAME_PROCESSOR in - unknown) UNAME_PROCESSOR=powerpc ;; - esac - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} - exit ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then - UNAME_PROCESSOR=i386 - UNAME_MACHINE=pc - fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} - exit ;; - *:QNX:*:4*) - echo i386-pc-qnx - exit ;; - NSE-?:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} - exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit ;; - SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} - exit ;; - *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; - *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in - A*) echo alpha-dec-vms ; exit ;; - I*) echo ia64-dec-vms ; exit ;; - V*) echo vax-dec-vms ; exit ;; - esac ;; - *:XENIX:*:SysV) - echo i386-pc-xenix - exit ;; - i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' - exit ;; -esac - -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - -eval $set_cc_for_build -cat >$dummy.c <<EOF -#ifdef _SEQUENT_ -# include <sys/types.h> -# include <sys/utsname.h> -#endif -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include <sys/param.h> - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix\n"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); - -#endif - -#if defined (vax) -# if !defined (ultrix) -# include <sys/param.h> -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - -# Apollos put the system type in the environment. - -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } - -# Convex versions that predate uname can use getsysinfo(1) - -if [ -x /usr/convex/getsysinfo ] -then - case `getsysinfo -f cpu_type` in - c1*) - echo c1-convex-bsd - exit ;; - c2*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - c34*) - echo c34-convex-bsd - exit ;; - c38*) - echo c38-convex-bsd - exit ;; - c4*) - echo c4-convex-bsd - exit ;; - esac -fi - -cat >&2 <<EOF -$0: unable to guess system type - -This script, last modified $timestamp, has failed to recognize -the operating system you are using. It is advised that you -download the most up to date version of the config scripts from - - http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess -and - http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub - -If the version you run ($0) is already up to date, please -send the following data and any information you think might be -pertinent to <config-patches@gnu.org> in order to provide the needed -information to handle your system. - -config.guess timestamp = $timestamp - -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` - -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} -EOF - -exit 1 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/storage/bdb/dist/config.sub b/storage/bdb/dist/config.sub deleted file mode 100755 index 1c366dfde9a..00000000000 --- a/storage/bdb/dist/config.sub +++ /dev/null @@ -1,1579 +0,0 @@ -#! /bin/sh -# Configuration validation subroutine script. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. - -timestamp='2005-07-08' - -# This file is (in principle) common to ALL GNU software. -# The presence of a machine in this file suggests that SOME GNU software -# can handle that machine. It does not imply ALL GNU software can. -# -# This file is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Please send patches to <config-patches@gnu.org>. Submit a context -# diff and a properly formatted ChangeLog entry. -# -# Configuration subroutine to validate and canonicalize a configuration type. -# Supply the specified configuration type as an argument. -# If it is invalid, we print an error message on stderr and exit with code 1. -# Otherwise, we print the canonical config type on stdout and succeed. - -# This file is supposed to be the same for all GNU packages -# and recognize all the CPU types, system types and aliases -# that are meaningful with *any* GNU software. -# Each package is responsible for reporting which valid configurations -# it does not support. The user should be able to distinguish -# a failure to support a valid configuration from a meaningless -# configuration. - -# The goal of this file is to map all the various variations of a given -# machine specification into a single specification in the form: -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or in some cases, the newer four-part form: -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# It is wrong to echo any other type of specification. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS - -Canonicalize a configuration name. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to <config-patches@gnu.org>." - -version="\ -GNU config.sub ($timestamp) - -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" - exit 1 ;; - - *local*) - # First pass through any local machine types. - echo $1 - exit ;; - - * ) - break ;; - esac -done - -case $# in - 0) echo "$me: missing argument$help" >&2 - exit 1;; - 1) ;; - *) echo "$me: too many arguments$help" >&2 - exit 1;; -esac - -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ - kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac - -### Let's recognize common machines as not being operating systems so -### that things like config.sub decstation-3100 work. We also -### recognize some manufacturers as not being operating systems, so we -### can provide default operating systems below. -case $os in - -sun*os*) - # Prevent following clause from handling this invalid input. - ;; - -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ - -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ - -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis | -knuth | -cray) - os= - basic_machine=$1 - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*) - os=-lynxos - ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` - ;; - -psos*) - os=-psos - ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; -esac - -# Decode aliases for certain CPU-COMPANY combinations. -case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | am33_2.0 \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ - | bfin \ - | c4x | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | fr30 | frv \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | i370 | i860 | i960 | ia64 \ - | ip2k | iq2000 \ - | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64vr | mips64vrel \ - | mips64orion | mips64orionel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | ms1 \ - | msp430 \ - | ns16k | ns32k \ - | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ - | pyramid \ - | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b \ - | strongarm \ - | tahoe | thumb | tic4x | tic80 | tron \ - | v850 | v850e \ - | we32k \ - | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ - | z8k) - basic_machine=$basic_machine-unknown - ;; - m32c) - basic_machine=$basic_machine-unknown - ;; - m6811 | m68hc11 | m6812 | m68hc12) - # Motorola 68HC11/12. - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) - ;; - - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* \ - | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ - | clipper-* | craynv-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ - | elxsi-* \ - | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* | iq2000-* \ - | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mips64vr5900-* | mips64vr5900el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | ms1-* \ - | msp430-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ - | pyramid-* \ - | romp-* | rs6000-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \ - | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ - | tahoe-* | thumb-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tron-* \ - | v850-* | v850e-* | vax-* \ - | we32k-* \ - | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ - | xstormy16-* | xtensa-* \ - | ymp-* \ - | z8k-*) - ;; - m32c-*) - ;; - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att - ;; - 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16c) - basic_machine=cr16c-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 - ;; - decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - djgpp) - basic_machine=i586-pc - os=-msdosdjgpp - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; -# I'm not sure what "Sysv32" means. Should this be sysv3.2? - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - mingw32) - basic_machine=i386-pc - os=-mingw32 - ;; - miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos - ;; - news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next - case $os in - -nextstep* ) - ;; - -ns2*) - os=-nextstep2 - ;; - *) - os=-nextstep3 - ;; - esac - ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; - np1) - basic_machine=np1-gould - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - openrisc | openrisc-*) - basic_machine=or32-unknown - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc - ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc - ;; - pentium4) - basic_machine=i786-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc) basic_machine=powerpc-unknown - ;; - ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff - ;; - rm[46]00) - basic_machine=mips-siemens - ;; - rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - s390 | s390-*) - basic_machine=s390-ibm - ;; - s390x | s390x-*) - basic_machine=s390x-ibm - ;; - sa29200) - basic_machine=a29k-amd - os=-udi - ;; - sb1) - basic_machine=mipsisa64sb1-unknown - ;; - sb1el) - basic_machine=mipsisa64sb1el-unknown - ;; - sei) - basic_machine=mips-sei - os=-seiux - ;; - sequent) - basic_machine=i386-sequent - ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; - sh64) - basic_machine=sh64-unknown - ;; - sparclite-wrs | simso-wrs) - basic_machine=sparclite-wrs - os=-vxworks - ;; - sps7) - basic_machine=m68k-bull - os=-sysv2 - ;; - spur) - basic_machine=spur-unknown - ;; - st2000) - basic_machine=m68k-tandem - ;; - stratus) - basic_machine=i860-stratus - os=-sysv4 - ;; - sun2) - basic_machine=m68000-sun - ;; - sun2os3) - basic_machine=m68000-sun - os=-sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - os=-sunos4 - ;; - sun3os3) - basic_machine=m68k-sun - os=-sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - os=-sunos4 - ;; - sun4os3) - basic_machine=sparc-sun - os=-sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - os=-sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - os=-solaris2 - ;; - sun3 | sun3-*) - basic_machine=m68k-sun - ;; - sun4) - basic_machine=sparc-sun - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - ;; - sv1) - basic_machine=sv1-cray - os=-unicos - ;; - symmetry) - basic_machine=i386-sequent - os=-dynix - ;; - t3e) - basic_machine=alphaev5-cray - os=-unicos - ;; - t90) - basic_machine=t90-cray - os=-unicos - ;; - tic54x | c54x*) - basic_machine=tic54x-unknown - os=-coff - ;; - tic55x | c55x*) - basic_machine=tic55x-unknown - os=-coff - ;; - tic6x | c6x*) - basic_machine=tic6x-unknown - os=-coff - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - tpf) - basic_machine=s390x-ibm - os=-tpf - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - xbox) - basic_machine=i686-pc - os=-mingw32 - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - ymp) - basic_machine=ymp-cray - os=-unicos - ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - none) - basic_machine=none-none - os=-none - ;; - -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond - ;; - op50n) - basic_machine=hppa1.1-oki - ;; - op60c) - basic_machine=hppa1.1-oki - ;; - romp) - basic_machine=romp-ibm - ;; - mmix) - basic_machine=mmix-knuth - ;; - rs6000) - basic_machine=rs6000-ibm - ;; - vax) - basic_machine=vax-dec - ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; - pdp11) - basic_machine=pdp11-dec - ;; - we32k) - basic_machine=we32k-att - ;; - sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) - basic_machine=sh-unknown - ;; - sparc | sparcv8 | sparcv9 | sparcv9b) - basic_machine=sparc-sun - ;; - cydra) - basic_machine=cydra-cydrome - ;; - orion) - basic_machine=orion-highlevel - ;; - orion105) - basic_machine=clipper-highlevel - ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple - ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple - ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. - ;; - *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` - ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if [ x"$os" != x"" ] -then -case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; - -solaris) - os=-solaris2 - ;; - -svr4*) - os=-sysv4 - ;; - -unixware*) - os=-sysv4.2uw - ;; - -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` - ;; - # First accept the basic system types. - # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ - | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ - | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* \ - | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ - | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ - | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ - | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ - | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku*) - # Remember, each alternative MUST END IN *, to match a version number. - ;; - -qnx*) - case $basic_machine in - x86-* | i*86-*) - ;; - *) - os=-nto$os - ;; - esac - ;; - -nto-qnx*) - ;; - -nto*) - os=`echo $os | sed -e 's|nto|nto-qnx|'` - ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ - | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) - ;; - -mac*) - os=`echo $os | sed -e 's|mac|macos|'` - ;; - -linux-dietlibc) - os=-linux-dietlibc - ;; - -linux*) - os=`echo $os | sed -e 's|linux|linux-gnu|'` - ;; - -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` - ;; - -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` - ;; - -opened*) - os=-openedition - ;; - -os400*) - os=-os400 - ;; - -wince*) - os=-wince - ;; - -osfrose*) - os=-osfrose - ;; - -osf*) - os=-osf - ;; - -utek*) - os=-bsd - ;; - -dynix*) - os=-bsd - ;; - -acis*) - os=-aos - ;; - -atheos*) - os=-atheos - ;; - -syllable*) - os=-syllable - ;; - -386bsd) - os=-bsd - ;; - -ctix* | -uts*) - os=-sysv - ;; - -nova*) - os=-rtmk-nova - ;; - -ns2 ) - os=-nextstep2 - ;; - -nsk*) - os=-nsk - ;; - # Preserve the version number of sinix5. - -sinix5.*) - os=`echo $os | sed -e 's|sinix|sysv|'` - ;; - -sinix*) - os=-sysv4 - ;; - -tpf*) - os=-tpf - ;; - -triton*) - os=-sysv3 - ;; - -oss*) - os=-sysv3 - ;; - -svr4) - os=-sysv4 - ;; - -svr3) - os=-sysv3 - ;; - -sysvr4) - os=-sysv4 - ;; - # This must come after -sysvr4. - -sysv*) - ;; - -ose*) - os=-ose - ;; - -es1800*) - os=-ose - ;; - -xenix) - os=-xenix - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - os=-mint - ;; - -aros*) - os=-aros - ;; - -kaos*) - os=-kaos - ;; - -zvmoe) - os=-zvmoe - ;; - -none) - ;; - *) - # Get rid of the `-' at the beginning of $os. - os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 - exit 1 - ;; -esac -else - -# Here we handle the default operating systems that come with various machines. -# The value should be what the vendor currently ships out the door with their -# machine or put another way, the most popular os provided with the machine. - -# Note that if you're going to try to match "-MANUFACTURER" here (say, -# "-sun"), then you have to tell the case statement up towards the top -# that MANUFACTURER isn't an operating system. Otherwise, code above -# will signal an error saying that MANUFACTURER isn't an operating -# system, and we'll never get to this point. - -case $basic_machine in - *-acorn) - os=-riscix1.2 - ;; - arm*-rebel) - os=-linux - ;; - arm*-semi) - os=-aout - ;; - c4x-* | tic4x-*) - os=-coff - ;; - # This must come before the *-dec entry. - pdp10-*) - os=-tops20 - ;; - pdp11-*) - os=-none - ;; - *-dec | vax-*) - os=-ultrix4.2 - ;; - m68*-apollo) - os=-domain - ;; - i386-sun) - os=-sunos4.0.2 - ;; - m68000-sun) - os=-sunos3 - # This also exists in the configure program, but was not the - # default. - # os=-sunos4 - ;; - m68*-cisco) - os=-aout - ;; - mips*-cisco) - os=-elf - ;; - mips*-*) - os=-elf - ;; - or32-*) - os=-coff - ;; - *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 - ;; - sparc-* | *-sun) - os=-sunos4.1.1 - ;; - *-be) - os=-beos - ;; - *-haiku) - os=-haiku - ;; - *-ibm) - os=-aix - ;; - *-knuth) - os=-mmixware - ;; - *-wec) - os=-proelf - ;; - *-winbond) - os=-proelf - ;; - *-oki) - os=-proelf - ;; - *-hp) - os=-hpux - ;; - *-hitachi) - os=-hiux - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv - ;; - *-cbm) - os=-amigaos - ;; - *-dg) - os=-dgux - ;; - *-dolphin) - os=-sysv3 - ;; - m68k-ccur) - os=-rtu - ;; - m88k-omron*) - os=-luna - ;; - *-next ) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 - ;; - *-gould) - os=-sysv - ;; - *-highlevel) - os=-bsd - ;; - *-encore) - os=-bsd - ;; - *-sgi) - os=-irix - ;; - *-siemens) - os=-sysv4 - ;; - *-masscomp) - os=-rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=-uxpv - ;; - *-rom68k) - os=-coff - ;; - *-*bug) - os=-coff - ;; - *-apple) - os=-macos - ;; - *-atari*) - os=-mint - ;; - *) - os=-none - ;; -esac -fi - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) - vendor=acorn - ;; - -sunos*) - vendor=sun - ;; - -aix*) - vendor=ibm - ;; - -beos*) - vendor=be - ;; - -hpux*) - vendor=hp - ;; - -mpeix*) - vendor=hp - ;; - -hiux*) - vendor=hitachi - ;; - -unos*) - vendor=crds - ;; - -dgux*) - vendor=dg - ;; - -luna*) - vendor=omron - ;; - -genix*) - vendor=ns - ;; - -mvs* | -opened*) - vendor=ibm - ;; - -os400*) - vendor=ibm - ;; - -ptx*) - vendor=sequent - ;; - -tpf*) - vendor=ibm - ;; - -vxsim* | -vxworks* | -windiss*) - vendor=wrs - ;; - -aux*) - vendor=apple - ;; - -hms*) - vendor=hitachi - ;; - -mpw* | -macos*) - vendor=apple - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - vendor=atari - ;; - -vos*) - vendor=stratus - ;; - esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` - ;; -esac - -echo $basic_machine$os -exit - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/storage/bdb/dist/configure.ac b/storage/bdb/dist/configure.ac deleted file mode 100644 index d9045434513..00000000000 --- a/storage/bdb/dist/configure.ac +++ /dev/null @@ -1,754 +0,0 @@ -# $Id: configure.ac,v 12.9 2005/10/14 20:52:29 bostic Exp $ -# Process this file with autoconf to produce a configure script. - -PACKAGE=db -AC_INIT(Berkeley DB, - __EDIT_DB_VERSION__, support@sleepycat.com, db-__EDIT_DB_VERSION__) -AC_CONFIG_SRCDIR([../db/db.c]) -AC_CONFIG_HEADERS([db_config.h:config.hin]) - -# Configure setup. -AC_CANONICAL_HOST() -AC_ARG_PROGRAM() - -# Don't build in the top-level or dist directories. -AC_MSG_CHECKING(if building in the top-level or dist directories) -if [ test -d db_archive -o -f configure.ac ] ; then - AC_MSG_RESULT(yes) - AC_MSG_ERROR( - [Berkeley DB should not be built in the top-level or dist directories.]) -fi -AC_MSG_RESULT(no) - -# Substitution variables. -AC_SUBST(ADDITIONAL_INCS) -AC_SUBST(ADDITIONAL_LANG) -AC_SUBST(ADDITIONAL_OBJS) -AC_SUBST(ADDITIONAL_PROGS) -AC_SUBST(BUILD_TARGET) -AC_SUBST(CFLAGS) -AC_SUBST(CONFIGURATION_ARGS) -AC_SUBST(CONFIGURATION_PATH) -AC_SUBST(CPPFLAGS) -AC_SUBST(CRYPTO_OBJS) -AC_SUBST(CXX) -AC_SUBST(CXXFLAGS) -AC_SUBST(DB_PROTO1) -AC_SUBST(DB_PROTO2) -AC_SUBST(DEFAULT_LIB) -AC_SUBST(DEFAULT_LIB_CXX) -AC_SUBST(INSTALLER) -AC_SUBST(INSTALL_LIBS) -AC_SUBST(INSTALL_TARGET) -AC_SUBST(JAR) -AC_SUBST(JAVACFLAGS) -AC_SUBST(LDFLAGS) -AC_SUBST(LIBCSO_LIBS) -AC_SUBST(LIBJSO_LIBS) -AC_SUBST(LIBS) -AC_SUBST(LIBSO_LIBS) -AC_SUBST(LIBTOOL) -AC_SUBST(LIBTSO_LIBS) -AC_SUBST(LIBTSO_MODSUFFIX) -AC_SUBST(LIBTSO_MODULE) -AC_SUBST(LIBXSO_LIBS) -AC_SUBST(MAKEFILE_CC) -AC_SUBST(MAKEFILE_CCLINK) -AC_SUBST(MAKEFILE_CXX) -AC_SUBST(MAKEFILE_CXXLINK) -AC_SUBST(MAKEFILE_SOLINK) -AC_SUBST(MAKEFILE_XSOLINK) -AC_SUBST(OSDIR) -AC_SUBST(PATH_SEPARATOR) -AC_SUBST(POSTLINK) -AC_SUBST(REPLACEMENT_OBJS) -AC_SUBST(RPC_CLIENT_OBJS) -AC_SUBST(RPC_SERVER_H) -AC_SUBST(SOFLAGS) -AC_SUBST(TEST_LIBS) -AC_SUBST(db_cv_build_type) -AC_SUBST(db_int_def) -AC_SUBST(o) - -# Set the default installation location. -AC_PREFIX_DEFAULT(/usr/local/BerkeleyDB.__EDIT_DB_VERSION_MAJOR__.__EDIT_DB_VERSION_MINOR__) - -# Configure the version information. -AC_SUBST(DB_VERSION_MAJOR) -DB_VERSION_MAJOR="__EDIT_DB_VERSION_MAJOR__" -AC_SUBST(DB_VERSION_MINOR) -DB_VERSION_MINOR="__EDIT_DB_VERSION_MINOR__" -AC_SUBST(DB_VERSION_PATCH) -DB_VERSION_PATCH="__EDIT_DB_VERSION_PATCH__" -AC_SUBST(DB_VERSION_STRING) -DB_VERSION_STRING='"__EDIT_DB_VERSION_STRING__"' -AC_SUBST(DB_VERSION_UNIQUE_NAME) - -# Process all options before using them. -AM_OPTIONS_SET - -# Set some #defines based on configuration options. -if test "$db_cv_diagnostic" = "yes"; then - AC_DEFINE(DIAGNOSTIC) - AH_TEMPLATE(DIAGNOSTIC, - [Define to 1 if you want a version with run-time diagnostic checking.]) -fi -if test "$db_cv_debug_rop" = "yes"; then - AC_DEFINE(DEBUG_ROP) - AH_TEMPLATE(DEBUG_ROP, - [Define to 1 if you want a version that logs read operations.]) -fi -if test "$db_cv_debug_wop" = "yes"; then - AC_DEFINE(DEBUG_WOP) - AH_TEMPLATE(DEBUG_WOP, - [Define to 1 if you want a version that logs write operations.]) -fi -if test "$db_cv_umrw" = "yes"; then - AC_DEFINE(UMRW) - AH_TEMPLATE(UMRW, - [Define to 1 to mask harmless uninitialized memory read/writes.]) - -fi -if test "$db_cv_test" = "yes"; then - AC_DEFINE(CONFIG_TEST) - AH_TEMPLATE(CONFIG_TEST, - [Define to 1 if you want to build a version for running the test suite.]) -fi - -# Check for programs used in building and installation. -AM_PROGRAMS_SET -AC_PROG_INSTALL - -BUILD_TARGET="library_build" -INSTALL_TARGET="library_install" - -# This is where we handle stuff that autoconf can't handle: compiler, -# preprocessor and load flags, libraries that the standard tests don't -# look for. -# -# There are additional libraries we need for some compiler/architecture -# combinations. -# -# Some architectures require DB to be compiled with special flags and/or -# libraries for threaded applications -# -# The makefile CC may be different than the CC used in config testing, -# because the makefile CC may be set to use $(LIBTOOL). -# -# Don't override anything if it's already set from the environment. -optimize_debug="-O" -case "$host_os" in -aix4.3.*|aix5*) - optimize_debug="-O2" - CC=${CC-"xlc_r"} - CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE" - LDFLAGS="$LDFLAGS -Wl,-brtl";; -bsdi3*) CC=${CC-"shlicc2"} - LIBS="$LIBS -lipc";; -cygwin*) - CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE -D_REENTRANT";; -freebsd*) - CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE" - LDFLAGS="$LDFLAGS -pthread";; -gnu*|k*bsd*-gnu|linux*) - CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE -D_REENTRANT";; -hpux*) CPPFLAGS="$CPPFLAGS -D_REENTRANT";; -irix*) optimize_debug="-O2" - CPPFLAGS="$CPPFLAGS -D_SGI_MP_SOURCE";; -mpeix*) CPPFLAGS="$CPPFLAGS -D_POSIX_SOURCE -D_SOCKET_SOURCE" - LIBS="$LIBS -lsocket -lsvipc";; -osf*) CPPFLAGS="$CPPFLAGS -pthread";; -*qnx*) AC_DEFINE(HAVE_QNX) - AH_TEMPLATE(HAVE_QNX, [Define to 1 if building on QNX.]);; -solaris*) - CPPFLAGS="$CPPFLAGS -D_REENTRANT";; -esac - -# If the user wants a debugging environment, change any compiler optimization -# flags to -g. We used to add -g to the -O compiler flags, but compilers are -# good enough at code re-organization that debugging with -O no longer works. -# If you want to compile with a different set of flags, specify CFLAGS in the -# environment before configuring. -if test "$db_cv_debug" = "yes"; then - AC_DEFINE(DEBUG) - AH_TEMPLATE(DEBUG, [Define to 1 if you want a debugging version.]) - - optimize_debug="-g" -fi - -# Set CFLAGS/CXXFLAGS. We MUST set the flags before we call autoconf -# compiler configuration macros, because if we don't, they set CFLAGS -# to no optimization and -g, which isn't what we want. -CFLAGS=${CFLAGS-$optimize_debug} -CXXFLAGS=${CXXFLAGS-"$CFLAGS"} - -# The default compiler is cc (NOT gcc), the default CFLAGS is as specified -# above, NOT what is set by AC_PROG_CC, as it won't set optimization flags -# for any compiler other than gcc. -AC_PROG_CC(cc gcc) - -# We know what compiler we're going to use, now. Set per-compiler flags. -if test "$GCC" = "yes"; then - # We want -O2 if we're using gcc. - CFLAGS="$CFLAGS " - CFLAGS=`echo "$CFLAGS" | sed 's/-O /-O2 /g'` -else - case "$host_os" in - hpux11.0*) ;; - hpux11*) CPPFLAGS="$CPPFLAGS -mt";; - esac -fi - -# Checks for compiler characteristics. -DB_PROTO1="#undef __P" - -# AC_PROG_CC_STDC only sets ac_cv_prog_cc_stdc if the test fails, so -# check for "no", not "yes". -if test "$ac_cv_prog_cc_stdc" = "no"; then - DB_PROTO2="#define __P(protos) ()" -else - DB_PROTO2="#define __P(protos) protos" -fi - -AC_C_CONST -AC_SUBST(DB_CONST) -if test "$ac_cv_c_const" != "yes"; then - DB_CONST="#define const" -fi - -# Because of shared library building, the ${CC} used for config tests -# may be different than the ${CC} we want to put in the Makefile. -# The latter is known as ${MAKEFILE_CC} in this script. -MAKEFILE_CC="${CC}" -MAKEFILE_CCLINK="${CC}" -MAKEFILE_CXX="nocxx" -MAKEFILE_CXXLINK="nocxx" - -# See if we need the C++ compiler at all. If so, we'd like to find one that -# interoperates with the C compiler we chose. Since we prefered cc over gcc, -# we'll also prefer the vendor's compiler over g++/gcc. If we're wrong, the -# user can set CC and CXX in their environment before running configure. -# -# AC_PROG_CXX sets CXX, but it uses $CXX and $CCC (in that order) as its -# first choices. -if test "$db_cv_cxx" = "yes"; then - if test "$GCC" != "yes"; then - case "$host_os" in - aix*) AC_CHECK_TOOL(CCC, xlC_r) - LIBXSO_LIBS="-lC_r $LIBXSO_LIBS" - LIBS="-lC_r $LIBS";; - hpux*) AC_CHECK_TOOL(CCC, aCC);; - irix*) AC_CHECK_TOOL(CCC, CC);; - osf*) AC_CHECK_TOOL(CCC, cxx);; - solaris*) AC_CHECK_TOOL(CCC, CC);; - esac - fi - AC_PROG_CXX - ###### WORKAROUND: SEE SR #7938 - AC_PROG_CXXCPP - ############################### - AC_CXX_HAVE_STDHEADERS - MAKEFILE_CXX="${CXX}" - MAKEFILE_CXXLINK="${CXX}" -fi - -# Do some gcc specific configuration. -AC_GCC_CONFIG1 -AC_GCC_CONFIG2 - -# We need the -Kthread/-pthread flag when compiling on SCO/Caldera's UnixWare -# and OpenUNIX releases. We can't make the test until we know which compiler -# we're using. -case "$host_os" in -sysv5UnixWare*|sysv5OpenUNIX8*) - if test "$GCC" == "yes"; then - CPPFLAGS="$CPPFLAGS -pthread" - LDFLAGS="$LDFLAGS -pthread" - else - CPPFLAGS="$CPPFLAGS -Kthread" - LDFLAGS="$LDFLAGS -Kthread" - fi;; -esac - -# Export our compiler preferences for the libtool configuration. -export CC CCC -CCC=CXX - -# Libtool configuration. -AC_PROG_LIBTOOL - -SOFLAGS="-rpath \$(libdir)" -LIBTOOL_PROG="${SHELL} ./libtool" - -# Set SOSUFFIX and friends -SOSUFFIX_CONFIG -MODSUFFIX_CONFIG -JMODSUFFIX_CONFIG - -INSTALLER="\$(LIBTOOL) --mode=install cp -p" - -MAKEFILE_CC="\$(LIBTOOL) --mode=compile ${MAKEFILE_CC}" -MAKEFILE_SOLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CCLINK} -avoid-version" -MAKEFILE_CCLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CCLINK}" -MAKEFILE_CXX="\$(LIBTOOL) --mode=compile ${MAKEFILE_CXX}" -MAKEFILE_XSOLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CXXLINK} -avoid-version" -MAKEFILE_CXXLINK="\$(LIBTOOL) --mode=link ${MAKEFILE_CXXLINK}" - -LIBTOOL="\$(SHELL) ./libtool" - -case "$host_os" in -cygwin* | mingw*) - MAKEFILE_SOLINK="$MAKEFILE_SOLINK -no-undefined" - MAKEFILE_XSOLINK="$MAKEFILE_XSOLINK -no-undefined";; -esac - -# Configure for shared libraries, static libraries, or both. If both are -# configured, build the utilities and example programs with shared versions. -# -# $o is set to ".o" or ".lo", and is the file suffix used in the Makefile -# instead of .o -if test `$LIBTOOL_PROG --config | - grep build_libtool_libs | grep no` 2>/dev/null; then - enable_shared="no" -else - enable_shared="yes" -fi -if test `$LIBTOOL_PROG --config | - grep build_old_libs | grep no` 2>/dev/null; then - enable_static="no" -else - enable_static="yes" -fi - -case "$host_os" in - darwin*) - LIBTSO_MODULE="" - LIBTSO_MODSUFFIX=".dylib" - ;; - *) - LIBTSO_MODULE="-module" - LIBTSO_MODSUFFIX=@MODSUFFIX@ - ;; -esac - -# C API. -if test "$enable_shared" = "no"; then - DEFAULT_LIB="\$(libdb_version)" - POSTLINK=": " - o=".o" -else - DEFAULT_LIB="\$(libso_target)" - POSTLINK="\$(LIBTOOL) --mode=execute true" - o=".lo" -fi -INSTALL_LIBS="$DEFAULT_LIB" -if test "$enable_static" = "yes"; then - INSTALL_LIBS="$INSTALL_LIBS \$(libdb)" -fi - -# Optional C++ API. -if test "$db_cv_cxx" = "yes"; then - if test "$enable_shared" = "no"; then - DEFAULT_LIB_CXX="\$(libcxx_version)" - fi - if test "$enable_shared" = "yes"; then - DEFAULT_LIB_CXX="\$(libxso_target)" - fi - INSTALL_LIBS="$INSTALL_LIBS $DEFAULT_LIB_CXX" - if test "$enable_static" = "yes"; then - INSTALL_LIBS="$INSTALL_LIBS \$(libcxx)" - fi -fi - -# We split DbConstants.java into debug and release versions so Windows -# developers don't need to do anything special to use the Debug DLL. -if test "$db_cv_debug" = "yes"; then - db_cv_build_type=debug -else - db_cv_build_type=release -fi - -# Optional Java API. -if test "$db_cv_java" = "yes"; then - # Java requires shared libraries. - if test "$enable_shared" = "no"; then - AC_MSG_ERROR([Java requires shared libraries]) - fi - - # A classpath that includes . is needed to check for Java - CLASSPATH=".:$CLASSPATH" - export CLASSPATH - AC_PROG_JAVAC - AC_PROG_JAR - AC_PROG_JAVA - AC_JNI_INCLUDE_DIR - - AC_MSG_CHECKING(java version) - case "$JAVA" in - *kaffe* ) - JAVA_VERSION=`$JAVA -version 2>&1 | - sed -e '/Java Version:/!d' -e 's/.*Java Version: \([[^ ]]*\)[[ ]]*/\1/'` ;; - * ) JAVA_VERSION=`$JAVA -version 2>&1 | - sed -e '/ version /!d' -e 's/.*"\(.*\)".*/\1/'` ;; - esac - AC_MSG_RESULT($JAVA_VERSION) - case "$JAVA_VERSION" in - 1.[[3456789]]* | 1.[[1-9]][[0-9]]* | [[23456789]]* ) ;; - * ) - AC_MSG_ERROR([Java version 1.3 or higher required, got $JAVA_VERSION]) ;; - esac - - for JNI_INCLUDE_DIR in $JNI_INCLUDE_DIRS - do - CPPFLAGS="$CPPFLAGS -I$JNI_INCLUDE_DIR" - done - - ADDITIONAL_LANG="$ADDITIONAL_LANG java" - INSTALL_LIBS="$INSTALL_LIBS \$(libjso_target)" -else - JAVAC=nojavac -fi - -# MinGW support. -if test "$db_cv_mingw" = "yes"; then - OSDIR=os_win32 - PATH_SEPARATOR="\\\\/:" - - AC_DEFINE(DB_WIN32) - AC_DEFINE(STDC_HEADERS) -else - OSDIR=os - PATH_SEPARATOR="/" -fi - -# Checks for include files, structures, C types. -AC_HEADER_STAT -AC_HEADER_TIME -AC_HEADER_DIRENT -AC_CHECK_HEADERS(sys/select.h sys/time.h sys/fcntl.h) -AC_CHECK_MEMBERS([struct stat.st_blksize]) -AM_TYPES - -AC_CACHE_CHECK([for ANSI C exit success/failure values], db_cv_exit_defines, [ -AC_TRY_COMPILE([#include <stdlib.h>], return (EXIT_SUCCESS);, - [db_cv_exit_defines=yes], [db_cv_exit_defines=no])]) -if test "$db_cv_exit_defines" = "yes"; then - AC_DEFINE(HAVE_EXIT_SUCCESS) - AH_TEMPLATE(HAVE_EXIT_SUCCESS, - [Define to 1 if you have EXIT_SUCCESS/EXIT_FAILURE #defines.]) -fi - -# Test for various functions/libraries -- do tests that change library values -# first. -# -# The Berkeley DB library calls fdatasync, and it's only available in -lrt on -# Solaris. See if we can find it either without additional libraries or in -# -lrt. If fdatasync is found in -lrt, add -lrt to the shared library links. -AC_SEARCH_LIBS(fdatasync, rt, [dnl - if test "$ac_cv_search_fdatasync" != "none required" ; then - LIBSO_LIBS="$LIBSO_LIBS -lrt"; - fi]) - -# The test and example programs use the sched_yield function, taken from -lrt -# on Solaris. -AC_SEARCH_LIBS(sched_yield, rt) - -# !!! -# We can't check for pthreads in the same way we did the test for sched_yield -# because the Solaris C library includes pthread interfaces which are not -# inter-process safe. For that reason we always add -lpthread if we find a -# pthread library. -# -# We can't depend on any specific call existing (pthread_create, for example), -# as it may be #defined in an include file -- OSF/1 (Tru64) has this problem. -AC_HAVE_LIBRARY(pthread, TEST_LIBS="$TEST_LIBS -lpthread") - -# !!! -# We could be more exact about whether these libraries are needed, but don't -# bother -- if they exist, we load them, it's only the test programs anyway. -AC_HAVE_LIBRARY(m, TEST_LIBS="$TEST_LIBS -lm") -AC_HAVE_LIBRARY(socket, TEST_LIBS="$TEST_LIBS -lsocket") -AC_HAVE_LIBRARY(nsl, TEST_LIBS="$TEST_LIBS -lnsl") - -# Check for mutexes. -# We do this here because it changes $LIBS. -AM_DEFINE_MUTEXES - -# Checks for system functions for which we have replacements. -# -# XXX -# The only portable getcwd call is getcwd(char *, size_t), where the -# buffer is non-NULL -- Solaris can't handle a NULL buffer, and they -# deleted getwd(). -AC_REPLACE_FUNCS(getcwd getopt memcmp memcpy memmove raise) -AC_REPLACE_FUNCS(strcasecmp strdup strerror strtol strtoul) - -# Check for system functions we optionally use. -AC_CHECK_FUNCS(\ - _fstati64 clock_gettime directio fchmod fcntl fdatasync ftruncate\ - getrusage gettimeofday getuid pstat_getdynamic rand sched_yield\ - select snprintf srand sysconf vsnprintf yield) - -# Pthread_self. -# The use of pthread_self to identify threads can be forced. -if test "$db_cv_pthread_self" = "yes"; then - AC_CHECK_FUNCS(pthread_self) -fi - -# Pread/pwrite. -# HP-UX has pread/pwrite, but it doesn't work with largefile support. -# NCR's version of System V R 4.3 has pread/pwrite symbols, but no support. -case "$host_os-$host_vendor" in -hpux*|sysv4.3*-ncr) - AC_MSG_WARN( - [pread/pwrite interfaces ignored on $host_os-$host_vendor.]);; -*) - AC_CHECK_FUNCS(pread pwrite);; -esac - -# Check for fcntl(2) to deny child process access to file descriptors. -AC_CACHE_CHECK([for fcntl/F_SETFD], db_cv_fcntl_f_setfd, [ -AC_TRY_LINK([ -#include <sys/types.h> -#include <fcntl.h>], [ - fcntl(1, F_SETFD, 1); -], [db_cv_fcntl_f_setfd=yes], [db_cv_fcntl_f_setfd=no])]) -if test "$db_cv_fcntl_f_setfd" = "yes"; then - AC_DEFINE(HAVE_FCNTL_F_SETFD) - AH_TEMPLATE(HAVE_FCNTL_F_SETFD, - [Define to 1 if fcntl/F_SETFD denies child access to file descriptors.]) -fi - -# A/UX has a broken getopt(3). -case "$host_os" in -aux*) AC_LIBOBJ([getopt]);; -esac - -# Linux has a broken O_DIRECT flag, but you can't detect it at configure time. -# Linux and SGI require buffer alignment we may not match, otherwise writes -# will fail. Default to not using the O_DIRECT flag. -if test "$db_cv_o_direct" = "yes"; then - AC_CACHE_CHECK([for open/O_DIRECT], db_cv_open_o_direct, [ - AC_TRY_LINK([ - #include <sys/types.h> - #include <fcntl.h>], [ - open("a", O_RDONLY | O_DIRECT, 0); - ], [db_cv_open_o_direct=yes], [db_cv_open_o_direct=no])]) - if test \ - "$db_cv_o_direct" = "yes" -a "$db_cv_open_o_direct" = "yes"; then - AC_DEFINE(HAVE_O_DIRECT) - AH_TEMPLATE(HAVE_O_DIRECT, - [Define to 1 if you have the O_DIRECT flag.]) - fi -fi - -# Check for largefile support. -AC_SYS_LARGEFILE - -# Figure out how to create shared regions. -# -# First, we look for mmap. -# -# BSD/OS has mlock(2), but it doesn't work until the 4.1 release. -# -# Nextstep (version 3.3) apparently supports mmap(2) (the mmap symbol -# is defined in the C library) but does not support munmap(2). Don't -# try to use mmap if we can't find munmap. -# -# Ultrix has mmap(2), but it doesn't work. -mmap_ok=no -case "$host_os" in -bsdi3*|bsdi4.0) - AC_MSG_WARN([mlock(2) interface ignored on $host_os-$host_vendor.]) - mmap_ok=yes - AC_CHECK_FUNCS(mmap munmap, , mmap_ok=no);; -ultrix*) - AC_MSG_WARN([mmap(2) interface ignored on $host_os-$host_vendor.]);; -*) - mmap_ok=yes - AC_CHECK_FUNCS(mlock munlock) - AC_CHECK_FUNCS(mmap munmap, , mmap_ok=no);; -esac - -# Second, we look for shmget. -# -# SunOS has the shmget(2) interfaces, but there appears to be a missing -# #include <debug/debug.h> file, so we ignore them. -shmget_ok=no -case "$host_os" in -sunos*) - AC_MSG_WARN([shmget(2) interface ignored on $host_os-$host_vendor.]);; -*) - shmget_ok=yes - AC_CHECK_FUNCS(shmget, , shmget_ok=no);; -esac - -# We require either mmap/munmap(2) or shmget(2). -if test "$mmap_ok" = "no" -a "$shmget_ok" = "no"; then - AC_MSG_WARN([Neither mmap/munmap(2) or shmget(2) library functions.]) -fi - -# Optional RPC client/server. -if test "$db_cv_rpc" = "yes"; then - AM_RPC_CONFIGURE -fi - -# Optional Tcl support. -if test "$db_cv_tcl" = "yes"; then - AM_TCL_LOAD -fi - -# Optional sequence code. -AM_SEQUENCE_CONFIGURE - -# Optional DB 1.85 compatibility API. -if test "$db_cv_compat185" = "yes"; then - ADDITIONAL_INCS="db_185.h $ADDITIONAL_INCS" - - ADDITIONAL_OBJS="db185${o} $ADDITIONAL_OBJS" -fi - -# Optional utilities. -if test "$db_cv_dump185" = "yes"; then - ADDITIONAL_PROGS="db_dump185 $ADDITIONAL_PROGS" -fi - -# You can disable pieces of functionality to save space. -# -# Btree is always configured: it is the standard method, and Hash off-page -# duplicates require it. -ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(BTREE_OBJS)" - -# Hash can be disabled. -if test "$db_cv_build_hash" = "yes"; then - AC_DEFINE(HAVE_HASH) - AH_TEMPLATE(HAVE_HASH, [Define to 1 if building Hash access method.]) - ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(HASH_OBJS)" - if test "$db_cv_build_verify" = "yes"; then - ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(HASH_VRFY_OBJS)" - fi -else - ADDITIONAL_OBJS="$ADDITIONAL_OBJS hash_stub${o}" -fi - -# Queue can be disabled. -if test "$db_cv_build_queue" = "yes"; then - AC_DEFINE(HAVE_QUEUE) - AH_TEMPLATE(HAVE_QUEUE, [Define to 1 if building Queue access method.]) - ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(QUEUE_OBJS)" - if test "$db_cv_build_verify" = "yes"; then - ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(QUEUE_VRFY_OBJS)" - fi -else - ADDITIONAL_OBJS="$ADDITIONAL_OBJS qam_stub${o}" -fi - -# Replication can be disabled. -if test "$db_cv_build_replication" = "yes"; then - AC_DEFINE(HAVE_REPLICATION) - AH_TEMPLATE(HAVE_REPLICATION, - [Define to 1 if building replication support.]) - ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(REP_OBJS)" -else - ADDITIONAL_OBJS="$ADDITIONAL_OBJS rep_stub${o}" -fi - -# The statistics code can be disabled. -if test "$db_cv_build_statistics" = "yes"; then - AC_DEFINE(HAVE_STATISTICS) - AH_TEMPLATE(HAVE_STATISTICS, - [Define to 1 if building statistics support.]) -fi - -# The verification code can be disabled. -if test "$db_cv_build_verify" = "yes"; then - AC_DEFINE(HAVE_VERIFY) - AH_TEMPLATE(HAVE_VERIFY, - [Define to 1 if building access method verification support.]) - ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(BTREE_VRFY_OBJS)" -else - ADDITIONAL_OBJS="$ADDITIONAL_OBJS db_vrfy_stub${o}" -fi - -# The crypto code can be disabled. -if test -d "$srcdir/../crypto" -a "$db_cv_build_cryptography" = "yes"; then - AC_DEFINE(HAVE_CRYPTO) - AH_TEMPLATE(HAVE_CRYPTO, - [Define to 1 if Berkeley DB release includes strong cryptography.]) - - CRYPTO_OBJS="\$(CRYPTO_OBJS)" -else - CRYPTO_OBJS="crypto_stub${o}" -fi - -# If DIAGNOSTIC is defined, include the log print routines in the library -# itself, various diagnostic modes use them. -if test "$db_cv_diagnostic" = "yes"; then - ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(PRINT_OBJS)" -fi - -# We need to add the additional object files into the Makefile with the correct -# suffix. We can't use $LTLIBOBJS itself, because that variable has $U encoded -# in it for automake, and that's not what we want. See SR #7227 for additional -# information. -# -# XXX: I'm not sure this is correct. -REPLACEMENT_OBJS=`echo "$LIB@&t@OBJS" | - sed "s,\.[[^.]]* ,$o ,g;s,\.[[^.]]*$,$o,"` - -# This is necessary so that .o files in LIBOBJS are also built via -# the ANSI2KNR-filtering rules. -LIB@&t@OBJS=`echo "$LIB@&t@OBJS" | - sed 's,\.[[^.]]* ,$U&,g;s,\.[[^.]]*$,$U&,'` -LTLIBOBJS=`echo "$LIB@&t@OBJS" | - sed 's,\.[[^.]]* ,.lo ,g;s,\.[[^.]]*$,.lo,'` -AC_SUBST(LTLIBOBJS) - -# Initial output file list. -CREATE_LIST="Makefile - db_cxx.h:$srcdir/../dbinc/db_cxx.in - db_int.h:$srcdir/../dbinc/db_int.in" - -# MinGW needs win_db.h. -if test "$db_cv_mingw" = "yes"; then -CREATE_LIST="$CREATE_LIST - win_db.h:$srcdir/win_db.in" -fi - -# Create the db.h file from a source file, a list of global function -# prototypes, and, if configured for unique names, a list of #defines -# to do DB_VERSION_UNIQUE_NAME substitution. -if test "$db_cv_uniquename" = "yes"; then - CREATE_LIST="$CREATE_LIST - db.h:$srcdir/../dbinc/db.in:$srcdir/../dbinc_auto/ext_def.in:$srcdir/../dbinc_auto/ext_prot.in" -else - CREATE_LIST="$CREATE_LIST - db.h:$srcdir/../dbinc/db.in:$srcdir/../dbinc_auto/ext_prot.in" -fi - -# If configured for unique names, create the db_int_uext.h file (which -# does the DB_VERSION_UNIQUE_NAME substitution), which is included by -# the db_int.h file. -if test "$db_cv_uniquename" = "yes"; then - CREATE_LIST="$CREATE_LIST - db_int_def.h:$srcdir/../dbinc_auto/int_def.in" - db_int_def='#include "db_int_def.h"' -fi - -# Create the db_185.h and db185_int.h files from source files, a list of -# global function prototypes, and, if configured for unique names, a list -# of #defines to do DB_VERSION_UNIQUE_NAME substitution. -if test "$db_cv_compat185" = "yes"; then - if test "$db_cv_uniquename" = "yes"; then - CREATE_LIST="$CREATE_LIST - db_185.h:$srcdir/../dbinc/db_185.in:$srcdir/../dbinc_auto/ext_185_def.in:$srcdir/../dbinc_auto/ext_185_prot.in - db185_int.h:$srcdir/../db185/db185_int.in:$srcdir/../dbinc_auto/ext_185_def.in:$srcdir/../dbinc_auto/ext_185_prot.in" - else - CREATE_LIST="$CREATE_LIST - db_185.h:$srcdir/../dbinc/db_185.in:$srcdir/../dbinc_auto/ext_185_prot.in - db185_int.h:$srcdir/../db185/db185_int.in:$srcdir/../dbinc_auto/ext_185_prot.in" - fi -fi - -AC_CONFIG_FILES($CREATE_LIST) -AC_OUTPUT diff --git a/storage/bdb/dist/db.ecd.in b/storage/bdb/dist/db.ecd.in deleted file mode 100644 index 92a6a090716..00000000000 --- a/storage/bdb/dist/db.ecd.in +++ /dev/null @@ -1,64 +0,0 @@ -# Embedix Componenet Description (ECD) file for BerkeleyDB. -# -# $Id: db.ecd.in,v 11.1 2001/04/04 14:06:13 bostic Exp $ - -<GROUP System> -<GROUP Library> -<COMPONENT BerkeleyDB> - SRPM=db - <SPECPATCH></SPECPATCH> - <HELP> - Berkeley DB is Sleepycat Software's programmatic database toolkit. - </HELP> - - TYPE=bool - DEFAULT_VALUE=1 - PROMPT=Include BerkeleyDB library? - <KEEPLIST> - /usr/lib/libdb-@DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.so - /usr/include/db.h - /usr/lib/libdb.so - </KEEPLIST> - <PROVIDES> - libdb-@DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.so - </PROVIDES> - <REQUIRES> - ld-linux.so.2 - libc.so.6 - </REQUIRES> - STATIC_SIZE=0 - STARTUP_TIME=0 - - @EMBEDIX_ECD_CXX@ - - <OPTION db-extra> - TYPE=bool - DEFAULT_VALUE=1 - PROMPT=Include BerkeleyDB Utilities? - <KEEPLIST> - /usr/bin/db_archive - /usr/bin/db_checkpoint - /usr/bin/db_deadlock - /usr/bin/db_dump - /usr/bin/db_load - /usr/bin/db_printlog - /usr/bin/db_recover - /usr/bin/db_stat - /usr/bin/db_upgrade - /usr/bin/db_verify - @EMBEDIX_ECD_RPC@ - </KEEPLIST> - <REQUIRES> - libdb-@DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.so - ld-linux.so.2 - libc.so.6 - libdl.so.2 - libm.so.6 - </REQUIRES> - STATIC_SIZE=0 - STARTUP_TIME=0 - </OPTION> - -</COMPONENT> -</GROUP> -</GROUP> diff --git a/storage/bdb/dist/db.spec.in b/storage/bdb/dist/db.spec.in deleted file mode 100644 index ef253bcfcf4..00000000000 --- a/storage/bdb/dist/db.spec.in +++ /dev/null @@ -1,52 +0,0 @@ -# Berkeley DB @DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.@DB_VERSION_PATCH@ - -Summary: Sleepycat Berkeley DB database library -Name: db -Version: @DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.@DB_VERSION_PATCH@ -Release: 1 -Copyright: Freely redistributable, see LICENSE for details. -Source: http://www.sleepycat.com/update/@DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.@DB_VERSION_PATCH@/db-@DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.@DB_VERSION_PATCH@.tar.gz -URL: http://www.sleepycat.com -Group: System Environment/Libraries -BuildRoot: @CONFIGURATION_PATH@/RPM_INSTALL - -%description -Berkeley DB is a programmatic toolkit that provides fast, reliable, -mission-critical, and scalable built-in database support for software -ranging from embedded applications running on hand-held appliances to -enterprise-scale servers. - -The Berkeley DB access methods include B+tree, Extended Linear Hashing, -Fixed and Variable-length records, and Persistent Queues. Berkeley DB -provides full transactional support, database recovery, online backups, -and separate access to locking, logging and shared memory caching -subsystems. - -Berkeley DB supports C, C++, Java, Tcl, Perl, and Python APIs. The -software is available for Linux, a wide variety of UNIX platforms, -Windows 95/98, Windows/NT, Windows 2000, VxWorks and QNX. - -%prep -%setup - -%build -cd build_unix -CFLAGS="$RPM_OPT_FLAGS" ../dist/configure @CONFIGURATION_ARGS@ -make library_build - -%install -cd build_unix -make prefix=@CONFIGURATION_PATH@/RPM_INSTALL@EMBEDIX_ROOT@ install - -@RPM_POST_INSTALL@ - -@RPM_POST_UNINSTALL@ - -%files -%defattr(-,root,root) -%dir @EMBEDIX_ROOT@/bin -%dir @EMBEDIX_ROOT@/docs -%dir @EMBEDIX_ROOT@/include -%dir @EMBEDIX_ROOT@/lib - -%changelog diff --git a/storage/bdb/dist/gen_inc.awk b/storage/bdb/dist/gen_inc.awk deleted file mode 100644 index d48d02bb1d2..00000000000 --- a/storage/bdb/dist/gen_inc.awk +++ /dev/null @@ -1,73 +0,0 @@ -# This awk script parses C input files looking for lines marked "PUBLIC:" -# and "EXTERN:". (PUBLIC lines are DB internal function prototypes and -# #defines, EXTERN are DB external function prototypes and #defines.) -# -# PUBLIC lines are put into two versions of per-directory include files: -# one file that contains the prototypes, and one file that contains a -# #define for the name to be processed during configuration when creating -# unique names for every global symbol in the DB library. -# -# The EXTERN lines are put into two files: one of which contains prototypes -# which are always appended to the db.h file, and one of which contains a -# #define list for use when creating unique symbol names. -# -# Four arguments: -# e_dfile list of EXTERN #defines -# e_pfile include file that contains EXTERN prototypes -# i_dfile list of internal (PUBLIC) #defines -# i_pfile include file that contains internal (PUBLIC) prototypes -/PUBLIC:/ { - sub("^.*PUBLIC:[ ][ ]*", "") - if ($0 ~ "^#if|^#ifdef|^#ifndef|^#else|^#endif") { - print $0 >> i_pfile - print $0 >> i_dfile - next - } - pline = sprintf("%s %s", pline, $0) - if (pline ~ "\\)\\);") { - sub("^[ ]*", "", pline) - print pline >> i_pfile - if (pline !~ db_version_unique_name) { - gsub("[ ][ ]*__P.*", "", pline) - sub("^.*[ ][*]*", "", pline) - printf("#define %s %s@DB_VERSION_UNIQUE_NAME@\n", - pline, pline) >> i_dfile - } - pline = "" - } -} - -# When we switched to methods in 4.0, we guessed txn_{abort,begin,commit} -# were the interfaces applications would likely use and not be willing to -# change, due to the sheer volume of the calls. Provide wrappers -- we -# could do txn_abort and txn_commit using macros, but not txn_begin, as -# the name of the field is txn_begin, we didn't want to modify it. -# -# The issue with txn_begin hits us in another way. If configured with the -# --with-uniquename option, we use #defines to re-define DB's interfaces -# to unique names. We can't do that for these functions because txn_begin -# is also a field name in the DB_ENV structure, and the #defines we use go -# at the end of the db.h file -- we get control too late to #define a field -# name. So, modify the script that generates the unique names #defines to -# not generate them for these three functions, and don't include the three -# functions in libraries built with that configuration option. -/EXTERN:/ { - sub("^.*EXTERN:[ ][ ]*", "") - if ($0 ~ "^#if|^#ifdef|^#ifndef|^#else|^#endif") { - print $0 >> e_pfile - print $0 >> e_dfile - next - } - eline = sprintf("%s %s", eline, $0) - if (eline ~ "\\)\\);") { - sub("^[ ]*", "", eline) - print eline >> e_pfile - if (eline !~ db_version_unique_name && eline !~ "^int txn_") { - gsub("[ ][ ]*__P.*", "", eline) - sub("^.*[ ][*]*", "", eline) - printf("#define %s %s@DB_VERSION_UNIQUE_NAME@\n", - eline, eline) >> e_dfile - } - eline = "" - } -} diff --git a/storage/bdb/dist/gen_rec.awk b/storage/bdb/dist/gen_rec.awk deleted file mode 100644 index bfb972fbac7..00000000000 --- a/storage/bdb/dist/gen_rec.awk +++ /dev/null @@ -1,981 +0,0 @@ -#!/bin/sh - -# -# See the file LICENSE for redistribution information. -# -# Copyright (c) 1996-2005 -# Sleepycat Software. All rights reserved. -# -# $Id: gen_rec.awk,v 12.6 2005/10/12 18:48:44 ubell Exp $ -# - -# This awk script generates all the log, print, and read routines for the DB -# logging. It also generates a template for the recovery functions (these -# functions must still be edited, but are highly stylized and the initial -# template gets you a fair way along the path). -# -# For a given file prefix.src, we generate a file prefix_auto.c, and a file -# prefix_auto.h that contains: -# -# external declarations for the file's functions -# defines for the physical record types -# (logical types are defined in each subsystem manually) -# structures to contain the data unmarshalled from the log. -# -# This awk script requires that four variables be set when it is called: -# -# source_file -- the C source file being created -# header_file -- the C #include file being created -# template_file -- the template file being created -# -# And stdin must be the input file that defines the recovery setup. -# -# Within each file prefix.src, we use a number of public keywords (documented -# in the reference guide) as well as the following ones which are private to -# DB: -# DBPRIVATE Indicates that a file will be built as part of DB, -# rather than compiled independently, and so can use -# DB-private interfaces (such as DB_LOG_NOCOPY). -# DB A DB handle. Logs the dbreg fileid for that handle, -# and makes the *_log interface take a DB * instead of a -# DB_ENV *. -# PGDBT Just like DBT, only we know it stores a page or page -# header, so we can byte-swap it (once we write the -# byte-swapping code, which doesn't exist yet). -# LOCKS Just like DBT, but uses a print function for locks. - -BEGIN { - if (source_file == "" || - header_file == "" || template_file == "") { - print "Usage: gen_rec.awk requires three variables to be set:" - print "\theader_file\t-- the recover #include file being created" - print "\tprint_file\t-- the print source file being created" - print "\tsource_file\t-- the recover source file being created" - print "\ttemplate_file\t-- the template file being created" - exit - } - FS="[\t ][\t ]*" - CFILE=source_file - HFILE=header_file - PFILE=print_file - TFILE=template_file - dbprivate = 0 - buf_only = 1; -} -/^[ ]*DBPRIVATE/ { - dbprivate = 1 -} -/^[ ]*PREFIX/ { - prefix = $2 - num_funcs = 0; - - # Start .c files. - printf("/* Do not edit: automatically built by gen_rec.awk. */\n\n") \ - > CFILE - printf("#include \"db_config.h\"\n\n") >> CFILE - printf("/* Do not edit: automatically built by gen_rec.awk. */\n\n") \ - > PFILE - printf("#include \"db_config.h\"\n\n") >> PFILE - if (prefix == "__ham") - printf("#ifdef HAVE_HASH\n") >> PFILE - if (prefix == "__qam") - printf("#ifdef HAVE_QUEUE\n") >> PFILE - - # Start .h file, make the entire file conditional. - printf("/* Do not edit: automatically built by gen_rec.awk. */\n\n") \ - > HFILE - printf("#ifndef\t%s_AUTO_H\n#define\t%s_AUTO_H\n", prefix, prefix) \ - >> HFILE; - - # Write recovery template file headers - # This assumes we're doing DB recovery. - printf("#include \"db_config.h\"\n\n") > TFILE - printf("#ifndef NO_SYSTEM_INCLUDES\n") >> TFILE - printf("#include <sys/types.h>\n\n") >> TFILE - printf("#include <string.h>\n") >> TFILE - printf("#endif\n\n") >> TFILE - printf("#include \"db_int.h\"\n") >> TFILE - printf("#include \"dbinc/db_page.h\"\n") >> TFILE - printf("#include \"dbinc/%s.h\"\n", prefix) >> TFILE - printf("#include \"dbinc/log.h\"\n\n") >> TFILE -} -/^[ ]*INCLUDE/ { - for (i = 2; i < NF; i++) - printf("%s ", $i) >> CFILE - printf("%s\n", $i) >> CFILE - for (i = 2; i < NF; i++) - printf("%s ", $i) >> PFILE - printf("%s\n", $i) >> PFILE -} -/^[ ]*(BEGIN|IGNORED|BEGIN_BUF)/ { - if (in_begin) { - print "Invalid format: missing END statement" - exit - } - in_begin = 1; - is_dbt = 0; - has_dbp = 0; - is_uint = 0; - need_log_function = ($1 == "BEGIN") || ($1 == "BEGIN_BUF"); - not_buf = ($1 == "BEGIN") || ($1 == "IGNORED"); - if (not_buf) - buf_only = 0; - nvars = 0; - - thisfunc = $2; - funcname = sprintf("%s_%s", prefix, $2); - - if (not_buf) - rectype = $3; - - funcs[num_funcs] = funcname; - ++num_funcs; -} -/^[ ]*(DB|ARG|DBT|LOCKS|PGDBT|POINTER|TIME)/ { - vars[nvars] = $2; - types[nvars] = $3; - atypes[nvars] = $1; - modes[nvars] = $1; - formats[nvars] = $NF; - for (i = 4; i < NF; i++) - types[nvars] = sprintf("%s %s", types[nvars], $i); - - if ($1 == "DB") { - has_dbp = 1; - } - - if ($1 == "DB" || $1 == "ARG" || $1 == "TIME") { - sizes[nvars] = sprintf("sizeof(u_int32_t)"); - is_uint = 1; - } else if ($1 == "POINTER") - sizes[nvars] = sprintf("sizeof(*%s)", $2); - else { # DBT, PGDBT - sizes[nvars] = \ - sprintf("sizeof(u_int32_t) + (%s == NULL ? 0 : %s->size)", \ - $2, $2); - is_dbt = 1; - } - nvars++; -} -/^[ ]*END/ { - if (!in_begin) { - print "Invalid format: missing BEGIN statement" - exit; - } - - # Declare the record type. - if (not_buf) { - printf("#define\tDB_%s\t%d\n", funcname, rectype) >> HFILE - } - - # Structure declaration. - printf("typedef struct _%s_args {\n", funcname) >> HFILE - - # Here are the required fields for every structure - if (not_buf) { - printf("\tu_int32_t type;\n\tDB_TXN *txnid;\n") >> HFILE - printf("\tDB_LSN prev_lsn;\n") >>HFILE - } - - # Here are the specified fields. - for (i = 0; i < nvars; i++) { - t = types[i]; - if (modes[i] == "POINTER") { - ndx = index(t, "*"); - t = substr(types[i], 1, ndx - 2); - } - printf("\t%s\t%s;\n", t, vars[i]) >> HFILE - } - printf("} %s_args;\n\n", funcname) >> HFILE - - # Output the log, print and read functions. - if (need_log_function) { - log_function(); - } - if (not_buf) { - print_function(); - } - read_function(); - - # Recovery template - if (not_buf) { - cmd = sprintf(\ - "sed -e s/PREF/%s/ -e s/FUNC/%s/ < template/rec_ctemp >> %s", - prefix, thisfunc, TFILE) - system(cmd); - } - - # Done writing stuff, reset and continue. - in_begin = 0; -} - -END { - # End the conditional for the HFILE - printf("#endif\n") >> HFILE; - - if (buf_only == 1) - exit - - # Print initialization routine; function prototype - p[1] = sprintf("int %s_init_print %s%s", prefix, - "__P((DB_ENV *, int (***)(DB_ENV *, DBT *, DB_LSN *, ", - "db_recops, void *), size_t *));"); - p[2] = ""; - proto_format(p, PFILE); - - # Create the routine to call __db_add_recovery(print_fn, id) - printf("int\n%s_init_print(dbenv, dtabp, dtabsizep)\n", \ - prefix) >> PFILE; - printf("\tDB_ENV *dbenv;\n") >> PFILE;; - printf("\tint (***dtabp)__P((DB_ENV *, DBT *, DB_LSN *,") >> PFILE; - printf(" db_recops, void *));\n") >> PFILE; - printf("\tsize_t *dtabsizep;\n{\n") >> PFILE; - # If application-specific, the user will need a prototype for - # __db_add_recovery, since they won't have DB's. - if (!dbprivate) { - printf("\tint __db_add_recovery __P((DB_ENV *,\n") >> PFILE; - printf(\ -"\t int (***)(DB_ENV *, DBT *, DB_LSN *, db_recops, void *),\n") >> PFILE; - printf("\t size_t *,\n") >> PFILE; - printf(\ -"\t int (*)(DB_ENV *, DBT *, DB_LSN *, db_recops, void *), u_int32_t));\n") \ - >> PFILE; - } - - printf("\tint ret;\n\n") >> PFILE; - for (i = 0; i < num_funcs; i++) { - printf("\tif ((ret = __db_add_recovery(dbenv, ") >> PFILE; - printf("dtabp, dtabsizep,\n") >> PFILE; - printf("\t %s_print, DB_%s)) != 0)\n", \ - funcs[i], funcs[i]) >> PFILE; - printf("\t\treturn (ret);\n") >> PFILE; - } - printf("\treturn (0);\n}\n") >> PFILE; - if (prefix == "__ham") - printf("#endif /* HAVE_HASH */\n") >> PFILE - if (prefix == "__qam") - printf("#endif /* HAVE_QUEUE */\n") >> PFILE - - # We only want to generate *_init_recover functions if this is a - # DB-private, rather than application-specific, set of recovery - # functions. Application-specific recovery functions should be - # dispatched using the DB_ENV->set_app_dispatch callback rather - # than a DB dispatch table ("dtab"). - if (!dbprivate) - exit - - # Recover initialization routine - p[1] = sprintf("int %s_init_recover %s%s", prefix, - "__P((DB_ENV *, int (***)(DB_ENV *, DBT *, DB_LSN *, ", - "db_recops, void *), size_t *));"); - p[2] = ""; - proto_format(p, CFILE); - - # Create the routine to call db_add_recovery(func, id) - printf("int\n%s_init_recover(dbenv, dtabp, dtabsizep)\n", \ - prefix) >> CFILE; - printf("\tDB_ENV *dbenv;\n") >> CFILE; - printf("\tint (***dtabp)__P((DB_ENV *, DBT *, DB_LSN *,") >> CFILE; - printf(" db_recops, void *));\n") >> CFILE; - printf("\tsize_t *dtabsizep;\n{\n\tint ret;\n\n") >> CFILE; - for (i = 0; i < num_funcs; i++) { - printf("\tif ((ret = __db_add_recovery(dbenv, ") >> CFILE; - printf("dtabp, dtabsizep,\n") >> CFILE; - printf("\t %s_recover, DB_%s)) != 0)\n", \ - funcs[i], funcs[i]) >> CFILE; - printf("\t\treturn (ret);\n") >> CFILE; - } - printf("\treturn (0);\n}\n") >> CFILE; -} - -function log_function() -{ - # Write the log function; function prototype - pi = 1; - if (not_buf) { - p[pi++] = sprintf("int %s_log", funcname); - p[pi++] = " "; - if (has_dbp == 1) { - p[pi++] = "__P((DB *"; - } else { - p[pi++] = "__P((DB_ENV *"; - } - p[pi++] = ", DB_TXN *, DB_LSN *, u_int32_t"; - } else { - p[pi++] = sprintf("int %s_buf", funcname); - p[pi++] = " "; - p[pi++] = "__P((u_int8_t *, size_t, size_t *"; - } - for (i = 0; i < nvars; i++) { - if (modes[i] == "DB") - continue; - p[pi++] = ", "; - p[pi++] = sprintf("%s%s%s", - (modes[i] == "DBT" || modes[i] == "LOCKS" || - modes[i] == "PGDBT") ? "const " : "", types[i], - (modes[i] == "DBT" || modes[i] == "LOCKS" || - modes[i] == "PGDBT") ? " *" : ""); - } - p[pi++] = ""; - p[pi++] = "));"; - p[pi++] = ""; - proto_format(p, CFILE); - - # Function declaration - if (not_buf && has_dbp == 1) { - printf("int\n%s_log(dbp, txnid, ret_lsnp, flags", \ - funcname) >> CFILE; - } else if (not_buf) { - printf("int\n%s_log(dbenv, txnid, ret_lsnp, flags", \ - funcname) >> CFILE; - } else { - printf("int\n%s_buf(buf, max, lenp", funcname) >> CFILE; - } - for (i = 0; i < nvars; i++) { - if (modes[i] == "DB") { - # We pass in fileids on the dbp, so if this is one, - # skip it. - continue; - } - printf(",") >> CFILE; - if ((i % 6) == 0) - printf("\n ") >> CFILE; - else - printf(" ") >> CFILE; - printf("%s", vars[i]) >> CFILE; - } - printf(")\n") >> CFILE; - - # Now print the parameters - if (not_buf) { - if (has_dbp == 1) { - printf("\tDB *dbp;\n") >> CFILE; - } else { - printf("\tDB_ENV *dbenv;\n") >> CFILE; - } - printf("\tDB_TXN *txnid;\n\tDB_LSN *ret_lsnp;\n") >> CFILE; - printf("\tu_int32_t flags;\n") >> CFILE; - } else { - printf("\tu_int8_t *buf;\n") >> CFILE; - printf("\tsize_t max, *lenp;\n") >> CFILE; - } - for (i = 0; i < nvars; i++) { - # We just skip for modes == DB. - if (modes[i] == "DBT" || - modes[i] == "LOCKS" || modes[i] == "PGDBT") - printf("\tconst %s *%s;\n", types[i], vars[i]) >> CFILE; - else if (modes[i] != "DB") - printf("\t%s %s;\n", types[i], vars[i]) >> CFILE; - } - - # Function body and local decls - printf("{\n") >> CFILE; - if (not_buf) { - printf("\tDBT logrec;\n") >> CFILE; - if (has_dbp == 1) - printf("\tDB_ENV *dbenv;\n") >> CFILE; - if (dbprivate) - printf("\tDB_TXNLOGREC *lr;\n") >> CFILE; - printf("\tDB_LSN *lsnp, null_lsn, *rlsnp;\n") >> CFILE; - printf("\tu_int32_t ") >> CFILE; - if (is_dbt == 1) - printf("zero, ") >> CFILE; - if (is_uint == 1) - printf("uinttmp, ") >> CFILE; - printf("rectype, txn_num;\n") >> CFILE; - printf("\tu_int npad;\n") >> CFILE; - } else { - if (is_dbt == 1) - printf("\tu_int32_t zero;\n") >> CFILE; - if (is_uint == 1) - printf("\tu_int32_t uinttmp;\n") >> CFILE; - printf("\tu_int8_t *endbuf;\n") >> CFILE; - } - printf("\tu_int8_t *bp;\n") >> CFILE; - printf("\tint ") >> CFILE; - if (dbprivate && not_buf) { - printf("is_durable, ") >> CFILE; - } - printf("ret;\n\n") >> CFILE; - - # Initialization - if (not_buf) { - if (has_dbp == 1) - printf("\tdbenv = dbp->dbenv;\n") >> CFILE; - if (dbprivate) - printf("\tCOMPQUIET(lr, NULL);\n\n") >> CFILE; - printf("\trectype = DB_%s;\n", funcname) >> CFILE; - printf("\tnpad = 0;\n") >> CFILE; - printf("\trlsnp = ret_lsnp;\n\n") >> CFILE; - } - printf("\tret = 0;\n\n") >> CFILE; - - if (not_buf) { - if (dbprivate) { - printf("\tif (LF_ISSET(DB_LOG_NOT_DURABLE)") \ - >> CFILE; - if (has_dbp == 1) { - printf(" ||\n\t ") >> CFILE; - printf("F_ISSET(dbp, DB_AM_NOT_DURABLE)) {\n") \ - >> CFILE; - } else { - printf(") {\n") >> CFILE; - printf("\t\tif (txnid == NULL)\n") >> CFILE; - printf("\t\t\treturn (0);\n") >> CFILE; - } - printf("\t\tis_durable = 0;\n") >> CFILE; - printf("\t} else\n") >> CFILE; - printf("\t\tis_durable = 1;\n\n") >> CFILE; - } - printf("\tif (txnid == NULL) {\n") >> CFILE; - printf("\t\ttxn_num = 0;\n") >> CFILE; - printf("\t\tlsnp = &null_lsn;\n") >> CFILE; - printf("\t\tnull_lsn.file = null_lsn.offset = 0;\n") >> CFILE; - printf("\t} else {\n") >> CFILE; - if (dbprivate && funcname != "__db_debug") { - printf(\ - "\t\tif (TAILQ_FIRST(&txnid->kids) != NULL &&\n") >> CFILE; - printf("\t\t (ret = __txn_activekids(") >> CFILE; - printf("dbenv, rectype, txnid)) != 0)\n") >> CFILE; - printf("\t\t\treturn (ret);\n") >> CFILE; - } - printf("\t\t/*\n\t\t * We need to assign begin_lsn while ") \ - >> CFILE; - printf("holding region mutex.\n") >> CFILE; - printf("\t\t * That assignment is done inside the ") >> CFILE; - printf("DbEnv->log_put call,\n\t\t * ") >> CFILE; - printf("so pass in the appropriate memory location to be ") \ - >> CFILE; - printf("filled\n\t\t * in by the log_put code.\n\t\t */\n") \ - >> CFILE; - printf("\t\tDB_SET_TXN_LSNP(txnid, &rlsnp, &lsnp);\n") >> CFILE; - printf("\t\ttxn_num = txnid->txnid;\n") >> CFILE; - printf("\t}\n\n") >> CFILE; - - # If we're logging a DB handle, make sure we have a log - # file ID for it. - db_handle_id_function(modes, nvars); - - # Malloc - printf("\tlogrec.size = ") >> CFILE; - printf("sizeof(rectype) + ") >> CFILE; - printf("sizeof(txn_num) + sizeof(DB_LSN)") >> CFILE; - for (i = 0; i < nvars; i++) - printf("\n\t + %s", sizes[i]) >> CFILE; - printf(";\n") >> CFILE - if (dbprivate) { - printf("\tif (CRYPTO_ON(dbenv)) {\n") >> CFILE; - printf("\t\tnpad =\n") >> CFILE; - printf("\t\t ((DB_CIPHER *)dbenv->crypto_handle)") \ - >> CFILE; - printf("->adj_size(logrec.size);\n") >> CFILE; - printf("\t\tlogrec.size += npad;\n\t}\n\n") >> CFILE - - printf("\tif (is_durable || txnid == NULL) {\n") \ - >> CFILE; - printf("\t\tif ((ret =\n\t\t __os_malloc(dbenv, ") \ - >> CFILE; - printf("logrec.size, &logrec.data)) != 0)\n") >> CFILE; - printf("\t\t\treturn (ret);\n") >> CFILE; - printf("\t} else {\n") >> CFILE; - write_malloc("\t\t", - "lr", "logrec.size + sizeof(DB_TXNLOGREC)", CFILE) - printf("#ifdef DIAGNOSTIC\n") >> CFILE; - printf("\t\tif ((ret =\n\t\t __os_malloc(dbenv, ") \ - >> CFILE; - printf("logrec.size, &logrec.data)) != 0) {\n") \ - >> CFILE; - printf("\t\t\t__os_free(dbenv, lr);\n") >> CFILE; - printf("\t\t\treturn (ret);\n") >> CFILE; - printf("\t\t}\n") >> CFILE; - printf("#else\n") >> CFILE; - printf("\t\tlogrec.data = lr->data;\n") >> CFILE; - printf("#endif\n") >> CFILE; - printf("\t}\n") >> CFILE; - } else { - write_malloc("\t", "logrec.data", "logrec.size", CFILE) - printf("\tbp = logrec.data;\n\n") >> CFILE; - } - printf("\tif (npad > 0)\n") >> CFILE; - printf("\t\tmemset((u_int8_t *)logrec.data + logrec.size ") \ - >> CFILE; - printf("- npad, 0, npad);\n\n") >> CFILE; - printf("\tbp = logrec.data;\n\n") >> CFILE; - - # Copy args into buffer - printf("\tmemcpy(bp, &rectype, sizeof(rectype));\n") >> CFILE; - printf("\tbp += sizeof(rectype);\n\n") >> CFILE; - printf("\tmemcpy(bp, &txn_num, sizeof(txn_num));\n") >> CFILE; - printf("\tbp += sizeof(txn_num);\n\n") >> CFILE; - printf("\tmemcpy(bp, lsnp, sizeof(DB_LSN));\n") >> CFILE; - printf("\tbp += sizeof(DB_LSN);\n\n") >> CFILE; - } else { - # If we're logging a DB handle, make sure we have a log - # file ID for it. - db_handle_id_function(modes, nvars); - - printf("\tbp = buf;\n") >> CFILE; - printf("\tendbuf = bp + max;\n\n") >> CFILE - } - - for (i = 0; i < nvars; i++) { - if (modes[i] == "ARG" || modes[i] == "TIME") { - printf("\tuinttmp = (u_int32_t)%s;\n", \ - vars[i]) >> CFILE; - if (!not_buf) { - printf(\ - "\tif (bp + sizeof(uinttmp) > endbuf)\n") \ - >> CFILE; - printf("\t\treturn (ENOMEM);\n") >> CFILE; - } - printf("\tmemcpy(bp, &uinttmp, sizeof(uinttmp));\n") \ - >> CFILE; - printf("\tbp += sizeof(uinttmp);\n\n") >> CFILE; - } else if (modes[i] == "DBT" || \ - modes[i] == "LOCKS" || modes[i] == "PGDBT") { - printf("\tif (%s == NULL) {\n", vars[i]) >> CFILE; - printf("\t\tzero = 0;\n") >> CFILE; - if (!not_buf) { - printf(\ - "\t\tif (bp + sizeof(u_int32_t) > endbuf)\n") \ - >> CFILE; - printf("\t\t\treturn (ENOMEM);\n") >> CFILE; - } - printf("\t\tmemcpy(bp, &zero, sizeof(u_int32_t));\n") \ - >> CFILE; - printf("\t\tbp += sizeof(u_int32_t);\n") >> CFILE; - printf("\t} else {\n") >> CFILE; - if (!not_buf) { - printf(\ - "\t\tif (bp + sizeof(%s->size) > endbuf)\n", \ - vars[i]) >> CFILE; - printf("\t\t\treturn (ENOMEM);\n") >> CFILE; - } - printf("\t\tmemcpy(bp, &%s->size, ", vars[i]) >> CFILE; - printf("sizeof(%s->size));\n", vars[i]) >> CFILE; - printf("\t\tbp += sizeof(%s->size);\n", vars[i]) \ - >> CFILE; - if (!not_buf) { - printf("\t\tif (bp + %s->size > endbuf)\n", \ - vars[i]) >> CFILE; - printf("\t\t\treturn (ENOMEM);\n") >> CFILE; - } - printf("\t\tmemcpy(bp, %s->data, %s->size);\n", \ - vars[i], vars[i]) >> CFILE; - printf("\t\tbp += %s->size;\n\t}\n\n", \ - vars[i]) >> CFILE; - } else if (modes[i] == "DB") { - printf("\tuinttmp = ") >> CFILE; - printf("(u_int32_t)dbp->log_filename->id;\n") >> CFILE; - printf("\tmemcpy(bp, &uinttmp, sizeof(uinttmp));\n") \ - >> CFILE; - printf("\tbp += sizeof(uinttmp);\n\n") >> CFILE; - } else { # POINTER - if (!not_buf) { - printf("\tif (bp + %s > endbuf)\n", \ - sizes[i]) >> CFILE; - printf("\t\treturn (ENOMEM);\n") >> CFILE; - } - printf("\tif (%s != NULL)\n", vars[i]) >> CFILE; - printf("\t\tmemcpy(bp, %s, %s);\n", vars[i], \ - sizes[i]) >> CFILE; - printf("\telse\n") >> CFILE; - printf("\t\tmemset(bp, 0, %s);\n", sizes[i]) >> CFILE; - printf("\tbp += %s;\n\n", sizes[i]) >> CFILE; - } - } - - # Error checking. User code won't have DB_ASSERT available, but - # this is a pretty unlikely assertion anyway, so we just leave it out - # rather than requiring assert.h. - if (not_buf) { - if (dbprivate) { - printf("\tDB_ASSERT((u_int32_t)") >> CFILE; - printf("(bp - (u_int8_t *)logrec.data) ") >> CFILE; - printf("<= logrec.size);\n\n") >> CFILE; - # Save the log record off in the txn's linked list, - # or do log call. - # We didn't call the crypto alignment function when - # we created this log record (because we don't have - # the right header files to find the function), so - # we have to copy the log record to make sure the - # alignment is correct. - printf("\tif (is_durable || txnid == NULL) {\n") \ - >> CFILE; - # Output the log record and update the return LSN. - printf("\t\tif ((ret = __log_put(dbenv, rlsnp,") \ - >> CFILE; - printf("(DBT *)&logrec,\n") >> CFILE; - printf("\t\t flags | DB_LOG_NOCOPY)) == 0") >> CFILE; - printf(" && txnid != NULL) {\n") >> CFILE; - printf("\t\t\t*lsnp = *rlsnp;\n") >> CFILE; - - printf("\t\t\tif (rlsnp != ret_lsnp)\n") >> CFILE; - printf("\t\t\t\t *ret_lsnp = *rlsnp;\n") >> CFILE; - printf("\t\t}\n\t} else {\n") >> CFILE; - printf("#ifdef DIAGNOSTIC\n") >> CFILE; - - # Add the debug bit if we are logging a ND record. - printf("\t\t/*\n") >> CFILE; - printf("\t\t * Set the debug bit if we are") >> CFILE; - printf(" going to log non-durable\n") >> CFILE; - printf("\t\t * transactions so they will be ignored") \ - >> CFILE; - printf(" by recovery.\n") >> CFILE; - printf("\t\t */\n") >> CFILE; - printf("\t\tmemcpy(lr->data, logrec.data, ") >> CFILE - printf("logrec.size);\n") >> CFILE; - printf("\t\trectype |= DB_debug_FLAG;\n") >> CFILE; - printf("\t\tmemcpy(") >> CFILE - printf("logrec.data, &rectype, sizeof(rectype));\n\n") \ - >> CFILE; - # Output the log record. - printf("\t\tret = __log_put(dbenv,\n") >> CFILE; - printf("\t\t rlsnp, (DBT *)&logrec, ") >> CFILE; - printf("flags | DB_LOG_NOCOPY);\n") >> CFILE; - printf("#else\n") >> CFILE; - printf("\t\tret = 0;\n") >> CFILE; - printf("#endif\n") >> CFILE; - # Add a ND record to the txn list. - printf("\t\tSTAILQ_INSERT_HEAD(&txnid") >> CFILE; - printf("->logs, lr, links);\n") >> CFILE; - printf("\t\tF_SET((TXN_DETAIL *)") >> CFILE; - printf("txnid->td, TXN_DTL_INMEMORY);\n") >> CFILE; - # Update the return LSN. - printf("\t\tLSN_NOT_LOGGED(*ret_lsnp);\n") >> CFILE; - printf("\t}\n\n") >> CFILE; - } else { - printf("\tif ((ret = dbenv->log_put(dbenv, rlsnp,") >> CFILE; - printf(" (DBT *)&logrec,\n") >> CFILE; - printf("\t flags | DB_LOG_NOCOPY)) == 0") >> CFILE; - printf(" && txnid != NULL) {\n") >> CFILE; - - # Update the transactions last_lsn. - printf("\t\t*lsnp = *rlsnp;\n") >> CFILE; - printf("\t\tif (rlsnp != ret_lsnp)\n") >> CFILE; - printf("\t\t\t *ret_lsnp = *rlsnp;\n") >> CFILE; - printf("\t}\n") >> CFILE; - - } - # If out of disk space log writes may fail. If we are debugging - # that print out which records did not make it to disk. - printf("#ifdef LOG_DIAGNOSTIC\n") >> CFILE - printf("\tif (ret != 0)\n") >> CFILE; - printf("\t\t(void)%s_print(dbenv,\n", funcname) >> CFILE; - printf("\t\t (DBT *)&logrec, ret_lsnp, ") >> CFILE - printf("DB_TXN_PRINT, NULL);\n#endif\n\n") >> CFILE - # Free and return - if (dbprivate) { - printf("#ifdef DIAGNOSTIC\n") >> CFILE - write_free("\t", "logrec.data", CFILE) - printf("#else\n") >> CFILE - printf("\tif (is_durable || txnid == NULL)\n") >> CFILE; - write_free("\t\t", "logrec.data", CFILE) - printf("#endif\n") >> CFILE - } else { - write_free("\t", "logrec.data", CFILE) - } - } else { - printf("\t*lenp = (u_int32_t)(bp - buf);\n\n") >> CFILE - } - - printf("\treturn (ret);\n}\n\n") >> CFILE; -} - -# If we're logging a DB handle, make sure we have a log -# file ID for it. -function db_handle_id_function(modes, n) -{ - for (i = 0; i < n; i++) - if (modes[i] == "DB") { - # We actually log the DB handle's fileid; from - # that ID we're able to acquire an open handle - # at recovery time. - printf(\ - "\tDB_ASSERT(dbp->log_filename != NULL);\n") \ - >> CFILE; - printf("\tif (dbp->log_filename->id == ") \ - >> CFILE; - printf("DB_LOGFILEID_INVALID &&\n\t ") \ - >> CFILE - printf("(ret = __dbreg_lazy_id(dbp)) != 0)\n") \ - >> CFILE - printf("\t\treturn (ret);\n\n") >> CFILE; - break; - } -} - -function print_function() -{ - # Write the print function; function prototype - p[1] = sprintf("int %s_print", funcname); - p[2] = " "; - p[3] = "__P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *));"; - p[4] = ""; - proto_format(p, PFILE); - - # Function declaration - printf("int\n%s_print(dbenv, ", funcname) >> PFILE; - printf("dbtp, lsnp, notused2, notused3)\n") >> PFILE; - printf("\tDB_ENV *dbenv;\n") >> PFILE; - printf("\tDBT *dbtp;\n") >> PFILE; - printf("\tDB_LSN *lsnp;\n") >> PFILE; - printf("\tdb_recops notused2;\n\tvoid *notused3;\n{\n") >> PFILE; - - # Locals - printf("\t%s_args *argp;\n", funcname) >> PFILE; - for (i = 0; i < nvars; i ++) - if (modes[i] == "TIME") { - printf("\tstruct tm *lt;\n") >> PFILE - printf("\ttime_t timeval;\n") >> PFILE - break; - } - for (i = 0; i < nvars; i ++) - if (modes[i] == "DBT" || modes[i] == "PGDBT") { - printf("\tu_int32_t i;\n") >> PFILE - printf("\tint ch;\n") >> PFILE - break; - } - printf("\tint ret;\n\n") >> PFILE; - - # Get rid of complaints about unused parameters. - printf("\tnotused2 = DB_TXN_PRINT;\n\tnotused3 = NULL;\n\n") >> PFILE; - - # Call read routine to initialize structure - printf("\tif ((ret = %s_read(dbenv, dbtp->data, &argp)) != 0)\n", \ - funcname) >> PFILE; - printf("\t\treturn (ret);\n") >> PFILE; - - # Print values in every record - printf("\t(void)printf(\n\t \"[%%lu][%%lu]%s%%s: ",\ - funcname) >> PFILE; - printf("rec: %%lu txnid %%lx ") >> PFILE; - printf("prevlsn [%%lu][%%lu]\\n\",\n") >> PFILE; - printf("\t (u_long)lsnp->file,\n") >> PFILE; - printf("\t (u_long)lsnp->offset,\n") >> PFILE; - printf("\t (argp->type & DB_debug_FLAG) ? \"_debug\" : \"\",\n") \ - >> PFILE; - printf("\t (u_long)argp->type,\n") >> PFILE; - printf("\t (u_long)argp->txnid->txnid,\n") >> PFILE; - printf("\t (u_long)argp->prev_lsn.file,\n") >> PFILE; - printf("\t (u_long)argp->prev_lsn.offset);\n") >> PFILE; - - # Now print fields of argp - for (i = 0; i < nvars; i ++) { - if (modes[i] == "TIME") { - printf("\ttimeval = (time_t)argp->%s;\n", - vars[i]) >> PFILE; - printf("\tlt = localtime(&timeval);\n") >> PFILE; - printf("\t(void)printf(\n\t \"\\t%s: ", - vars[i]) >> PFILE; - } else - printf("\t(void)printf(\"\\t%s: ", vars[i]) >> PFILE; - - if (modes[i] == "DBT" || modes[i] == "PGDBT") { - printf("\");\n") >> PFILE; - printf("\tfor (i = 0; i < ") >> PFILE; - printf("argp->%s.size; i++) {\n", vars[i]) >> PFILE; - printf("\t\tch = ((u_int8_t *)argp->%s.data)[i];\n", \ - vars[i]) >> PFILE; - printf("\t\tprintf(isprint(ch) || ch == 0x0a") >> PFILE; - printf(" ? \"%%c\" : \"%%#x \", ch);\n") >> PFILE; - printf("\t}\n\t(void)printf(\"\\n\");\n") >> PFILE; - } else if (types[i] == "DB_LSN *") { - printf("[%%%s][%%%s]\\n\",\n", \ - formats[i], formats[i]) >> PFILE; - printf("\t (u_long)argp->%s.file,", \ - vars[i]) >> PFILE; - printf(" (u_long)argp->%s.offset);\n", \ - vars[i]) >> PFILE; - } else if (modes[i] == "TIME") { - # Time values are displayed in two ways: the standard - # string returned by ctime, and in the input format - # expected by db_recover -t. - printf(\ - "%%%s (%%.24s, 20%%02lu%%02lu%%02lu%%02lu%%02lu.%%02lu)\\n\",\n", \ - formats[i]) >> PFILE; - printf("\t (long)argp->%s, ", vars[i]) >> PFILE; - printf("ctime(&timeval),", vars[i]) >> PFILE; - printf("\n\t (u_long)lt->tm_year - 100, ") >> PFILE; - printf("(u_long)lt->tm_mon+1,") >> PFILE; - printf("\n\t (u_long)lt->tm_mday, ") >> PFILE; - printf("(u_long)lt->tm_hour,") >> PFILE; - printf("\n\t (u_long)lt->tm_min, ") >> PFILE; - printf("(u_long)lt->tm_sec);\n") >> PFILE; - } else if (modes[i] == "LOCKS") { - printf("\\n\");\n") >> PFILE; - printf("\t__lock_list_print(dbenv, &argp->locks);\n") \ - >> PFILE; - } else { - if (formats[i] == "lx") - printf("0x") >> PFILE; - printf("%%%s\\n\", ", formats[i]) >> PFILE; - if (formats[i] == "lx" || formats[i] == "lu") - printf("(u_long)") >> PFILE; - if (formats[i] == "ld") - printf("(long)") >> PFILE; - printf("argp->%s);\n", vars[i]) >> PFILE; - } - } - printf("\t(void)printf(\"\\n\");\n") >> PFILE; - write_free("\t", "argp", PFILE); - printf("\treturn (0);\n") >> PFILE; - printf("}\n\n") >> PFILE; -} - -function read_function() -{ - # Write the read function; function prototype - if (not_buf) - p[1] = sprintf("int %s_read __P((DB_ENV *, void *,", funcname); - else - p[1] = sprintf("int %s_read __P((DB_ENV *, void *, void **,", \ - funcname); - p[2] = " "; - p[3] = sprintf("%s_args **));", funcname); - p[4] = ""; - proto_format(p, CFILE); - - # Function declaration - if (not_buf) - printf("int\n%s_read(dbenv, recbuf, argpp)\n", funcname) \ - >> CFILE; - else - printf(\ - "int\n%s_read(dbenv, recbuf, nextp, argpp)\n", funcname) \ - >> CFILE; - - # Now print the parameters - printf("\tDB_ENV *dbenv;\n") >> CFILE; - printf("\tvoid *recbuf;\n") >> CFILE; - if (!not_buf) - printf("\tvoid **nextp;\n") >> CFILE; - printf("\t%s_args **argpp;\n", funcname) >> CFILE; - - # Function body and local decls - printf("{\n\t%s_args *argp;\n", funcname) >> CFILE; - if (is_uint == 1) - printf("\tu_int32_t uinttmp;\n") >> CFILE; - printf("\tu_int8_t *bp;\n") >> CFILE; - - - if (dbprivate) { - # We only use dbenv and ret in the private malloc case. - printf("\tint ret;\n\n") >> CFILE; - } else { - printf("\t/* Keep the compiler quiet. */\n") >> CFILE; - printf("\n\tdbenv = NULL;\n") >> CFILE; - } - - if (not_buf) { - malloc_size = sprintf("sizeof(%s_args) + sizeof(DB_TXN)", \ - funcname) - } else { - malloc_size = sprintf("sizeof(%s_args)", funcname) - } - write_malloc("\t", "argp", malloc_size, CFILE) - - # Set up the pointers to the txnid. - printf("\tbp = recbuf;\n") >> CFILE; - - if (not_buf) { - printf("\targp->txnid = (DB_TXN *)&argp[1];\n\n") >> CFILE; - - # First get the record type, prev_lsn, and txnid fields. - - printf("\tmemcpy(&argp->type, bp, sizeof(argp->type));\n") \ - >> CFILE; - printf("\tbp += sizeof(argp->type);\n\n") >> CFILE; - printf("\tmemcpy(&argp->txnid->txnid, bp, ") >> CFILE; - printf("sizeof(argp->txnid->txnid));\n") >> CFILE; - printf("\tbp += sizeof(argp->txnid->txnid);\n\n") >> CFILE; - printf("\tmemcpy(&argp->prev_lsn, bp, sizeof(DB_LSN));\n") \ - >> CFILE; - printf("\tbp += sizeof(DB_LSN);\n\n") >> CFILE; - } - - # Now get rest of data. - for (i = 0; i < nvars; i ++) { - if (modes[i] == "DBT" || \ - modes[i] == "LOCKS" || modes[i] == "PGDBT") { - printf("\tmemset(&argp->%s, 0, sizeof(argp->%s));\n", \ - vars[i], vars[i]) >> CFILE; - printf("\tmemcpy(&argp->%s.size, ", vars[i]) >> CFILE; - printf("bp, sizeof(u_int32_t));\n") >> CFILE; - printf("\tbp += sizeof(u_int32_t);\n") >> CFILE; - printf("\targp->%s.data = bp;\n", vars[i]) >> CFILE; - printf("\tbp += argp->%s.size;\n", vars[i]) >> CFILE; - } else if (modes[i] == "ARG" || modes[i] == "TIME" || - modes[i] == "DB") { - printf("\tmemcpy(&uinttmp, bp, sizeof(uinttmp));\n") \ - >> CFILE; - printf("\targp->%s = (%s)uinttmp;\n", vars[i], \ - types[i]) >> CFILE; - printf("\tbp += sizeof(uinttmp);\n") >> CFILE; - } else { # POINTER - printf("\tmemcpy(&argp->%s, bp, ", vars[i]) >> CFILE; - printf(" sizeof(argp->%s));\n", vars[i]) >> CFILE; - printf("\tbp += sizeof(argp->%s);\n", vars[i]) >> CFILE; - } - printf("\n") >> CFILE; - } - - # Free and return - if (!not_buf) - printf("\t*nextp = bp;\n") >> CFILE; - printf("\t*argpp = argp;\n") >> CFILE; - printf("\treturn (0);\n}\n\n") >> CFILE; -} - -# proto_format -- -# Pretty-print a function prototype. -function proto_format(p, fp) -{ - printf("/*\n") >> fp; - - s = ""; - for (i = 1; i in p; ++i) - s = s p[i]; - - t = " * PUBLIC: " - if (length(s) + length(t) < 80) - printf("%s%s", t, s) >> fp; - else { - split(s, p, "__P"); - len = length(t) + length(p[1]); - printf("%s%s", t, p[1]) >> fp - - n = split(p[2], comma, ","); - comma[1] = "__P" comma[1]; - for (i = 1; i <= n; i++) { - if (len + length(comma[i]) > 70) { - printf("\n * PUBLIC: ") >> fp; - len = 0; - } - printf("%s%s", comma[i], i == n ? "" : ",") >> fp; - len += length(comma[i]) + 2; - } - } - printf("\n */\n") >> fp; - delete p; -} - -function write_malloc(tab, ptr, size, file) -{ - if (dbprivate) { - print(tab "if ((ret = __os_malloc(dbenv,") >> file - print(tab " " size ", &" ptr ")) != 0)") >> file - print(tab "\treturn (ret);") >> file; - } else { - print(tab "if ((" ptr " = malloc(" size ")) == NULL)") >> file - print(tab "\treturn (ENOMEM);") >> file - } -} - -function write_free(tab, ptr, file) -{ - if (dbprivate) { - print(tab "__os_free(dbenv, " ptr ");") >> file - } else { - print(tab "free(" ptr ");") >> file - } -} diff --git a/storage/bdb/dist/gen_rpc.awk b/storage/bdb/dist/gen_rpc.awk deleted file mode 100644 index ac29648ea6a..00000000000 --- a/storage/bdb/dist/gen_rpc.awk +++ /dev/null @@ -1,1197 +0,0 @@ -# -# $Id: gen_rpc.awk,v 12.4 2005/07/21 18:21:20 bostic Exp $ -# Awk script for generating client/server RPC code. -# -# This awk script generates most of the RPC routines for DB client/server -# use. It also generates a template for server and client procedures. These -# functions must still be edited, but are highly stylized and the initial -# template gets you a fair way along the path). -# -# This awk script requires that these variables be set when it is called: -# -# major -- Major version number -# minor -- Minor version number -# xidsize -- size of GIDs -# client_file -- the C source file being created for client code -# ctmpl_file -- the C template file being created for client code -# server_file -- the C source file being created for server code -# stmpl_file -- the C template file being created for server code -# xdr_file -- the XDR message file created -# -# And stdin must be the input file that defines the RPC setup. -BEGIN { - if (major == "" || minor == "" || xidsize == "" || - client_file == "" || ctmpl_file == "" || - server_file == "" || stmpl_file == "" || xdr_file == "") { - print "Usage: gen_rpc.awk requires these variables be set:" - print "\tmajor\t-- Major version number" - print "\tminor\t-- Minor version number" - print "\txidsize\t-- GID size" - print "\tclient_file\t-- the client C source file being created" - print "\tctmpl_file\t-- the client template file being created" - print "\tserver_file\t-- the server C source file being created" - print "\tstmpl_file\t-- the server template file being created" - print "\txdr_file\t-- the XDR message file being created" - error = 1; exit - } - - FS="\t\t*" - CFILE=client_file - printf("/* Do not edit: automatically built by gen_rpc.awk. */\n") \ - > CFILE - - TFILE = ctmpl_file - printf("/* Do not edit: automatically built by gen_rpc.awk. */\n") \ - > TFILE - - SFILE = server_file - printf("/* Do not edit: automatically built by gen_rpc.awk. */\n") \ - > SFILE - - # Server procedure template. - PFILE = stmpl_file - XFILE = xdr_file - printf("/* Do not edit: automatically built by gen_rpc.awk. */\n") \ - > XFILE - nendlist = 1; - - # Output headers - general_headers() - - # Put out the actual illegal and no-server functions. - illegal_functions(CFILE) -} -END { - if (error == 0) { - printf("program DB_RPC_SERVERPROG {\n") >> XFILE - printf("\tversion DB_RPC_SERVERVERS {\n") >> XFILE - - for (i = 1; i < nendlist; ++i) - printf("\t\t%s;\n", endlist[i]) >> XFILE - - printf("\t} = %d%03d;\n", major, minor) >> XFILE - printf("} = 351457;\n") >> XFILE - - obj_init("DB", "dbp", obj_db, CFILE) - obj_init("DBC", "dbc", obj_dbc, CFILE) - obj_init("DB_ENV", "dbenv", obj_dbenv, CFILE) - obj_init("DB_TXN", "txn", obj_txn, CFILE) - } -} - -/^[ ]*LOCAL/ { - # LOCAL methods are ones where we don't override the handle - # method for RPC, nor is it illegal -- it's just satisfied - # locally. - next; -} -/^[ ]*NOFUNC/ { - ++obj_indx; - - # NOFUNC methods are illegal on the RPC client. - if ($2 ~ "^db_") - obj_illegal(obj_db, "dbp", $2, $3) - else if ($2 ~ "^dbc_") - obj_illegal(obj_dbc, "dbc", $2, $3) - else if ($2 ~ "^env_") - obj_illegal(obj_dbenv, "dbenv", $2, $3) - else if ($2 ~ "^txn_") - obj_illegal(obj_txn, "txn", $2, $3) - else { - print "unexpected handle prefix: " $2 - error = 1; exit - } - next; -} -/^[ ]*BEGIN/ { - ++obj_indx; - - name = $2; - link_only = ret_code = 0 - if ($3 == "LINKONLY") - link_only = 1 - else if ($3 == "RETCODE") - ret_code = 1 - - funcvars = 0; - newvars = 0; - nvars = 0; - rvars = 0; - xdr_free = 0; - - db_handle = 0; - dbc_handle = 0; - dbt_handle = 0; - env_handle = 0; - mp_handle = 0; - txn_handle = 0; -} -/^[ ]*ARG/ { - rpc_type[nvars] = $2; - c_type[nvars] = $3; - pr_type[nvars] = $3; - args[nvars] = $4; - func_arg[nvars] = 0; - if (rpc_type[nvars] == "LIST") { - list_type[nvars] = $5; - } else - list_type[nvars] = 0; - - if (c_type[nvars] == "DBT *") - dbt_handle = 1; - else if (c_type[nvars] == "DB_ENV *") { - ctp_type[nvars] = "CT_ENV"; - env_handle = 1; - env_idx = nvars; - - if (nvars == 0) - obj_func("dbenv", obj_dbenv); - } else if (c_type[nvars] == "DB *") { - ctp_type[nvars] = "CT_DB"; - if (db_handle != 1) { - db_handle = 1; - db_idx = nvars; - } - - if (nvars == 0) - obj_func("dbp", obj_db); - } else if (c_type[nvars] == "DBC *") { - ctp_type[nvars] = "CT_CURSOR"; - dbc_handle = 1; - dbc_idx = nvars; - - if (nvars == 0) - obj_func("dbc", obj_dbc); - } else if (c_type[nvars] == "DB_TXN *") { - ctp_type[nvars] = "CT_TXN"; - txn_handle = 1; - txn_idx = nvars; - - if (nvars == 0) - obj_func("txn", obj_txn); - } - - ++nvars; -} -/^[ ]*FUNCPROT/ { - pr_type[nvars] = $2; -} -/^[ ]*FUNCARG/ { - rpc_type[nvars] = "IGNORE"; - c_type[nvars] = $2; - args[nvars] = sprintf("func%d", funcvars); - func_arg[nvars] = 1; - ++funcvars; - ++nvars; -} -/^[ ]*RET/ { - ret_type[rvars] = $2; - retc_type[rvars] = $3; - retargs[rvars] = $4; - if (ret_type[rvars] == "LIST" || ret_type[rvars] == "DBT") { - xdr_free = 1; - } - if (ret_type[rvars] == "LIST") { - retlist_type[rvars] = $5; - } else - retlist_type[rvars] = 0; - ret_isarg[rvars] = 0; - - ++rvars; -} -/^[ ]*ARET/ { - ret_type[rvars] = $2; - rpc_type[nvars] = "IGNORE"; - retc_type[rvars] = $3; - c_type[nvars] = sprintf("%s *", $3); - pr_type[nvars] = c_type[nvars]; - retargs[rvars] = $4; - args[nvars] = sprintf("%sp", $4); - if (ret_type[rvars] == "LIST" || ret_type[rvars] == "DBT") { - xdr_free = 1; - } - func_arg[nvars] = 0; - if (ret_type[nvars] == "LIST") { - retlist_type[rvars] = $5; - list_type[nvars] = $5; - } else { - retlist_type[rvars] = 0; - list_type[nvars] = 0; - } - ret_isarg[rvars] = 1; - - ++nvars; - ++rvars; -} -/^[ ]*END/ { - # - # ===================================================== - # LINKONLY -- just reference the function, that's all. - # - if (link_only) - next; - - # - # ===================================================== - # XDR messages. - # - printf("\n") >> XFILE - printf("struct __%s_msg {\n", name) >> XFILE - for (i = 0; i < nvars; ++i) { - if (rpc_type[i] == "LIST") { - if (list_type[i] == "GID") { - printf("\topaque %s<>;\n", args[i]) >> XFILE - } else { - printf("\tunsigned int %s<>;\n", args[i]) >> XFILE - } - } - if (rpc_type[i] == "ID") { - printf("\tunsigned int %scl_id;\n", args[i]) >> XFILE - } - if (rpc_type[i] == "STRING") { - printf("\tstring %s<>;\n", args[i]) >> XFILE - } - if (rpc_type[i] == "GID") { - printf("\topaque %s[%d];\n", args[i], xidsize) >> XFILE - } - if (rpc_type[i] == "INT") { - printf("\tunsigned int %s;\n", args[i]) >> XFILE - } - if (rpc_type[i] == "DBT") { - printf("\tunsigned int %sdlen;\n", args[i]) >> XFILE - printf("\tunsigned int %sdoff;\n", args[i]) >> XFILE - printf("\tunsigned int %sulen;\n", args[i]) >> XFILE - printf("\tunsigned int %sflags;\n", args[i]) >> XFILE - printf("\topaque %sdata<>;\n", args[i]) >> XFILE - } - } - printf("};\n") >> XFILE - - printf("\n") >> XFILE - # - # Generate the reply message - # - printf("struct __%s_reply {\n", name) >> XFILE - printf("\t/* num return vars: %d */\n", rvars) >> XFILE - printf("\tint status;\n") >> XFILE - for (i = 0; i < rvars; ++i) { - if (ret_type[i] == "ID") { - printf("\tunsigned int %scl_id;\n", retargs[i]) >> XFILE - } - if (ret_type[i] == "STRING") { - printf("\tstring %s<>;\n", retargs[i]) >> XFILE - } - if (ret_type[i] == "INT") { - printf("\tunsigned int %s;\n", retargs[i]) >> XFILE - } - if (ret_type[i] == "DBL") { - printf("\tdouble %s;\n", retargs[i]) >> XFILE - } - if (ret_type[i] == "DBT") { - printf("\topaque %sdata<>;\n", retargs[i]) >> XFILE - } - if (ret_type[i] == "LIST") { - if (retlist_type[i] == "GID") { - printf("\topaque %s<>;\n", retargs[i]) >> XFILE - } else { - printf("\tunsigned int %s<>;\n", retargs[i]) >> XFILE - } - } - } - printf("};\n") >> XFILE - - endlist[nendlist] = \ - sprintf("__%s_reply __DB_%s(__%s_msg) = %d", \ - name, name, name, nendlist); - nendlist++; - # - # ===================================================== - # Server functions. - # - # First spit out PUBLIC prototypes for server functions. - # - printf("__%s_reply *\n", name) >> SFILE - printf("__db_%s_%d%03d__SVCSUFFIX__(msg, req)\n", \ - name, major, minor) >> SFILE - printf("\t__%s_msg *msg;\n", name) >> SFILE; - printf("\tstruct svc_req *req;\n", name) >> SFILE; - printf("{\n") >> SFILE - printf("\tstatic __%s_reply reply; /* must be static */\n", \ - name) >> SFILE - if (xdr_free) { - printf("\tstatic int __%s_free = 0; /* must be static */\n\n", \ - name) >> SFILE - } - printf("\tCOMPQUIET(req, NULL);\n", name) >> SFILE - if (xdr_free) { - printf("\tif (__%s_free)\n", name) >> SFILE - printf("\t\txdr_free((xdrproc_t)xdr___%s_reply, (void *)&reply);\n", \ - name) >> SFILE - printf("\t__%s_free = 0;\n", name) >> SFILE - printf("\n\t/* Reinitialize allocated fields */\n") >> SFILE - for (i = 0; i < rvars; ++i) { - if (ret_type[i] == "LIST") { - printf("\treply.%s.%s_val = NULL;\n", \ - retargs[i], retargs[i]) >> SFILE - } - if (ret_type[i] == "DBT") { - printf("\treply.%sdata.%sdata_val = NULL;\n", \ - retargs[i], retargs[i]) >> SFILE - } - } - } - - need_out = 0; - # - # Compose server proc to call. Decompose message components as args. - # - printf("\n\t__%s_proc(", name) >> SFILE - sep = ""; - for (i = 0; i < nvars; ++i) { - if (rpc_type[i] == "IGNORE") { - continue; - } - if (rpc_type[i] == "ID") { - printf("%smsg->%scl_id", sep, args[i]) >> SFILE - } - if (rpc_type[i] == "STRING") { - printf("%s(*msg->%s == '\\0') ? NULL : msg->%s", \ - sep, args[i], args[i]) >> SFILE - } - if (rpc_type[i] == "GID") { - printf("%s(u_int8_t *)msg->%s", sep, args[i]) >> SFILE - } - if (rpc_type[i] == "INT") { - printf("%smsg->%s", sep, args[i]) >> SFILE - } - if (rpc_type[i] == "LIST") { - printf("%smsg->%s.%s_val", \ - sep, args[i], args[i]) >> SFILE - printf("%smsg->%s.%s_len", \ - sep, args[i], args[i]) >> SFILE - } - if (rpc_type[i] == "DBT") { - printf("%smsg->%sdlen", sep, args[i]) >> SFILE - sep = ",\n\t "; - printf("%smsg->%sdoff", sep, args[i]) >> SFILE - printf("%smsg->%sulen", sep, args[i]) >> SFILE - printf("%smsg->%sflags", sep, args[i]) >> SFILE - printf("%smsg->%sdata.%sdata_val", \ - sep, args[i], args[i]) >> SFILE - printf("%smsg->%sdata.%sdata_len", \ - sep, args[i], args[i]) >> SFILE - } - sep = ",\n\t "; - } - printf("%s&reply", sep) >> SFILE - if (xdr_free) - printf("%s&__%s_free);\n", sep, name) >> SFILE - else - printf(");\n\n") >> SFILE - if (need_out) { - printf("\nout:\n") >> SFILE - } - printf("\treturn (&reply);\n") >> SFILE - printf("}\n\n") >> SFILE - - # - # ===================================================== - # Generate Procedure Template Server code - # - # Spit out comment, prototype, function name and arg list. - printf("/* BEGIN __%s_proc */\n", name) >> PFILE - delete p; - pi = 1; - p[pi++] = sprintf("void __%s_proc __P((", name); - p[pi++] = ""; - for (i = 0; i < nvars; ++i) { - if (rpc_type[i] == "IGNORE") - continue; - if (rpc_type[i] == "ID") { - p[pi++] = "long"; - p[pi++] = ", "; - } - if (rpc_type[i] == "STRING") { - p[pi++] = "char *"; - p[pi++] = ", "; - } - if (rpc_type[i] == "GID") { - p[pi++] = "u_int8_t *"; - p[pi++] = ", "; - } - if (rpc_type[i] == "INT") { - p[pi++] = "u_int32_t"; - p[pi++] = ", "; - } - if (rpc_type[i] == "INTRET") { - p[pi++] = "u_int32_t *"; - p[pi++] = ", "; - } - if (rpc_type[i] == "LIST" && list_type[i] == "GID") { - p[pi++] = "u_int8_t *"; - p[pi++] = ", "; - p[pi++] = "u_int32_t"; - p[pi++] = ", "; - } - if (rpc_type[i] == "LIST" && list_type[i] == "INT") { - p[pi++] = "u_int32_t *"; - p[pi++] = ", "; - p[pi++] = "u_int32_t"; - p[pi++] = ", "; - } - if (rpc_type[i] == "LIST" && list_type[i] == "ID") { - p[pi++] = "u_int32_t *"; - p[pi++] = ", "; - p[pi++] = "u_int32_t"; - p[pi++] = ", "; - } - if (rpc_type[i] == "DBT") { - p[pi++] = "u_int32_t"; - p[pi++] = ", "; - p[pi++] = "u_int32_t"; - p[pi++] = ", "; - p[pi++] = "u_int32_t"; - p[pi++] = ", "; - p[pi++] = "u_int32_t"; - p[pi++] = ", "; - p[pi++] = "void *"; - p[pi++] = ", "; - p[pi++] = "u_int32_t"; - p[pi++] = ", "; - } - } - p[pi++] = sprintf("__%s_reply *", name); - if (xdr_free) { - p[pi++] = ", "; - p[pi++] = "int *));"; - } else { - p[pi++] = ""; - p[pi++] = "));"; - } - p[pi++] = ""; - - printf("void\n") >> PFILE - printf("__%s_proc(", name) >> PFILE - sep = ""; - argcount = 0; - for (i = 0; i < nvars; ++i) { - argcount++; - split_lines(); - if (argcount == 0) { - sep = ""; - } - if (rpc_type[i] == "IGNORE") - continue; - if (rpc_type[i] == "ID") { - printf("%s%scl_id", sep, args[i]) >> PFILE - } - if (rpc_type[i] == "STRING") { - printf("%s%s", sep, args[i]) >> PFILE - } - if (rpc_type[i] == "GID") { - printf("%s%s", sep, args[i]) >> PFILE - } - if (rpc_type[i] == "INT") { - printf("%s%s", sep, args[i]) >> PFILE - } - if (rpc_type[i] == "INTRET") { - printf("%s%s", sep, args[i]) >> PFILE - } - if (rpc_type[i] == "LIST") { - printf("%s%s", sep, args[i]) >> PFILE - argcount++; - split_lines(); - if (argcount == 0) { - sep = ""; - } else { - sep = ", "; - } - printf("%s%slen", sep, args[i]) >> PFILE - } - if (rpc_type[i] == "DBT") { - printf("%s%sdlen", sep, args[i]) >> PFILE - sep = ", "; - argcount++; - split_lines(); - if (argcount == 0) { - sep = ""; - } else { - sep = ", "; - } - printf("%s%sdoff", sep, args[i]) >> PFILE - argcount++; - split_lines(); - if (argcount == 0) { - sep = ""; - } else { - sep = ", "; - } - printf("%s%sulen", sep, args[i]) >> PFILE - argcount++; - split_lines(); - if (argcount == 0) { - sep = ""; - } else { - sep = ", "; - } - printf("%s%sflags", sep, args[i]) >> PFILE - argcount++; - split_lines(); - if (argcount == 0) { - sep = ""; - } else { - sep = ", "; - } - printf("%s%sdata", sep, args[i]) >> PFILE - argcount++; - split_lines(); - if (argcount == 0) { - sep = ""; - } else { - sep = ", "; - } - printf("%s%ssize", sep, args[i]) >> PFILE - } - sep = ", "; - } - printf("%sreplyp",sep) >> PFILE - if (xdr_free) { - printf("%sfreep)\n",sep) >> PFILE - } else { - printf(")\n") >> PFILE - } - # - # Spit out arg types/names; - # - for (i = 0; i < nvars; ++i) { - if (rpc_type[i] == "ID") { - printf("\tunsigned int %scl_id;\n", args[i]) >> PFILE - } - if (rpc_type[i] == "STRING") { - printf("\tchar *%s;\n", args[i]) >> PFILE - } - if (rpc_type[i] == "GID") { - printf("\tu_int8_t *%s;\n", args[i]) >> PFILE - } - if (rpc_type[i] == "INT") { - printf("\tu_int32_t %s;\n", args[i]) >> PFILE - } - if (rpc_type[i] == "LIST" && list_type[i] == "GID") { - printf("\tu_int8_t * %s;\n", args[i]) >> PFILE - } - if (rpc_type[i] == "LIST" && list_type[i] == "INT") { - printf("\tu_int32_t * %s;\n", args[i]) >> PFILE - printf("\tu_int32_t %ssize;\n", args[i]) >> PFILE - } - if (rpc_type[i] == "LIST" && list_type[i] == "ID") { - printf("\tu_int32_t * %s;\n", args[i]) >> PFILE - } - if (rpc_type[i] == "LIST") { - printf("\tu_int32_t %slen;\n", args[i]) >> PFILE - } - if (rpc_type[i] == "DBT") { - printf("\tu_int32_t %sdlen;\n", args[i]) >> PFILE - printf("\tu_int32_t %sdoff;\n", args[i]) >> PFILE - printf("\tu_int32_t %sulen;\n", args[i]) >> PFILE - printf("\tu_int32_t %sflags;\n", args[i]) >> PFILE - printf("\tvoid *%sdata;\n", args[i]) >> PFILE - printf("\tu_int32_t %ssize;\n", args[i]) >> PFILE - } - } - printf("\t__%s_reply *replyp;\n",name) >> PFILE - if (xdr_free) { - printf("\tint * freep;\n") >> PFILE - } - - printf("/* END __%s_proc */\n", name) >> PFILE - - # - # Function body - # - printf("{\n") >> PFILE - printf("\tint ret;\n") >> PFILE - for (i = 0; i < nvars; ++i) { - if (rpc_type[i] == "ID") { - printf("\t%s %s;\n", c_type[i], args[i]) >> PFILE - printf("\tct_entry *%s_ctp;\n", args[i]) >> PFILE - } - } - printf("\n") >> PFILE - for (i = 0; i < nvars; ++i) { - if (rpc_type[i] == "ID") { - printf("\tACTIVATE_CTP(%s_ctp, %scl_id, %s);\n", \ - args[i], args[i], ctp_type[i]) >> PFILE - printf("\t%s = (%s)%s_ctp->ct_anyp;\n", \ - args[i], c_type[i], args[i]) >> PFILE - } - } - printf("\n\t/*\n\t * XXX Code goes here\n\t */\n\n") >> PFILE - printf("\treplyp->status = ret;\n") >> PFILE - printf("\treturn;\n") >> PFILE - printf("}\n\n") >> PFILE - - # - # ===================================================== - # Generate Client code - # - # Spit out PUBLIC prototypes. - # - delete p; - pi = 1; - p[pi++] = sprintf("int __dbcl_%s __P((", name); - p[pi++] = ""; - for (i = 0; i < nvars; ++i) { - p[pi++] = pr_type[i]; - p[pi++] = ", "; - } - p[pi - 1] = ""; - p[pi] = "));"; - proto_format(p, CFILE); - - # - # Spit out function name/args. - # - printf("int\n") >> CFILE - printf("__dbcl_%s(", name) >> CFILE - sep = ""; - for (i = 0; i < nvars; ++i) { - printf("%s%s", sep, args[i]) >> CFILE - sep = ", "; - } - printf(")\n") >> CFILE - - for (i = 0; i < nvars; ++i) - if (func_arg[i] == 0) - printf("\t%s %s;\n", c_type[i], args[i]) >> CFILE - else - printf("\t%s;\n", c_type[i]) >> CFILE - - printf("{\n") >> CFILE - printf("\tCLIENT *cl;\n") >> CFILE - printf("\t__%s_msg msg;\n", name) >> CFILE - printf("\t__%s_reply *replyp = NULL;\n", name) >> CFILE; - printf("\tint ret;\n") >> CFILE - if (!env_handle) - printf("\tDB_ENV *dbenv;\n") >> CFILE - # - # If we are managing a list, we need a few more vars. - # - for (i = 0; i < nvars; ++i) { - if (rpc_type[i] == "LIST") { - printf("\t%s %sp;\n", c_type[i], args[i]) >> CFILE - printf("\tint %si;\n", args[i]) >> CFILE - if (list_type[i] == "GID") - printf("\tu_int8_t ** %sq;\n", args[i]) >> CFILE - else - printf("\tu_int32_t * %sq;\n", args[i]) >> CFILE - } - } - - printf("\n") >> CFILE - printf("\tret = 0;\n") >> CFILE - if (!env_handle) { - if (db_handle) - printf("\tdbenv = %s->dbenv;\n", args[db_idx]) >> CFILE - else if (dbc_handle) - printf("\tdbenv = %s->dbp->dbenv;\n", \ - args[dbc_idx]) >> CFILE - else if (txn_handle) - printf("\tdbenv = %s->mgrp->dbenv;\n", \ - args[txn_idx]) >> CFILE - else - printf("\tdbenv = NULL;\n") >> CFILE - printf("\tif (dbenv == NULL || !RPC_ON(dbenv))\n") >> CFILE - printf("\t\treturn (__dbcl_noserver(NULL));\n") >> CFILE - } else { - printf("\tif (%s == NULL || !RPC_ON(%s))\n", \ - args[env_idx], args[env_idx]) >> CFILE - printf("\t\treturn (__dbcl_noserver(%s));\n", \ - args[env_idx]) >> CFILE - } - printf("\n") >> CFILE - - printf("\tcl = (CLIENT *)%s->cl_handle;\n\n", \ - env_handle ? args[env_idx] : "dbenv") >> CFILE - - # - # If there is a function arg, check that it is NULL - # - for (i = 0; i < nvars; ++i) { - if (func_arg[i] != 1) - continue; - printf("\tif (%s != NULL) {\n", args[i]) >> CFILE - if (!env_handle) { - printf("\t\t__db_err(dbenv, ") >> CFILE - } else { - printf("\t\t__db_err(%s, ", args[env_idx]) >> CFILE - } - printf("\"User functions not supported in RPC\");\n") >> CFILE - printf("\t\treturn (EINVAL);\n\t}\n") >> CFILE - } - - # - # Compose message components - # - for (i = 0; i < nvars; ++i) { - if (rpc_type[i] == "ID") { - # We don't need to check for a NULL DB_ENV *, because - # we already checked for it. I frankly couldn't care - # less, but lint gets all upset at the wasted cycles. - if (c_type[i] != "DB_ENV *") { - printf("\tif (%s == NULL)\n", args[i]) >> CFILE - printf("\t\tmsg.%scl_id = 0;\n\telse\n", \ - args[i]) >> CFILE - indent = "\t\t"; - } else - indent = "\t"; - if (c_type[i] == "DB_TXN *") { - printf("%smsg.%scl_id = %s->txnid;\n", \ - indent, args[i], args[i]) >> CFILE - } else { - printf("%smsg.%scl_id = %s->cl_id;\n", \ - indent, args[i], args[i]) >> CFILE - } - } - if (rpc_type[i] == "GID") { - printf("\tmemcpy(msg.%s, %s, %d);\n", \ - args[i], args[i], xidsize) >> CFILE - } - if (rpc_type[i] == "INT") { - printf("\tmsg.%s = %s;\n", args[i], args[i]) >> CFILE - } - if (rpc_type[i] == "STRING") { - printf("\tif (%s == NULL)\n", args[i]) >> CFILE - printf("\t\tmsg.%s = \"\";\n", args[i]) >> CFILE - printf("\telse\n") >> CFILE - printf("\t\tmsg.%s = (char *)%s;\n", \ - args[i], args[i]) >> CFILE - } - if (rpc_type[i] == "DBT") { - printf("\tmsg.%sdlen = %s->dlen;\n", \ - args[i], args[i]) >> CFILE - printf("\tmsg.%sdoff = %s->doff;\n", \ - args[i], args[i]) >> CFILE - printf("\tmsg.%sulen = %s->ulen;\n", \ - args[i], args[i]) >> CFILE - printf("\tmsg.%sflags = %s->flags;\n", \ - args[i], args[i]) >> CFILE - printf("\tmsg.%sdata.%sdata_val = %s->data;\n", \ - args[i], args[i], args[i]) >> CFILE - printf("\tmsg.%sdata.%sdata_len = %s->size;\n", \ - args[i], args[i], args[i]) >> CFILE - } - if (rpc_type[i] == "LIST") { - printf("\tfor (%si = 0, %sp = %s; *%sp != 0; ", \ - args[i], args[i], args[i], args[i]) >> CFILE - printf(" %si++, %sp++)\n\t\t;\n", args[i], args[i]) \ - >> CFILE - - # - # If we are an array of ints, *_len is how many - # elements. If we are a GID, *_len is total bytes. - # - printf("\tmsg.%s.%s_len = %si",args[i], args[i], \ - args[i]) >> CFILE - if (list_type[i] == "GID") - printf(" * %d;\n", xidsize) >> CFILE - else - printf(";\n") >> CFILE - printf("\tif ((ret = __os_calloc(") >> CFILE - if (!env_handle) - printf("dbenv,\n") >> CFILE - else - printf("%s,\n", args[env_idx]) >> CFILE - printf("\t msg.%s.%s_len,", \ - args[i], args[i]) >> CFILE - if (list_type[i] == "GID") - printf(" 1,") >> CFILE - else - printf(" sizeof(u_int32_t),") >> CFILE - printf(" &msg.%s.%s_val)) != 0)\n",\ - args[i], args[i], args[i], args[i]) >> CFILE - printf("\t\treturn (ret);\n") >> CFILE - printf("\tfor (%sq = msg.%s.%s_val, %sp = %s; ", \ - args[i], args[i], args[i], \ - args[i], args[i]) >> CFILE - printf("%si--; %sq++, %sp++)\n", \ - args[i], args[i], args[i]) >> CFILE - printf("\t\t*%sq = ", args[i]) >> CFILE - if (list_type[i] == "GID") - printf("*%sp;\n", args[i]) >> CFILE - if (list_type[i] == "ID") - printf("(*%sp)->cl_id;\n", args[i]) >> CFILE - if (list_type[i] == "INT") - printf("*%sp;\n", args[i]) >> CFILE - } - } - - printf("\n") >> CFILE - printf("\treplyp = __db_%s_%d%03d(&msg, cl);\n", name, major, minor) \ - >> CFILE - for (i = 0; i < nvars; ++i) { - if (rpc_type[i] == "LIST") { - printf("\t__os_free(") >> CFILE - if (!env_handle) - printf("dbenv, ") >> CFILE - else - printf("%s, ", args[env_idx]) >> CFILE - printf("msg.%s.%s_val);\n", args[i], args[i]) >> CFILE - } - } - printf("\tif (replyp == NULL) {\n") >> CFILE - if (!env_handle) { - printf("\t\t__db_err(dbenv, ") >> CFILE - printf("clnt_sperror(cl, \"Berkeley DB\"));\n") >> CFILE - } else { - printf("\t\t__db_err(%s, ", args[env_idx]) >> CFILE - printf("clnt_sperror(cl, \"Berkeley DB\"));\n") >> CFILE - } - printf("\t\tret = DB_NOSERVER;\n") >> CFILE - printf("\t\tgoto out;\n") >> CFILE - printf("\t}\n") >> CFILE - - if (ret_code == 0) { - printf("\tret = replyp->status;\n") >> CFILE - - # - # Set any arguments that are returned - # - for (i = 0; i < rvars; ++i) { - if (ret_isarg[i]) { - printf("\tif (%sp != NULL)\n", \ - retargs[i]) >> CFILE; - printf("\t\t*%sp = replyp->%s;\n", \ - retargs[i], retargs[i]) >> CFILE; - } - } - } else { - printf("\tret = __dbcl_%s_ret(", name) >> CFILE - sep = ""; - for (i = 0; i < nvars; ++i) { - printf("%s%s", sep, args[i]) >> CFILE - sep = ", "; - } - printf("%sreplyp);\n", sep) >> CFILE - } - printf("out:\n") >> CFILE - # - # Free reply if there was one. - # - printf("\tif (replyp != NULL)\n") >> CFILE - printf("\t\txdr_free((xdrproc_t)xdr___%s_reply,",name) >> CFILE - printf(" (void *)replyp);\n") >> CFILE - printf("\treturn (ret);\n") >> CFILE - printf("}\n\n") >> CFILE - - # - # Generate Client Template code - # - if (ret_code) { - # - # If we are doing a list, write prototypes - # - delete p; - pi = 1; - p[pi++] = sprintf("int __dbcl_%s_ret __P((", name); - p[pi++] = ""; - for (i = 0; i < nvars; ++i) { - p[pi++] = pr_type[i]; - p[pi++] = ", "; - } - p[pi] = sprintf("__%s_reply *));", name); - proto_format(p, TFILE); - - printf("int\n") >> TFILE - printf("__dbcl_%s_ret(", name) >> TFILE - sep = ""; - for (i = 0; i < nvars; ++i) { - printf("%s%s", sep, args[i]) >> TFILE - sep = ", "; - } - printf("%sreplyp)\n",sep) >> TFILE - - for (i = 0; i < nvars; ++i) - if (func_arg[i] == 0) - printf("\t%s %s;\n", c_type[i], args[i]) \ - >> TFILE - else - printf("\t%s;\n", c_type[i]) >> TFILE - printf("\t__%s_reply *replyp;\n", name) >> TFILE; - printf("{\n") >> TFILE - printf("\tint ret;\n") >> TFILE - # - # Local vars in template - # - for (i = 0; i < rvars; ++i) { - if (ret_type[i] == "ID" || ret_type[i] == "STRING" || - ret_type[i] == "INT" || ret_type[i] == "DBL") { - printf("\t%s %s;\n", \ - retc_type[i], retargs[i]) >> TFILE - } else if (ret_type[i] == "LIST") { - if (retlist_type[i] == "GID") - printf("\tu_int8_t *__db_%s;\n", \ - retargs[i]) >> TFILE - if (retlist_type[i] == "ID" || - retlist_type[i] == "INT") - printf("\tu_int32_t *__db_%s;\n", \ - retargs[i]) >> TFILE - } else { - printf("\t/* %s %s; */\n", \ - ret_type[i], retargs[i]) >> TFILE - } - } - # - # Client return code - # - printf("\n") >> TFILE - printf("\tif (replyp->status != 0)\n") >> TFILE - printf("\t\treturn (replyp->status);\n") >> TFILE - for (i = 0; i < rvars; ++i) { - varname = ""; - if (ret_type[i] == "ID") { - varname = sprintf("%scl_id", retargs[i]); - } - if (ret_type[i] == "STRING") { - varname = retargs[i]; - } - if (ret_type[i] == "INT" || ret_type[i] == "DBL") { - varname = retargs[i]; - } - if (ret_type[i] == "DBT") { - varname = sprintf("%sdata", retargs[i]); - } - if (ret_type[i] == "ID" || ret_type[i] == "STRING" || - ret_type[i] == "INT" || ret_type[i] == "DBL") { - printf("\t%s = replyp->%s;\n", \ - retargs[i], varname) >> TFILE - } else if (ret_type[i] == "LIST") { - printf("\n\t/*\n") >> TFILE - printf("\t * XXX Handle list\n") >> TFILE - printf("\t */\n\n") >> TFILE - } else { - printf("\t/* Handle replyp->%s; */\n", \ - varname) >> TFILE - } - } - printf("\n\t/*\n\t * XXX Code goes here\n\t */\n\n") >> TFILE - printf("\treturn (replyp->status);\n") >> TFILE - printf("}\n\n") >> TFILE - } -} - -function general_headers() -{ - printf("#include \"db_config.h\"\n") >> CFILE - printf("\n") >> CFILE - printf("#ifndef NO_SYSTEM_INCLUDES\n") >> CFILE - printf("#include <sys/types.h>\n") >> CFILE - printf("\n") >> CFILE - printf("#include <rpc/rpc.h>\n") >> CFILE - printf("\n") >> CFILE - printf("#include <string.h>\n") >> CFILE - printf("#endif\n") >> CFILE - printf("\n") >> CFILE - printf("#include \"db_server.h\"\n") >> CFILE - printf("\n") >> CFILE - printf("#include \"db_int.h\"\n") >> CFILE - printf("#include \"dbinc/txn.h\"\n") >> CFILE - printf("#include \"dbinc_auto/rpc_client_ext.h\"\n") >> CFILE - printf("\n") >> CFILE - - printf("#include \"db_config.h\"\n") >> TFILE - printf("\n") >> TFILE - printf("#ifndef NO_SYSTEM_INCLUDES\n") >> TFILE - printf("#include <sys/types.h>\n") >> TFILE - printf("\n") >> TFILE - printf("#include <string.h>\n") >> TFILE - printf("#endif\n") >> TFILE - printf("#include \"db_int.h\"\n") >> TFILE - printf("#include \"dbinc/txn.h\"\n") >> TFILE - printf("\n") >> TFILE - - printf("#include \"db_config.h\"\n") >> SFILE - printf("\n") >> SFILE - printf("#ifndef NO_SYSTEM_INCLUDES\n") >> SFILE - printf("#include <sys/types.h>\n") >> SFILE - printf("\n") >> SFILE - printf("#include <rpc/rpc.h>\n") >> SFILE - printf("\n") >> SFILE - printf("#include <string.h>\n") >> SFILE - printf("#endif\n") >> SFILE - printf("\n") >> SFILE - printf("#include \"db_server.h\"\n") >> SFILE - printf("\n") >> SFILE - printf("#include \"db_int.h\"\n") >> SFILE - printf("#include \"dbinc/db_server_int.h\"\n") >> SFILE - printf("#include \"dbinc_auto/rpc_server_ext.h\"\n") >> SFILE - printf("\n") >> SFILE - - printf("#include \"db_config.h\"\n") >> PFILE - printf("\n") >> PFILE - printf("#ifndef NO_SYSTEM_INCLUDES\n") >> PFILE - printf("#include <sys/types.h>\n") >> PFILE - printf("\n") >> PFILE - printf("#include <rpc/rpc.h>\n") >> PFILE - printf("\n") >> PFILE - printf("#include <string.h>\n") >> PFILE - printf("#endif\n") >> PFILE - printf("\n") >> PFILE - printf("#include \"db_server.h\"\n") >> PFILE - printf("\n") >> PFILE - printf("#include \"db_int.h\"\n") >> PFILE - printf("#include \"dbinc/db_server_int.h\"\n") >> PFILE - printf("\n") >> PFILE -} - -# -# illegal_functions -- -# Output general illegal-call functions -function illegal_functions(OUTPUT) -{ - printf("static int __dbcl_dbp_illegal __P((DB *));\n") >> OUTPUT - printf("static int __dbcl_noserver __P((DB_ENV *));\n") >> OUTPUT - printf("static int __dbcl_txn_illegal __P((DB_TXN *));\n") >> OUTPUT - printf("\n") >> OUTPUT - - printf("static int\n") >> OUTPUT - printf("__dbcl_noserver(dbenv)\n") >> OUTPUT - printf("\tDB_ENV *dbenv;\n") >> OUTPUT - printf("{\n\t__db_err(dbenv,") >> OUTPUT - printf(" \"No Berkeley DB RPC server environment\");\n") >> OUTPUT - printf("\treturn (DB_NOSERVER);\n") >> OUTPUT - printf("}\n\n") >> OUTPUT - - printf("/*\n") >> OUTPUT - printf(" * __dbcl_dbenv_illegal --\n") >> OUTPUT - printf(" * DB_ENV method not supported under RPC.\n") >> OUTPUT - printf(" *\n") >> OUTPUT - printf(" * PUBLIC: int __dbcl_dbenv_illegal __P((DB_ENV *));\n")\ - >> OUTPUT - printf(" */\n") >> OUTPUT - printf("int\n") >> OUTPUT - printf("__dbcl_dbenv_illegal(dbenv)\n") >> OUTPUT - printf("\tDB_ENV *dbenv;\n") >> OUTPUT - printf("{\n\t__db_err(dbenv,") >> OUTPUT - printf("\n\t \"Interface not supported by ") >> OUTPUT - printf("Berkeley DB RPC client environments\");\n") >> OUTPUT - printf("\treturn (DB_OPNOTSUP);\n") >> OUTPUT - printf("}\n\n") >> OUTPUT - printf("/*\n") >> OUTPUT - printf(" * __dbcl_dbp_illegal --\n") >> OUTPUT - printf(" * DB method not supported under RPC.\n") >> OUTPUT - printf(" */\n") >> OUTPUT - printf("static int\n") >> OUTPUT - printf("__dbcl_dbp_illegal(dbp)\n") >> OUTPUT - printf("\tDB *dbp;\n") >> OUTPUT - printf("{\n\treturn (__dbcl_dbenv_illegal(dbp->dbenv));\n") >> OUTPUT - printf("}\n\n") >> OUTPUT - printf("/*\n") >> OUTPUT - printf(" * __dbcl_txn_illegal --\n") >> OUTPUT - printf(" * DB_TXN method not supported under RPC.\n") >> OUTPUT - printf(" */\n") >> OUTPUT - printf("static int\n__dbcl_txn_illegal(txn)\n") >> OUTPUT - printf("\tDB_TXN *txn;\n") >> OUTPUT - printf("{\n\treturn (__dbcl_dbenv_illegal(txn->mgrp->dbenv));\n")\ - >> OUTPUT - printf("}\n\n") >> OUTPUT -} - -function obj_func(v, l) -{ - # Ignore db_create -- there's got to be something cleaner, but I - # don't want to rewrite rpc.src right now. - if (name == "db_create") - return; - if (name == "env_create") - return; - - # Strip off the leading prefix for the method name -- there's got to - # be something cleaner, but I don't want to rewrite rpc.src right now. - len = length(name); - i = index(name, "_"); - l[obj_indx] = sprintf("\t%s->%s = __dbcl_%s;", - v, substr(name, i + 1, len - i), name); -} - -function obj_illegal(l, handle, method, proto) -{ - # All of the functions return an int, with one exception. Hack - # to make that work. - type = method == "db_get_mpf" ? "DB_MPOOLFILE *" : "int" - - # Strip off the leading prefix for the method name -- there's got to - # be something cleaner, but I don't want to rewrite rpc.src right now. - len = length(method); - i = index(method, "_"); - - l[obj_indx] =\ - sprintf("\t%s->%s =\n\t (%s (*)(",\ - handle, substr(method, i + 1, len - i), type)\ - proto\ - sprintf("))\n\t __dbcl_%s_illegal;", handle); -} - -function obj_init(obj, v, list, OUTPUT) { - printf("/*\n") >> OUTPUT - printf(" * __dbcl_%s_init --\n", v) >> OUTPUT - printf(" *\tInitialize %s handle methods.\n", obj) >> OUTPUT - printf(" *\n") >> OUTPUT - printf(\ - " * PUBLIC: void __dbcl_%s_init __P((%s *));\n", v, obj) >> OUTPUT - printf(" */\n") >> OUTPUT - printf("void\n") >> OUTPUT - printf("__dbcl_%s_init(%s)\n", v, v) >> OUTPUT - printf("\t%s *%s;\n", obj, v) >> OUTPUT - printf("{\n") >> OUTPUT - for (i = 1; i < obj_indx; ++i) { - if (i in list) - print list[i] >> OUTPUT - } - printf("\treturn;\n}\n\n") >> OUTPUT -} - -# -# split_lines -- -# Add line separators to pretty-print the output. -function split_lines() { - if (argcount > 3) { - # Reset the counter, remove any trailing whitespace from - # the separator. - argcount = 0; - sub("[ ]$", "", sep) - - printf("%s\n\t\t", sep) >> PFILE - } -} - -# proto_format -- -# Pretty-print a function prototype. -function proto_format(p, OUTPUT) -{ - printf("/*\n") >> OUTPUT; - - s = ""; - for (i = 1; i in p; ++i) - s = s p[i]; - - t = " * PUBLIC: " - if (length(s) + length(t) < 80) - printf("%s%s", t, s) >> OUTPUT; - else { - split(s, p, "__P"); - len = length(t) + length(p[1]); - printf("%s%s", t, p[1]) >> OUTPUT - - n = split(p[2], comma, ","); - comma[1] = "__P" comma[1]; - for (i = 1; i <= n; i++) { - if (len + length(comma[i]) > 75) { - printf("\n * PUBLIC: ") >> OUTPUT; - len = 0; - } - printf("%s%s", comma[i], i == n ? "" : ",") >> OUTPUT; - len += length(comma[i]); - } - } - printf("\n */\n") >> OUTPUT; -} diff --git a/storage/bdb/dist/install-sh b/storage/bdb/dist/install-sh deleted file mode 100755 index b41a2459161..00000000000 --- a/storage/bdb/dist/install-sh +++ /dev/null @@ -1,251 +0,0 @@ -#!/bin/sh -# -# install - install a program, script, or datafile -# This comes from X11R5 (mit/util/scripts/install.sh). -# -# Copyright 1991 by the Massachusetts Institute of Technology -# -# Permission to use, copy, modify, distribute, and sell this software and its -# documentation for any purpose is hereby granted without fee, provided that -# the above copyright notice appear in all copies and that both that -# copyright notice and this permission notice appear in supporting -# documentation, and that the name of M.I.T. not be used in advertising or -# publicity pertaining to distribution of the software without specific, -# written prior permission. M.I.T. makes no representations about the -# suitability of this software for any purpose. It is provided "as is" -# without express or implied warranty. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. It can only install one file at a time, a restriction -# shared with many OS's install programs. - - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" - - -# put in absolute paths if you don't have them in your path; or use env. vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" - -transformbasename="" -transform_arg="" -instcmd="$mvprog" -chmodcmd="$chmodprog 0755" -chowncmd="" -chgrpcmd="" -stripcmd="" -rmcmd="$rmprog -f" -mvcmd="$mvprog" -src="" -dst="" -dir_arg="" - -while [ x"$1" != x ]; do - case $1 in - -c) instcmd="$cpprog" - shift - continue;; - - -d) dir_arg=true - shift - continue;; - - -m) chmodcmd="$chmodprog $2" - shift - shift - continue;; - - -o) chowncmd="$chownprog $2" - shift - shift - continue;; - - -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; - - -s) stripcmd="$stripprog" - shift - continue;; - - -t=*) transformarg=`echo $1 | sed 's/-t=//'` - shift - continue;; - - -b=*) transformbasename=`echo $1 | sed 's/-b=//'` - shift - continue;; - - *) if [ x"$src" = x ] - then - src=$1 - else - # this colon is to work around a 386BSD /bin/sh bug - : - dst=$1 - fi - shift - continue;; - esac -done - -if [ x"$src" = x ] -then - echo "install: no input file specified" - exit 1 -else - true -fi - -if [ x"$dir_arg" != x ]; then - dst=$src - src="" - - if [ -d $dst ]; then - instcmd=: - chmodcmd="" - else - instcmd=$mkdirprog - fi -else - -# Waiting for this to be detected by the "$instcmd $src $dsttmp" command -# might cause directories to be created, which would be especially bad -# if $src (and thus $dsttmp) contains '*'. - - if [ -f $src -o -d $src ] - then - true - else - echo "install: $src does not exist" - exit 1 - fi - - if [ x"$dst" = x ] - then - echo "install: no destination specified" - exit 1 - else - true - fi - -# If destination is a directory, append the input filename; if your system -# does not like double slashes in filenames, you may need to add some logic - - if [ -d $dst ] - then - dst="$dst"/`basename $src` - else - true - fi -fi - -## this sed command emulates the dirname command -dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` - -# Make sure that the destination directory exists. -# this part is taken from Noah Friedman's mkinstalldirs script - -# Skip lots of stat calls in the usual case. -if [ ! -d "$dstdir" ]; then -defaultIFS=' - ' -IFS="${IFS-${defaultIFS}}" - -oIFS="${IFS}" -# Some sh's can't handle IFS=/ for some reason. -IFS='%' -set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` -IFS="${oIFS}" - -pathcomp='' - -while [ $# -ne 0 ] ; do - pathcomp="${pathcomp}${1}" - shift - - if [ ! -d "${pathcomp}" ] ; - then - $mkdirprog "${pathcomp}" - else - true - fi - - pathcomp="${pathcomp}/" -done -fi - -if [ x"$dir_arg" != x ] -then - $doit $instcmd $dst && - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi -else - -# If we're going to rename the final executable, determine the name now. - - if [ x"$transformarg" = x ] - then - dstfile=`basename $dst` - else - dstfile=`basename $dst $transformbasename | - sed $transformarg`$transformbasename - fi - -# don't allow the sed command to completely eliminate the filename - - if [ x"$dstfile" = x ] - then - dstfile=`basename $dst` - else - true - fi - -# Make a temp file name in the proper directory. - - dsttmp=$dstdir/#inst.$$# - -# Move or copy the file name to the temp name - - $doit $instcmd $src $dsttmp && - - trap "rm -f ${dsttmp}" 0 && - -# and set any options; do chmod last to preserve setuid bits - -# If any of these fail, we abort the whole thing. If we want to -# ignore errors from any of these, just make sure not to ignore -# errors from the above "$doit $instcmd $src $dsttmp" command. - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && - -# Now rename the file to the real destination. - - $doit $rmcmd -f $dstdir/$dstfile && - $doit $mvcmd $dsttmp $dstdir/$dstfile - -fi && - - -exit 0 diff --git a/storage/bdb/dist/ltmain.sh b/storage/bdb/dist/ltmain.sh deleted file mode 100644 index 8915481a41b..00000000000 --- a/storage/bdb/dist/ltmain.sh +++ /dev/null @@ -1,6558 +0,0 @@ -# ltmain.sh - Provide generalized library-building support services. -# NOTE: Changing this file will not affect anything until you rerun configure. -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005 -# Free Software Foundation, Inc. -# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996 -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -basename="s,^.*/,,g" - -# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh -# is ksh but when the shell is invoked as "sh" and the current value of -# the _XPG environment variable is not equal to 1 (one), the special -# positional parameter $0, within a function call, is the name of the -# function. -progpath="$0" - -# The name of this program: -progname=`echo "$progpath" | $SED $basename` -modename="$progname" - -# Global variables: -EXIT_SUCCESS=0 -EXIT_FAILURE=1 - -PROGRAM=ltmain.sh -PACKAGE=libtool -VERSION=1.5.20 -TIMESTAMP=" (1.1220.2.287 2005/08/31 18:54:15)" - -# See if we are running on zsh, and set the options which allow our -# commands through without removal of \ escapes. -if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi - -# Check that we have a working $echo. -if test "X$1" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift -elif test "X$1" = X--fallback-echo; then - # Avoid inline document here, it may be left over - : -elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then - # Yippee, $echo works! - : -else - # Restart under the correct shell, and then maybe $echo will work. - exec $SHELL "$progpath" --no-reexec ${1+"$@"} -fi - -if test "X$1" = X--fallback-echo; then - # used as fallback echo - shift - cat <<EOF -$* -EOF - exit $EXIT_SUCCESS -fi - -default_mode= -help="Try \`$progname --help' for more information." -magic="%%%MAGIC variable%%%" -mkdir="mkdir" -mv="mv -f" -rm="rm -f" - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -Xsed="${SED}"' -e 1s/^X//' -sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g' -# test EBCDIC or ASCII -case `echo X|tr X '\101'` in - A) # ASCII based system - # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr - SP2NL='tr \040 \012' - NL2SP='tr \015\012 \040\040' - ;; - *) # EBCDIC based system - SP2NL='tr \100 \n' - NL2SP='tr \r\n \100\100' - ;; -esac - -# NLS nuisances. -# Only set LANG and LC_ALL to C if already set. -# These must not be set unconditionally because not all systems understand -# e.g. LANG=C (notably SCO). -# We save the old values to restore during execute mode. -if test "${LC_ALL+set}" = set; then - save_LC_ALL="$LC_ALL"; LC_ALL=C; export LC_ALL -fi -if test "${LANG+set}" = set; then - save_LANG="$LANG"; LANG=C; export LANG -fi - -# Make sure IFS has a sensible default -lt_nl=' -' -IFS=" $lt_nl" - -if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then - $echo "$modename: not configured to build any kind of library" 1>&2 - $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 - exit $EXIT_FAILURE -fi - -# Global variables. -mode=$default_mode -nonopt= -prev= -prevopt= -run= -show="$echo" -show_help= -execute_dlfiles= -lo2o="s/\\.lo\$/.${objext}/" -o2lo="s/\\.${objext}\$/.lo/" - -##################################### -# Shell function definitions: -# This seems to be the best place for them - -# func_win32_libid arg -# return the library type of file 'arg' -# -# Need a lot of goo to handle *both* DLLs and import libs -# Has to be a shell function in order to 'eat' the argument -# that is supplied when $file_magic_command is called. -func_win32_libid () -{ - win32_libid_type="unknown" - win32_fileres=`file -L $1 2>/dev/null` - case $win32_fileres in - *ar\ archive\ import\ library*) # definitely import - win32_libid_type="x86 archive import" - ;; - *ar\ archive*) # could be an import, or static - if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \ - $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then - win32_nmres=`eval $NM -f posix -A $1 | \ - sed -n -e '1,100{/ I /{x;/import/!{s/^/import/;h;p;};x;};}'` - if test "X$win32_nmres" = "Ximport" ; then - win32_libid_type="x86 archive import" - else - win32_libid_type="x86 archive static" - fi - fi - ;; - *DLL*) - win32_libid_type="x86 DLL" - ;; - *executable*) # but shell scripts are "executable" too... - case $win32_fileres in - *MS\ Windows\ PE\ Intel*) - win32_libid_type="x86 DLL" - ;; - esac - ;; - esac - $echo $win32_libid_type -} - - -# func_infer_tag arg -# Infer tagged configuration to use if any are available and -# if one wasn't chosen via the "--tag" command line option. -# Only attempt this if the compiler in the base compile -# command doesn't match the default compiler. -# arg is usually of the form 'gcc ...' -func_infer_tag () -{ - if test -n "$available_tags" && test -z "$tagname"; then - CC_quoted= - for arg in $CC; do - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - CC_quoted="$CC_quoted $arg" - done - case $@ in - # Blanks in the command may have been stripped by the calling shell, - # but not from the CC environment variable when configure was run. - " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;; - # Blanks at the start of $base_compile will cause this to fail - # if we don't check for them as well. - *) - for z in $available_tags; do - if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then - # Evaluate the configuration. - eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" - CC_quoted= - for arg in $CC; do - # Double-quote args containing other shell metacharacters. - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - CC_quoted="$CC_quoted $arg" - done - case "$@ " in - " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) - # The compiler in the base compile command matches - # the one in the tagged configuration. - # Assume this is the tagged configuration we want. - tagname=$z - break - ;; - esac - fi - done - # If $tagname still isn't set, then no tagged configuration - # was found and let the user know that the "--tag" command - # line option must be used. - if test -z "$tagname"; then - $echo "$modename: unable to infer tagged configuration" - $echo "$modename: specify a tag with \`--tag'" 1>&2 - exit $EXIT_FAILURE -# else -# $echo "$modename: using $tagname tagged configuration" - fi - ;; - esac - fi -} - - -# func_extract_an_archive dir oldlib -func_extract_an_archive () -{ - f_ex_an_ar_dir="$1"; shift - f_ex_an_ar_oldlib="$1" - - $show "(cd $f_ex_an_ar_dir && $AR x $f_ex_an_ar_oldlib)" - $run eval "(cd \$f_ex_an_ar_dir && $AR x \$f_ex_an_ar_oldlib)" || exit $? - if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then - : - else - $echo "$modename: ERROR: object name conflicts: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" 1>&2 - exit $EXIT_FAILURE - fi -} - -# func_extract_archives gentop oldlib ... -func_extract_archives () -{ - my_gentop="$1"; shift - my_oldlibs=${1+"$@"} - my_oldobjs="" - my_xlib="" - my_xabs="" - my_xdir="" - my_status="" - - $show "${rm}r $my_gentop" - $run ${rm}r "$my_gentop" - $show "$mkdir $my_gentop" - $run $mkdir "$my_gentop" - my_status=$? - if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then - exit $my_status - fi - - for my_xlib in $my_oldlibs; do - # Extract the objects. - case $my_xlib in - [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; - *) my_xabs=`pwd`"/$my_xlib" ;; - esac - my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'` - my_xdir="$my_gentop/$my_xlib" - - $show "${rm}r $my_xdir" - $run ${rm}r "$my_xdir" - $show "$mkdir $my_xdir" - $run $mkdir "$my_xdir" - status=$? - if test "$status" -ne 0 && test ! -d "$my_xdir"; then - exit $status - fi - case $host in - *-darwin*) - $show "Extracting $my_xabs" - # Do not bother doing anything if just a dry run - if test -z "$run"; then - darwin_orig_dir=`pwd` - cd $my_xdir || exit $? - darwin_archive=$my_xabs - darwin_curdir=`pwd` - darwin_base_archive=`$echo "X$darwin_archive" | $Xsed -e 's%^.*/%%'` - darwin_arches=`lipo -info "$darwin_archive" 2>/dev/null | $EGREP Architectures 2>/dev/null` - if test -n "$darwin_arches"; then - darwin_arches=`echo "$darwin_arches" | $SED -e 's/.*are://'` - darwin_arch= - $show "$darwin_base_archive has multiple architectures $darwin_arches" - for darwin_arch in $darwin_arches ; do - mkdir -p "unfat-$$/${darwin_base_archive}-${darwin_arch}" - lipo -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" - cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" - func_extract_an_archive "`pwd`" "${darwin_base_archive}" - cd "$darwin_curdir" - $rm "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" - done # $darwin_arches - ## Okay now we have a bunch of thin objects, gotta fatten them up :) - darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print| xargs basename | sort -u | $NL2SP` - darwin_file= - darwin_files= - for darwin_file in $darwin_filelist; do - darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` - lipo -create -output "$darwin_file" $darwin_files - done # $darwin_filelist - ${rm}r unfat-$$ - cd "$darwin_orig_dir" - else - cd "$darwin_orig_dir" - func_extract_an_archive "$my_xdir" "$my_xabs" - fi # $darwin_arches - fi # $run - ;; - *) - func_extract_an_archive "$my_xdir" "$my_xabs" - ;; - esac - my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` - done - func_extract_archives_result="$my_oldobjs" -} -# End of Shell function definitions -##################################### - -# Darwin sucks -eval std_shrext=\"$shrext_cmds\" - -# Parse our command line options once, thoroughly. -while test "$#" -gt 0 -do - arg="$1" - shift - - case $arg in - -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; - *) optarg= ;; - esac - - # If the previous option needs an argument, assign it. - if test -n "$prev"; then - case $prev in - execute_dlfiles) - execute_dlfiles="$execute_dlfiles $arg" - ;; - tag) - tagname="$arg" - preserve_args="${preserve_args}=$arg" - - # Check whether tagname contains only valid characters - case $tagname in - *[!-_A-Za-z0-9,/]*) - $echo "$progname: invalid tag name: $tagname" 1>&2 - exit $EXIT_FAILURE - ;; - esac - - case $tagname in - CC) - # Don't test for the "default" C tag, as we know, it's there, but - # not specially marked. - ;; - *) - if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then - taglist="$taglist $tagname" - # Evaluate the configuration. - eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`" - else - $echo "$progname: ignoring unknown tag $tagname" 1>&2 - fi - ;; - esac - ;; - *) - eval "$prev=\$arg" - ;; - esac - - prev= - prevopt= - continue - fi - - # Have we seen a non-optional argument yet? - case $arg in - --help) - show_help=yes - ;; - - --version) - $echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" - $echo - $echo "Copyright (C) 2005 Free Software Foundation, Inc." - $echo "This is free software; see the source for copying conditions. There is NO" - $echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - exit $? - ;; - - --config) - ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath - # Now print the configurations for the tags. - for tagname in $taglist; do - ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath" - done - exit $? - ;; - - --debug) - $echo "$progname: enabling shell trace mode" - set -x - preserve_args="$preserve_args $arg" - ;; - - --dry-run | -n) - run=: - ;; - - --features) - $echo "host: $host" - if test "$build_libtool_libs" = yes; then - $echo "enable shared libraries" - else - $echo "disable shared libraries" - fi - if test "$build_old_libs" = yes; then - $echo "enable static libraries" - else - $echo "disable static libraries" - fi - exit $? - ;; - - --finish) mode="finish" ;; - - --mode) prevopt="--mode" prev=mode ;; - --mode=*) mode="$optarg" ;; - - --preserve-dup-deps) duplicate_deps="yes" ;; - - --quiet | --silent) - show=: - preserve_args="$preserve_args $arg" - ;; - - --tag) prevopt="--tag" prev=tag ;; - --tag=*) - set tag "$optarg" ${1+"$@"} - shift - prev=tag - preserve_args="$preserve_args --tag" - ;; - - -dlopen) - prevopt="-dlopen" - prev=execute_dlfiles - ;; - - -*) - $echo "$modename: unrecognized option \`$arg'" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - ;; - - *) - nonopt="$arg" - break - ;; - esac -done - -if test -n "$prevopt"; then - $echo "$modename: option \`$prevopt' requires an argument" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE -fi - -# If this variable is set in any of the actions, the command in it -# will be execed at the end. This prevents here-documents from being -# left over by shells. -exec_cmd= - -if test -z "$show_help"; then - - # Infer the operation mode. - if test -z "$mode"; then - $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2 - $echo "*** Future versions of Libtool will require --mode=MODE be specified." 1>&2 - case $nonopt in - *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*) - mode=link - for arg - do - case $arg in - -c) - mode=compile - break - ;; - esac - done - ;; - *db | *dbx | *strace | *truss) - mode=execute - ;; - *install*|cp|mv) - mode=install - ;; - *rm) - mode=uninstall - ;; - *) - # If we have no mode, but dlfiles were specified, then do execute mode. - test -n "$execute_dlfiles" && mode=execute - - # Just use the default operation mode. - if test -z "$mode"; then - if test -n "$nonopt"; then - $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 - else - $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 - fi - fi - ;; - esac - fi - - # Only execute mode is allowed to have -dlopen flags. - if test -n "$execute_dlfiles" && test "$mode" != execute; then - $echo "$modename: unrecognized option \`-dlopen'" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - # Change the help message to a mode-specific one. - generic_help="$help" - help="Try \`$modename --help --mode=$mode' for more information." - - # These modes are in order of execution frequency so that they run quickly. - case $mode in - # libtool compile mode - compile) - modename="$modename: compile" - # Get the compilation command and the source file. - base_compile= - srcfile="$nonopt" # always keep a non-empty value in "srcfile" - suppress_opt=yes - suppress_output= - arg_mode=normal - libobj= - later= - - for arg - do - case $arg_mode in - arg ) - # do not "continue". Instead, add this to base_compile - lastarg="$arg" - arg_mode=normal - ;; - - target ) - libobj="$arg" - arg_mode=normal - continue - ;; - - normal ) - # Accept any command-line options. - case $arg in - -o) - if test -n "$libobj" ; then - $echo "$modename: you cannot specify \`-o' more than once" 1>&2 - exit $EXIT_FAILURE - fi - arg_mode=target - continue - ;; - - -static | -prefer-pic | -prefer-non-pic) - later="$later $arg" - continue - ;; - - -no-suppress) - suppress_opt=no - continue - ;; - - -Xcompiler) - arg_mode=arg # the next one goes into the "base_compile" arg list - continue # The current "srcfile" will either be retained or - ;; # replaced later. I would guess that would be a bug. - - -Wc,*) - args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` - lastarg= - save_ifs="$IFS"; IFS=',' - for arg in $args; do - IFS="$save_ifs" - - # Double-quote args containing other shell metacharacters. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - lastarg="$lastarg $arg" - done - IFS="$save_ifs" - lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` - - # Add the arguments to base_compile. - base_compile="$base_compile $lastarg" - continue - ;; - - * ) - # Accept the current argument as the source file. - # The previous "srcfile" becomes the current argument. - # - lastarg="$srcfile" - srcfile="$arg" - ;; - esac # case $arg - ;; - esac # case $arg_mode - - # Aesthetically quote the previous argument. - lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` - - case $lastarg in - # Double-quote args containing other shell metacharacters. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, and some SunOS ksh mistreat backslash-escaping - # in scan sets (worked around with variable expansion), - # and furthermore cannot handle '|' '&' '(' ')' in scan sets - # at all, so we specify them separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - lastarg="\"$lastarg\"" - ;; - esac - - base_compile="$base_compile $lastarg" - done # for arg - - case $arg_mode in - arg) - $echo "$modename: you must specify an argument for -Xcompile" - exit $EXIT_FAILURE - ;; - target) - $echo "$modename: you must specify a target with \`-o'" 1>&2 - exit $EXIT_FAILURE - ;; - *) - # Get the name of the library object. - [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` - ;; - esac - - # Recognize several different file suffixes. - # If the user specifies -o file.o, it is replaced with file.lo - xform='[cCFSifmso]' - case $libobj in - *.ada) xform=ada ;; - *.adb) xform=adb ;; - *.ads) xform=ads ;; - *.asm) xform=asm ;; - *.c++) xform=c++ ;; - *.cc) xform=cc ;; - *.ii) xform=ii ;; - *.class) xform=class ;; - *.cpp) xform=cpp ;; - *.cxx) xform=cxx ;; - *.f90) xform=f90 ;; - *.for) xform=for ;; - *.java) xform=java ;; - esac - - libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` - - case $libobj in - *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; - *) - $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 - exit $EXIT_FAILURE - ;; - esac - - func_infer_tag $base_compile - - for arg in $later; do - case $arg in - -static) - build_old_libs=yes - continue - ;; - - -prefer-pic) - pic_mode=yes - continue - ;; - - -prefer-non-pic) - pic_mode=no - continue - ;; - esac - done - - qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"` - case $qlibobj in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - qlibobj="\"$qlibobj\"" ;; - esac - test "X$libobj" != "X$qlibobj" \ - && $echo "X$libobj" | grep '[]~#^*{};<>?"'"'"' &()|`$[]' \ - && $echo "$modename: libobj name \`$libobj' may not contain shell special characters." - objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` - xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$obj"; then - xdir= - else - xdir=$xdir/ - fi - lobj=${xdir}$objdir/$objname - - if test -z "$base_compile"; then - $echo "$modename: you must specify a compilation command" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - # Delete any leftover library objects. - if test "$build_old_libs" = yes; then - removelist="$obj $lobj $libobj ${libobj}T" - else - removelist="$lobj $libobj ${libobj}T" - fi - - $run $rm $removelist - trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 - - # On Cygwin there's no "real" PIC flag so we must build both object types - case $host_os in - cygwin* | mingw* | pw32* | os2*) - pic_mode=default - ;; - esac - if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then - # non-PIC code in shared libraries is not supported - pic_mode=default - fi - - # Calculate the filename of the output object if compiler does - # not support -o with -c - if test "$compiler_c_o" = no; then - output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} - lockfile="$output_obj.lock" - removelist="$removelist $output_obj $lockfile" - trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 - else - output_obj= - need_locks=no - lockfile= - fi - - # Lock this critical section if it is needed - # We use this script file to make the link, it avoids creating a new file - if test "$need_locks" = yes; then - until $run ln "$progpath" "$lockfile" 2>/dev/null; do - $show "Waiting for $lockfile to be removed" - sleep 2 - done - elif test "$need_locks" = warn; then - if test -f "$lockfile"; then - $echo "\ -*** ERROR, $lockfile exists and contains: -`cat $lockfile 2>/dev/null` - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $run $rm $removelist - exit $EXIT_FAILURE - fi - $echo "$srcfile" > "$lockfile" - fi - - if test -n "$fix_srcfile_path"; then - eval srcfile=\"$fix_srcfile_path\" - fi - qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"` - case $qsrcfile in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - qsrcfile="\"$qsrcfile\"" ;; - esac - - $run $rm "$libobj" "${libobj}T" - - # Create a libtool object file (analogous to a ".la" file), - # but don't create it if we're doing a dry run. - test -z "$run" && cat > ${libobj}T <<EOF -# $libobj - a libtool object file -# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# Name of the PIC object. -EOF - - # Only build a PIC object if we are building libtool libraries. - if test "$build_libtool_libs" = yes; then - # Without this assignment, base_compile gets emptied. - fbsd_hideous_sh_bug=$base_compile - - if test "$pic_mode" != no; then - command="$base_compile $qsrcfile $pic_flag" - else - # Don't build PIC code - command="$base_compile $qsrcfile" - fi - - if test ! -d "${xdir}$objdir"; then - $show "$mkdir ${xdir}$objdir" - $run $mkdir ${xdir}$objdir - status=$? - if test "$status" -ne 0 && test ! -d "${xdir}$objdir"; then - exit $status - fi - fi - - if test -z "$output_obj"; then - # Place PIC objects in $objdir - command="$command -o $lobj" - fi - - $run $rm "$lobj" "$output_obj" - - $show "$command" - if $run eval "$command"; then : - else - test -n "$output_obj" && $run $rm $removelist - exit $EXIT_FAILURE - fi - - if test "$need_locks" = warn && - test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then - $echo "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $run $rm $removelist - exit $EXIT_FAILURE - fi - - # Just move the object if needed, then go on to compile the next one - if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then - $show "$mv $output_obj $lobj" - if $run $mv $output_obj $lobj; then : - else - error=$? - $run $rm $removelist - exit $error - fi - fi - - # Append the name of the PIC object to the libtool object file. - test -z "$run" && cat >> ${libobj}T <<EOF -pic_object='$objdir/$objname' - -EOF - - # Allow error messages only from the first compilation. - if test "$suppress_opt" = yes; then - suppress_output=' >/dev/null 2>&1' - fi - else - # No PIC object so indicate it doesn't exist in the libtool - # object file. - test -z "$run" && cat >> ${libobj}T <<EOF -pic_object=none - -EOF - fi - - # Only build a position-dependent object if we build old libraries. - if test "$build_old_libs" = yes; then - if test "$pic_mode" != yes; then - # Don't build PIC code - command="$base_compile $qsrcfile" - else - command="$base_compile $qsrcfile $pic_flag" - fi - if test "$compiler_c_o" = yes; then - command="$command -o $obj" - fi - - # Suppress compiler output if we already did a PIC compilation. - command="$command$suppress_output" - $run $rm "$obj" "$output_obj" - $show "$command" - if $run eval "$command"; then : - else - $run $rm $removelist - exit $EXIT_FAILURE - fi - - if test "$need_locks" = warn && - test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then - $echo "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $run $rm $removelist - exit $EXIT_FAILURE - fi - - # Just move the object if needed - if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then - $show "$mv $output_obj $obj" - if $run $mv $output_obj $obj; then : - else - error=$? - $run $rm $removelist - exit $error - fi - fi - - # Append the name of the non-PIC object the libtool object file. - # Only append if the libtool object file exists. - test -z "$run" && cat >> ${libobj}T <<EOF -# Name of the non-PIC object. -non_pic_object='$objname' - -EOF - else - # Append the name of the non-PIC object the libtool object file. - # Only append if the libtool object file exists. - test -z "$run" && cat >> ${libobj}T <<EOF -# Name of the non-PIC object. -non_pic_object=none - -EOF - fi - - $run $mv "${libobj}T" "${libobj}" - - # Unlock the critical section if it was locked - if test "$need_locks" != no; then - $run $rm "$lockfile" - fi - - exit $EXIT_SUCCESS - ;; - - # libtool link mode - link | relink) - modename="$modename: link" - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) - # It is impossible to link a dll without this setting, and - # we shouldn't force the makefile maintainer to figure out - # which system we are compiling for in order to pass an extra - # flag for every libtool invocation. - # allow_undefined=no - - # FIXME: Unfortunately, there are problems with the above when trying - # to make a dll which has undefined symbols, in which case not - # even a static library is built. For now, we need to specify - # -no-undefined on the libtool link line when we can be certain - # that all symbols are satisfied, otherwise we get a static library. - allow_undefined=yes - ;; - *) - allow_undefined=yes - ;; - esac - libtool_args="$nonopt" - base_compile="$nonopt $@" - compile_command="$nonopt" - finalize_command="$nonopt" - - compile_rpath= - finalize_rpath= - compile_shlibpath= - finalize_shlibpath= - convenience= - old_convenience= - deplibs= - old_deplibs= - compiler_flags= - linker_flags= - dllsearchpath= - lib_search_path=`pwd` - inst_prefix_dir= - - avoid_version=no - dlfiles= - dlprefiles= - dlself=no - export_dynamic=no - export_symbols= - export_symbols_regex= - generated= - libobjs= - ltlibs= - module=no - no_install=no - objs= - non_pic_objects= - precious_files_regex= - prefer_static_libs=no - preload=no - prev= - prevarg= - release= - rpath= - xrpath= - perm_rpath= - temp_rpath= - thread_safe=no - vinfo= - vinfo_number=no - - func_infer_tag $base_compile - - # We need to know -static, to get the right output filenames. - for arg - do - case $arg in - -all-static | -static) - if test "X$arg" = "X-all-static"; then - if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then - $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2 - fi - if test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - else - if test -z "$pic_flag" && test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - fi - build_libtool_libs=no - build_old_libs=yes - prefer_static_libs=yes - break - ;; - esac - done - - # See if our shared archives depend on static archives. - test -n "$old_archive_from_new_cmds" && build_old_libs=yes - - # Go through the arguments, transforming them on the way. - while test "$#" -gt 0; do - arg="$1" - shift - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test - ;; - *) qarg=$arg ;; - esac - libtool_args="$libtool_args $qarg" - - # If the previous option needs an argument, assign it. - if test -n "$prev"; then - case $prev in - output) - compile_command="$compile_command @OUTPUT@" - finalize_command="$finalize_command @OUTPUT@" - ;; - esac - - case $prev in - dlfiles|dlprefiles) - if test "$preload" = no; then - # Add the symbol object into the linking commands. - compile_command="$compile_command @SYMFILE@" - finalize_command="$finalize_command @SYMFILE@" - preload=yes - fi - case $arg in - *.la | *.lo) ;; # We handle these cases below. - force) - if test "$dlself" = no; then - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - self) - if test "$prev" = dlprefiles; then - dlself=yes - elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then - dlself=yes - else - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - *) - if test "$prev" = dlfiles; then - dlfiles="$dlfiles $arg" - else - dlprefiles="$dlprefiles $arg" - fi - prev= - continue - ;; - esac - ;; - expsyms) - export_symbols="$arg" - if test ! -f "$arg"; then - $echo "$modename: symbol file \`$arg' does not exist" - exit $EXIT_FAILURE - fi - prev= - continue - ;; - expsyms_regex) - export_symbols_regex="$arg" - prev= - continue - ;; - inst_prefix) - inst_prefix_dir="$arg" - prev= - continue - ;; - precious_regex) - precious_files_regex="$arg" - prev= - continue - ;; - release) - release="-$arg" - prev= - continue - ;; - objectlist) - if test -f "$arg"; then - save_arg=$arg - moreargs= - for fil in `cat $save_arg` - do -# moreargs="$moreargs $fil" - arg=$fil - # A libtool-controlled object. - - # Check to see that this really is a libtool object. - if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - pic_object= - non_pic_object= - - # Read the .lo file - # If there is no directory component, then add one. - case $arg in - */* | *\\*) . $arg ;; - *) . ./$arg ;; - esac - - if test -z "$pic_object" || \ - test -z "$non_pic_object" || - test "$pic_object" = none && \ - test "$non_pic_object" = none; then - $echo "$modename: cannot find name of object for \`$arg'" 1>&2 - exit $EXIT_FAILURE - fi - - # Extract subdirectory from the argument. - xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$arg"; then - xdir= - else - xdir="$xdir/" - fi - - if test "$pic_object" != none; then - # Prepend the subdirectory the object is found in. - pic_object="$xdir$pic_object" - - if test "$prev" = dlfiles; then - if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then - dlfiles="$dlfiles $pic_object" - prev= - continue - else - # If libtool objects are unsupported, then we need to preload. - prev=dlprefiles - fi - fi - - # CHECK ME: I think I busted this. -Ossama - if test "$prev" = dlprefiles; then - # Preload the old-style object. - dlprefiles="$dlprefiles $pic_object" - prev= - fi - - # A PIC object. - libobjs="$libobjs $pic_object" - arg="$pic_object" - fi - - # Non-PIC object. - if test "$non_pic_object" != none; then - # Prepend the subdirectory the object is found in. - non_pic_object="$xdir$non_pic_object" - - # A standard non-PIC object - non_pic_objects="$non_pic_objects $non_pic_object" - if test -z "$pic_object" || test "$pic_object" = none ; then - arg="$non_pic_object" - fi - fi - else - # Only an error if not doing a dry-run. - if test -z "$run"; then - $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 - exit $EXIT_FAILURE - else - # Dry-run case. - - # Extract subdirectory from the argument. - xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$arg"; then - xdir= - else - xdir="$xdir/" - fi - - pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` - non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` - libobjs="$libobjs $pic_object" - non_pic_objects="$non_pic_objects $non_pic_object" - fi - fi - done - else - $echo "$modename: link input file \`$save_arg' does not exist" - exit $EXIT_FAILURE - fi - arg=$save_arg - prev= - continue - ;; - rpath | xrpath) - # We need an absolute path. - case $arg in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - $echo "$modename: only absolute run-paths are allowed" 1>&2 - exit $EXIT_FAILURE - ;; - esac - if test "$prev" = rpath; then - case "$rpath " in - *" $arg "*) ;; - *) rpath="$rpath $arg" ;; - esac - else - case "$xrpath " in - *" $arg "*) ;; - *) xrpath="$xrpath $arg" ;; - esac - fi - prev= - continue - ;; - xcompiler) - compiler_flags="$compiler_flags $qarg" - prev= - compile_command="$compile_command $qarg" - finalize_command="$finalize_command $qarg" - continue - ;; - xlinker) - linker_flags="$linker_flags $qarg" - compiler_flags="$compiler_flags $wl$qarg" - prev= - compile_command="$compile_command $wl$qarg" - finalize_command="$finalize_command $wl$qarg" - continue - ;; - xcclinker) - linker_flags="$linker_flags $qarg" - compiler_flags="$compiler_flags $qarg" - prev= - compile_command="$compile_command $qarg" - finalize_command="$finalize_command $qarg" - continue - ;; - shrext) - shrext_cmds="$arg" - prev= - continue - ;; - darwin_framework) - compiler_flags="$compiler_flags $arg" - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - prev= - continue - ;; - *) - eval "$prev=\"\$arg\"" - prev= - continue - ;; - esac - fi # test -n "$prev" - - prevarg="$arg" - - case $arg in - -all-static) - if test -n "$link_static_flag"; then - compile_command="$compile_command $link_static_flag" - finalize_command="$finalize_command $link_static_flag" - fi - continue - ;; - - -allow-undefined) - # FIXME: remove this flag sometime in the future. - $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 - continue - ;; - - -avoid-version) - avoid_version=yes - continue - ;; - - -dlopen) - prev=dlfiles - continue - ;; - - -dlpreopen) - prev=dlprefiles - continue - ;; - - -export-dynamic) - export_dynamic=yes - continue - ;; - - -export-symbols | -export-symbols-regex) - if test -n "$export_symbols" || test -n "$export_symbols_regex"; then - $echo "$modename: more than one -exported-symbols argument is not allowed" - exit $EXIT_FAILURE - fi - if test "X$arg" = "X-export-symbols"; then - prev=expsyms - else - prev=expsyms_regex - fi - continue - ;; - - -framework|-arch) - prev=darwin_framework - compiler_flags="$compiler_flags $arg" - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - continue - ;; - - -inst-prefix-dir) - prev=inst_prefix - continue - ;; - - # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* - # so, if we see these flags be careful not to treat them like -L - -L[A-Z][A-Z]*:*) - case $with_gcc/$host in - no/*-*-irix* | /*-*-irix*) - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - ;; - esac - continue - ;; - - -L*) - dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - absdir=`cd "$dir" && pwd` - if test -z "$absdir"; then - $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 - exit $EXIT_FAILURE - fi - dir="$absdir" - ;; - esac - case "$deplibs " in - *" -L$dir "*) ;; - *) - deplibs="$deplibs -L$dir" - lib_search_path="$lib_search_path $dir" - ;; - esac - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) - case :$dllsearchpath: in - *":$dir:"*) ;; - *) dllsearchpath="$dllsearchpath:$dir";; - esac - ;; - esac - continue - ;; - - -l*) - if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then - case $host in - *-*-cygwin* | *-*-pw32* | *-*-beos*) - # These systems don't actually have a C or math library (as such) - continue - ;; - *-*-mingw* | *-*-os2*) - # These systems don't actually have a C library (as such) - test "X$arg" = "X-lc" && continue - ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) - # Do not include libc due to us having libc/libc_r. - test "X$arg" = "X-lc" && continue - ;; - *-*-rhapsody* | *-*-darwin1.[012]) - # Rhapsody C and math libraries are in the System framework - deplibs="$deplibs -framework System" - continue - esac - elif test "X$arg" = "X-lc_r"; then - case $host in - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) - # Do not include libc_r directly, use -pthread flag. - continue - ;; - esac - fi - deplibs="$deplibs $arg" - continue - ;; - - # Tru64 UNIX uses -model [arg] to determine the layout of C++ - # classes, name mangling, and exception handling. - -model) - compile_command="$compile_command $arg" - compiler_flags="$compiler_flags $arg" - finalize_command="$finalize_command $arg" - prev=xcompiler - continue - ;; - - -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) - compiler_flags="$compiler_flags $arg" - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - continue - ;; - - -module) - module=yes - continue - ;; - - ################################################################ - #### Local edit for Sleepycat SR #8705 - #### Some cases separated below. - ################################################################ - # -64, -mips[0-9] enable 64-bit mode on the SGI compiler - # -r[0-9][0-9]* specifies the processor on the SGI compiler - # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler - # +DA*, +DD* enable 64-bit mode on the HP compiler - # -q* pass through compiler args for the IBM compiler - # -m* pass through architecture-specific compiler args for GCC - -r[0-9][0-9]*|-xtarget=*|+DA*|+DD*|-q*|-m*) - - # Unknown arguments in both finalize_command and compile_command need - # to be aesthetically quoted because they are evaled later. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - if test "$with_gcc" = "yes" ; then - compiler_flags="$compiler_flags $arg" - fi - continue - ;; - - ################################################################ - #### Local edit for Sleepycat SR #8705 - #### This case was given to us by Albert Chin, and we expect - #### this to be included in future versions of libtool, - #### though we must verify that before upgrading. - #### Note that libtool 1.5.20 at least, incorporates similar - #### code, but it got refactored incorrectly. - ################################################################ - # Flags for IRIX and Solaris compiler - -64|-mips[0-9]|-xarch=*) - # Unknown arguments in both finalize_command and compile_command need - # to be aesthetically quoted because they are evaled later. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - compiler_flags="$compiler_flags $arg" - continue - ;; - - -shrext) - prev=shrext - continue - ;; - - -no-fast-install) - fast_install=no - continue - ;; - - -no-install) - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) - # The PATH hackery in wrapper scripts is required on Windows - # in order for the loader to find any dlls it needs. - $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 - $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 - fast_install=no - ;; - *) no_install=yes ;; - esac - continue - ;; - - -no-undefined) - allow_undefined=no - continue - ;; - - -objectlist) - prev=objectlist - continue - ;; - - -o) prev=output ;; - - -precious-files-regex) - prev=precious_regex - continue - ;; - - -release) - prev=release - continue - ;; - - -rpath) - prev=rpath - continue - ;; - - -R) - prev=xrpath - continue - ;; - - -R*) - dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - $echo "$modename: only absolute run-paths are allowed" 1>&2 - exit $EXIT_FAILURE - ;; - esac - case "$xrpath " in - *" $dir "*) ;; - *) xrpath="$xrpath $dir" ;; - esac - continue - ;; - - -static) - # The effects of -static are defined in a previous loop. - # We used to do the same as -all-static on platforms that - # didn't have a PIC flag, but the assumption that the effects - # would be equivalent was wrong. It would break on at least - # Digital Unix and AIX. - continue - ;; - - -thread-safe) - thread_safe=yes - continue - ;; - - -version-info) - prev=vinfo - continue - ;; - -version-number) - prev=vinfo - vinfo_number=yes - continue - ;; - - -Wc,*) - args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` - arg= - save_ifs="$IFS"; IFS=',' - for flag in $args; do - IFS="$save_ifs" - case $flag in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - flag="\"$flag\"" - ;; - esac - arg="$arg $wl$flag" - compiler_flags="$compiler_flags $flag" - done - IFS="$save_ifs" - arg=`$echo "X$arg" | $Xsed -e "s/^ //"` - ;; - - -Wl,*) - args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` - arg= - save_ifs="$IFS"; IFS=',' - for flag in $args; do - IFS="$save_ifs" - case $flag in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - flag="\"$flag\"" - ;; - esac - arg="$arg $wl$flag" - compiler_flags="$compiler_flags $wl$flag" - linker_flags="$linker_flags $flag" - done - IFS="$save_ifs" - arg=`$echo "X$arg" | $Xsed -e "s/^ //"` - ;; - - -Xcompiler) - prev=xcompiler - continue - ;; - - -Xlinker) - prev=xlinker - continue - ;; - - -XCClinker) - prev=xcclinker - continue - ;; - - # Some other compiler flag. - -* | +*) - # Unknown arguments in both finalize_command and compile_command need - # to be aesthetically quoted because they are evaled later. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - ;; - - *.$objext) - # A standard object. - objs="$objs $arg" - ;; - - *.lo) - # A libtool-controlled object. - - # Check to see that this really is a libtool object. - if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - pic_object= - non_pic_object= - - # Read the .lo file - # If there is no directory component, then add one. - case $arg in - */* | *\\*) . $arg ;; - *) . ./$arg ;; - esac - - if test -z "$pic_object" || \ - test -z "$non_pic_object" || - test "$pic_object" = none && \ - test "$non_pic_object" = none; then - $echo "$modename: cannot find name of object for \`$arg'" 1>&2 - exit $EXIT_FAILURE - fi - - # Extract subdirectory from the argument. - xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$arg"; then - xdir= - else - xdir="$xdir/" - fi - - if test "$pic_object" != none; then - # Prepend the subdirectory the object is found in. - pic_object="$xdir$pic_object" - - if test "$prev" = dlfiles; then - if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then - dlfiles="$dlfiles $pic_object" - prev= - continue - else - # If libtool objects are unsupported, then we need to preload. - prev=dlprefiles - fi - fi - - # CHECK ME: I think I busted this. -Ossama - if test "$prev" = dlprefiles; then - # Preload the old-style object. - dlprefiles="$dlprefiles $pic_object" - prev= - fi - - # A PIC object. - libobjs="$libobjs $pic_object" - arg="$pic_object" - fi - - # Non-PIC object. - if test "$non_pic_object" != none; then - # Prepend the subdirectory the object is found in. - non_pic_object="$xdir$non_pic_object" - - # A standard non-PIC object - non_pic_objects="$non_pic_objects $non_pic_object" - if test -z "$pic_object" || test "$pic_object" = none ; then - arg="$non_pic_object" - fi - fi - else - # Only an error if not doing a dry-run. - if test -z "$run"; then - $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 - exit $EXIT_FAILURE - else - # Dry-run case. - - # Extract subdirectory from the argument. - xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$arg"; then - xdir= - else - xdir="$xdir/" - fi - - pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` - non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` - libobjs="$libobjs $pic_object" - non_pic_objects="$non_pic_objects $non_pic_object" - fi - fi - ;; - - *.$libext) - # An archive. - deplibs="$deplibs $arg" - old_deplibs="$old_deplibs $arg" - continue - ;; - - *.la) - # A libtool-controlled library. - - if test "$prev" = dlfiles; then - # This library was specified with -dlopen. - dlfiles="$dlfiles $arg" - prev= - elif test "$prev" = dlprefiles; then - # The library was specified with -dlpreopen. - dlprefiles="$dlprefiles $arg" - prev= - else - deplibs="$deplibs $arg" - fi - continue - ;; - - # Some other compiler argument. - *) - # Unknown arguments in both finalize_command and compile_command need - # to be aesthetically quoted because they are evaled later. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - ;; - esac # arg - - # Now actually substitute the argument into the commands. - if test -n "$arg"; then - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - fi - done # argument parsing loop - - if test -n "$prev"; then - $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then - eval arg=\"$export_dynamic_flag_spec\" - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - fi - - oldlibs= - # calculate the name of the file, without its directory - outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` - libobjs_save="$libobjs" - - if test -n "$shlibpath_var"; then - # get the directories listed in $shlibpath_var - eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` - else - shlib_search_path= - fi - eval sys_lib_search_path=\"$sys_lib_search_path_spec\" - eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" - - output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` - if test "X$output_objdir" = "X$output"; then - output_objdir="$objdir" - else - output_objdir="$output_objdir/$objdir" - fi - # Create the object directory. - if test ! -d "$output_objdir"; then - $show "$mkdir $output_objdir" - $run $mkdir $output_objdir - status=$? - if test "$status" -ne 0 && test ! -d "$output_objdir"; then - exit $status - fi - fi - - # Determine the type of output - case $output in - "") - $echo "$modename: you must specify an output file" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - ;; - *.$libext) linkmode=oldlib ;; - *.lo | *.$objext) linkmode=obj ;; - *.la) linkmode=lib ;; - *) linkmode=prog ;; # Anything else should be a program. - esac - - case $host in - *cygwin* | *mingw* | *pw32*) - # don't eliminate duplications in $postdeps and $predeps - duplicate_compiler_generated_deps=yes - ;; - *) - duplicate_compiler_generated_deps=$duplicate_deps - ;; - esac - specialdeplibs= - - libs= - # Find all interdependent deplibs by searching for libraries - # that are linked more than once (e.g. -la -lb -la) - for deplib in $deplibs; do - if test "X$duplicate_deps" = "Xyes" ; then - case "$libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - libs="$libs $deplib" - done - - if test "$linkmode" = lib; then - libs="$predeps $libs $compiler_lib_search_path $postdeps" - - # Compute libraries that are listed more than once in $predeps - # $postdeps and mark them as special (i.e., whose duplicates are - # not to be eliminated). - pre_post_deps= - if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then - for pre_post_dep in $predeps $postdeps; do - case "$pre_post_deps " in - *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; - esac - pre_post_deps="$pre_post_deps $pre_post_dep" - done - fi - pre_post_deps= - fi - - deplibs= - newdependency_libs= - newlib_search_path= - need_relink=no # whether we're linking any uninstalled libtool libraries - notinst_deplibs= # not-installed libtool libraries - notinst_path= # paths that contain not-installed libtool libraries - case $linkmode in - lib) - passes="conv link" - for file in $dlfiles $dlprefiles; do - case $file in - *.la) ;; - *) - $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 - exit $EXIT_FAILURE - ;; - esac - done - ;; - prog) - compile_deplibs= - finalize_deplibs= - alldeplibs=no - newdlfiles= - newdlprefiles= - passes="conv scan dlopen dlpreopen link" - ;; - *) passes="conv" - ;; - esac - for pass in $passes; do - if test "$linkmode,$pass" = "lib,link" || - test "$linkmode,$pass" = "prog,scan"; then - libs="$deplibs" - deplibs= - fi - if test "$linkmode" = prog; then - case $pass in - dlopen) libs="$dlfiles" ;; - dlpreopen) libs="$dlprefiles" ;; - link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; - esac - fi - if test "$pass" = dlopen; then - # Collect dlpreopened libraries - save_deplibs="$deplibs" - deplibs= - fi - for deplib in $libs; do - lib= - found=no - case $deplib in - -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - compiler_flags="$compiler_flags $deplib" - fi - continue - ;; - -l*) - if test "$linkmode" != lib && test "$linkmode" != prog; then - $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2 - continue - fi - name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` - for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do - for search_ext in .la $std_shrext .so .a; do - # Search the libtool library - lib="$searchdir/lib${name}${search_ext}" - if test -f "$lib"; then - if test "$search_ext" = ".la"; then - found=yes - else - found=no - fi - break 2 - fi - done - done - if test "$found" != yes; then - # deplib doesn't seem to be a libtool library - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" - fi - continue - else # deplib is a libtool library - # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, - # We need to do some special things here, and not later. - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - case " $predeps $postdeps " in - *" $deplib "*) - if (${SED} -e '2q' $lib | - grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - library_names= - old_library= - case $lib in - */* | *\\*) . $lib ;; - *) . ./$lib ;; - esac - for l in $old_library $library_names; do - ll="$l" - done - if test "X$ll" = "X$old_library" ; then # only static version available - found=no - ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` - test "X$ladir" = "X$lib" && ladir="." - lib=$ladir/$old_library - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" - fi - continue - fi - fi - ;; - *) ;; - esac - fi - fi - ;; # -l - -L*) - case $linkmode in - lib) - deplibs="$deplib $deplibs" - test "$pass" = conv && continue - newdependency_libs="$deplib $newdependency_libs" - newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` - ;; - prog) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - continue - fi - if test "$pass" = scan; then - deplibs="$deplib $deplibs" - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` - ;; - *) - $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2 - ;; - esac # linkmode - continue - ;; # -L - -R*) - if test "$pass" = link; then - dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` - # Make sure the xrpath contains only unique directories. - case "$xrpath " in - *" $dir "*) ;; - *) xrpath="$xrpath $dir" ;; - esac - fi - deplibs="$deplib $deplibs" - continue - ;; - *.la) lib="$deplib" ;; - *.$libext) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - continue - fi - case $linkmode in - lib) - valid_a_lib=no - case $deplibs_check_method in - match_pattern*) - set dummy $deplibs_check_method - match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` - if eval $echo \"$deplib\" 2>/dev/null \ - | $SED 10q \ - | $EGREP "$match_pattern_regex" > /dev/null; then - valid_a_lib=yes - fi - ;; - pass_all) - valid_a_lib=yes - ;; - esac - if test "$valid_a_lib" != yes; then - $echo - $echo "*** Warning: Trying to link with static lib archive $deplib." - $echo "*** I have the capability to make that library automatically link in when" - $echo "*** you link to this library. But I can only do this if you have a" - $echo "*** shared version of the library, which you do not appear to have" - $echo "*** because the file extensions .$libext of this argument makes me believe" - $echo "*** that it is just a static archive that I should not used here." - else - $echo - $echo "*** Warning: Linking the shared library $output against the" - $echo "*** static library $deplib is not portable!" - deplibs="$deplib $deplibs" - fi - continue - ;; - prog) - if test "$pass" != link; then - deplibs="$deplib $deplibs" - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - continue - ;; - esac # linkmode - ;; # *.$libext - *.lo | *.$objext) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - elif test "$linkmode" = prog; then - if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then - # If there is no dlopen support or we're linking statically, - # we need to preload. - newdlprefiles="$newdlprefiles $deplib" - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - newdlfiles="$newdlfiles $deplib" - fi - fi - continue - ;; - %DEPLIBS%) - alldeplibs=yes - continue - ;; - esac # case $deplib - if test "$found" = yes || test -f "$lib"; then : - else - $echo "$modename: cannot find the library \`$lib'" 1>&2 - exit $EXIT_FAILURE - fi - - # Check to see that this really is a libtool archive. - if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : - else - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - exit $EXIT_FAILURE - fi - - ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` - test "X$ladir" = "X$lib" && ladir="." - - dlname= - dlopen= - dlpreopen= - libdir= - library_names= - old_library= - # If the library was installed with an old release of libtool, - # it will not redefine variables installed, or shouldnotlink - installed=yes - shouldnotlink=no - avoidtemprpath= - - - # Read the .la file - case $lib in - */* | *\\*) . $lib ;; - *) . ./$lib ;; - esac - - if test "$linkmode,$pass" = "lib,link" || - test "$linkmode,$pass" = "prog,scan" || - { test "$linkmode" != prog && test "$linkmode" != lib; }; then - test -n "$dlopen" && dlfiles="$dlfiles $dlopen" - test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" - fi - - if test "$pass" = conv; then - # Only check for convenience libraries - deplibs="$lib $deplibs" - if test -z "$libdir"; then - if test -z "$old_library"; then - $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 - exit $EXIT_FAILURE - fi - # It is a libtool convenience library, so add in its objects. - convenience="$convenience $ladir/$objdir/$old_library" - old_convenience="$old_convenience $ladir/$objdir/$old_library" - tmp_libs= - for deplib in $dependency_libs; do - deplibs="$deplib $deplibs" - if test "X$duplicate_deps" = "Xyes" ; then - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - tmp_libs="$tmp_libs $deplib" - done - elif test "$linkmode" != prog && test "$linkmode" != lib; then - $echo "$modename: \`$lib' is not a convenience library" 1>&2 - exit $EXIT_FAILURE - fi - continue - fi # $pass = conv - - - # Get the name of the library we link against. - linklib= - for l in $old_library $library_names; do - linklib="$l" - done - if test -z "$linklib"; then - $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 - exit $EXIT_FAILURE - fi - - # This library was specified with -dlopen. - if test "$pass" = dlopen; then - if test -z "$libdir"; then - $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 - exit $EXIT_FAILURE - fi - if test -z "$dlname" || - test "$dlopen_support" != yes || - test "$build_libtool_libs" = no; then - # If there is no dlname, no dlopen support or we're linking - # statically, we need to preload. We also need to preload any - # dependent libraries so libltdl's deplib preloader doesn't - # bomb out in the load deplibs phase. - dlprefiles="$dlprefiles $lib $dependency_libs" - else - newdlfiles="$newdlfiles $lib" - fi - continue - fi # $pass = dlopen - - # We need an absolute path. - case $ladir in - [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; - *) - abs_ladir=`cd "$ladir" && pwd` - if test -z "$abs_ladir"; then - $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 - $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 - abs_ladir="$ladir" - fi - ;; - esac - laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` - - # Find the relevant object directory and library name. - if test "X$installed" = Xyes; then - if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then - $echo "$modename: warning: library \`$lib' was moved." 1>&2 - dir="$ladir" - absdir="$abs_ladir" - libdir="$abs_ladir" - else - dir="$libdir" - absdir="$libdir" - fi - test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes - else - if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then - dir="$ladir" - absdir="$abs_ladir" - # Remove this search path later - notinst_path="$notinst_path $abs_ladir" - else - dir="$ladir/$objdir" - absdir="$abs_ladir/$objdir" - # Remove this search path later - notinst_path="$notinst_path $abs_ladir" - fi - fi # $installed = yes - name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` - - # This library was specified with -dlpreopen. - if test "$pass" = dlpreopen; then - if test -z "$libdir"; then - $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 - exit $EXIT_FAILURE - fi - # Prefer using a static library (so that no silly _DYNAMIC symbols - # are required to link). - if test -n "$old_library"; then - newdlprefiles="$newdlprefiles $dir/$old_library" - # Otherwise, use the dlname, so that lt_dlopen finds it. - elif test -n "$dlname"; then - newdlprefiles="$newdlprefiles $dir/$dlname" - else - newdlprefiles="$newdlprefiles $dir/$linklib" - fi - fi # $pass = dlpreopen - - if test -z "$libdir"; then - # Link the convenience library - if test "$linkmode" = lib; then - deplibs="$dir/$old_library $deplibs" - elif test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$dir/$old_library $compile_deplibs" - finalize_deplibs="$dir/$old_library $finalize_deplibs" - else - deplibs="$lib $deplibs" # used for prog,scan pass - fi - continue - fi - - - if test "$linkmode" = prog && test "$pass" != link; then - newlib_search_path="$newlib_search_path $ladir" - deplibs="$lib $deplibs" - - linkalldeplibs=no - if test "$link_all_deplibs" != no || test -z "$library_names" || - test "$build_libtool_libs" = no; then - linkalldeplibs=yes - fi - - tmp_libs= - for deplib in $dependency_libs; do - case $deplib in - -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test - esac - # Need to link against all dependency_libs? - if test "$linkalldeplibs" = yes; then - deplibs="$deplib $deplibs" - else - # Need to hardcode shared library paths - # or/and link against static libraries - newdependency_libs="$deplib $newdependency_libs" - fi - if test "X$duplicate_deps" = "Xyes" ; then - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - tmp_libs="$tmp_libs $deplib" - done # for deplib - continue - fi # $linkmode = prog... - - if test "$linkmode,$pass" = "prog,link"; then - if test -n "$library_names" && - { test "$prefer_static_libs" = no || test -z "$old_library"; }; then - # We need to hardcode the library path - if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then - # Make sure the rpath contains only unique directories. - case "$temp_rpath " in - *" $dir "*) ;; - *" $absdir "*) ;; - *) temp_rpath="$temp_rpath $absdir" ;; - esac - fi - - # Hardcode the library path. - # Skip directories that are in the system default run-time - # search path. - case " $sys_lib_dlsearch_path " in - *" $absdir "*) ;; - *) - case "$compile_rpath " in - *" $absdir "*) ;; - *) compile_rpath="$compile_rpath $absdir" - esac - ;; - esac - case " $sys_lib_dlsearch_path " in - *" $libdir "*) ;; - *) - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" - esac - ;; - esac - fi # $linkmode,$pass = prog,link... - - if test "$alldeplibs" = yes && - { test "$deplibs_check_method" = pass_all || - { test "$build_libtool_libs" = yes && - test -n "$library_names"; }; }; then - # We only need to search for static libraries - continue - fi - fi - - link_static=no # Whether the deplib will be linked statically - if test -n "$library_names" && - { test "$prefer_static_libs" = no || test -z "$old_library"; }; then - if test "$installed" = no; then - notinst_deplibs="$notinst_deplibs $lib" - need_relink=yes - fi - # This is a shared library - - # Warn about portability, can't link against -module's on - # some systems (darwin) - if test "$shouldnotlink" = yes && test "$pass" = link ; then - $echo - if test "$linkmode" = prog; then - $echo "*** Warning: Linking the executable $output against the loadable module" - else - $echo "*** Warning: Linking the shared library $output against the loadable module" - fi - $echo "*** $linklib is not portable!" - fi - if test "$linkmode" = lib && - test "$hardcode_into_libs" = yes; then - # Hardcode the library path. - # Skip directories that are in the system default run-time - # search path. - case " $sys_lib_dlsearch_path " in - *" $absdir "*) ;; - *) - case "$compile_rpath " in - *" $absdir "*) ;; - *) compile_rpath="$compile_rpath $absdir" - esac - ;; - esac - case " $sys_lib_dlsearch_path " in - *" $libdir "*) ;; - *) - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" - esac - ;; - esac - fi - - if test -n "$old_archive_from_expsyms_cmds"; then - # figure out the soname - set dummy $library_names - realname="$2" - shift; shift - libname=`eval \\$echo \"$libname_spec\"` - # use dlname if we got it. it's perfectly good, no? - if test -n "$dlname"; then - soname="$dlname" - elif test -n "$soname_spec"; then - # bleh windows - case $host in - *cygwin* | mingw*) - major=`expr $current - $age` - versuffix="-$major" - ;; - esac - eval soname=\"$soname_spec\" - else - soname="$realname" - fi - - # Make a new name for the extract_expsyms_cmds to use - soroot="$soname" - soname=`$echo $soroot | ${SED} -e 's/^.*\///'` - newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a" - - # If the library has no export list, then create one now - if test -f "$output_objdir/$soname-def"; then : - else - $show "extracting exported symbol list from \`$soname'" - save_ifs="$IFS"; IFS='~' - cmds=$extract_expsyms_cmds - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - fi - - # Create $newlib - if test -f "$output_objdir/$newlib"; then :; else - $show "generating import library for \`$soname'" - save_ifs="$IFS"; IFS='~' - cmds=$old_archive_from_expsyms_cmds - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - fi - # make sure the library variables are pointing to the new library - dir=$output_objdir - linklib=$newlib - fi # test -n "$old_archive_from_expsyms_cmds" - - if test "$linkmode" = prog || test "$mode" != relink; then - add_shlibpath= - add_dir= - add= - lib_linked=yes - case $hardcode_action in - immediate | unsupported) - if test "$hardcode_direct" = no; then - add="$dir/$linklib" - case $host in - *-*-sco3.2v5* ) add_dir="-L$dir" ;; - *-*-darwin* ) - # if the lib is a module then we can not link against - # it, someone is ignoring the new warnings I added - if /usr/bin/file -L $add 2> /dev/null | $EGREP "bundle" >/dev/null ; then - $echo "** Warning, lib $linklib is a module, not a shared library" - if test -z "$old_library" ; then - $echo - $echo "** And there doesn't seem to be a static archive available" - $echo "** The link will probably fail, sorry" - else - add="$dir/$old_library" - fi - fi - esac - elif test "$hardcode_minus_L" = no; then - case $host in - *-*-sunos*) add_shlibpath="$dir" ;; - esac - add_dir="-L$dir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = no; then - add_shlibpath="$dir" - add="-l$name" - else - lib_linked=no - fi - ;; - relink) - if test "$hardcode_direct" = yes; then - add="$dir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$dir" - # Try looking first in the location we're being installed to. - if test -n "$inst_prefix_dir"; then - case $libdir in - [\\/]*) - add_dir="$add_dir -L$inst_prefix_dir$libdir" - ;; - esac - fi - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then - add_shlibpath="$dir" - add="-l$name" - else - lib_linked=no - fi - ;; - *) lib_linked=no ;; - esac - - if test "$lib_linked" != yes; then - $echo "$modename: configuration error: unsupported hardcode properties" - exit $EXIT_FAILURE - fi - - if test -n "$add_shlibpath"; then - case :$compile_shlibpath: in - *":$add_shlibpath:"*) ;; - *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; - esac - fi - if test "$linkmode" = prog; then - test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" - test -n "$add" && compile_deplibs="$add $compile_deplibs" - else - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - if test "$hardcode_direct" != yes && \ - test "$hardcode_minus_L" != yes && \ - test "$hardcode_shlibpath_var" = yes; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; - esac - fi - fi - fi - - if test "$linkmode" = prog || test "$mode" = relink; then - add_shlibpath= - add_dir= - add= - # Finalize command for both is simple: just hardcode it. - if test "$hardcode_direct" = yes; then - add="$libdir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$libdir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; - esac - add="-l$name" - elif test "$hardcode_automatic" = yes; then - if test -n "$inst_prefix_dir" && - test -f "$inst_prefix_dir$libdir/$linklib" ; then - add="$inst_prefix_dir$libdir/$linklib" - else - add="$libdir/$linklib" - fi - else - # We cannot seem to hardcode it, guess we'll fake it. - add_dir="-L$libdir" - # Try looking first in the location we're being installed to. - if test -n "$inst_prefix_dir"; then - case $libdir in - [\\/]*) - add_dir="$add_dir -L$inst_prefix_dir$libdir" - ;; - esac - fi - add="-l$name" - fi - - if test "$linkmode" = prog; then - test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" - test -n "$add" && finalize_deplibs="$add $finalize_deplibs" - else - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - fi - fi - elif test "$linkmode" = prog; then - # Here we assume that one of hardcode_direct or hardcode_minus_L - # is not unsupported. This is valid on all known static and - # shared platforms. - if test "$hardcode_direct" != unsupported; then - test -n "$old_library" && linklib="$old_library" - compile_deplibs="$dir/$linklib $compile_deplibs" - finalize_deplibs="$dir/$linklib $finalize_deplibs" - else - compile_deplibs="-l$name -L$dir $compile_deplibs" - finalize_deplibs="-l$name -L$dir $finalize_deplibs" - fi - elif test "$build_libtool_libs" = yes; then - # Not a shared library - if test "$deplibs_check_method" != pass_all; then - # We're trying link a shared library against a static one - # but the system doesn't support it. - - # Just print a warning and add the library to dependency_libs so - # that the program can be linked against the static library. - $echo - $echo "*** Warning: This system can not link to static lib archive $lib." - $echo "*** I have the capability to make that library automatically link in when" - $echo "*** you link to this library. But I can only do this if you have a" - $echo "*** shared version of the library, which you do not appear to have." - if test "$module" = yes; then - $echo "*** But as you try to build a module library, libtool will still create " - $echo "*** a static module, that should work as long as the dlopening application" - $echo "*** is linked with the -dlopen flag to resolve symbols at runtime." - if test -z "$global_symbol_pipe"; then - $echo - $echo "*** However, this would only work if libtool was able to extract symbol" - $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" - $echo "*** not find such a program. So, this module is probably useless." - $echo "*** \`nm' from GNU binutils and a full rebuild may help." - fi - if test "$build_old_libs" = no; then - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - else - deplibs="$dir/$old_library $deplibs" - link_static=yes - fi - fi # link shared/static library? - - if test "$linkmode" = lib; then - if test -n "$dependency_libs" && - { test "$hardcode_into_libs" != yes || - test "$build_old_libs" = yes || - test "$link_static" = yes; }; then - # Extract -R from dependency_libs - temp_deplibs= - for libdir in $dependency_libs; do - case $libdir in - -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` - case " $xrpath " in - *" $temp_xrpath "*) ;; - *) xrpath="$xrpath $temp_xrpath";; - esac;; - *) temp_deplibs="$temp_deplibs $libdir";; - esac - done - dependency_libs="$temp_deplibs" - fi - - newlib_search_path="$newlib_search_path $absdir" - # Link against this library - test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" - # ... and its dependency_libs - tmp_libs= - for deplib in $dependency_libs; do - newdependency_libs="$deplib $newdependency_libs" - if test "X$duplicate_deps" = "Xyes" ; then - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - tmp_libs="$tmp_libs $deplib" - done - - if test "$link_all_deplibs" != no; then - # Add the search paths of all dependency libraries - for deplib in $dependency_libs; do - case $deplib in - -L*) path="$deplib" ;; - *.la) - dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` - test "X$dir" = "X$deplib" && dir="." - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; - *) - absdir=`cd "$dir" && pwd` - if test -z "$absdir"; then - $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 - absdir="$dir" - fi - ;; - esac - if grep "^installed=no" $deplib > /dev/null; then - path="$absdir/$objdir" - else - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` - if test -z "$libdir"; then - $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 - exit $EXIT_FAILURE - fi - if test "$absdir" != "$libdir"; then - $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 - fi - path="$absdir" - fi - depdepl= - case $host in - *-*-darwin*) - # we do not want to link against static libs, - # but need to link against shared - eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` - if test -n "$deplibrary_names" ; then - for tmp in $deplibrary_names ; do - depdepl=$tmp - done - if test -f "$path/$depdepl" ; then - depdepl="$path/$depdepl" - fi - # do not add paths which are already there - case " $newlib_search_path " in - *" $path "*) ;; - *) newlib_search_path="$newlib_search_path $path";; - esac - fi - path="" - ;; - *) - path="-L$path" - ;; - esac - ;; - -l*) - case $host in - *-*-darwin*) - # Again, we only want to link against shared libraries - eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"` - for tmp in $newlib_search_path ; do - if test -f "$tmp/lib$tmp_libs.dylib" ; then - eval depdepl="$tmp/lib$tmp_libs.dylib" - break - fi - done - path="" - ;; - *) continue ;; - esac - ;; - *) continue ;; - esac - case " $deplibs " in - *" $path "*) ;; - *) deplibs="$path $deplibs" ;; - esac - case " $deplibs " in - *" $depdepl "*) ;; - *) deplibs="$depdepl $deplibs" ;; - esac - done - fi # link_all_deplibs != no - fi # linkmode = lib - done # for deplib in $libs - dependency_libs="$newdependency_libs" - if test "$pass" = dlpreopen; then - # Link the dlpreopened libraries before other libraries - for deplib in $save_deplibs; do - deplibs="$deplib $deplibs" - done - fi - if test "$pass" != dlopen; then - if test "$pass" != conv; then - # Make sure lib_search_path contains only unique directories. - lib_search_path= - for dir in $newlib_search_path; do - case "$lib_search_path " in - *" $dir "*) ;; - *) lib_search_path="$lib_search_path $dir" ;; - esac - done - newlib_search_path= - fi - - if test "$linkmode,$pass" != "prog,link"; then - vars="deplibs" - else - vars="compile_deplibs finalize_deplibs" - fi - for var in $vars dependency_libs; do - # Add libraries to $var in reverse order - eval tmp_libs=\"\$$var\" - new_libs= - for deplib in $tmp_libs; do - # FIXME: Pedantically, this is the right thing to do, so - # that some nasty dependency loop isn't accidentally - # broken: - #new_libs="$deplib $new_libs" - # Pragmatically, this seems to cause very few problems in - # practice: - case $deplib in - -L*) new_libs="$deplib $new_libs" ;; - -R*) ;; - *) - # And here is the reason: when a library appears more - # than once as an explicit dependence of a library, or - # is implicitly linked in more than once by the - # compiler, it is considered special, and multiple - # occurrences thereof are not removed. Compare this - # with having the same library being listed as a - # dependency of multiple other libraries: in this case, - # we know (pedantically, we assume) the library does not - # need to be listed more than once, so we keep only the - # last copy. This is not always right, but it is rare - # enough that we require users that really mean to play - # such unportable linking tricks to link the library - # using -Wl,-lname, so that libtool does not consider it - # for duplicate removal. - case " $specialdeplibs " in - *" $deplib "*) new_libs="$deplib $new_libs" ;; - *) - case " $new_libs " in - *" $deplib "*) ;; - *) new_libs="$deplib $new_libs" ;; - esac - ;; - esac - ;; - esac - done - tmp_libs= - for deplib in $new_libs; do - case $deplib in - -L*) - case " $tmp_libs " in - *" $deplib "*) ;; - *) tmp_libs="$tmp_libs $deplib" ;; - esac - ;; - *) tmp_libs="$tmp_libs $deplib" ;; - esac - done - eval $var=\"$tmp_libs\" - done # for var - fi - # Last step: remove runtime libs from dependency_libs - # (they stay in deplibs) - tmp_libs= - for i in $dependency_libs ; do - case " $predeps $postdeps $compiler_lib_search_path " in - *" $i "*) - i="" - ;; - esac - if test -n "$i" ; then - tmp_libs="$tmp_libs $i" - fi - done - dependency_libs=$tmp_libs - done # for pass - if test "$linkmode" = prog; then - dlfiles="$newdlfiles" - dlprefiles="$newdlprefiles" - fi - - case $linkmode in - oldlib) - if test -n "$deplibs"; then - $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 - fi - - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 - fi - - if test -n "$rpath"; then - $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 - fi - - if test -n "$xrpath"; then - $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 - fi - - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 - fi - - if test -n "$export_symbols" || test -n "$export_symbols_regex"; then - $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 - fi - - # Now set the variables for building old libraries. - build_libtool_libs=no - oldlibs="$output" - objs="$objs$old_deplibs" - ;; - - lib) - # Make sure we only generate libraries of the form `libNAME.la'. - case $outputname in - lib*) - name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` - eval shared_ext=\"$shrext_cmds\" - eval libname=\"$libname_spec\" - ;; - *) - if test "$module" = no; then - $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - if test "$need_lib_prefix" != no; then - # Add the "lib" prefix for modules if required - name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` - eval shared_ext=\"$shrext_cmds\" - eval libname=\"$libname_spec\" - else - libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` - fi - ;; - esac - - if test -n "$objs"; then - if test "$deplibs_check_method" != pass_all; then - $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 - exit $EXIT_FAILURE - else - $echo - $echo "*** Warning: Linking the shared library $output against the non-libtool" - $echo "*** objects $objs is not portable!" - libobjs="$libobjs $objs" - fi - fi - - if test "$dlself" != no; then - $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 - fi - - set dummy $rpath - if test "$#" -gt 2; then - $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 - fi - install_libdir="$2" - - oldlibs= - if test -z "$rpath"; then - if test "$build_libtool_libs" = yes; then - # Building a libtool convenience library. - # Some compilers have problems with a `.al' extension so - # convenience libraries should have the same extension an - # archive normally would. - oldlibs="$output_objdir/$libname.$libext $oldlibs" - build_libtool_libs=convenience - build_old_libs=yes - fi - - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 - fi - else - - # Parse the version information argument. - save_ifs="$IFS"; IFS=':' - set dummy $vinfo 0 0 0 - IFS="$save_ifs" - - if test -n "$8"; then - $echo "$modename: too many parameters to \`-version-info'" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - # convert absolute version numbers to libtool ages - # this retains compatibility with .la files and attempts - # to make the code below a bit more comprehensible - - case $vinfo_number in - yes) - number_major="$2" - number_minor="$3" - number_revision="$4" - # - # There are really only two kinds -- those that - # use the current revision as the major version - # and those that subtract age and use age as - # a minor version. But, then there is irix - # which has an extra 1 added just for fun - # - case $version_type in - darwin|linux|osf|windows) - current=`expr $number_major + $number_minor` - age="$number_minor" - revision="$number_revision" - ;; - freebsd-aout|freebsd-elf|sunos) - current="$number_major" - revision="$number_minor" - age="0" - ;; - irix|nonstopux) - current=`expr $number_major + $number_minor - 1` - age="$number_minor" - revision="$number_minor" - ;; - esac - ;; - no) - current="$2" - revision="$3" - age="$4" - ;; - esac - - # Check that each of the things are valid numbers. - case $current in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - $echo "$modename: CURRENT \`$current' must be a nonnegative integer" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit $EXIT_FAILURE - ;; - esac - - case $revision in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - $echo "$modename: REVISION \`$revision' must be a nonnegative integer" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit $EXIT_FAILURE - ;; - esac - - case $age in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - $echo "$modename: AGE \`$age' must be a nonnegative integer" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit $EXIT_FAILURE - ;; - esac - - if test "$age" -gt "$current"; then - $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit $EXIT_FAILURE - fi - - # Calculate the version variables. - major= - versuffix= - verstring= - case $version_type in - none) ;; - - darwin) - # Like Linux, but with the current version available in - # verstring for coding it into the library header - major=.`expr $current - $age` - versuffix="$major.$age.$revision" - # Darwin ld doesn't like 0 for these options... - minor_current=`expr $current + 1` - verstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" - ;; - - freebsd-aout) - major=".$current" - versuffix=".$current.$revision"; - ;; - - freebsd-elf) - major=".$current" - versuffix=".$current"; - ;; - - irix | nonstopux) - major=`expr $current - $age + 1` - - case $version_type in - nonstopux) verstring_prefix=nonstopux ;; - *) verstring_prefix=sgi ;; - esac - verstring="$verstring_prefix$major.$revision" - - # Add in all the interfaces that we are compatible with. - loop=$revision - while test "$loop" -ne 0; do - iface=`expr $revision - $loop` - loop=`expr $loop - 1` - verstring="$verstring_prefix$major.$iface:$verstring" - done - - # Before this point, $major must not contain `.'. - major=.$major - versuffix="$major.$revision" - ;; - - linux) - major=.`expr $current - $age` - versuffix="$major.$age.$revision" - ;; - - osf) - major=.`expr $current - $age` - versuffix=".$current.$age.$revision" - verstring="$current.$age.$revision" - - # Add in all the interfaces that we are compatible with. - loop=$age - while test "$loop" -ne 0; do - iface=`expr $current - $loop` - loop=`expr $loop - 1` - verstring="$verstring:${iface}.0" - done - - # Make executables depend on our current version. - verstring="$verstring:${current}.0" - ;; - - sunos) - major=".$current" - versuffix=".$current.$revision" - ;; - - windows) - # Use '-' rather than '.', since we only want one - # extension on DOS 8.3 filesystems. - major=`expr $current - $age` - versuffix="-$major" - ;; - - *) - $echo "$modename: unknown library version type \`$version_type'" 1>&2 - $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 - exit $EXIT_FAILURE - ;; - esac - - # Clear the version info if we defaulted, and they specified a release. - if test -z "$vinfo" && test -n "$release"; then - major= - case $version_type in - darwin) - # we can't check for "0.0" in archive_cmds due to quoting - # problems, so we reset it completely - verstring= - ;; - *) - verstring="0.0" - ;; - esac - if test "$need_version" = no; then - versuffix= - else - versuffix=".0.0" - fi - fi - - # Remove version info from name if versioning should be avoided - if test "$avoid_version" = yes && test "$need_version" = no; then - major= - versuffix= - verstring="" - fi - - # Check to see if the archive will have undefined symbols. - if test "$allow_undefined" = yes; then - if test "$allow_undefined_flag" = unsupported; then - $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 - build_libtool_libs=no - build_old_libs=yes - fi - else - # Don't allow undefined symbols. - allow_undefined_flag="$no_undefined_flag" - fi - fi - - if test "$mode" != relink; then - # Remove our outputs, but don't remove object files since they - # may have been created when compiling PIC objects. - removelist= - tempremovelist=`$echo "$output_objdir/*"` - for p in $tempremovelist; do - case $p in - *.$objext) - ;; - $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) - if test "X$precious_files_regex" != "X"; then - if echo $p | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 - then - continue - fi - fi - removelist="$removelist $p" - ;; - *) ;; - esac - done - if test -n "$removelist"; then - $show "${rm}r $removelist" - $run ${rm}r $removelist - fi - fi - - # Now set the variables for building old libraries. - if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then - oldlibs="$oldlibs $output_objdir/$libname.$libext" - - # Transform .lo files to .o files. - oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` - fi - - # Eliminate all temporary directories. - for path in $notinst_path; do - lib_search_path=`$echo "$lib_search_path " | ${SED} -e 's% $path % %g'` - deplibs=`$echo "$deplibs " | ${SED} -e 's% -L$path % %g'` - dependency_libs=`$echo "$dependency_libs " | ${SED} -e 's% -L$path % %g'` - done - - if test -n "$xrpath"; then - # If the user specified any rpath flags, then add them. - temp_xrpath= - for libdir in $xrpath; do - temp_xrpath="$temp_xrpath -R$libdir" - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" ;; - esac - done - if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then - dependency_libs="$temp_xrpath $dependency_libs" - fi - fi - - # Make sure dlfiles contains only unique files that won't be dlpreopened - old_dlfiles="$dlfiles" - dlfiles= - for lib in $old_dlfiles; do - case " $dlprefiles $dlfiles " in - *" $lib "*) ;; - *) dlfiles="$dlfiles $lib" ;; - esac - done - - # Make sure dlprefiles contains only unique files - old_dlprefiles="$dlprefiles" - dlprefiles= - for lib in $old_dlprefiles; do - case "$dlprefiles " in - *" $lib "*) ;; - *) dlprefiles="$dlprefiles $lib" ;; - esac - done - - if test "$build_libtool_libs" = yes; then - if test -n "$rpath"; then - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) - # these systems don't actually have a c library (as such)! - ;; - *-*-rhapsody* | *-*-darwin1.[012]) - # Rhapsody C library is in the System framework - deplibs="$deplibs -framework System" - ;; - *-*-netbsd*) - # Don't link with libc until the a.out ld.so is fixed. - ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) - # Do not include libc due to us having libc/libc_r. - test "X$arg" = "X-lc" && continue - ;; - *) - # Add libc to deplibs on all other systems if necessary. - if test "$build_libtool_need_lc" = "yes"; then - deplibs="$deplibs -lc" - fi - ;; - esac - fi - - # Transform deplibs into only deplibs that can be linked in shared. - name_save=$name - libname_save=$libname - release_save=$release - versuffix_save=$versuffix - major_save=$major - # I'm not sure if I'm treating the release correctly. I think - # release should show up in the -l (ie -lgmp5) so we don't want to - # add it in twice. Is that correct? - release="" - versuffix="" - major="" - newdeplibs= - droppeddeps=no - case $deplibs_check_method in - pass_all) - # Don't check for shared/static. Everything works. - # This might be a little naive. We might want to check - # whether the library exists or not. But this is on - # osf3 & osf4 and I'm not really sure... Just - # implementing what was already the behavior. - newdeplibs=$deplibs - ;; - test_compile) - # This code stresses the "libraries are programs" paradigm to its - # limits. Maybe even breaks it. We compile a program, linking it - # against the deplibs as a proxy for the library. Then we can check - # whether they linked in statically or dynamically with ldd. - $rm conftest.c - cat > conftest.c <<EOF - int main() { return 0; } -EOF - $rm conftest - $LTCC -o conftest conftest.c $deplibs - if test "$?" -eq 0 ; then - ldd_output=`ldd conftest` - for i in $deplibs; do - name=`expr $i : '-l\(.*\)'` - # If $name is empty we are operating on a -L argument. - if test "$name" != "" && test "$name" -ne "0"; then - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - case " $predeps $postdeps " in - *" $i "*) - newdeplibs="$newdeplibs $i" - i="" - ;; - esac - fi - if test -n "$i" ; then - libname=`eval \\$echo \"$libname_spec\"` - deplib_matches=`eval \\$echo \"$library_names_spec\"` - set dummy $deplib_matches - deplib_match=$2 - if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then - newdeplibs="$newdeplibs $i" - else - droppeddeps=yes - $echo - $echo "*** Warning: dynamic linker does not accept needed library $i." - $echo "*** I have the capability to make that library automatically link in when" - $echo "*** you link to this library. But I can only do this if you have a" - $echo "*** shared version of the library, which I believe you do not have" - $echo "*** because a test_compile did reveal that the linker did not use it for" - $echo "*** its dynamic dependency list that programs get resolved with at runtime." - fi - fi - else - newdeplibs="$newdeplibs $i" - fi - done - else - # Error occurred in the first compile. Let's try to salvage - # the situation: Compile a separate program for each library. - for i in $deplibs; do - name=`expr $i : '-l\(.*\)'` - # If $name is empty we are operating on a -L argument. - if test "$name" != "" && test "$name" != "0"; then - $rm conftest - $LTCC -o conftest conftest.c $i - # Did it work? - if test "$?" -eq 0 ; then - ldd_output=`ldd conftest` - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - case " $predeps $postdeps " in - *" $i "*) - newdeplibs="$newdeplibs $i" - i="" - ;; - esac - fi - if test -n "$i" ; then - libname=`eval \\$echo \"$libname_spec\"` - deplib_matches=`eval \\$echo \"$library_names_spec\"` - set dummy $deplib_matches - deplib_match=$2 - if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then - newdeplibs="$newdeplibs $i" - else - droppeddeps=yes - $echo - $echo "*** Warning: dynamic linker does not accept needed library $i." - $echo "*** I have the capability to make that library automatically link in when" - $echo "*** you link to this library. But I can only do this if you have a" - $echo "*** shared version of the library, which you do not appear to have" - $echo "*** because a test_compile did reveal that the linker did not use this one" - $echo "*** as a dynamic dependency that programs can get resolved with at runtime." - fi - fi - else - droppeddeps=yes - $echo - $echo "*** Warning! Library $i is needed by this library but I was not able to" - $echo "*** make it link in! You will probably need to install it or some" - $echo "*** library that it depends on before this library will be fully" - $echo "*** functional. Installing it before continuing would be even better." - fi - else - newdeplibs="$newdeplibs $i" - fi - done - fi - ;; - file_magic*) - set dummy $deplibs_check_method - file_magic_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` - for a_deplib in $deplibs; do - name=`expr $a_deplib : '-l\(.*\)'` - # If $name is empty we are operating on a -L argument. - if test "$name" != "" && test "$name" != "0"; then - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - case " $predeps $postdeps " in - *" $a_deplib "*) - newdeplibs="$newdeplibs $a_deplib" - a_deplib="" - ;; - esac - fi - if test -n "$a_deplib" ; then - libname=`eval \\$echo \"$libname_spec\"` - for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do - potential_libs=`ls $i/$libname[.-]* 2>/dev/null` - for potent_lib in $potential_libs; do - # Follow soft links. - if ls -lLd "$potent_lib" 2>/dev/null \ - | grep " -> " >/dev/null; then - continue - fi - # The statement above tries to avoid entering an - # endless loop below, in case of cyclic links. - # We might still enter an endless loop, since a link - # loop can be closed while we follow links, - # but so what? - potlib="$potent_lib" - while test -h "$potlib" 2>/dev/null; do - potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` - case $potliblink in - [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; - *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; - esac - done - if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ - | ${SED} 10q \ - | $EGREP "$file_magic_regex" > /dev/null; then - newdeplibs="$newdeplibs $a_deplib" - a_deplib="" - break 2 - fi - done - done - fi - if test -n "$a_deplib" ; then - droppeddeps=yes - $echo - $echo "*** Warning: linker path does not have real file for library $a_deplib." - $echo "*** I have the capability to make that library automatically link in when" - $echo "*** you link to this library. But I can only do this if you have a" - $echo "*** shared version of the library, which you do not appear to have" - $echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib" ; then - $echo "*** with $libname but no candidates were found. (...for file magic test)" - else - $echo "*** with $libname and none of the candidates passed a file format test" - $echo "*** using a file magic. Last file checked: $potlib" - fi - fi - else - # Add a -L argument. - newdeplibs="$newdeplibs $a_deplib" - fi - done # Gone through all deplibs. - ;; - match_pattern*) - set dummy $deplibs_check_method - match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` - for a_deplib in $deplibs; do - name=`expr $a_deplib : '-l\(.*\)'` - # If $name is empty we are operating on a -L argument. - if test -n "$name" && test "$name" != "0"; then - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - case " $predeps $postdeps " in - *" $a_deplib "*) - newdeplibs="$newdeplibs $a_deplib" - a_deplib="" - ;; - esac - fi - if test -n "$a_deplib" ; then - libname=`eval \\$echo \"$libname_spec\"` - for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do - potential_libs=`ls $i/$libname[.-]* 2>/dev/null` - for potent_lib in $potential_libs; do - potlib="$potent_lib" # see symlink-check above in file_magic test - if eval $echo \"$potent_lib\" 2>/dev/null \ - | ${SED} 10q \ - | $EGREP "$match_pattern_regex" > /dev/null; then - newdeplibs="$newdeplibs $a_deplib" - a_deplib="" - break 2 - fi - done - done - fi - if test -n "$a_deplib" ; then - droppeddeps=yes - $echo - $echo "*** Warning: linker path does not have real file for library $a_deplib." - $echo "*** I have the capability to make that library automatically link in when" - $echo "*** you link to this library. But I can only do this if you have a" - $echo "*** shared version of the library, which you do not appear to have" - $echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib" ; then - $echo "*** with $libname but no candidates were found. (...for regex pattern test)" - else - $echo "*** with $libname and none of the candidates passed a file format test" - $echo "*** using a regex pattern. Last file checked: $potlib" - fi - fi - else - # Add a -L argument. - newdeplibs="$newdeplibs $a_deplib" - fi - done # Gone through all deplibs. - ;; - none | unknown | *) - newdeplibs="" - tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ - -e 's/ -[LR][^ ]*//g'` - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - for i in $predeps $postdeps ; do - # can't use Xsed below, because $i might contain '/' - tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"` - done - fi - if $echo "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' \ - | grep . >/dev/null; then - $echo - if test "X$deplibs_check_method" = "Xnone"; then - $echo "*** Warning: inter-library dependencies are not supported in this platform." - else - $echo "*** Warning: inter-library dependencies are not known to be supported." - fi - $echo "*** All declared inter-library dependencies are being dropped." - droppeddeps=yes - fi - ;; - esac - versuffix=$versuffix_save - major=$major_save - release=$release_save - libname=$libname_save - name=$name_save - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library is the System framework - newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` - ;; - esac - - if test "$droppeddeps" = yes; then - if test "$module" = yes; then - $echo - $echo "*** Warning: libtool could not satisfy all declared inter-library" - $echo "*** dependencies of module $libname. Therefore, libtool will create" - $echo "*** a static module, that should work as long as the dlopening" - $echo "*** application is linked with the -dlopen flag." - if test -z "$global_symbol_pipe"; then - $echo - $echo "*** However, this would only work if libtool was able to extract symbol" - $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" - $echo "*** not find such a program. So, this module is probably useless." - $echo "*** \`nm' from GNU binutils and a full rebuild may help." - fi - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - else - $echo "*** The inter-library dependencies that have been dropped here will be" - $echo "*** automatically added whenever a program is linked with this library" - $echo "*** or is declared to -dlopen it." - - if test "$allow_undefined" = no; then - $echo - $echo "*** Since this library must not contain undefined symbols," - $echo "*** because either the platform does not support them or" - $echo "*** it was explicitly requested with -no-undefined," - $echo "*** libtool will only create a static version of it." - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - fi - fi - # Done checking deplibs! - deplibs=$newdeplibs - fi - - # All the library-specific variables (install_libdir is set above). - library_names= - old_library= - dlname= - - # Test again, we may have decided not to build it any more - if test "$build_libtool_libs" = yes; then - if test "$hardcode_into_libs" = yes; then - # Hardcode the library paths - hardcode_libdirs= - dep_rpath= - rpath="$finalize_rpath" - test "$mode" != relink && rpath="$compile_rpath$rpath" - for libdir in $rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - dep_rpath="$dep_rpath $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) perm_rpath="$perm_rpath $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - if test -n "$hardcode_libdir_flag_spec_ld"; then - eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" - else - eval dep_rpath=\"$hardcode_libdir_flag_spec\" - fi - fi - if test -n "$runpath_var" && test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - rpath="$rpath$dir:" - done - eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" - fi - test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" - fi - - shlibpath="$finalize_shlibpath" - test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" - if test -n "$shlibpath"; then - eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" - fi - - # Get the real and link names of the library. - eval shared_ext=\"$shrext_cmds\" - eval library_names=\"$library_names_spec\" - set dummy $library_names - realname="$2" - shift; shift - - if test -n "$soname_spec"; then - eval soname=\"$soname_spec\" - else - soname="$realname" - fi - if test -z "$dlname"; then - dlname=$soname - fi - - lib="$output_objdir/$realname" - for link - do - linknames="$linknames $link" - done - - # Use standard objects if they are pic - test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then - $show "generating symbol list for \`$libname.la'" - export_symbols="$output_objdir/$libname.exp" - $run $rm $export_symbols - cmds=$export_symbols_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - if len=`expr "X$cmd" : ".*"` && - test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then - $show "$cmd" - $run eval "$cmd" || exit $? - skipped_export=false - else - # The command line is too long to execute in one step. - $show "using reloadable object file for export list..." - skipped_export=: - # Break out early, otherwise skipped_export may be - # set to false by a later but shorter cmd. - break - fi - done - IFS="$save_ifs" - if test -n "$export_symbols_regex"; then - $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" - $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' - $show "$mv \"${export_symbols}T\" \"$export_symbols\"" - $run eval '$mv "${export_symbols}T" "$export_symbols"' - fi - fi - fi - - if test -n "$export_symbols" && test -n "$include_expsyms"; then - $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' - fi - - tmp_deplibs= - for test_deplib in $deplibs; do - case " $convenience " in - *" $test_deplib "*) ;; - *) - tmp_deplibs="$tmp_deplibs $test_deplib" - ;; - esac - done - deplibs="$tmp_deplibs" - - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec"; then - save_libobjs=$libobjs - eval libobjs=\"\$libobjs $whole_archive_flag_spec\" - else - gentop="$output_objdir/${outputname}x" - generated="$generated $gentop" - - func_extract_archives $gentop $convenience - libobjs="$libobjs $func_extract_archives_result" - fi - fi - - if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then - eval flag=\"$thread_safe_flag_spec\" - linker_flags="$linker_flags $flag" - fi - - # Make a backup of the uninstalled library when relinking - if test "$mode" = relink; then - $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? - fi - - # Do each of the archive commands. - if test "$module" = yes && test -n "$module_cmds" ; then - if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then - eval test_cmds=\"$module_expsym_cmds\" - cmds=$module_expsym_cmds - else - eval test_cmds=\"$module_cmds\" - cmds=$module_cmds - fi - else - if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then - eval test_cmds=\"$archive_expsym_cmds\" - cmds=$archive_expsym_cmds - else - eval test_cmds=\"$archive_cmds\" - cmds=$archive_cmds - fi - fi - - if test "X$skipped_export" != "X:" && - len=`expr "X$test_cmds" : ".*" 2>/dev/null` && - test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then - : - else - # The command line is too long to link in one step, link piecewise. - $echo "creating reloadable object files..." - - # Save the value of $output and $libobjs because we want to - # use them later. If we have whole_archive_flag_spec, we - # want to use save_libobjs as it was before - # whole_archive_flag_spec was expanded, because we can't - # assume the linker understands whole_archive_flag_spec. - # This may have to be revisited, in case too many - # convenience libraries get linked in and end up exceeding - # the spec. - if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then - save_libobjs=$libobjs - fi - save_output=$output - output_la=`$echo "X$output" | $Xsed -e "$basename"` - - # Clear the reloadable object creation command queue and - # initialize k to one. - test_cmds= - concat_cmds= - objlist= - delfiles= - last_robj= - k=1 - output=$output_objdir/$output_la-${k}.$objext - # Loop over the list of objects to be linked. - for obj in $save_libobjs - do - eval test_cmds=\"$reload_cmds $objlist $last_robj\" - if test "X$objlist" = X || - { len=`expr "X$test_cmds" : ".*" 2>/dev/null` && - test "$len" -le "$max_cmd_len"; }; then - objlist="$objlist $obj" - else - # The command $test_cmds is almost too long, add a - # command to the queue. - if test "$k" -eq 1 ; then - # The first file doesn't have a previous command to add. - eval concat_cmds=\"$reload_cmds $objlist $last_robj\" - else - # All subsequent reloadable object files will link in - # the last one created. - eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\" - fi - last_robj=$output_objdir/$output_la-${k}.$objext - k=`expr $k + 1` - output=$output_objdir/$output_la-${k}.$objext - objlist=$obj - len=1 - fi - done - # Handle the remaining objects by creating one last - # reloadable object file. All subsequent reloadable object - # files will link in the last one created. - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" - - if ${skipped_export-false}; then - $show "generating symbol list for \`$libname.la'" - export_symbols="$output_objdir/$libname.exp" - $run $rm $export_symbols - libobjs=$output - # Append the command to create the export file. - eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\" - fi - - # Set up a command to remove the reloadable object files - # after they are used. - i=0 - while test "$i" -lt "$k" - do - i=`expr $i + 1` - delfiles="$delfiles $output_objdir/$output_la-${i}.$objext" - done - - $echo "creating a temporary reloadable object file: $output" - - # Loop through the commands generated above and execute them. - save_ifs="$IFS"; IFS='~' - for cmd in $concat_cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - - libobjs=$output - # Restore the value of output. - output=$save_output - - if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then - eval libobjs=\"\$libobjs $whole_archive_flag_spec\" - fi - # Expand the library linking commands again to reset the - # value of $libobjs for piecewise linking. - - # Do each of the archive commands. - if test "$module" = yes && test -n "$module_cmds" ; then - if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then - cmds=$module_expsym_cmds - else - cmds=$module_cmds - fi - else - if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then - cmds=$archive_expsym_cmds - else - cmds=$archive_cmds - fi - fi - - # Append the command to remove the reloadable object files - # to the just-reset $cmds. - eval cmds=\"\$cmds~\$rm $delfiles\" - fi - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || { - lt_exit=$? - - # Restore the uninstalled library and exit - if test "$mode" = relink; then - $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)' - fi - - exit $lt_exit - } - done - IFS="$save_ifs" - - # Restore the uninstalled library and exit - if test "$mode" = relink; then - $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? - - if test -n "$convenience"; then - if test -z "$whole_archive_flag_spec"; then - $show "${rm}r $gentop" - $run ${rm}r "$gentop" - fi - fi - - exit $EXIT_SUCCESS - fi - - # Create links to the real library. - for linkname in $linknames; do - if test "$realname" != "$linkname"; then - $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" - $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? - fi - done - - # If -module or -export-dynamic was specified, set the dlname. - if test "$module" = yes || test "$export_dynamic" = yes; then - # On all known operating systems, these are identical. - dlname="$soname" - fi - fi - ;; - - obj) - if test -n "$deplibs"; then - $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 - fi - - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 - fi - - if test -n "$rpath"; then - $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 - fi - - if test -n "$xrpath"; then - $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 - fi - - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 - fi - - case $output in - *.lo) - if test -n "$objs$old_deplibs"; then - $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 - exit $EXIT_FAILURE - fi - libobj="$output" - obj=`$echo "X$output" | $Xsed -e "$lo2o"` - ;; - *) - libobj= - obj="$output" - ;; - esac - - # Delete the old objects. - $run $rm $obj $libobj - - # Objects from convenience libraries. This assumes - # single-version convenience libraries. Whenever we create - # different ones for PIC/non-PIC, this we'll have to duplicate - # the extraction. - reload_conv_objs= - gentop= - # reload_cmds runs $LD directly, so let us get rid of - # -Wl from whole_archive_flag_spec - wl= - - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec"; then - eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\" - else - gentop="$output_objdir/${obj}x" - generated="$generated $gentop" - - func_extract_archives $gentop $convenience - reload_conv_objs="$reload_objs $func_extract_archives_result" - fi - fi - - # Create the old-style object. - reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test - - output="$obj" - cmds=$reload_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - - # Exit if we aren't doing a library object file. - if test -z "$libobj"; then - if test -n "$gentop"; then - $show "${rm}r $gentop" - $run ${rm}r $gentop - fi - - exit $EXIT_SUCCESS - fi - - if test "$build_libtool_libs" != yes; then - if test -n "$gentop"; then - $show "${rm}r $gentop" - $run ${rm}r $gentop - fi - - # Create an invalid libtool object if no PIC, so that we don't - # accidentally link it into a program. - # $show "echo timestamp > $libobj" - # $run eval "echo timestamp > $libobj" || exit $? - exit $EXIT_SUCCESS - fi - - if test -n "$pic_flag" || test "$pic_mode" != default; then - # Only do commands if we really have different PIC objects. - reload_objs="$libobjs $reload_conv_objs" - output="$libobj" - cmds=$reload_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - fi - - if test -n "$gentop"; then - $show "${rm}r $gentop" - $run ${rm}r $gentop - fi - - exit $EXIT_SUCCESS - ;; - - prog) - case $host in - *cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; - esac - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 - fi - - if test "$preload" = yes; then - if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && - test "$dlopen_self_static" = unknown; then - $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." - fi - fi - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library is the System framework - compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` - finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` - ;; - esac - - case $host in - *darwin*) - # Don't allow lazy linking, it breaks C++ global constructors - if test "$tagname" = CXX ; then - compile_command="$compile_command ${wl}-bind_at_load" - finalize_command="$finalize_command ${wl}-bind_at_load" - fi - ;; - esac - - compile_command="$compile_command $compile_deplibs" - finalize_command="$finalize_command $finalize_deplibs" - - if test -n "$rpath$xrpath"; then - # If the user specified any rpath flags, then add them. - for libdir in $rpath $xrpath; do - # This is the magic to use -rpath. - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" ;; - esac - done - fi - - # Now hardcode the library paths - rpath= - hardcode_libdirs= - for libdir in $compile_rpath $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - rpath="$rpath $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) perm_rpath="$perm_rpath $libdir" ;; - esac - fi - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) - case :$dllsearchpath: in - *":$libdir:"*) ;; - *) dllsearchpath="$dllsearchpath:$libdir";; - esac - ;; - esac - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - compile_rpath="$rpath" - - rpath= - hardcode_libdirs= - for libdir in $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - rpath="$rpath $flag" - fi - elif test -n "$runpath_var"; then - case "$finalize_perm_rpath " in - *" $libdir "*) ;; - *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - finalize_rpath="$rpath" - - if test -n "$libobjs" && test "$build_old_libs" = yes; then - # Transform all the library objects into standard objects. - compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - fi - - dlsyms= - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - if test -n "$NM" && test -n "$global_symbol_pipe"; then - dlsyms="${outputname}S.c" - else - $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 - fi - fi - - if test -n "$dlsyms"; then - case $dlsyms in - "") ;; - *.c) - # Discover the nlist of each of the dlfiles. - nlist="$output_objdir/${outputname}.nm" - - $show "$rm $nlist ${nlist}S ${nlist}T" - $run $rm "$nlist" "${nlist}S" "${nlist}T" - - # Parse the name list into a source file. - $show "creating $output_objdir/$dlsyms" - - test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ -/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ -/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ - -#ifdef __cplusplus -extern \"C\" { -#endif - -/* Prevent the only kind of declaration conflicts we can make. */ -#define lt_preloaded_symbols some_other_symbol - -/* External symbol declarations for the compiler. */\ -" - - if test "$dlself" = yes; then - $show "generating symbol list for \`$output'" - - test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" - - # Add our own program objects to the symbol list. - progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - for arg in $progfiles; do - $show "extracting global C symbols from \`$arg'" - $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" - done - - if test -n "$exclude_expsyms"; then - $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' - $run eval '$mv "$nlist"T "$nlist"' - fi - - if test -n "$export_symbols_regex"; then - $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' - $run eval '$mv "$nlist"T "$nlist"' - fi - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - export_symbols="$output_objdir/$outputname.exp" - $run $rm $export_symbols - $run eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' - else - $run eval "${SED} -e 's/\([ ][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' - $run eval 'grep -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' - $run eval 'mv "$nlist"T "$nlist"' - fi - fi - - for arg in $dlprefiles; do - $show "extracting global C symbols from \`$arg'" - name=`$echo "$arg" | ${SED} -e 's%^.*/%%'` - $run eval '$echo ": $name " >> "$nlist"' - $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" - done - - if test -z "$run"; then - # Make sure we have at least an empty file. - test -f "$nlist" || : > "$nlist" - - if test -n "$exclude_expsyms"; then - $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T - $mv "$nlist"T "$nlist" - fi - - # Try sorting and uniquifying the output. - if grep -v "^: " < "$nlist" | - if sort -k 3 </dev/null >/dev/null 2>&1; then - sort -k 3 - else - sort +2 - fi | - uniq > "$nlist"S; then - : - else - grep -v "^: " < "$nlist" > "$nlist"S - fi - - if test -f "$nlist"S; then - eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' - else - $echo '/* NONE */' >> "$output_objdir/$dlsyms" - fi - - $echo >> "$output_objdir/$dlsyms" "\ - -#undef lt_preloaded_symbols - -#if defined (__STDC__) && __STDC__ -# define lt_ptr void * -#else -# define lt_ptr char * -# define const -#endif - -/* The mapping between symbol names and symbols. */ -" - - case $host in - *cygwin* | *mingw* ) - $echo >> "$output_objdir/$dlsyms" "\ -/* DATA imports from DLLs on WIN32 can't be const, because - runtime relocations are performed -- see ld's documentation - on pseudo-relocs */ -struct { -" - ;; - * ) - $echo >> "$output_objdir/$dlsyms" "\ -const struct { -" - ;; - esac - - - $echo >> "$output_objdir/$dlsyms" "\ - const char *name; - lt_ptr address; -} -lt_preloaded_symbols[] = -{\ -" - - eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" - - $echo >> "$output_objdir/$dlsyms" "\ - {0, (lt_ptr) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif\ -" - fi - - pic_flag_for_symtable= - case $host in - # compiling the symbol table file with pic_flag works around - # a FreeBSD bug that causes programs to crash when -lm is - # linked before any other PIC object. But we must not use - # pic_flag when linking with -static. The problem exists in - # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. - *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) - case "$compile_command " in - *" -static "*) ;; - *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";; - esac;; - *-*-hpux*) - case "$compile_command " in - *" -static "*) ;; - *) pic_flag_for_symtable=" $pic_flag";; - esac - esac - - # Now compile the dynamic symbol file. - $show "(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" - $run eval '(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? - - # Clean up the generated files. - $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" - $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" - - # Transform the symbol file into the correct name. - compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` - finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` - ;; - *) - $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 - exit $EXIT_FAILURE - ;; - esac - else - # We keep going just in case the user didn't refer to - # lt_preloaded_symbols. The linker will fail if global_symbol_pipe - # really was required. - - # Nullify the symbol file. - compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` - finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` - fi - - if test "$need_relink" = no || test "$build_libtool_libs" != yes; then - # Replace the output file specification. - compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` - link_command="$compile_command$compile_rpath" - - # We have no uninstalled library dependencies, so finalize right now. - $show "$link_command" - $run eval "$link_command" - status=$? - - # Delete the generated files. - if test -n "$dlsyms"; then - $show "$rm $output_objdir/${outputname}S.${objext}" - $run $rm "$output_objdir/${outputname}S.${objext}" - fi - - exit $status - fi - - if test -n "$shlibpath_var"; then - # We should set the shlibpath_var - rpath= - for dir in $temp_rpath; do - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) - # Absolute path. - rpath="$rpath$dir:" - ;; - *) - # Relative path: add a thisdir entry. - rpath="$rpath\$thisdir/$dir:" - ;; - esac - done - temp_rpath="$rpath" - fi - - if test -n "$compile_shlibpath$finalize_shlibpath"; then - compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" - fi - if test -n "$finalize_shlibpath"; then - finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" - fi - - compile_var= - finalize_var= - if test -n "$runpath_var"; then - if test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - rpath="$rpath$dir:" - done - compile_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - if test -n "$finalize_perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $finalize_perm_rpath; do - rpath="$rpath$dir:" - done - finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - fi - - if test "$no_install" = yes; then - # We don't need to create a wrapper script. - link_command="$compile_var$compile_command$compile_rpath" - # Replace the output file specification. - link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` - # Delete the old output file. - $run $rm $output - # Link the executable and exit - $show "$link_command" - $run eval "$link_command" || exit $? - exit $EXIT_SUCCESS - fi - - if test "$hardcode_action" = relink; then - # Fast installation is not supported - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" - - $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 - $echo "$modename: \`$output' will be relinked during installation" 1>&2 - else - if test "$fast_install" != no; then - link_command="$finalize_var$compile_command$finalize_rpath" - if test "$fast_install" = yes; then - relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` - else - # fast_install is set to needless - relink_command= - fi - else - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" - fi - fi - - # Replace the output file specification. - link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` - - # Delete the old output files. - $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname - - $show "$link_command" - $run eval "$link_command" || exit $? - - # Now create the wrapper script. - $show "creating $output" - - # Quote the relink command for shipping. - if test -n "$relink_command"; then - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` - relink_command="$var=\"$var_value\"; export $var; $relink_command" - fi - done - relink_command="(cd `pwd`; $relink_command)" - relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` - fi - - # Quote $echo for shipping. - if test "X$echo" = "X$SHELL $progpath --fallback-echo"; then - case $progpath in - [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; - *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; - esac - qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` - else - qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` - fi - - # Only actually do things if our run command is non-null. - if test -z "$run"; then - # win32 will think the script is a binary if it has - # a .exe suffix, so we strip it off here. - case $output in - *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;; - esac - # test for cygwin because mv fails w/o .exe extensions - case $host in - *cygwin*) - exeext=.exe - outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;; - *) exeext= ;; - esac - case $host in - *cygwin* | *mingw* ) - cwrappersource=`$echo ${objdir}/lt-${outputname}.c` - cwrapper=`$echo ${output}.exe` - $rm $cwrappersource $cwrapper - trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 - - cat > $cwrappersource <<EOF - -/* $cwrappersource - temporary wrapper executable for $objdir/$outputname - Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP - - The $output program cannot be directly executed until all the libtool - libraries that it depends on are installed. - - This wrapper executable should never be moved out of the build directory. - If it is, it will not operate correctly. - - Currently, it simply execs the wrapper *script* "/bin/sh $output", - but could eventually absorb all of the scripts functionality and - exec $objdir/$outputname directly. -*/ -EOF - cat >> $cwrappersource<<"EOF" -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <malloc.h> -#include <stdarg.h> -#include <assert.h> - -#if defined(PATH_MAX) -# define LT_PATHMAX PATH_MAX -#elif defined(MAXPATHLEN) -# define LT_PATHMAX MAXPATHLEN -#else -# define LT_PATHMAX 1024 -#endif - -#ifndef DIR_SEPARATOR -#define DIR_SEPARATOR '/' -#endif - -#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ - defined (__OS2__) -#define HAVE_DOS_BASED_FILE_SYSTEM -#ifndef DIR_SEPARATOR_2 -#define DIR_SEPARATOR_2 '\\' -#endif -#endif - -#ifndef DIR_SEPARATOR_2 -# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) -#else /* DIR_SEPARATOR_2 */ -# define IS_DIR_SEPARATOR(ch) \ - (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) -#endif /* DIR_SEPARATOR_2 */ - -#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) -#define XFREE(stale) do { \ - if (stale) { free ((void *) stale); stale = 0; } \ -} while (0) - -const char *program_name = NULL; - -void * xmalloc (size_t num); -char * xstrdup (const char *string); -char * basename (const char *name); -char * fnqualify(const char *path); -char * strendzap(char *str, const char *pat); -void lt_fatal (const char *message, ...); - -int -main (int argc, char *argv[]) -{ - char **newargz; - int i; - - program_name = (char *) xstrdup ((char *) basename (argv[0])); - newargz = XMALLOC(char *, argc+2); -EOF - - cat >> $cwrappersource <<EOF - newargz[0] = "$SHELL"; -EOF - - cat >> $cwrappersource <<"EOF" - newargz[1] = fnqualify(argv[0]); - /* we know the script has the same name, without the .exe */ - /* so make sure newargz[1] doesn't end in .exe */ - strendzap(newargz[1],".exe"); - for (i = 1; i < argc; i++) - newargz[i+1] = xstrdup(argv[i]); - newargz[argc+1] = NULL; -EOF - - cat >> $cwrappersource <<EOF - execv("$SHELL",newargz); -EOF - - cat >> $cwrappersource <<"EOF" - return 127; -} - -void * -xmalloc (size_t num) -{ - void * p = (void *) malloc (num); - if (!p) - lt_fatal ("Memory exhausted"); - - return p; -} - -char * -xstrdup (const char *string) -{ - return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL -; -} - -char * -basename (const char *name) -{ - const char *base; - -#if defined (HAVE_DOS_BASED_FILE_SYSTEM) - /* Skip over the disk name in MSDOS pathnames. */ - if (isalpha (name[0]) && name[1] == ':') - name += 2; -#endif - - for (base = name; *name; name++) - if (IS_DIR_SEPARATOR (*name)) - base = name + 1; - return (char *) base; -} - -char * -fnqualify(const char *path) -{ - size_t size; - char *p; - char tmp[LT_PATHMAX + 1]; - - assert(path != NULL); - - /* Is it qualified already? */ -#if defined (HAVE_DOS_BASED_FILE_SYSTEM) - if (isalpha (path[0]) && path[1] == ':') - return xstrdup (path); -#endif - if (IS_DIR_SEPARATOR (path[0])) - return xstrdup (path); - - /* prepend the current directory */ - /* doesn't handle '~' */ - if (getcwd (tmp, LT_PATHMAX) == NULL) - lt_fatal ("getcwd failed"); - size = strlen(tmp) + 1 + strlen(path) + 1; /* +2 for '/' and '\0' */ - p = XMALLOC(char, size); - sprintf(p, "%s%c%s", tmp, DIR_SEPARATOR, path); - return p; -} - -char * -strendzap(char *str, const char *pat) -{ - size_t len, patlen; - - assert(str != NULL); - assert(pat != NULL); - - len = strlen(str); - patlen = strlen(pat); - - if (patlen <= len) - { - str += len - patlen; - if (strcmp(str, pat) == 0) - *str = '\0'; - } - return str; -} - -static void -lt_error_core (int exit_status, const char * mode, - const char * message, va_list ap) -{ - fprintf (stderr, "%s: %s: ", program_name, mode); - vfprintf (stderr, message, ap); - fprintf (stderr, ".\n"); - - if (exit_status >= 0) - exit (exit_status); -} - -void -lt_fatal (const char *message, ...) -{ - va_list ap; - va_start (ap, message); - lt_error_core (EXIT_FAILURE, "FATAL", message, ap); - va_end (ap); -} -EOF - # we should really use a build-platform specific compiler - # here, but OTOH, the wrappers (shell script and this C one) - # are only useful if you want to execute the "real" binary. - # Since the "real" binary is built for $host, then this - # wrapper might as well be built for $host, too. - $run $LTCC -s -o $cwrapper $cwrappersource - ;; - esac - $rm $output - trap "$rm $output; exit $EXIT_FAILURE" 1 2 15 - - $echo > $output "\ -#! $SHELL - -# $output - temporary wrapper script for $objdir/$outputname -# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP -# -# The $output program cannot be directly executed until all the libtool -# libraries that it depends on are installed. -# -# This wrapper script should never be moved out of the build directory. -# If it is, it will not operate correctly. - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -Xsed='${SED} -e 1s/^X//' -sed_quote_subst='$sed_quote_subst' - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -relink_command=\"$relink_command\" - -# This environment variable determines our operation mode. -if test \"\$libtool_install_magic\" = \"$magic\"; then - # install mode needs the following variable: - notinst_deplibs='$notinst_deplibs' -else - # When we are sourced in execute mode, \$file and \$echo are already set. - if test \"\$libtool_execute_magic\" != \"$magic\"; then - echo=\"$qecho\" - file=\"\$0\" - # Make sure echo works. - if test \"X\$1\" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift - elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then - # Yippee, \$echo works! - : - else - # Restart under the correct shell, and then maybe \$echo will work. - exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} - fi - fi\ -" - $echo >> $output "\ - - # Find the directory that this script lives in. - thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` - test \"x\$thisdir\" = \"x\$file\" && thisdir=. - - # Follow symbolic links until we get to the real thisdir. - file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` - while test -n \"\$file\"; do - destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` - - # If there was a directory component, then change thisdir. - if test \"x\$destdir\" != \"x\$file\"; then - case \"\$destdir\" in - [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; - *) thisdir=\"\$thisdir/\$destdir\" ;; - esac - fi - - file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` - file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` - done - - # Try to get the absolute directory name. - absdir=\`cd \"\$thisdir\" && pwd\` - test -n \"\$absdir\" && thisdir=\"\$absdir\" -" - - if test "$fast_install" = yes; then - $echo >> $output "\ - program=lt-'$outputname'$exeext - progdir=\"\$thisdir/$objdir\" - - if test ! -f \"\$progdir/\$program\" || \\ - { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ - test \"X\$file\" != \"X\$progdir/\$program\"; }; then - - file=\"\$\$-\$program\" - - if test ! -d \"\$progdir\"; then - $mkdir \"\$progdir\" - else - $rm \"\$progdir/\$file\" - fi" - - $echo >> $output "\ - - # relink executable if necessary - if test -n \"\$relink_command\"; then - if relink_command_output=\`eval \$relink_command 2>&1\`; then : - else - $echo \"\$relink_command_output\" >&2 - $rm \"\$progdir/\$file\" - exit $EXIT_FAILURE - fi - fi - - $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || - { $rm \"\$progdir/\$program\"; - $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } - $rm \"\$progdir/\$file\" - fi" - else - $echo >> $output "\ - program='$outputname' - progdir=\"\$thisdir/$objdir\" -" - fi - - $echo >> $output "\ - - if test -f \"\$progdir/\$program\"; then" - - # Export our shlibpath_var if we have one. - if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then - $echo >> $output "\ - # Add our own library path to $shlibpath_var - $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" - - # Some systems cannot cope with colon-terminated $shlibpath_var - # The second colon is a workaround for a bug in BeOS R4 sed - $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` - - export $shlibpath_var -" - fi - - # fixup the dll searchpath if we need to. - if test -n "$dllsearchpath"; then - $echo >> $output "\ - # Add the dll search path components to the executable PATH - PATH=$dllsearchpath:\$PATH -" - fi - - $echo >> $output "\ - if test \"\$libtool_execute_magic\" != \"$magic\"; then - # Run the actual program with our arguments. -" - case $host in - # Backslashes separate directories on plain windows - *-*-mingw | *-*-os2*) - $echo >> $output "\ - exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} -" - ;; - - *) - $echo >> $output "\ - exec \"\$progdir/\$program\" \${1+\"\$@\"} -" - ;; - esac - $echo >> $output "\ - \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\" - exit $EXIT_FAILURE - fi - else - # The program doesn't exist. - \$echo \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 - \$echo \"This script is just a wrapper for \$program.\" 1>&2 - $echo \"See the $PACKAGE documentation for more information.\" 1>&2 - exit $EXIT_FAILURE - fi -fi\ -" - chmod +x $output - fi - exit $EXIT_SUCCESS - ;; - esac - - # See if we need to build an old-fashioned archive. - for oldlib in $oldlibs; do - - if test "$build_libtool_libs" = convenience; then - oldobjs="$libobjs_save" - addlibs="$convenience" - build_libtool_libs=no - else - if test "$build_libtool_libs" = module; then - oldobjs="$libobjs_save" - build_libtool_libs=no - else - oldobjs="$old_deplibs $non_pic_objects" - fi - addlibs="$old_convenience" - fi - - if test -n "$addlibs"; then - gentop="$output_objdir/${outputname}x" - generated="$generated $gentop" - - func_extract_archives $gentop $addlibs - oldobjs="$oldobjs $func_extract_archives_result" - fi - - # Do each command in the archive commands. - if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then - cmds=$old_archive_from_new_cmds - else - # POSIX demands no paths to be encoded in archives. We have - # to avoid creating archives with duplicate basenames if we - # might have to extract them afterwards, e.g., when creating a - # static archive out of a convenience library, or when linking - # the entirety of a libtool archive into another (currently - # not supported by libtool). - if (for obj in $oldobjs - do - $echo "X$obj" | $Xsed -e 's%^.*/%%' - done | sort | sort -uc >/dev/null 2>&1); then - : - else - $echo "copying selected object files to avoid basename conflicts..." - - if test -z "$gentop"; then - gentop="$output_objdir/${outputname}x" - generated="$generated $gentop" - - $show "${rm}r $gentop" - $run ${rm}r "$gentop" - $show "$mkdir $gentop" - $run $mkdir "$gentop" - status=$? - if test "$status" -ne 0 && test ! -d "$gentop"; then - exit $status - fi - fi - - save_oldobjs=$oldobjs - oldobjs= - counter=1 - for obj in $save_oldobjs - do - objbase=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` - case " $oldobjs " in - " ") oldobjs=$obj ;; - *[\ /]"$objbase "*) - while :; do - # Make sure we don't pick an alternate name that also - # overlaps. - newobj=lt$counter-$objbase - counter=`expr $counter + 1` - case " $oldobjs " in - *[\ /]"$newobj "*) ;; - *) if test ! -f "$gentop/$newobj"; then break; fi ;; - esac - done - $show "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" - $run ln "$obj" "$gentop/$newobj" || - $run cp "$obj" "$gentop/$newobj" - oldobjs="$oldobjs $gentop/$newobj" - ;; - *) oldobjs="$oldobjs $obj" ;; - esac - done - fi - - eval cmds=\"$old_archive_cmds\" - - if len=`expr "X$cmds" : ".*"` && - test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then - cmds=$old_archive_cmds - else - # the command line is too long to link in one step, link in parts - $echo "using piecewise archive linking..." - save_RANLIB=$RANLIB - RANLIB=: - objlist= - concat_cmds= - save_oldobjs=$oldobjs - - # Is there a better way of finding the last object in the list? - for obj in $save_oldobjs - do - last_oldobj=$obj - done - for obj in $save_oldobjs - do - oldobjs="$objlist $obj" - objlist="$objlist $obj" - eval test_cmds=\"$old_archive_cmds\" - if len=`expr "X$test_cmds" : ".*" 2>/dev/null` && - test "$len" -le "$max_cmd_len"; then - : - else - # the above command should be used before it gets too long - oldobjs=$objlist - if test "$obj" = "$last_oldobj" ; then - RANLIB=$save_RANLIB - fi - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" - objlist= - fi - done - RANLIB=$save_RANLIB - oldobjs=$objlist - if test "X$oldobjs" = "X" ; then - eval cmds=\"\$concat_cmds\" - else - eval cmds=\"\$concat_cmds~\$old_archive_cmds\" - fi - fi - fi - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - eval cmd=\"$cmd\" - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - done - - if test -n "$generated"; then - $show "${rm}r$generated" - $run ${rm}r$generated - fi - - # Now create the libtool archive. - case $output in - *.la) - old_library= - test "$build_old_libs" = yes && old_library="$libname.$libext" - $show "creating $output" - - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` - relink_command="$var=\"$var_value\"; export $var; $relink_command" - fi - done - # Quote the link command for shipping. - relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" - relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` - if test "$hardcode_automatic" = yes ; then - relink_command= - fi - - - # Only create the output if not a dry run. - if test -z "$run"; then - for installed in no yes; do - if test "$installed" = yes; then - if test -z "$install_libdir"; then - break - fi - output="$output_objdir/$outputname"i - # Replace all uninstalled libtool libraries with the installed ones - newdependency_libs= - for deplib in $dependency_libs; do - case $deplib in - *.la) - name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` - if test -z "$libdir"; then - $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 - exit $EXIT_FAILURE - fi - newdependency_libs="$newdependency_libs $libdir/$name" - ;; - *) newdependency_libs="$newdependency_libs $deplib" ;; - esac - done - dependency_libs="$newdependency_libs" - newdlfiles= - for lib in $dlfiles; do - name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - if test -z "$libdir"; then - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - exit $EXIT_FAILURE - fi - newdlfiles="$newdlfiles $libdir/$name" - done - dlfiles="$newdlfiles" - newdlprefiles= - for lib in $dlprefiles; do - name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - if test -z "$libdir"; then - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - exit $EXIT_FAILURE - fi - newdlprefiles="$newdlprefiles $libdir/$name" - done - dlprefiles="$newdlprefiles" - else - newdlfiles= - for lib in $dlfiles; do - case $lib in - [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; - *) abs=`pwd`"/$lib" ;; - esac - newdlfiles="$newdlfiles $abs" - done - dlfiles="$newdlfiles" - newdlprefiles= - for lib in $dlprefiles; do - case $lib in - [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; - *) abs=`pwd`"/$lib" ;; - esac - newdlprefiles="$newdlprefiles $abs" - done - dlprefiles="$newdlprefiles" - fi - $rm $output - # place dlname in correct position for cygwin - tdlname=$dlname - case $host,$output,$installed,$module,$dlname in - *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; - esac - $echo > $output "\ -# $outputname - a libtool library file -# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# The name that we can dlopen(3). -dlname='$tdlname' - -# Names of this library. -library_names='$library_names' - -# The name of the static archive. -old_library='$old_library' - -# Libraries that this one depends upon. -dependency_libs='$dependency_libs' - -# Version information for $libname. -current=$current -age=$age -revision=$revision - -# Is this an already installed library? -installed=$installed - -# Should we warn about portability when linking against -modules? -shouldnotlink=$module - -# Files to dlopen/dlpreopen -dlopen='$dlfiles' -dlpreopen='$dlprefiles' - -# Directory that this library needs to be installed in: -libdir='$install_libdir'" - if test "$installed" = no && test "$need_relink" = yes; then - $echo >> $output "\ -relink_command=\"$relink_command\"" - fi - done - fi - - # Do a symbolic link so that the libtool archive can be found in - # LD_LIBRARY_PATH before the program is installed. - $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" - $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? - ;; - esac - exit $EXIT_SUCCESS - ;; - - # libtool install mode - install) - modename="$modename: install" - - # There may be an optional sh(1) argument at the beginning of - # install_prog (especially on Windows NT). - if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || - # Allow the use of GNU shtool's install command. - $echo "X$nonopt" | grep shtool > /dev/null; then - # Aesthetically quote it. - arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - install_prog="$arg " - arg="$1" - shift - else - install_prog= - arg=$nonopt - fi - - # The real first argument should be the name of the installation program. - # Aesthetically quote it. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - install_prog="$install_prog$arg" - - # We need to accept at least all the BSD install flags. - dest= - files= - opts= - prev= - install_type= - isdir=no - stripme= - for arg - do - if test -n "$dest"; then - files="$files $dest" - dest=$arg - continue - fi - - case $arg in - -d) isdir=yes ;; - -f) - case " $install_prog " in - *[\\\ /]cp\ *) ;; - *) prev=$arg ;; - esac - ;; - -g | -m | -o) prev=$arg ;; - -s) - stripme=" -s" - continue - ;; - -*) - ;; - *) - # If the previous option needed an argument, then skip it. - if test -n "$prev"; then - prev= - else - dest=$arg - continue - fi - ;; - esac - - # Aesthetically quote the argument. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - install_prog="$install_prog $arg" - done - - if test -z "$install_prog"; then - $echo "$modename: you must specify an install program" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - if test -n "$prev"; then - $echo "$modename: the \`$prev' option requires an argument" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - if test -z "$files"; then - if test -z "$dest"; then - $echo "$modename: no file or destination specified" 1>&2 - else - $echo "$modename: you must specify a destination" 1>&2 - fi - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - # Strip any trailing slash from the destination. - dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` - - # Check to see that the destination is a directory. - test -d "$dest" && isdir=yes - if test "$isdir" = yes; then - destdir="$dest" - destname= - else - destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` - test "X$destdir" = "X$dest" && destdir=. - destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` - - # Not a directory, so check to see that there is only one file specified. - set dummy $files - if test "$#" -gt 2; then - $echo "$modename: \`$dest' is not a directory" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - fi - case $destdir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - for file in $files; do - case $file in - *.lo) ;; - *) - $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - ;; - esac - done - ;; - esac - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic="$magic" - - staticlibs= - future_libdirs= - current_libdirs= - for file in $files; do - - # Do each installation. - case $file in - *.$libext) - # Do the static libraries later. - staticlibs="$staticlibs $file" - ;; - - *.la) - # Check to see that this really is a libtool archive. - if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : - else - $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - library_names= - old_library= - relink_command= - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $file ;; - *) . ./$file ;; - esac - - # Add the libdir to current_libdirs if it is the destination. - if test "X$destdir" = "X$libdir"; then - case "$current_libdirs " in - *" $libdir "*) ;; - *) current_libdirs="$current_libdirs $libdir" ;; - esac - else - # Note the libdir as a future libdir. - case "$future_libdirs " in - *" $libdir "*) ;; - *) future_libdirs="$future_libdirs $libdir" ;; - esac - fi - - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ - test "X$dir" = "X$file/" && dir= - dir="$dir$objdir" - - if test -n "$relink_command"; then - # Determine the prefix the user has applied to our future dir. - inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"` - - # Don't allow the user to place us outside of our expected - # location b/c this prevents finding dependent libraries that - # are installed to the same prefix. - # At present, this check doesn't affect windows .dll's that - # are installed into $libdir/../bin (currently, that works fine) - # but it's something to keep an eye on. - if test "$inst_prefix_dir" = "$destdir"; then - $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2 - exit $EXIT_FAILURE - fi - - if test -n "$inst_prefix_dir"; then - # Stick the inst_prefix_dir data into the link command. - relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` - else - relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%%"` - fi - - $echo "$modename: warning: relinking \`$file'" 1>&2 - $show "$relink_command" - if $run eval "$relink_command"; then : - else - $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 - exit $EXIT_FAILURE - fi - fi - - # See the names of the shared library. - set dummy $library_names - if test -n "$2"; then - realname="$2" - shift - shift - - srcname="$realname" - test -n "$relink_command" && srcname="$realname"T - - # Install the shared library and build the symlinks. - $show "$install_prog $dir/$srcname $destdir/$realname" - $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? - if test -n "$stripme" && test -n "$striplib"; then - $show "$striplib $destdir/$realname" - $run eval "$striplib $destdir/$realname" || exit $? - fi - - if test "$#" -gt 0; then - # Delete the old symlinks, and create new ones. - # Try `ln -sf' first, because the `ln' binary might depend on - # the symlink we replace! Solaris /bin/ln does not understand -f, - # so we also need to try rm && ln -s. - for linkname - do - if test "$linkname" != "$realname"; then - $show "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })" - $run eval "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })" - fi - done - fi - - # Do each command in the postinstall commands. - lib="$destdir/$realname" - cmds=$postinstall_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || { - lt_exit=$? - - # Restore the uninstalled library and exit - if test "$mode" = relink; then - $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)' - fi - - exit $lt_exit - } - done - IFS="$save_ifs" - fi - - # Install the pseudo-library for information purposes. - name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - instname="$dir/$name"i - $show "$install_prog $instname $destdir/$name" - $run eval "$install_prog $instname $destdir/$name" || exit $? - - # Maybe install the static library, too. - test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" - ;; - - *.lo) - # Install (i.e. copy) a libtool object. - - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile="$destdir/$destname" - else - destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - destfile="$destdir/$destfile" - fi - - # Deduce the name of the destination old-style object file. - case $destfile in - *.lo) - staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` - ;; - *.$objext) - staticdest="$destfile" - destfile= - ;; - *) - $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - ;; - esac - - # Install the libtool object if requested. - if test -n "$destfile"; then - $show "$install_prog $file $destfile" - $run eval "$install_prog $file $destfile" || exit $? - fi - - # Install the old object if enabled. - if test "$build_old_libs" = yes; then - # Deduce the name of the old-style object file. - staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` - - $show "$install_prog $staticobj $staticdest" - $run eval "$install_prog \$staticobj \$staticdest" || exit $? - fi - exit $EXIT_SUCCESS - ;; - - *) - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile="$destdir/$destname" - else - destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - destfile="$destdir/$destfile" - fi - - # If the file is missing, and there is a .exe on the end, strip it - # because it is most likely a libtool script we actually want to - # install - stripped_ext="" - case $file in - *.exe) - if test ! -f "$file"; then - file=`$echo $file|${SED} 's,.exe$,,'` - stripped_ext=".exe" - fi - ;; - esac - - # Do a test to see if this is really a libtool program. - case $host in - *cygwin*|*mingw*) - wrapper=`$echo $file | ${SED} -e 's,.exe$,,'` - ;; - *) - wrapper=$file - ;; - esac - if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then - notinst_deplibs= - relink_command= - - # Note that it is not necessary on cygwin/mingw to append a dot to - # foo even if both foo and FILE.exe exist: automatic-append-.exe - # behavior happens only for exec(3), not for open(2)! Also, sourcing - # `FILE.' does not work on cygwin managed mounts. - # - # If there is no directory component, then add one. - case $wrapper in - */* | *\\*) . ${wrapper} ;; - *) . ./${wrapper} ;; - esac - - # Check the variables that should have been set. - if test -z "$notinst_deplibs"; then - $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 - exit $EXIT_FAILURE - fi - - finalize=yes - for lib in $notinst_deplibs; do - # Check to see that each library is installed. - libdir= - if test -f "$lib"; then - # If there is no directory component, then add one. - case $lib in - */* | *\\*) . $lib ;; - *) . ./$lib ;; - esac - fi - libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test - if test -n "$libdir" && test ! -f "$libfile"; then - $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 - finalize=no - fi - done - - relink_command= - # Note that it is not necessary on cygwin/mingw to append a dot to - # foo even if both foo and FILE.exe exist: automatic-append-.exe - # behavior happens only for exec(3), not for open(2)! Also, sourcing - # `FILE.' does not work on cygwin managed mounts. - # - # If there is no directory component, then add one. - case $wrapper in - */* | *\\*) . ${wrapper} ;; - *) . ./${wrapper} ;; - esac - - outputname= - if test "$fast_install" = no && test -n "$relink_command"; then - if test "$finalize" = yes && test -z "$run"; then - tmpdir="/tmp" - test -n "$TMPDIR" && tmpdir="$TMPDIR" - tmpdir="$tmpdir/libtool-$$" - save_umask=`umask` - umask 0077 - if $mkdir "$tmpdir"; then - umask $save_umask - else - umask $save_umask - $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2 - continue - fi - file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'` - outputname="$tmpdir/$file" - # Replace the output file specification. - relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` - - $show "$relink_command" - if $run eval "$relink_command"; then : - else - $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 - ${rm}r "$tmpdir" - continue - fi - file="$outputname" - else - $echo "$modename: warning: cannot relink \`$file'" 1>&2 - fi - else - # Install the binary that we compiled earlier. - file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` - fi - fi - - # remove .exe since cygwin /usr/bin/install will append another - # one anyway - case $install_prog,$host in - */usr/bin/install*,*cygwin*) - case $file:$destfile in - *.exe:*.exe) - # this is ok - ;; - *.exe:*) - destfile=$destfile.exe - ;; - *:*.exe) - destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'` - ;; - esac - ;; - esac - $show "$install_prog$stripme $file $destfile" - $run eval "$install_prog\$stripme \$file \$destfile" || exit $? - test -n "$outputname" && ${rm}r "$tmpdir" - ;; - esac - done - - for file in $staticlibs; do - name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - - # Set up the ranlib parameters. - oldlib="$destdir/$name" - - $show "$install_prog $file $oldlib" - $run eval "$install_prog \$file \$oldlib" || exit $? - - if test -n "$stripme" && test -n "$old_striplib"; then - $show "$old_striplib $oldlib" - $run eval "$old_striplib $oldlib" || exit $? - fi - - # Do each command in the postinstall commands. - cmds=$old_postinstall_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - done - - if test -n "$future_libdirs"; then - $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 - fi - - if test -n "$current_libdirs"; then - # Maybe just do a dry run. - test -n "$run" && current_libdirs=" -n$current_libdirs" - exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' - else - exit $EXIT_SUCCESS - fi - ;; - - # libtool finish mode - finish) - modename="$modename: finish" - libdirs="$nonopt" - admincmds= - - if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then - for dir - do - libdirs="$libdirs $dir" - done - - for libdir in $libdirs; do - if test -n "$finish_cmds"; then - # Do each command in the finish commands. - cmds=$finish_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" || admincmds="$admincmds - $cmd" - done - IFS="$save_ifs" - fi - if test -n "$finish_eval"; then - # Do the single finish_eval. - eval cmds=\"$finish_eval\" - $run eval "$cmds" || admincmds="$admincmds - $cmds" - fi - done - fi - - # Exit here if they wanted silent mode. - test "$show" = : && exit $EXIT_SUCCESS - - $echo "----------------------------------------------------------------------" - $echo "Libraries have been installed in:" - for libdir in $libdirs; do - $echo " $libdir" - done - $echo - $echo "If you ever happen to want to link against installed libraries" - $echo "in a given directory, LIBDIR, you must either use libtool, and" - $echo "specify the full pathname of the library, or use the \`-LLIBDIR'" - $echo "flag during linking and do at least one of the following:" - if test -n "$shlibpath_var"; then - $echo " - add LIBDIR to the \`$shlibpath_var' environment variable" - $echo " during execution" - fi - if test -n "$runpath_var"; then - $echo " - add LIBDIR to the \`$runpath_var' environment variable" - $echo " during linking" - fi - if test -n "$hardcode_libdir_flag_spec"; then - libdir=LIBDIR - eval flag=\"$hardcode_libdir_flag_spec\" - - $echo " - use the \`$flag' linker flag" - fi - if test -n "$admincmds"; then - $echo " - have your system administrator run these commands:$admincmds" - fi - if test -f /etc/ld.so.conf; then - $echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" - fi - $echo - $echo "See any operating system documentation about shared libraries for" - $echo "more information, such as the ld(1) and ld.so(8) manual pages." - $echo "----------------------------------------------------------------------" - exit $EXIT_SUCCESS - ;; - - # libtool execute mode - execute) - modename="$modename: execute" - - # The first argument is the command name. - cmd="$nonopt" - if test -z "$cmd"; then - $echo "$modename: you must specify a COMMAND" 1>&2 - $echo "$help" - exit $EXIT_FAILURE - fi - - # Handle -dlopen flags immediately. - for file in $execute_dlfiles; do - if test ! -f "$file"; then - $echo "$modename: \`$file' is not a file" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - dir= - case $file in - *.la) - # Check to see that this really is a libtool archive. - if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : - else - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - # Read the libtool library. - dlname= - library_names= - - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $file ;; - *) . ./$file ;; - esac - - # Skip this library if it cannot be dlopened. - if test -z "$dlname"; then - # Warn if it was a shared library. - test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" - continue - fi - - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` - test "X$dir" = "X$file" && dir=. - - if test -f "$dir/$objdir/$dlname"; then - dir="$dir/$objdir" - else - $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 - exit $EXIT_FAILURE - fi - ;; - - *.lo) - # Just add the directory containing the .lo file. - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` - test "X$dir" = "X$file" && dir=. - ;; - - *) - $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 - continue - ;; - esac - - # Get the absolute pathname. - absdir=`cd "$dir" && pwd` - test -n "$absdir" && dir="$absdir" - - # Now add the directory to shlibpath_var. - if eval "test -z \"\$$shlibpath_var\""; then - eval "$shlibpath_var=\"\$dir\"" - else - eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" - fi - done - - # This variable tells wrapper scripts just to set shlibpath_var - # rather than running their programs. - libtool_execute_magic="$magic" - - # Check if any of the arguments is a wrapper script. - args= - for file - do - case $file in - -*) ;; - *) - # Do a test to see if this is really a libtool program. - if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $file ;; - *) . ./$file ;; - esac - - # Transform arg to wrapped name. - file="$progdir/$program" - fi - ;; - esac - # Quote arguments (to preserve shell metacharacters). - file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` - args="$args \"$file\"" - done - - if test -z "$run"; then - if test -n "$shlibpath_var"; then - # Export the shlibpath_var. - eval "export $shlibpath_var" - fi - - # Restore saved environment variables - if test "${save_LC_ALL+set}" = set; then - LC_ALL="$save_LC_ALL"; export LC_ALL - fi - if test "${save_LANG+set}" = set; then - LANG="$save_LANG"; export LANG - fi - - # Now prepare to actually exec the command. - exec_cmd="\$cmd$args" - else - # Display what would be done. - if test -n "$shlibpath_var"; then - eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" - $echo "export $shlibpath_var" - fi - $echo "$cmd$args" - exit $EXIT_SUCCESS - fi - ;; - - # libtool clean and uninstall mode - clean | uninstall) - modename="$modename: $mode" - rm="$nonopt" - files= - rmforce= - exit_status=0 - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic="$magic" - - for arg - do - case $arg in - -f) rm="$rm $arg"; rmforce=yes ;; - -*) rm="$rm $arg" ;; - *) files="$files $arg" ;; - esac - done - - if test -z "$rm"; then - $echo "$modename: you must specify an RM program" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - fi - - rmdirs= - - origobjdir="$objdir" - for file in $files; do - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` - if test "X$dir" = "X$file"; then - dir=. - objdir="$origobjdir" - else - objdir="$dir/$origobjdir" - fi - name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - test "$mode" = uninstall && objdir="$dir" - - # Remember objdir for removal later, being careful to avoid duplicates - if test "$mode" = clean; then - case " $rmdirs " in - *" $objdir "*) ;; - *) rmdirs="$rmdirs $objdir" ;; - esac - fi - - # Don't error if the file doesn't exist and rm -f was used. - if (test -L "$file") >/dev/null 2>&1 \ - || (test -h "$file") >/dev/null 2>&1 \ - || test -f "$file"; then - : - elif test -d "$file"; then - exit_status=1 - continue - elif test "$rmforce" = yes; then - continue - fi - - rmfiles="$file" - - case $name in - *.la) - # Possibly a libtool archive, so verify it. - if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - . $dir/$name - - # Delete the libtool libraries and symlinks. - for n in $library_names; do - rmfiles="$rmfiles $objdir/$n" - done - test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" - test "$mode" = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" - - if test "$mode" = uninstall; then - if test -n "$library_names"; then - # Do each command in the postuninstall commands. - cmds=$postuninstall_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" - if test "$?" -ne 0 && test "$rmforce" != yes; then - exit_status=1 - fi - done - IFS="$save_ifs" - fi - - if test -n "$old_library"; then - # Do each command in the old_postuninstall commands. - cmds=$old_postuninstall_cmds - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $show "$cmd" - $run eval "$cmd" - if test "$?" -ne 0 && test "$rmforce" != yes; then - exit_status=1 - fi - done - IFS="$save_ifs" - fi - # FIXME: should reinstall the best remaining shared library. - fi - fi - ;; - - *.lo) - # Possibly a libtool object, so verify it. - if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - - # Read the .lo file - . $dir/$name - - # Add PIC object to the list of files to remove. - if test -n "$pic_object" \ - && test "$pic_object" != none; then - rmfiles="$rmfiles $dir/$pic_object" - fi - - # Add non-PIC object to the list of files to remove. - if test -n "$non_pic_object" \ - && test "$non_pic_object" != none; then - rmfiles="$rmfiles $dir/$non_pic_object" - fi - fi - ;; - - *) - if test "$mode" = clean ; then - noexename=$name - case $file in - *.exe) - file=`$echo $file|${SED} 's,.exe$,,'` - noexename=`$echo $name|${SED} 's,.exe$,,'` - # $file with .exe has already been added to rmfiles, - # add $file without .exe - rmfiles="$rmfiles $file" - ;; - esac - # Do a test to see if this is a libtool program. - if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - relink_command= - . $dir/$noexename - - # note $name still contains .exe if it was in $file originally - # as does the version of $file that was added into $rmfiles - rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" - if test "$fast_install" = yes && test -n "$relink_command"; then - rmfiles="$rmfiles $objdir/lt-$name" - fi - if test "X$noexename" != "X$name" ; then - rmfiles="$rmfiles $objdir/lt-${noexename}.c" - fi - fi - fi - ;; - esac - $show "$rm $rmfiles" - $run $rm $rmfiles || exit_status=1 - done - objdir="$origobjdir" - - # Try to remove the ${objdir}s in the directories where we deleted files - for dir in $rmdirs; do - if test -d "$dir"; then - $show "rmdir $dir" - $run rmdir $dir >/dev/null 2>&1 - fi - done - - exit $exit_status - ;; - - "") - $echo "$modename: you must specify a MODE" 1>&2 - $echo "$generic_help" 1>&2 - exit $EXIT_FAILURE - ;; - esac - - if test -z "$exec_cmd"; then - $echo "$modename: invalid operation mode \`$mode'" 1>&2 - $echo "$generic_help" 1>&2 - exit $EXIT_FAILURE - fi -fi # test -z "$show_help" - -if test -n "$exec_cmd"; then - eval exec $exec_cmd - exit $EXIT_FAILURE -fi - -# We need to display help for each of the modes. -case $mode in -"") $echo \ -"Usage: $modename [OPTION]... [MODE-ARG]... - -Provide generalized library-building support services. - - --config show all configuration variables - --debug enable verbose shell tracing --n, --dry-run display commands without modifying any files - --features display basic configuration information and exit - --finish same as \`--mode=finish' - --help display this help message and exit - --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] - --quiet same as \`--silent' - --silent don't print informational messages - --tag=TAG use configuration variables from tag TAG - --version print version information - -MODE must be one of the following: - - clean remove files from the build directory - compile compile a source file into a libtool object - execute automatically set library path, then run a program - finish complete the installation of libtool libraries - install install libraries or executables - link create a library or an executable - uninstall remove libraries from an installed directory - -MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for -a more detailed description of MODE. - -Report bugs to <bug-libtool@gnu.org>." - exit $EXIT_SUCCESS - ;; - -clean) - $echo \ -"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... - -Remove files from the build directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed -to RM. - -If FILE is a libtool library, object or program, all the files associated -with it are deleted. Otherwise, only FILE itself is deleted using RM." - ;; - -compile) - $echo \ -"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE - -Compile a source file into a libtool library object. - -This mode accepts the following additional options: - - -o OUTPUT-FILE set the output file name to OUTPUT-FILE - -prefer-pic try to building PIC objects only - -prefer-non-pic try to building non-PIC objects only - -static always build a \`.o' file suitable for static linking - -COMPILE-COMMAND is a command to be used in creating a \`standard' object file -from the given SOURCEFILE. - -The output file name is determined by removing the directory component from -SOURCEFILE, then substituting the C source code suffix \`.c' with the -library object suffix, \`.lo'." - ;; - -execute) - $echo \ -"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... - -Automatically set library path, then run a program. - -This mode accepts the following additional options: - - -dlopen FILE add the directory containing FILE to the library path - -This mode sets the library path environment variable according to \`-dlopen' -flags. - -If any of the ARGS are libtool executable wrappers, then they are translated -into their corresponding uninstalled binary, and any of their required library -directories are added to the library path. - -Then, COMMAND is executed, with ARGS as arguments." - ;; - -finish) - $echo \ -"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... - -Complete the installation of libtool libraries. - -Each LIBDIR is a directory that contains libtool libraries. - -The commands that this mode executes may require superuser privileges. Use -the \`--dry-run' option if you just want to see what would be executed." - ;; - -install) - $echo \ -"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... - -Install executables or libraries. - -INSTALL-COMMAND is the installation command. The first component should be -either the \`install' or \`cp' program. - -The rest of the components are interpreted as arguments to that command (only -BSD-compatible install options are recognized)." - ;; - -link) - $echo \ -"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... - -Link object files or libraries together to form another library, or to -create an executable program. - -LINK-COMMAND is a command using the C compiler that you would use to create -a program from several object files. - -The following components of LINK-COMMAND are treated specially: - - -all-static do not do any dynamic linking at all - -avoid-version do not add a version suffix if possible - -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime - -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols - -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) - -export-symbols SYMFILE - try to export only the symbols listed in SYMFILE - -export-symbols-regex REGEX - try to export only the symbols matching REGEX - -LLIBDIR search LIBDIR for required installed libraries - -lNAME OUTPUT-FILE requires the installed library libNAME - -module build a library that can dlopened - -no-fast-install disable the fast-install mode - -no-install link a not-installable executable - -no-undefined declare that a library does not refer to external symbols - -o OUTPUT-FILE create OUTPUT-FILE from the specified objects - -objectlist FILE Use a list of object files found in FILE to specify objects - -precious-files-regex REGEX - don't remove output files matching REGEX - -release RELEASE specify package release information - -rpath LIBDIR the created library will eventually be installed in LIBDIR - -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries - -static do not do any dynamic linking of libtool libraries - -version-info CURRENT[:REVISION[:AGE]] - specify library version info [each variable defaults to 0] - -All other options (arguments beginning with \`-') are ignored. - -Every other argument is treated as a filename. Files ending in \`.la' are -treated as uninstalled libtool libraries, other files are standard or library -object files. - -If the OUTPUT-FILE ends in \`.la', then a libtool library is created, -only library objects (\`.lo' files) may be specified, and \`-rpath' is -required, except when creating a convenience library. - -If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created -using \`ar' and \`ranlib', or on Windows using \`lib'. - -If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file -is created, otherwise an executable program is created." - ;; - -uninstall) - $echo \ -"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... - -Remove libraries from an installation directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed -to RM. - -If FILE is a libtool library, all the files associated with it are deleted. -Otherwise, only FILE itself is deleted using RM." - ;; - -*) - $echo "$modename: invalid operation mode \`$mode'" 1>&2 - $echo "$help" 1>&2 - exit $EXIT_FAILURE - ;; -esac - -$echo -$echo "Try \`$modename --help' for more information about other modes." - -exit $? - -# The TAGs below are defined such that we never get into a situation -# in which we disable both kinds of libraries. Given conflicting -# choices, we go for a static library, that is the most portable, -# since we can't tell whether shared libraries were disabled because -# the user asked for that or because the platform doesn't support -# them. This is particularly important on AIX, because we don't -# support having both static and shared libraries enabled at the same -# time on that platform, so we default to a shared-only configuration. -# If a disable-shared tag is given, we'll fallback to a static-only -# configuration. But we'll never go from static-only to shared-only. - -# ### BEGIN LIBTOOL TAG CONFIG: disable-shared -build_libtool_libs=no -build_old_libs=yes -# ### END LIBTOOL TAG CONFIG: disable-shared - -# ### BEGIN LIBTOOL TAG CONFIG: disable-static -build_old_libs=`case $build_libtool_libs in yes) $echo no;; *) $echo yes;; esac` -# ### END LIBTOOL TAG CONFIG: disable-static - -# Local Variables: -# mode:shell-script -# sh-indentation:2 -# End: diff --git a/storage/bdb/dist/pubdef.in b/storage/bdb/dist/pubdef.in deleted file mode 100644 index b0873839d7d..00000000000 --- a/storage/bdb/dist/pubdef.in +++ /dev/null @@ -1,412 +0,0 @@ -# $Id: pubdef.in,v 12.18 2005/11/08 03:25:00 bostic Exp $ -# -# Name -# D == documentation -# I == include file -# J == Java constant -# N == wrapped by the Java native layer -DB_AFTER D I J -DB_AGGRESSIVE D I J -DB_ALREADY_ABORTED * I * -DB_AM_CHKSUM * I * -DB_AM_CL_WRITER * I * -DB_AM_COMPENSATE * I * -DB_AM_CREATED * I * -DB_AM_CREATED_MSTR * I * -DB_AM_DBM_ERROR * I * -DB_AM_DELIMITER * I * -DB_AM_DISCARD * I * -DB_AM_DUP * I * -DB_AM_DUPSORT * I * -DB_AM_ENCRYPT * I * -DB_AM_FIXEDLEN * I * -DB_AM_INMEM * I * -DB_AM_INORDER * I * -DB_AM_IN_RENAME * I * -DB_AM_NOT_DURABLE * I * -DB_AM_OPEN_CALLED * I * -DB_AM_PAD * I * -DB_AM_PGDEF * I * -DB_AM_RDONLY * I * -DB_AM_READ_UNCOMMITTED * I * -DB_AM_RECNUM * I * -DB_AM_RECOVER * I * -DB_AM_RENUMBER * I * -DB_AM_REVSPLITOFF * I * -DB_AM_SECONDARY * I * -DB_AM_SNAPSHOT * I * -DB_AM_SUBDB * I * -DB_AM_SWAP * I * -DB_AM_TXN * I * -DB_AM_VERIFYING * I * -DB_APPEND D I J -DB_ARCH_ABS D I J -DB_ARCH_DATA D I J -DB_ARCH_LOG D I J -DB_ARCH_REMOVE D I J -DB_ASSOC_IMMUTABLE_KEY * I * -DB_AUTO_COMMIT D I J -DB_BEFORE D I J -DB_BTREE D I J -DB_BTREEMAGIC * I * -DB_BTREEOLDVER * I * -DB_BTREEVERSION * I * -DB_BUFFER_SMALL D I N -DB_CACHED_COUNTS * I * -DB_CDB_ALLDB D I J -DB_CHKSUM D I J -DB_COMPACT_FLAGS * I * -DB_CONFIG D * * -DB_CONSUME D I J -DB_CONSUME_WAIT D I J -DB_CREATE D I J -DB_CURRENT D I J -DB_CXX_NO_EXCEPTIONS D I * -DB_DBM_HSEARCH * I * -DB_DBT_APPMALLOC D I N -DB_DBT_DUPOK * I * -DB_DBT_ISSET * I * -DB_DBT_MALLOC D I J -DB_DBT_PARTIAL D I J -DB_DBT_REALLOC D I N -DB_DBT_USERMEM D I J -DB_DEGREE_2 * I * -DB_DELETED * I * -DB_DIRECT D I * -DB_DIRECT_DB D I J -DB_DIRECT_LOG D I J -DB_DIRTY_READ * I * -DB_DONOTINDEX D I J -DB_DSYNC_DB D I J -DB_DSYNC_LOG D I J -DB_DUP D I J -DB_DUPSORT D I J -DB_DURABLE_UNKNOWN * I * -DB_EID_BROADCAST D I J -DB_EID_INVALID D I J -DB_ENCRYPT D I J -DB_ENCRYPT_AES D I J -DB_ENV_AUTO_COMMIT * I * -DB_ENV_CDB * I * -DB_ENV_CDB_ALLDB * I * -DB_ENV_CREATE * I * -DB_ENV_DBLOCAL * I * -DB_ENV_DIRECT_DB * I * -DB_ENV_DIRECT_LOG * I * -DB_ENV_DSYNC_DB * I * -DB_ENV_DSYNC_LOG * I * -DB_ENV_FATAL * I * -DB_ENV_LOCKDOWN * I * -DB_ENV_LOG_AUTOREMOVE * I * -DB_ENV_LOG_INMEMORY * I * -DB_ENV_NOLOCKING * I * -DB_ENV_NOMMAP * I * -DB_ENV_NOPANIC * I * -DB_ENV_OPEN_CALLED * I * -DB_ENV_OVERWRITE * I * -DB_ENV_PRIVATE * I * -DB_ENV_REGION_INIT * I * -DB_ENV_RPCCLIENT * I * -DB_ENV_RPCCLIENT_GIVEN * I * -DB_ENV_SYSTEM_MEM * I * -DB_ENV_THREAD * I * -DB_ENV_TIME_NOTGRANTED * I * -DB_ENV_TXN_NOSYNC * I * -DB_ENV_TXN_WRITE_NOSYNC * I * -DB_ENV_YIELDCPU * I * -DB_EXCL D I J -DB_EXTENT * I * -DB_FAST_STAT D I J -DB_FCNTL_LOCKING * I * -DB_FILE_ID_LEN * I * -DB_FIRST D I J -DB_FLUSH D I J -DB_FORCE D I J -DB_FREELIST_ONLY D I J -DB_FREE_SPACE D I J -DB_GET_BOTH D I J -DB_GET_BOTHC * I * -DB_GET_BOTH_RANGE D I J -DB_GET_RECNO D I J -DB_HANDLE_LOCK * I * -DB_HASH D I J -DB_HASHMAGIC * I * -DB_HASHOLDVER * I * -DB_HASHVERSION * I * -DB_HOME D * * -DB_IMMUTABLE_KEY D I J -DB_INIT_CDB D I J -DB_INIT_LOCK D I J -DB_INIT_LOG D I J -DB_INIT_MPOOL D I J -DB_INIT_REP D I J -DB_INIT_TXN D I J -DB_INORDER D I J -DB_JOINENV * I J -DB_JOIN_ITEM D I J -DB_JOIN_NOSORT D I J -DB_KEYEMPTY D I J -DB_KEYEXIST D I J -DB_KEYFIRST D I J -DB_KEYLAST D I J -DB_LAST D I J -DB_LOCKDOWN D I J -DB_LOCKVERSION * I * -DB_LOCK_ABORT * I * -DB_LOCK_DEADLOCK D I J -DB_LOCK_DEFAULT D I J -DB_LOCK_DUMP * I * -DB_LOCK_EXPIRE D I J -DB_LOCK_GET D I J -DB_LOCK_GET_TIMEOUT D I J -DB_LOCK_INHERIT * I * -DB_LOCK_IREAD D I J -DB_LOCK_IWR D I J -DB_LOCK_IWRITE D I J -DB_LOCK_MAXLOCKS D I J -DB_LOCK_MAXWRITE D I J -DB_LOCK_MINLOCKS D I J -DB_LOCK_MINWRITE D I J -DB_LOCK_NG * I * -DB_LOCK_NORUN * I * -DB_LOCK_NOTGRANTED D I J -DB_LOCK_NOWAIT D I J -DB_LOCK_OLDEST D I J -DB_LOCK_PUT D I J -DB_LOCK_PUT_ALL D I J -DB_LOCK_PUT_OBJ D I J -DB_LOCK_PUT_READ * I * -DB_LOCK_RANDOM D I J -DB_LOCK_READ D I J -DB_LOCK_READ_UNCOMMITTED * I * -DB_LOCK_RECORD * I * -DB_LOCK_SET_TIMEOUT * I * -DB_LOCK_SWITCH * I * -DB_LOCK_TIMEOUT D I J -DB_LOCK_TRADE * I * -DB_LOCK_UPGRADE * I * -DB_LOCK_UPGRADE_WRITE * I * -DB_LOCK_WAIT * I * -DB_LOCK_WRITE D I J -DB_LOCK_WWRITE * I * -DB_LOCK_YOUNGEST D I J -DB_LOGC_BUF_SIZE * I * -DB_LOGFILEID_INVALID * I * -DB_LOGMAGIC * I * -DB_LOGOLDVER * I * -DB_LOGVERSION * I * -DB_LOG_AUTOREMOVE D I J -DB_LOG_BUFFER_FULL D I * -DB_LOG_CHKPNT * I * -DB_LOG_COMMIT * I * -DB_LOG_DISK * I * -DB_LOG_INMEMORY D I J -DB_LOG_LOCKED * I * -DB_LOG_NOCOPY * I * -DB_LOG_NOT_DURABLE * I * -DB_LOG_PERM * I * -DB_LOG_RESEND * I * -DB_LOG_SILENT_ERR * I * -DB_LOG_WRNOSYNC * I * -DB_LSTAT_ABORTED * I * -DB_LSTAT_EXPIRED * I * -DB_LSTAT_FREE * I * -DB_LSTAT_HELD * I * -DB_LSTAT_PENDING * I * -DB_LSTAT_WAITING * I * -DB_MAX_PAGES * I * -DB_MAX_RECORDS * I * -DB_MPOOL_CLEAN D I * -DB_MPOOL_CREATE D I * -DB_MPOOL_DIRTY D I * -DB_MPOOL_DISCARD D I * -DB_MPOOL_FREE * I * -DB_MPOOL_LAST D I * -DB_MPOOL_NEW D I * -DB_MPOOL_NOFILE D I J -DB_MPOOL_UNLINK D I J -DB_MULTIPLE D I J -DB_MULTIPLE_INIT D I * -DB_MULTIPLE_KEY D I J -DB_MULTIPLE_KEY_NEXT D I * -DB_MULTIPLE_NEXT D I * -DB_MULTIPLE_RECNO_NEXT D I * -DB_MUTEX_ALLOCATED * I * -DB_MUTEX_LOCKED * I * -DB_MUTEX_LOGICAL_LOCK * I * -DB_MUTEX_SELF_BLOCK D I * -DB_MUTEX_THREAD * I * -DB_NEEDSPLIT * I * -DB_NEXT D I J -DB_NEXT_DUP D I J -DB_NEXT_NODUP D I J -DB_NODUPDATA D I J -DB_NOLOCKING D I J -DB_NOMMAP D I J -DB_NOORDERCHK D I J -DB_NOOVERWRITE D I J -DB_NOPANIC D I J -DB_NOSERVER D I * -DB_NOSERVER_HOME D I J -DB_NOSERVER_ID D I J -DB_NOSYNC D I J -DB_NOTFOUND D I J -DB_NO_AUTO_COMMIT * I * -DB_ODDFILESIZE D I * -DB_OK_BTREE * I * -DB_OK_HASH * I * -DB_OK_QUEUE * I * -DB_OK_RECNO * I * -DB_OLD_VERSION D I * -DB_OPFLAGS_MASK * I * -DB_ORDERCHKONLY D I J -DB_OVERWRITE D I J -DB_PAGE_LOCK * I * -DB_PAGE_NOTFOUND D I * -DB_PANIC_ENVIRONMENT D I J -DB_POSITION D I J -DB_PREV D I J -DB_PREV_NODUP D I J -DB_PRINTABLE D I J -DB_PRIORITY_DEFAULT D I J -DB_PRIORITY_HIGH D I J -DB_PRIORITY_LOW D I J -DB_PRIORITY_VERY_HIGH D I J -DB_PRIORITY_VERY_LOW D I J -DB_PRIVATE D I J -DB_PR_PAGE * I * -DB_PR_RECOVERYTEST * I * -DB_QAMMAGIC * I * -DB_QAMOLDVER * I * -DB_QAMVERSION * I * -DB_QUEUE D I J -DB_RDONLY D I J -DB_RDWRMASTER * I * -DB_READ_COMMITTED D I J -DB_READ_UNCOMMITTED D I J -DB_RECNO D I J -DB_RECNUM D I J -DB_RECORDCOUNT * I * -DB_RECORD_LOCK * I * -DB_RECOVER D I J -DB_RECOVER_FATAL D I J -DB_REDO * I * -DB_REGION_INIT D I J -DB_REGION_MAGIC * I * -DB_REGISTER D I J -DB_RENAMEMAGIC * I * -DB_RENUMBER D I J -DB_REP_ANYWHERE D I J -DB_REP_BULKOVF * I * -DB_REP_CLIENT D I J -DB_REP_CONF_BULK D I J -DB_REP_CONF_DELAYCLIENT D I J -DB_REP_CONF_NOAUTOINIT D I J -DB_REP_CONF_NOWAIT D I J -DB_REP_DUPMASTER D I N -DB_REP_EGENCHG * I * -DB_REP_HANDLE_DEAD D I N -DB_REP_HOLDELECTION D I N -DB_REP_IGNORE D I J -DB_REP_ISPERM D I J -DB_REP_JOIN_FAILURE D I N -DB_REP_LOCKOUT D I N -DB_REP_LOGREADY * I * -DB_REP_MASTER D I J -DB_REP_NEWMASTER D I J -DB_REP_NEWSITE D I J -DB_REP_NOBUFFER D I J -DB_REP_NOTPERM D I J -DB_REP_PAGEDONE * I * -DB_REP_PERMANENT D I J -DB_REP_REREQUEST D I J -DB_REP_STARTUPDONE D I J -DB_REP_UNAVAIL D I N -DB_REVSPLITOFF D I J -DB_RMW D I J -DB_RPCCLIENT D I J -DB_RUNRECOVERY D I N -DB_SALVAGE D I J -DB_SECONDARY_BAD D I * -DB_SEQUENCE_OLDVER * I * -DB_SEQUENCE_VERSION * I * -DB_SEQ_DEC D I J -DB_SEQ_INC D I J -DB_SEQ_RANGE_SET * I * -DB_SEQ_WRAP D I J -DB_SEQ_WRAPPED * I * -DB_SET D I J -DB_SET_LOCK_TIMEOUT D I J -DB_SET_RANGE D I J -DB_SET_RECNO D I J -DB_SET_TXN_LSNP * I * -DB_SET_TXN_NOW * I * -DB_SET_TXN_TIMEOUT D I J -DB_SNAPSHOT D I J -DB_STAT_ALL D I * -DB_STAT_CLEAR D I J -DB_STAT_LOCK_CONF D I * -DB_STAT_LOCK_LOCKERS D I * -DB_STAT_LOCK_OBJECTS D I * -DB_STAT_LOCK_PARAMS D I * -DB_STAT_MEMP_HASH D I * -DB_STAT_SUBSYSTEM D I * -DB_SURPRISE_KID * I * -DB_SWAPBYTES * I * -DB_SYSTEM_MEM D I J -DB_TEST_ELECTINIT * I * -DB_TEST_ELECTVOTE1 * I * -DB_TEST_POSTDESTROY * I * -DB_TEST_POSTLOG * I * -DB_TEST_POSTLOGMETA * I * -DB_TEST_POSTOPEN * I * -DB_TEST_POSTSYNC * I * -DB_TEST_PREDESTROY * I * -DB_TEST_PREOPEN * I * -DB_TEST_SUBDB_LOCKS * I * -DB_THREAD D I J -DB_THREADID_STRLEN D I * -DB_TIMEOUT * I * -DB_TIME_NOTGRANTED D I J -DB_TRUNCATE D I J -DB_TXNVERSION * I * -DB_TXN_ABORT D I J -DB_TXN_APPLY D I J -DB_TXN_BACKWARD_ALLOC * I * -DB_TXN_BACKWARD_ROLL D I J -DB_TXN_CKP * I * -DB_TXN_FORWARD_ROLL D I J -DB_TXN_NOSYNC D I J -DB_TXN_NOT_DURABLE D I J -DB_TXN_NOWAIT D I J -DB_TXN_OPENFILES * I * -DB_TXN_POPENFILES * I * -DB_TXN_PRINT D I J -DB_TXN_SYNC D I J -DB_TXN_WRITE_NOSYNC D I J -DB_UNDO * I * -DB_UNKNOWN D I J -DB_UNREF * I * -DB_UPDATE_SECONDARY * I * -DB_UPGRADE D I J -DB_USE_ENVIRON D I J -DB_USE_ENVIRON_ROOT D I J -DB_VERB_DEADLOCK D I J -DB_VERB_RECOVERY D I J -DB_VERB_REGISTER D I J -DB_VERB_REPLICATION D I J -DB_VERB_WAITSFOR D I J -DB_VERIFY D I J -DB_VERIFY_BAD D I N -DB_VERIFY_FATAL * I * -DB_VERSION_MAJOR * I J -DB_VERSION_MINOR * I J -DB_VERSION_MISMATCH D I N -DB_VERSION_PATCH * I J -DB_VERSION_STRING * I N -DB_WRITECURSOR D I J -DB_WRITELOCK * I * -DB_WRITEOPEN * I * -DB_XA_CREATE D I J -DB_XIDDATASIZE D I J -DB_YIELDCPU D I J diff --git a/storage/bdb/dist/s_all b/storage/bdb/dist/s_all deleted file mode 100644 index cabd38e8dc6..00000000000 --- a/storage/bdb/dist/s_all +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -# $Id: s_all,v 12.0 2004/11/17 03:43:35 bostic Exp $ - -sh s_perm # permissions. -#sh s_symlink # symbolic links. -sh s_readme # distribution README file. - -# -# The following order is important, s_include must run last. -# -sh s_config # autoconf. -sh s_recover # logging/recovery files. -#sh s_rpc # RPC files. -sh s_include # standard include files. - -sh s_win32 # Win32 include files. -sh s_win32_dsp # Win32 build environment. -#sh s_vxworks # VxWorks include files. -#sh s_java # Java support. -#sh s_test # Test suite support. -#sh s_tags # Tags files. diff --git a/storage/bdb/dist/s_config b/storage/bdb/dist/s_config deleted file mode 100644 index 194df83a59e..00000000000 --- a/storage/bdb/dist/s_config +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/sh - -# $Id: s_config,v 12.1 2005/08/16 05:19:18 mjc Exp $ -# -# Build the autoconfiguration files. - -trap 'rm -f aclocal.m4 ; exit 0' 0 1 2 3 13 15 - -. ./RELEASE - -echo "autoconf: building aclocal.m4..." -cat aclocal/*.ac aclocal_java/*.ac > aclocal.m4 - -echo "autoconf: running autoheader to build config.hin..." -rm -f config.hin -autoheader -chmod 444 config.hin - -echo "autoconf: running autoconf to build configure" -rm -f configure -autoconf - -# Edit version information we couldn't pre-compute. -sed -e "s/__EDIT_DB_VERSION_MAJOR__/$DB_VERSION_MAJOR/g" \ - -e "s/__EDIT_DB_VERSION_MINOR__/$DB_VERSION_MINOR/g" \ - -e "s/__EDIT_DB_VERSION_PATCH__/$DB_VERSION_PATCH/g" \ - -e "s/__EDIT_DB_VERSION_STRING__/$DB_VERSION_STRING/g" \ - -e "s/__EDIT_DB_VERSION_UNIQUE_NAME__/$DB_VERSION_UNIQUE_NAME/g" \ - -e "s/__EDIT_DB_VERSION__/$DB_VERSION/g" configure > configure.version -mv configure.version configure - -rm -rf autom4te.cache -chmod 555 configure - -chmod 555 config.guess config.sub install-sh diff --git a/storage/bdb/dist/s_crypto b/storage/bdb/dist/s_crypto deleted file mode 100644 index cc54a347c07..00000000000 --- a/storage/bdb/dist/s_crypto +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/sh - -# $Id: s_crypto,v 12.0 2004/11/17 03:43:35 bostic Exp $ - -# Remove crypto from the DB source tree. - -d=.. - -t=/tmp/__db_a -trap 'rm -f $t ; exit 0' 0 -trap 'rm -f $t ; exit 1' 1 2 3 13 15 - -if ! test -d $d/crypto; then - echo "s_crypto: no crypto sources found in the source tree." - exit 1 -fi - -# Remove the crypto. -rm -rf $d/crypto - -# Update the release splash page. -f=$d/docs/index.html -chmod 664 $f -(echo '/DOES/' && - echo 's/DOES/DOES NOT/' && - echo 'w' && - echo 'q') | ed $f - -# Win/32. -f=win_config.in -chmod 664 $f -(echo '/#define.HAVE_CRYPTO/' && - echo 'c' && - echo '/* #undef HAVE_CRYPTO */' - echo '.' && - echo 'w' && - echo 'q') | ed $f - -f=srcfiles.in -chmod 664 $f -(echo 'g/^crypto\//d' && - echo '/crypto_stub\.c/' && - echo 's/small/dynamic small static vx/' && - echo 'w' && - echo 'q') | ed $f - - sh ./s_win32 - sh ./s_win32_dsp - -# VxWorks -f=vx_config.in -chmod 664 $f -(echo '/#define.HAVE_CRYPTO/' && - echo 'c' && - echo '/* #undef HAVE_CRYPTO */' - echo '.' && - echo 'w' && - echo 'q') | ed $f - - sh ./s_vxworks diff --git a/storage/bdb/dist/s_dir b/storage/bdb/dist/s_dir deleted file mode 100644 index 58513a8321d..00000000000 --- a/storage/bdb/dist/s_dir +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/sh - - -make_dir() -{ - if test ! -d $1; then - echo "mkdir $1" - mkdir $1 - status=$? - if test $status -ne 0 && test ! -d $1; then - echo "error: $status" - fi - fi -} - -echo "Creating directories..." - -make_dir ../test_server -make_dir ../dbinc_auto -make_dir ../build_vxworks/BerkeleyDB -make_dir ../build_vxworks/db_archive -make_dir ../build_vxworks/db_archive/db_archive -make_dir ../build_vxworks/db_checkpoint -make_dir ../build_vxworks/db_checkpoint/db_checkpoint -make_dir ../build_vxworks/db_deadlock -make_dir ../build_vxworks/db_deadlock/db_deadlock -make_dir ../build_vxworks/db_dump -make_dir ../build_vxworks/db_dump/db_dump -make_dir ../build_vxworks/db_load -make_dir ../build_vxworks/db_load/db_load -make_dir ../build_vxworks/db_printlog -make_dir ../build_vxworks/db_printlog/db_printlog -make_dir ../build_vxworks/db_recover -make_dir ../build_vxworks/db_recover/db_recover -make_dir ../build_vxworks/db_stat -make_dir ../build_vxworks/db_stat/db_stat -make_dir ../build_vxworks/db_upgrade -make_dir ../build_vxworks/db_upgrade/db_upgrade -make_dir ../build_vxworks/db_verify -make_dir ../build_vxworks/db_verify/db_verify -make_dir ../build_vxworks/dbdemo/dbdemo -make_dir ../dbinc_auto - diff --git a/storage/bdb/dist/s_include b/storage/bdb/dist/s_include deleted file mode 100644 index e5531e1bcbf..00000000000 --- a/storage/bdb/dist/s_include +++ /dev/null @@ -1,155 +0,0 @@ -#!/bin/sh - -# $Id: s_include,v 12.0 2004/11/17 03:43:35 bostic Exp $ -# -# Build the automatically generated function prototype files. - -msgc="/* DO NOT EDIT: automatically built by dist/s_include. */" - -. ./RELEASE - -head() -{ - defonly=0 - while : - do case "$1" in - space) - echo ""; shift;; - defonly) - defonly=1; shift;; - *) - name="$1"; break;; - esac - done - - echo "$msgc" - echo "#ifndef $name" - echo "#define $name" - echo "" - if [ $defonly -eq 0 ]; then - echo "#if defined(__cplusplus)" - echo "extern \"C\" {" - echo "#endif" - echo "" - fi -} - -tail() -{ - defonly=0 - while : - do case "$1" in - defonly) - defonly=1; shift;; - *) - name="$1"; break;; - esac - done - - echo "" - if [ $defonly -eq 0 ]; then - echo "#if defined(__cplusplus)" - echo "}" - echo "#endif" - fi - echo "#endif /* !$name */" -} - -# We are building several files: -# 1 external #define file -# 1 external prototype file -# 1 internal #define file -# N internal prototype files -e_dfile=/tmp/__db_c.$$ -e_pfile=/tmp/__db_a.$$ -i_dfile=/tmp/__db_d.$$ -i_pfile=/tmp/__db_b.$$ -trap 'rm -f $e_dfile $e_pfile $i_dfile $i_pfile; exit 0' 0 1 2 3 13 15 - -head defonly space _DB_EXT_DEF_IN_ > $e_dfile -head space _DB_EXT_PROT_IN_ > $e_pfile -head defonly _DB_INT_DEF_IN_ > $i_dfile - -# Process the standard directories, creating per-directory prototype -# files and adding to the external prototype and #define files. -for i in db btree clib common crypto dbreg env fileops hash hmac \ - lock log mp mutex os qam rep sequence txn xa; do - head "_${i}_ext_h_" > $i_pfile - - if [ $i = os ] ; then - f=`ls ../$i/*.c ../os_win32/*.c` - elif [ $i = rpc_server ] ; then - f=`ls ../$i/c/*.c` - elif [ $i = crypto ] ; then - f=`ls ../$i/*.c ../$i/*/*.c` - else - f=`ls ../$i/*.c` - fi - awk -f gen_inc.awk \ - -v db_version_unique_name=$DB_VERSION_UNIQUE_NAME \ - -v e_dfile=$e_dfile \ - -v e_pfile=$e_pfile \ - -v i_dfile=$i_dfile \ - -v i_pfile=$i_pfile $f - - tail "_${i}_ext_h_" >> $i_pfile - - f=../dbinc_auto/${i}_ext.h - cmp $i_pfile $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $i_pfile $f && chmod 444 $f) -done - -# Process directories which only add to the external prototype and #define -# files. -for i in dbm hsearch; do - f=`ls ../$i/*.c` - awk -f gen_inc.awk \ - -v db_version_unique_name=$DB_VERSION_UNIQUE_NAME \ - -v e_dfile=$e_dfile \ - -v e_pfile=$e_pfile \ - -v i_dfile="" \ - -v i_pfile="" $f -done - -# There are a few globals in DB -- add them to the external/internal -# #define files. -(echo "#define __db_global_values __db_global_values@DB_VERSION_UNIQUE_NAME@"; - echo "#define __db_jump __db_jump@DB_VERSION_UNIQUE_NAME@") >> $i_dfile -(echo "#define db_xa_switch db_xa_switch@DB_VERSION_UNIQUE_NAME@") >> $e_dfile - -# Wrap up the external #defines/prototypes, and internal #defines. -tail defonly _DB_EXT_DEF_IN_ >> $e_dfile -f=../dbinc_auto/ext_def.in -cmp $e_dfile $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $e_dfile $f && chmod 444 $f) - -tail _DB_EXT_PROT_IN_ >> $e_pfile -f=../dbinc_auto/ext_prot.in -cmp $e_pfile $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $e_pfile $f && chmod 444 $f) - -tail defonly _DB_INT_DEF_IN_ >> $i_dfile -f=../dbinc_auto/int_def.in -cmp $i_dfile $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $i_dfile $f && chmod 444 $f) - -# DB185 compatibility support. -head space defonly _DB_EXT_185_DEF_IN_ > $e_dfile -head space _DB_EXT_185_PROT_IN_ > $e_pfile - -f=`ls ../db185/*.c` -awk -f gen_inc.awk \ - -v db_version_unique_name=$DB_VERSION_UNIQUE_NAME \ - -v e_dfile=$e_dfile \ - -v e_pfile=$e_pfile \ - -v i_dfile="" \ - -v i_pfile="" $f - -tail defonly _DB_EXT_185_DEF_IN_ >> $e_dfile -f=../dbinc_auto/ext_185_def.in -cmp $e_dfile $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $e_dfile $f && chmod 444 $f) - -tail _DB_EXT_185_PROT_IN_ >> $e_pfile -f=../dbinc_auto/ext_185_prot.in -cmp $e_pfile $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $e_pfile $f && chmod 444 $f) diff --git a/storage/bdb/dist/s_java b/storage/bdb/dist/s_java deleted file mode 100644 index 57b88e8e560..00000000000 --- a/storage/bdb/dist/s_java +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -# $Id: s_java,v 12.0 2004/11/17 03:43:35 bostic Exp $ -# -# Build the Java files. - -sh s_java_stat # Create Java stat methods -sh s_java_swig # Create core Java API with SWIG -sh s_java_const # Create Java constants diff --git a/storage/bdb/dist/s_java_const b/storage/bdb/dist/s_java_const deleted file mode 100644 index 8374b1f61a8..00000000000 --- a/storage/bdb/dist/s_java_const +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/sh - -# $Id: s_java_const,v 12.0 2004/11/17 03:43:35 bostic Exp $ -# -# Build the Java files. - -msgjava="/* DO NOT EDIT: automatically built by dist/s_java_const. */" - -. RELEASE - -t=/tmp/__java -trap 'rm -f $t; exit 0' 0 1 2 3 13 15 - -(echo "$msgjava" && - echo && - echo 'package com.sleepycat.db.internal;' && - echo && - echo 'public interface DbConstants' && - echo '{' && - for i in `egrep '^DB_.*J$' pubdef.in | awk '{print $1}'`; do \ - egrep -w "^#define[ ]$i|^[ ][ ]*$i" ../dbinc/db.in; \ - done | - sed -e "s/@DB_VERSION_MAJOR@/$DB_VERSION_MAJOR/" \ - -e "s/@DB_VERSION_MINOR@/$DB_VERSION_MINOR/" \ - -e "s/@DB_VERSION_PATCH@/$DB_VERSION_PATCH/" \ - -e 's/^#define[ ][ ]*//' \ - -e 's/[()=,]/ /g' \ - -e 's/\/\*/ /' | \ - awk '{ print " int " $1 " = " $2 ";" }' && - echo '}' && - echo && - echo '// end of DbConstants.java') > $t - -f=../java/src/com/sleepycat/db/internal/DbConstants.java -cmp $t $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) diff --git a/storage/bdb/dist/s_java_stat b/storage/bdb/dist/s_java_stat deleted file mode 100644 index 0d00be59646..00000000000 --- a/storage/bdb/dist/s_java_stat +++ /dev/null @@ -1,364 +0,0 @@ -#!/bin/sh - -# $Id: s_java_stat,v 12.9 2005/11/04 00:09:21 mjc Exp $ -# -# Build the Java files. - -msgjava="/*- - * DO NOT EDIT: automatically built by dist/s_java_stat. - * - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2002-2005 - * Sleepycat Software. All rights reserved. - */" - - -s=/tmp/__java.sed -t=/tmp/__java -c=/tmp/__javajnic -u1=/tmp/__javautil1 -u2=/tmp/__javautil2 -trap 'rm -f $t $c $u1 $u2; exit 0' 0 1 2 3 13 15 - -# Script to convert DB C structure declarations into Java declarations. -jclass() -{ - cat > $s <<EOF -/struct __db_$1 {/,/^}/{ - /__db_$1/d - /;/!d - /^}/d - /db_threadid_t/d - /char[ ]*/{ - s/^[ ]*char[* ]*[ ]*\([^[;]*\).*/\\ -$2 private String \1;\\ -$2 public String get_\1() {\\ -$2 return \1;\\ -$2 }/p - d - } - /time_t/{ - s/^[ ]*[^ ]*[ ]*\([^;]*\).*/\\ -$2 private long \1;\\ -$2 public long get_\1() {\\ -$2 return \1;\\ -$2 }/p - d - } - /db_seq_t/{ - s/^[ ]*[^ ]*[ ]*\([^;]*\).*/\\ -$2 private long \1;\\ -$2 public long get_\1() {\\ -$2 return \1;\\ -$2 }/p - d - } - /DB_LSN[ ]*/{ - s/^[ ]*[^ ]*[ ]*\([^;]*\).*/\\ -$2 private LogSequenceNumber \1;\\ -$2 public LogSequenceNumber get_\1() {\\ -$2 return \1;\\ -$2 }/p - d - } - /DB_TXN_ACTIVE[ ]*\*/{ - s/^[ ]*[^\*]*\*[ ]*\([^;]*\).*/\\ -$2 private Active[] \1;\\ -$2 public Active[] get_\1() {\\ -$2 return \1;\\ -$2 }/p - d - } - /u_int8_t[ ]*xid\[/{ - s/^[ ]*[^ ]*[ ]*\([^[;]*\).*/\\ -$2 private byte[] \1;\\ -$2 public byte[] get_\1() {\\ -$2 return \1;\\ -$2 }/p - d - } - s/^[ ]*[^ ]*[ ]*\([^;]*\).*/\\ -$2 private int \1;\\ -$2 public int get_\1() {\\ -$2 return \1;\\ -$2 }/p -} -EOF - sed -n -f $s < ../dbinc/db.in | - perl -w -p -e 's/get_(st|bt|hash|qs|compact)_/get_/;' \ - -e 'if (m/get.*\(/) {' \ - -e 's/_n([b-df-hj-np-tv-z]|upgrade)/_num_$1/;' \ - -e 's/_(min|max)([a-z])/_$1_$2/;' \ - -e 's/_cnt/_count_/;' \ - -e 's/_pg/_pages_/;' \ - -e 's/(count|flag|free|page|percent|size|timeout)/_$1/g;' \ - -e 's/([^p])(id\()/$1_$2/g;' \ - -e 's/__*/_/g;' \ - -e 's/_(.)/\U$1/g' \ - -e '};' \ - -e '1' -} - -# Script to convert DB C structure declarations into a JNI method to fill the -# corresponding Java class -jclass_jni() -{ - fill=__dbj_fill_$1 - j_class=$2 - jni_fieldid_decls $1 $2 - jni_fieldids $1 $2 - cat > $s <<EOF -/struct __db_$1 {/,/^}/{ - /__db_$1/d - /;/!d - /^}/d - /db_threadid_t/d - /char[ ]*/{ - s/^[ ]*char[* ]*[ ]*\([^[;]*\).*/ JAVADB_STAT_STRING(jnienv, jobj, $1_\1_fid, statp, \1);/p - d - } - /time_t/{ - s/^[ ]*[^ ]*[ ]*\([^;]*\).*/ JAVADB_STAT_LONG(jnienv, jobj, $1_\1_fid, statp, \1);/p - d - } - /db_seq_t/{ - s/^[ ]*[^ ]*[ ]*\([^;]*\).*/ JAVADB_STAT_LONG(jnienv, jobj, $1_\1_fid, statp, \1);/p - d - } - /DB_LSN[ ]*/{ - s/^[ ]*[^ ]*[ ]*\([^;]*\).*/ JAVADB_STAT_LSN(jnienv, jobj, $1_\1_fid, statp, \1);/p - d - } - /DB_TXN_ACTIVE[ ]*\*/{ - s/^[ ]*[^\*]*\*[ ]*\([^;]*\).*/ JAVADB_STAT_ACTIVE(jnienv, jobj, $1_\1_fid, statp, \1);/p - d - } - /u_int8_t[ ]*xid\[/{ - s/^[ ]*[^ ]*[ ]*\([^[;]*\).*/ JAVADB_STAT_XID(jnienv, jobj, $1_\1_fid, statp, \1);/p - d - } - s/^[ ]*[^ ]*[ ]*\([^;]*\).*/ JAVADB_STAT_INT(jnienv, jobj, $1_\1_fid, statp, \1);/p -} -EOF - echo "static int $fill(JNIEnv *jnienv, " >> $c - echo " jobject jobj, struct __db_$1 *statp) {" >> $c - sed -n -f $s < ../dbinc/db.in >> $c - echo ' return (0);' >> $c - echo '}' >> $c -} - -jni_fieldid_decls() -{ - cat > $s <<EOF -/struct __db_$1 {/,/^}/{ - /__db_$1/d - /;/!d - /^}/d - /db_threadid_t/d - /char[ ]*/{ - s/^[ ]*char[* ]*[ ]*\([^[;]*\).*/static jfieldID $1_\1_fid;/p - d - } - /time_t/{ - s/^[ ]*[^ ]*[ ]*\([^;]*\).*/static jfieldID $1_\1_fid;/p - d - } - /db_seq_t/{ - s/^[ ]*[^ ]*[ ]*\([^;]*\).*/static jfieldID $1_\1_fid;/p - d - } - /DB_LSN[ ]*/{ - s/^[ ]*[^ ]*[ ]*\([^;]*\).*/static jfieldID $1_\1_fid;/p - d - } - /DB_TXN_ACTIVE[ ]*\*/{ - s/^[ ]*[^\*]*\*[ ]*\([^;]*\).*/static jfieldID $1_\1_fid;/p - d - } - /u_int8_t[ ]*xid\[/{ - s/^[ ]*[^ ]*[ ]*\([^[;]*\).*/static jfieldID $1_\1_fid;/p - d - } - s/^[ ]*[^ ]*[ ]*\([^;]*\).*/static jfieldID $1_\1_fid;/p -} -EOF - sed -n -f $s < ../dbinc/db.in >> $u1 -} - -jni_fieldids() -{ - cat > $s <<EOF -/struct __db_$1 {/,/^}/{ - /__db_$1/d - /;/!d - /^}/d - /db_threadid_t/d - /char[ ]*/{ - s/^[ ]*char[* ]*[ ]*\([^[;]*\).*/ { \&$1_\1_fid, \&$1_class, \"\1\", \"Ljava\/lang\/String;\" },/p - d - } - /time_t/{ - s/^[ ]*[^ ]*[ ]*\([^;]*\).*/ { \&$1_\1_fid, \&$1_class, \"\1\", \"J\" },/p - d - } - /db_seq_t/{ - s/^[ ]*[^ ]*[ ]*\([^;]*\).*/ { \&$1_\1_fid, \&$1_class, \"\1\", \"J\" },/p - d - } - /DB_LSN[ ]*/{ - s/^[ ]*[^ ]*[ ]*\([^;]*\).*/ { \&$1_\1_fid, \&$1_class, \"\1\", \"L\" DB_PKG \"LogSequenceNumber;\" },/p - d - } - /DB_TXN_ACTIVE[ ]*\*/{ - s/^[ ]*[^\*]*\*[ ]*\([^;]*\).*/ { \&$1_\1_fid, \&$1_class, \"\1\", \"[L\" DB_PKG \"TransactionStats\$Active;\" },/p - d - } - /u_int8_t[ ]*xid\[/{ - s/^[ ]*[^ ]*[ ]*\([^[;]*\).*/ { \&$1_\1_fid, \&$1_class, \"\1\", \"[B\" },/p - d - } - s/^[ ]*[^ ]*[ ]*\([^;]*\).*/ { \&$1_\1_fid, \&$1_class, \"\1\", \"I\" },/p -} -EOF - sed -n -f $s < ../dbinc/db.in >> $u2 -} - -# Script to convert DB C structure declarations into a toString method body -jclass_toString() -{ - cat > $s <<EOF -/struct __db_$1 {/,/^}/{ - /__db_$1/d - /;/!d - /^}/d - /db_threadid_t/d - /char[ ]*/{ - s/^[ ]*char[* ]*[ ]*\([^[;]*\).*/$3 + "\\\\n$3 \1=" + \1/p - d - } - /DB_TXN_ACTIVE[ ]*\*/{ - s/^[ ]*[^\*]*\*[ ]*\([^;]*\).*/$3 + \"\\\\n$3 \1=\" + DbUtil.objectArrayToString(\1, \"\1\")/p - d - } - /u_int8_t[ ]*xid\[/{ - s/^[ ]*[^ ]*[ ]*\([^[;]*\).*/$3 + \"\\\\n$3 \1=\" + DbUtil.byteArrayToString(\1)/p - d - } - s/^[ ]*[^ ]*[ ]*\([^;]*\).*/$3 + \"\\\\n$3 \1=\" + \1/p -} -EOF - echo - echo "$3 public String toString() {" - echo "$3 return \"$2:\"" - sed -n -f $s < ../dbinc/db.in - echo "$3 ;" - echo "$3 }" -} - -stat_class() -{ - c_struct=__db_$1 - j_class=$2 - extends=$3 - - (echo "$msgjava" - echo - echo 'package com.sleepycat.db;' - echo - echo "public class $j_class$extends {" - echo " // no public constructor" - echo " protected $j_class() {}" - jclass $1 - jclass_toString $1 $2 - echo '}') > $t - jclass_jni $1 $2 - f=../java/src/com/sleepycat/db/$j_class.java - cmp $t $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) -} - -echo "$msgjava" > $c -> $u1 -> $u2 - -stat_class bt_stat BtreeStats " extends DatabaseStats" - -# Build CompactStats.java - not purely a statistics class, but close enough to -# share this code. -(echo "$msgjava" - echo - echo 'package com.sleepycat.db;' - echo - echo 'import com.sleepycat.db.internal.DbUtil;' - echo - echo "public class CompactStats" - echo '{' - echo " // no public constructor" - echo " protected CompactStats() {}" - echo - echo " /* package */" - echo " CompactStats(int fillpercent, int timeout, int pages) {" - echo " this.compact_fillpercent = fillpercent;" - echo " this.compact_timeout = timeout;" - echo " this.compact_pages = pages;" - echo " }" - jclass compact - jclass_toString compact CompactStats - echo '}' - echo '// end of TransactionStats.java') > $t -jclass_jni compact __dbj_fill_compact -f=../java/src/com/sleepycat/db/CompactStats.java -cmp $t $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) - -stat_class h_stat HashStats " extends DatabaseStats" -stat_class lock_stat LockStats -stat_class log_stat LogStats -stat_class mpool_fstat CacheFileStats -stat_class mpool_stat CacheStats -stat_class mutex_stat MutexStats -stat_class qam_stat QueueStats " extends DatabaseStats" -stat_class rep_stat ReplicationStats -stat_class seq_stat SequenceStats - -# Build TransactionStats.java - special because of embedded Active class -(echo "$msgjava" - echo - echo 'package com.sleepycat.db;' - echo - echo 'import com.sleepycat.db.internal.DbUtil;' - echo - echo "public class TransactionStats" - echo '{' - echo " // no public constructor" - echo " protected TransactionStats() {}" - echo - echo -n " public static class Active {" - echo " // no public constructor" - echo " protected Active() {}" - jclass txn_active " " - jclass_toString txn_active Active " " - echo ' };' - jclass txn_stat - jclass_toString txn_stat TransactionStats - echo '}' - echo '// end of TransactionStats.java') > $t -jclass_jni txn_stat __dbj_fill_txn_stat -jclass_jni txn_active __dbj_fill_txn_active -f=../java/src/com/sleepycat/db/TransactionStats.java -cmp $t $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) - -mv $c $t -f=../libdb_java/java_stat_auto.c -cmp $t $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) - -f=../libdb_java/java_util.i -sed '/BEGIN-STAT-FIELD-DECLS/q' < $f > $t -cat $u1 >> $t -sed -n '/END-STAT-FIELD-DECLS/,/BEGIN-STAT-FIELDS/p' < $f >> $t -cat $u2 >> $t -sed -n '/END-STAT-FIELDS/,$p' < $f >> $t -cmp $t $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $t $f && chmod 644 $f) diff --git a/storage/bdb/dist/s_java_swig b/storage/bdb/dist/s_java_swig deleted file mode 100644 index 8be53b058bc..00000000000 --- a/storage/bdb/dist/s_java_swig +++ /dev/null @@ -1,65 +0,0 @@ -#!/bin/sh - -# $Id: s_java_swig,v 12.2 2005/10/17 19:20:12 bostic Exp $ -# -# Run SWIG to generate the Java APIs - -t=/tmp/__db_a -trap 'rm -f $t ; exit 0' 0 -trap 'rm -f $t ; exit 1' 1 2 3 13 15 - -SWIG=swig -SWIG_DIR=../libdb_java -SWIG_FILE=$SWIG_DIR/db.i -PACKAGE="com.sleepycat.db.internal" - -die() { - echo "$@" >&2 - exit 1 -} - -[ -f $SWIG_FILE ] || die "Must be run from the dist directory" - -for api in java ; do - echo "Building $api API" - - swig_args="" - case $api in - java) - swig_args="-nodefault -package $PACKAGE $args" - ;; - esac - - $SWIG -Wall -$api $swig_args -I$SWIG_DIR \ - -o ../libdb_$api/db_${api}_wrap.c $SWIG_FILE || exit $? -done - -# Skip Java sources if run with "-n" -if [ "x$1" = "x-n" ] ; then - rm -f $SWIG_DIR/*.java - exit 0 -fi - -# Fixups for Java -JAVA_SRCTOP=../java/src -JAVA_PKGDIR=com/sleepycat/db/internal -JAVA_SRCDIR=$JAVA_SRCTOP/$JAVA_PKGDIR - -# SWIG 1.3.18 puts the Java files in the same directory as the native code. -cd $SWIG_DIR -[ -f Db.java ] || exit 1 - -for f in *.java ; do - case $f in - SWIGTYPE*) - die "Interface contains unresolved types: $f" - esac - rm -f $JAVA_SRCDIR/$f - perl -p $SWIG_DIR/java-post.pl < $f > $JAVA_SRCDIR/$f || exit $? - rm -f $f -done - -# db_config.h must be the first #include, move it to the top of the file. -( - echo '#include "db_config.h"' - sed '/#include "db_config.h"/d' < db_java_wrap.c -) > $t && cp $t db_java_wrap.c diff --git a/storage/bdb/dist/s_javah b/storage/bdb/dist/s_javah deleted file mode 100644 index 67c41d09c4d..00000000000 --- a/storage/bdb/dist/s_javah +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/sh - -# $Id: s_javah,v 1.1 2002/08/14 17:14:24 dda Exp $ -# -# Use javah to build the libdb_java/com_*.h header files. -# -# To run this, you will need a javac and javah in your PATH. -# If possible, install tools with a recent vintage, JDK 1.3 or higher is good. -# Using Sun's JDK rather than some other installation ensures -# that the header files will not be constantly changed. - -. ./RELEASE - -JAVAC=javac -JAVAH=javah -export CLASSPATH -CLASSPATH= - -# CLASSES are only those classes for which we have native methods. -D=com.sleepycat.db -CLASSES="$D.Dbc $D.DbEnv $D.Db $D.DbLock $D.DbLogc $D.DbLsn $D.Dbt $D.DbTxn $D.xa.DbXAResource" - -d=/tmp/__javah -c=$d/classes -trap 'rm -rf $d; exit 0' 0 1 2 3 13 15 - -rm -rf $d -mkdir $d || exit 1 -mkdir $c || exit 1 - -# Make skeleton versions of XA classes and interfaces -# We only need to compile them, not run them. -pkg="package javax.transaction.xa" -echo "$pkg; public interface XAResource {}" > $d/XAResource.java -echo "$pkg; public interface Xid {}" > $d/Xid.java -echo "$pkg; public class XAException extends Exception {}" \ - > $d/XAException.java - - -# Create the .class files and use them with javah to create the .h files -${JAVAC} -d $c $d/*.java \ - ../java/src/com/sleepycat/db/*.java \ - ../java/src/com/sleepycat/db/xa/*.java || exit 1 -${JAVAH} -classpath $c -d $d ${CLASSES} || exit 1 - -for cl in ${CLASSES}; do - h=`echo $cl | sed -e 's/\./_/g'`.h - t=$d/$h - f=../libdb_java/$h - if [ ! -f $t ]; then - echo "ERROR: $t does not exist" - exit 1 - fi - cmp $t $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) -done diff --git a/storage/bdb/dist/s_je2db b/storage/bdb/dist/s_je2db deleted file mode 100644 index a5c64197e57..00000000000 --- a/storage/bdb/dist/s_je2db +++ /dev/null @@ -1,88 +0,0 @@ -#!/bin/sh - - -# The examples must be hand-edited after they are copied: -# - add setInitializeCache(true), setInitializeLocking(true), setType(BTREE) -# - add null databaseName param to openDatabase() and openSecondaryDatabase() -# - remove foreign key configuration and imports - -COPY_EXAMPLES=0 - -JEDIR=$1 -if [ $# -eq 1 ] ; then - DBDIR=.. -else - DBDIR=$2 -fi - -if [ ! -d "$DBDIR/dbinc" -o ! -f "$JEDIR/build.xml" ] ; then - echo >&2 "Usage $0 /path/to/je [ /path/to/db ]" - exit 1 -fi - -JEDIR=$(cd "$JEDIR" ; /bin/pwd) -DBDIR=$(cd "$DBDIR" ; /bin/pwd) - -JESRC="$JEDIR/src" -JETEST="$JEDIR/test" -JEEXAMPLES="$JEDIR/examples" -DBSRC="$DBDIR/java/src" -DBTEST="$DBDIR/test/scr024/src" -DBEXAMPLES="$DBDIR/examples_java/src" -DIRMATCH="com/sleepycat\(/examples\)*/\(\(bind\)\|\(collections\)\|\(util\)\)" - -cd "$JESRC" -for d in `find . -type d | grep -v CVS | grep $DIRMATCH` ; do - #echo "$DBSRC/$d" - mkdir -p "$DBSRC/$d" -done -cd "$JETEST" -for d in `find . -type d | grep -v CVS | grep $DIRMATCH` ; do - #echo "$DBTEST/$d" - mkdir -p "$DBTEST/$d" -done -if [ $COPY_EXAMPLES -eq 1 ] ; then - cd "$JEEXAMPLES" - for d in `find . -type d | grep -v CVS | grep $DIRMATCH` ; do - #echo "$DBEXAMPLES/$d" - mkdir -p "$DBEXAMPLES/$d" - done -fi - -E1='s/com\.sleepycat\.je/com.sleepycat.db/g' -E2='/import com\.sleepycat\.db\.ForeignKeyNullifier/d' -E3='/implements/s/, ForeignKeyNullifier//' -E4='/<!-- begin JE only -->/,/<!-- end JE only -->/d' -EXCLUDETESTS="\(\(ForeignKeyTest\)\|\(TupleSerialFactoryTest\)\\|\(XACollectionTest\)\)" - -cd "$JESRC" -for f in `find . -name '*.java' | grep $DIRMATCH` ; do - #echo $DBSRC/$f - sed -e "$E1" -e "$E2" -e "$E3" -e "$E4" < $f > $DBSRC/$f.sed.out - diff -q -I "\$\Id:" $DBSRC/$f $DBSRC/$f.sed.out || \ - mv -f $DBSRC/$f.sed.out $DBSRC/$f - rm -f $DBSRC/$f.sed.out -done - -cd "$JETEST" -for f in `find . -name '*.java' | grep $DIRMATCH | grep -v $EXCLUDETESTS` ; do - #echo $DBTEST/$f - sed -e "$E1" < $f > $DBTEST/$f.sed.out - diff -q -I "\$\Id:" $DBTEST/$f $DBTEST/$f.sed.out || \ - mv -f $DBTEST/$f.sed.out $DBTEST/$f - rm -f $DBTEST/$f.sed.out -done -cp -f "com/sleepycat/collections/test/serial/TestSerial.java.original" \ - "$DBTEST/com/sleepycat/collections/test/serial" - -if [ $COPY_EXAMPLES -eq 1 ] ; then - cd "$JEEXAMPLES" - for f in `find . -name '*.java' | grep $DIRMATCH` ; do - #echo $DBEXAMPLES/$f - sed -e "$E1" < $f > $DBEXAMPLES/$f.sed.out - diff -q -I "\$\Id:" $DBEXAMPLES/$f $DBEXAMPLES/$f.sed.out || \ - mv -f $DBEXAMPLES/$f.sed.out $DBEXAMPLES/$f - rm -f $DBEXAMPLES/$f.sed.out - done -fi - -exit 0 diff --git a/storage/bdb/dist/s_perm b/storage/bdb/dist/s_perm deleted file mode 100755 index 219a76835e6..00000000000 --- a/storage/bdb/dist/s_perm +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/sh - -# $Id: s_perm,v 12.0 2004/11/17 03:43:35 bostic Exp $ - -d=.. -echo 'Updating Berkeley DB source tree permissions...' - -run() -{ - #echo " $1 ($2)" - if [ -f "$d/$1" ]; then - chmod "$2" "$d/$1" - else - echo "$d/$1: no such file or directory" - exit 1 - fi -} - -run build_win32/include.tcl 664 -run dist/config.guess 555 -run dist/config.sub 555 -run dist/configure 555 -run dist/install-sh 555 -run dist/s_all 555 -run dist/s_config 555 -run dist/s_crypto 555 -run dist/s_include 555 -run dist/s_java 555 -run dist/s_java_const 555 -run dist/s_java_stat 555 -run dist/s_java_swig 555 -run dist/s_perm 555 -run dist/s_readme 555 -run dist/s_recover 555 -run dist/s_rpc 555 -run dist/s_symlink 555 -run dist/s_tags 555 -run dist/s_test 555 -run dist/s_vxworks 555 -run dist/s_win32 555 -run dist/s_win32_dsp 555 -run dist/vx_buildcd 555 -#run mod_db4/configure 555 - -#run perl/BerkeleyDB/dbinfo 555 -#run perl/BerkeleyDB/mkpod 555 - -#for i in `cd $d && find build_vxworks \ -# -name '*.wsp' -o -name '*.cdf' -o -name '*.wpj'`; do - #echo " $i (775)" -# chmod 775 $d/$i -#done diff --git a/storage/bdb/dist/s_readme b/storage/bdb/dist/s_readme deleted file mode 100644 index 1a56da1bff3..00000000000 --- a/storage/bdb/dist/s_readme +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh - -# $Id: s_readme,v 12.0 2004/11/17 03:43:35 bostic Exp $ -# -# Build the README. - -echo 'Updating Berkeley DB README file...' - -d=.. - -t=/tmp/__t -trap 'rm -f $t; exit 0' 0 1 2 3 13 15 - -. RELEASE - -cat << END_OF_README>$t -$DB_VERSION_STRING - -This is version $DB_VERSION_MAJOR.$DB_VERSION_MINOR.$DB_VERSION_PATCH of Berkeley DB from Sleepycat Software. To view -the release and installation documentation, load the distribution file -docs/index.html into your web browser. -END_OF_README - -f=../README -cmp $t $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) diff --git a/storage/bdb/dist/s_recover b/storage/bdb/dist/s_recover deleted file mode 100755 index 9bea4a60493..00000000000 --- a/storage/bdb/dist/s_recover +++ /dev/null @@ -1,71 +0,0 @@ -#!/bin/sh - -# $Id: s_recover,v 12.0 2004/11/17 03:43:35 bostic Exp $ -# -# Build the automatically generated logging/recovery files. - -header=/tmp/__db_a -loglist=/tmp/__db_b -print=/tmp/__db_c -source=/tmp/__db_d -template=/tmp/__db_e -tmp=/tmp/__db_f - -trap 'rm -f /tmp/__db_[abcdef]; exit 1' 1 2 3 13 15 -trap 'rm -f /tmp/__db_[abcdef]; exit 0' 0 - -DIR="db dbreg btree fileops hash qam rep txn" - -# Check to make sure we haven't duplicated a log record entry, and build -# the list of log record types that the test suite uses. -for i in $DIR; do - for f in ../$i/*.src; do - # Grab the PREFIX; there should only be one per file, and - # so it's okay to just take the first. - grep '^PREFIX' $f | sed q - egrep '^BEGIN[ ]|^IGNORED[ ]|^DEPRECATED[ ]' $f | - awk '{print $1 "\t" $2 "\t" $3}' - done -done > $loglist -grep -v '^PREFIX' $loglist | - awk '{print $2 "\t" $3}' | sort -n -k 2 | uniq -d -f 1 > $tmp -[ -s $tmp ] && { - echo "DUPLICATE LOG VALUES:" - cat $tmp - rm -f $tmp - exit 1 -} -f=../test/logtrack.list -cmp $loglist $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $loglist $f && chmod 444 $f) - -# Build DB's recovery routines. -for i in $DIR; do - for f in ../$i/*.src; do - subsystem=`basename $f .src` - awk -f gen_rec.awk \ - -v header_file=$header \ - -v print_file=$print\ - -v source_file=$source \ - -v template_file=$template < $f - - f=../dbinc_auto/${subsystem}_auto.h - cmp $header $f > /dev/null 2>&1 || - (echo "Building $f" && - rm -f $f && cp $header $f && chmod 444 $f) - f=../$i/${subsystem}_auto.c - cmp $source $f > /dev/null 2>&1 || - (echo "Building $f" && - rm -f $f && cp $source $f && chmod 444 $f) - f=../$i/${subsystem}_autop.c - cmp $print $f > /dev/null 2>&1 || - (echo "Building $f" && - rm -f $f && cp $print $f && chmod 444 $f) - f=template/rec_${subsystem} - cmp $template $f > /dev/null 2>&1 || - (echo "Building $f" && - rm -f $f && cp $template $f && chmod 444 $f) - done -done - -# Build the example application's recovery routines. -#(cd ../examples_c/ex_apprec && sh auto_rebuild) diff --git a/storage/bdb/dist/s_rpc b/storage/bdb/dist/s_rpc deleted file mode 100644 index 7da75819e06..00000000000 --- a/storage/bdb/dist/s_rpc +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/sh - -# $Id: s_rpc,v 12.0 2004/11/17 03:43:35 bostic Exp $ -# -# Build the automatically generated RPC files - -echo "Building RPC client/server files..." - -. ./RELEASE - -t=/tmp/__db_a -trap 'rm -f $t ; exit 0' 0 -trap 'rm -f $t ; exit 1' 1 2 3 13 15 - -client_file=../rpc_client/gen_client.c -ctmpl_file=./template/gen_client_ret -server_file=../rpc_server/c/gen_db_server.c -stmpl_file=./template/db_server_proc -xdr_file=../rpc_server/db_server.x - -rm -f $client_file $ctmpl_file $server_file $stmpl_file $xdr_file - -# -# Generate client/server/XDR code -# -xidsize=\ -`awk '/^#define/ { if ($2 == "DB_XIDDATASIZE") { print $3 }}' ../dbinc/db.in` - -awk -f gen_rpc.awk \ - -v client_file=$client_file \ - -v ctmpl_file=$ctmpl_file \ - -v major=$DB_VERSION_MAJOR \ - -v minor=$DB_VERSION_MINOR \ - -v server_file=$server_file \ - -v stmpl_file=$stmpl_file \ - -v xdr_file=$xdr_file \ - -v xidsize=$xidsize < ../rpc_server/rpc.src - -chmod 444 $client_file $server_file diff --git a/storage/bdb/dist/s_symlink b/storage/bdb/dist/s_symlink deleted file mode 100755 index 576fbf3b54b..00000000000 --- a/storage/bdb/dist/s_symlink +++ /dev/null @@ -1,58 +0,0 @@ -#!/bin/sh - -# $Id: s_symlink,v 12.1 2004/12/30 21:27:57 bostic Exp $ - -echo 'Creating Berkeley DB source tree symbolic links...' - -build() -{ - #echo " $1 -> $2" - (cd ../`dirname $1` && rm -f `basename $1` && ln -s $2 `basename $1`) -} - -build btree/tags ../dist/tags -build build_unix/tags ../dist/tags -build clib/tags ../dist/tags -build common/tags ../dist/tags -build crypto/tags ../dist/tags -build cxx/tags ../dist/tags -build db/tags ../dist/tags -build db185/tags ../dist/tags -build db_archive/tags ../dist/tags -build db_checkpoint/tags ../dist/tags -build db_deadlock/tags ../dist/tags -build db_dump/tags ../dist/tags -build db_dump185/tags ../dist/tags -build db_hotbackup/tags ../dist/tags -build db_load/tags ../dist/tags -build db_printlog/tags ../dist/tags -build db_recover/tags ../dist/tags -build db_stat/tags ../dist/tags -build db_upgrade/tags ../dist/tags -build db_verify/tags ../dist/tags -build dbinc/tags ../dist/tags -build dbinc_auto/tags ../dist/tags -build dbm/tags ../dist/tags -build dbreg/tags ../dist/tags -build env/tags ../dist/tags -#build examples_c/tags ../dist/tags -#build examples_cxx/tags ../dist/tags -build fileops/tags ../dist/tags -build hash/tags ../dist/tags -build hmac/tags ../dist/tags -build hsearch/tags ../dist/tags -#build libdb_java/tags ../dist/tags -build lock/tags ../dist/tags -build log/tags ../dist/tags -build mp/tags ../dist/tags -build mutex/tags ../dist/tags -build os/tags ../dist/tags -#build os_vxworks/tags ../dist/tags -build os_win32/tags ../dist/tags -build qam/tags ../dist/tags -build rep/tags ../dist/tags -#build rpc_client/tags ../dist/tags -#build rpc_server/tags ../dist/tags -build sequence/tags ../dist/tags -#build tcl/tags ../dist/tags -build txn/tags ../dist/tags -build xa/tags ../dist/tags diff --git a/storage/bdb/dist/s_tags b/storage/bdb/dist/s_tags deleted file mode 100755 index 22613775d94..00000000000 --- a/storage/bdb/dist/s_tags +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/sh - -# $Id: s_tags,v 12.1 2005/10/25 14:21:21 bostic Exp $ -# -# Build tags files. - -files=`echo ../dbinc/*.h \ - ../dbinc/*.in \ - ../btree/*.[ch] \ - ../clib/*.[ch] \ - ../common/*.[ch] \ - ../crypto/*.[ch] \ - ../crypto/mersenne/*.[ch] \ - ../crypto/rijndael/*.[ch] \ - ../db/*.[ch] \ - ../db185/*.[ch] \ - ../dbm/*.[ch] \ - ../dbreg/*.[ch] \ - ../env/*.[ch] \ - ../fileops/*.[ch] \ - ../hash/*.[ch] \ - ../hmac/*.[ch] \ - ../hsearch/*.[ch] \ - ../lock/*.[ch] \ - ../log/*.[ch] \ - ../mp/*.[ch] \ - ../mutex/*.[ch] \ - ../os/*.[ch] \ - ../qam/*.[ch] \ - ../rep/*.[ch] \ - ../rpc_client/*.[ch] \ - ../rpc_server/c/*.[ch] \ - ../sequence/*.[ch] \ - ../tcl/*.[ch] \ - ../txn/*.[ch] \ - ../xa/*.[ch] \ - ../cxx/*.cpp \ - ../libdb_java/*.[ch] | sed 's/[^ ]*stub.c//g'` - -f=tags -echo "Building $f" -rm -f $f - -# Figure out what flags this ctags accepts. -flags="" -if ctags -d ../db/db.c 2>/dev/null; then - flags="-d $flags" -fi -if ctags -t ../db/db.c 2>/dev/null; then - flags="-t $flags" -fi -if ctags -w ../db/db.c 2>/dev/null; then - flags="-w $flags" -fi - -ctags $flags $files 2>/dev/null -chmod 444 $f - -for i in test_perf test_rep test_server; do - f=../$i/tags - echo "Building $f" - (cd ../$i && ctags $flags *.[ch] 2>/dev/null) - chmod 444 $f -done diff --git a/storage/bdb/dist/s_test b/storage/bdb/dist/s_test deleted file mode 100644 index 83b3c567587..00000000000 --- a/storage/bdb/dist/s_test +++ /dev/null @@ -1,102 +0,0 @@ -#!/bin/sh - -# $Id: s_test,v 12.2 2005/06/23 15:26:39 carol Exp $ -# -# Build the Tcl test files. - -msg1="# Automatically built by dist/s_test; may require local editing." -msg2="# Automatically built by dist/s_test; may require local editing." - -t=/tmp/__t -trap 'rm -f $t; exit 0' 0 1 2 3 13 15 - -. RELEASE - -(echo "$msg1" && \ - echo "" && \ - echo "set tclsh_path @TCL_TCLSH@" && \ - echo "set tcllib .libs/libdb_tcl-@DB_VERSION_MAJOR@.@DB_VERSION_MINOR@@LIBTSO_MODSUFFIX@" && \ - echo "" && \ - echo "set rpc_server localhost" && \ - echo "set rpc_path ." && \ - echo "set rpc_testdir \$rpc_path/TESTDIR" && \ - echo "" && \ - echo "set src_root @srcdir@/.." && \ - echo "set test_path @srcdir@/../test" && \ - echo "set je_root @srcdir@/../../je" && \ - echo "" && \ - echo "global testdir" && \ - echo "set testdir ./TESTDIR" && \ - echo "" && \ - echo "global dict" && \ - echo "global util_path" && \ - echo "" && \ - echo "global is_freebsd_test" && \ - echo "global is_hp_test" && \ - echo "global is_linux_test" && \ - echo "global is_qnx_test" && \ - echo "global is_sunos_test" && \ - echo "global is_windows_test" && \ - echo "global is_windows9x_test" && \ - echo "" && \ - echo "set KILL \"@db_cv_path_kill@\"") > $t - -f=../test/include.tcl -cmp $t $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) - -(echo "$msg1" && \ - echo "" && \ - echo "set tclsh_path SET_YOUR_TCLSH_PATH" && \ - echo "set tcllib ./Debug/libdb_tcl${DB_VERSION_MAJOR}${DB_VERSION_MINOR}d.dll" && \ - echo "" && \ - echo "set src_root .." && \ - echo "set test_path ../test" && \ - echo "set je_root ../../je" && \ - echo "" && \ - echo "global testdir" && \ - echo "set testdir ./TESTDIR" && \ - echo "" && \ - echo "global dict" && \ - echo "global util_path" && \ - echo "" && \ - echo "global is_freebsd_test" && \ - echo "global is_hp_test" && \ - echo "global is_linux_test" && \ - echo "global is_qnx_test" && \ - echo "global is_sunos_test" && \ - echo "global is_windows_test" && \ - echo "global is_windows9x_test" && \ - echo "" && \ - echo "set KILL ./dbkill.exe") > $t - -f=../build_win32/include.tcl -cmp $t $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) - -# Build the test directory TESTS file. -(echo $msg2; -cat `egrep -l '^#[ ][ ]*TEST' ../test/*.tcl` | -sed -e '/^#[ ][ ]*TEST/!{' \ - -e 's/.*//' \ - -e '}' | -cat -s | -sed -e '/TEST/{' \ - -e 's/^#[ ][ ]*TEST[ ]*//' \ - -e 's/^ //' \ - -e 'H' \ - -e 'd' \ - -e '}' \ - -e 's/.*//' \ - -e x \ - -e 's/\n/__LINEBREAK__/g' | -sort | -sed -e 's/__LINEBREAK__/\ -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\ -/' \ - -e 's/__LINEBREAK__/\ - /g' | -sed -e 's/^[ ][ ]*$//') > $t - -f=../test/TESTS -cmp $t $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) diff --git a/storage/bdb/dist/s_vxworks b/storage/bdb/dist/s_vxworks deleted file mode 100644 index de2e41b55b6..00000000000 --- a/storage/bdb/dist/s_vxworks +++ /dev/null @@ -1,302 +0,0 @@ -#!/bin/sh - -# $Id: s_vxworks,v 12.6 2005/11/03 17:46:13 bostic Exp $ -# -# Build the VxWorks files. - -msgc="/* DO NOT EDIT: automatically built by dist/s_vxworks. */" - -. RELEASE - -s=/tmp/__db_a -t=/tmp/__db_b -u=/tmp/__db_c -vxfilelist=/tmp/__db_d -vxsmallfiles=/tmp/__db_e - -trap 'rm -f $s $t $u $vxfilelist $vxsmallfiles ; exit 0' 0 -trap 'rm -f $s $t $u $vxfilelist $vxsmallfiles ; exit 1' 1 2 3 13 15 - -# Build the VxWorks automatically generated files. -cat <<ENDOFSEDTEXT > $s -/extern "C" {/{ -n -n -i\\ -\\ -/* Tornado 2 does not provide a standard C pre-processor #define. */\\ -#ifndef __vxworks\\ -#define __vxworks\\ -#endif -} -/@inttypes_h_decl@/d -/@stddef_h_decl@/d -/@stdint_h_decl@/d -/@unistd_h_decl@/d -/@thread_h_decl@/d -s/@u_int8_decl@/typedef unsigned char u_int8_t;/ -/@int16_decl@/d -s/@u_int16_decl@/typedef unsigned short u_int16_t;/ -/@int32_decl@/d -s/@u_int32_decl@/typedef unsigned int u_int32_t;/ -s/@int64_decl@// -s/@u_int64_decl@/typedef unsigned long long u_int64_t;/ -/@u_char_decl@/d -/@u_short_decl@/d -/@u_int_decl@/d -/@u_long_decl@/d -/@ssize_t_decl@/d -s/@uintmax_t_decl@/typedef unsigned long uintmax_t;/ -s/@uintptr_t_decl@/typedef unsigned long uintptr_t;/ -s/@db_seq_decl@/typedef int db_seq_t;/ -/@pid_t_decl@/d -s/@db_threadid_t_decl@/typedef uintmax_t db_threadid_t;/ -s/@DB_VERSION_MAJOR@/$DB_VERSION_MAJOR/ -s/@DB_VERSION_MINOR@/$DB_VERSION_MINOR/ -s/@DB_VERSION_PATCH@/$DB_VERSION_PATCH/ -s/@DB_VERSION_STRING@/"$DB_VERSION_STRING"/ -s/@DB_VERSION_UNIQUE_NAME@// -s/@DB_CONST@// -s/@DB_PROTO1@/#undef __P/ -s/@DB_PROTO2@/#define __P(protos) protos/ -ENDOFSEDTEXT -(echo "$msgc" && - sed -f $s ../dbinc/db.in && - cat ../dbinc_auto/ext_prot.in) > $t -test `egrep '@.*@' $t` && { - egrep '@.*@' $t - echo 'Unexpanded autoconf variables found in VxWorks db.h.' - exit 1 -} -f=../build_vxworks/db.h -cmp $t $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) - -cat <<ENDOFSEDTEXT > $s -s/@INT64_FMT@/#define INT64_FMT "%lld"/ -s/@UINT64_FMT@/#define UINT64_FMT "%llu"/ -s/@PATH_SEPARATOR@/\/\\\\\\\\/ -s/@db_int_def@// -ENDOFSEDTEXT -(echo "$msgc" && sed -f $s ../dbinc/db_int.in) > $t -test `egrep '@.*@' $t` && { - egrep '@.*@' $t - echo 'Unexpanded autoconf variables found in VxWorks db_int.h.' - exit 1 -} -f=../build_vxworks/db_int.h -cmp $t $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) - -f=../build_vxworks/db_config.h -(echo "$msgc" && sed "s/__EDIT_DB_VERSION__/$DB_VERSION/" vx_config.in) > $t -cmp $t $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) - -f=../build_vxworks/db_config_small.h -(echo "$msgc" && - sed -e "s/__EDIT_DB_VERSION__/$DB_VERSION/" \ - -e "s;^#define.*HAVE_CRYPTO.*1;/* #undef HAVE_CRYPTO */;" \ - -e "s;^#define.*HAVE_HASH.*1;/* #undef HAVE_HASH */;" \ - -e "s;^#define.*HAVE_QUEUE.*1;/* #undef HAVE_QUEUE */;" \ - -e "s;^#define.*HAVE_REPLICATION.*1;/* #undef HAVE_REPLICATION */;" \ - -e "s;^#define.*HAVE_STATISTICS.*1;/* #undef HAVE_STATISTICS */;" \ - -e "s;^#define.*HAVE_VERIFY.*1;/* #undef HAVE_VERIFY */;" \ - vx_config.in) > $t -cmp $t $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) - -# Build a sed script that will change a "standard" DB utility into -# VxWorks-compatible code. -transform() -{ - # Build a sed script that will add argument parsing support and - # rename all of the functions to be private to this file. -cat <<ENDOFSEDTEXT -/^main(argc, argv)$/{ -i\\ -$1(args)\\ -\\ char *args;\\ -{\\ -\\ int argc;\\ -\\ char **argv;\\ -\\ -\\ __db_util_arg("$1", args, &argc, &argv);\\ -\\ return ($1_main(argc, argv) ? EXIT_FAILURE : EXIT_SUCCESS);\\ -}\\ -\\ -#include <stdio.h>\\ -#define ERROR_RETURN ERROR\\ -\\ -int\\ -$1_main(argc, argv) -d -} -/^ while ((ch = getopt/i\\ -\\ __db_getopt_reset = 1; -/^[ ]*extern int optind;/s/;/, __db_getopt_reset;/ -ENDOFSEDTEXT - - # Replace all function names with VxWorks safe names. - # Function names are: - # Tokens starting at the beginning of the line, immediately - # followed by an opening parenthesis. - # Replace: - # Matches preceded by a non-C-token character and immediately - # followed by an opening parenthesis. - # Matches preceded by a non-C-token character and immediately - # followed by " __P". - # Matches starting at the beginning of the line, immediately - # followed by an opening parenthesis. - for k in `sed -e 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)(.*$/\1/p' -e d $2`; do - echo "s/\([^a-zA-Z0-9_]\)\($k(\)/\1$1_\2/g" - echo "s/\([^a-zA-Z0-9_]\)\($k[ ]__P\)/\1$1_\2/g" - echo "s/^\($k(\)/$1_\1/g" - done - - # There is a special case the rules above don't catch: - # a txn_compare function used as an argument to qsort(3). - # a print_app_record function used as argument to - # dbenv->set_app_dispatch). - echo "s/, txn_compare);/, db_stat_txn_compare);/" - echo "s/, print_app_record)) /, db_printlog_print_app_record)) /" - - # We convert the ex_access sample into dbdemo for VxWorks. - echo 's/progname = "ex_access";/progname = "dbdemo";/' - - # The example programs have to load db_int.h, not db.h -- else - # they won't have the right Berkeley DB prototypes for getopt - # and friends. - echo '/#include.*db.h/c\' - echo '#include <db_config.h>\' - echo '#include <db_int.h>' -} - -PROGRAM_LIST="db_archive db_checkpoint db_deadlock db_dump db_hotbackup \ - db_load db_printlog db_recover db_stat db_upgrade db_verify ex_access" - -# Build VxWorks versions of the utilities. -for i in $PROGRAM_LIST; do - if [ $i = "ex_access" ]; then - target=dbdemo - dir=../examples_c - else - target=$i - dir=../$i - fi - - transform $target $dir/$i.c > $s - sed -f $s < $dir/$i.c > $t - - f=../build_vxworks/$target/$target.c - cmp $t $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) -done - -# Build VxWorks Tornado 2.0 project files for the utilities. -for i in $PROGRAM_LIST; do - if [ $i = "ex_access" ]; then - target=dbdemo - dir=../examples_c - else - target=$i - dir=../$i - fi - - sed "s/__DB_APPLICATION_NAME__/$target/g" < vx_2.0/wpj.in > $t - f=../build_vxworks/$target/${target}20.wpj - cmp $t $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) - sed "s/__DB_APPLICATION_NAME__/$target/g" < vx_2.2/wpj.in > $t - f=../build_vxworks/$target/${target}22.wpj - cmp $t $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) -done - -# Build the list of files VxWorks knows about. -sed -e '/^$/d' -e '/^[ #]/d' srcfiles.in | - egrep -w vx | - sed 's/[ ].*//' > $vxfilelist - -# Build the list of files VxWorks knows about. -sed -e '/^$/d' -e '/^[ #]/d' srcfiles.in | - egrep -w vxsmall | - sed 's/[ ].*//' > $vxsmallfiles - -# Build VxWorks Tornado 2.0 project files for the library itself. -for v in 0 2 ; do - # - # Build regular project files - # - (cat vx_2.${v}/BerkeleyDB.wpj - for i in `cat $vxfilelist`; do - o="<BEGIN> FILE_\$(PRJ_DIR)/../$i" - echo "${o}_dependDone" - echo "TRUE" - echo "<END>" - echo - echo "${o}_dependencies" - echo "\$(PRJ_DIR)/db_config.h \\" - echo " \$(PRJ_DIR)/db_int.h \\" - echo " \$(PRJ_DIR)/db.h" - echo "<END>" - echo - echo "${o}_objects" - echo "`basename $i .c`.o" - echo "<END>" - echo - echo "${o}_tool" - echo "C/C++ compiler" - echo "<END>" - echo - done - echo "<BEGIN> PROJECT_FILES" - sed -e '$!s/$/ \\/' \ - -e 's/^/$(PRJ_DIR)\/..\//' \ - -e '1!s/^/ /' < $vxfilelist - echo "<END>" - echo - echo "<BEGIN> userComments" - echo "BerkeleyDB" - echo "<END>") > $t - # - # Build small lib project files - # - (cat vx_2.${v}/BerkeleyDBsmall.wpj - for i in `cat $vxsmallfiles`; do - o="<BEGIN> FILE_\$(PRJ_DIR)/../$i" - echo "${o}_dependDone" - echo "TRUE" - echo "<END>" - echo - echo "${o}_dependencies" - echo "\$(PRJ_DIR)/db_config.h \\" - echo " \$(PRJ_DIR)/db_int.h \\" - echo " \$(PRJ_DIR)/db.h" - echo "<END>" - echo - echo "${o}_objects" - echo "`basename $i .c`.o" - echo "<END>" - echo - echo "${o}_tool" - echo "C/C++ compiler" - echo "<END>" - echo - done - echo "<BEGIN> PROJECT_FILES" - sed -e '$!s/$/ \\/' \ - -e 's/^/$(PRJ_DIR)\/..\//' \ - -e '1!s/^/ /' < $vxsmallfiles - echo "<END>" - echo - echo "<BEGIN> userComments" - echo "BerkeleyDB" - echo "<END>") > $u - f=../build_vxworks/BerkeleyDB2${v}.wpj - cmp $t $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) - f=../build_vxworks/BerkeleyDB2${v}small.wpj - cmp $u $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $u $f && chmod 444 $f) -done - diff --git a/storage/bdb/dist/s_win32 b/storage/bdb/dist/s_win32 deleted file mode 100644 index 490bcc888c0..00000000000 --- a/storage/bdb/dist/s_win32 +++ /dev/null @@ -1,147 +0,0 @@ -#!/bin/sh - -# $Id: s_win32,v 12.10 2005/11/03 17:46:13 bostic Exp $ -# -# Build Windows/32 include files. - -msgc="/* DO NOT EDIT: automatically built by dist/s_win32. */" -msgw="; DO NOT EDIT: automatically built by dist/s_win32." - -. RELEASE - -s=/tmp/__db_a$$ -t=/tmp/__db_b$$ -rm -f $s $t - -trap 'rm -f $s $t ; exit 1' 1 2 3 13 15 - -# Build the Win32 automatically generated files. -cat <<ENDOFSEDTEXT > $s -/@inttypes_h_decl@/d -/@stdint_h_decl@/d -s/@stddef_h_decl@/#include <stddef.h>/ -/@unistd_h_decl@/d -/@thread_h_decl@/d -s/@u_int8_decl@/typedef unsigned char u_int8_t;/ -s/@int16_decl@/typedef short int16_t;/ -s/@u_int16_decl@/typedef unsigned short u_int16_t;/ -s/@int32_decl@/typedef int int32_t;/ -s/@u_int32_decl@/typedef unsigned int u_int32_t;/ -s/@int64_decl@/typedef __int64 int64_t;/ -s/@u_int64_decl@/typedef unsigned __int64 u_int64_t;/ -s/@db_seq_decl@/typedef int64_t db_seq_t;/ -s/@pid_t_decl@/typedef int pid_t;/ -s/@db_threadid_t_decl@/typedef u_int32_t db_threadid_t;/ -/@u_char_decl@/{ - i\\ -#ifndef _WINSOCKAPI_ - s/@u_char_decl@/typedef unsigned char u_char;/ -} -s/@u_short_decl@/typedef unsigned short u_short;/ -s/@u_int_decl@/typedef unsigned int u_int;/ -/@u_long_decl@/{ - s/@u_long_decl@/typedef unsigned long u_long;/ - a\\ -#endif -} -/@ssize_t_decl@/{ - i\\ -#ifdef _WIN64\\ -typedef int64_t ssize_t;\\ -#else\\ -typedef int32_t ssize_t;\\ -#endif - d -} -s/@uintmax_t_decl@/typedef u_int64_t uintmax_t;/ -/@uintptr_t_decl@/{ - i\\ -#ifdef _WIN64\\ -typedef u_int64_t uintptr_t;\\ -#else\\ -typedef u_int32_t uintptr_t;\\ -#endif - d -} -s/@DB_VERSION_MAJOR@/$DB_VERSION_MAJOR/ -s/@DB_VERSION_MINOR@/$DB_VERSION_MINOR/ -s/@DB_VERSION_PATCH@/$DB_VERSION_PATCH/ -s/@DB_VERSION_STRING@/"$DB_VERSION_STRING"/ -s/@DB_VERSION_UNIQUE_NAME@// -s/@DB_CONST@// -s/@DB_PROTO1@/#undef __P/ -s/@DB_PROTO2@/#define __P(protos) protos/ -ENDOFSEDTEXT -(echo "$msgc" && - sed -f $s ../dbinc/db.in && - cat ../dbinc_auto/ext_prot.in) > $t -test `egrep '@.*@' $t` && { - egrep '@.*@' $t - echo 'Unexpanded autoconf variables found in Windows db.h.' - exit 1 -} -f=../build_win32/db.h -cmp $t $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) - -cat <<ENDOFSEDTEXT > $s -s/@cxx_have_stdheaders@/#define HAVE_CXX_STDHEADERS 1/ -ENDOFSEDTEXT -(echo "$msgc" && sed -f $s ../dbinc/db_cxx.in) > $t -test `egrep '@.*@' $t` && { - egrep '@.*@' $t - echo 'Unexpanded autoconf variables found in Windows db_cxx.h.' - exit 1 -} -f=../build_win32/db_cxx.h -cmp $t $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) - -cat <<ENDOFSEDTEXT > $s -s/@INT64_FMT@// -s/@UINT64_FMT@// -s/@PATH_SEPARATOR@/\\\\\\\\\/:/ -s/@db_int_def@// -ENDOFSEDTEXT -(echo "$msgc" && sed -f $s ../dbinc/db_int.in) > $t -test `egrep '@.*@' $t` && { - egrep '@.*@' $t - echo 'Unexpanded autoconf variables found in Windows db_int.h.' - exit 1 -} -f=../build_win32/db_int.h -cmp $t $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) - -f=../build_win32/db_config.h -(echo "$msgc" && sed "s/__EDIT_DB_VERSION__/$DB_VERSION/" win_config.in) > $t -cmp $t $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) - -f=../build_win32/libdb.rc -cat <<ENDOFSEDTEXT > $s -s/%MAJOR%/$DB_VERSION_MAJOR/ -s/%MINOR%/$DB_VERSION_MINOR/ -s/%PATCH%/$DB_VERSION_PATCH/ -ENDOFSEDTEXT -sed -f $s ../build_win32/libdbrc.src > $t -cmp $t $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) - -f=../build_win32/libdb.def -(echo $msgw && - echo && - echo EXPORTS; -a=1 -for i in `sed -e '/^$/d' -e '/^#/d' win_exports.in`; do - echo " $i @$a" - a=`expr $a + 1` -done) > $t -cmp $t $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $t $f && chmod 444 $f) - -f=../build_win32/win_db.h -i=win_db.in -cmp $i $f > /dev/null 2>&1 || - (echo "Building $f" && rm -f $f && cp $i $f && chmod 444 $f) - -rm -f $s $t diff --git a/storage/bdb/dist/s_win32_dsp b/storage/bdb/dist/s_win32_dsp deleted file mode 100644 index 59d3664a5f0..00000000000 --- a/storage/bdb/dist/s_win32_dsp +++ /dev/null @@ -1,138 +0,0 @@ -#!/bin/sh - -# $Id: s_win32_dsp,v 12.3 2005/10/20 01:45:53 mjc Exp $ -# -# Build Windows/32 .dsp files. - -. RELEASE - -SRCFILES=srcfiles.in - -create_dsp() -{ - projname="$1" # name of the .dsp file - match="$2" # the string used to egrep the $sources file - sources="$3" # a modified version of $SRCFILES to facilitate matches - dsptemplate="$4" # overall template file for the .dsp - extra_cppflags="$5" # extra flags to send to compiler - release_libs="$6" # libraries to link against in Release builds - debug_libs="$7" # libraries to link against in Debug builds - lib_suffix="$8" # the library name is libdb@lib_suffix@@VERSION@ - - srctemplate="$BUILDDIR/srcfile_dsp.src" # template file for the src file fragments - dspoutput=$BUILDDIR/$projname.dsp - - - postbuild=$dspoutput.postbuild - if [ ! -f $postbuild ] ; then - postbuild=/dev/null - fi - - rm -f $dspoutput.insert - for srcpath in `egrep "$match" $sources | sed -e 's/[ ].*//'` - do - # take the path name and break it up, converting / to \\. - # so many backslashes needed because of shell quoting and - # sed quoting -- we'll end up with two backslashes for every - # forward slash, but we need that when feeding that to the - # later sed command. - set - `echo $srcpath | sed -e 's;\(.*\)/;../\\1 ;' \ - -e "s;$BUILDDIR;.;" \ - -e 's;/;\\\\\\\\;g'` - srcdir="$1" - srcfile="$2" - sed -e "s/@srcdir@/$srcdir/g" \ - -e "s/@srcfile@/$srcfile/g" \ - < $srctemplate >> $dspoutput.insert - done - sed -e "/@SOURCE_FILES@/r$dspoutput.insert" \ - -e "/@SOURCE_FILES@/d" \ - -e "/@POST_BUILD@/r$postbuild" \ - -e "/@POST_BUILD@/d" \ - -e "s/@project_name@/$projname/g" \ - -e "s/@bin_rel_dest@/Release/g" \ - -e "s/@lib_rel_dest@/Release/g" \ - -e "s/@bin_debug_dest@/Debug/g" \ - -e "s/@lib_debug_dest@/Debug/g" \ - -e "s,@extra_cppflags@,$extra_cppflags,g" \ - -e "s,@release_libs@,$release_libs,g" \ - -e "s,@debug_libs@,$debug_libs,g" \ - -e "s,@lib_suffix@,$lib_suffix,g" \ - -e "s/@DB_VERSION_MAJOR@/$DB_VERSION_MAJOR/g" \ - -e "s/@DB_VERSION_MINOR@/$DB_VERSION_MINOR/g" \ - < $dsptemplate > $dspoutput.new - - # Set the file mode to 644 because the VC++ IDE needs a writeable file - # in our development environment. - cmp $dspoutput.new $dspoutput > /dev/null 2>&1 || - (echo "Building $dspoutput" && rm -f $dspoutput && - cp $dspoutput.new $dspoutput && chmod 664 $dspoutput) - rm -f $dspoutput.insert $dspoutput.new -} - -TMPA=/tmp/swin32dsp$$a -trap "rm -f $TMPA; exit 1" 1 2 3 15 - -# create a copy of the srcfiles with comments and empty lines removed. -# add a space at the end of each list of modules so that each module -# can be unambiguously matched e.g. ' dynamic ' -sed -e "s/#.*$//" \ - -e "/^[ ]*$/d" \ - -e "s/[ ][ ]*/ /" \ - -e "s/[ ]*$//" \ - -e "/[ ]/!d" \ - -e "s/$/ /" < $SRCFILES > $TMPA - -# get a list of all modules mentioned -# -MODULES="`sed -e 's/^[^ ]* //' < $TMPA \ - | tr ' ' '\012' | sort | uniq`" - -for BUILDDIR in ../build_win32 -do - for module in $MODULES - do - case "$module" in - dynamic ) - create_dsp db_dll " $module " $TMPA $BUILDDIR/dynamic_dsp.src - ;; - small ) - create_dsp db_small " $module " $TMPA $BUILDDIR/static_dsp.src \ - '/D "HAVE_SMALLBUILD"' '' '' _small - ;; - static ) - create_dsp db_static " $module " $TMPA $BUILDDIR/static_dsp.src - ;; - java ) - create_dsp db_java " $module " $TMPA $BUILDDIR/dynamic_dsp.src '' \ - 'libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib' \ - 'libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib' _java - ;; - tcl ) - create_dsp db_tcl " $module " $TMPA $BUILDDIR/dynamic_dsp.src \ - '/D "DB_TCL_SUPPORT"' \ - 'libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@.lib tcl84.lib' \ - 'libdb@DB_VERSION_MAJOR@@DB_VERSION_MINOR@d.lib tcl84g.lib' _tcl - ;; - testutil ) - create_dsp db_test " $module " $TMPA $BUILDDIR/app_dsp.src \ - '' '/out:"$(OUTDIR)/dbkill.exe"' '/out:"$(OUTDIR)/dbkill.exe"' - ;; - app=ex_repquote ) - create_dsp ex_repquote " $module " $TMPA \ - $BUILDDIR/app_dsp.src '' 'ws2_32.lib' 'ws2_32.lib' - ;; - app=* ) - appname=`echo $module | sed -e 's/^app=//'` - create_dsp $appname " $module " $TMPA \ - $BUILDDIR/app_dsp.src - ;; - vx|vxsmall ) - ;; - * ) - echo "s_win32_dsp: module name $module in $SRCFILES is unknown type" - ;; - esac - done -done - -rm -f $TMPA diff --git a/storage/bdb/dist/s_winmsi b/storage/bdb/dist/s_winmsi deleted file mode 100644 index 23b9afe4ef9..00000000000 --- a/storage/bdb/dist/s_winmsi +++ /dev/null @@ -1,134 +0,0 @@ -#!/bin/bash - -# $Id: s_winmsi,v 1.7 2005/10/26 13:29:32 dda Exp $ -# -# Note: The s_winmsi script in Berkeley DB core closely parallels the -# s_winmsi script in Berkeley DB/XML. If you change one, -# consider whether your changes apply to the other. -# As of this writing, the two s_winmsi scripts 'diff' very closely, and -# identical portions have been factored into functions in s_winmsi.fcn. -# -# Usage: s_winmsi [ options ] -# -# See the Usage() function in s_winmsi.fcn for a full list of options. -# By default, this script expects a db-X.Y.Z.NC.zip file -# to be in this directory, and uses it to build all binaries -# needed for an Windows install, and finally builds the an -# output db-X.Y.Z.NC.msi file that can be installed on -# Windows XP and 2000. -# -# The major other inputs to this script are these files: -# -# features.in list of choosable features (like Java,PHP,...) -# files.in what files are in each feature and where they belong -# links.in a list of URLs that end up as part of the Start Menu -# environment.in a list of environment vars that must be set -# -# This script does a number of operations, using the directory -# './winmsi/stage' as a staging area: -# -# extracts the contents of the input ZIP file and uses those -# files (minus docs/...) to build a Sources directory for -# the Sources features. -# -# builds Berkeley DB using Visual Studio tools using a .BAT -# script derived from winbuild.in . -# -# builds Perl and other APIs . -# -# uses {features,files,links,environment}.in to build some include -# files in WiX XML format. These files are named -# *.wixinc (e.g. directory.wixinc) -# -# run m4 on dbcorewix.in to create dbcore.wxs . dbcorewix.in -# uses m4 macros to allow reasonable refactoring of repeated -# UI code. Also, m4 is used to include the files created in -# the previous step. -# -# Use the WiX compiler/linker on the .wxs files to create the .msi file. -# -################################################################ - -# Define all needed shell functions -. ./winmsi/s_winmsi.fcn - -ERRORLOG="$0".log -SetupErrorLog - -# Do this before parsing options, we need the version number -. ./RELEASE -dbver=db-$DB_VERSION.NC - -# Set variables used by functions to customize this installer -PRODUCT_NAME="Berkeley DB" -PRODUCT_VERSION="$DB_VERSION" -PRODUCT_STAGE=`pwd`/winmsi/stage -PRODUCT_LICENSEDIR="${PRODUCT_STAGE}/$dbver" -PRODUCT_SUB_BLDDIR="${PRODUCT_STAGE}/$dbver" -PRODUCT_BLDDIR="${PRODUCT_STAGE}/$dbver" -PRODUCT_SRCDIR="${PRODUCT_STAGE}/$dbver" -PRODUCT_DBBUILDDIR="${PRODUCT_STAGE}/$dbver/build_unix" -PRODUCT_SHARED_WINMSIDIR=`pwd`/winmsi -PRODUCT_IMAGEDIR=$PRODUCT_SHARED_WINMSIDIR/images -PRODUCT_ZIP_FILEFMT="db-X.Y.Z.NC.zip" -PRODUCT_MSI_FILEFMT="db-X.Y.Z.NC.msi" - -PRODUCT_MAJOR=`echo "$PRODUCT_VERSION" | \ - sed -e 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\1/'` -PRODUCT_MINOR=`echo "$PRODUCT_VERSION" | \ - sed -e 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\2/'` -PRODUCT_PATCH=`echo "$PRODUCT_VERSION" | \ - sed -e 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\3/'` -PRODUCT_MAJMIN="${PRODUCT_MAJOR}${PRODUCT_MINOR}" - -# Gather command line options, and use reasonable defaults -SetupOptions \ - -input "$dbver.zip" \ - -output "$dbver.msi" \ - "$@" - -if [ "$OPT_USEBUILD" != '' ]; then - PRODUCT_BLDDIR="${OPT_USEBUILD}" - PRODUCT_SUB_BLDDIR="${OPT_USEBUILD}" -fi - -Progress "s_winmsi starting, errors to $ERRORLOG" - -# Fail fast for certain missing files - -RequireCygwin -RequireJava -RequireTcl -RequireWix -RequirePerl - -CreateStage -cd ${PRODUCT_STAGE} - - -CreateSources ${PRODUCT_STAGE}/Sources - -# The docs are put into a separate feature set -mv ${PRODUCT_STAGE}/Sources/docs ${PRODUCT_STAGE}/ - -# Build everything unless we were told to use a preexisting build -if [ "$OPT_USEBUILD" = '' ]; then - CreateWindowsBuild - CreateWindowsSystem - CreateInclude \ - ${PRODUCT_SUB_BLDDIR}/installed_include \ - ${PRODUCT_SUB_BLDDIR}/dbinc/* \ - ${PRODUCT_SUB_BLDDIR}/dbinc_auto/* \ - ${PRODUCT_SUB_BLDDIR}/build_win32/*.h - CreateDbPerl -fi - -if ! "$OPT_SKIPGEN" ; then - CreateLicenseRtf ../../../LICENSE license.rtf - CreateWixIncludeFiles -fi - -CreateMsi ../dbcorewix.in dbcore.wxs "$OPT_OUTFILE" - -Progress "s_winmsi finished, $OPT_OUTFILE created." -exit 0 - diff --git a/storage/bdb/dist/srcfiles.in b/storage/bdb/dist/srcfiles.in deleted file mode 100644 index 530c216934b..00000000000 --- a/storage/bdb/dist/srcfiles.in +++ /dev/null @@ -1,405 +0,0 @@ -# $Id: srcfiles.in,v 12.24 2005/10/27 14:45:25 bostic Exp $ -# -# This is an input file for the s_win32_dsp and s_vxworks scripts. It lists -# the source files in the Berkeley DB tree and notes which are used to build -# the Win/32 and VxWorks libraries. -# -# Please keep this list sorted alphabetically! -# -# Each non-blank, non-comment line is of the form -# filename module [ module ...] -# -# The possible modules, including the name of the project (.dsp) file: -# -# app=NAME Linked into application NAME.exe (db_NAME.dsp) -# dynamic File is in the Windows DLL (db_dll.dsp) -# small File is in the small Windows library (db_small.dsp) -# static File is in the Windows static library (db_static.dsp) -# java File is in the Windows Java DLL (db_java.dsp) -# tcl File is in the Windows tcl DLL (db_tcl.dsp) -# testutil File is used for Windows testing (db_test.dsp) -# vx File is in the VxWorks library. -# vxsmall File is in the small VxWorks library. - -btree/bt_compact.c dynamic small static vx vxsmall -btree/bt_compare.c dynamic small static vx vxsmall -btree/bt_conv.c dynamic small static vx vxsmall -btree/bt_curadj.c dynamic small static vx vxsmall -btree/bt_cursor.c dynamic small static vx vxsmall -btree/bt_delete.c dynamic small static vx vxsmall -btree/bt_method.c dynamic small static vx vxsmall -btree/bt_open.c dynamic small static vx vxsmall -btree/bt_put.c dynamic small static vx vxsmall -btree/bt_rec.c dynamic small static vx vxsmall -btree/bt_reclaim.c dynamic small static vx vxsmall -btree/bt_recno.c dynamic small static vx vxsmall -btree/bt_rsearch.c dynamic small static vx vxsmall -btree/bt_search.c dynamic small static vx vxsmall -btree/bt_split.c dynamic small static vx vxsmall -btree/bt_stat.c dynamic small static vx vxsmall -btree/bt_upgrade.c dynamic small static vx vxsmall -btree/bt_verify.c dynamic static vx -btree/btree_auto.c dynamic small static vx vxsmall -btree/btree_autop.c app=db_printlog -build_vxworks/db_archive/db_archive.c -build_vxworks/db_checkpoint/db_checkpoint.c -build_vxworks/db_deadlock/db_deadlock.c -build_vxworks/db_dump/db_dump.c -build_vxworks/db_hotbackup/db_hotbackup.c -build_vxworks/db_load/db_load.c -build_vxworks/db_printlog/db_printlog.c -build_vxworks/db_recover/db_recover.c -build_vxworks/db_stat/db_stat.c -build_vxworks/db_upgrade/db_upgrade.c -build_vxworks/db_verify/db_verify.c -build_vxworks/dbdemo/dbdemo.c -build_win32/dbkill.cpp testutil -build_win32/libdb.def dynamic -build_win32/libdb.rc dynamic -build_win32/libdb_tcl.def tcl -clib/getcwd.c -clib/getopt.c vx vxsmall -clib/memcmp.c -clib/memmove.c -clib/raise.c -clib/snprintf.c vx vxsmall -clib/strcasecmp.c dynamic small static vx vxsmall -clib/strdup.c vx vxsmall -clib/strerror.c -clib/strtol.c -clib/strtoul.c -common/crypto_stub.c small vxsmall -common/db_byteorder.c dynamic small static vx vxsmall -common/db_clock.c dynamic static vx -common/db_err.c dynamic small static vx vxsmall -common/db_getlong.c dynamic small static vx vxsmall -common/db_idspace.c dynamic small static vx vxsmall -common/db_log2.c dynamic small static vx vxsmall -common/util_arg.c vx vxsmall -common/util_cache.c dynamic small static vx vxsmall -common/util_log.c dynamic small static vx vxsmall -common/util_sig.c dynamic small static vx vxsmall -crypto/aes_method.c dynamic static vx -crypto/crypto.c dynamic static vx -crypto/mersenne/mt19937db.c dynamic static vx -crypto/rijndael/rijndael-alg-fst.c dynamic static vx -crypto/rijndael/rijndael-api-fst.c dynamic static vx -cxx/cxx_db.cpp dynamic small static -cxx/cxx_dbc.cpp dynamic small static -cxx/cxx_dbt.cpp dynamic small static -cxx/cxx_env.cpp dynamic small static -cxx/cxx_except.cpp dynamic small static -cxx/cxx_lock.cpp dynamic small static -cxx/cxx_logc.cpp dynamic small static -cxx/cxx_mpool.cpp dynamic small static -cxx/cxx_multi.cpp dynamic small static -cxx/cxx_seq.cpp dynamic small static -cxx/cxx_txn.cpp dynamic small static -db/crdel_auto.c dynamic small static vx vxsmall -db/crdel_autop.c app=db_printlog -db/crdel_rec.c dynamic small static vx vxsmall -db/db.c dynamic small static vx vxsmall -db/db_am.c dynamic small static vx vxsmall -db/db_auto.c dynamic small static vx vxsmall -db/db_autop.c app=db_printlog -db/db_cam.c dynamic small static vx vxsmall -db/db_conv.c dynamic small static vx vxsmall -db/db_dispatch.c dynamic small static vx vxsmall -db/db_dup.c dynamic small static vx vxsmall -db/db_iface.c dynamic small static vx vxsmall -db/db_join.c dynamic small static vx vxsmall -db/db_meta.c dynamic small static vx vxsmall -db/db_method.c dynamic small static vx vxsmall -db/db_open.c dynamic small static vx vxsmall -db/db_overflow.c dynamic small static vx vxsmall -db/db_ovfl_vrfy.c dynamic static vx -db/db_pr.c dynamic small static vx vxsmall -db/db_rec.c dynamic small static vx vxsmall -db/db_reclaim.c dynamic small static vx vxsmall -db/db_remove.c dynamic small static vx vxsmall -db/db_rename.c dynamic small static vx vxsmall -db/db_ret.c dynamic small static vx vxsmall -db/db_setid.c dynamic small static vx vxsmall -db/db_setlsn.c dynamic small static vx vxsmall -db/db_stati.c dynamic small static vx vxsmall -db/db_truncate.c dynamic small static vx vxsmall -db/db_upg.c dynamic small static vx vxsmall -db/db_upg_opd.c dynamic small static vx vxsmall -db/db_vrfy.c dynamic static vx -db/db_vrfy_stub.c small vxsmall -db/db_vrfyutil.c dynamic static vx -db185/db185.c -db_archive/db_archive.c app=db_archive -db_checkpoint/db_checkpoint.c app=db_checkpoint -db_deadlock/db_deadlock.c app=db_deadlock -db_dump/db_dump.c app=db_dump -db_dump185/db_dump185.c -db_hotbackup/db_hotbackup.c app=db_hotbackup -db_load/db_load.c app=db_load -db_printlog/db_printlog.c app=db_printlog -db_recover/db_recover.c app=db_recover -db_server_clnt.c -db_server_svc.c -db_server_xdr.c -db_stat/db_stat.c app=db_stat -db_upgrade/db_upgrade.c app=db_upgrade -db_verify/db_verify.c app=db_verify -dbm/dbm.c dynamic static -dbreg/dbreg.c dynamic small static vx vxsmall -dbreg/dbreg_auto.c dynamic small static vx vxsmall -dbreg/dbreg_autop.c app=db_printlog -dbreg/dbreg_rec.c dynamic small static vx vxsmall -dbreg/dbreg_stat.c dynamic small static vx vxsmall -dbreg/dbreg_util.c dynamic small static vx vxsmall -env/db_salloc.c dynamic small static vx vxsmall -env/db_shash.c dynamic small static vx vxsmall -env/env_failchk.c dynamic small static vx vxsmall -env/env_file.c dynamic small static vx vxsmall -env/env_method.c dynamic small static vx vxsmall -env/env_open.c dynamic small static vx vxsmall -env/env_recover.c dynamic small static vx vxsmall -env/env_region.c dynamic small static vx vxsmall -env/env_register.c dynamic small static vx vxsmall -env/env_stat.c dynamic small static vx vxsmall -examples_c/bench_001.c -examples_c/csv/DbRecord.c app=ex_csvload app=ex_csvquery -examples_c/csv/code.c app=ex_csvcode -examples_c/csv/csv_local.c app=ex_csvload app=ex_csvquery -examples_c/csv/db.c app=ex_csvload app=ex_csvquery -examples_c/csv/load.c app=ex_csvload -examples_c/csv/load_main.c app=ex_csvload -examples_c/csv/query.c app=ex_csvquery -examples_c/csv/query_main.c app=ex_csvquery -examples_c/csv/util.c app=ex_csvload app=ex_csvquery -examples_c/ex_access.c app=ex_access -examples_c/ex_apprec/ex_apprec.c -examples_c/ex_apprec/ex_apprec_auto.c -examples_c/ex_apprec/ex_apprec_autop.c -examples_c/ex_apprec/ex_apprec_rec.c -examples_c/ex_btrec.c app=ex_btrec -examples_c/ex_dbclient.c -examples_c/ex_env.c app=ex_env -examples_c/ex_lock.c app=ex_lock -examples_c/ex_mpool.c app=ex_mpool -examples_c/ex_repquote/ex_rq_client.c app=ex_repquote -examples_c/ex_repquote/ex_rq_main.c app=ex_repquote -examples_c/ex_repquote/ex_rq_master.c app=ex_repquote -examples_c/ex_repquote/ex_rq_net.c app=ex_repquote -examples_c/ex_repquote/ex_rq_util.c app=ex_repquote -examples_c/ex_sequence.c app=ex_sequence -examples_c/ex_thread.c -examples_c/ex_tpcb.c app=ex_tpcb -examples_c/getting_started/example_database_load.c app=example_database_load -examples_c/getting_started/example_database_read.c app=example_database_read -examples_c/getting_started/gettingstarted_common.c app=example_database_load app=example_database_read -examples_c/txn_guide/txn_guide.c app=ex_txnguide -examples_c/txn_guide/txn_guide_inmemory.c app=ex_txnguide_inmem -examples_cxx/AccessExample.cpp app=excxx_access -examples_cxx/BtRecExample.cpp app=excxx_btrec -examples_cxx/EnvExample.cpp app=excxx_env -examples_cxx/LockExample.cpp app=excxx_lock -examples_cxx/MpoolExample.cpp app=excxx_mpool -examples_cxx/SequenceExample.cpp app=excxx_sequence -examples_cxx/TpcbExample.cpp app=excxx_tpcb -examples_cxx/getting_started/MyDb.cpp app=excxx_example_database_load app=excxx_example_database_read -examples_cxx/getting_started/excxx_example_database_load.cpp app=excxx_example_database_load -examples_cxx/getting_started/excxx_example_database_read.cpp app=excxx_example_database_read -examples_cxx/txn_guide/TxnGuide.cpp app=excxx_txnguide -examples_cxx/txn_guide/TxnGuideInMemory.cpp app=excxx_txnguide_inmem -fileops/fileops_auto.c dynamic small static vx vxsmall -fileops/fileops_autop.c app=db_printlog -fileops/fop_basic.c dynamic small static vx vxsmall -fileops/fop_rec.c dynamic small static vx vxsmall -fileops/fop_util.c dynamic small static vx vxsmall -gen_db_server.c -hash/hash.c dynamic static vx -hash/hash_auto.c dynamic static vx -hash/hash_autop.c app=db_printlog -hash/hash_conv.c dynamic static vx -hash/hash_dup.c dynamic static vx -hash/hash_func.c dynamic small static vx vxsmall -hash/hash_meta.c dynamic static vx -hash/hash_method.c dynamic static vx -hash/hash_open.c dynamic static vx -hash/hash_page.c dynamic static vx -hash/hash_rec.c dynamic static vx -hash/hash_reclaim.c dynamic static vx -hash/hash_stat.c dynamic static vx -hash/hash_stub.c small vxsmall -hash/hash_upgrade.c dynamic static vx -hash/hash_verify.c dynamic static vx -hmac/hmac.c dynamic small static vx vxsmall -hmac/sha1.c dynamic small static vx vxsmall -hsearch/hsearch.c dynamic static vx -libdb_java/db_java_wrap.c java -lock/lock.c dynamic small static vx vxsmall -lock/lock_deadlock.c dynamic small static vx vxsmall -lock/lock_failchk.c dynamic small static vx vxsmall -lock/lock_id.c dynamic small static vx vxsmall -lock/lock_list.c dynamic small static vx vxsmall -lock/lock_method.c dynamic small static vx vxsmall -lock/lock_region.c dynamic small static vx vxsmall -lock/lock_stat.c dynamic small static vx vxsmall -lock/lock_timer.c dynamic small static vx vxsmall -lock/lock_util.c dynamic small static vx vxsmall -log/log.c dynamic small static vx vxsmall -log/log_archive.c dynamic small static vx vxsmall -log/log_compare.c dynamic small static vx vxsmall -log/log_debug.c dynamic small static vx vxsmall -log/log_get.c dynamic small static vx vxsmall -log/log_method.c dynamic small static vx vxsmall -log/log_put.c dynamic small static vx vxsmall -log/log_stat.c dynamic small static vx vxsmall -mp/mp_alloc.c dynamic small static vx vxsmall -mp/mp_bh.c dynamic small static vx vxsmall -mp/mp_fget.c dynamic small static vx vxsmall -mp/mp_fmethod.c dynamic small static vx vxsmall -mp/mp_fopen.c dynamic small static vx vxsmall -mp/mp_fput.c dynamic small static vx vxsmall -mp/mp_fset.c dynamic small static vx vxsmall -mp/mp_method.c dynamic small static vx vxsmall -mp/mp_region.c dynamic small static vx vxsmall -mp/mp_register.c dynamic small static vx vxsmall -mp/mp_stat.c dynamic small static vx vxsmall -mp/mp_sync.c dynamic small static vx vxsmall -mp/mp_trickle.c dynamic small static vx vxsmall -mutex/mut_alloc.c dynamic small static vx vxsmall -mutex/mut_fcntl.c -mutex/mut_method.c dynamic small static vx vxsmall -mutex/mut_pthread.c -mutex/mut_region.c dynamic small static vx vxsmall -mutex/mut_stat.c dynamic small static vx vxsmall -mutex/mut_tas.c vx vxsmall -mutex/mut_win32.c dynamic small static -mutex/tm.c app=tm -os/os_abs.c -os/os_alloc.c dynamic small static vx vxsmall -os/os_clock.c vx vxsmall -os/os_config.c -os/os_dir.c vx vxsmall -os/os_errno.c vx vxsmall -os/os_fid.c vx vxsmall -os/os_flock.c vx vxsmall -os/os_fsync.c vx vxsmall -os/os_handle.c vx vxsmall -os/os_id.c dynamic small static vx vxsmall -os/os_map.c -os/os_method.c dynamic small static vx vxsmall -os/os_mkdir.c dynamic small static vx vxsmall -os/os_oflags.c dynamic small static vx vxsmall -os/os_open.c vx vxsmall -os/os_region.c dynamic small static vx vxsmall -os/os_rename.c vx vxsmall -os/os_root.c dynamic small static vx vxsmall -os/os_rpath.c dynamic small static vx vxsmall -os/os_rw.c vx vxsmall -os/os_seek.c vx vxsmall -os/os_sleep.c vx vxsmall -os/os_spin.c vx vxsmall -os/os_stat.c vx vxsmall -os/os_tmpdir.c dynamic small static vx vxsmall -os/os_truncate.c vx vxsmall -os/os_unlink.c vx vxsmall -os_vxworks/os_vx_abs.c vx vxsmall -os_vxworks/os_vx_config.c vx vxsmall -os_vxworks/os_vx_map.c vx vxsmall -os_win32/os_abs.c dynamic small static -os_win32/os_clock.c dynamic small static -os_win32/os_config.c dynamic small static -os_win32/os_dir.c dynamic small static -os_win32/os_errno.c dynamic small static -os_win32/os_fid.c dynamic small static -os_win32/os_flock.c dynamic small static -os_win32/os_fsync.c dynamic small static -os_win32/os_handle.c dynamic small static -os_win32/os_map.c dynamic small static -os_win32/os_open.c dynamic small static -os_win32/os_rename.c dynamic small static -os_win32/os_rw.c dynamic small static -os_win32/os_seek.c dynamic small static -os_win32/os_sleep.c dynamic small static -os_win32/os_spin.c dynamic small static -os_win32/os_stat.c dynamic small static -os_win32/os_truncate.c dynamic small static -os_win32/os_unlink.c dynamic small static -qam/qam.c dynamic static vx -qam/qam_auto.c dynamic static vx -qam/qam_autop.c app=db_printlog -qam/qam_conv.c dynamic static vx -qam/qam_files.c dynamic static vx -qam/qam_method.c dynamic static vx -qam/qam_open.c dynamic static vx -qam/qam_rec.c dynamic static vx -qam/qam_stat.c dynamic static vx -qam/qam_stub.c small vxsmall -qam/qam_upgrade.c dynamic static vx -qam/qam_verify.c dynamic static vx -rep/rep_auto.c dynamic static vx -rep/rep_autop.c app=db_printlog -rep/rep_backup.c dynamic static vx -rep/rep_elect.c dynamic static vx -rep/rep_log.c dynamic static vx -rep/rep_method.c dynamic static vx -rep/rep_record.c dynamic static vx -rep/rep_region.c dynamic static vx -rep/rep_stat.c dynamic static vx -rep/rep_stub.c small vxsmall -rep/rep_util.c dynamic static vx -rep/rep_verify.c dynamic static vx -rpc_client/client.c -rpc_client/gen_client.c -rpc_client/gen_client_ret.c -rpc_server/c/db_server_proc.c -rpc_server/c/db_server_util.c -rpc_server/cxx/db_server_cxxproc.cpp -rpc_server/cxx/db_server_cxxutil.cpp -sequence/seq_stat.c dynamic small static -sequence/sequence.c dynamic small static -tcl/tcl_compat.c tcl -tcl/tcl_db.c tcl -tcl/tcl_db_pkg.c tcl -tcl/tcl_dbcursor.c tcl -tcl/tcl_env.c tcl -tcl/tcl_internal.c tcl -tcl/tcl_lock.c tcl -tcl/tcl_log.c tcl -tcl/tcl_mp.c tcl -tcl/tcl_rep.c tcl -tcl/tcl_seq.c tcl -tcl/tcl_txn.c tcl -tcl/tcl_util.c tcl -test_perf/db_perf.c app=db_perf -test_perf/perf_checkpoint.c app=db_perf -test_perf/perf_config.c app=db_perf -test_perf/perf_dbs.c app=db_perf -test_perf/perf_dead.c app=db_perf -test_perf/perf_debug.c app=db_perf -test_perf/perf_file.c app=db_perf -test_perf/perf_key.c app=db_perf -test_perf/perf_log.c app=db_perf -test_perf/perf_misc.c app=db_perf -test_perf/perf_op.c app=db_perf -test_perf/perf_parse.c app=db_perf -test_perf/perf_rand.c app=db_perf -test_perf/perf_spawn.c app=db_perf -test_perf/perf_stat.c app=db_perf -test_perf/perf_sync.c app=db_perf -test_perf/perf_thread.c app=db_perf -test_perf/perf_trickle.c app=db_perf -test_perf/perf_txn.c app=db_perf -test_perf/perf_util.c app=db_perf -test_perf/perf_vx.c -txn/txn.c dynamic small static vx vxsmall -txn/txn_auto.c dynamic small static vx vxsmall -txn/txn_autop.c app=db_printlog -txn/txn_chkpt.c dynamic small static vx vxsmall -txn/txn_failchk.c dynamic small static vx vxsmall -txn/txn_method.c dynamic small static vx vxsmall -txn/txn_rec.c dynamic small static vx vxsmall -txn/txn_recover.c dynamic small static vx vxsmall -txn/txn_region.c dynamic small static vx vxsmall -txn/txn_stat.c dynamic small static vx vxsmall -txn/txn_util.c dynamic small static vx vxsmall -xa/xa.c dynamic small static vx vxsmall -xa/xa_db.c dynamic small static vx vxsmall -xa/xa_map.c dynamic small static vx vxsmall diff --git a/storage/bdb/dist/template/rec_ctemp b/storage/bdb/dist/template/rec_ctemp deleted file mode 100644 index 2951189c5bd..00000000000 --- a/storage/bdb/dist/template/rec_ctemp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * PREF_FUNC_recover -- - * Recovery function for FUNC. - * - * PUBLIC: int PREF_FUNC_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -PREF_FUNC_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - PREF_FUNC_args *argp; - DB *file_dbp; - DBC *dbc; - DB_MPOOLFILE *mpf; - PAGE *pagep; - int cmp_n, cmp_p, modified, ret; - - REC_PRINT(PREF_FUNC_print); - REC_INTRO(PREF_FUNC_read, 1); - - if ((ret = mpf->get(mpf, &argp->pgno, 0, &pagep)) != 0) - if (DB_REDO(op)) { - if ((ret = mpf->get(mpf, - &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) - goto out; - } else { - *lsnp = argp->prev_lsn; - ret = 0; - goto out; - } - - modified = 0; - cmp_n = log_compare(lsnp, &LSN(pagep)); - - /* - * Use this when there is something like "pagelsn" in the argp - * structure. Sometimes, you might need to compare meta-data - * lsn's instead. - * - * cmp_p = log_compare(&LSN(pagep), argp->pagelsn); - */ - if (cmp_p == 0 && DB_REDO(op)) { - /* Need to redo update described. */ - modified = 1; - } else if (cmp_n == 0 && !DB_REDO(op)) { - /* Need to undo update described. */ - modified = 1; - } - if (ret = mpf->put(mpf, pagep, modified ? DB_MPOOL_DIRTY : 0)) - goto out; - - *lsnp = argp->prev_lsn; - ret = 0; - -out: REC_CLOSE; -} - diff --git a/storage/bdb/dist/template/rec_rep b/storage/bdb/dist/template/rec_rep deleted file mode 100644 index 872812cd069..00000000000 --- a/storage/bdb/dist/template/rec_rep +++ /dev/null @@ -1,13 +0,0 @@ -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/__rep.h" -#include "dbinc/log.h" - diff --git a/storage/bdb/dist/vx_2.0/BerkeleyDB.wpj b/storage/bdb/dist/vx_2.0/BerkeleyDB.wpj deleted file mode 100644 index 692d1b40bb6..00000000000 --- a/storage/bdb/dist/vx_2.0/BerkeleyDB.wpj +++ /dev/null @@ -1,251 +0,0 @@ -Document file - DO NOT EDIT - -<BEGIN> BUILD_PENTIUM_debug_BUILDRULE -BerkeleyDB20.out -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_AR -ar386 -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_ARCHIVE -$(PRJ_DIR)/PENTIUMgnu/BerkeleyDB20_sim.a -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_AS -cc386 -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_CC -cc386 -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_CFLAGS --g \ - -mpentium \ - -ansi \ - -nostdinc \ - -DRW_MULTI_THREAD \ - -D_REENTRANT \ - -fvolatile \ - -nostdlib \ - -fno-builtin \ - -fno-defer-pop \ - -I. \ - -I$(WIND_BASE)/target/h \ - -DCPU=PENTIUM \ - -O0 \ - -I$(PRJ_DIR) \ - -I$(PRJ_DIR)/.. \ - -DDIAGNOSTIC \ - -DDEBUG -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_CFLAGS_AS --g \ - -mpentium \ - -ansi \ - -nostdinc \ - -fvolatile \ - -nostdlib \ - -fno-builtin \ - -fno-defer-pop \ - -P \ - -x \ - assembler-with-cpp \ - -I. \ - -I$(WIND_BASE)/target/h \ - -DCPU=PENTIUM -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_CPP -cc386 -E -P -xc -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_LD -ld386 -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_LDFLAGS --X -N -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_LD_PARTIAL_FLAGS --X -r -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_NM -nm386 -g -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_OPTION_DEFINE_MACRO --D -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_OPTION_INCLUDE_DIR --I -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_POST_BUILD_RULE - -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_PRJ_LIBS - -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_SIZE -size386 -<END> - -<BEGIN> BUILD_PENTIUM_debug_RO_DEPEND_PATH -{$(WIND_BASE)/target/h/} \ - {$(WIND_BASE)/target/src/} \ - {$(WIND_BASE)/target/config/} -<END> - -<BEGIN> BUILD_PENTIUM_debug_TC -::tc_PENTIUMgnu -<END> - -<BEGIN> BUILD_PENTIUM_release_BUILDRULE -BerkeleyDB20.out -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_AR -ar386 -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_ARCHIVE -$(PRJ_DIR)/PENTIUMgnu/BerkeleyDB20_sim.a -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_AS -cc386 -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_CC -cc386 -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_CFLAGS --mpentium \ - -ansi \ - -nostdinc \ - -DRW_MULTI_THREAD \ - -D_REENTRANT \ - -fvolatile \ - -nostdlib \ - -fno-builtin \ - -fno-defer-pop \ - -I. \ - -I$(WIND_BASE)/target/h \ - -DCPU=PENTIUM \ - -O2 \ - -I$(PRJ_DIR) \ - -I$(PRJ_DIR)/.. -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_CFLAGS_AS --g \ - -mpentium \ - -ansi \ - -nostdinc \ - -fvolatile \ - -nostdlib \ - -fno-builtin \ - -fno-defer-pop \ - -P \ - -x \ - assembler-with-cpp \ - -I. \ - -I$(WIND_BASE)/target/h \ - -DCPU=PENTIUM -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_CPP -cc386 -E -P -xc -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_LD -ld386 -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_LDDEPS - -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_LDFLAGS --X -N -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_LD_PARTIAL_FLAGS --X -r -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_NM -nm386 -g -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_OPTION_DEFINE_MACRO --D -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_OPTION_INCLUDE_DIR --I -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_POST_BUILD_RULE - -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_PRJ_LIBS - -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_SIZE -size386 -<END> - -<BEGIN> BUILD_PENTIUM_release_RO_DEPEND_PATH -{$(WIND_BASE)/target/h/} \ - {$(WIND_BASE)/target/src/} \ - {$(WIND_BASE)/target/config/} -<END> - -<BEGIN> BUILD_PENTIUM_release_TC -::tc_PENTIUMgnu -<END> - -<BEGIN> BUILD_RULE_BerkeleyDB20.out - -<END> - -<BEGIN> BUILD_RULE_BerkeleyDB20_sim.out - -<END> - -<BEGIN> BUILD_RULE_archive - -<END> - -<BEGIN> BUILD_RULE_objects - -<END> - -<BEGIN> BUILD__CURRENT -PENTIUM_debug -<END> - -<BEGIN> BUILD__LIST -PENTIUM_release PENTIUM_debug -<END> - -<BEGIN> CORE_INFO_TYPE -::prj_vxApp -<END> - -<BEGIN> CORE_INFO_VERSION -2.0 -<END> - diff --git a/storage/bdb/dist/vx_2.0/BerkeleyDBsmall.wpj b/storage/bdb/dist/vx_2.0/BerkeleyDBsmall.wpj deleted file mode 100644 index 3c9fd350fa1..00000000000 --- a/storage/bdb/dist/vx_2.0/BerkeleyDBsmall.wpj +++ /dev/null @@ -1,251 +0,0 @@ -Document file - DO NOT EDIT - -<BEGIN> BUILD_PENTIUM_debug_BUILDRULE -BerkeleyDB20small.out -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_AR -ar386 -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_ARCHIVE -$(PRJ_DIR)/PENTIUMgnu/BerkeleyDB20small_sim.a -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_AS -cc386 -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_CC -cc386 -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_CFLAGS --g \ - -mpentium \ - -ansi \ - -nostdinc \ - -DRW_MULTI_THREAD \ - -D_REENTRANT \ - -fvolatile \ - -nostdlib \ - -fno-builtin \ - -fno-defer-pop \ - -I. \ - -I$(WIND_BASE)/target/h \ - -DCPU=PENTIUM \ - -O0 \ - -I$(PRJ_DIR) \ - -I$(PRJ_DIR)/.. \ - -DDIAGNOSTIC \ - -DDEBUG -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_CFLAGS_AS --g \ - -mpentium \ - -ansi \ - -nostdinc \ - -fvolatile \ - -nostdlib \ - -fno-builtin \ - -fno-defer-pop \ - -P \ - -x \ - assembler-with-cpp \ - -I. \ - -I$(WIND_BASE)/target/h \ - -DCPU=PENTIUM -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_CPP -cc386 -E -P -xc -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_LD -ld386 -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_LDFLAGS --X -N -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_LD_PARTIAL_FLAGS --X -r -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_NM -nm386 -g -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_OPTION_DEFINE_MACRO --D -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_OPTION_INCLUDE_DIR --I -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_POST_BUILD_RULE - -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_PRJ_LIBS - -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_SIZE -size386 -<END> - -<BEGIN> BUILD_PENTIUM_debug_RO_DEPEND_PATH -{$(WIND_BASE)/target/h/} \ - {$(WIND_BASE)/target/src/} \ - {$(WIND_BASE)/target/config/} -<END> - -<BEGIN> BUILD_PENTIUM_debug_TC -::tc_PENTIUMgnu -<END> - -<BEGIN> BUILD_PENTIUM_release_BUILDRULE -BerkeleyDB20small.out -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_AR -ar386 -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_ARCHIVE -$(PRJ_DIR)/PENTIUMgnu/BerkeleyDB20small_sim.a -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_AS -cc386 -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_CC -cc386 -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_CFLAGS --mpentium \ - -ansi \ - -nostdinc \ - -DRW_MULTI_THREAD \ - -D_REENTRANT \ - -fvolatile \ - -nostdlib \ - -fno-builtin \ - -fno-defer-pop \ - -I. \ - -I$(WIND_BASE)/target/h \ - -DCPU=PENTIUM \ - -O2 \ - -I$(PRJ_DIR) \ - -I$(PRJ_DIR)/.. -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_CFLAGS_AS --g \ - -mpentium \ - -ansi \ - -nostdinc \ - -fvolatile \ - -nostdlib \ - -fno-builtin \ - -fno-defer-pop \ - -P \ - -x \ - assembler-with-cpp \ - -I. \ - -I$(WIND_BASE)/target/h \ - -DCPU=PENTIUM -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_CPP -cc386 -E -P -xc -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_LD -ld386 -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_LDDEPS - -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_LDFLAGS --X -N -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_LD_PARTIAL_FLAGS --X -r -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_NM -nm386 -g -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_OPTION_DEFINE_MACRO --D -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_OPTION_INCLUDE_DIR --I -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_POST_BUILD_RULE - -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_PRJ_LIBS - -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_SIZE -size386 -<END> - -<BEGIN> BUILD_PENTIUM_release_RO_DEPEND_PATH -{$(WIND_BASE)/target/h/} \ - {$(WIND_BASE)/target/src/} \ - {$(WIND_BASE)/target/config/} -<END> - -<BEGIN> BUILD_PENTIUM_release_TC -::tc_PENTIUMgnu -<END> - -<BEGIN> BUILD_RULE_BerkeleyDB20small.out - -<END> - -<BEGIN> BUILD_RULE_BerkeleyDB20small_sim.out - -<END> - -<BEGIN> BUILD_RULE_archive - -<END> - -<BEGIN> BUILD_RULE_objects - -<END> - -<BEGIN> BUILD__CURRENT -PENTIUM_debug -<END> - -<BEGIN> BUILD__LIST -PENTIUM_release PENTIUM_debug -<END> - -<BEGIN> CORE_INFO_TYPE -::prj_vxApp -<END> - -<BEGIN> CORE_INFO_VERSION -2.0 -<END> - diff --git a/storage/bdb/dist/vx_2.0/wpj.in b/storage/bdb/dist/vx_2.0/wpj.in deleted file mode 100644 index a38cf7251a6..00000000000 --- a/storage/bdb/dist/vx_2.0/wpj.in +++ /dev/null @@ -1,160 +0,0 @@ -Document file - DO NOT EDIT - -<BEGIN> BUILD_PENTIUMgnu_BUILDRULE -__DB_APPLICATION_NAME__20.out -<END> - -<BEGIN> BUILD_PENTIUMgnu_MACRO_AR -ar386 -<END> - -<BEGIN> BUILD_PENTIUMgnu_MACRO_ARCHIVE -$(PRJ_DIR)/PENTIUMgnu/__DB_APPLICATION_NAME__20.a -<END> - -<BEGIN> BUILD_PENTIUMgnu_MACRO_AS -cc386 -<END> - -<BEGIN> BUILD_PENTIUMgnu_MACRO_CC -cc386 -<END> - -<BEGIN> BUILD_PENTIUMgnu_MACRO_CFLAGS --g \ - -mpentium \ - -ansi \ - -nostdinc \ - -DRW_MULTI_THREAD \ - -D_REENTRANT \ - -fvolatile \ - -nostdlib \ - -fno-builtin \ - -fno-defer-pop \ - -I$(PRJ_DIR)/.. \ - -I$(PRJ_DIR)/../.. \ - -I$(WIND_BASE)/target/h \ - -DCPU=PENTIUM -<END> - -<BEGIN> BUILD_PENTIUMgnu_MACRO_CFLAGS_AS --g \ - -mpentium \ - -ansi \ - -nostdinc \ - -fvolatile \ - -nostdlib \ - -fno-builtin \ - -fno-defer-pop \ - -P \ - -x \ - assembler-with-cpp \ - -I$(WIND_BASE)/target/h \ - -DCPU=PENTIUM -<END> - -<BEGIN> BUILD_PENTIUMgnu_MACRO_CPP -cc386 -E -P -xc -<END> - -<BEGIN> BUILD_PENTIUMgnu_MACRO_LD -ld386 -<END> - -<BEGIN> BUILD_PENTIUMgnu_MACRO_LDDEPS - -<END> - -<BEGIN> BUILD_PENTIUMgnu_MACRO_LDFLAGS --X -N -<END> - -<BEGIN> BUILD_PENTIUMgnu_MACRO_LD_PARTIAL_FLAGS --X -r -<END> - -<BEGIN> BUILD_PENTIUMgnu_MACRO_NM -nm386 -g -<END> - -<BEGIN> BUILD_PENTIUMgnu_MACRO_OPTION_DEFINE_MACRO --D -<END> - -<BEGIN> BUILD_PENTIUMgnu_MACRO_OPTION_INCLUDE_DIR --I -<END> - -<BEGIN> BUILD_PENTIUMgnu_MACRO_POST_BUILD_RULE - -<END> - -<BEGIN> BUILD_PENTIUMgnu_MACRO_PRJ_LIBS - -<END> - -<BEGIN> BUILD_PENTIUMgnu_MACRO_SIZE -size386 -<END> - -<BEGIN> BUILD_PENTIUMgnu_RO_DEPEND_PATH -{$(WIND_BASE)/target/h/} \ - {$(WIND_BASE)/target/src/} \ - {$(WIND_BASE)/target/config/} -<END> - -<BEGIN> BUILD_PENTIUMgnu_TC -::tc_PENTIUMgnu -<END> - -<BEGIN> BUILD_RULE_archive - -<END> - -<BEGIN> BUILD_RULE___DB_APPLICATION_NAME__20.out - -<END> - -<BEGIN> BUILD_RULE_objects - -<END> - -<BEGIN> BUILD__CURRENT -PENTIUMgnu -<END> - -<BEGIN> BUILD__LIST -PENTIUMgnu -<END> - -<BEGIN> CORE_INFO_TYPE -::prj_vxApp -<END> - -<BEGIN> CORE_INFO_VERSION -2.0 -<END> - -<BEGIN> FILE___DB_APPLICATION_NAME__.c_dependDone -FALSE -<END> - -<BEGIN> FILE___DB_APPLICATION_NAME__.c_dependencies - -<END> - -<BEGIN> FILE___DB_APPLICATION_NAME__.c_objects -__DB_APPLICATION_NAME__.o -<END> - -<BEGIN> FILE___DB_APPLICATION_NAME__.c_tool -C/C++ compiler -<END> - -<BEGIN> PROJECT_FILES -$(PRJ_DIR)/__DB_APPLICATION_NAME__.c -<END> - -<BEGIN> userComments -__DB_APPLICATION_NAME__ -<END> diff --git a/storage/bdb/dist/vx_2.2/BerkeleyDB.wpj b/storage/bdb/dist/vx_2.2/BerkeleyDB.wpj deleted file mode 100644 index e27a231f76f..00000000000 --- a/storage/bdb/dist/vx_2.2/BerkeleyDB.wpj +++ /dev/null @@ -1,310 +0,0 @@ -Document file - DO NOT EDIT - -<BEGIN> BUILD_PENTIUM_debug_BUILDRULE -BerkeleyDB22.out -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_AR -arpentium -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_ARCHIVE -$(PRJ_DIR)/PENTIUM_debug/BerkeleyDB22.a -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_AS -ccpentium -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_CC -ccpentium -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_CC_ARCH_SPEC --mcpu=pentiumpro -march=pentiumpro -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_CFLAGS --g \ - -mcpu=pentiumpro \ - -march=pentiumpro \ - -ansi \ - -nostdlib \ - -fno-builtin \ - -fno-defer-pop \ - -I. \ - -I$(WIND_BASE)/target/h \ - -DCPU=PENTIUM2 \ - -DTOOL_FAMILY=gnu \ - -DTOOL=gnu \ - -O0 \ - -I$(PRJ_DIR) \ - -I$(PRJ_DIR)/.. \ - -DDIAGNOSTIC \ - -DDEBUG -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_CFLAGS_AS --g \ - -mcpu=pentiumpro \ - -march=pentiumpro \ - -ansi \ - -nostdlib \ - -fno-builtin \ - -fno-defer-pop \ - -P \ - -xassembler-with-cpp \ - -I. \ - -I$(WIND_BASE)/target/h \ - -DCPU=PENTIUM2 \ - -DTOOL_FAMILY=gnu \ - -DTOOL=gnu -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_CPP -ccpentium -E -P -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_HEX_FLAGS - -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_LD -ldpentium -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_LDFLAGS --X -N -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_LD_PARTIAL -ccpentium -r -nostdlib -Wl,-X -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_LD_PARTIAL_FLAGS --X -r -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_NM -nmpentium -g -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_OPTION_DEFINE_MACRO --D -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_OPTION_DEPEND --M -w -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_OPTION_GENERATE_DEPENDENCY_FILE --MD -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_OPTION_INCLUDE_DIR --I -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_OPTION_LANG_C --xc -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_OPTION_UNDEFINE_MACRO --U -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_POST_BUILD_RULE - -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_PRJ_LIBS - -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_SIZE -sizepentium -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_TOOL_FAMILY -gnu -<END> - -<BEGIN> BUILD_PENTIUM_debug_RO_DEPEND_PATH -{$(WIND_BASE)/target/h/} \ - {$(WIND_BASE)/target/src/} \ - {$(WIND_BASE)/target/config/} -<END> - -<BEGIN> BUILD_PENTIUM_debug_TC -::tc_PENTIUM2gnu -<END> - -<BEGIN> BUILD_PENTIUM_release_BUILDRULE -BerkeleyDB22.out -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_AR -arpentium -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_ARCHIVE -$(PRJ_DIR)/PENTIUM_release/BerkeleyDB22.a -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_AS -ccpentium -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_CC -ccpentium -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_CC_ARCH_SPEC --mcpu=pentiumpro -march=pentiumpro -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_CFLAGS --g \ - -mcpu=pentiumpro \ - -march=pentiumpro \ - -ansi \ - -nostdlib \ - -fno-builtin \ - -fno-defer-pop \ - -I. \ - -I$(WIND_BASE)/target/h \ - -DCPU=PENTIUM2 \ - -DTOOL_FAMILY=gnu \ - -DTOOL=gnu \ - -O2 \ - -I$(PRJ_DIR) \ - -I$(PRJ_DIR)/.. -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_CFLAGS_AS --g \ - -mcpu=pentiumpro \ - -march=pentiumpro \ - -ansi \ - -nostdlib \ - -fno-builtin \ - -fno-defer-pop \ - -P \ - -xassembler-with-cpp \ - -I. \ - -I$(WIND_BASE)/target/h \ - -DCPU=PENTIUM2 \ - -DTOOL_FAMILY=gnu \ - -DTOOL=gnu -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_CPP -ccpentium -E -P -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_HEX_FLAGS - -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_LD -ldpentium -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_LDFLAGS --X -N -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_LD_PARTIAL -ccpentium -r -nostdlib -Wl,-X -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_LD_PARTIAL_FLAGS --X -r -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_NM -nmpentium -g -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_OPTION_DEFINE_MACRO --D -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_OPTION_DEPEND --M -w -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_OPTION_GENERATE_DEPENDENCY_FILE --MD -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_OPTION_INCLUDE_DIR --I -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_OPTION_LANG_C --xc -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_OPTION_UNDEFINE_MACRO --U -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_POST_BUILD_RULE - -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_PRJ_LIBS - -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_SIZE -sizepentium -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_TOOL_FAMILY -gnu -<END> - -<BEGIN> BUILD_PENTIUM_release_RO_DEPEND_PATH -{$(WIND_BASE)/target/h/} \ - {$(WIND_BASE)/target/src/} \ - {$(WIND_BASE)/target/config/} -<END> - -<BEGIN> BUILD_PENTIUM_release_TC -::tc_PENTIUM2gnu -<END> - -<BEGIN> BUILD_RULE_BerkeleyDB22.out - -<END> - -<BEGIN> BUILD_RULE_BerkeleyDB22.pl - -<END> - -<BEGIN> BUILD_RULE_archive - -<END> - -<BEGIN> BUILD_RULE_objects - -<END> - -<BEGIN> BUILD__CURRENT -PENTIUM_debug -<END> - -<BEGIN> BUILD__LIST -PENTIUM_release PENTIUM_debug -<END> - -<BEGIN> CORE_INFO_TYPE -::prj_vxApp -<END> - -<BEGIN> CORE_INFO_VERSION -2.2 -<END> - diff --git a/storage/bdb/dist/vx_2.2/BerkeleyDBsmall.wpj b/storage/bdb/dist/vx_2.2/BerkeleyDBsmall.wpj deleted file mode 100644 index bfbdadc46a5..00000000000 --- a/storage/bdb/dist/vx_2.2/BerkeleyDBsmall.wpj +++ /dev/null @@ -1,310 +0,0 @@ -Document file - DO NOT EDIT - -<BEGIN> BUILD_PENTIUM_debug_BUILDRULE -BerkeleyDB22small.out -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_AR -arpentium -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_ARCHIVE -$(PRJ_DIR)/PENTIUM_debug/BerkeleyDB22small.a -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_AS -ccpentium -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_CC -ccpentium -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_CC_ARCH_SPEC --mcpu=pentiumpro -march=pentiumpro -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_CFLAGS --g \ - -mcpu=pentiumpro \ - -march=pentiumpro \ - -ansi \ - -nostdlib \ - -fno-builtin \ - -fno-defer-pop \ - -I. \ - -I$(WIND_BASE)/target/h \ - -DCPU=PENTIUM2 \ - -DTOOL_FAMILY=gnu \ - -DTOOL=gnu \ - -O0 \ - -I$(PRJ_DIR) \ - -I$(PRJ_DIR)/.. \ - -DDIAGNOSTIC \ - -DDEBUG -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_CFLAGS_AS --g \ - -mcpu=pentiumpro \ - -march=pentiumpro \ - -ansi \ - -nostdlib \ - -fno-builtin \ - -fno-defer-pop \ - -P \ - -xassembler-with-cpp \ - -I. \ - -I$(WIND_BASE)/target/h \ - -DCPU=PENTIUM2 \ - -DTOOL_FAMILY=gnu \ - -DTOOL=gnu -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_CPP -ccpentium -E -P -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_HEX_FLAGS - -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_LD -ldpentium -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_LDFLAGS --X -N -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_LD_PARTIAL -ccpentium -r -nostdlib -Wl,-X -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_LD_PARTIAL_FLAGS --X -r -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_NM -nmpentium -g -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_OPTION_DEFINE_MACRO --D -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_OPTION_DEPEND --M -w -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_OPTION_GENERATE_DEPENDENCY_FILE --MD -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_OPTION_INCLUDE_DIR --I -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_OPTION_LANG_C --xc -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_OPTION_UNDEFINE_MACRO --U -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_POST_BUILD_RULE - -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_PRJ_LIBS - -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_SIZE -sizepentium -<END> - -<BEGIN> BUILD_PENTIUM_debug_MACRO_TOOL_FAMILY -gnu -<END> - -<BEGIN> BUILD_PENTIUM_debug_RO_DEPEND_PATH -{$(WIND_BASE)/target/h/} \ - {$(WIND_BASE)/target/src/} \ - {$(WIND_BASE)/target/config/} -<END> - -<BEGIN> BUILD_PENTIUM_debug_TC -::tc_PENTIUM2gnu -<END> - -<BEGIN> BUILD_PENTIUM_release_BUILDRULE -BerkeleyDB22small.out -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_AR -arpentium -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_ARCHIVE -$(PRJ_DIR)/PENTIUM_release/BerkeleyDB22small.a -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_AS -ccpentium -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_CC -ccpentium -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_CC_ARCH_SPEC --mcpu=pentiumpro -march=pentiumpro -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_CFLAGS --g \ - -mcpu=pentiumpro \ - -march=pentiumpro \ - -ansi \ - -nostdlib \ - -fno-builtin \ - -fno-defer-pop \ - -I. \ - -I$(WIND_BASE)/target/h \ - -DCPU=PENTIUM2 \ - -DTOOL_FAMILY=gnu \ - -DTOOL=gnu \ - -O2 \ - -I$(PRJ_DIR) \ - -I$(PRJ_DIR)/.. -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_CFLAGS_AS --g \ - -mcpu=pentiumpro \ - -march=pentiumpro \ - -ansi \ - -nostdlib \ - -fno-builtin \ - -fno-defer-pop \ - -P \ - -xassembler-with-cpp \ - -I. \ - -I$(WIND_BASE)/target/h \ - -DCPU=PENTIUM2 \ - -DTOOL_FAMILY=gnu \ - -DTOOL=gnu -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_CPP -ccpentium -E -P -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_HEX_FLAGS - -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_LD -ldpentium -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_LDFLAGS --X -N -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_LD_PARTIAL -ccpentium -r -nostdlib -Wl,-X -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_LD_PARTIAL_FLAGS --X -r -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_NM -nmpentium -g -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_OPTION_DEFINE_MACRO --D -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_OPTION_DEPEND --M -w -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_OPTION_GENERATE_DEPENDENCY_FILE --MD -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_OPTION_INCLUDE_DIR --I -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_OPTION_LANG_C --xc -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_OPTION_UNDEFINE_MACRO --U -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_POST_BUILD_RULE - -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_PRJ_LIBS - -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_SIZE -sizepentium -<END> - -<BEGIN> BUILD_PENTIUM_release_MACRO_TOOL_FAMILY -gnu -<END> - -<BEGIN> BUILD_PENTIUM_release_RO_DEPEND_PATH -{$(WIND_BASE)/target/h/} \ - {$(WIND_BASE)/target/src/} \ - {$(WIND_BASE)/target/config/} -<END> - -<BEGIN> BUILD_PENTIUM_release_TC -::tc_PENTIUM2gnu -<END> - -<BEGIN> BUILD_RULE_BerkeleyDB22small.out - -<END> - -<BEGIN> BUILD_RULE_BerkeleyDB22small.pl - -<END> - -<BEGIN> BUILD_RULE_archive - -<END> - -<BEGIN> BUILD_RULE_objects - -<END> - -<BEGIN> BUILD__CURRENT -PENTIUM_debug -<END> - -<BEGIN> BUILD__LIST -PENTIUM_release PENTIUM_debug -<END> - -<BEGIN> CORE_INFO_TYPE -::prj_vxApp -<END> - -<BEGIN> CORE_INFO_VERSION -2.2 -<END> - diff --git a/storage/bdb/dist/vx_2.2/wpj.in b/storage/bdb/dist/vx_2.2/wpj.in deleted file mode 100644 index d883ef2b193..00000000000 --- a/storage/bdb/dist/vx_2.2/wpj.in +++ /dev/null @@ -1,194 +0,0 @@ -Document file - DO NOT EDIT - -<BEGIN> BUILD_PENTIUM2gnu_BUILDRULE -__DB_APPLICATION_NAME__22.out -<END> - -<BEGIN> BUILD_PENTIUM2gnu_MACRO_AR -arpentium -<END> - -<BEGIN> BUILD_PENTIUM2gnu_MACRO_ARCHIVE -$(PRJ_DIR)/PENTIUM2gnu/__DB_APPLICATION_NAME__22.a -<END> - -<BEGIN> BUILD_PENTIUM2gnu_MACRO_AS -ccpentium -<END> - -<BEGIN> BUILD_PENTIUM2gnu_MACRO_CC -ccpentium -<END> - -<BEGIN> BUILD_PENTIUM2gnu_MACRO_CC_ARCH_SPEC --mcpu=pentiumpro -march=pentiumpro -<END> - -<BEGIN> BUILD_PENTIUM2gnu_MACRO_CFLAGS --g \ - -mcpu=pentiumpro \ - -march=pentiumpro \ - -ansi \ - -nostdlib \ - -DRW_MULTI_THREAD \ - -D_REENTRANT \ - -fvolatile \ - -fno-builtin \ - -fno-defer-pop \ - -I$(PRJ_DIR)/.. \ - -I$(PRJ_DIR)/../.. \ - -I$(WIND_BASE)/target/h \ - -DCPU=PENTIUM2 \ - -DTOOL_FAMILY=gnu \ - -DTOOL=gnu -<END> - -<BEGIN> BUILD_PENTIUM2gnu_MACRO_CFLAGS_AS --g \ - -mcpu=pentiumpro \ - -march=pentiumpro \ - -ansi \ - -nostdlib \ - -fno-builtin \ - -fno-defer-pop \ - -P \ - -xassembler-with-cpp \ - -I$(WIND_BASE)/target/h \ - -DCPU=PENTIUM2 \ - -DTOOL_FAMILY=gnu \ - -DTOOL=gnu -<END> - -<BEGIN> BUILD_PENTIUM2gnu_MACRO_CPP -ccpentium -E -P -<END> - -<BEGIN> BUILD_PENTIUM2gnu_MACRO_HEX_FLAGS - -<END> - -<BEGIN> BUILD_PENTIUM2gnu_MACRO_LD -ldpentium -<END> - -<BEGIN> BUILD_PENTIUM2gnu_MACRO_LDFLAGS --X -N -<END> - -<BEGIN> BUILD_PENTIUM2gnu_MACRO_LD_PARTIAL -ccpentium -r -nostdlib -Wl,-X -<END> - -<BEGIN> BUILD_PENTIUM2gnu_MACRO_LD_PARTIAL_FLAGS --X -r -<END> - -<BEGIN> BUILD_PENTIUM2gnu_MACRO_NM -nmpentium -g -<END> - -<BEGIN> BUILD_PENTIUM2gnu_MACRO_OPTION_DEFINE_MACRO --D -<END> - -<BEGIN> BUILD_PENTIUM2gnu_MACRO_OPTION_DEPEND --M -w -<END> - -<BEGIN> BUILD_PENTIUM2gnu_MACRO_OPTION_GENERATE_DEPENDENCY_FILE --MD -<END> - -<BEGIN> BUILD_PENTIUM2gnu_MACRO_OPTION_INCLUDE_DIR --I -<END> - -<BEGIN> BUILD_PENTIUM2gnu_MACRO_OPTION_LANG_C --xc -<END> - -<BEGIN> BUILD_PENTIUM2gnu_MACRO_OPTION_UNDEFINE_MACRO --U -<END> - -<BEGIN> BUILD_PENTIUM2gnu_MACRO_POST_BUILD_RULE - -<END> - -<BEGIN> BUILD_PENTIUM2gnu_MACRO_PRJ_LIBS - -<END> - -<BEGIN> BUILD_PENTIUM2gnu_MACRO_SIZE -sizepentium -<END> - -<BEGIN> BUILD_PENTIUM2gnu_MACRO_TOOL_FAMILY -gnu -<END> - -<BEGIN> BUILD_PENTIUM2gnu_RO_DEPEND_PATH -{$(WIND_BASE)/target/h/} \ - {$(WIND_BASE)/target/src/} \ - {$(WIND_BASE)/target/config/} -<END> - -<BEGIN> BUILD_PENTIUM2gnu_TC -::tc_PENTIUM2gnu -<END> - -<BEGIN> BUILD_RULE_archive - -<END> - -<BEGIN> BUILD_RULE___DB_APPLICATION_NAME__22.out - -<END> - -<BEGIN> BUILD_RULE___DB_APPLICATION_NAME__22.pl - -<END> - -<BEGIN> BUILD_RULE_objects - -<END> - -<BEGIN> BUILD__CURRENT -PENTIUM2gnu -<END> - -<BEGIN> BUILD__LIST -PENTIUM2gnu -<END> - -<BEGIN> CORE_INFO_TYPE -::prj_vxApp -<END> - -<BEGIN> CORE_INFO_VERSION -2.2 -<END> - -<BEGIN> FILE___DB_APPLICATION_NAME__.c_dependDone -FALSE -<END> - -<BEGIN> FILE___DB_APPLICATION_NAME__.c_dependencies - -<END> - -<BEGIN> FILE___DB_APPLICATION_NAME__.c_objects -__DB_APPLICATION_NAME__.o -<END> - -<BEGIN> FILE___DB_APPLICATION_NAME__.c_tool -C/C++ compiler -<END> - -<BEGIN> PROJECT_FILES -$(PRJ_DIR)/__DB_APPLICATION_NAME__.c -<END> - -<BEGIN> userComments -__DB_APPLICATION_NAME__ -<END> diff --git a/storage/bdb/dist/vx_3.1/Makefile.custom b/storage/bdb/dist/vx_3.1/Makefile.custom deleted file mode 100644 index ca781f7b251..00000000000 --- a/storage/bdb/dist/vx_3.1/Makefile.custom +++ /dev/null @@ -1,51 +0,0 @@ -# -# Custom Makefile shell -# -# This file may be edited freely, since it will not be regenerated -# by the project manager. -# -# Use this makefile to define rules to make external binaries -# and deposit them in the $(EXTERNAL_BINARIES_DIR) directory. -# -# If you have specified external modules during your component -# creation, you will find make rules already in place below. -# You will likely have to edit these to suit your individual -# build setup. -# -# You may wish to use the CPU, BUILD_SPEC or TOOL make variables in -# your Makefile to support builds for different architectures. Use -# the FORCE_EXTERNAL_MAKE phony target to ensure that your external -# make always runs. -# -# The example below assumes that your custom makefile is in the -# mySourceTree directory, and that the binary file it produces -# is placed into the $(BUILD_SPEC) sub-directory. -# -# EXTERNAL_SOURCE_BASE = /folk/me/mySourceTree -# EXTERNAL_MODULE = myLibrary.o -# EXTERNAL_MAKE = make -# -# $(EXTERNAL_BINARIES_DIR)/$(EXTERNAL_MODULE) : FORCE_EXTERNAL_MAKE -# $(EXTERNAL_MAKE) -C $(EXTERNAL_SOURCE_BASE) \ -# -f $(EXTERNAL_SOURCE_BASE)/Makefile \ -# CPU=$(CPU) BUILD_SPEC=$(BUILD_SPEC) $(@F) -# $(CP) $(subst /,$(DIRCHAR),$(EXTERNAL_SOURCE_BASE)/$(BUILD_SPEC)/$(@F) $@) -# -# If you are not adding your external modules from the component wizard, -# you will have to include them in your component yourself: -# -# From the GUI, you can do this with the Component's 'Add external module' -# dialog. -# -# If you are using the command line, add the module(s) by editing the -# MODULES line in component.cdf file, e.g. -# -# Component INCLUDE_MYCOMPONENT { -# -# MODULES foo.o goo.o \ -# myLibrary.o -# - - -# rules to build custom libraries - diff --git a/storage/bdb/dist/vx_3.1/cdf.1 b/storage/bdb/dist/vx_3.1/cdf.1 deleted file mode 100644 index 17db06f7e61..00000000000 --- a/storage/bdb/dist/vx_3.1/cdf.1 +++ /dev/null @@ -1,12 +0,0 @@ -/* component.cdf - dynamically updated configuration */ - -/* - * NOTE: you may edit this file to alter the configuration - * But all non-configuration information, including comments, - * will be lost upon rebuilding this project. - */ - -/* Component information */ - -Component INCLUDE_BERKELEYDB { - ENTRY_POINTS ALL_GLOBAL_SYMBOLS diff --git a/storage/bdb/dist/vx_3.1/cdf.2 b/storage/bdb/dist/vx_3.1/cdf.2 deleted file mode 100644 index 76f123af9fb..00000000000 --- a/storage/bdb/dist/vx_3.1/cdf.2 +++ /dev/null @@ -1,9 +0,0 @@ - NAME BerkeleyDB - PREF_DOMAIN ANY - _INIT_ORDER usrComponentsInit -} - -/* EntryPoint information */ - -/* Module information */ - diff --git a/storage/bdb/dist/vx_3.1/cdf.3 b/storage/bdb/dist/vx_3.1/cdf.3 deleted file mode 100644 index a3146ced95a..00000000000 --- a/storage/bdb/dist/vx_3.1/cdf.3 +++ /dev/null @@ -1,2 +0,0 @@ -/* Parameter information */ - diff --git a/storage/bdb/dist/vx_3.1/component.cdf b/storage/bdb/dist/vx_3.1/component.cdf deleted file mode 100644 index 91edaa87853..00000000000 --- a/storage/bdb/dist/vx_3.1/component.cdf +++ /dev/null @@ -1,30 +0,0 @@ -/* component.cdf - dynamically updated configuration */ - -/* - * NOTE: you may edit this file to alter the configuration - * But all non-configuration information, including comments, - * will be lost upon rebuilding this project. - */ - -/* Component information */ - -Component INCLUDE___DB_CAPAPPL_NAME__ { - ENTRY_POINTS ALL_GLOBAL_SYMBOLS - MODULES __DB_APPLICATION_NAME__.o - NAME __DB_APPLICATION_NAME__ - PREF_DOMAIN ANY - _INIT_ORDER usrComponentsInit -} - -/* EntryPoint information */ - -/* Module information */ - -Module __DB_APPLICATION_NAME__.o { - - NAME __DB_APPLICATION_NAME__.o - SRC_PATH_NAME $PRJ_DIR/../__DB_APPLICATION_NAME__.c -} - -/* Parameter information */ - diff --git a/storage/bdb/dist/vx_3.1/component.wpj b/storage/bdb/dist/vx_3.1/component.wpj deleted file mode 100644 index 01c51c1b97f..00000000000 --- a/storage/bdb/dist/vx_3.1/component.wpj +++ /dev/null @@ -1,475 +0,0 @@ -Document file - DO NOT EDIT - -<BEGIN> CORE_INFO_TYPE -::prj_component -<END> - -<BEGIN> CORE_INFO_VERSION -AE1.1 -<END> - -<BEGIN> BUILD__CURRENT -PENTIUM2gnu.debug -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_CURRENT_TARGET -default -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_DEFAULTFORCPU -1 -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_FILE_$(PRJ_DIR)/../__DB_APPLICATION_NAME__.c_infoTags -toolMacro objects -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_FILE_$(PRJ_DIR)/../__DB_APPLICATION_NAME__.c_objects -__DB_APPLICATION_NAME__.o -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_FILE_$(PRJ_DIR)/../__DB_APPLICATION_NAME__.c_toolMacro -CC -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_FILE_$(PRJ_DIR)/../__DB_APPLICATION_NAME__.c_objects -__DB_APPLICATION_NAME__.o -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_FILE_$(PRJ_DIR)/../__DB_APPLICATION_NAME__.c_toolMacro -CC -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_FILE_$(PRJ_DIR)/compConfig.c_infoTags -toolMacro objects -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_FILE_$(PRJ_DIR)/compConfig.c_objects -compConfig.o -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_FILE_$(PRJ_DIR)/compConfig.c_toolMacro -CC -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_AR -arpentium -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_AS -ccpentium -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_CC -ccpentium -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_CFLAGS --mcpu=pentiumpro \ - -march=pentiumpro \ - -ansi \ - -DRW_MULTI_THREAD \ - -D_REENTRANT \ - -g \ - -nostdlib \ - -fno-builtin \ - -fno-defer-pop \ - -MD \ - -Wall \ - -I. \ - -I$(WIND_BASE)/target/h \ - -I$(PRJ_DIR)/../.. \ - -I$(PRJ_DIR)/../../.. \ - -DCPU=PENTIUM2 -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_CFLAGS_AS --mcpu=pentiumpro \ - -march=pentiumpro \ - -ansi \ - -g \ - -nostdlib \ - -fno-builtin \ - -fno-defer-pop \ - -P \ - -x \ - assembler-with-cpp \ - -Wall \ - -I. \ - -I$(WIND_BASE)/target/h \ - -DCPU=PENTIUM2 -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_CPP -ccpentium -E -P -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_CPPFILT -c++filtpentium --strip-underscores -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_LD -ldpentium -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_LDFLAGS --X -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_LDPARTIAL -ccpentium \ - -B$(WIND_BASE)/host/$(WIND_HOST_TYPE)/lib/gcc-lib/ \ - -nostdlib \ - -r \ - -Wl,-X -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_LD_PARTIAL_FLAGS --X -r -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_NM -nmpentium -g -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_OPTION_DEFINE_MACRO --D -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_OPTION_GENERATE_DEPENDENCY_FILE --MD -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_OPTION_INCLUDE_DIR --I -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_RELEASE -0 -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_SIZE -sizepentium -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_RELEASE -0 -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_RO_DEPEND_PATH -$(WIND_BASE)/target/h/ -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_TC -::tc_PENTIUM2gnu.debug -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_DEFAULTFORCPU -0 -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_FILE_$(PRJ_DIR)/../__DB_APPLICATION_NAME__.c_infoTags -toolMacro objects -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_FILE_$(PRJ_DIR)/../__DB_APPLICATION_NAME__.c_objects -__DB_APPLICATION_NAME__.o -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_FILE_$(PRJ_DIR)/../__DB_APPLICATION_NAME__.c_toolMacro -CC -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_FILE_$(PRJ_DIR)/compConfig.c_infoTags -toolMacro objects -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_FILE_$(PRJ_DIR)/compConfig.c_objects -compConfig.o -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_FILE_$(PRJ_DIR)/compConfig.c_toolMacro -CC -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_AR -arpentium -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_AS -ccpentium -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_CC -ccpentium -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_CFLAGS --mcpu=pentiumpro \ - -march=pentiumpro \ - -ansi \ - -DRW_MULTI_THREAD \ - -D_REENTRANT \ - -O2 \ - -nostdlib \ - -fno-builtin \ - -fno-defer-pop \ - -MD \ - -Wall \ - -I. \ - -I$(WIND_BASE)/target/h \ - -I$(PRJ_DIR)/../.. \ - -I$(PRJ_DIR)/../../.. \ - -DCPU=PENTIUM2 -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_CFLAGS_AS --mcpu=pentiumpro \ - -march=pentiumpro \ - -ansi \ - -O2 \ - -nostdlib \ - -fno-builtin \ - -fno-defer-pop \ - -P \ - -x \ - assembler-with-cpp \ - -Wall \ - -I. \ - -I$(WIND_BASE)/target/h \ - -DCPU=PENTIUM2 -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_CPP -ccpentium -E -P -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_CPPFILT -c++filtpentium --strip-underscores -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_LD -ldpentium -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_LDFLAGS --X -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_LDPARTIAL -ccpentium \ - -B$(WIND_BASE)/host/$(WIND_HOST_TYPE)/lib/gcc-lib/ \ - -nostdlib \ - -r \ - -Wl,-X -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_LD_PARTIAL_FLAGS --X -r -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_NM -nmpentium -g -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_OPTION_DEFINE_MACRO --D -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_OPTION_GENERATE_DEPENDENCY_FILE --MD -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_OPTION_INCLUDE_DIR --I -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_RELEASE -1 -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_SIZE -sizepentium -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_RELEASE -1 -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_RO_DEPEND_PATH -$(WIND_BASE)/target/h/ -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_TC -::tc_PENTIUM2gnu.release -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_DEFAULTFORCPU -1 -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_FILE_$(PRJ_DIR)/../__DB_APPLICATION_NAME__.c_infoTags -toolMacro objects -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_FILE_$(PRJ_DIR)/../__DB_APPLICATION_NAME__.c_objects -__DB_APPLICATION_NAME__.o -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_FILE_$(PRJ_DIR)/../__DB_APPLICATION_NAME__.c_toolMacro -CC -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_FILE_$(PRJ_DIR)/compConfig.c_infoTags -toolMacro objects -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_FILE_$(PRJ_DIR)/compConfig.c_objects -compConfig.o -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_FILE_$(PRJ_DIR)/compConfig.c_toolMacro -CC -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_AR -arpentium -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_AS -ccpentium -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_CC -ccpentium -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_CFLAGS --mcpu=pentium \ - -march=pentium \ - -ansi \ - -DRW_MULTI_THREAD \ - -D_REENTRANT \ - -g \ - -nostdlib \ - -fno-builtin \ - -fno-defer-pop \ - -MD \ - -Wall \ - -I. \ - -I$(WIND_BASE)/target/h \ - -I$(PRJ_DIR)/../.. \ - -I$(PRJ_DIR)/../../.. \ - -DCPU=PENTIUM -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_CFLAGS_AS --mcpu=pentium \ - -march=pentium \ - -ansi \ - -g \ - -nostdlib \ - -fno-builtin \ - -fno-defer-pop \ - -P \ - -x \ - assembler-with-cpp \ - -Wall \ - -I. \ - -I$(WIND_BASE)/target/h \ - -DCPU=PENTIUM -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_CPP -ccpentium -E -P -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_CPPFILT -c++filtpentium --strip-underscores -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_LD -ldpentium -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_LDFLAGS --X -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_LDPARTIAL -ccpentium \ - -B$(WIND_BASE)/host/$(WIND_HOST_TYPE)/lib/gcc-lib/ \ - -nostdlib \ - -r \ - -Wl,-X -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_LD_PARTIAL_FLAGS --X -r -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_NM -nmpentium -g -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_OPTION_DEFINE_MACRO --D -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_OPTION_GENERATE_DEPENDENCY_FILE --MD -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_OPTION_INCLUDE_DIR --I -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_RELEASE -0 -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_SIZE -sizepentium -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_RELEASE -0 -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_RO_DEPEND_PATH -$(WIND_BASE)/target/h/ -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_TC -::tc_PENTIUMgnu.debug -<END> - -<BEGIN> BUILD__LIST -PENTIUM2gnu.debug PENTIUM2gnu.release PENTIUMgnu.debug -<END> - -<BEGIN> PROJECT_FILES -$(PRJ_DIR)/../__DB_APPLICATION_NAME__.c \ - $(PRJ_DIR)/compConfig.c -<END> - -<BEGIN> WCC__CDF_PATH -$(PRJ_DIR) -<END> - -<BEGIN> WCC__CURRENT -PENTIUM2gnu.debug -<END> - -<BEGIN> WCC__LIST -PENTIUM2gnu.debug -<END> - -<BEGIN> WCC__MXR_LIBS -lib$(CPU)$(TOOL)vx.a -<END> - -<BEGIN> WCC__OBJS_PATH -$(WIND_BASE)/target/lib/obj$CPU$TOOLvx -<END> - diff --git a/storage/bdb/dist/vx_3.1/wpj.1 b/storage/bdb/dist/vx_3.1/wpj.1 deleted file mode 100644 index 414b4e8fa35..00000000000 --- a/storage/bdb/dist/vx_3.1/wpj.1 +++ /dev/null @@ -1,22 +0,0 @@ -Document file - DO NOT EDIT - -<BEGIN> CORE_INFO_TYPE -::prj_component -<END> - -<BEGIN> CORE_INFO_VERSION -AE1.0 -<END> - -<BEGIN> BUILD__CURRENT -PENTIUM2gnu.debug -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_CURRENT_TARGET -default -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_DEFAULTFORCPU -0 -<END> - diff --git a/storage/bdb/dist/vx_3.1/wpj.2 b/storage/bdb/dist/vx_3.1/wpj.2 deleted file mode 100644 index 0294f763ef7..00000000000 --- a/storage/bdb/dist/vx_3.1/wpj.2 +++ /dev/null @@ -1,130 +0,0 @@ -<BEGIN> BUILD_PENTIUM2gnu.debug_FILE_$(PRJ_DIR)/compConfig.c_infoTags -toolMacro objects -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_FILE_$(PRJ_DIR)/compConfig.c_objects -compConfig.o -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_FILE_$(PRJ_DIR)/compConfig.c_toolMacro -CC -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_AR -arpentium -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_AS -ccpentium -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_CC -ccpentium -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_CFLAGS --mcpu=pentiumpro \ - -march=pentiumpro \ - -ansi \ - -DRW_MULTI_THREAD \ - -D_REENTRANT \ - -g \ - -nostdlib \ - -fno-builtin \ - -fno-defer-pop \ - -MD \ - -Wall \ - -I. \ - -I$(WIND_BASE)/target/h \ - -DCPU=PENTIUM2 \ - -I$(PRJ_DIR)/.. \ - -I$(PRJ_DIR)/../.. \ - -DDEBUG \ - -DDIAGNOSTIC -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_CFLAGS_AS --mcpu=pentiumpro \ - -march=pentiumpro \ - -ansi \ - -g \ - -nostdlib \ - -fno-builtin \ - -fno-defer-pop \ - -P \ - -x \ - assembler-with-cpp \ - -Wall \ - -I. \ - -I$(WIND_BASE)/target/h \ - -DCPU=PENTIUM2 -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_CPP -ccpentium -E -P -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_CPPFILT -c++filtpentium --strip-underscores -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_LD -ldpentium -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_LDFLAGS --X -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_LDPARTIAL -ccpentium \ - -B$(WIND_BASE)/host/$(WIND_HOST_TYPE)/lib/gcc-lib/ \ - -nostdlib \ - -r \ - -Wl,-X -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_LD_PARTIAL_FLAGS --X -r -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_NM -nmpentium -g -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_OPTION_DEFINE_MACRO --D -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_OPTION_GENERATE_DEPENDENCY_FILE --MD -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_OPTION_INCLUDE_DIR --I -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_RELEASE -0 -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_MACRO_SIZE -sizepentium -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_RELEASE -0 -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_RO_DEPEND_PATH -$(WIND_BASE)/target/h/ -<END> - -<BEGIN> BUILD_PENTIUM2gnu.debug_TC -::tc_PENTIUM2gnu.debug -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_DEFAULTFORCPU -0 -<END> - diff --git a/storage/bdb/dist/vx_3.1/wpj.3 b/storage/bdb/dist/vx_3.1/wpj.3 deleted file mode 100644 index f06e6253923..00000000000 --- a/storage/bdb/dist/vx_3.1/wpj.3 +++ /dev/null @@ -1,128 +0,0 @@ -<BEGIN> BUILD_PENTIUM2gnu.release_FILE_$(PRJ_DIR)/compConfig.c_infoTags -toolMacro objects -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_FILE_$(PRJ_DIR)/compConfig.c_objects -compConfig.o -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_FILE_$(PRJ_DIR)/compConfig.c_toolMacro -CC -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_AR -arpentium -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_AS -ccpentium -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_CC -ccpentium -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_CFLAGS --mcpu=pentiumpro \ - -march=pentiumpro \ - -ansi \ - -DRW_MULTI_THREAD \ - -D_REENTRANT \ - -O2 \ - -nostdlib \ - -fno-builtin \ - -fno-defer-pop \ - -MD \ - -Wall \ - -I. \ - -I$(WIND_BASE)/target/h \ - -DCPU=PENTIUM2 \ - -I$(PRJ_DIR)/.. \ - -I$(PRJ_DIR)/../.. -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_CFLAGS_AS --mcpu=pentiumpro \ - -march=pentiumpro \ - -ansi \ - -O2 \ - -nostdlib \ - -fno-builtin \ - -fno-defer-pop \ - -P \ - -x \ - assembler-with-cpp \ - -Wall \ - -I. \ - -I$(WIND_BASE)/target/h \ - -DCPU=PENTIUM2 -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_CPP -ccpentium -E -P -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_CPPFILT -c++filtpentium --strip-underscores -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_LD -ldpentium -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_LDFLAGS --X -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_LDPARTIAL -ccpentium \ - -B$(WIND_BASE)/host/$(WIND_HOST_TYPE)/lib/gcc-lib/ \ - -nostdlib \ - -r \ - -Wl,-X -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_LD_PARTIAL_FLAGS --X -r -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_NM -nmpentium -g -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_OPTION_DEFINE_MACRO --D -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_OPTION_GENERATE_DEPENDENCY_FILE --MD -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_OPTION_INCLUDE_DIR --I -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_RELEASE -1 -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_MACRO_SIZE -sizepentium -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_RELEASE -1 -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_RO_DEPEND_PATH -$(WIND_BASE)/target/h/ -<END> - -<BEGIN> BUILD_PENTIUM2gnu.release_TC -::tc_PENTIUM2gnu.release -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_DEFAULTFORCPU -1 -<END> - diff --git a/storage/bdb/dist/vx_3.1/wpj.4 b/storage/bdb/dist/vx_3.1/wpj.4 deleted file mode 100644 index 84de6ebf359..00000000000 --- a/storage/bdb/dist/vx_3.1/wpj.4 +++ /dev/null @@ -1,135 +0,0 @@ -<BEGIN> BUILD_PENTIUMgnu.debug_FILE_$(PRJ_DIR)/compConfig.c_infoTags -toolMacro objects -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_FILE_$(PRJ_DIR)/compConfig.c_objects -compConfig.o -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_FILE_$(PRJ_DIR)/compConfig.c_toolMacro -CC -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_AR -arpentium -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_AS -ccpentium -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_CC -ccpentium -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_CFLAGS --mcpu=pentium \ - -march=pentium \ - -ansi \ - -DRW_MULTI_THREAD \ - -D_REENTRANT \ - -g \ - -nostdlib \ - -fno-builtin \ - -fno-defer-pop \ - -MD \ - -Wall \ - -I. \ - -I$(WIND_BASE)/target/h \ - -DCPU=PENTIUM \ - -I$(PRJ_DIR)/.. \ - -I$(PRJ_DIR)/../.. \ - -DDEBUG \ - -DDIAGNOSTIC -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_CFLAGS_AS --mcpu=pentium \ - -march=pentium \ - -ansi \ - -g \ - -nostdlib \ - -fno-builtin \ - -fno-defer-pop \ - -P \ - -x \ - assembler-with-cpp \ - -Wall \ - -I. \ - -I$(WIND_BASE)/target/h \ - -DCPU=PENTIUM -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_CPP -ccpentium -E -P -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_CPPFILT -c++filtpentium --strip-underscores -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_LD -ldpentium -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_LDFLAGS --X -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_LDPARTIAL -ccpentium \ - -B$(WIND_BASE)/host/$(WIND_HOST_TYPE)/lib/gcc-lib/ \ - -nostdlib \ - -r \ - -Wl,-X -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_LD_PARTIAL_FLAGS --X -r -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_NM -nmpentium -g -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_OPTION_DEFINE_MACRO --D -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_OPTION_GENERATE_DEPENDENCY_FILE --MD -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_OPTION_INCLUDE_DIR --I -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_RELEASE -0 -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_MACRO_SIZE -sizepentium -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_RELEASE -0 -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_RO_DEPEND_PATH -$(WIND_BASE)/target/h/ -<END> - -<BEGIN> BUILD_PENTIUMgnu.debug_TC -::tc_PENTIUMgnu.debug -<END> - -<BEGIN> BUILD__LIST -PENTIUMgnu.debug PENTIUM2gnu.debug PENTIUM2gnu.release -<END> - -<BEGIN> COMPONENT_COM_TYPE - -<END> - -<BEGIN> PROJECT_FILES diff --git a/storage/bdb/dist/vx_3.1/wpj.5 b/storage/bdb/dist/vx_3.1/wpj.5 deleted file mode 100644 index f4056e7e22a..00000000000 --- a/storage/bdb/dist/vx_3.1/wpj.5 +++ /dev/null @@ -1,22 +0,0 @@ -<END> - -<BEGIN> WCC__CDF_PATH -$(PRJ_DIR) -<END> - -<BEGIN> WCC__CURRENT -PENTIUMgnu.debug -<END> - -<BEGIN> WCC__LIST -PENTIUMgnu.debug -<END> - -<BEGIN> WCC__MXR_LIBS -lib$(CPU)$(TOOL)vx.a -<END> - -<BEGIN> WCC__OBJS_PATH -$(WIND_BASE)/target/lib/obj$CPU$TOOLvx -<END> - diff --git a/storage/bdb/dist/vx_buildcd b/storage/bdb/dist/vx_buildcd deleted file mode 100755 index 72bd10b8d52..00000000000 --- a/storage/bdb/dist/vx_buildcd +++ /dev/null @@ -1,119 +0,0 @@ -#!/bin/sh -# $Id: vx_buildcd,v 12.0 2004/11/17 03:43:37 bostic Exp $ -# -# Build the Setup SDK CD image on the VxWorks host machine. - -. ./RELEASE - -B=`pwd` -B=$B/.. -D=$B/dist/vx_setup -C=$D/db.CD -Q=/export/home/sue/SetupSDK -S=$Q/resource/mfg/setup -W=sun4-solaris2 - -symdoc=$D/docs/BerkeleyDB.$DB_VERSION_MAJOR.$DB_VERSION_MINOR.$DB_VERSION_PATCH -symdb=$D/windlink/sleepycat/BerkeleyDB.$DB_VERSION_MAJOR.$DB_VERSION_MINOR.$DB_VERSION_PATCH -rm -rf $D/docs $D/windlink -mkdir $D/docs $D/windlink $D/windlink/sleepycat -ln -s $B/docs $symdoc -ln -s $B $symdb - -s=/tmp/__db_a -t=/tmp/__db_b - -# -# Remove the old CD directory if it is there. -if test -d $C; then - echo "$C cannot exist." - echo "As root, execute 'rm -rf $C'" - echo "and then rerun the script" - exit 1 -fi - -# -# Check for absolute pathnames in the project files. -# That is bad, but Tornado insists on putting them in -# whenever you add new files. -# -rm -f $t -f=`find $B/build_vxworks -name \*.wpj -print` -for i in $f; do - grep -l -- "$B" $i >> $t -done -if test -s $t; then - echo "The following files contain absolute pathnames." - echo "They must be fixed before building the CD image:" - cat $t - exit 1 -fi - -# -# NOTE: We reuse the same sed script over several files. -# -cat <<ENDOFSEDTEXT > $s -s/@DB_VERSION_MAJOR@/$DB_VERSION_MAJOR/g -s/@DB_VERSION_MINOR@/$DB_VERSION_MINOR/g -s/@DB_VERSION_PATCH@/$DB_VERSION_PATCH/g -s#@DB_SETUP_DIR@#$D#g -ENDOFSEDTEXT - -f=$D/setup.pool -(sed -f $s $D/vx_setup.in) > $t - (echo "Building $f" && rm -f $f && cp $t $f) - -f=$D/README.TXT -(sed -f $s $D/README.in) > $t - (echo "Building $f" && rm -f $f && cp $t $f) - -f=$D/CONFIG.TCL -(sed -f $s $D/CONFIG.in) > $t - (echo "Building $f" && rm -f $f && cp $t $f) - -f=$D/filelist.demo -(sed -f $s $D/vx_demofile.in) > $t - (echo "Building $f" && rm -f $f && cp $t $f) - -# Copy the Sleepycat specific files into the SetupSDK area. -(cd $D && cp README.TXT $S) -(cd $D && cp LICENSE.TXT $S) -(cd $D && cp CONFIG.TCL $S/RESOURCE/TCL) -(cd $D && cp SETUP.BMP $S/RESOURCE/BITMAPS) - -# -# NOTE: The contents of LIB must be on one, long, single line. -# Even preserving it with a \ doesn't work for htmlBook. -# -f=../docs/LIB -(echo "Building $f" && rm -f $f) -cat <<ENDOFLIBTEXT >> $f -{BerkeleyDB.$DB_VERSION_MAJOR.$DB_VERSION_MINOR.$DB_VERSION_PATCH} {Sleepycat Software Berkeley DB} {<b>BerkeleyDB.$DB_VERSION_MAJOR.$DB_VERSION_MINOR.$DB_VERSION_PATCH</b>} {<b><a href="./index.html">BerkeleyDB.$DB_VERSION_MAJOR.$DB_VERSION_MINOR.$DB_VERSION_PATCH</a></b>} {Sleepycat BerkeleyDB} {} {} {} -ENDOFLIBTEXT - -# -# Start generating the file list. -f=$D/filelist.all - -# -# Just put everything into the image. But we only want to find regular -# files; we cannot have all the directories listed too. -# -# NOTE: This find is overly aggressive in getting files, particularly -# for the 'windlink/sleepycat' files. We actually end up with 3 sets of the -# documentation, the "real" ones in 'docs/BerkeleyDB*', the set found -# via 'windlink/sleepycat/Berk*/docs' and the one found via our symlink in -# 'windlink/sleepycat/Berk*/dist/vx_setup/docs/Berk*'. -# -# However, we waste a little disk space so that the expression below -# is trivial and we don't have to maintain it as new files/directories -# are added to DB. -# -(cd $D && find docs/BerkeleyDB.$DB_VERSION_MAJOR.$DB_VERSION_MINOR.$DB_VERSION_PATCH/ -follow -name \* -type f -print) > $t -(cd $D && find windlink/sleepycat/BerkeleyDB.$DB_VERSION_MAJOR.$DB_VERSION_MINOR.$DB_VERSION_PATCH/ -follow -name docs -prune -o -type f -print) >> $t -(echo "Building $f" && rm -f $f && cp $t $f) -# -# Finally build the CD image! -# -env PATH=$Q/$W/bin:$PATH QMS_BASE=$Q WIND_HOST_TYPE=$W \ -pool mfg -d $C -v -nokey BerkeleyDB.$DB_VERSION_MAJOR.$DB_VERSION_MINOR < $D/setup.pool diff --git a/storage/bdb/dist/vx_config.in b/storage/bdb/dist/vx_config.in deleted file mode 100644 index 539600d62ab..00000000000 --- a/storage/bdb/dist/vx_config.in +++ /dev/null @@ -1,451 +0,0 @@ -/* !!! - * The CONFIG_TEST option may be added using the Tornado project build. - * DO NOT modify it here. - */ -/* Define to 1 if you want to build a version for running the test suite. */ -/* #undef CONFIG_TEST */ - -/* We use DB_WIN32 much as one would use _WIN32 -- to specify that we're using - an operating system environment that supports Win32 calls and semantics. We - don't use _WIN32 because Cygwin/GCC also defines _WIN32, even though - Cygwin/GCC closely emulates the Unix environment. */ -/* #undef DB_WIN32 */ - -/* !!! - * The DEBUG option may be added using the Tornado project build. - * DO NOT modify it here. - */ -/* Define to 1 if you want a debugging version. */ -/* #undef DEBUG */ - -/* Define to 1 if you want a version that logs read operations. */ -/* #undef DEBUG_ROP */ - -/* Define to 1 if you want a version that logs write operations. */ -/* #undef DEBUG_WOP */ - -/* !!! - * The DIAGNOSTIC option may be added using the Tornado project build. - * DO NOT modify it here. - */ -/* Define to 1 if you want a version with run-time diagnostic checking. */ -/* #undef DIAGNOSTIC */ - -/* Define to 1 if 64-bit types are available. */ -#define HAVE_64BIT_TYPES 1 - -/* Define to 1 if you have the `clock_gettime' function. */ -#define HAVE_CLOCK_GETTIME 1 - -/* Define to 1 if Berkeley DB release includes strong cryptography. */ -#define HAVE_CRYPTO 1 - -/* Define to 1 if you have the `directio' function. */ -/* #undef HAVE_DIRECTIO */ - -/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'. - */ -#define HAVE_DIRENT_H 1 - -/* Define to 1 if you have the <dlfcn.h> header file. */ -/* #undef HAVE_DLFCN_H */ - -/* Define to 1 if you have EXIT_SUCCESS/EXIT_FAILURE #defines. */ -#define HAVE_EXIT_SUCCESS 1 - -/* Define to 1 if you have the `fchmod' function. */ -/* #undef HAVE_FCHMOD */ - -/* Define to 1 if you have the `fcntl' function. */ -/* #undef HAVE_FCNTL */ - -/* Define to 1 if fcntl/F_SETFD denies child access to file descriptors. */ -/* #undef HAVE_FCNTL_F_SETFD */ - -/* Define to 1 if you have the `fdatasync' function. */ -/* #undef HAVE_FDATASYNC */ - -/* Define to 1 if allocated filesystem blocks are not zeroed. */ -#define HAVE_FILESYSTEM_NOTZERO 1 - -/* Define to 1 if you have the `ftruncate' function. */ -#define HAVE_FTRUNCATE 1 - -/* Define to 1 if you have the `getcwd' function. */ -#define HAVE_GETCWD 1 - -/* Define to 1 if you have the `getopt' function. */ -/* #undef HAVE_GETOPT */ - -/* Define to 1 if you have the `getrusage' function. */ -/* #undef HAVE_GETRUSAGE */ - -/* Define to 1 if you have the `gettimeofday' function. */ -/* #undef HAVE_GETTIMEOFDAY */ - -/* Define to 1 if you have the `getuid' function. */ -/* #undef HAVE_GETUID */ - -/* Define to 1 if building Hash access method. */ -#define HAVE_HASH 1 - -/* Define to 1 if thread identifier type db_threadid_t is integral. */ -#define HAVE_INTEGRAL_THREAD_TYPE 1 - -/* Define to 1 if you have the <inttypes.h> header file. */ -/* #undef HAVE_INTTYPES_H */ - -/* Define to 1 if you have the `nsl' library (-lnsl). */ -/* #undef HAVE_LIBNSL */ - -/* Define to 1 if you have the `memcmp' function. */ -#define HAVE_MEMCMP 1 - -/* Define to 1 if you have the `memcpy' function. */ -#define HAVE_MEMCPY 1 - -/* Define to 1 if you have the `memmove' function. */ -#define HAVE_MEMMOVE 1 - -/* Define to 1 if you have the <memory.h> header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the `mlock' function. */ -/* #undef HAVE_MLOCK */ - -/* Define to 1 if you have the `mmap' function. */ -/* #undef HAVE_MMAP */ - -/* Define to 1 if you have the `munlock' function. */ -/* #undef HAVE_MUNLOCK */ - -/* Define to 1 if you have the `munmap' function. */ -/* #undef HAVE_MUNMAP */ - -/* Define to 1 to use the GCC compiler and 68K assembly language mutexes. */ -/* #undef HAVE_MUTEX_68K_GCC_ASSEMBLY */ - -/* Define to 1 to use the AIX _check_lock mutexes. */ -/* #undef HAVE_MUTEX_AIX_CHECK_LOCK */ - -/* Define to 1 to use the GCC compiler and Alpha assembly language mutexes. */ -/* #undef HAVE_MUTEX_ALPHA_GCC_ASSEMBLY */ - -/* Define to 1 to use the GCC compiler and ARM assembly language mutexes. */ -/* #undef HAVE_MUTEX_ARM_GCC_ASSEMBLY */ - -/* Define to 1 to use the Apple/Darwin _spin_lock_try mutexes. */ -/* #undef HAVE_MUTEX_DARWIN_SPIN_LOCK_TRY */ - -/* Define to 1 to use the UNIX fcntl system call mutexes. */ -/* #undef HAVE_MUTEX_FCNTL */ - -/* Define to 1 to use the GCC compiler and PaRisc assembly language mutexes. - */ -/* #undef HAVE_MUTEX_HPPA_GCC_ASSEMBLY */ - -/* Define to 1 to use the msem_XXX mutexes on HP-UX. */ -/* #undef HAVE_MUTEX_HPPA_MSEM_INIT */ - -/* Define to 1 to use the GCC compiler and IA64 assembly language mutexes. */ -/* #undef HAVE_MUTEX_IA64_GCC_ASSEMBLY */ - -/* Define to 1 to use the GCC compiler and MIPS assembly language mutexes. */ -/* #undef HAVE_MUTEX_MIPS_GCC_ASSEMBLY */ - -/* Define to 1 to use the msem_XXX mutexes on systems other than HP-UX. */ -/* #undef HAVE_MUTEX_MSEM_INIT */ - -/* Define to 1 to use the GCC compiler and PowerPC assembly language mutexes. - */ -/* #undef HAVE_MUTEX_PPC_GCC_ASSEMBLY */ - -/* Define to 1 to use POSIX 1003.1 pthread_XXX mutexes. */ -/* #undef HAVE_MUTEX_PTHREADS */ - -/* Define to 1 to use Reliant UNIX initspin mutexes. */ -/* #undef HAVE_MUTEX_RELIANTUNIX_INITSPIN */ - -/* Define to 1 to use the IBM C compiler and S/390 assembly language mutexes. - */ -/* #undef HAVE_MUTEX_S390_CC_ASSEMBLY */ - -/* Define to 1 to use the GCC compiler and S/390 assembly language mutexes. */ -/* #undef HAVE_MUTEX_S390_GCC_ASSEMBLY */ - -/* Define to 1 to use the SCO compiler and x86 assembly language mutexes. */ -/* #undef HAVE_MUTEX_SCO_X86_CC_ASSEMBLY */ - -/* Define to 1 to use the obsolete POSIX 1003.1 sema_XXX mutexes. */ -/* #undef HAVE_MUTEX_SEMA_INIT */ - -/* Define to 1 to use the SGI XXX_lock mutexes. */ -/* #undef HAVE_MUTEX_SGI_INIT_LOCK */ - -/* Define to 1 to use the Solaris _lock_XXX mutexes. */ -/* #undef HAVE_MUTEX_SOLARIS_LOCK_TRY */ - -/* Define to 1 to use the Solaris lwp threads mutexes. */ -/* #undef HAVE_MUTEX_SOLARIS_LWP */ - -/* Define to 1 to use the GCC compiler and Sparc assembly language mutexes. */ -/* #undef HAVE_MUTEX_SPARC_GCC_ASSEMBLY */ - -/* Define to 1 if mutexes hold system resources. */ -#define HAVE_MUTEX_SYSTEM_RESOURCES 1 - -/* Define to 1 to configure mutexes intra-process only. */ -/* #undef HAVE_MUTEX_THREAD_ONLY */ - -/* Define to 1 to use the CC compiler and Tru64 assembly language mutexes. */ -/* #undef HAVE_MUTEX_TRU64_CC_ASSEMBLY */ - -/* Define to 1 to use the UNIX International mutexes. */ -/* #undef HAVE_MUTEX_UI_THREADS */ - -/* Define to 1 to use the UTS compiler and assembly language mutexes. */ -/* #undef HAVE_MUTEX_UTS_CC_ASSEMBLY */ - -/* Define to 1 to use VMS mutexes. */ -/* #undef HAVE_MUTEX_VMS */ - -/* Define to 1 to use VxWorks mutexes. */ -#define HAVE_MUTEX_VXWORKS 1 - -/* Define to 1 to use the MSVC compiler and Windows mutexes. */ -/* #undef HAVE_MUTEX_WIN32 */ - -/* Define to 1 to use the GCC compiler and Windows mutexes. */ -/* #undef HAVE_MUTEX_WIN32_GCC */ - -/* Define to 1 to use the GCC compiler and amd64 assembly language mutexes. */ -/* #undef HAVE_MUTEX_X86_64_GCC_ASSEMBLY */ - -/* Define to 1 to use the GCC compiler and x86 assembly language mutexes. */ -/* #undef HAVE_MUTEX_X86_GCC_ASSEMBLY */ - -/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */ -/* #undef HAVE_NDIR_H */ - -/* Define to 1 if you have the O_DIRECT flag. */ -/* #undef HAVE_O_DIRECT */ - -/* Define to 1 if you have the `pread' function. */ -/* #undef HAVE_PREAD */ - -/* Define to 1 if you have the `pstat_getdynamic' function. */ -/* #undef HAVE_PSTAT_GETDYNAMIC */ - -/* Define to 1 if you have the `pthread_self' function. */ -/* #undef HAVE_PTHREAD_SELF */ - -/* Define to 1 if you have the `pwrite' function. */ -/* #undef HAVE_PWRITE */ - -/* Define to 1 if building on QNX. */ -/* #undef HAVE_QNX */ - -/* Define to 1 if building Queue access method. */ -#define HAVE_QUEUE 1 - -/* Define to 1 if you have the `raise' function. */ -#define HAVE_RAISE 1 - -/* Define to 1 if you have the `rand' function. */ -#define HAVE_RAND 1 - -/* Define to 1 if building replication support. */ -#define HAVE_REPLICATION 1 - -/* Define to 1 if building RPC client/server. */ -/* #undef HAVE_RPC */ - -/* Define to 1 if you have the `sched_yield' function. */ -#define HAVE_SCHED_YIELD 1 - -/* Define to 1 if you have the `select' function. */ -#define HAVE_SELECT 1 - -/* Define to 1 if building sequence support. */ -/* #undef HAVE_SEQUENCE */ - -/* Define to 1 if you have the `shmget' function. */ -/* #undef HAVE_SHMGET */ - -/* Define to 1 if you have the `snprintf' function. */ -/* #undef HAVE_SNPRINTF */ - -/* Define to 1 if you have the `srand' function. */ -#define HAVE_SRAND 1 - -/* Define to 1 if building statistics support. */ -#define HAVE_STATISTICS 1 - -/* Define to 1 if you have the <stdint.h> header file. */ -/* #undef HAVE_STDINT_H */ - -/* Define to 1 if you have the <stdlib.h> header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the `strcasecmp' function. */ -/* #undef HAVE_STRCASECMP */ - -/* Define to 1 if you have the `strdup' function. */ -/* #undef HAVE_STRDUP */ - -/* Define to 1 if you have the `strerror' function. */ -#define HAVE_STRERROR 1 - -/* Define to 1 if you have the <strings.h> header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the <string.h> header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the `strtol' function. */ -#define HAVE_STRTOL 1 - -/* Define to 1 if you have the `strtoul' function. */ -#define HAVE_STRTOUL 1 - -/* Define to 1 if `st_blksize' is member of `struct stat'. */ -#define HAVE_STRUCT_STAT_ST_BLKSIZE 1 - -/* Define to 1 if you have the `sysconf' function. */ -/* #undef HAVE_SYSCONF */ - -/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'. - */ -/* #undef HAVE_SYS_DIR_H */ - -/* Define to 1 if you have the <sys/fcntl.h> header file. */ -/* #undef HAVE_SYS_FCNTL_H */ - -/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'. - */ -/* #undef HAVE_SYS_NDIR_H */ - -/* Define to 1 if you have the <sys/select.h> header file. */ -/* #undef HAVE_SYS_SELECT_H */ - -/* Define to 1 if you have the <sys/stat.h> header file. */ -/* #undef HAVE_SYS_STAT_H */ - -/* Define to 1 if you have the <sys/time.h> header file. */ -/* #undef HAVE_SYS_TIME_H */ - -/* Define to 1 if you have the <sys/types.h> header file. */ -/* #undef HAVE_SYS_TYPES_H */ - -/* Define to 1 if you have the <unistd.h> header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if unlink of file with open file descriptors will fail. */ -#define HAVE_UNLINK_WITH_OPEN_FAILURE 1 - -/* Define to 1 if building access method verification support. */ -#define HAVE_VERIFY 1 - -/* Define to 1 if you have the `vsnprintf' function. */ -/* #undef HAVE_VSNPRINTF */ - -/* Define to 1 if building VxWorks. */ -#define HAVE_VXWORKS 1 - -/* Define to 1 if you have the `yield' function. */ -/* #undef HAVE_YIELD */ - -/* Define to 1 if you have the `_fstati64' function. */ -/* #undef HAVE__FSTATI64 */ - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "support@sleepycat.com" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "Berkeley DB" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "Berkeley DB __EDIT_DB_VERSION__" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "db-__EDIT_DB_VERSION__" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "__EDIT_DB_VERSION__" - -/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */ -/* #undef STAT_MACROS_BROKEN */ - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ -/* #undef TIME_WITH_SYS_TIME */ - -/* Define to 1 to mask harmless uninitialized memory read/writes. */ -/* #undef UMRW */ - -/* Number of bits in a file offset, on hosts where this is settable. */ -/* #undef _FILE_OFFSET_BITS */ - -/* Define for large files, on AIX-style hosts. */ -/* #undef _LARGE_FILES */ - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - -/* - * Exit success/failure macros. - */ -#ifndef HAVE_EXIT_SUCCESS -#define EXIT_FAILURE 1 -#define EXIT_SUCCESS 0 -#endif - -/* - * Don't step on the namespace. Other libraries may have their own - * implementations of these functions, we don't want to use their - * implementations or force them to use ours based on the load order. - */ -#ifndef HAVE_GETCWD -#define getcwd __db_Cgetcwd -#endif -#ifndef HAVE_GETOPT -#define getopt __db_Cgetopt -#define optarg __db_Coptarg -#define opterr __db_Copterr -#define optind __db_Coptind -#define optopt __db_Coptopt -#endif -#ifndef HAVE_MEMCMP -#define memcmp __db_Cmemcmp -#endif -#ifndef HAVE_MEMCPY -#define memcpy __db_Cmemcpy -#endif -#ifndef HAVE_MEMMOVE -#define memmove __db_Cmemmove -#endif -#ifndef HAVE_RAISE -#define raise __db_Craise -#endif -#ifndef HAVE_SNPRINTF -#define snprintf __db_Csnprintf -#endif -#ifndef HAVE_STRCASECMP -#define strcasecmp __db_Cstrcasecmp -#define strncasecmp __db_Cstrncasecmp -#endif -#ifndef HAVE_STRERROR -#define strerror __db_Cstrerror -#endif -#ifndef HAVE_VSNPRINTF -#define vsnprintf __db_Cvsnprintf -#endif - -/* - * !!! - * The following is not part of the automatic configuration setup, but - * provides the information necessary to build Berkeley DB on VxWorks. - */ -#include "vxWorks.h" diff --git a/storage/bdb/dist/vx_setup/CONFIG.in b/storage/bdb/dist/vx_setup/CONFIG.in deleted file mode 100644 index 1fccd1d2ed6..00000000000 --- a/storage/bdb/dist/vx_setup/CONFIG.in +++ /dev/null @@ -1,10 +0,0 @@ -# -# Install configuration file. -# -# Note: This file may be modified during the pool manufacturing process to -# add additional configuration statements. This file is sourced by -# INSTW32.TCL. -# - -cdromDescSet "Berkeley DB @DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.@DB_VERSION_PATCH@" - diff --git a/storage/bdb/dist/vx_setup/LICENSE.TXT b/storage/bdb/dist/vx_setup/LICENSE.TXT deleted file mode 100644 index 812dce00d49..00000000000 --- a/storage/bdb/dist/vx_setup/LICENSE.TXT +++ /dev/null @@ -1,3 +0,0 @@ -Copyright (c) 1996-2005 - Sleepycat Software. All rights reserved. -See the file LICENSE for redistribution information. diff --git a/storage/bdb/dist/vx_setup/MESSAGES.TCL b/storage/bdb/dist/vx_setup/MESSAGES.TCL deleted file mode 100644 index 718a67fbc50..00000000000 --- a/storage/bdb/dist/vx_setup/MESSAGES.TCL +++ /dev/null @@ -1,651 +0,0 @@ -# MESSAGES.TCL - All setup strings. - -# modification history -# -------------------- -# 03q,20apr99,bjl added release notes message for backward compatibility -# page. -# 03p,12apr99,wmd Add word about simulator in message about the drivers -# object product. -# 03o,03mar99,tcy Adjust setup directory size based on platform (fix for -# SPR 25228) -# 03n,24feb99,tcy modified DLL update messages -# 03m,22feb99,tcy modified to align messages -# 03l,17feb99,tcy modified message in the finish page for program group -# installation -# 03k,11feb99,tcy added messages for backward compatibility page -# 03j,25jan99,tcy added messages from INSTW32.TCL -# 03i,25jan99,wmd Reword the message for 5010_DRIVERS_INFO. -# 03h,09dec98,bjl added messages about manufacturers updating patches. -# 03g,01dec98,wmd Fix typos. -# 03f,23nov98,tcy warn user to disable virus protection on Welcome screen -# 03e,19nov98,wmd fixed minor nits in wording. -# 03d,19nov98,bjl added web site locations for patchinfo. -# 03c,18nov98,bjl added formatted patch messages for patchinfo file. -# 03b,12nov98,tcy added message for not saving installation key -# 03a,10nov98,tcy added warning message for space in destination directory -# removed message for checking temporary disk space -# 02z,27oct98,bjl added recommended patch messages, modified required msg. -# 02y,26oct98,tcy added message for checking temporary disk space -# 02x,22oct98,wmd fix messages for clarity. -# 02w,21oct98,wmd fix message for drv/obj. -# 02v,20oct98,tcy added message for updating system and changed dcom message -# 02u,20oct98,bjl added tornado registry name entry message. -# 02t,19oct98,bjl added tornado registry description message. -# 02s,16oct98,wmd add new message for driver product warning. -# 02r,16oct98,wmd fixed README.TXT description. -# 02q,12oct98,tcy removed extraneous "the" from messages -# 02p,06oct98,tcy added CD description to Welcome page -# 02o,29sep98,bjl added required patches message 5000_PATCHES_TEXT. -# 02n,29sep98,wmd add text for readme page -# 02m,29sep98,tcy refined DLL registration page text -# 02l,29sep98,tcy changed message for DCOM -# 02k,26sep98,tcy added messages for DLL and DCOM pages -# 02j,24sep98,tcy removed "following" from 1080_WARN_4 message. -# 02i,17sep98,tcy added comment on size of SETUP files to 1140_COMP_SELECT. -# 02h,17sep98,wmd reword message 1080_WARN_4. -# 02g,14sep98,tcy changed 1210_FINISH and 1550_USAGE messages -# 02f,08sep98,tcy warn user library update may take several minutes -# 02e,01sep98,wmd reword message for installing over tree. -# added new messages for license agreement pages. -# 02d,20aug98,wmd added message for license agreeement. -# 02c,18aug98,tcy added message for zip-file dialog box -# 02d,04aug98,wmd added newer/older duplicate file warnings. -# 02c,24jul98,tcy added system check messages -# 02b,16jul98,wmd add new messages for T-2. -# 02a,22jul98,tcy moved license messages to LICW32.TCL; -# removed portMapper messages -# 01n,09feb98,pdn updated string 1080_WARN_4 -# 01m,08apr97,pdn added new string for remote icon installing -# fixed spr#8334 -# 01l,08mar97,tcy fixed language in string id 3340 -# 01k,07mar97,tcy added string id 3340 -# 01j,10feb97,pdn added more license messages. -# 01i,09feb97,pdn implemented variable argument list for strTableGet(), -# clean up. -# 01h,17jan97,jmo fixed language in strings -# 01g,12dec96,tcy merged in TEXT-only strings -# 01f,12dec96,pdn added 1080_WARN_4 string warning that CD-ROM -# revision is older than expected. -# 01e,27nov96,sj added string for warning against installing in -# the root of windows drive. -# 01d,18nov96,tcy added strings for text-based installation script -# 01c,14nov96,pdn substituted function for some global variables -# 01b,14nov96,sj added strings from Windows installation script -# 01a,11nov96,pdn written - -proc strTableGet {strId args} { - global strTable - global setupVals - global current_file - - if [regexp {^format.*$} $strTable($strId) junk] { - return [eval $strTable($strId)] - } { - return $strTable($strId) - } -} - -set strTable(1000_WELCOME_CD) \ - "format %s \"[cdNameGet description]\"" - -set strTable(1000_WELCOME1) \ - "format %s \"Welcome to the SETUP program. This program will\ - install \[cdromDescGet\] on your computer.\"" - -set strTable(1010_WELCOME2) \ - "It is strongly recommended that you exit all programs and disable virus\ - protection before running this SETUP program." - -set strTable(1020_WELCOME3) \ - "At any time, you can quit the SETUP program by clicking the <Cancel>\ - button. You also can go back to previous dialog boxes by clicking the\ - <Back> button. To accept the current settings for a dialog box and go on\ - with the installation process, click the <Next> button." - -set strTable(3020_WELCOME3) \ - "format %s \"At any prompt, you can cancel installation \[cdromDescGet\]\ - by typing \'exit\'. You can also go to the previous question\ - by typing \'-\'. To accept current settings and go on with\ - the installation process, press <Return>.\"" - -set strTable(1030_WELCOME4) \ - "WARNING: This program is protected by copyright law and international\ - treaties." - -set strTable(1040_WELCOME5) \ - "Unauthorized reproduction or distribution of this program, or any portion\ - of it, may result in severe civil and criminal penalties, and will be\ - prosecuted to the maximum extent possible under law." - -set strTable(1050_ROOT_WARN) \ - "format %s \"Installing \[cdromDescGet\] as \[setupId effective user\] is not\ - recommended. We suggest that you logoff and logon as a normal\ - user before running this program.\ - \n\nClick Next to continue with SETUP anyway.\"" - -set strTable(3050_ROOT_WARN) \ - "format %s \"Installing \[cdromDescGet\] as \[setupId effective user\]\ - is not recommended. We suggest that you logoff and \ - logon as a normal user before running this program.\ - \n\nPress <Return> to continue with SETUP anyway.\"" - -set strTable(1051_ROOT_WARN) \ - "format %s \"Installing \[cdromDescGet\] without System Administrator\ - privileges is not recommended. Under your present privileges,\ - SETUP will not offer certain installation options, such as \ - the installation of some services, etc. Also, the software\ - will be installed as a personal copy and will not be visible\ - to other users on this machine.\ - \n\nTo install \[cdromDescGet\] with access to all its\ - installation features and options, we suggest that you exit\ - the installation now and rerun it later with System\ - Administrator\'s privileges.\n\nClick <Next> to continue with\ - SETUP anyway.\"" - -set strTable(1060_REGISTRATION) \ - "Below, type your name, the name of your company." - -set strTable(1070_WARN_1) \ - "The installation key you entered is invalid. Please enter a valid\ - installation key." - -set strTable(1071_WARN_1) \ - "Please enter the requested information." - -set strTable(1080_WARN_2) \ - "You entered a key that was not created for this CD-ROM. Please verify\ - that you are using the appropriate key. If this problem persists, contact\ - Wind River Systems Sales department for help." - -set strTable(1080_WARN_3) \ - "The installation key you entered is meant for other vendor's CD-ROM.\ - Please contact the vendor who issued the CD-ROM for a proper key." - -set strTable(1085_WARN_4) \ - "This CD-ROM does not require an installation key. Click the \"Next\"\ - button to continue the installation." - -set strTable(1090_WARN_3) \ - "format %s \"Can\'t initiate SETUP: \[lindex \$args 0\]. Please correct\ - the problem then run SETUP again.\"" - -set strTable(1095_WARN_NO_TCPIP) \ - "SETUP has detected that your system does not have TCP-IP installed.\ - To correct the problem, please contact your administrator and then\ - run SETUP again.\nAborting setup." - -set strTable(1097_WARN_NO_LONGFILENAME_SUP) \ - "SETUP has detected that your system does not have long filename\ - support. To correct the problem, please contact your administrator\ - and then run SETUP again.\nAborting setup." - -set strTable(1105_FULL_INSTALL) \ - "Installs the Tornado products, tools, compilers, and other optional\ - components that you may have purchased." - -set strTable(1107_PROGRAM_GROUP) \ -"Installs only the Tornado program group and tools icons for access to\ - Tornado tools installed on a remote server." - -set strTable(1100_DEST_DIR) \ - "format %s \"Please type the name of the directory where you want SETUP to\ - install \[cdromDescGet\].\ - \n\nClick the <Browse> button to choose the directory\ - interactively.\"" - -set strTable(1100_REMOTE_DIR) \ - "format %s \"Please type the name of the directory where Tornado has\ - already been installed.\ - \n\nClick the <Browse> button to choose the directory\ - interactively.\"" - -set strTable(3100_DEST_DIR) \ - "format %s \"Please type the name of the directory where you want SETUP\ - to install \[cdromDescGet\].\"" - -set strTable(1110_DEST_DIR_WARN) \ - "The installation directory you entered does not exist.\ - \nDo you want to create it now?" - -set strTable(3110_DEST_DIR_WARN) \ - "The installation directory you entered does not exist." - -set strTable(3115_DEST_DIR_QUESTION) \ - "Do you want to create it now? \[y\]" - -set strTable(1111_DEST_DIR_WARN) \ - "format %s \"Installing \[cdromDescGet\] in the root directory is not\ - recommended.\nClick <Yes> to select another directory.\"" - -set strTable(1120_DEST_DIR_WARN2) \ - "format %s \"Creating \[destDirGet\] failed: file exists.\"" - -set strTable(1121_DEST_DIR_WARN2) \ - "format %s \"Installing in \[destDirGet\] is not recommended.\ - \nDo you want to change the installation directory?\"" - -set strTable(1122_DEST_DIR_WARN2) \ - "format %s \"Unable to create \[destDirGet\].\"" - -set strTable(1130_DEST_DIR_WARN3) \ - "You do not have permission to write files into the installation directory\ - you entered.\ - \n\nPlease choose a writable directory." - -set strTable(1135_DEST_DIR_WARN4) \ - "format %s \"The installation directory you entered contains white\ - space(s). Please select another directory.\"" - -set strTable(1137_DUP_PRODUCT_WARN) \ - "format %s \"Reinstalling products may potentially destroy any\ - modifications you may have made to previously installed files.\ - Do you wish to continue with the installation or go back to the\ - '\[strTableGet 1450_TITLE_OPTION\]' page to reconsider your choices?\"" - -set strTable(3155_COMP_SELECT_QUESTION) \ - "Do you want to go back and specify a directory on a bigger partition?\ - \[y\]" - -set strTable(1140_COMP_SELECT) \ - "format %s \"In the option list below, please check all items you wish\ - to install. SETUP files will be copied to your selected directory and\ - take up \[setupSizeGet\] MB of disk space.\n\"" - -set strTable(3140_COMP_SELECT) \ - "In the option list below, select the item(s) you want to install." - -set strTable(3145_COMP_SELECT_CHANGE) \ - "Press <Return> to accept the setting. To change the setting, enter a\ - list of item numbers separated by spaces." - -set strTable(3145_COMP_SELECT_CHANGE_INVALID) \ - "The item number(s) you entered is not valid." - -set strTable(1150_COMP_SELECT_WARN) \ - "There is not enough disk space to install the selected component(s).\ - \n\nDo you want to go back and specify a directory on a bigger disk or\ - partition?" - -set strTable(3150_COMP_SELECT_WARN) \ - "There is not enough space to install the selected component(s)." - -set strTable(1151_COMP_SELECT_WARN) \ - "At least one component must be selected to continue installation." - -set strTable(1160_PERMISSION) \ - "SETUP is about to install the component(s) you have requested.\ - \n\nThe selected button(s) below indicate the file permissions which\ - will be set during the installation process.\ - \n\nPlease adjust these to suit your site requirements." - -set strTable(3160_PERMISSION) \ - "SETUP is about to install the component(s) you have requested." - -set strTable(3162_PERMISSION) \ - "The list below indicates the file permissions which will be set during\ - the installation process. Please adjust these to suit your site\ - requirements." - -set strTable(3165_PERMISSION_QUESTION) \ - "Press <Return> to accept the setting. To change the setting, enter a\ - list of item numbers separated by spaces." - -set strTable(1161_FOLDER_SELECT) \ - "SETUP will add program icons to the Program Folder listed below. You may\ - type a new folder name, or select one from the existing Folders list." - -set strTable(1162_FOLDER_SELECT) \ - "Please enter a valid folder name." - -set strTable(1170_FILE_COPY) \ - "format %s \"SETUP is copying the selected component(s) to the directory\ - \[destDirGet\].\"" - -set strTable(1171_FILE_COPY) \ - "format %s \"SETUP cannot read \[setupFileNameGet 0\] from the CD-ROM.\ - Please ensure that the CD-ROM is properly mounted.\"" - -set strTable(1180_LIB_UPDATE) \ - "SETUP is updating the VxWorks libraries. We recommend that you let\ - SETUP finish this step, or the libraries will be in an inconsistent\ - state. Please be patient as the process may take several minutes. \ - If you want to quit the SETUP program, click <Cancel> and run\ - the SETUP program again at a later time." - -set strTable(3180_LIB_UPDATE) \ - "SETUP is updating the VxWorks libraries." - -set strTable(1190_REGISTRY_HOST) \ - "The Tornado Registry is a daemon that keeps track of all available\ - targets by name. Only one registry is required on your network, \ - and it can run on any networked host.\ - \n\nPlease enter the name of the host where the Tornado Registry will\ - be running." - -set strTable(1191_REGISTRY_DESC) \ - "The Tornado Registry is a daemon that keeps track of all available\ - targets by name. Only one registry is required on your network, \ - and it can run on any networked host." - -set strTable(1192_REGISTRY_NAME) \ - "Please enter the name of the host where the Tornado Registry will\ - be running." - -set strTable(1200_FINISH_WARN) \ - "format %s \"However, there were \[errorCountGet\] error(s) which occured\ - during the process. Please review the log file\ - \[destDirDispGet\]/setup.log for more information.\"" - -set strTable(1210_FINISH) \ - "format %s \"SETUP has completed installing the selected product(s).\"" - -set strTable(1212_FINISH) \ - "SETUP has completed installing the program folders and icons." - -set strTable(1213_FINISH) \ - "Terminating SETUP program." - -set strTable(1360_QUIT_CALLBACK) \ - "format %s \"SETUP is not complete. If you quit the SETUP program now,\ - \[cdromDescGet\] will not be installed.\n\nYou may run\ - the SETUP program at a later time to complete the\ - installation.\ - \n\nTo continue installing the program, click <Resume>. \ - To quit the SETUP program, click <Exit SETUP>.\"" - -set strTable(3360_QUIT_CALLBACK) \ - "format %s \"SETUP is not complete. If you quit the SETUP program now,\ - \[cdromDescGet\] will not be installed.\n\nYou may run the\ - SETUP program at a later time to complete the installation.\ - \n\nTo continue installing the program, Press <Return>. \ - To quit the SETUP program, type \'exit\'.\"" - -set strTable(1370_FILE_ACCESS_ERROR) \ - "format %s \"SETUP cannot create/update file \[lindex \$args 0\]:\ - \[lindex \$args 1\]\"" - -set strTable(1380_DEFLATE_ERROR) \ - "format %s \"SETUP isn\'t able to deflate \[setupFileNameGet 0\]\ - \n\nPlease select one of the following options\ - to continue with the SETUP process.\"" - -set strTable(1390_MEMORY_LOW) \ - "The system is running out of memory. To continue, close applications\ - or increase the system swap space." - -set strTable(1400_DISK_FULL) \ - "No disk space left. To continue, free up some disk space." - -set strTable(1550_USAGE) \ - "Usage: SETUP /I\[con\]\]\t\n\ - /I : Add standard Tornado icons \n\ - from a remote installation" - -set strTable(1410_TITLE_WELCOME) "Welcome" -set strTable(1420_TITLE_WARNING) "Warning" -set strTable(1430_TITLE_REGISTRATION) "User Registration" -set strTable(1440_TITLE_DESTDIR) "Select Directory" -set strTable(1450_TITLE_OPTION) "Select Products" -set strTable(1460_TITLE_PERMISSION) "Permission" -set strTable(1470_TITLE_FILECOPY) "Copying Files" -set strTable(1480_TITLE_LIBUPDATE) "Update Libraries" -set strTable(1490_TITLE_REGISTRY_HOST) "Tornado Registry" -set strTable(1495_TITLE_BACKWARD_COMPATIBILITY) "Backward Compatibility" -set strTable(1500_TITLE_FINISH) "Finish" -set strTable(1560_TITLE_FOLDER) "Select Folder" -set strTable(1563_TITLE_DLL_REG) "Software Registration" -set strTable(1567_TITLE_DCOM) "DCOM Installation" - -set strTable(1570_OPTION_SELECT) \ - "Choose one of the options listed below, then click the\ - <Next> button to continue the installation." - -set strTable(1576_OPTION_MANUAL) \ - "Install Tornado Registry manually" - -set strTable(1577_OPTION_STARTUP) \ - "Install Tornado Registry locally in the Startup Group" - -set strTable(1578_OPTION_SERVICE) \ - "Install Tornado Registry locally as a Service" - -set strTable(1579_OPTION_REMOTE) \ - "Configure to use a remote Tornado Registry" - -set strTable(1580_OPTION_DESC) \ - "If you plan on running Tornado in a non-networked environment, we\ - recommend that you install the registry in your Startup Group or as an\ - NT Service. For more information, consult your Tornado User\'s Guide." - -set strTable(1581_OPTION_DESC) \ - "If you plan on running Tornado in a non-networked environment, we\ - recommend that you install the registry in your Startup Group. For more\ - information, consult your Tornado User\'s Guide." - -set strTable(3000_RETURN_QUESTION) \ - "Press <Return> to continue" - -set strTable(3055_EXIT_QUESTION) \ - "Type \'exit\' to quit the program or press <Return> to continue" - -set strTable(3370_BACK_CALLBACK) \ - "Cannot go back further." - -set strTable(1080_WARN_4) \ - "The installation key you entered attempted to unlock one or more \ - products that may have been removed from our product line. \ - Please compare the unlocked product list on the\ - \"[strTableGet 1450_TITLE_OPTION]\" screen with your purchased order\ - list, and contact us if you discover any differences." - -set strTable(4000_BASE_INSTALL_WARN) \ - "format %s \"Warning! Re-installing Tornado over an existing \ - tree will overwrite any installed patches. \ - If you proceed with the installation, please \ - re-install patches if any.\"" - -set strTable(4000_BASE_INSTALL_WARN_1) \ - "Select <Install> to overwrite existing Tornado installation,\ - or choose <Select Path> to enable you to back up to the \'Select\ - Directory\' page to enter an alternate path." - -set strTable(4010_FILE_EXISTS_OLDER_WARN) \ - "format %s \"The file \'\$current_file\' exists in your destination\ - directory path \'\[destDirGet\]\' and is older. You can\ - set the policy for handling duplicate files by\ - selecting one of the following buttons. All files to be\ - overwritten will be backed up.\"" - -set strTable(4010_FILE_EXISTS_NEWER_WARN) \ - "format %s \"The file \'\$current_file\' exists in your destination\ - directory path \'\[destDirGet\]\' and is newer. You can\ - set the policy for handling duplicate files by\ - selecting one of the following buttons. All files to be\ - overwritten will be backed up.\"" - -set strTable(4010_FILE_EXISTS_WARN_1) \ - "Overwrite the existing file." - -set strTable(4010_FILE_EXISTS_WARN_2) \ - "Do not overwrite the existing file." - -set strTable(4010_FILE_EXISTS_WARN_3) \ - "Overwrite ALL files, do not show this dialog again." - -set strTable(4020_ANALYZING_BANNER) \ - "Analyzing installation files, please wait..." - -set strTable(4030_NO_ZIP_FILE) \ - "format %s \"SETUP cannot find the ZIP files for installing\ - \[cdromDescGet\] in the default directory.\n\n\ - Please type the name of the WIND\ - directory containing the ZIP files.\n\nClick the\ - <Browse> button to choose the directory interactively.\"" - -set strTable(4040_LIC_TEXT) \ - "Attention: By clicking on the \"I accept\" button or by\ - Installing the software you are consenting to be bound by\ - the terms of this agreement (this \"Agreement\"). If you do\ - not agree to all of the terms, click the \"I don't Accept\" button\ - and do not install this software. A copy of this Agreement can be viewed\ - in the Setup directory under the destination path that you have\ - designated after the installation is completed." - -set strTable(4050_PROJECT_TEXT) \ - "Please enter your project name, and the number of licensed\ - users on the project in the spaces below." - -set strTable(4060_LICENSE_TEXT) \ - "By clicking on the \"I accept\" button \ - you are consenting to be bound by the terms of this agreement.\ - If you do not agree to all of the terms, click the \"Cancel\"\ - button and do not install this software." - -set strTable(4070_DLL_TEXT) \ - "SETUP is registering software on your machine. This will take a few\ - minutes." - -set strTable(4080_DCOM_TEXT) \ - "Setup has detected that your COM/DCOM DLLs must\ - be updated for the correct operation of Tornado 2.0.\ - \n\n\ - Setup will now ask you to run DCOM95 to update your\ - DLLs.\ - \n\n\ - You will have to reboot your system after DLL files have been\ - installed. Please rerun SETUP to continue with installation\ - after your system has rebooted.\ - \n\n\ - Note: The DCOM95 installation programs update your\ - system DLLs. You should save all open documents and close all\ - programs before proceeding.\ - \n\nWould you like to install \"DCOM95\" now?" - -set strTable(4082_DCOM95_AND_COMCTL_TEXT) \ - "Setup has detected that your COM/DCOM and Common Control DLLs must\ - be updated for the correct operation of Tornado 2.0.\ - \n\n\ - Setup will now ask you to run DCOM95 and 401comupd.exe to update your\ - DLLs.\ - \n\n\ - You must reboot your system after DLL files have been\ - installed. After rebooting, please rerun SETUP to continue with\ - installation.\ - \n\n\ - Note: 401comupd.exe and DCOM95 installation programs update your\ - system DLLs. You should save all open documents and close all\ - programs before proceeding\ - \n\nWould you like to install \"401comupd.exe\" and \"DCOM95\" now?" - -set strTable(4085_COMCTL_UPDATE_TEXT) \ - "Setup has detected that your Common Control DLLs must\ - be updated for the correct operation of Tornado 2.0.\ - \n\n\ - Setup will now ask you to run DCOM95 and 401comupd.exe to update your\ - DLLs.\ - \n\n\ - You will have to reboot your system after DLL files have been\ - installed. Please rerun SETUP to continue with installation\ - after your system has rebooted.\ - \n\n\ - Note: The 401comupd.exe installation program updates your system DLLs. You\ - should save all open documents and close all programs before installing\ - 401comupd.exe.\ - \n\nWould you like to install \"401comupd.exe\" now?" - -set strTable(4090_README_TEXT) \ - "Please read the README file contents that are displayed below.\ - It contains important information that will enable you to install\ - and successfully run the BerkeleyDB product. For your convenience\ - this file is copied to your installation directory path." - -set strTable(5000_PATCHES_REQUIRED_TEXT) \ - "SETUP has detected that required operating system patches\ - have not been installed on this machine. These patches are\ - necessary for the correct operation of SETUP and Tornado. Please refer\ - to the Tornado Release Notes for details.\n\n\ - The following operating system patches must be installed before\ - you can continue with installation:\n\n" - -set strTable(5001_PATCHES_RECOMMENDED_TEXT) \ - "\n\nSETUP has also detected that recommended operating system patches\ - have not been installed. It is recommended that these patches are\ - installed before starting Tornado to ensure correct operation.\n\n\ - The following operating system patches are recommended to be installed:\n\n" - -set strTable(5002_PATCHES_RECOMMENDED_TEXT) \ - "SETUP has detected that some operating system patches have not been\ - installed on this machine. It is recommended that these\ - patches are installed before starting Tornado to ensure correct\ - operation. Please refer to the Tornado Release Notes\ - for details.\n\n\ - The following operating system patches are recommended to be installed:\n\n" - -set strTable(5003_PATCHES_REQUIRED_FORMATTED_TEXT) \ - "\n SETUP has detected that required operating system patches\n\ - have not been installed on this machine. These patches are\n\ - necessary for the correct operation of SETUP and Tornado. Please refer\n\ - to the Tornado Release Notes for details.\n\n\ - The following operating system patches must be installed before\n\ - you can continue with installation:\n\n" - -set strTable(5004_PATCHES_RECOMMENDED_FORMATTED_TEXT) \ - "\n\n SETUP has also detected that recommended operating system patches\n\ - have not been installed. It is recommended that these patches are\n\ - installed before starting Tornado to ensure correct operation.\n\n\ - The following operating system patches are recommended to be installed:\n\n" - -set strTable(5005_PATCHES_RECOMMENDED_FORMATTED_TEXT) \ - "\n SETUP has detected that some operating system patches have not been\n\ - installed on this machine. It is recommended that these\n\ - patches are installed before starting Tornado to ensure correct\n\ - operation. Please refer to the Tornado Release Notes\n\ - for details.\n\n\ - The following operating system patches are recommended to be installed:\n\n" - -set strTable(5006_PATCHES_SUN_LOCATION) \ - "\nPatches for Sun machines are available at http://sunsolve.sun.com.\n" - -set strTable(5007_PATCHES_HP_LOCATION) \ - "\nPatches for HP machines are available at:\n\ - http://us-support.external.hp.com (US, Canada, Asia-Pacific, and\ - Latin-America)\n\ - http://europe-support.external.hp.com (Europe)\n" - -set strTable(5008_PATCHES_UPDATE) \ - "\nNote: System vendors very frequently update and replace patches.\ - If a specific patch is no longer available, please use the\ - replacement patch suggested by the system vendor.\n" - -set strTable(5009_PATCHES_UPDATE_FORMATTED) \ - "\n Note: System vendors very frequently update and replace patches.\n\ - If a specific patch is no longer available, please use the\n\ - replacement patch suggested by the system vendor.\n" - -set strTable(5010_DRIVERS_INFO) \ - "The installation of the Driver component is required because\n\ - you have selected the basic Tornado product for installation.\n\n\ - If you wish to uncheck this item you must uncheck either the\n\ - basic Tornado and/or Tornado Simulator product(s) or go to the\n\ - 'Details' button for Tornado and uncheck both the Simulator and\n\ - the Tornado Object parts." - -set strTable(5020_DO_NOT_SAVE_KEY_FOR_FAE) \ - "The installation key you are about to enter will NOT\ - be saved in the system registry.\nIs this what you want?" - -set strTable(5030_BACKWARD_COMPATIBILITY) \ - "While the portmapper is not needed for Tornado 2.0, it is\ - included in this release for development environments in\ - which both Tornado 2.0 and Tornado 1.0.1 are in use.\ - \n\nWould you like to use your Tornado 1.0.x tools with Tornado 2.0?" - -set strTable(5040_BACKWARD_COMPATIBILITY) \ - "Note:\ - \n\nIf you have selected to install the Tornado Registry as\ - a service, there is no way to retain backward compatibility\ - with Tornado 1.0.x." - -set strTable(5050_BACKWARD_COMPATIBILITY) \ - "For more information on backward compatibility,\ - please consult the Tornado 2.0 Release Notes." diff --git a/storage/bdb/dist/vx_setup/README.in b/storage/bdb/dist/vx_setup/README.in deleted file mode 100644 index f96948c37ba..00000000000 --- a/storage/bdb/dist/vx_setup/README.in +++ /dev/null @@ -1,7 +0,0 @@ -README.TXT: Sleepycat Software Berkeley DB @DB_VERSION_MAJOR@.@DB_VERSION_MINOR@ Release v@DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.@DB_VERSION_PATCH@ - -Information on known problems, changes introduced with the -current revision of the CD-ROM, and other product bulletins -can be obtained from the Sleepycat Software web site: - - http://www.sleepycat.com/ diff --git a/storage/bdb/dist/vx_setup/SETUP.BMP b/storage/bdb/dist/vx_setup/SETUP.BMP Binary files differdeleted file mode 100644 index 2918480b8c2..00000000000 --- a/storage/bdb/dist/vx_setup/SETUP.BMP +++ /dev/null diff --git a/storage/bdb/dist/vx_setup/vx_allfile.in b/storage/bdb/dist/vx_setup/vx_allfile.in deleted file mode 100644 index 8d87fa97b59..00000000000 --- a/storage/bdb/dist/vx_setup/vx_allfile.in +++ /dev/null @@ -1,7 +0,0 @@ -windlink/sleepycat/BerkeleyDB.@DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.@DB_VERSION_PATCH@/build_vxworks/BerkeleyDB20.wpj -windlink/sleepycat/BerkeleyDB.@DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.@DB_VERSION_PATCH@/build_vxworks/BerkeleyDB20.wsp -windlink/sleepycat/BerkeleyDB.@DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.@DB_VERSION_PATCH@/build_vxworks/BerkeleyDB20.wpj -windlink/sleepycat/BerkeleyDB.@DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.@DB_VERSION_PATCH@/build_vxworks/BerkeleyDB22.wsp -windlink/sleepycat/BerkeleyDB.@DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.@DB_VERSION_PATCH@/build_vxworks/db.h -windlink/sleepycat/BerkeleyDB.@DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.@DB_VERSION_PATCH@/build_vxworks/db_config.h -windlink/sleepycat/BerkeleyDB.@DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.@DB_VERSION_PATCH@/build_vxworks/db_int.h diff --git a/storage/bdb/dist/vx_setup/vx_demofile.in b/storage/bdb/dist/vx_setup/vx_demofile.in deleted file mode 100644 index 772f4cb4bc0..00000000000 --- a/storage/bdb/dist/vx_setup/vx_demofile.in +++ /dev/null @@ -1,4 +0,0 @@ -windlink/sleepycat/BerkeleyDB.@DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.@DB_VERSION_PATCH@/build_vxworks/dbdemo/dbdemo20.wpj -windlink/sleepycat/BerkeleyDB.@DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.@DB_VERSION_PATCH@/build_vxworks/dbdemo/dbdemo22.wpj -windlink/sleepycat/BerkeleyDB.@DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.@DB_VERSION_PATCH@/build_vxworks/dbdemo/README -windlink/sleepycat/BerkeleyDB.@DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.@DB_VERSION_PATCH@/build_vxworks/dbdemo/dbdemo.c diff --git a/storage/bdb/dist/vx_setup/vx_setup.in b/storage/bdb/dist/vx_setup/vx_setup.in deleted file mode 100644 index 7bc3f510cfa..00000000000 --- a/storage/bdb/dist/vx_setup/vx_setup.in +++ /dev/null @@ -1,13 +0,0 @@ -Sleepycat Software BerkeleyDB @DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.@DB_VERSION_PATCH@ -db@DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.@DB_VERSION_PATCH@ demo-db@DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.@DB_VERSION_PATCH@ -BerkeleyDB.@DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.@DB_VERSION_PATCH@ -@DB_SETUP_DIR@ -Sleepycat Software BerkeleyDB @DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.@DB_VERSION_PATCH@ -db@DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.@DB_VERSION_PATCH@ -@DB_SETUP_DIR@/filelist.all -BerkeleyDB.@DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.@DB_VERSION_PATCH@-Demo -@DB_SETUP_DIR@ -BerkeleyDB @DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.@DB_VERSION_PATCH@ Demo program -demo-db@DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.@DB_VERSION_PATCH@ -@DB_SETUP_DIR@/filelist.demo -Sleepycat Software BerkeleyDB @DB_VERSION_MAJOR@.@DB_VERSION_MINOR@.@DB_VERSION_PATCH@ diff --git a/storage/bdb/dist/win_config.in b/storage/bdb/dist/win_config.in deleted file mode 100644 index 56814d115c2..00000000000 --- a/storage/bdb/dist/win_config.in +++ /dev/null @@ -1,451 +0,0 @@ -/* Define to 1 if you want to build a version for running the test suite. */ -/* #undef CONFIG_TEST */ - -/* We use DB_WIN32 much as one would use _WIN32 -- to specify that we're using - an operating system environment that supports Win32 calls and semantics. We - don't use _WIN32 because Cygwin/GCC also defines _WIN32, even though - Cygwin/GCC closely emulates the Unix environment. */ -#define DB_WIN32 1 - -/* Define to 1 if you want a debugging version. */ -/* #undef DEBUG */ -#if defined(_DEBUG) -#if !defined(DEBUG) -#define DEBUG 1 -#endif -#endif - -/* Define to 1 if you want a version that logs read operations. */ -/* #undef DEBUG_ROP */ - -/* Define to 1 if you want a version that logs write operations. */ -/* #undef DEBUG_WOP */ - -/* Define to 1 if you want a version with run-time diagnostic checking. */ -/* #undef DIAGNOSTIC */ - -/* Define to 1 if 64-bit types are available. */ -#define HAVE_64BIT_TYPES 1 - -/* Define to 1 if you have the `clock_gettime' function. */ -/* #undef HAVE_CLOCK_GETTIME */ - -/* Define to 1 if Berkeley DB release includes strong cryptography. */ -#ifndef HAVE_SMALLBUILD -#define HAVE_CRYPTO 1 -#endif - -/* Define to 1 if you have the `directio' function. */ -/* #undef HAVE_DIRECTIO */ - -/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'. - */ -/* #undef HAVE_DIRENT_H */ - -/* Define to 1 if you have the <dlfcn.h> header file. */ -/* #undef HAVE_DLFCN_H */ - -/* Define to 1 if you have EXIT_SUCCESS/EXIT_FAILURE #defines. */ -#define HAVE_EXIT_SUCCESS 1 - -/* Define to 1 if you have the `fchmod' function. */ -/* #undef HAVE_FCHMOD */ - -/* Define to 1 if you have the `fcntl' function. */ -/* #undef HAVE_FCNTL */ - -/* Define to 1 if fcntl/F_SETFD denies child access to file descriptors. */ -/* #undef HAVE_FCNTL_F_SETFD */ - -/* Define to 1 if you have the `fdatasync' function. */ -/* #undef HAVE_FDATASYNC */ - -/* Define to 1 if allocated filesystem blocks are not zeroed. */ -#define HAVE_FILESYSTEM_NOTZERO 1 - -/* Define to 1 if you have the `ftruncate' function. */ -#define HAVE_FTRUNCATE 1 - -/* Define to 1 if you have the `getcwd' function. */ -#define HAVE_GETCWD 1 - -/* Define to 1 if you have the `getopt' function. */ -/* #undef HAVE_GETOPT */ - -/* Define to 1 if you have the `getrusage' function. */ -/* #undef HAVE_GETRUSAGE */ - -/* Define to 1 if you have the `gettimeofday' function. */ -/* #undef HAVE_GETTIMEOFDAY */ - -/* Define to 1 if you have the `getuid' function. */ -/* #undef HAVE_GETUID */ - -/* Define to 1 if building Hash access method. */ -#ifndef HAVE_SMALLBUILD -#define HAVE_HASH 1 -#endif - -/* Define to 1 if thread identifier type db_threadid_t is integral. */ -#define HAVE_INTEGRAL_THREAD_TYPE 1 - -/* Define to 1 if you have the <inttypes.h> header file. */ -/* #undef HAVE_INTTYPES_H */ - -/* Define to 1 if you have the `nsl' library (-lnsl). */ -/* #undef HAVE_LIBNSL */ - -/* Define to 1 if you have the `memcmp' function. */ -#define HAVE_MEMCMP 1 - -/* Define to 1 if you have the `memcpy' function. */ -#define HAVE_MEMCPY 1 - -/* Define to 1 if you have the `memmove' function. */ -#define HAVE_MEMMOVE 1 - -/* Define to 1 if you have the <memory.h> header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the `mlock' function. */ -/* #undef HAVE_MLOCK */ - -/* Define to 1 if you have the `mmap' function. */ -/* #undef HAVE_MMAP */ - -/* Define to 1 if you have the `munlock' function. */ -/* #undef HAVE_MUNLOCK */ - -/* Define to 1 if you have the `munmap' function. */ -/* #undef HAVE_MUNMAP */ - -/* Define to 1 to use the GCC compiler and 68K assembly language mutexes. */ -/* #undef HAVE_MUTEX_68K_GCC_ASSEMBLY */ - -/* Define to 1 to use the AIX _check_lock mutexes. */ -/* #undef HAVE_MUTEX_AIX_CHECK_LOCK */ - -/* Define to 1 to use the GCC compiler and Alpha assembly language mutexes. */ -/* #undef HAVE_MUTEX_ALPHA_GCC_ASSEMBLY */ - -/* Define to 1 to use the GCC compiler and ARM assembly language mutexes. */ -/* #undef HAVE_MUTEX_ARM_GCC_ASSEMBLY */ - -/* Define to 1 to use the Apple/Darwin _spin_lock_try mutexes. */ -/* #undef HAVE_MUTEX_DARWIN_SPIN_LOCK_TRY */ - -/* Define to 1 to use the UNIX fcntl system call mutexes. */ -/* #undef HAVE_MUTEX_FCNTL */ - -/* Define to 1 to use the GCC compiler and PaRisc assembly language mutexes. - */ -/* #undef HAVE_MUTEX_HPPA_GCC_ASSEMBLY */ - -/* Define to 1 to use the msem_XXX mutexes on HP-UX. */ -/* #undef HAVE_MUTEX_HPPA_MSEM_INIT */ - -/* Define to 1 to use the GCC compiler and IA64 assembly language mutexes. */ -/* #undef HAVE_MUTEX_IA64_GCC_ASSEMBLY */ - -/* Define to 1 to use the GCC compiler and MIPS assembly language mutexes. */ -/* #undef HAVE_MUTEX_MIPS_GCC_ASSEMBLY */ - -/* Define to 1 to use the msem_XXX mutexes on systems other than HP-UX. */ -/* #undef HAVE_MUTEX_MSEM_INIT */ - -/* Define to 1 to use the GCC compiler and PowerPC assembly language mutexes. - */ -/* #undef HAVE_MUTEX_PPC_GCC_ASSEMBLY */ - -/* Define to 1 to use POSIX 1003.1 pthread_XXX mutexes. */ -/* #undef HAVE_MUTEX_PTHREADS */ - -/* Define to 1 to use Reliant UNIX initspin mutexes. */ -/* #undef HAVE_MUTEX_RELIANTUNIX_INITSPIN */ - -/* Define to 1 to use the IBM C compiler and S/390 assembly language mutexes. - */ -/* #undef HAVE_MUTEX_S390_CC_ASSEMBLY */ - -/* Define to 1 to use the GCC compiler and S/390 assembly language mutexes. */ -/* #undef HAVE_MUTEX_S390_GCC_ASSEMBLY */ - -/* Define to 1 to use the SCO compiler and x86 assembly language mutexes. */ -/* #undef HAVE_MUTEX_SCO_X86_CC_ASSEMBLY */ - -/* Define to 1 to use the obsolete POSIX 1003.1 sema_XXX mutexes. */ -/* #undef HAVE_MUTEX_SEMA_INIT */ - -/* Define to 1 to use the SGI XXX_lock mutexes. */ -/* #undef HAVE_MUTEX_SGI_INIT_LOCK */ - -/* Define to 1 to use the Solaris _lock_XXX mutexes. */ -/* #undef HAVE_MUTEX_SOLARIS_LOCK_TRY */ - -/* Define to 1 to use the Solaris lwp threads mutexes. */ -/* #undef HAVE_MUTEX_SOLARIS_LWP */ - -/* Define to 1 to use the GCC compiler and Sparc assembly language mutexes. */ -/* #undef HAVE_MUTEX_SPARC_GCC_ASSEMBLY */ - -/* Define to 1 if mutexes hold system resources. */ -/* #undef HAVE_MUTEX_SYSTEM_RESOURCES */ - -/* Define to 1 to configure mutexes intra-process only. */ -/* #undef HAVE_MUTEX_THREAD_ONLY */ - -/* Define to 1 to use the CC compiler and Tru64 assembly language mutexes. */ -/* #undef HAVE_MUTEX_TRU64_CC_ASSEMBLY */ - -/* Define to 1 to use the UNIX International mutexes. */ -/* #undef HAVE_MUTEX_UI_THREADS */ - -/* Define to 1 to use the UTS compiler and assembly language mutexes. */ -/* #undef HAVE_MUTEX_UTS_CC_ASSEMBLY */ - -/* Define to 1 to use VMS mutexes. */ -/* #undef HAVE_MUTEX_VMS */ - -/* Define to 1 to use VxWorks mutexes. */ -/* #undef HAVE_MUTEX_VXWORKS */ - -/* Define to 1 to use the MSVC compiler and Windows mutexes. */ -#define HAVE_MUTEX_WIN32 1 - -/* Define to 1 to use the GCC compiler and Windows mutexes. */ -/* #undef HAVE_MUTEX_WIN32_GCC */ - -/* Define to 1 to use the GCC compiler and amd64 assembly language mutexes. */ -/* #undef HAVE_MUTEX_X86_64_GCC_ASSEMBLY */ - -/* Define to 1 to use the GCC compiler and x86 assembly language mutexes. */ -/* #undef HAVE_MUTEX_X86_GCC_ASSEMBLY */ - -/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */ -/* #undef HAVE_NDIR_H */ - -/* Define to 1 if you have the O_DIRECT flag. */ -/* #undef HAVE_O_DIRECT */ - -/* Define to 1 if you have the `pread' function. */ -/* #undef HAVE_PREAD */ - -/* Define to 1 if you have the `pstat_getdynamic' function. */ -/* #undef HAVE_PSTAT_GETDYNAMIC */ - -/* Define to 1 if you have the `pthread_self' function. */ -/* #undef HAVE_PTHREAD_SELF */ - -/* Define to 1 if you have the `pwrite' function. */ -/* #undef HAVE_PWRITE */ - -/* Define to 1 if building on QNX. */ -/* #undef HAVE_QNX */ - -/* Define to 1 if building Queue access method. */ -#ifndef HAVE_SMALLBUILD -#define HAVE_QUEUE 1 -#endif - -/* Define to 1 if you have the `raise' function. */ -#define HAVE_RAISE 1 - -/* Define to 1 if you have the `rand' function. */ -#define HAVE_RAND 1 - -/* Define to 1 if building replication support. */ -#ifndef HAVE_SMALLBUILD -#define HAVE_REPLICATION 1 -#endif - -/* Define to 1 if building RPC client/server. */ -/* #undef HAVE_RPC */ - -/* Define to 1 if you have the `sched_yield' function. */ -/* #undef HAVE_SCHED_YIELD */ - -/* Define to 1 if you have the `select' function. */ -/* #undef HAVE_SELECT */ - -/* Define to 1 if building sequence support. */ -#define HAVE_SEQUENCE 1 - -/* Define to 1 if you have the `shmget' function. */ -/* #undef HAVE_SHMGET */ - -/* Define to 1 if you have the `snprintf' function. */ -#define HAVE_SNPRINTF 1 - -/* Define to 1 if you have the `srand' function. */ -#define HAVE_SRAND 1 - -/* Define to 1 if building statistics support. */ -#define HAVE_STATISTICS 1 - -/* Define to 1 if you have the <stdint.h> header file. */ -/* #undef HAVE_STDINT_H */ - -/* Define to 1 if you have the <stdlib.h> header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the `strcasecmp' function. */ -/* #undef HAVE_STRCASECMP */ - -/* Define to 1 if you have the `strdup' function. */ -#define HAVE_STRDUP 1 - -/* Define to 1 if you have the `strerror' function. */ -#define HAVE_STRERROR 1 - -/* Define to 1 if you have the <strings.h> header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the <string.h> header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the `strtol' function. */ -#define HAVE_STRTOL 1 - -/* Define to 1 if you have the `strtoul' function. */ -#define HAVE_STRTOUL 1 - -/* Define to 1 if `st_blksize' is member of `struct stat'. */ -/* #undef HAVE_STRUCT_STAT_ST_BLKSIZE */ - -/* Define to 1 if you have the `sysconf' function. */ -/* #undef HAVE_SYSCONF */ - -/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'. - */ -/* #undef HAVE_SYS_DIR_H */ - -/* Define to 1 if you have the <sys/fcntl.h> header file. */ -#define HAVE_SYS_FCNTL_H 1 - -/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'. - */ -/* #undef HAVE_SYS_NDIR_H */ - -/* Define to 1 if you have the <sys/select.h> header file. */ -/* #undef HAVE_SYS_SELECT_H */ - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the <sys/time.h> header file. */ -/* #undef HAVE_SYS_TIME_H */ - -/* Define to 1 if you have the <sys/types.h> header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the <unistd.h> header file. */ -/* #undef HAVE_UNISTD_H */ - -/* Define to 1 if unlink of file with open file descriptors will fail. */ -/* #undef HAVE_UNLINK_WITH_OPEN_FAILURE */ - -/* Define to 1 if building access method verification support. */ -#ifndef HAVE_SMALLBUILD -#define HAVE_VERIFY 1 -#endif - -/* Define to 1 if you have the `vsnprintf' function. */ -#define HAVE_VSNPRINTF 1 - -/* Define to 1 if building VxWorks. */ -/* #undef HAVE_VXWORKS */ - -/* Define to 1 if you have the `yield' function. */ -/* #undef HAVE_YIELD */ - -/* Define to 1 if you have the `_fstati64' function. */ -#define HAVE__FSTATI64 1 - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "support@sleepycat.com" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "Berkeley DB" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "Berkeley DB __EDIT_DB_VERSION__" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "db-__EDIT_DB_VERSION__" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "__EDIT_DB_VERSION__" - -/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */ -/* #undef STAT_MACROS_BROKEN */ - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ -/* #undef TIME_WITH_SYS_TIME */ - -/* Define to 1 to mask harmless uninitialized memory read/writes. */ -/* #undef UMRW */ - -/* Number of bits in a file offset, on hosts where this is settable. */ -/* #undef _FILE_OFFSET_BITS */ - -/* Define for large files, on AIX-style hosts. */ -/* #undef _LARGE_FILES */ - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - -/* - * Exit success/failure macros. - */ -#ifndef HAVE_EXIT_SUCCESS -#define EXIT_FAILURE 1 -#define EXIT_SUCCESS 0 -#endif - -/* - * Don't step on the namespace. Other libraries may have their own - * implementations of these functions, we don't want to use their - * implementations or force them to use ours based on the load order. - */ -#ifndef HAVE_GETCWD -#define getcwd __db_Cgetcwd -#endif -#ifndef HAVE_MEMCMP -#define memcmp __db_Cmemcmp -#endif -#ifndef HAVE_MEMCPY -#define memcpy __db_Cmemcpy -#endif -#ifndef HAVE_MEMMOVE -#define memmove __db_Cmemmove -#endif -#ifndef HAVE_RAISE -#define raise __db_Craise -#endif -#ifndef HAVE_SNPRINTF -#define snprintf __db_Csnprintf -#endif -#ifndef HAVE_STRCASECMP -#define strcasecmp __db_Cstrcasecmp -#define strncasecmp __db_Cstrncasecmp -#endif -#ifndef HAVE_STRERROR -#define strerror __db_Cstrerror -#endif -#ifndef HAVE_VSNPRINTF -#define vsnprintf __db_Cvsnprintf -#endif - -#include "win_db.h" - -/* - * Microsoft's compiler _doesn't_ define __STDC__ unless you invoke it with - * arguments turning OFF all vendor extensions. Even more unfortunately, if - * we do that, it fails to parse windows.h!!!!! So, we define __STDC__ here, - * after windows.h comes in. Note: the compiler knows we've defined it, and - * starts enforcing strict ANSI compliance from this point on. - */ -#define __STDC__ 1 diff --git a/storage/bdb/dist/win_db.in b/storage/bdb/dist/win_db.in deleted file mode 100644 index 433eaa6c09f..00000000000 --- a/storage/bdb/dist/win_db.in +++ /dev/null @@ -1,120 +0,0 @@ -/*- - * $Id: win_db.in,v 12.7 2005/11/02 03:12:17 mjc Exp $ - * - * The following provides the information necessary to build Berkeley - * DB on native Windows, and other Windows environments such as MinGW. - */ - -/* - * Avoid warnings with Visual Studio 8. - */ -#define _CRT_SECURE_NO_DEPRECATE 1 - -#include <sys/types.h> -#include <sys/stat.h> - -#include <direct.h> -#include <fcntl.h> -#include <io.h> -#include <limits.h> -#include <memory.h> -#include <process.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <tchar.h> -#include <time.h> -#include <errno.h> - -/* - * To build Tcl interface libraries, the include path must be configured to - * use the directory containing <tcl.h>, usually the include directory in - * the Tcl distribution. - */ -#ifdef DB_TCL_SUPPORT -#include <tcl.h> -#endif - -#define WIN32_LEAN_AND_MEAN -#include <windows.h> - -/* - * All of the necessary includes have been included, ignore the #includes - * in the Berkeley DB source files. - */ -#define NO_SYSTEM_INCLUDES - -/* - * Microsoft's C runtime library has fsync, getcwd, getpid, snprintf and - * vsnprintf, but under different names. - */ -#define fsync _commit -#define getcwd(buf, size) _getcwd(buf, size) -#define getpid _getpid -#define snprintf _snprintf -#define vsnprintf _vsnprintf - -/* - * Windows defines off_t to long (i.e., 32 bits). - */ -#define off_t __db_off_t -typedef __int64 off_t; - -/* - * Win32 does not define getopt and friends in any header file, so we must. - */ -#if defined(__cplusplus) -extern "C" { -#endif -extern int optind; -extern char *optarg; -extern int getopt(int, char * const *, const char *); -#if defined(__cplusplus) -} -#endif - -#ifdef _UNICODE -#define TO_TSTRING(dbenv, s, ts, ret) do { \ - int __len = (int)strlen(s) + 1; \ - ts = NULL; \ - if ((ret = __os_malloc((dbenv), \ - __len * sizeof (_TCHAR), &(ts))) == 0 && \ - MultiByteToWideChar(CP_UTF8, 0, \ - (s), -1, (ts), __len) == 0) \ - ret = __os_get_errno(); \ - } while (0) - -#define FROM_TSTRING(dbenv, ts, s, ret) { \ - int __len = WideCharToMultiByte(CP_UTF8, 0, ts, -1, \ - NULL, 0, NULL, NULL); \ - s = NULL; \ - if ((ret = __os_malloc((dbenv), __len, &(s))) == 0 && \ - WideCharToMultiByte(CP_UTF8, 0, \ - (ts), -1, (s), __len, NULL, NULL) == 0) \ - ret = __os_get_errno(); \ - } while (0) - -#define FREE_STRING(dbenv, s) do { \ - if ((s) != NULL) { \ - __os_free((dbenv), (s)); \ - (s) = NULL; \ - } \ - } while (0) - -#else -#define TO_TSTRING(dbenv, s, ts, ret) (ret) = 0, (ts) = (_TCHAR *)(s) -#define FROM_TSTRING(dbenv, ts, s, ret) (ret) = 0, (s) = (char *)(ts) -#define FREE_STRING(dbenv, ts) -#endif - -#ifndef INVALID_HANDLE_VALUE -#define INVALID_HANDLE_VALUE ((HANDLE)-1) -#endif - -#ifndef INVALID_FILE_ATTRIBUTES -#define INVALID_FILE_ATTRIBUTES ((DWORD)-1) -#endif - -#ifndef INVALID_SET_FILE_POINTER -#define INVALID_SET_FILE_POINTER ((DWORD)-1) -#endif diff --git a/storage/bdb/dist/win_exports.in b/storage/bdb/dist/win_exports.in deleted file mode 100644 index 8aa6be789a2..00000000000 --- a/storage/bdb/dist/win_exports.in +++ /dev/null @@ -1,191 +0,0 @@ -# $Id: win_exports.in,v 12.12 2005/10/14 06:19:27 mjc Exp $ - -# Standard interfaces. - db_create - db_env_create - db_sequence_create - db_strerror - db_version - db_xa_switch - log_compare - -# Library configuration interfaces. - db_env_set_func_close - db_env_set_func_dirfree - db_env_set_func_dirlist - db_env_set_func_exists - db_env_set_func_free - db_env_set_func_fsync - db_env_set_func_ftruncate - db_env_set_func_ioinfo - db_env_set_func_malloc - db_env_set_func_map - db_env_set_func_open - db_env_set_func_pread - db_env_set_func_pwrite - db_env_set_func_read - db_env_set_func_realloc - db_env_set_func_rename - db_env_set_func_seek - db_env_set_func_sleep - db_env_set_func_unlink - db_env_set_func_unmap - db_env_set_func_write - db_env_set_func_yield - -# Needed for application-specific logging and recovery routines. - __db_add_recovery - -# These are needed to link the tcl library. - __db_dbm_close - __db_dbm_delete - __db_dbm_fetch - __db_dbm_firstkey - __db_dbm_init - __db_dbm_nextkey - __db_dbm_store - __db_get_flags_fn - __db_get_seq_flags_fn - __db_hcreate - __db_hdestroy - __db_hsearch - __db_loadme - __db_ndbm_clearerr - __db_ndbm_close - __db_ndbm_delete - __db_ndbm_dirfno - __db_ndbm_error - __db_ndbm_fetch - __db_ndbm_firstkey - __db_ndbm_nextkey - __db_ndbm_open - __db_ndbm_pagfno - __db_ndbm_rdonly - __db_ndbm_store - __db_panic - __db_r_attach - __db_r_detach - __ham_func2 - __ham_func3 - __ham_func4 - __ham_func5 - __ham_test - __lock_id_set - __os_calloc - __os_closehandle - __os_dirfree - __os_dirlist - __os_free - __os_ioinfo - __os_malloc - __os_mkdir - __os_open - __os_openhandle - __os_read - __os_realloc - __os_strdup - __os_umalloc - __os_unlink - __os_write - __txn_id_set - -# These are needed for linking tools or java. - __bam_adj_read - __bam_cadjust_read - __bam_cdel_read - __bam_curadj_read - __bam_merge_read - __bam_pgin - __bam_pgno_read - __bam_pgout - __bam_rcuradj_read - __bam_relink_read - __bam_repl_read - __bam_root_read - __bam_rsplit_read - __bam_split_read - __crdel_metasub_read - __crdel_inmem_create_read - __crdel_inmem_rename_read - __crdel_inmem_remove_read - __db_addrem_read - __db_big_read - __db_cksum_read - __db_debug_read - __db_dispatch - __db_dl - __db_dumptree - __db_err - __db_getlong - __db_getulong - __db_global_values - __db_isbigendian - __db_msg - __db_noop_read - __db_omode - __db_ovref_read - __db_pg_alloc_read - __db_pg_free_read - __db_pg_freedata_read - __db_pg_init_read - __db_pg_new_read - __db_pg_prepare_read - __db_pg_sort_read - __db_pgin - __db_pgout - __db_pr_callback - __db_rpath - __db_stat_pp - __db_stat_print_pp - __db_util_cache - __db_util_interrupted - __db_util_logset - __db_util_siginit - __db_util_sigresend - __db_verify_internal - __dbreg_register_read - __fop_create_read - __fop_file_remove_read - __fop_remove_read - __fop_rename_read - __fop_write_read - __ham_chgpg_read - __ham_copypage_read - __ham_curadj_read - __ham_get_meta - __ham_groupalloc_read - __ham_insdel_read - __ham_metagroup_read - __ham_newpage_read - __ham_pgin - __ham_pgout - __ham_release_meta - __ham_replace_read - __ham_splitdata_read - __lock_list_print - __log_stat_pp - __mutex_set_wait_info - __os_clock - __os_exists - __os_get_errno - __os_id - __os_mapfile - __os_seek - __os_set_errno - __os_sleep - __os_spin - __os_ufree - __os_unmapfile - __os_yield - __qam_add_read - __qam_del_read - __qam_delext_read - __qam_incfirst_read - __qam_mvptr_read - __qam_pgin_out - __rep_stat_print - __txn_child_read - __txn_ckp_read - __txn_recycle_read - __txn_regop_read - __txn_xa_regop_read diff --git a/storage/bdb/dist/winmsi/dbcorewix.in b/storage/bdb/dist/winmsi/dbcorewix.in deleted file mode 100644 index 03635177de0..00000000000 --- a/storage/bdb/dist/winmsi/dbcorewix.in +++ /dev/null @@ -1,196 +0,0 @@ -<!-- $Id: dbcorewix.in,v 1.8 2005/04/18 18:40:27 philipr Exp $ - - - - Dbcorewix.in is the DB core WiX input file, and is used by - - s_winmsi to create dbcore.wxs (an input to WiX). - - Most everything here is pure 'WiX' syntax within XML, - - the exceptions are: - - 1) everything is pushed through the m4 preprocessor first. - - this makes certain boilerplate actions in the UI tolerable. - - We put all needed defines at the top of this file. - - 2) a very few identifiers beginning with WIX_DB_* - - are predefined as m4 macros on the command line. - - These are items that only the caller (s_winmsi) can know. - - - - M4 makes many things easier, but there are peculiarities. - - In particular, if you are using a macro with args, like - - TOPSTRIPE, note that *any* occurance of the characters "( ) ," - - are interpreted by m4, even if they occur in an Xml comment or string. - - Remember this when editing this file! - - - - Beyond that, there is a lot to understand about WiX - - and how this file operates, to get started, look at - - various WiX tutorials, like: - - http://www.ondotnet.com/pub/a/dotnet/2004/04/19/wix.html - - http://blogs.msdn.com/robmen/archive/2004/04/05/107709.aspx - - Also view the lecture covered here: - - http://blogs.msdn.com/robmen/archive/2004/09/23/233684.aspx - - - - Finally, understand that WiX is an XML layering above the concepts - - defined by the world of the MSI installer. To really know how to do WiX, - - (and especially the UI), you need to understand the MSI installer. - - A key point is that MSI (and hence WiX) is not really procedural. - - MSI defines a number of tables (like Feature or CustomAction) in - - an internal database. WiX merely specifies how to fill these tables, - - and the msiexec program merely cranks through the various tables, - - processing each row. It is true that you can do procedural things - - via CustomActions, but to get them in order, you must specify columns - - in the table with things like After="SomeOtherRowId". - - - - See "About the User Interface" and subordinate documents: - - http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/about_the_user_interface.asp ---> - -m4_include(WIX_DB_SHARED_WINMSIDIR/dbwix.m4) <!-- Define common macros --> - -<Wix xmlns="http://schemas.microsoft.com/wix/2003/01/wi"> - - <!-- The ???? stuff asks WiX to create a unique GUID for us --> - <Product Id='????????-????-????-????-????????????' - Name='Berkeley DB WIX_DB_VERSION' Version='WIX_DB_VERSION.0' - Manufacturer='Sleepycat Software, Inc.' Language='1033'> - - <!-- Store files as a compressed 'cabinet' embedded in the .MSI file. --> - <Package Id='????????-????-????-????-????????????' - Keywords="Embedded Database Datastore" - Description='Berkeley DB WIX_DB_VERSION' - Comments='includes sources and binaries' InstallerVersion='200' - Compressed='yes' Platforms="Intel" - Languages="1033" SummaryCodepage="1252" /> - - <Media Id='1' Cabinet='dbcore.cab' EmbedCab='yes' /> - - COMMON_PROPERTIES() - - <!-- Declare properties for environment --> - WIX_DB_ENV_FEATURE_PROPS() - - <Condition Message= - "To install [ProductName], you must be running Windows 2000 or Windows XP."> - <![CDATA[VersionNT>=500]]></Condition> - - <Condition Message= - "You must have administrative access to install this product."> - NOT Priviledged - </Condition> - - <Directory Id="TARGETDIR" Name="SourceDir"> - <Directory Id="DesktopFolder" Name="." SourceName="." /> - <Directory Id="FavoritesFolder" Name="." SourceName="." /> - - <Directory Id="ProgramFilesFolder" Name="." SourceName="."> - <Directory Id="SleepycatSoftwareFolder" Name="Sleepy~1" - LongName="Sleepycat Software"> - <Directory Id="INSTALLDIR" Name="WIX_DB_8CHAR_VERSION" - LongName="Berkeley DB WIX_DB_VERSION"> - <Directory Id="INSTALLUTIL" Name="instutil" - LongName="installutil"> - </Directory> - - - <!-- Note: these guids must be changed when an installer - - for a new release is made available. - - - - TODO: to play by the rules of components (see - - http://blogs.msdn.com/robmen/archive/2003/10/18/56497.aspx, - - "Component Rules 101" by Rob Mensching), - - we should devise a strategy for ALL guids (remember - - many are created by s_winmsi). This should work: - - - - Each guid is composed of three parts, like so: - - PPPPPPPP-VVVV-VVVV-HHHH-HHHHHHHHHHHH - - The P part is unique to the product, e.g. - - the bdb core installer might always use 9A3FE019. - - The V part is the version of the product, e.g. - - 4.2.37 might be translated as 0402-0025 # 25 is 37 in hex - - The H part is a hash value created from the directory - - that houses the component. Like if the component for - - the directory "bin/Debug" hashed to 1234567890abcdef, - - then the H part is 1234-567890abcdef. - - - - This scheme guarantees that rebuilds of the installer - - over the same release tree get the same GUIDs. - - But for a different release tree (which *should* get - - installed in a different directory, since install - - directories are named by release number), we will get - - completely different GUIDs. - --> - <Component Id="RequiredFiles" - Guid="13E1DF48-903B-11D9-8BDE-F66BAD1E3F3A" - KeyPath="yes" SharedDllRefCount="yes" - Location="either" DiskId="1"> - - <File Id="LICENSE.txt" Name="LICENSE.txt" - src="WIX_DB_SRCDIR\LICENSE" /> - <File Id="README.txt" Name="README.txt" - src="WIX_DB_SRCDIR\README" /> - <Registry Id="RootDir.RegistryVal" Root="HKLM" - Key="SOFTWARE\Sleepycat Software\Berkeley DB\WIX_DB_VERSION" - Name="RootDirectory" Value="[INSTALLDIR]" Type="string" - Action="write" /> - <CreateFolder /> - </Component> - - COMMON_COMPONENTS() - - <!-- <Directory>, <Component> generated from files.in --> - WIX_DB_DIRECTORY_STRUCTURE() - - </Directory> - </Directory> - </Directory> - <Directory Id="ProgramMenuFolder" Name="." SourceName="."> - <Directory Id="BerkeleyDbMenu" Name="WIX_DB_8CHAR_VERSION" - LongName="Berkeley DB WIX_DB_VERSION" /> - </Directory> - </Directory> - - <!-- <File>, <Shortcut> generated from links.in --> - WIX_DB_LINKS() - - COMMON_FEATURES(`Berkeley DB') - - <!-- ================================================================ --> - <UI> - - <Property Id="DefaultUIFont"><![CDATA[Tahoma8]]></Property> - <TextStyle Id="Tahoma8" FaceName="Tahoma" Size="8" /> - - DIALOG_WELCOME(MainWelcomeDlg, , ShowLicenseDlg) - DIALOG_LICENSE(ShowLicenseDlg, MainWelcomeDlg, TargetFolderDlg, - `Berkeley DB') - DIALOG_TARGET(TargetFolderDlg, ShowLicenseDlg, FeatureSelectionDlg) - DIALOG_FEATURE(FeatureSelectionDlg, TargetFolderDlg, EnvVarDlg, - `Debug libraries are needed for working C/C++ examples.') - DIALOG_ENVIRONMENT(EnvVarDlg, FeatureSelectionDlg, ReadyToInstallDlg) - DIALOG_READY(ReadyToInstallDlg, EnvVarDlg, ) - - DIALOG_PROGRESS(ShowProgressDlg, , ) - DIALOG_SUCCESS(InstallSuccessDlg, , , `Berkeley DB', - `in the product blog http://www.sleepycat.com/blogs/db or in the news group news://comp.databases.berkeley-db') - - <!-- Here are extra admin dialogs --> - DIALOG_ADMIN_CANCEL(CancelInstallerDlg) - DIALOG_ADMIN_NOSPACE(OutOfSpaceDlg, FeatureSelectionDlg) - DIALOG_ADMIN_INTERRUPTED(InstallErrorDlg, Return) - DIALOG_ADMIN_INTERRUPTED(InstallCancelledDlg, Exit) - - - <!-- This sequence tells MSI what to do when (at the highest level) --> - <InstallUISequence> - <Show Dialog="InstallErrorDlg" OnExit="error" /> - <Show Dialog="InstallCancelledDlg" OnExit="cancel" /> - <Show Dialog="InstallSuccessDlg" OnExit="success" /> - <Show Dialog="MainWelcomeDlg" After="CostFinalize" /> - <Show Dialog="ShowProgressDlg" After="MainWelcomeDlg" /> - </InstallUISequence> - - COMMON_UI_TEXT() - <Property Id="MaxInstallSize">49 MB</Property> - - - </UI> - - COMMON_EXECUTE_SEQUENCE() - - </Product> -</Wix> diff --git a/storage/bdb/dist/winmsi/dbvarsbat.in b/storage/bdb/dist/winmsi/dbvarsbat.in deleted file mode 100644 index b49375285f8..00000000000 --- a/storage/bdb/dist/winmsi/dbvarsbat.in +++ /dev/null @@ -1,25 +0,0 @@ -@echo off - -:: $Id: dbvarsbat.in,v 1.2 2005/04/15 18:59:59 philipr Exp $ -:: This file sets the environment variables needed to run Berkeley DB. - -set DBROOTDIR= -for /F "tokens=3 delims= " %%A in ('REG QUERY "HKLM\SOFTWARE\Sleepycat Software\Berkeley DB\WIX_DB_VERSION" /v RootDirectory') do set DBROOTDIR=%%A -if ERRORLEVEL 2 goto MISSING -if not defined DBROOTDIR goto MISSING - -echo Setting environment variables for Berkeley DB, installed in %DBROOTDIR% - -set PATH=%DBROOTDIR%\bin;%DBROOTDIR%\bin\debug;%PATH% -set CLASSPATH=%CLASSPATH%;%DBROOTDIR%\jar\debug\db.jar;%DBROOTDIR%\jar\debug\dbexamples.jar;%CLASSPATH%;%DBROOTDIR%\jar\db.jar;%DBROOTDIR%\jar\dbexamples.jar -goto END - -:MISSING -echo -echo NOTE: -echo The Berkeley DB version could not be determined. -echo If you are running on Windows 2000, make sure the -echo REG.EXE program is installed from the Tools disk" -echo - -:END diff --git a/storage/bdb/dist/winmsi/dbwix.m4 b/storage/bdb/dist/winmsi/dbwix.m4 deleted file mode 100644 index 42fa44e62a8..00000000000 --- a/storage/bdb/dist/winmsi/dbwix.m4 +++ /dev/null @@ -1,833 +0,0 @@ -<!-- $Id: dbwix.m4,v 1.7 2005/04/18 18:41:07 philipr Exp $ - - This file is included by WiX input files to define m4 macros. - - m4 is tricky. It has NO notion of XML comments, so - - take care using these names in comments after they are defined, - - since they will be expanded (probably what you don't want). - - - - Note that this file is shared by multiple installers. - - If you want to change a definition to customize an individual project, - - consider redefining the macro in a local file. - --> - -<!-- Some basic UI characteristics --> -m4_define(`DIALOG_WIDTH', `390') -m4_define(`DIALOG_HEIGHT', `320') -m4_define(`BOTTOMSTRIPE_Y', `m4_eval(DIALOG_HEIGHT-32)') -m4_define(`NAVBUTTON_Y', `m4_eval(DIALOG_HEIGHT-23)') -m4_define(`NAVBUTTON_DIM', `X="`$1'" Y="NAVBUTTON_Y" Width="66" Height="17"') - -<!-- _YPOS is a running total of the current Y position --> -m4_define(`_YPOS', `0') -m4_define(`SETY', `m4_define(`_YPOS', `$1')') -m4_define(`INCY', `SETY(m4_eval(_YPOS+(`$1')))') - -<!-- PARTIALHEIGHT(yheight [, gap=10 ]) --> -m4_define(`PARTIALHEIGHT', `Y="_YPOS" Height="`$1'" INCY(`$1') INCY(_GETGAP(`$2'))') -m4_define(`_GETGAP', `m4_ifelse(`',`$1', 10, `$1')') -m4_define(`FULLHEIGHT', `Y="_YPOS" Height="m4_eval(BOTTOMSTRIPE_Y - _YPOS - 10)"') - -<!-- BOTTOM_Y: bottom of the usable area before nav buttons --> -m4_define(`BOTTOM_Y', `m4_eval(BOTTOMSTRIPE_Y - 10)') - -m4_define(`DIALOGPROP', `Width="DIALOG_WIDTH" Height="DIALOG_HEIGHT" - Title="[ProductName] - Installer" NoMinimize="yes"') - -m4_define(`TOPSTRIPE', ` - SETY(`$1') - INCY(10) -<!-- stripe bitmap removed for now until we get better quality bitmaps. - <Control Id="TopStripe" Type="Bitmap" - X="0" Y="0" Width="DIALOG_WIDTH" Height="`$1'" Text="Stripe" /> ---> - <Control Id="TopStripeBorder" Type="Line" - X="0" Y="`$1'" Width="DIALOG_WIDTH" Height="0" /> - <Control Id="TopTitle" Type="Text" - X="8" Y="6" Width="292" Height="25" Transparent="yes"> - <Text>{&MSSansBold8}`$2'</Text> - </Control> - <Control Id="TopText" Type="Text" - X="16" Y="23" Width="m4_eval(DIALOG_WIDTH-34)" - Height="m4_eval(`$1' - 19)" Transparent="yes"> - <Text>`$3'</Text> - </Control>') - -m4_define(`TEXTCONTROL', ` - <Control Id="`$1'" Type="Text" - X="20" Y="_YPOS" Width="m4_eval(DIALOG_WIDTH-42)" Height="`$2'"> - <Text>`$3'</Text> - </Control> - INCY(`$2')') - -<!-- TEXTCONTROL2 (name,height,text). No newline --> -m4_define(`TEXTCONTROL2', ` - <Control Id="`$1'" Type="Text" - X="20" Y="_YPOS" Width="m4_eval(DIALOG_WIDTH-42)" Height="`$2'" Transparent="yes"> - <Text>`$3'</Text> - </Control>') - -m4_define(`BOTTOMSTRIPE', ` - <Control Id="BottomStripeBorder" Type="Line" - X="0" Y="BOTTOMSTRIPE_Y" Width="DIALOG_WIDTH" Height="0" />') - -m4_define(`NEWDIALOGEVENT', ` - <Publish Event="NewDialog" Value="`$1'"> - <![CDATA[1]]> - </Publish>') - -m4_define(`SPAWNDIALOGEVENT', ` - <Publish Event="SpawnDialog" Value="`$1'"> - <![CDATA[1]]> - </Publish>') - -<!-- use an arrow only if the text is Back, like this: "< Back" --> -m4_define(`BACKBUTTON_GENERIC', ` - <Control Id="`$1'" Type="PushButton" - NAVBUTTON_DIM(170) - Text="m4_ifelse(Back,`$1',< )&`$1'" `$2'> - `$3' - </Control>') - -<!-- use an arrow only if the text is Next, like this: "Next >" --> -m4_define(`NEXTBUTTON_GENERIC', ` - <Control Id="`$1'" Type="PushButton" - NAVBUTTON_DIM(236) - Default="yes" Text="&`$1'm4_ifelse(Next,`$1', >)" `$2'> - `$3' - </Control>') - -m4_define(`CANCELBUTTON_GENERIC', ` - <Control Id="`$1'" Type="PushButton" - NAVBUTTON_DIM(308) - Text="`$1'" `$2'> - `$3' - </Control>') - -m4_define(`NEXTBUTTON_NOTDEFAULT', ` - <Control Id="`$1'" Type="PushButton" - NAVBUTTON_DIM(236) - Default="no" Text="&`$1'm4_ifelse(Next,`$1', >)" `$2'> - `$3' - </Control>') - -<!-- typical usages --> -m4_define(`BACKBUTTON_DISABLED', `BACKBUTTON_GENERIC(Back, Disabled="yes")') -m4_define(`BACKBUTTON', `BACKBUTTON_GENERIC(Back, , NEWDIALOGEVENT(`$1'))') -m4_define(`NEXTBUTTON_DISABLED', `NEXTBUTTON_GENERIC(Next, Disabled="yes")') -m4_define(`NEXTBUTTON', `NEXTBUTTON_GENERIC(Next, , NEWDIALOGEVENT(`$1'))') -m4_define(`CANCELBUTTON', `CANCELBUTTON_GENERIC(Cancel, Cancel="yes", - SPAWNDIALOGEVENT(CancelInstallerDlg))') - -<!-- a little (imperfect) magic to create some unique GUIDs. --> -m4_define(`_GUIDSUFFIX', `10000000') -m4_define(`_SETGUID', `m4_define(`_GUIDSUFFIX', `$1')') -m4_define(`_GUIDINC', `_SETGUID(m4_eval(_GUIDSUFFIX+1))') -m4_define(`GUID_CREATE_UNIQUE', `_GUIDINC()WIX_DB_GUID_PREFIX()`'_GUIDSUFFIX()') - -<!-- These three defines are data values, used by GUID_CREATE_PERSISTENT --> -m4_define(`_WIXDB_PRODUCT', WIX_DB_PRODUCT_NAME) -m4_define(`_WIXDB_VERSION', WIX_DB_VERSION) -m4_define(`_WIXDB_CURDIR', `unknown') -m4_define(`_WIXDB_CURFILE', `unknown') -m4_define(`_WIXDB_SUBDIR', `') - -<!-- These defines set the data values above --> -m4_define(`WIX_DB_SET_PRODUCT', `m4_define(`_WIXDB_PRODUCT', `$1')') -m4_define(`WIX_DB_SET_VERSION', `m4_define(`_WIXDB_VERSION', `$1')') -m4_define(`WIX_DB_SET_CURDIR', `m4_define(`_WIXDB_CURDIR', `$1')') -m4_define(`WIX_DB_SET_CURFILE', `m4_define(`_WIXDB_CURFILE', `$1')') -m4_define(`WIX_DB_SET_SUBDIR', `m4_define(`_WIXDB_SUBDIR', `$1')') - -m4_define(`_LASTCHAR', `m4_substr(`$1',m4_eval(m4_len(`$1')-1))') -m4_define(`_LOPCHAR', `m4_substr(`$1',0,m4_eval(m4_len(`$1')-1))') -m4_define(`_CHOPNAME', `m4_ifelse(_LASTCHAR(`$1'),/,`$1',`_CHOPNAME(_LOPCHAR(`$1'))')') -m4_define(`WIX_DB_BEGIN_SUBDIR', `WIX_DB_SET_SUBDIR(_WIXDB_SUBDIR/`$1')') -m4_define(`WIX_DB_END_SUBDIR', `WIX_DB_SET_SUBDIR(_LOPCHAR(_CHOPNAME(_WIXDB_SUBDIR)))') -m4_define(`WIX_DB_CLEAR_SUBDIR', `WIX_DB_SET_SUBDIR()') - -<!-- Create a GUID from the current product, directory, file --> -m4_define(`WIX_DB_PERSISTENT_GUID', `m4_esyscmd(echo "_WIXDB_PRODUCT @@ _WIXDB_VERSION @@ _WIXDB_CURDIR @@ _WIXDB_SUBDIR @@ _WIXDB_CURFILE" | openssl md5 | sed -e "s/^\(........\)\(....\)\(....\)\(....\)\(....\)\(............\)/\1-\2-\3-\4-\5/")') - -m4_define(`DB_LICENSE_INTRO', `The following license applies to this copy of software you are about to install. Please read it carefully before proceeding. Select below the nature of the license by which you will use this product. For more information about Sleepycat Software's licensing please refer to http://www.sleepycat.com/download/incensinginfo.shtml or contact us at info@sleepycat.com.') - -m4_define(`DB_ENVIRONMENT_INTRO', `[ProductName] will need to modify certain environment variables to work properly. If you elect not to set these variables you may find that some utilities`,' scripts and other parts of [ProductName] won't work properly. Please indicate that you skipped this step if you request support help from us.') - -m4_define(`COMMON_PROPERTIES', ` - <Property Id="ApplicationUsers"><![CDATA[AnyUser]]></Property> - <Property Id="LicenseType"><![CDATA[Open]]></Property> - - <!-- The ARP* properties affect the Add/Remove Programs dialog --> - <Property Id="ARPURLINFOABOUT"><![CDATA[http://www.sleepycat.com]]></Property> - <Property Id="ARPCONTACT"><![CDATA[support@sleepycat.com]]></Property> - <Property Id="ARPNOMODIFY"><![CDATA[1]]></Property> - <Property Id="ARPNOREPAIR"><![CDATA[1]]></Property> - <!-- TODO: this icon does not work here --> - <Property Id="ARPPRODUCTION"><![CDATA[IconWeb]]></Property> - - <Property Id="INSTALLLEVEL"><![CDATA[200]]></Property> - <Property Id="FullOrCustom"><![CDATA[Full]]></Property> - - <Property Id="DiscussionCheck" Hidden="yes"><![CDATA[yes]]></Property> - <Property Id="AnnouncementsCheck" Hidden="yes"><![CDATA[yes]]></Property> - <Property Id="NewsletterCheck" Hidden="yes"><![CDATA[yes]]></Property> - <Property Id="EmailAddress" Hidden="yes"></Property> - <Property Id="SalesContactCheck" Hidden="yes"><![CDATA[yes]]></Property> - <Property Id="EnvironmentSetCheck" Hidden="yes"><![CDATA[1]]></Property> - <Property Id="EnvironmentGenCheck" Hidden="yes"><![CDATA[1]]></Property> -<!-- (PBR) We use DebugCheck to track the state of the debug checkbox --> - <Property Id="DebugCheck" Hidden="yes"><![CDATA[yes]]></Property> - - <!-- Part of the build process creates a program instenv.exe - - that is installed into InstUtil and used only by the installer. - - When a user wants to generate a file with environment vars, - - we launch instreg and that program creates it. - - - - The final location of the instenv.exe program is not known - - when we create this property, we set the real value of the - - property later. - --> - - <Property Id="InstEnvironmentProgram"><![CDATA[0]]></Property> -<!-- TODO: should not have to hardwire PATH and CLASSPATH here --> - <CustomAction Id="InstEnvironment" Property="InstEnvironmentProgram" - ExeCommand="[INSTALLDIR]\dbvars.bat PATH=[PATHEscValue] CLASSPATH=[CLASSPATHEscValue]" Return="asyncNoWait"/> - - <!-- Some properties to aid in debugging. - - Sometimes creating a msg dialog is the easiest way to see the - - value of a property. To make this work when you hit the next - - button, add this to your NEXTBUTTON__GENERIC call: - - <Publish Event="DoAction" Value="InstDebug"><![CDATA[1]]></Publish> - - --> - <Property Id="DebugUserId">dda</Property> - <Property Id="DebugShowProgram">msg.exe</Property> - - <!-- tweek me as needed --> - <CustomAction Id="InstDebug" Property="DebugShowProgram" - ExeCommand="[DebugUserId] InstEnvironmentProgram=[InstEnvironmentProgram]= EnvironmentGenCheck=[EnvironmentGenCheck]= AlwaysInstall=[!AlwaysInstall]=" Return="asyncNoWait" /> - - <Property Id="NULL" Hidden="yes"></Property> - <Property Id="FeatureList" Hidden="yes"></Property> - <Property Id="DoInstallDebug" Hidden="yes">yes</Property> - <Property Id="DoInstallEnvironment" Hidden="yes">yes</Property> - - <Binary Id="SleepycatLogo" src="WIX_DB_IMAGEDIR\sleepycat.jpg" /> - <Binary Id="Stripe" src="WIX_DB_IMAGEDIR\topstripe.ibd" /> - - <!-- TODO: does not work yet --> - <Binary Id="IconWeb" src="WIX_DB_IMAGEDIR\caticon.ibd" /> - - <!-- These are 16x16 Windows ico files --> - <Binary Id="IconCreateDir" src="WIX_DB_IMAGEDIR\foldernew.ibd" /> - <Binary Id="IconUp" src="WIX_DB_IMAGEDIR\folderup.ibd" /> - -') - -m4_define(`COMMON_COMPONENTS', ` - <Component Id="RequiredCommonFiles" - Guid="545CFE00-93D7-11D9-EAD3-F63F68BDEB1A" - KeyPath="yes" SharedDllRefCount="yes" - Location="either" DiskId="1"> - <Registry Id="Ext.Registry" Root="HKCR" - Key=".bdbsc" - Value="Sleepycat.InformationalShortcut" - Type="string" Action="write" /> - <Registry Id="Name.Registry" Root="HKCR" - Key="Sleepycat.InformationalShortcut" - Value="Sleepycat Software Informational Shortcut" - Type="string" Action="write" /> - <Registry Id="Tip.Registry" Root="HKCR" - Key="Sleepycat.InformationalShortcut" Name="InfoTip" - Value="Sleepycat Software Informational Shortcut" - Type="string" Action="write" /> - <Registry Id="NoShow.Registry" Root="HKCR" - Key="Sleepycat.InformationalShortcut" Name="NeverShowExt" - Type="string" Action="write" /> - <Registry Id="Icon.Registry" Root="HKCR" - Key="Sleepycat.InformationalShortcut\DefaultIcon" - Value="[INSTALLDIR]\installutil\webicon.ico" - Type="string" Action="write" /> - <Registry Id="Command.Registry" Root="HKCR" - Key="Sleepycat.InformationalShortcut\shell\open\command" - Value="rundll32.exe shdocvw.dll,OpenURL %1" - Type="string" Action="write" /> - <Registry Id="Explore.Registry" Root="HKCU" - Key="Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.bdbsc\OpenWithProgIds\Sleepycat.InformationalShortcut" - Action="write" /> - <Registry Id="HklmExt.Registry" Root="HKLM" - Key="Software\Classes\.bdbsc" - Value="Sleepycat.InformationalShortcut" - Type="string" Action="write" /> - <Registry Id="HklmCommand.Registry" Root="HKLM" - Key="Software\Classes\Sleepycat.InformationalShortcut\shell\open\command" - Value="rundll32.exe shdocvw.dll,OpenURL %1" - Type="string" Action="write" /> - </Component> -') - -m4_define(`COMMON_UI_TEXT', ` - <!-- These are needed to show various canned text --> - <UIText Id="AbsentPath" /> - <UIText Id="NewFolder">Fldr|New Folder</UIText> - <UIText Id="bytes">bytes</UIText> - <UIText Id="GB">GB</UIText> - <UIText Id="KB">KB</UIText> - <UIText Id="MB">MB</UIText> - <UIText Id="MenuAbsent">This feature will not be installed.</UIText> - <UIText Id="MenuAllLocal">This feature, and all subfeatures, will be installed.</UIText> - <UIText Id="MenuLocal">This feature will be installed.</UIText> - <UIText Id="SelAbsentAbsent">This feature will remain uninstalled.</UIText> - <UIText Id="SelAbsentLocal">This feature will be installed.</UIText> - <UIText Id="SelChildCostNeg">This feature frees up [1] on your hard drive.</UIText> - <UIText Id="SelChildCostPos">This feature requires [1] on your hard drive.</UIText> - <UIText Id="SelCostPending">Compiling cost for this feature...</UIText> - <UIText Id="SelLocalAbsent">This feature will be completely removed.</UIText> - <UIText Id="SelLocalLocal">This feature will remain installed.</UIText> - <UIText Id="SelParentCostNegNeg">This feature frees up [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures free up [4] on your hard drive.</UIText> - <UIText Id="SelParentCostNegPos">This feature frees up [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures require [4] on your hard drive.</UIText> - <UIText Id="SelParentCostPosNeg">This feature requires [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures free up [4] on your hard drive.</UIText> - <UIText Id="SelParentCostPosPos">This feature requires [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures require [4] on your hard drive.</UIText> - <UIText Id="TimeRemaining">Time remaining: {[1] min }[2] sec</UIText> - <UIText Id="VolumeCostAvailable">Available</UIText> - <UIText Id="VolumeCostDifference">Differences</UIText> - <UIText Id="VolumeCostRequired">Required</UIText> - <UIText Id="VolumeCostSize">Disk Size</UIText> - <UIText Id="VolumeCostVolume">Volume</UIText> -') - -m4_define(`COMMON_FEATURES', ` - <!-- Here we list all the features to be installed. - - There is one canned feature, the rest of the - - features come from features.in, by way of a file - - that gets included. - --> - <Feature Id="AlwaysInstall" Title="Always Install" - Description="`$1'" Display="hidden" Level="1" - AllowAdvertise="no" - ConfigurableDirectory="INSTALLDIR" Absent="disallow"> - <ComponentRef Id="RequiredFiles" /> - <ComponentRef Id="RequiredCommonFiles" /> - </Feature> - - <!-- <Feature>, <ComponentRef> generated from {features,files}.in --> - WIX_DB_FEATURE_STRUCTURE() -') - -m4_define(`COMMON_EXECUTE_SEQUENCE', ` - <!-- TODO: fix comment - - We modify the execute sequence to insert some custom actions: - - we want the instenv program to run during install (after files - - are installed), and during uninstall (before files are removed). - - We set a condition on the custom actions to make this happen. - - The "!ident" notation indicates the current action for a feature - - with that identifier. We use the AlwaysInstall feature because - - it is always present in our feature list. A value of 3 means - - it is being installed locally, 1 means it is being uninstalled. - - TODO: removed for now - <Custom Action="InstEnvironment" After="PublishProduct"> - <![CDATA[Not Installed]]></Custom> - --> - <InstallExecuteSequence> - </InstallExecuteSequence> -') - -<!-- - - Here are macros for each dialog that is shared by the installers. - - The idea for any customization is that each installer - - could potentially override a particular dialog. - - However, if it is feasible to share code, any of these - - dialogs could be parameterized further. - - - - In general, these macros have 3 parameters. - - The first is the id name of the dialog. - - The second is the id of the previous dialog (for the Back button). - - The third is the id of the next dialog (for the Next button). - --> -m4_define(`DIALOG_WELCOME', ` - <Dialog Id="`$1'" DIALOGPROP> - BOTTOMSTRIPE() - BACKBUTTON_DISABLED() - CANCELBUTTON() - NEXTBUTTON(`$3') - - TOPSTRIPE(54, `Welcome', -`The Installer will install [ProductName] on your computer. -To continue, click Next.') - - <Control Id="Logo" Type="Bitmap" Text="SleepycatLogo" - X="0" Width="DIALOG_WIDTH" PARTIALHEIGHT(168) /> - </Dialog> -') - -<!-- Takes a 4th parameter, a short product name, like "Berkeley DB" --> -m4_define(`DIALOG_LICENSE', ` - <RadioGroup Property="LicenseType"> - <RadioButton Value="Open" - X="0" Y="0" Width="310" Height="15" - Text="I qualify for the &open source license shown above" /> - <RadioButton Value="Commercial" - X="0" Y="15" Width="310" Height="15" - Text="I will need a co&mmercial license when I ship my product" /> - </RadioGroup> - - <Dialog Id="`$1'" DIALOGPROP> - - TOPSTRIPE(84, `Open Source License', DB_LICENSE_INTRO(`$4')) - BOTTOMSTRIPE() - BACKBUTTON(`$2') - CANCELBUTTON() - NEXTBUTTON(`$3') - - <Control Id="LicenseText" Type="ScrollableText" X="8" Width="368" - PARTIALHEIGHT(130) Sunken="yes"> - <Text>WIX_DB_LICENSE_RTF()</Text> - </Control> - - <Control Id="LicenseRadio" Type="RadioButtonGroup" X="8" Width="340" - PARTIALHEIGHT(35) Property="LicenseType" /> - - </Dialog> -') - -m4_define(`DIALOG_TARGET', ` - - <RadioGroup Property="ApplicationUsers"> - <RadioButton Value="AnyUser" X="0" Y="0" Width="270" Height="15" - Text="&Anyone who uses this computer (all users)" /> - <RadioButton Value="CurUser" X="0" Y="15" Width="270" Height="15" - Text="Only for the current user" /> - </RadioGroup> - - <Dialog Id="`$1'" DIALOGPROP> - - TOPSTRIPE(44, `Installation Folder', - `Click Next to install to the default folder.') - BOTTOMSTRIPE() - BACKBUTTON(`$2') - CANCELBUTTON() - - NEXTBUTTON_GENERIC(Next,, - NEWDIALOGEVENT(`$3') - <Publish Event="SetInstallLevel" Value="300"> - <![CDATA[0]]></Publish> - <Publish Property="ALLUSERS" Value="1"> - <![CDATA[ApplicationUsers = "AnyUser"]]></Publish> - <Publish Property="ALLUSERS" Value="{}"> - <![CDATA[ApplicationUsers = "CurUser"]]></Publish> - <Publish Property="SelectedSetupType" Value="Custom"> - <![CDATA[1]]></Publish> - - ) - - TEXTCONTROL(InstallToText, 16, `Install [ProductName] to:') - - <Control Id="ChangeFolder" Type="PushButton" X="318" Y="_YPOS" - Width="66" Height="17" Text="&Change..."> - <Publish Event="SpawnDialog" Value="ChangeFolderDlg"> - <![CDATA[1]]></Publish> - <Publish Property="NewInstallDir" Value="INSTALLDIR"> - <![CDATA[1]]></Publish> - </Control> - - <Control Id="InstallToValue" Type="Text" X="40" Width="250" - PARTIALHEIGHT(20, 20) - Property="NewInstallDir" Text="[INSTALLDIR]" /> - - TEXTCONTROL(InstallForText, 14, `Install [ProductName] for:') - - <Control Id="InstallForRadio" Type="RadioButtonGroup" PARTIALHEIGHT(50) - X="40" Width="310" Property="ApplicationUsers" /> - </Dialog> - - <Dialog Id="ChangeFolderDlg" DIALOGPROP> - TOPSTRIPE(44, `Change the Installation Folder', - `Browse to the folder you want to install to.') - BOTTOMSTRIPE() - NEXTBUTTON_GENERIC(OK,, - <Publish Event="SetTargetPath" - Value="[NewInstallDir]"><![CDATA[1]]></Publish> - <Publish Event="EndDialog" Value="Return"><![CDATA[1]]></Publish> - ) - CANCELBUTTON_GENERIC(Cancel, Cancel="yes", - <Publish Event="Reset" Value="0"><![CDATA[1]]></Publish> - <Publish Event="EndDialog" Value="Return"><![CDATA[1]]></Publish> - ) - - TEXTCONTROL(LookText, 15, `&Install into:') - - <Control Id="DirCombo" Type="DirectoryCombo" - X="20" Width="270" Y="_YPOS" Height="80" - Property="NewInstallDir" Indirect="yes" Removable="yes" - Fixed="yes" Remote="yes" CDROM="yes" RAMDisk="yes" Floppy="yes" /> - - <Control Id="FolderUp" Type="PushButton" - X="320" Width="19" Y="_YPOS" Height="19" - ToolTip="Up One Level" Icon="yes" FixedSize="yes" - IconSize="16" Text="IconUp"> - <Publish Event="DirectoryListUp" Value="0"><![CDATA[1]]></Publish> - </Control> - - <Control Id="FolderCreate" Type="PushButton" - X="345" Width="19" Y="_YPOS" Height="19" - ToolTip="Create New Folder" Icon="yes" FixedSize="yes" - IconSize="16" Text="IconCreateDir"> - <Publish Event="DirectoryListNew" Value="0"><![CDATA[1]]></Publish> - </Control> - - INCY(25) - <Control Id="DirList" Type="DirectoryList" - X="20" Width="342" PARTIALHEIGHT(100, 5) - Property="NewInstallDir" Sunken="yes" - Indirect="yes" TabSkip="no" /> - - <Control Id="FolderText" Type="Text" - X="20" Width="99" PARTIALHEIGHT(14, 1) - TabSkip="no" Text="&Folder name:" /> - - <Control Id="PathEditControl" Type="PathEdit" - X="20" Width="342" PARTIALHEIGHT(17) - Property="NewInstallDir" Sunken="yes" Indirect="yes" /> - - </Dialog> - -') - -<!-- Takes a 4th parameter, any extra text (restrictions) for debug libs --> -m4_define(`DIALOG_FEATURE', ` - <Dialog Id="`$1'" DIALOGPROP TrackDiskSpace="yes"> - - TOPSTRIPE(36, `Feature Selection', - `Select the features of [ProductName] you want. Maximum install size is [MaxInstallSize].') - BOTTOMSTRIPE() - CANCELBUTTON - BACKBUTTON(`$2') - - NEXTBUTTON_GENERIC(Next,, - <Publish Event="NewDialog" Value="`$3'"> - <![CDATA[OutOfNoRbDiskSpace <> 1]]></Publish> - <Publish Event="NewDialog" Value="OutOfSpaceDlg"> - <![CDATA[OutOfNoRbDiskSpace = 1]]></Publish> - <Publish Property="FullOrCustom" Value="Custom"> - <![CDATA[1]]></Publish> - - <!-- - - This updates the FeatureList property and the - - properties like PATHValue that track the value - - to be displayed for environment variables. - --> - WIX_DB_ENV_FEATURE_SET() - ) - - - <!-- TODO: When the debug checkbox is clicked, - - we would like to update the disk space usage numbers - - as shown in the SelectionTreeControl. Tried this: - <Publish Event="DoAction" Value="CostFinalize"> - <![CDATA[1]]></Publish> - - but it made all the numbers zero. Probably need - - to perform a whole sequence, (like CostInitialize,...) - --> - - - TEXTCONTROL(ClickText, 15, -`Click on an icon in the list below to change how a feature is installed.') - INCY(5) - - <Control Id="SelectionTreeControl" Type="SelectionTree" - X="8" Width="220" FULLHEIGHT - Property="NewInstallDir" Sunken="yes" TabSkip="no" /> - - <Control Id="GroupBoxControl" Type="GroupBox" - X="235" Width="131" FULLHEIGHT - Text="Feature Description" /> - INCY(15) - - <Control Id="ItemDescription" Type="Text" - X="241" Width="120" PARTIALHEIGHT(50) > - <Text></Text> - <Subscribe Event="SelectionDescription" Attribute="Text" /> - </Control> - - <Control Id="Size" Type="Text" - X="241" Width="120" PARTIALHEIGHT(50) - Text="Feature size"> - <Subscribe Event="SelectionSize" Attribute="Text" /> - </Control> - - </Dialog> -') - -<!-- - - Note: for Win/9X, Win/ME - - Here we must do costfinalize whenever leaving - - this dialog (via Back or Next) because changing whether we have - - environment enabled or not changes the list of features - - (which is finalized by costfinalize). - - Calling costfinalize more than once is apparently not - - supported on older (9X,ME) systems. - --> -m4_define(`DIALOG_ENVIRONMENT', ` - <Dialog Id="`$1'" DIALOGPROP> - TOPSTRIPE(84, `Setting Environment Variables', DB_ENVIRONMENT_INTRO) - BOTTOMSTRIPE() - CANCELBUTTON - BACKBUTTON_GENERIC(Back, , - NEWDIALOGEVENT(`$2') -<!--PBR (4/4/2005) I removed this because it resets the feature choices - <Publish Event="DoAction" Value="CostFinalize"> - <![CDATA[1]]></Publish> ---> - ) - NEXTBUTTON_GENERIC(Next, , - NEWDIALOGEVENT(`$3') -<!--PBR (4/4/2005) I removed this because it resets the feature choices - <Publish Event="DoAction" Value="CostFinalize"> - <![CDATA[1]]></Publish> ---> - <Publish Property="DoInstallEnvironment" Value="yes"> - <![CDATA[EnvironmentSetCheck = "1"]]></Publish> - <Publish Property="DoInstallEnvironment" Value="no"> - <![CDATA[EnvironmentSetCheck <> "1"]]></Publish> - ) - - <Control Id="SetEnvBox" Type="CheckBox" PARTIALHEIGHT(15, 5) - Text="Set the values in the environment variables" - X="26" Width="250" Property="EnvironmentSetCheck" CheckBoxValue="1"/> - <Control Id="GenEnvBox" Type="CheckBox" PARTIALHEIGHT(15, 8) - Text="Generate a dbvars.bat file with the given values" - X="26" Width="250" Property="EnvironmentGenCheck" CheckBoxValue="1"/> - INCY(5) - - TEXTCONTROL(ReviewText, 12, -`Here are the new environment values:') - - <Control Id="LargeBox" Type="Text" - X="19" Width="340" FULLHEIGHT - Disabled="yes" Sunken="yes" Transparent="yes" TabSkip="no" /> - - INCY(5) - - <!-- Show the properties for environment --> - WIX_DB_ENV_FEATURE_SHOW() - - </Dialog> -') - -m4_define(`DIALOG_READY', ` - <Dialog Id="`$1'" DIALOGPROP TrackDiskSpace="yes"> - NEXTBUTTON_GENERIC(Install,, - <Publish Event="NewDialog" Value="OutOfSpaceDlg"> - <![CDATA[OutOfNoRbDiskSpace = 1]]></Publish> - <Publish Event="EndDialog" Value="Return"> - <![CDATA[OutOfNoRbDiskSpace <> 1]]></Publish> - -<!-- Note: we set the name of the instenv now because we do not know - the installed pathname at the beginning of the execution --> - - <Publish Property="InstEnvironmentProgram" - Value="[INSTALLDIR]\installutil\bin\instenv.exe"> - <![CDATA[1]]></Publish> - ) - - TOPSTRIPE(44, `Ready', `The installer is ready to begin.') - BOTTOMSTRIPE() - CANCELBUTTON() - BACKBUTTON(`$2') - - TEXTCONTROL(ReviewText, 24, -`If you want to review or change any of your installation settings, click Back to the Feature Selection. Click Cancel to exit the installer.') - - <Control Id="LargeBox" Type="Text" - X="19" Width="340" FULLHEIGHT - Disabled="yes" Sunken="yes" Transparent="yes" TabSkip="no" /> - - INCY(5) - - <Control Id="DestinationText" Type="Text" - X="23" Width="316" PARTIALHEIGHT(11, 4) - TabSkip="no" Text="Destination Folder:" /> - - <Control Id="DestinationValue" Type="Text" - X="37" Width="316" PARTIALHEIGHT(13, 8) - TabSkip="no" Text="[INSTALLDIR]" /> - - <Control Id="FeatureListText" Type="Text" - X="23" Width="316" PARTIALHEIGHT(13, 4) - TabSkip="no" Text="Features to be installed:" /> - - <Control Id="FeatureListValue" Type="Text" - X="37" Width="316" PARTIALHEIGHT(30, 8) - TabSkip="no" Text="Shortcuts[FeatureList]" /> - - <Control Id="EnvironmentText" Type="Text" - X="23" Width="316" PARTIALHEIGHT(15, 0) - TabSkip="no" Text="Environment Variables:" /> - - <Control Id="EnvironmentValue" Type="Text" - X="37" Width="316" PARTIALHEIGHT(20, 0) - TabSkip="no" Text="[DoInstallEnvironment]" /> - - </Dialog> - -') - -m4_define(`DIALOG_PROGRESS', ` - <Dialog Id="`$1'" DIALOGPROP Modeless="yes"> - BOTTOMSTRIPE() - BACKBUTTON_DISABLED() - CANCELBUTTON() - NEXTBUTTON_DISABLED() - - TOPSTRIPE(44, `Installer Progress', `Installing [ProductName].') - - <Control Id="ActionText" Type="Text" - X="59" Y="100" Width="275" Height="12"> - <Subscribe Event="ActionText" Attribute="Text" /> - </Control> - - <Control Id="ActionProgress95" Type="ProgressBar" - X="59" Y="113" Width="275" Height="12" - ProgressBlocks="yes" Text="Progress done"> - <Subscribe Event="InstallFiles" Attribute="Progress" /> - <Subscribe Event="MoveFiles" Attribute="Progress" /> - <Subscribe Event="RemoveFiles" Attribute="Progress" /> - <Subscribe Event="RemoveRegistryValues" Attribute="Progress" /> - <Subscribe Event="WriteIniValues" Attribute="Progress" /> - <Subscribe Event="WriteRegistryValues" Attribute="Progress" /> - <Subscribe Event="UnmoveFiles" Attribute="Progress" /> - <Subscribe Event="AdminInstallFinalize" Attribute="Progress" /> - <Subscribe Event="SetProgress" Attribute="Progress" /> - </Control> - </Dialog> -') - -<!-- - - Takes two extra parameters (in addition to the usual dialog parms) - - 4th: a short product name, like "Berkeley DB" - - 5th: a description of where to find online info, like "on www.xyz.com" - --> -m4_define(`DIALOG_SUCCESS', ` - <Dialog Id="`$1'" DIALOGPROP> - BOTTOMSTRIPE() - NEXTBUTTON_GENERIC(Finish, Cancel="yes", - <Publish Event="DoAction" Value="CleanUp"> - <![CDATA[ISSCRIPTRUNNING="1"]]></Publish> - <Publish Event="EndDialog" Value="Exit"> - <![CDATA[1]]></Publish> - ) - CANCELBUTTON_GENERIC(Cancel, Disabled="yes", ) - BACKBUTTON_DISABLED() - - TOPSTRIPE(44, `Installed', `[ProductName] is now installed.') - - TEXTCONTROL(InstallSuccessText, 80, -`Please contact support@sleepycat.com for any technical issues or info@sleepycat.com for sales and licensing questions. - -Information about this product can also be found $5. - -Thank you for installing [ProductName].') - - <Control Id="Image" Type="Bitmap" Text="SleepycatLogo" - X="0" Width="DIALOG_WIDTH" FULLHEIGHT TabSkip="no" /> - - </Dialog> -') - - -m4_define(`DIALOG_ADMIN_INTERRUPTED', ` - <Dialog Id="`$1'" DIALOGPROP> - TOPSTRIPE(44, `Interrupted', -`The installer was interrupted before [ProductName] could be completely installed.') - - BOTTOMSTRIPE() - NEXTBUTTON_GENERIC(Finish, Cancel="yes", - <Publish Event="DoAction" Value="CleanUp"> - <![CDATA[ISSCRIPTRUNNING="1"]]></Publish> - <Publish Event="EndDialog" Value="Exit"> - <![CDATA[1]]></Publish> - <Condition Action="default"> - <![CDATA[NOT UpdateStarted]]></Condition> - ) - CANCELBUTTON_GENERIC(Cancel, Disabled="yes", - <Publish Property="Suspend" Value="1"><![CDATA[1]]></Publish> - <Publish Event="EndDialog" Value="`$2'"><![CDATA[1]]></Publish> - <Condition Action="disable"><![CDATA[NOT UpdateStarted]]></Condition> - <Condition Action="enable"><![CDATA[UpdateStarted]]></Condition> - ) - BACKBUTTON_GENERIC(Back, Disabled="yes", - <Publish Property="Suspend" Value="{}"><![CDATA[1]]></Publish> - <Publish Event="EndDialog" Value="`$2'"><![CDATA[1]]></Publish> - <Condition Action="disable"><![CDATA[NOT UpdateStarted]]></Condition> - <Condition Action="enable"><![CDATA[UpdateStarted]]></Condition> - <Condition Action="default"><![CDATA[UpdateStarted]]></Condition> - ) - - <Control Id="NotModifiedText" Type="Text" - X="20" Y="_YPOS" Width="228" Height="50" Transparent="yes"> - <Text>Your system has not been modified. To complete the installation later, please run the installer again.</Text> - <Condition Action="hide"><![CDATA[UpdateStarted]]></Condition> - <Condition Action="show"><![CDATA[NOT UpdateStarted]]></Condition> - </Control> - - <Control Id="YesModifiedText" Type="Text" - X="20" Y="_YPOS" Width="228" Height="50" Transparent="yes"> - <Text>The product may be partially installed. Any installed elements will be removed when you exit.</Text> - <Condition Action="hide"><![CDATA[NOT UpdateStarted]]></Condition> - <Condition Action="show"><![CDATA[UpdateStarted]]></Condition> - </Control> - INCY(30) - - TEXTCONTROL(FinishText, 25, `Click Finish to exit the install.') - - <Control Id="Image" Type="Bitmap" - X="0" Width="DIALOG_WIDTH" PARTIALHEIGHT(168) Text="SleepycatLogo" /> - </Dialog> -') - -m4_define(`DIALOG_ADMIN_CANCEL', ` - - <Dialog Id="`$1'" Width="280" Height="90" - Title="[ProductName] - Installer" NoMinimize="yes"> - - SETY(20) - TEXTCONTROL(CancelText, 24, -`Are you sure you want to cancel [ProductName] installation?') - - <Control Id="YesButton" Type="PushButton" - X="60" Y="60" Width="66" Height="17" Text="&Yes"> - <Publish Event="DoAction" Value="CleanUp"> - <![CDATA[ISSCRIPTRUNNING="1"]]></Publish> - <Publish Event="EndDialog" Value="Exit"><![CDATA[1]]></Publish> - </Control> - - <Control Id="NoButton" Type="PushButton" - X="130" Y="60" Width="66" Height="17" - Default="yes" Cancel="yes" Text="&No"> - <Publish Event="EndDialog" Value="Return"> - <![CDATA[1]]></Publish> - </Control> - - </Dialog> -') - -m4_define(`DIALOG_ADMIN_NOSPACE', ` - <Dialog Id="`$1'" DIALOGPROP> - TOPSTRIPE(44, `Out of Disk Space', -`The disk does not have enough space for the selected features.') - BOTTOMSTRIPE() - - CANCELBUTTON_GENERIC(OK, Default="yes" Cancel="yes", - <Publish Event="NewDialog" Value="`$2'"> - <![CDATA[ACTION <> "ADMIN"]]></Publish> - ) - - TEXTCONTROL(NoSpaceText, 43, -`The highlighted volumes (if any) do not have enough disk space for the currently selected features. You can either remove files from the highlighted volumes, or choose to install fewer features, or choose a different destination drive.') - - <Control Id="VolumeCostListControl" Type="VolumeCostList" - X="23" Width="310" FULLHEIGHT - Sunken="yes" Fixed="yes" Remote="yes"> - <Text>{120}{70}{70}{70}{70}</Text> - </Control> - </Dialog> -') diff --git a/storage/bdb/dist/winmsi/environment.in b/storage/bdb/dist/winmsi/environment.in deleted file mode 100644 index 4f394f73a57..00000000000 --- a/storage/bdb/dist/winmsi/environment.in +++ /dev/null @@ -1,23 +0,0 @@ -# $Id: environment.in,v 1.5 2005/04/15 19:00:19 philipr Exp $ -# Lists environment variables needed to install particular -# features in Windows. Feature names must be -# listed in features.in . The meaning of each line is: -# if a given FEATURE is selected, add to the environment VARIABLE -# the given VALUE (relative to the root of the tree). -# Options may be +first or +last to put it at the beginning or end -# of the variable. The items are processed in the order given here, -# so an entry with +first will no longer be first if another line -# with +first follows it. - -# Note: columns below must be separated by tabs. - -# feature variable value options - -DCoreAPI PATH /bin\\debug +first -CoreAPI PATH /bin +first - -# The debug versions go last, they are preferred if they are installed. -JavaEx CLASSPATH /jar\\dbexamples.jar +last -JavaAPI CLASSPATH /jar\\db.jar +last -DJavaEx CLASSPATH /jar\\debug\\dbexamples.jar +last -DJavaAPI CLASSPATH /jar\\debug\\db.jar +last diff --git a/storage/bdb/dist/winmsi/features.in b/storage/bdb/dist/winmsi/features.in deleted file mode 100644 index ead896050cf..00000000000 --- a/storage/bdb/dist/winmsi/features.in +++ /dev/null @@ -1,33 +0,0 @@ -# $Id: features.in,v 1.5 2005/04/15 19:03:35 philipr Exp $ -# Lists features that can be installed on Windows, -# and their dependencies. - -# Note: columns below must be separated by tabs. -# -# Feature: the feature identifier. If it is dependent on another feature, -# that is specified via Dependent/Featurename -# Short name: the name as it shows in the installer's tree display -# Description: the description that shows when the item is selected -# -# Options are one or more of: -# +default: the feature is installed by default -# +required: the feature cannot be deselected (implies default) -# +invisible: the feature is not shown to the user (implies required) -# - -# feature short name description options - -CoreAPI "Core Features" "C/C++ API and required binaries" +required -CoreAPI/DCoreAPI "Debug Core Features" "" -CoreTools "Tools and Utilities" "Compiled tools for DB maintenance" +default -CoreEx "C/C++ Examples" "C and C++ compiled examples (requires debug libraries to function)" +default - -JavaAPI "Java" "Java API JAR and JNI native libraries" -JavaAPI/JavaEx "Java Examples" "Java examples JAR" -JavaAPI/DJavaAPI "Debug Java" "" -JavaAPI/DJavaAPI/DJavaEx "Debug Java Examples" "" -PerlAPI "Perl" "Perl API .pm and .pod files" -TclAPI "Tcl" "Tcl API binaries" -TclAPI/DTclAPI "Debug Tcl" "" -Docs "Documentation" "Documentation for all products" -Sources "Source files" "Source files for all products" +default diff --git a/storage/bdb/dist/winmsi/files.in b/storage/bdb/dist/winmsi/files.in deleted file mode 100644 index ed04b788dcf..00000000000 --- a/storage/bdb/dist/winmsi/files.in +++ /dev/null @@ -1,89 +0,0 @@ -# $Id: files.in,v 1.8 2005/10/26 13:29:32 dda Exp $ -# Lists files needed to install particular -# features in Windows. Feature names must be -# listed in features.in . -# - -# Note: columns below must be separated by tabs. -# ${PRODUCT_MAJMIN} is a macro for "43" (for BDB 4.3.x) - -# feature source file targdir shortname - -CoreAPI build_win32/Release/libdb${PRODUCT_MAJMIN}.dll /bin/ -DCoreAPI build_win32/Debug/libdb${PRODUCT_MAJMIN}d.dll /bin/debug/ -DCoreAPI build_win32/Debug/db_dll.pdb /bin/debug/ -CoreAPI build_win32/Release/libdb${PRODUCT_MAJMIN}.lib /lib/ -DCoreAPI build_win32/Debug/libdb${PRODUCT_MAJMIN}d.lib /lib/ -CoreAPI build_win32/Release/msvcr71.dll /bin/ -DCoreAPI build_win32/Debug/msvcr71d.dll /bin/debug/ -CoreAPI build_win32/Release/msvcp71.dll /bin/ -DCoreAPI build_win32/Debug/msvcp71d.dll /bin/debug/ - -# After the build process, we create an installed_include directory -# housing all the needed include files, for user convenience -CoreAPI installed_include/ /include/ - -CoreAPI ${PRODUCT_SHARED_WINMSIDIR}/images/webicon.ico /installutil/ -CoreAPI ${PRODUCT_STAGE}/dbvars.bat / - -# We don't include the .lib files for Java, nobody needs to -# link C/C++ against the java library -JavaAPI build_win32/Release/libdb_java${PRODUCT_MAJMIN}.dll /bin/ dbj${PRODUCT_MAJMIN}.dll -DJavaAPI build_win32/Debug/libdb_java${PRODUCT_MAJMIN}d.dll /bin/debug/ dbj${PRODUCT_MAJMIN}d.dll -DJavaAPI build_win32/Debug/db_java.pdb /bin/debug/ -JavaAPI build_win32/Release/db.jar /jar/ -DJavaAPI build_win32/Debug/db.jar /jar/debug/ - -JavaEx build_win32/Release/dbexamples.jar /jar/ dbexam~1.jar -DJavaEx build_win32/Debug/dbexamples.jar /jar/debug/ dbexam~1.jar - -# We don't include the .lib files for Tcl, nobody needs to -# link C/C++ against the Tcl library -DTclAPI build_win32/Debug/libdb_tcl${PRODUCT_MAJMIN}d.dll /bin/debug/ dbt${PRODUCT_MAJMIN}d.dll -DTclAPI build_win32/Debug/db_tcl.pdb /bin/debug/ -TclAPI build_win32/Release/libdb_tcl${PRODUCT_MAJMIN}.dll /bin/ dbt${PRODUCT_MAJMIN}.dll - -PerlAPI perl/BerkeleyDB/blib/ /lib/perl/ - -CoreTools build_win32/Release/db_archive.exe /bin/ db_arc~1.exe -CoreTools build_win32/Release/db_checkpoint.exe /bin/ db_che~1.exe -CoreTools build_win32/Release/db_deadlock.exe /bin/ db_dea~1.exe -CoreTools build_win32/Release/db_dump.exe /bin/ db_dump.exe -CoreTools build_win32/Release/db_load.exe /bin/ db_load.exe -CoreTools build_win32/Release/db_printlog.exe /bin/ db_pri~1.exe -CoreTools build_win32/Release/db_recover.exe /bin/ db_rec~1.exe -CoreTools build_win32/Release/db_stat.exe /bin/ db_sta~1.exe -CoreTools build_win32/Release/db_upgrade.exe /bin/ db_upg~1.exe -CoreTools build_win32/Release/db_verify.exe /bin/ db_ver~1.exe - -CoreEx build_win32/Debug/ex_access.exe /bin/debug/ ex_acc~1.exe -CoreEx build_win32/Debug/ex_access.pdb /bin/debug/ ex_acc~1.pdb -CoreEx build_win32/Debug/ex_btrec.exe /bin/debug/ ex_btr~1.exe -CoreEx build_win32/Debug/ex_btrec.pdb /bin/debug/ ex_btr~1.pdb -CoreEx build_win32/Debug/ex_env.exe /bin/debug/ ex_env.exe -CoreEx build_win32/Debug/ex_env.pdb /bin/debug/ ex_env.pdb -CoreEx build_win32/Debug/ex_lock.exe /bin/debug/ ex_loc~1.exe -CoreEx build_win32/Debug/ex_lock.pdb /bin/debug/ ex_loc~1.pdb -CoreEx build_win32/Debug/ex_mpool.pdb /bin/debug/ ex_mpo~1.pdb -CoreEx build_win32/Debug/ex_mpool.exe /bin/debug/ ex_mpo~1.exe -CoreEx build_win32/Debug/ex_repquote.exe /bin/debug/ ex_rep~1.exe -CoreEx build_win32/Debug/ex_repquote.pdb /bin/debug/ ex_rep~1.pdb -CoreEx build_win32/Debug/ex_tpcb.exe /bin/debug/ ex_tpcb.exe -CoreEx build_win32/Debug/ex_tpcb.pdb /bin/debug/ ex_tpcb.pdb - -CoreEx build_win32/Debug/excxx_access.exe /bin/debug/ excxx_ac.exe -CoreEx build_win32/Debug/excxx_access.pdb /bin/debug/ excxx_ac.pdb -CoreEx build_win32/Debug/excxx_btrec.exe /bin/debug/ excxx_bt.exe -CoreEx build_win32/Debug/excxx_btrec.pdb /bin/debug/ excxx_bt.pdb -CoreEx build_win32/Debug/excxx_env.exe /bin/debug/ excxx_en.exe -CoreEx build_win32/Debug/excxx_env.pdb /bin/debug/ excxx_en.pdb -CoreEx build_win32/Debug/excxx_lock.exe /bin/debug/ excxx_lk.exe -CoreEx build_win32/Debug/excxx_lock.pdb /bin/debug/ excxx_lk.pdb -CoreEx build_win32/Debug/excxx_mpool.exe /bin/debug/ excxx_mp.exe -CoreEx build_win32/Debug/excxx_mpool.pdb /bin/debug/ excxx_mp.pdb -CoreEx build_win32/Debug/excxx_tpcb.exe /bin/debug/ excxx_tp.exe -CoreEx build_win32/Debug/excxx_tpcb.pdb /bin/debug/ excxx_tp.pdb - -Docs ${PRODUCT_STAGE}/docs/ /docs/ - -Sources ${PRODUCT_STAGE}/Sources/ /db-${PRODUCT_VERSION}/ diff --git a/storage/bdb/dist/winmsi/images/caticon.ibd b/storage/bdb/dist/winmsi/images/caticon.ibd Binary files differdeleted file mode 100644 index e8b17bff46f..00000000000 --- a/storage/bdb/dist/winmsi/images/caticon.ibd +++ /dev/null diff --git a/storage/bdb/dist/winmsi/images/foldernew.ibd b/storage/bdb/dist/winmsi/images/foldernew.ibd Binary files differdeleted file mode 100644 index 10824136851..00000000000 --- a/storage/bdb/dist/winmsi/images/foldernew.ibd +++ /dev/null diff --git a/storage/bdb/dist/winmsi/images/folderup.ibd b/storage/bdb/dist/winmsi/images/folderup.ibd Binary files differdeleted file mode 100644 index f1d36969726..00000000000 --- a/storage/bdb/dist/winmsi/images/folderup.ibd +++ /dev/null diff --git a/storage/bdb/dist/winmsi/images/sleepycat.jpg b/storage/bdb/dist/winmsi/images/sleepycat.jpg Binary files differdeleted file mode 100644 index 213167760c4..00000000000 --- a/storage/bdb/dist/winmsi/images/sleepycat.jpg +++ /dev/null diff --git a/storage/bdb/dist/winmsi/images/topstripe.ibd b/storage/bdb/dist/winmsi/images/topstripe.ibd Binary files differdeleted file mode 100644 index be72f906702..00000000000 --- a/storage/bdb/dist/winmsi/images/topstripe.ibd +++ /dev/null diff --git a/storage/bdb/dist/winmsi/images/webicon.ico b/storage/bdb/dist/winmsi/images/webicon.ico Binary files differdeleted file mode 100644 index e8b17bff46f..00000000000 --- a/storage/bdb/dist/winmsi/images/webicon.ico +++ /dev/null diff --git a/storage/bdb/dist/winmsi/links.in b/storage/bdb/dist/winmsi/links.in deleted file mode 100644 index 2907e8cecfa..00000000000 --- a/storage/bdb/dist/winmsi/links.in +++ /dev/null @@ -1,18 +0,0 @@ -# $Id: links.in,v 1.4 2005/10/27 11:00:39 dda Exp $ -# Lists links to Web sites to be installed on Windows. -# If the URL starts with file: it is assumed to be a local file, -# relative to the installation directory. - -# Note: columns below must be separated by tabs. - -# shortname name URL - -sleepycp "Command Prompt" "cmd:dbvars.bat" -sleepywb "Sleepycat Website" "http://www.sleepycat.com" -sleepywb "Sleepycat Developer Zone" "http://dev.sleepycat.com" -sleepych "Change Log for Berkeley DB WIX_DB_VERSION" "http://www.sleepycat.com/update/WIX_DB_VERSION/if.WIX_DB_VERSION.html" -sleepynw "Berkeley DB Newsgroup" "http://groups-beta.google.com/group/comp.databases.berkeley-db" -sleepysu "Support for Berkeley DB" "http://www.sleepycat.com/services/support.html" -sleepyon "Online Documentation" "http://dev.sleepycat.com/documentation/bdb.html" -sleepyst "Company Store" "http://www.companystuffonline.com/sleepycat/" -sleepyld "On disk Documentation" "file:docs/index.html" diff --git a/storage/bdb/dist/winmsi/s_winmsi.fcn b/storage/bdb/dist/winmsi/s_winmsi.fcn deleted file mode 100644 index 3d0ccf83828..00000000000 --- a/storage/bdb/dist/winmsi/s_winmsi.fcn +++ /dev/null @@ -1,1434 +0,0 @@ -# $Id: s_winmsi.fcn,v 1.9 2005/10/26 13:29:34 dda Exp $ -# -# The common functions used by the s_winmsi scripts (both -# for core DB and DB/XML). -# -# This script uses several bash extensions that are convenient -# since we "know" it will always run under Cygwin: shell functions, -# 'return', declaration of 'local' variables, $(command) syntax, -# ${#X} (counting chars), ${X#regexp} (searching) $((expr)) (arithmetic) -# -# These functions use 'global' variables: -# ERRORLOG - a filename -# PRODUCT_NAME - e.g. "Berkeley DB" -# PRODUCT_VERSION - e.g. "4.1.25", derived from dist/RELEASE -# PRODUCT_MAJOR - e.g. "4", (for release 4.1.25) from dist/RELEASE -# PRODUCT_MINOR - e.g. "1", (for release 4.1.25) from dist/RELEASE -# PRODUCT_PATCH - e.g. "25", (for release 4.1.25) from dist/RELEASE -# PRODUCT_MAJMIN - e.g. "41", (for release 4.1.25) from dist/RELEASE -# PRODUCT_STAGE - the staging directory for temp files and builds -# PRODUCT_LICENSEDIR - the tree containing LICENSE and README -# PRODUCT_SUB_BLDDIR - top of the subproduct build e.g. "dbxml-2.0.1/dbxml" -# PRODUCT_BLDDIR - top of the build tree e.g. "dbxml-2.0.1" -# PRODUCT_SRCDIR - the dir we unzip to e.g. "dbxml-2.0.1" -# PRODUCT_DBBUILDDIR - where build_unix dir is for Berkeley DB (for Perl) -# PRODUCT_SHARED_WINMSIDIR - where the master winmsi directory is -# PRODUCT_IMAGEDIR - where the images are (usually winmsi/images) -# PRODUCT_ZIP_FILEFMT - what zip file looks like e.g. "db-X.Y.Z.NC.zip" -# PRODUCT_MSI_FILEFMT - what msi file looks like e.g. "db-X.Y.Z.NC.msi" -# -# Some of these may seem redundant, but there are options to take -# an already built tree from a different place than where we'll unzip -# to and take our sources from, for example. This allows a lot of flexibility -# for development and debugging (especially when these trees can be huge). - -# This is the magic tag that creates a new unique GUID in Wix. -# GUIDs are needed on every <Component ... > entry to ensure -# that the component can be uninstalled. -GENGUID='Guid="GUID_CREATE_UNIQUE()"' -PERSISTGUID='Guid="WIX_DB_PERSISTENT_GUID()"' - -# MakeRtf() -# Standard input is plain text, standard output is RTF. -# -MakeRtf() { - temp1=/tmp/sbm$$a - cat > $temp1 - - -# Courier is a good font, but the lines with all caps -# overflows our current dialog size: -# {\rtf1\ansi\deff0{\fonttbl{\f0\fnil\fcharset0 Courier New;}} -# \viewkind4\uc1\pard\lang1033\f0\fs16 -# -# Using Small fonts works: -# {\rtf1\ansi\deff0{\fonttbl{\f0\fswiss\fprq2\fcharset0 Small Fonts;}} -# {\colortbl ;\red0\green0\blue0;} -# \viewkind4\uc1\pard\cf1\lang1033\f0\fs14 - -# Arial is the best compromise: - sed -e 's/^ *//' << 'EndOfRTFHeader' - {\rtf1\ansi\deff0{\fonttbl{\f0\fswiss\fprq2\fcharset0 Arial;}} - {\colortbl ;\red0\green0\blue0;} - \viewkind4\uc1\pard\cf1\lang1033\f0\fs16 -EndOfRTFHeader - -# Embedded '<' and '>' can cause problems for Wix - sed -e 's:$:\\par:' -e 's:<: \\lquote :' -e 's:>: \\rquote :' < $temp1 - echo -n '}' - rm -f $temp1 -} - -# NextId() -# Get the next available unique id, a simple integer counter. -# We use a file, rather than a shell variable to track the -# number, because this is called from subshells at various -# points, and they cannot affect the variables in the parent shell. -# -ComponentID=component.id -NextId() -{ - local id=`cat $ComponentID 2>/dev/null` - if [ "$id" = '' ]; then - id=0 - fi - id=$(($id + 1)) - echo "$id" > $ComponentID - echo "$id" -} - -# CleanFileName(FILENAME) -# Removes any strange characters in file names, -# returning the new name on standard output. -CleanFileName() -{ - echo "$1" | sed -e 's/[-%@!]//g' -} - -# GetShortName(FILENAME) -# Get a Windows short name for the file, -# to fit into the 8.3 name space. -# This is not a great algorithm, but it works. -# The fact is, the names must be unique, but on -# Win2000 and WinXP, we'll never see them. - -ShortID=short.id -GetShortName() -{ - local name=`echo "$1" | tr '[a-z]' '[A-Z]'` - - # See if the name fits into 8.3. If so, - # return it right away. - # - case "$name" in - ?????????*.* ) ;; - *.????* ) ;; - *.*.* ) ;; - *[-%@!]* ) ;; - *.* ) echo "$name" - return - ;; - * ) - if [ "${#1}" -le 8 ]; then - echo "$name" - return - fi - ;; - esac - - # From NAMEISLONG.EXTLONG, build a name - # like NAME~ZZZ.EXT, where ZZZ is a unique (hex) - # number we build. This is - - local id=`cat $ShortID 2>/dev/null` - if [ "$id" = '' ]; then - id=0 - fi - id=$(($id + 1)) - echo "$id" > $ShortID - if [ "$id" -ge 4096 ]; then - echo "BADBADBAD.TXT" # return something that will give an error - Error "ShortId overflow" - exit 1 - fi - - # Convert the id to hex (I ran out of space using decimal) - # This is too slow: id=`echo 16 o $id p | dc` - id=`printf "%x" $id` - - # Collect and clean up the part of the name before, and after, the dot - local before=`CleanFileName "$name" | sed -e 's/^\([^.]*\)[.].*$/\1/'` - local after=`CleanFileName "$name" | sed -e 's/^[^.]*[.]\(.*\)$/\1/'` - - # Make sure the before part fits in 5 chars (not 8, since - # we need a few for the unique number). - if [ "${#before}" -gt 5 ]; then - before=`echo "$before" | sed -e 's/^\(.....\).*/\1/'` - fi - if [ "${#after}" -gt 3 ]; then - after=`echo "$after" | sed -e 's/^\(...\).*/\1/'` - fi - echo "${before}~${id}.${after}" -} - -# Progress([OPTION,]STRING...) -# Show a major processing step via echo to stdout and to the error log. -# An OPTION is "-minor", indicating no big banner. -# -Progress() -{ - if [ "$1" = -minor ]; then - shift - else - echo "" >> $ERRORLOG - echo "============================" >> $ERRORLOG - fi - echo "$@" >> $ERRORLOG - echo "$@" >&15 -} - -# Error(STRING...) -# Show an error in a standard way. -# -Error() -{ - echo "" >> $ERRORLOG - echo "****************** FAIL ******************" >> $ERRORLOG - echo "ERROR: $@" >> $ERRORLOG - echo "ERROR: $@" >&15 - echo "See $ERRORLOG for details" >&15 - return 1 -} - -# RequireFileInPath(NAME, PATHVAL, FILE) -# Look for FILE in the path that has value PATHVAL. -# The path's name is NAME if it needs to be shown. -# -RequireFileInPath() -{ - local type="$1" - local origpath="$2" - local file="$3" - local upath="$origpath" - if [ "$1" != PATH ]; then - upath=`cygpath -up "$origpath"` - fi - - SAVEIFS="$IFS" - IFS=":" - found=no - for dir in $upath; do - if [ -f "$dir/$file" ]; then - IFS="$SAVEIFS" - return - fi - done - IFS="$SAVEIFS" - Error "File $file not found in $type path: $origpath" - exit 1 -} - -# Rand4X() -# Return 4 random hex digits on output -# -Rand4X() { - # The sed command pads the front with 0's as needed - (echo 'obase=16'; echo $RANDOM ) | bc | - sed -e 's/^/0000/' -e 's/^.*\(....\)$/\1/' - -} - -# RunM4() -# Run M4, making appropriate substitutions. -# This function uses GLOBAL variables: PRODUCT_VERSION (e.g. "4.1.25") -# and PRODUCT_LICENSEDIR, which is where certain text files are found -# -RunM4() { - - # Given a version number, like 2.3.45, we want to - # create a 8 character name for the directory like db2_3_45. - # This name is under a "Sleepycat Software" directory, - # so it only needs to be unique within the universe of BDB versions. - # TODO: instead of using a version number like $DB_VERSION, - # maybe use $DB_VERSION_UNIQUE_NAME which looks like "_2003" - - local DB_8CHAR_VERSION=`echo $PRODUCT_VERSION | sed -e 's/[.]/_/g'` - if [ ${#DB_8CHAR_VERSION} -le 6 ]; then - DB_8CHAR_VERSION="db$DB_8CHAR_VERSION" - elif [ ${#DB_8CHAR_VERSION} -le 7 ]; then - DB_8CHAR_VERSION="d$DB_8CHAR_VERSION" - else - Error "Version number too large for simple version number algorithm" - exit 1 - fi - - # Remove leading ./ from PRODUCT_LICENSEDIR if present. - local licensedir=`cygpath -w "$PRODUCT_LICENSEDIR"` - - # Create a GUID prefix of the form: ????????-????-????-????-???? - # This leaves 8 digits of GUID to be manipulated by m4. - local GUID_PREFIX="`Rand4X``Rand4X`-`Rand4X`-`Rand4X`-`Rand4X`-`Rand4X`" - - # -P requires that all m4 macros, like define, eval, etc. - # are prefixed, like m4_define, m4_eval, etc. This avoids - # various name conflicts with input files. - # TODO: rename DB_SRCDIR as DB_LICENSEDIR - m4 -P \ - -DWIX_DB_VERSION="$PRODUCT_VERSION" \ - -DWIX_DB_8CHAR_VERSION="$DB_8CHAR_VERSION" \ - -DWIX_DB_GUID_PREFIX="$GUID_PREFIX" \ - -DWIX_DB_PRODUCT_NAME="$PRODUCT_NAME" \ - -DWIX_DB_SRCDIR="$licensedir" \ - -DWIX_DB_TOP="`cygpath -w $PRODUCT_BLDDIR`" \ - -DWIX_DB_SHARED_WINMSIDIR="$PRODUCT_SHARED_WINMSIDIR" \ - -DWIX_DB_IMAGEDIR="`cygpath -w $PRODUCT_IMAGEDIR`" \ - -DWIX_DB_FEATURE_STRUCTURE="m4_include(features.wixinc)" \ - -DWIX_DB_DIRECTORY_STRUCTURE="m4_include(directory.wixinc)" \ - -DWIX_DB_LINKS="m4_include(links.wixinc)" \ - -DWIX_DB_LICENSE_RTF="m4_include(license.rtf)" \ - -DWIX_DB_ENV_FEATURE_PROPS="m4_include(envprops.wixinc)" \ - -DWIX_DB_ENV_FEATURE_SET="m4_include(envset.wixinc)" \ - -DWIX_DB_ENV_FEATURE_SHOW="m4_include(envshow.wixinc)" -} - -# RunTallow(DIR, OPTIONS) -# Run Tallow, a tool from the WiX distribution -RunTallow() { - local dir="$1" - shift - - Id1=`NextId` - Id2=`NextId` - Id3=`NextId` - - # Tallow is a tool that walks a tree, producing - # a WiX directory heirarchy naming the files. - # The IDs it produces are not unique (between tallow - # runs), so we must make them so here. Thus "directory78" - # becomes "MyFeatureName.123.78" where 123 is an id from NextId. - # Secondly, instead of using the tallow output as a separately - # compiled fragment, we want to include it directly, so - # we need to strip out some extraneous XML entries at the top - # and bottom of its output. - # - # Another thing we do is when we see <Directory></Directory> - # pairs, we call m4 macros WIX_DB_{BEGIN,END}_SUBDIR because - # we need to track the current directory to generate 'persistent' - # GUIDs. See the discussion about GUIDs in dbwix.m4 . - # - # !!! For stripping out the extraneous XML, we rely heavily - # !!! on the output format, so this is likely to be fragile - # !!! between versions of tallow. Fortunately, it should fail hard. - # - echo "=============" >> tallow.log - echo tallow -nologo -d `cygpath -w "$dir"` "$@" >> tallow.log - echo " <!-- TALLOW output begins here -->" - tallow -nologo -d `cygpath -w "$dir"` "$@" > tallow.out || exit 1 - cat tallow.out >> tallow.log - echo "-------------" >> tallow.log - - sed -e '1,/<DirectoryRef/d' -e '/<\/DirectoryRef/,$d' \ - -e "s/Id=\"directory/Id=\"$feature.$Id1./" \ - -e "s/Id=\"component/Id=\"$feature.$Id2./" \ - -e "s/Id=\"file/Id=\"$feature.$Id3./" \ - -e '/^ <Directory/d' \ - -e '/^ <\/Directory/d' \ - -e '/<Directory/s/Name=\"\([^"]*\)"/Name="\1" WIX_DB_BEGIN_SUBDIR(\1) /' \ - -e '/<\/Directory>/s/$/ WIX_DB_END_SUBDIR()/' \ - -e "/<Component/s/>/ $PERSISTGUID>/" \ - < tallow.out > tallow.postsed || exit 1 - - echo 'WIX_DB_SET_CURFILE()' - echo 'WIX_DB_CLEAR_SUBDIR()' - cat tallow.postsed - echo 'WIX_DB_CLEAR_SUBDIR()' - - cat tallow.postsed >> tallow.log - echo " <!-- TALLOW output ends here -->" -} - -# ProcessFeatures(INFILES, INFEATURES, INENV, OUTDIRECTORIES, OUTFEATURES, -# OUTSET) -# Use the files.in and features.in files as -# input to create two output files, one containing a WiX XML -# fragment showing directories and needed files, -# and another containing a WiX XML fragment showing -# the features in a dependency tree. -# -# This creates the heart of the installer flexibility. -# -ProcessFeatures() { - InFiles="infiles.tmp"; CleanInputFile "$1" "$InFiles" 3 4 - InFeatures="infeatures.tmp"; CleanInputFile "$2" "$InFeatures" 3 4 - InEnv="inenv.tmp"; CleanInputFile "$3" "$InEnv" 3 4 - OutDirs="$4" - OutFeatures="$5" - OutSet="$6" - - rm -f $OutDirs; touch $OutDirs - rm -f $OutFeatures; touch $OutFeatures - - # Initialize the feature list. - # This will be expanded (per feature) in ProcessOneFeature - # - XmlLevel=4 - Xecho "<Publish Property=\"FeatureList\" Value=\"[NULL]\">" >> $OutSet - Xecho " <![CDATA[1]]></Publish>" >> $OutSet - - Dirs=`cut -f 3 < $InFiles | sort | uniq` - Prevdir="/" - ProcessDirTransition "$Prevdir" "/" >> $OutDirs - - for Dir in $Dirs; do - ProcessDirTransition "$Prevdir" "$Dir" >> $OutDirs - ProcessOneDirectory "$Dir" < $InFiles >> $OutDirs || exit 1 - Prevdir="$Dir" - done - ProcessDirTransition "$Prevdir" "/" >> $OutDirs - - cat $InEnv | ( - read line - while [ "$line" != '' ]; do - local FeatureName=`echo "$line" | cut -f 1` - local EnvVariable=`echo "$line" | cut -f 2` - local EnvValue=`echo "$line" | cut -f 3` - local EnvOption=`echo "$line" | cut -f 4` - ProcessOneEnv "$FeatureName" "$EnvVariable" "$EnvValue" "$EnvOption" "$OutDirs" "$OutSet" - read line - done - return 0 - ) || Error "Error processing environment" || exit 1 - - cat $InFeatures | ( - read line - while [ "$line" != '' ]; do - local FeaturePath=`echo "$line" | cut -f 1` - local ShortName=`echo "$line" | cut -f 2 | StripDoubleQuotes` - local Description=`echo "$line" | cut -f 3 | StripDoubleQuotes` - local FeatureOptions=`echo "$line" | cut -f 4 | StripDoubleQuotes` - ProcessOneFeature "$FeaturePath" "$ShortName" "$Description" "$FeatureOptions" "$OutDirs" "$OutFeatures" "$OutSet" - read line - done - return 0 - ) || Error "Error processing features" || exit 1 - -# (PBR) -# This test code didn't work. My hope was that I could force INSTALLLEVEL -# to 4 and this would then enable the debug features. -# Xecho "<Publish Property=\"INSTALLLEVEL\" Value=\"4\" />" >> $OutSet -# Xecho "<Publish Event=\"SetInstallLevel\" Value=\"4\" />" >> $OutSet - -} - -# ProcessLinks(INLINKS, OUTFEATURES) -# Process the INLINKS file, and produce XML on stdout. -# Each line of the input file requires the creation -# of a '.URL' file in the installation, and a Shortcut -# in the Windows menu to point to that. -# Also add the components generated to a feature, put in OUTFEATURES. -# -# TODO: We ought to have a Features column in the links.in file, -# otherwise, the local doc link is always installed. -# -ProcessLinks() { - # Set a var to a carriage return without actually putting one in this file - local CR=`echo A | tr A '\015'` - local InLinks="infiles.tmp"; CleanInputFile "$1" "$InLinks" 3 4 - local here_win=`cygpath -w $(pwd)` - # TODO: maybe get a real modification time, but not sure why we need it. - local MODTIMEHEX="0000000007DCC301DE" - XmlLevel=6 - local OutFeatures="$2" - - Xecho + "<Feature Id=\"LinksFeature\" Title=\"Links\"" >> $OutFeatures - Xecho " Description=\"Links\" Display=\"hidden\"" >> $OutFeatures - Xecho " Level=\"1\" AllowAdvertise=\"no\"" >> $OutFeatures - Xecho " ConfigurableDirectory=\"INSTALLUTIL\"" >> $$OUTFeatures - Xecho " Absent=\"disallow\">" >> $OutFeatures - - Xecho "<DirectoryRef Id=\"INSTALLUTIL\">" - Xecho " <Directory Id=\"INSTALLURL\" Name=\"url\">" - Xecho "WIX_DB_SET_CURDIR(/installutil/url)" - cat $InLinks | ( - read line - while [ "$line" != '' ]; do - local Shortname=`echo "$line" | cut -f 1 | StripDoubleQuotes` - local Name=`echo "$line" | cut -f 2 | StripDoubleQuotes` - local Url=`echo "$line" | cut -f 3 | StripDoubleQuotes` - read line - - # We register the name .bdbsc extension to get the proper icon - local UrlName="$Shortname.bdbsc" - local UrlShortName="$Shortname.d1b" - local TargetFile="[INSTALLDIR]\\installutil\\url\\$UrlName" - local CreateUrlFile=true - local CommandShortcut=false - local Program="" - case "$Url" in - file:* ) CreateUrlFile=false - TargetFile=`echo $Url | sed -e 's/file://'` - TargetFile="[INSTALLDIR]"`cygpath -w $TargetFile`;; - cmd:* ) CreateUrlFile=false - UrlName="$Shortname.bat" - UrlShortName="$Shortname.bat" - TargetFile="[INSTALLDIR]\\installutil\\url\\$UrlName" - Program=`echo $Url | sed -e 's/cmd://'` - CommandShortcut=true;; - esac - - Xecho "WIX_DB_SET_CURFILE($Shortname)" - Xecho + "<Component Id=\"Links.$Shortname\"" - Xecho " $PERSISTGUID" - Xecho " SharedDllRefCount=\"yes\" Location=\"either\">" - - if $CreateUrlFile; then - echo "[Default]$CR" > $UrlName - echo "BASEURL=$Url$CR" | RunM4 >> $UrlName || exit 1 - echo "[InternetShortcut]$CR" >> $UrlName - echo "URL=$Url$CR" | RunM4 >> $UrlName || exit 1 - echo "Modified=$MODTIMEHEX$CR" >> $UrlName - # TODO: we could have an Entry for IconFile=sleepyweb.ico IconIndex=1? - echo '' - Xecho "<File Id=\"File.$Shortname\" " - Xecho " LongName=\"$UrlName\" Name=\"$UrlShortName\"" - Xecho " Compressed=\"yes\" DiskId=\"1\"" - Xecho " src=\"$here_win\\$UrlName\" />" - fi - - if $CommandShortcut; then - echo "@echo off" > $UrlName - echo "set DBROOTDIR=" >> $UrlName - echo "for /F \"tokens=3 delims= \" %%A in ('REG QUERY \"HKLM\\SOFTWARE\\Sleepycat Software\\$PRODUCT_NAME\\$PRODUCT_VERSION\" /v RootDirectory') do set DBROOTDIR=%%A" >> $UrlName - echo "if ERRORLEVEL 2 goto MISSING" >> $UrlName - echo "if not defined DBROOTDIR goto MISSING" >> $UrlName - echo "set FN=\"%DBROOTDIR%$Program\"" >> $UrlName - echo "if not exist %FN% goto NOTFOUND" >> $UrlName - echo "cmd /k \"%DBROOTDIR%$Program\"$CR" >> $UrlName - echo "goto END" >> $UrlName - echo ":NOTFOUND" >> $UrlName - echo "echo" >> $UrlName - echo "echo Error: The program does not appear to be installed." >> $UrlName - echo "echo" >> $UrlName - echo "cmd /k" >> $UrlName - echo "goto END" >> $UrlName - echo ":MISSING" >> $UrlName - echo "echo" >> $UrlName - echo "echo NOTE:" >> $UrlName - echo "echo The $PRODUCT_NAME version could not be determined." >> $UrlName - echo "echo If you are running on Windows 2000, make sure the" >> $UrlName - echo "echo REG.EXE program is installed from the Tools disk" >> $UrlName - echo "echo" >> $UrlName - echo "cmd /k" >> $UrlName - echo ":END" >> $UrlName - - Xecho "<File Id=\"File.$Shortname\" " - Xecho " LongName=\"$UrlName\" Name=\"$UrlShortName\"" - Xecho " Compressed=\"yes\" DiskId=\"1\"" - Xecho " src=\"$here_win\\$UrlName\" />" - - Xecho "<Shortcut Id=\"Short.$Shortname\" Directory=\"BerkeleyDbMenu\"" - Xecho " Name=\"$Shortname\" LongName=\"$Name\"" - Xecho " WorkingDirectory=\"[INSTALLDIR]\"" - Xecho " Target='$TargetFile'" - Xecho " Show=\"normal\" />" - else - Xecho "<Shortcut Id=\"Short.$Shortname\" Directory=\"BerkeleyDbMenu\"" - Xecho " Name=\"$Shortname\" LongName=\"$Name\"" - Xecho " Target='$TargetFile'" - Xecho " Show=\"normal\" />" - fi - - - Xecho - "</Component>" - - Xecho "<ComponentRef Id=\"Links.$Shortname\" />" >> $OutFeatures - done - return 0 - ) || Error "Error processing links" || exit 1 - - Xecho "</Directory>" - Xecho "</DirectoryRef>" - Xecho - "</Feature>" >> $OutFeatures -} - -# ProcessOneDirectory(DIRECTORYNAME) -# Called by ProcessFeatures. -# Argument is the directory name to process -# Standard input is cleaned up files.in (dirname is 3rd column) -# Standard output will be WiX XML Component/File entries -# -ProcessOneDirectory() -{ - Dir="$1" - grep " ${Dir} " | ( - read line - while [ "$line" != '' ]; do - local feature=`echo "$line" | cut -f 1` - local srcfile=`echo "$line" | cut -f 2` - local targetdir=`echo "$line" | cut -f 3` - local shortname=`echo "$line" | cut -f 4` - - ProcessOneDirectoryFile "$feature" "$srcfile" "$targetdir" "$shortname" || exit 1 - read line - done - return 0 - ) || Error "Error processing directory $Dir" || exit 1 -} - -# ProcessOneDirectoryFile(DIRECTORYNAME) -# Called by ProcessOneDirectory to process a single file in a directory. -# Standard output will be a single WiX XML Component/File entries -# -ProcessOneDirectoryFile() -{ - local feature="$1" - local srcfile="$2" - local targetdir="$3" - local shortname="$4" - local base=`basename $srcfile` - - #echo "processing file $srcfile in $feature to directory $targetdir..." >&2 - - # Prepend the WIX_DB_TOP unless the source file is absolute - - local root= - local checkfile= - local wsrcfile= - - case "$srcfile" in - /* ) root="" - wsrcfile=`cygpath -w $srcfile` - checkfile="$srcfile" - ;; - * ) root="$PRODUCT_BLDDIR/" - wsrcfile="WIX_DB_TOP()\\`cygpath -w $srcfile`" - checkfile="$PRODUCT_BLDDIR/$srcfile" - ;; - esac - - # If srcfile ends in / then we'll use tallow to walk the directory - case "$srcfile" in - */ ) if [ ! -d "$root$srcfile" ]; then - Error "$root$srcfile: not a directory" - exit 1 - fi - Progress -minor " expanding $root$srcfile..." - RunTallow "$root$srcfile" - return 0 - ;; - *'*'* ) - local dirname=`dirname "$root$srcfile"` - RunTallow "$dirname" -df "$base" - return 0 - ;; - esac - - if [ "$shortname" = '' ]; then - shortname=`GetShortName "$base"` - fi - ID=`NextId` - - if [ ! -r "$checkfile" ]; then - Error "$srcfile: file in feature $feature does not exist" - Error " curdir=`pwd`, pathname=$checkfile" - exit 1 - fi - - Xecho "WIX_DB_SET_CURFILE(${base})" - Xecho + "<Component Id=\"$feature.$ID\" Location=\"either\" $PERSISTGUID>" - Xecho "<File Id=\"${feature}.${ID}\" Name=\"${shortname}\" LongName=\"${base}\" Compressed=\"yes\" KeyPath=\"yes\" DiskId=\"1\" src=\"${wsrcfile}\" />" - Xecho - "</Component>" - return 0 -} - -# ProcessOneFeature(FEATUREPATH, SHORTNAME, DESCRIPTION, OPTS, INDIRECTORYFILE, -# OUTFEATURE, OUTSET) -# Called by ProcessFeatures to process a line in the features.in file. -# The first three arguments are the values of the first three columns: -# the feature dependency path (e.g. "Java/JavaExamples"), the short -# name, and a descriptive name. The last argument is the directory -# file that lists the components. We use the last name of the feature -# path (e.g. JavaExamples) to locate all components (really directories) -# named accordingly, so they can be listed as needed parts of the Feature. -# Standard output will be WiX XML Feature entries. -# -ProcessOneFeature() { - local featurename="$1" - local shortname="$2" - local opts="$4" - local dirfile="$5" - local outfeature="$6" - local outset="$7" - - XmlLevel=4 - local featcount=0 - local featurestring="" - if [ $(SlashCount $featurename) -gt 0 ]; then - local parent=`echo $featurename | sed -e 's:/[^/]*$::' -e 's:.*/::'` - featurename=`echo $featurename | sed -e 's:^.*/::'` - featcount=1 - Xecho "<FeatureRef Id=\"$parent\">" >> $outfeature - fi - - - # TODO: how to get +default to work? - # have tried messing with level="0" (doesn't show it) - # InstallDefault=\"source\" (doesn't make a difference) - # - local leveldebug="Level=\"4\"" - local levelparam="Level=\"1\"" - local leveldisable="Level=\"0\"" - local defparam="InstallDefault=\"source\"" - local displayparam="Display=\"expand\"" - local params="AllowAdvertise=\"no\"" - local regfeature="" - - local descparam="" - if [ "$3" != '' ]; then - descparam="Description=\"$3\"" - fi - - local opt - local reqtext="" - local isdebugFeature=false - for opt in $opts; do - case "$opt" in - +default ) ;; - +required ) params="$params Absent=\"disallow\"" - reqtext=" (required)";; - +invisible ) displayparam="Display=\"hidden\"" - params="$params Absent=\"disallow\"";; - +debug ) isdebugFeature=true;; - - * ) Error "features.in: Bad option $opt" - exit 1;; - esac - done - - -# (PBR) -# I tried to get debugging features to work but I could not. The last thing I -# tried was to set either ADDSOURCE or INSTALLLEVEL. Neither of these solutions -# will cause the feature conditions to rerun. The only thing I've found to do -# that is to rerun CostFinalize. The problem with this is it will re-enable all -# the options again. I'm keeping the basic framework for +debug support - if "$isdebugFeature"; then - regfeature="${featurename:1}" - echo "regfeature = $regfeature" - - Xecho + "<Feature Id=\"$featurename\" Title=\"$shortname$reqtext\" $descparam $params $displayparam $leveldebug $defparam>" >> $outfeature - else - Xecho + "<Feature Id=\"$featurename\" Title=\"$shortname$reqtext\" $descparam $params $displayparam $levelparam $defparam>" >> $outfeature - fi - - - grep 'Component.*Id="'$featurename'[.0-9]*"' "$dirfile" | sed -e 's/\(Id="[^"]*"\).*/\1 \/>/' -e 's/Component /ComponentRef /' >> $outfeature - - # Create a separate subfeature for any environment variables - # associated with the main feature. - # The <Condition> stuff is the magic that enables/disables - # setting the environment variables depending on the check box property. - - Xecho + "<Feature Id=\"env.$featurename\" Title=\"env vars\" $params Display=\"hidden\" $levelparam $defparam>" >> $outfeature - - Xecho "<Condition $leveldisable><![CDATA[EnvironmentSetCheck<>1]]></Condition>" >> $outfeature - Xecho "<Condition $levelparam><![CDATA[EnvironmentSetCheck=1]]></Condition>" >> $outfeature - grep 'Component.*Id="env\.'$featurename'[.0-9]*"' "$dirfile" | sed -e 's/\(Id="[^"]*"\).*/\1 \/>/' -e 's/Component /ComponentRef /' >> $outfeature - - Xecho - "</Feature>" >> $outfeature - Xecho - "</Feature>" >> $outfeature - - while [ "$featcount" -gt 0 ]; do - Xecho - "</FeatureRef>" >> $outfeature - featcount=$(($featcount - 1)) - done - - # Append the name to the feature list if it is to be installed. - # This publish fragment gets 'executed' when leaving the - # dialog to select features. Note that we have to quote - # the comma for m4 (`,') since this appears in a macro usage. - # - -# (PBR) -# This code sets ADDSOURCE to show which debug options to include. This does not work - # If this is a debug feature, only turn on the value if the parent is on - if "$isdebugFeature"; then - regfeature="${featurename:1}" - -# Xecho "<Publish Property=\"ADDSOURCE\" Value=\"[ADDSOURCE]\`,'\">" >> $outset -# Xecho " <![CDATA[&${regfeature} = 3 AND DebugCheck=\"yes\" AND ADDSOURCE <> NULL]]></Publish>" >> $outset - -# Xecho "<Publish Property=\"ADDSOURCE\" Value=\"[ADDSOURCE]${featurename}\">" >> $outset -# Xecho " <![CDATA[&${regfeature} = 3 AND DebugCheck=\"yes\"]]></Publish>" >> $outset - - Xecho "<Publish Property=\"FeatureList\" Value=\"[FeatureList]\`,' ${shortname}\">" >> $outset - Xecho " <![CDATA[&${regfeature} = 3 AND DebugCheck=\"yes\"]]></Publish>" >> $outset - - else - Xecho "<Publish Property=\"FeatureList\" Value=\"[FeatureList]\`,' ${shortname}\">" >> $outset - Xecho " <![CDATA[&${featurename} = 3]]></Publish>" >> $outset - fi -} - -# ProcessOneEnv(FEATURE, ENVNAME, ENVVALUE, OPTS, OUTDIRS, OUTSET) -# Called by ProcessFeatures to process a line in the environment.in file. -# The four arguments are the values of the four columns. -# The output will be into two files: -# OUTDIRS: WiX XML Component entries, that contain environment values. -# This controls the actual setting of the variables. -# OUTSET: WiX XML to set the installer variables if an env variable -# is set or a feature selected. -# -ProcessOneEnv() { - local feature="$1" - local envname="$2" - local envvalue="$3" - local opts="$4" - local outdirs="$5" - local outset="$6" - - # Make the path uniform. - # echo "c:\Program Files\...\/Lib/Hello" | sed -e 's:\\/:\\:' -e 's:/:\\:g` - # This produces c:\Program Files\...\Lib\Hello - case "$envvalue" in - /* ) envvalue=`echo "$envvalue" | sed -e 's:^/::'` - esac - - local path="[INSTALLDIR]$envvalue" - - local opt - part="last" - for opt in $opts; do - case "$opt" in - +first ) part="first";; - +last ) part="last";; - * ) Error "environment.in: Bad option $opt" - exit 1;; - esac - done - - # Generate the OUTDIRS fragment - # This looks like: - # - # <Component Id="env.CoreAPI.43" Guid="4B75755F-1129-292C-3434-238410000247"> - # <Environment Id="env.44" Name="+-LIB" Action="set" - # Permanent="no" Part="first" Value="[INSTALLDIR]Lib" /> - # </Component> - # - # Having a unique guid makes uninstall work. - # Note: We really want these installed as System rather than - # User vars (using the System="yes" tag), but only if user - # installs for *all* users. There is no convenient way to - # do that, so we leave them as default (User variables). - - - XmlLevel=4 - local Id=`NextId` - Xecho "WIX_DB_SET_CURFILE(${envname})" >> $outdirs - Xecho + "<Component Id=\"env.$feature.$Id\" $PERSISTGUID>" >> $outdirs - Id=`NextId` - - Xecho "<Environment Id=\"env.$Id\" Name=\"+-$envname\" Action=\"set\"" >> $outdirs - Xecho " Permanent=\"no\" Part=\"$part\" Value=\"$path\" />" >> $outdirs - - Xecho "</Component>" >> $outdirs - - # Generate the OUTSET fragment - # This looks like: - # - # <Publish Property="CLASSPATHValue" Value="[INSTALLDIR]Lib/db.jar;[CLASSPATHValue]"> - # <![CDATA[&JavaAPI = 3]]></Publish> - # <Publish Property="CLASSPATHEscValue" Value="[INSTALLDIR]Lib/db.jar;[CLASSPATHEscValue]"> - # <![CDATA[&JavaAPI = 3]]></Publish> - # - # This is equivalent to pseudocode: - # if (InstallFeature(JavaAPI)) { - # Prepend CLASSPATHValue with "Lib/db.jar;" - # Prepend CLASSPATHEscValue with "Lib/db.jar;" - # } - # - XmlLevel=4 - Xecho "<Publish Property=\"${envname}Value\" Value=\"[INSTALLDIR]${envvalue};[${envname}Value]\">" >> $outset - Xecho " <![CDATA[&${feature} = 3]]></Publish>" >> $outset - - Xecho "<Publish Property=\"${envname}EscValue\" Value=\"[INSTALLDIR]${envvalue};[${envname}EscValue]\">" >> $outset - Xecho " <![CDATA[&${feature} = 3]]></Publish>" >> $outset - - -} - -# CreateProperty(ID, VALUE) -# Generate a <Property...> tag on the stdout -CreateProperty() { - Xecho "<Property Id=\"$1\" Hidden=\"yes\"><![CDATA[$2]]></Property>" -} - -# ProcessTagProperties(OUTPROPS) -# Generate some identification tags as properties. -# This will let us look at an installer and figure out -# when it was built, etc. -ProcessTagProperties() { - local outprops="$1" - local insdate=`date` - XmlLevel=4 - - CreateProperty _DB_MSI_INSTALLER_DATE "$insdate" >> $outprops - CreateProperty _DB_MSI_PRODUCT_NAME "$PRODUCT_NAME" >> $outprops - CreateProperty _DB_MSI_PRODUCT_VERSION "$PRODUCT_VERSION" >> $outprops - CreateProperty ARPCOMMENTS "Installer for $PRODUCT_NAME $PRODUCT_VERSION built on $insdate" >> $outprops -} - -# ProcessEnv(INENVFILE, INBATFILE, OUTPROPS, OUTSET, OUTSHOW) -# We generate some Property magic to show the user what is set. -# -ProcessEnv() { - InEnv="inenv.tmp"; CleanInputFile "$1" "$InEnv" 3 4 - inbat="$2" - outprops="$3" - outset="$4" - outshow="$5" - - # Get a list of the environment variables - local envvar - local envvars=`cut -f 2 < $InEnv | sort | uniq` - - # For each environment var, create lines that declare - # a pair of properties in the envprops.wixinc file like: - # - # <Property Id="CLASSPATHValue" Hidden="yes"></Property> - # <Property Id="CLASSPATHEscValue" Hidden="yes"></Property> - # - # And create lines in the envset.wixinc file like: - # - # <Publish Property="CLASSPATHValue" Value="%CLASSPATH%"> - # <![CDATA[1]]></Publish> - # <Publish Property="CLASSPATHEscValue" Value="\\%CLASSPATH\\%"> - # <![CDATA[1]]></Publish> - # - # More will be added to that file later. - # Then, create lines in the envshow.wixinc file like: - # - # <Control Id="CLASSPATHText" Type="Text" - # X="23" Width="316" PARTIALHEIGHT(10, 2) - # TabSkip="no" Text="CLASSPATH:" /> - # - # <Control Id="CLASSPATHValueText" Type="Text" - # X="37" Width="316" PARTIALHEIGHT(20, 7) - # TabSkip="no" Text="[CLASSPATHValue]" /> - - for envvar in $envvars; do - XmlLevel=4 - CreateProperty "${envvar}Value" "" >> $outprops - CreateProperty "${envvar}EscValue" "" >> $outprops - - XmlLevel=4 - Xecho "<Publish Property=\"${envvar}Value\" Value=\"%${envvar}%\">" >> $outset - Xecho " <![CDATA[1]]></Publish>" >> $outset - Xecho "<Publish Property=\"${envvar}EscValue\" Value=\"\\%${envvar}\\%\">" >> $outset - Xecho " <![CDATA[1]]></Publish>" >> $outset - - XmlLevel=4 - Xecho "<Control Id=\"${envvar}Text\" Type=\"Text\"" >> $outshow - Xecho " X=\"23\" Width=\"316\" PARTIALHEIGHT(10, 2)" >> $outshow - Xecho " TabSkip=\"no\" Text=\"${envvar}:\" />" >> $outshow - - Xecho "<Control Id=\"${envvar}ValueText\" Type=\"Text\"" >> $outshow - Xecho " X=\"37\" Width=\"316\" PARTIALHEIGHT(20, 7)" >> $outshow - Xecho " TabSkip=\"no\" Text=\"[${envvar}Value]\" />" >> $outshow - - done - - # Create the dbvars.bat file from the .bat template file - # TODO: the bat template file currently knows the variables - # and their values, it should get them from the environment.in - - RunM4 <"$inbat" >"$PRODUCT_STAGE/dbvars.bat" || Error "m4 failed" || exit 1 -} - - -# CleanInputFile(INFILENAME, OUTFILENAME, MINELEMENTS, MAXELEMENTS) -# A filter to preprocess and validate input files. -# We end up without comment lines, a single tab between elements, -# and a trailing tab. -# Also some selected shell variables are expanded for convenience. -# We verify that each line has the number of elements that fall within -# the given min and max. -# -CleanInputFile() { - sed \ - -e 's/#.*//' \ - -e 's/ * / /g' \ - -e 's/ */ /g' \ - -e '/^[ ]*$/d' \ - -e 's/$/ /' \ - -e 's/ */ /g' \ - -e 's:\${PRODUCT_VERSION}:'"${PRODUCT_VERSION}":g \ - -e 's:\${PRODUCT_MAJOR}:'"${PRODUCT_MAJOR}":g \ - -e 's:\${PRODUCT_MINOR}:'"${PRODUCT_MINOR}":g \ - -e 's:\${PRODUCT_PATCH}:'"${PRODUCT_PATCH}":g \ - -e 's:\${PRODUCT_MAJMIN}:'"${PRODUCT_MAJMIN}":g \ - -e 's:\${PRODUCT_STAGE}:'"${PRODUCT_STAGE}":g \ - -e 's:\${PRODUCT_SHARED_WINMSIDIR}:'"${PRODUCT_SHARED_WINMSIDIR}":g \ - < "$1" > "$2" - - # count tabs on each line - sed -e 's/[^ ]//g' -e 's/[ ]/x/g' < "$2" | ( - read line - linecount=1 - while [ "$line" != '' ]; do - chars=`echo "$line" | wc -c` - chars=$(($chars - 1)) # Remove newline - if [ "$chars" -lt "$3" -o "$chars" -gt "$4" ]; then - Error "$1: Input file error on or after line $linecount" - fi - read line - linecount=$(($linecount + 1)) - done - ) -} - -# StripDoubleQuotes() -# In some input files, we allow double quotes around -# multi-word strings for readability. We strip them -# here from standard input and write to standard output. -# We only expect them at the beginning and end. -# -StripDoubleQuotes() { - sed -e 's/^"//' -e 's/"$//' -} - -# IndentXml(PLUSMINUS_ARG) -# A global variable $XmlLevel is kept for the indent level. -# Every call creates blank output that matches the indent level. -# In addition, with a '-' argument, the indent level -# decrements by one before printing. -# With a '+', the indent level increments after printing. -# This is generally just used by Xecho -# -XmlLevel=0 -IndentXml() { - if [ "$1" = '-' -a $XmlLevel != 0 ]; then - XmlLevel=$(($XmlLevel - 1)) - fi - local idx=0 - while [ "$idx" != "$XmlLevel" ]; do - echo -n ' ' - idx=$(($idx + 1)) - done - if [ "$1" = '+' ]; then - XmlLevel=$(($XmlLevel + 1)) - fi -} - -# Xecho [ - | + ] ... -# echoes arguments (like) echo, except that the output -# is indented for XML first. If +, the indentation changes -# after printing, if -, the indentation changes before printing. -# -Xecho() -{ - local xarg= - if [ "$1" = '-' -o "$1" = '+' ]; then - xarg="$1" - shift - fi - IndentXml $xarg - echo "$@" -} - -# SlashCount(PATH) -# Returns the number of slashes in its argument -# Note, we are relying on some advanced -# features of bash shell substitution -# -SlashCount() -{ - local allslash=`echo "$1" | sed -e 's:[^/]*::g'` - echo "${#allslash}" -} - -# ProcessDirTransition(PREVDIR, NEXTDIR) -# Used by ProcessFeatures to create the parts -# of an WiX <Directory> heirarchy (on stdout) needed to -# transition from directory PREVDIR to NEXTDIR. -# This may include any needed </Directory> entries as well. -# For example, ProcessDirTransition /Bin/Stuff /Bin/Foo/Bar -# produces: -# </Directory> ...to go up one from 'Stuff' -# <Directory Foo> -# <Directory Bar> -# -ProcessDirTransition() { - local p="$1" - local n="$2" - if [ "$p" = '' ]; then p=/; fi - if [ "$n" = '' ]; then n=/; fi - local nextdir="$2" - - # The number of slashes in $p is the current directory level. - XmlLevel=$(($(SlashCount $p) + 4)) - - while [ "$p" != / ]; do - if [ "${n#${p}}" != "$n" ]; then - break - fi - - # go up one level, and keep $p terminated with a / - p=`dirname $p` - case "$p" in - */ ) ;; - * ) p=$p/;; - esac - Xecho - "</Directory>" - done - n=${n#${p}} - while [ "$n" != '' ]; do - local dirname=`echo $n | sed -e 's:/.*::'` - local cleanname=`CleanFileName "$dirname"` - local shortname=`GetShortName "$cleanname"` - local dirid=`NextId` - - local larg="" - if [ "${shortname}" != "${dirname}" ]; then - larg="LongName=\"${dirname}\"" - fi - Xecho + "<Directory Id=\"${cleanname}Dir.$dirid\" Name=\"${shortname}\" $larg>" - - n=`echo $n | sed -e 's:^[^/]*/::'` - done - - Xecho "WIX_DB_SET_CURDIR($nextdir)" # Tell the m4 macro what the current dir is -} - -# SetupErrorLog() -# Given the global variable ERRORLOG for the name of the -# error output file, do any setup required to make that happen. -# -SetupErrorLog() { - - # Before we start to use ERRORLOG, we get a full pathname, - # since the caller may change directories at times. - case "$ERRORLOG" in - /* ) ;; - *) ERRORLOG=`pwd`"/$ERRORLOG" ;; - esac - - rm -f $ERRORLOG - - # File descriptor tricks. - # Duplicate current stderr to 15, as we'll occasionally - # need to report progress to it. Then, redirect all - # stderr from now on to the ERRORLOG. - # - exec 15>&2 - exec 2>>$ERRORLOG -} - -# RequireCygwin -# Cygwin does not install certain needed components by default. -# Check to make sure that everything needed by the script -# and functions is here. -# -RequireCygwin() { - Progress -minor "checking for Cygwin..." - RequireFileInPath PATH "$PATH" m4 - RequireFileInPath PATH "$PATH" gcc - RequireFileInPath PATH "$PATH" make - RequireFileInPath PATH "$PATH" unzip - RequireFileInPath PATH "$PATH" bc - RequireFileInPath PATH "$PATH" openssl # needed for MD5 hashing -} - -# RequireJava() -# A java SDK (with include files) must be installed -# -RequireJava() { - Progress -minor "checking for Java..." - RequireFileInPath INCLUDE "$INCLUDE" jni.h - RequireFileInPath INCLUDE "$INCLUDE" jni_md.h - RequireFileInPath PATH "$PATH" jar.exe - RequireFileInPath PATH "$PATH" javac.exe -} - -# RequireTcl() -# A Tcl SDK (with compatible .lib files) must be installed -# -RequireTcl() { - Progress -minor "checking for Tcl..." - RequireFileInPath INCLUDE "$INCLUDE" tcl.h - RequireFileInPath LIB "$LIB" tcl84g.lib - RequireFileInPath LIB "$LIB" tcl84.lib -} - -# RequireWix() -# WiX must be installed -# -RequireWix() { - Progress -minor "checking for WiX..." - RequireFileInPath PATH "$PATH" candle.exe - RequireFileInPath PATH "$PATH" light.exe - RequireFileInPath PATH "$PATH" tallow.exe -} - -# RequirePerl() -# Perl must be installed -# -RequirePerl() { - Progress -minor "checking for Perl..." - RequireFileInPath PATH "$PATH" perl.exe -} - -# RequirePython() -# Python (and include files) must be installed -# -RequirePython() { - Progress -minor "checking for Python..." - RequireFileInPath INCLUDE "$INCLUDE" Python.h - RequireFileInPath PATH "$PATH" python.exe -} - -# CreateDbPerl() -# Build Perl interface (for Berkeley DB only). -# -CreateDbPerl() { - - # First build Berkeley DB using cygwin, as that version is - # needed for the Perl build - local here=`pwd` - Progress "building using Cygwin tools (needed for perl)" - cd "${PRODUCT_DBBUILDDIR}" - insdir="${PRODUCT_STAGE}/install_unix" - ../dist/configure --prefix="$insdir" >>$ERRORLOG || exit 1 - make install >>$ERRORLOG || exit 1 - - Progress "building perl" - cd ../perl/BerkeleyDB - BERKELEYDB_INCLUDE="$insdir/installed_include" BERKELEYDB_LIB="$insdir/lib" \ - perl Makefile.PL >>$ERRORLOG || exit 1 - make >>$ERRORLOG - cd $here -} - -# CreateWindowsSystem() -# Copy Window system files -# -CreateWindowsSystem() { - local here=`pwd` - Progress "Copy Window system files..." - cd "${PRODUCT_SUB_BLDDIR}" - cp -f $SYSTEMROOT/system32/msvcr71.dll build_win32/Release/ || exit 1 - cp -f $SYSTEMROOT/system32/msvcp71.dll build_win32/Release/ || exit 1 - cp -f $SYSTEMROOT/system32/msvcr71d.dll build_win32/Debug/ || exit 1 - cp -f $SYSTEMROOT/system32/msvcp71d.dll build_win32/Debug/ || exit 1 - cd $here -} - -# CreateInclude(DIR, FILES) -# Create an include directory populated with the files given -# -CreateInclude() { - - local incdir="$1" - shift - - Progress "creating the "$incdir" directory..." - rm -rf "$incdir" - mkdir "$incdir" || exit 1 - cp -r "$@" "$incdir" -} - -# CreateWindowsBuild() -# Do the windows build as defined by the winbuild.bat file -# -CreateWindowsBuild() { - local here=`pwd` - Progress "building using Windows tools..." - cd "${PRODUCT_SUB_BLDDIR}" || exit 1 - - # Before starting, copy any installer tools here. - # This makes building these tools straightforward - # and the results are left in the build directory. - # - cp -r ${PRODUCT_SHARED_WINMSIDIR}/instenv . - - # We create a wbuild.bat file, which is essentially - # identical, except it has the carriage returns added. - # This allows us to use our favorite editors on winbuild.bat . - # - sed -e 's/$//' < ${PRODUCT_STAGE}/../winbuild.bat | tr '\001' '\015' > wbuild.bat - # TODO: Needed? - rm -f build_win32/Berkeley_DB.sln - rm -f winbld.out winbld.err - touch winbld.out winbld.err - echo "Build output and errors are collected in" >> $ERRORLOG - echo " winbld.{out,err} until the build has completed." >> $ERRORLOG - cmd.exe /x /c call wbuild.bat - status=$? - cat winbld.out >> $ERRORLOG - if [ -s winbld.err -o "$status" != 0 ]; then - cat winbld.err >> $ERRORLOG - Error "Errors during windows build" - exit 1 - fi - cd $here -} - -# CreateSources(SOURCESDIR,DOCDIR...) -# Create the sources directory, ignoring things in the docdirs -# -CreateSources() { - local sources="$1" - - Progress "creating the Sources directory in $sources..." - rm -rf "$sources" - cp -r ${PRODUCT_SRCDIR} "$sources" || exit 1 -} - -# Usage() -# Show the usage for this script. -# -Usage() -{ - echo "Usage: s_winmsi [ options ]" >&2 - echo "Options: " >&2 - echo " -input file use file rather than ${PRODUCT_ZIP_FILEFMT}" >&2 - echo " where X.Y.Z is defined by ../RELEASE" >&2 - echo " -output file use file rather than ${PRODUCT_MSI_FILEFMT}" >&2 - echo " where X.Y.Z is defined by ../RELEASE" >&2 - echo " -usebuild DIR use DIR for exes, DLLs, etc. " >&2 - echo " rather than building from scratch" >&2 - echo " -preserve preserve the winmsi/msi_staging directory" >&2 - echo " -skipgen skip generating m4 include files" >&2 -} - -# SetupOptions() -# Parse command line options and set global variables as indicated below. -# -SetupOptions() { - OPT_USEBUILD= - OPT_PRESERVE=false - OPT_INFILE= - OPT_OUTFILE= - OPT_SKIPGEN=false - while [ "$#" -gt 0 ]; do - arg="$1"; shift - case "$arg" in - -usebuild ) OPT_USEBUILD="$1"; shift ;; - -skipgen ) OPT_SKIPGEN=true ;; - -preserve ) OPT_PRESERVE=true;; - -input ) OPT_INFILE="$1"; shift ;; - -output ) OPT_OUTFILE="$1"; shift ;; - * ) - echo "ERROR: Unknown argument '$arg' to s_winmsi" >&2 - Usage - exit 1 - ;; - esac - done - if [ "$OPT_INFILE" = '' -o ! -f "$OPT_INFILE" ]; then - echo "$OPT_INFILE: not found" - exit 1 - fi -} - -# CreateStage() -# Create the staging area -# -CreateStage() { - Progress "creating staging area..." - if [ "$PRODUCT_STAGE" = '' ]; then - Error "PRODUCT_STAGE not set" - exit 1 - fi - if ! $OPT_PRESERVE; then - trap 'rm -rf ${PRODUCT_STAGE} ; exit 0' 0 1 2 3 13 15 - fi - rm -rf ${PRODUCT_STAGE} || exit 1 - mkdir ${PRODUCT_STAGE} || exit 1 - - cd ${PRODUCT_STAGE} - - Progress "extracting $OPT_INFILE..." - unzip -q ../../$OPT_INFILE || exit 1 - - if [ ! -d $PRODUCT_LICENSEDIR ]; then - Error "$OPT_INFILE: no top level $PRODUCT_LICENSEDIR directory" - exit 1 - fi -} - -# CreateLicenseRtf(LICENSEIN, LICENSERTF) -# From a text LICENSE file, create the equivalent in .rtf format. -# -CreateLicenseRtf() { - local licensein="$1" - local licensertf="$2" - - if [ ! -f "$licensein" ]; then - Error "License file $licensein: does not exist" - exit 1 - fi - Progress "creating ${licensertf}..." - - # Build a list of references to components ids (i.e. directories) - # that are listed in the .wxs file. This is needed to refer to - # all of the source (sadly it appears there is no better way!) - # - if ! grep '^=-=-=-=' $licensein > /dev/null; then - Error "LICENSE has changed format, this script must be adapted" - exit 1 - fi - - sed -e '1,/^=-=-=-=-=/d' < $licensein | MakeRtf > $licensertf -} - - -# CreateMsi(INFILE,WXSFILE,MSIFILE) -# Do the final creation of the output .MSI file. -# It is assumed that all *.wixinc files are now in place. -# INFILE is an absolute name of the m4 input WiX file. -# WXSFILE is a short (basename) of the postprocessed WiX file, -# after macro expansion, it will be left in staging directory. -# MSIFILE is a short (basename) of the output .MSI name -# -CreateMsi() { - local infile="$1" - local wxs="$2" - local msifile="$3" - local o=`echo "$wxs" | sed -e 's/[.]wxs$//' -e 's/$/.wixobj/'` - - rm -f $o $wxs - - # Preprocess the ${PROD}wix.in file, adding the things we need - # - Progress "Running m4 to create $wxs..." - RunM4 < "$infile" > "$PRODUCT_STAGE/$wxs" || Error "m4 failed" || exit 1 - - local here=`pwd` - cd "$PRODUCT_STAGE" - rm -f "$o" "$msifile" - Progress "compiling $wxs..." - candle -w0 $wxs >> $ERRORLOG || Error "candle (compiler) failed" || exit 1 - - Progress "linking .msi file..." - light -o "$msifile" $o >> $ERRORLOG || Error "light (linker) failed" || exit 1 - (rm -f "../../$msifile" && mv "$msifile" ../..) >> $ERRORLOG || exit 1 - cd $here -} - -# CreateWixIncludeFiles() -# Do all processing of input files to produce -# the include files that we need to process the Wix input file. -# -CreateWixIncludeFiles() { - local here=`pwd` - cd "$PRODUCT_STAGE" - # Touch all the wix include files in case any end up empty. - touch directory.wixinc features.wixinc envprops.wixinc \ - envset.wixinc envshow.wixinc links.wixinc - - Progress "tagging the installer..." - ProcessTagProperties envprops.wixinc - - Progress "processing environment..." - ProcessEnv ../environment.in ../dbvarsbat.in envprops.wixinc envset.wixinc envshow.wixinc - - Progress "processing features and files..." - ProcessFeatures ../files.in ../features.in ../environment.in \ - directory.wixinc features.wixinc \ - envset.wixinc - - Progress "processing links..." - ProcessLinks ../links.in features.wixinc > links.wixinc - cd $here -} diff --git a/storage/bdb/dist/winmsi/winbuild.bat b/storage/bdb/dist/winmsi/winbuild.bat deleted file mode 100644 index 80b9dcf6446..00000000000 --- a/storage/bdb/dist/winmsi/winbuild.bat +++ /dev/null @@ -1,113 +0,0 @@ -@echo off -:: $Id: winbuild.bat,v 1.5 2005/10/26 13:29:34 dda Exp $ -:: Helper script to build Berkeley DB libraries and executables -:: using MSDEV -:: - -cd build_win32 - -:: One of these calls should find the desired batch file - -call :TryBat "c:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\vsvars32.bat" && goto BATFOUND1 - -call :TryBat "c:\Program Files\Microsoft Visual Studio .NET\Common7\Tools\vsvars32.bat" && goto BATFOUND2 - -call :TryBat "c:\Program Files\Microsoft Visual Studio.NET\Common7\Tools\vsvars32.bat" && goto BATFOUND3 - -goto BATNOTFOUND - -:BATFOUND1 -echo Using Visual Studio .NET 2003 -goto BATFOUND - -:BATFOUND2 -echo Using Visual Studio .NET -echo *********** CHECK: Make sure the binaries are built with the same system libraries that are shipped. -goto BATFOUND - -:BATFOUND3 -echo Using Visual Studio.NET -echo *********** CHECK: Make sure the binaries are built with the same system libraries that are shipped. -goto BATFOUND - -:BATFOUND -:CONVERSION -start /wait devenv /useenv Berkeley_DB.dsw - -:: For some reason, the command doesn't wait, at least on XP. -:: So we ask for input to continue. - - -echo. -echo ============================================================ -echo. -echo Converting the Berkeley DB Workspace to a .NET Solution. -echo This will run the IDE to interactively convert. -echo. -echo When prompted during the conversion, say: Yes-to-All. -echo When finished with the conversion, do a Save-All and Exit. -echo Then hit ENTER to continue this script. -echo. -echo ============================================================ -set result=y -set /P result="Continue? [y] " -if %result% == n goto NSTOP - -if exist Berkeley_DB.sln goto ENDCONVERSION -echo ************* Berkeley_DB.sln was not created *********** -echo Trying the conversion again... -goto CONVERSION -:ENDCONVERSION - -::intenv is used to set environment variables but this isn't used anymore -::devenv /useenv /build Release /project instenv ..\instenv\instenv.sln >> ..\winbld.out 2>&1 -::if not %errorlevel% == 0 goto ERROR - -echo Building Berkeley DB -devenv /useenv /build Debug /project build_all Berkeley_DB.sln >> ..\winbld.out 2>&1 -if not %errorlevel% == 0 goto ERROR -devenv /useenv /build Release /project build_all Berkeley_DB.sln >> ..\winbld.out 2>&1 -if not %errorlevel% == 0 goto ERROR -devenv /useenv /build Debug /project db_java Berkeley_DB.sln >> ..\winbld.out 2>&1 -if not %errorlevel% == 0 goto ERROR -devenv /useenv /build Release /project db_java Berkeley_DB.sln >> ..\winbld.out 2>&1 -if not %errorlevel% == 0 goto ERROR -devenv /useenv /build Debug /project db_tcl Berkeley_DB.sln >> ..\winbld.out 2>&1 -if not %errorlevel% == 0 goto ERROR -devenv /useenv /build Release /project db_tcl Berkeley_DB.sln >> ..\winbld.out 2>&1 -if not %errorlevel% == 0 goto ERROR - - -goto END - - -:ERROR -echo *********** ERROR: during win_build.bat ************* -echo *********** ERROR: during win_build.bat ************* >> ..\winbld.err -exit 1 -goto END - -:NSTOP -echo *********** ERROR: win_build.bat stop requested ************* -echo *********** ERROR: win_built.bat stop requested ************* >> ..\winbld.err -exit 2 -goto END - -:BATNOTFOUND -echo *********** ERROR: VC Config batch file not found ************* -echo *********** ERROR: VC Config batch file not found ************* >> ..\winbld.err -exit 3 -goto END - -:: TryBat(BATPATH) -:: If the BATPATH exists, use it and return 0, -:: otherwise, return 1. - -:TryBat -:: Filename = %1 -if not exist %1 exit /b 1 -call %1 -exit /b 0 -goto :EOF - -:END diff --git a/storage/bdb/env/db_salloc.c b/storage/bdb/env/db_salloc.c deleted file mode 100644 index 5566650d0cc..00000000000 --- a/storage/bdb/env/db_salloc.c +++ /dev/null @@ -1,374 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_salloc.c,v 12.4 2005/10/15 00:51:56 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stdlib.h> -#include <string.h> -#endif - -#include "db_int.h" - -/* - * Implement shared memory region allocation, using simple first-fit algorithm. - * The model is that we take a "chunk" of shared memory store and begin carving - * it up into areas, similarly to how malloc works. We do coalescing on free. - * - * The "len" field in the __data struct contains the length of the free region - * (less the size_t bytes that holds the length). We use the address provided - * by the caller to find this length, which allows us to free a chunk without - * requiring that the caller pass in the length of the chunk they're freeing. - */ -SH_LIST_HEAD(__head); -struct __data { - size_t len; - SH_LIST_ENTRY links; -}; - -#define ILLEGAL_SIZE 1 /* An illegal size. */ - -/* - * __db_shalloc_init -- - * Initialize the area as one large chunk. - * - * PUBLIC: void __db_shalloc_init __P((REGINFO *, size_t)); - */ -void -__db_shalloc_init(infop, size) - REGINFO *infop; - size_t size; -{ - struct __data *elp; - struct __head *hp; - - /* No initialization needed for heap memory regions. */ - if (F_ISSET(infop->dbenv, DB_ENV_PRIVATE)) - return; - - hp = infop->addr; - SH_LIST_INIT(hp); - - elp = (struct __data *)(hp + 1); - elp->len = (size - sizeof(struct __head)) - sizeof(elp->len); - SH_LIST_INSERT_HEAD(hp, elp, links, __data); -} - -/* - * __db_shalloc_size -- - * Return the space needed for an allocation, including alignment. - * - * PUBLIC: size_t __db_shalloc_size __P((size_t, size_t)); - */ -size_t -__db_shalloc_size(len, align) - size_t len, align; -{ - /* Never allocate less than the size of a struct __data. */ - if (len < sizeof(struct __data)) - len = sizeof(struct __data); - -#ifdef DIAGNOSTIC - /* Add room for a guard byte. */ - ++len; -#endif - - /* Never align to less than a uintmax_t boundary. */ - if (align <= sizeof(uintmax_t)) - align = sizeof(uintmax_t); - - return ((size_t)DB_ALIGN(len, align) + sizeof(struct __data)); -} - -/* - * __db_shalloc -- - * Allocate space from the shared region. - * - * PUBLIC: int __db_shalloc __P((REGINFO *, size_t, size_t, void *)); - */ -int -__db_shalloc(infop, len, align, retp) - REGINFO *infop; - size_t len, align; - void *retp; -{ - DB_ENV *dbenv; - struct __data *elp; - size_t *sp; - int ret; - void *p, *rp; - - dbenv = infop->dbenv; - - /* Never align to less than a uintmax_t boundary. */ - if (align <= sizeof(uintmax_t)) - align = sizeof(uintmax_t); - - /* In a private region, we call malloc for additional space. */ - if (F_ISSET(dbenv, DB_ENV_PRIVATE)) { - /* Check to see if we're over our limit. */ - if (infop->allocated >= infop->max_alloc) - return (ENOMEM); - - /* Add enough room for a size. */ - len += sizeof(size_t); - - /* Add enough room to guarantee alignment is possible. */ - len += align - 1; - - /* Allocate the space. */ - if ((ret = __os_malloc(dbenv, len, &p)) != 0) - return (ret); - infop->allocated += len; - - /* Store the size. */ - sp = p; - *sp++ = len; - - /* Find the aligned location. */ - *(void **)retp = rp = ALIGNP_INC(sp, align); - - /* Fill in any gaps with illegal sizes. */ - for (; (void *)sp < rp; ++sp) - *sp = ILLEGAL_SIZE; - - return (0); - } - - /* Never allocate less than the size of a struct __data. */ - if (len < sizeof(struct __data)) - len = sizeof(struct __data); - -#ifdef DIAGNOSTIC - /* Add room for a guard byte. */ - ++len; -#endif - - p = infop->addr; - - /* Walk the list, looking for a slot. */ - for (elp = SH_LIST_FIRST((struct __head *)p, __data); - elp != NULL; - elp = SH_LIST_NEXT(elp, links, __data)) { - /* - * Skip chunks that are too small to work. This avoids address - * wrap-around in the subsequent calculations (if len were too - * large). - */ - if (elp->len < len) - continue; - - /* - * Calculate the value of the returned pointer if we were to - * use this chunk. - * + Find the end of the chunk. - * + Subtract the memory the user wants. - * + Find the closest previous correctly-aligned address. - */ - rp = (u_int8_t *)elp + sizeof(size_t) + elp->len; - rp = (u_int8_t *)rp - len; - rp = ALIGNP_DEC(rp, align); - - /* - * Rp may now point before elp->links, in which case the chunk - * was too small, and we have to try again. - */ - if ((u_int8_t *)rp < (u_int8_t *)&elp->links) - continue; - - *(void **)retp = rp; -#ifdef DIAGNOSTIC - /* - * At this point, whether or not we still need to split up a - * chunk, retp is the address of the region we are returning, - * and (u_int8_t *)elp + sizeof(size_t) + elp->len gives us - * the address of the first byte after the end of the chunk. - * Make the byte immediately before that the guard byte. - */ - *((u_int8_t *)elp + sizeof(size_t) + elp->len - 1) = GUARD_BYTE; -#endif - -#define SHALLOC_FRAGMENT 32 - /* - * If there are at least SHALLOC_FRAGMENT additional bytes of - * memory, divide the chunk into two chunks. - */ - if ((u_int8_t *)rp >= - (u_int8_t *)&elp->links + SHALLOC_FRAGMENT) { - sp = rp; - *--sp = elp->len - - ((u_int8_t *)rp - (u_int8_t *)&elp->links); - elp->len -= *sp + sizeof(size_t); - return (0); - } - - /* - * Otherwise, we return the entire chunk, wasting some amount - * of space to keep the list compact. However, because the - * address we're returning to the user may not be the address - * of the start of the region for alignment reasons, set the - * size_t length fields back to the "real" length field to a - * flag value, so that we can find the real length during free. - */ - SH_LIST_REMOVE(elp, links, __data); - for (sp = rp; (u_int8_t *)--sp >= (u_int8_t *)&elp->links;) - *sp = ILLEGAL_SIZE; - return (0); - } - - return (ENOMEM); -} - -/* - * __db_shalloc_free -- - * Free space into the shared region. - * - * PUBLIC: void __db_shalloc_free __P((REGINFO *, void *)); - */ -void -__db_shalloc_free(infop, ptr) - REGINFO *infop; - void *ptr; -{ - DB_ENV *dbenv; - struct __data *elp, *lastp, *newp; - struct __head *hp; - size_t free_size, *sp; - int merged; - - dbenv = infop->dbenv; - - /* - * Step back over flagged length fields to find the beginning of - * the object and its real size. - */ - for (sp = (size_t *)ptr; sp[-1] == ILLEGAL_SIZE; --sp) - ; - ptr = sp; - - newp = (struct __data *)((u_int8_t *)ptr - sizeof(size_t)); - free_size = newp->len; - - /* In a private region, we call free. */ - if (F_ISSET(dbenv, DB_ENV_PRIVATE)) { - DB_ASSERT(infop->allocated >= free_size); - infop->allocated -= free_size; - - __os_free(dbenv, newp); - return; - } - -#ifdef DIAGNOSTIC - /* - * The "real size" includes the guard byte; it's just the last - * byte in the chunk, and the caller never knew it existed. - * - * Check it to make sure it hasn't been stomped. - */ - if (*((u_int8_t *)ptr + free_size - 1) != GUARD_BYTE) { - /* - * Eventually, once we push a DB_ENV handle down to these - * routines, we should use the standard output channels. - */ - fprintf(stderr, - "Guard byte incorrect during shared memory free.\n"); - abort(); - /* NOTREACHED */ - } - - /* Trash the returned memory (including guard byte). */ - memset(ptr, CLEAR_BYTE, free_size); -#endif - /* - * Walk the list, looking for where this entry goes. - * - * We keep the free list sorted by address so that coalescing is - * trivial. - * - * XXX - * Probably worth profiling this to see how expensive it is. - */ - hp = (struct __head *)(infop->addr); - for (elp = SH_LIST_FIRST(hp, __data), lastp = NULL; - elp != NULL && (void *)elp < (void *)ptr; - lastp = elp, elp = SH_LIST_NEXT(elp, links, __data)) - ; - - /* - * Elp is either NULL (we reached the end of the list), or the slot - * after the one that's being returned. Lastp is either NULL (we're - * returning the first element of the list) or the element before the - * one being returned. - * - * Check for coalescing with the next element. - */ - merged = 0; - if ((u_int8_t *)ptr + free_size == (u_int8_t *)elp) { - newp->len += elp->len + sizeof(size_t); - SH_LIST_REMOVE(elp, links, __data); - if (lastp != NULL) - SH_LIST_INSERT_AFTER(lastp, newp, links, __data); - else - SH_LIST_INSERT_HEAD(hp, newp, links, __data); - merged = 1; - } - - /* Check for coalescing with the previous element. */ - if (lastp != NULL && (u_int8_t *)lastp + - lastp->len + sizeof(size_t) == (u_int8_t *)newp) { - lastp->len += newp->len + sizeof(size_t); - - /* - * If we have already put the new element into the list take - * it back off again because it's just been merged with the - * previous element. - */ - if (merged) - SH_LIST_REMOVE(newp, links, __data); - merged = 1; - } - - if (!merged) { - if (lastp == NULL) - SH_LIST_INSERT_HEAD(hp, newp, links, __data); - else - SH_LIST_INSERT_AFTER(lastp, newp, links, __data); - } -} - -/* - * __db_shalloc_sizeof -- - * Return the size of a shalloc'd piece of memory. - * - * !!! - * Note that this is from an internal standpoint -- it includes not only - * the size of the memory being used, but also the extra alignment bytes - * in front and, #ifdef DIAGNOSTIC, the guard byte at the end. - * - * PUBLIC: size_t __db_shalloc_sizeof __P((void *)); - */ -size_t -__db_shalloc_sizeof(ptr) - void *ptr; -{ - struct __data *elp; - size_t *sp; - - /* - * Step back over flagged length fields to find the beginning of - * the object and its real size. - */ - for (sp = (size_t *)ptr; sp[-1] == ILLEGAL_SIZE; --sp) - ; - - elp = (struct __data *)((u_int8_t *)sp - sizeof(size_t)); - return (elp->len); -} diff --git a/storage/bdb/env/db_shash.c b/storage/bdb/env/db_shash.c deleted file mode 100644 index c18f77228c1..00000000000 --- a/storage/bdb/env/db_shash.c +++ /dev/null @@ -1,118 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: db_shash.c,v 12.1 2005/06/16 20:21:56 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - -#include "db_int.h" - -/* - * Table of good hash values. Up to ~250,000 buckets, we use powers of 2. - * After that, we slow the rate of increase by half. For each choice, we - * then use a nearby prime number as the hash value. - * - * If a terabyte is the maximum cache we'll see, and we assume there are - * 10 1K buckets on each hash chain, then 107374182 is the maximum number - * of buckets we'll ever need. - */ -static const struct { - u_int32_t power; - u_int32_t prime; -} list[] = { - { 32, 37}, /* 2^5 */ - { 64, 67}, /* 2^6 */ - { 128, 131}, /* 2^7 */ - { 256, 257}, /* 2^8 */ - { 512, 521}, /* 2^9 */ - { 1024, 1031}, /* 2^10 */ - { 2048, 2053}, /* 2^11 */ - { 4096, 4099}, /* 2^12 */ - { 8192, 8191}, /* 2^13 */ - { 16384, 16381}, /* 2^14 */ - { 32768, 32771}, /* 2^15 */ - { 65536, 65537}, /* 2^16 */ - { 131072, 131071}, /* 2^17 */ - { 262144, 262147}, /* 2^18 */ - { 393216, 393209}, /* 2^18 + 2^18/2 */ - { 524288, 524287}, /* 2^19 */ - { 786432, 786431}, /* 2^19 + 2^19/2 */ - { 1048576, 1048573}, /* 2^20 */ - { 1572864, 1572869}, /* 2^20 + 2^20/2 */ - { 2097152, 2097169}, /* 2^21 */ - { 3145728, 3145721}, /* 2^21 + 2^21/2 */ - { 4194304, 4194301}, /* 2^22 */ - { 6291456, 6291449}, /* 2^22 + 2^22/2 */ - { 8388608, 8388617}, /* 2^23 */ - { 12582912, 12582917}, /* 2^23 + 2^23/2 */ - { 16777216, 16777213}, /* 2^24 */ - { 25165824, 25165813}, /* 2^24 + 2^24/2 */ - { 33554432, 33554393}, /* 2^25 */ - { 50331648, 50331653}, /* 2^25 + 2^25/2 */ - { 67108864, 67108859}, /* 2^26 */ - { 100663296, 100663291}, /* 2^26 + 2^26/2 */ - { 134217728, 134217757}, /* 2^27 */ - { 201326592, 201326611}, /* 2^27 + 2^27/2 */ - { 268435456, 268435459}, /* 2^28 */ - { 402653184, 402653189}, /* 2^28 + 2^28/2 */ - { 536870912, 536870909}, /* 2^29 */ - { 805306368, 805306357}, /* 2^29 + 2^29/2 */ - {1073741824, 1073741827}, /* 2^30 */ - {0, 0} -}; - -/* - * __db_tablesize -- - * Choose a size for the hash table. - * - * PUBLIC: u_int32_t __db_tablesize __P((u_int32_t)); - */ -u_int32_t -__db_tablesize(n_buckets) - u_int32_t n_buckets; -{ - u_int i; - - /* - * We try to be clever about how big we make the hash tables. Use a - * prime number close to the "suggested" number of elements that will - * be in the hash table. Use 64 as the minimum hash table size. - * - * Ref: Sedgewick, Algorithms in C, "Hash Functions" - */ - if (n_buckets < 32) - n_buckets = 32; - - for (i = 0; i < sizeof(list)/sizeof(list[0]); ++i) - if (list[i].power >= n_buckets) - return (list[i].prime); - return (list[--i].prime); -} - -/* - * __db_hashinit -- - * Initialize a hash table that resides in shared memory. - * - * PUBLIC: void __db_hashinit __P((void *, u_int32_t)); - */ -void -__db_hashinit(begin, nelements) - void *begin; - u_int32_t nelements; -{ - u_int32_t i; - SH_TAILQ_HEAD(hash_head) *headp; - - headp = (struct hash_head *)begin; - - for (i = 0; i < nelements; i++, headp++) - SH_TAILQ_INIT(headp); -} diff --git a/storage/bdb/env/env_failchk.c b/storage/bdb/env/env_failchk.c deleted file mode 100644 index 4eac661dfc0..00000000000 --- a/storage/bdb/env/env_failchk.c +++ /dev/null @@ -1,356 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2005 - * Sleepycat Software. All rights reserved. - * - * $Id: env_failchk.c,v 12.17 2005/11/07 14:51:52 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_shash.h" -#include "dbinc/mutex_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_am.h" -#include "dbinc/hash.h" /* Needed for call to __ham_func5. */ -#include "dbinc/lock.h" -#include "dbinc/txn.h" - -static int __env_in_api __P((DB_ENV *)); - -/* - * __env_failchk_pp -- - * DB_ENV->failchk pre/post processing. - * - * PUBLIC: int __env_failchk_pp __P((DB_ENV *, u_int32_t)); - */ -int -__env_failchk_pp(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - DB_THREAD_INFO *ip; - int ret; - - PANIC_CHECK(dbenv); - ENV_ILLEGAL_BEFORE_OPEN(dbenv, "DB_ENV->failchk"); - - /* - * DB_ENV->failchk requires self and is-alive functions. We - * have a default self function, but no is-alive function. - */ - if (!ALIVE_ON(dbenv)) { - __db_err(dbenv, - "DB_ENV->failchk requires DB_ENV->is_alive be configured"); - return (EINVAL); - } - - if (flags != 0) - return (__db_ferr(dbenv, "DB_ENV->failchk", 0)); - - ENV_ENTER(dbenv, ip); - - /* - * We check for dead threads in the API first as this would be likely - * to hang other things we try later, like locks and transactions. - */ - if ((ret = __env_in_api(dbenv)) != 0) - goto err; - - if (LOCKING_ON(dbenv) && (ret = __lock_failchk(dbenv)) != 0) - goto err; - - if (TXN_ON(dbenv) && (ret = __txn_failchk(dbenv)) != 0) - goto err; - -err: ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __env_thread_init -- - * Initialize the thread control block table. - * - * PUBLIC: int __env_thread_init __P((DB_ENV *, int)); - */ -int -__env_thread_init(dbenv, created) - DB_ENV *dbenv; - int created; -{ - DB_HASHTAB *htab; - DB_MUTEXMGR *mtxmgr; - DB_MUTEXREGION *mtxregion; - REGINFO *infop; - THREAD_INFO *thread; - int ret; - - mtxmgr = dbenv->mutex_handle; - mtxregion = mtxmgr->reginfo.primary; - infop = &mtxmgr->reginfo; - - if (mtxregion->thread_off == INVALID_ROFF) { - if (dbenv->thr_nbucket == 0) { - dbenv->thr_hashtab = NULL; - if (ALIVE_ON(dbenv)) { - __db_err(dbenv, - "is_alive method specified but no thread region allocated"); - return (EINVAL); - } - return (0); - } - - if (!created) { - __db_err(dbenv, - "thread table must be allocated at environment create time"); - return (EINVAL); - } - - if ((ret = __db_shalloc(infop, - sizeof(THREAD_INFO), 0, &thread)) != 0) { - __db_err(dbenv, - "cannot allocate a thread status block"); - return (ret); - } - memset(thread, 0, sizeof(*thread)); - mtxregion->thread_off = R_OFFSET(infop, thread); - thread->thr_nbucket = __db_tablesize(dbenv->thr_nbucket); - if ((ret = __db_shalloc(infop, - thread->thr_nbucket * sizeof(DB_HASHTAB), 0, &htab)) != 0) - return (ret); - thread->thr_hashoff = R_OFFSET(infop, htab); - __db_hashinit(htab, thread->thr_nbucket); - thread->thr_max = dbenv->thr_max; - } else { - thread = R_ADDR(infop, mtxregion->thread_off); - htab = R_ADDR(infop, thread->thr_hashoff); - } - - dbenv->thr_hashtab = htab; - dbenv->thr_nbucket = thread->thr_nbucket; - dbenv->thr_max = thread->thr_max; - return (0); -} - -/* - * __env_in_api -- - * Look for threads which died in the api and complain. - */ -static int -__env_in_api(dbenv) - DB_ENV *dbenv; -{ - DB_HASHTAB *htab; - DB_MUTEXMGR *mtxmgr; - DB_MUTEXREGION *mtxregion; - DB_THREAD_INFO *ip; - REGINFO *infop; - THREAD_INFO *thread; - u_int32_t i; - - if ((htab = dbenv->thr_hashtab) == NULL) - return (EINVAL); - - mtxmgr = dbenv->mutex_handle; - mtxregion = mtxmgr->reginfo.primary; - infop = &mtxmgr->reginfo; - thread = R_ADDR(infop, mtxregion->thread_off); - - for (i = 0; i < dbenv->thr_nbucket; i++) - SH_TAILQ_FOREACH(ip, &htab[i], dbth_links, __db_thread_info) { - if (ip->dbth_state == THREAD_SLOT_NOT_IN_USE || - (ip->dbth_state == THREAD_OUT && - thread->thr_count < thread->thr_max)) - continue; - if (dbenv->is_alive(dbenv, ip->dbth_pid, ip->dbth_tid)) - continue; - if (ip->dbth_state == THREAD_OUT) { - ip->dbth_state = THREAD_SLOT_NOT_IN_USE; - continue; - } - return (__db_failed(dbenv, - "Thread died in Berkeley DB library", - ip->dbth_pid, ip->dbth_tid)); - } - - return (0); -} - -struct __db_threadid { - pid_t pid; - db_threadid_t tid; -}; - -static int __thread_id_cmp __P((struct __db_threadid *, DB_THREAD_INFO *)); -static int __thread_state_cmp __P((DB_THREAD_STATE, DB_THREAD_INFO *)); - -static -int __thread_id_cmp(id, ip) - struct __db_threadid *id; - DB_THREAD_INFO *ip; -{ -#ifdef HAVE_INTEGRAL_THREAD_TYPE - return (id->pid == ip->dbth_pid && id->tid == ip->dbth_tid); -#else - if (memcmp(&id->pid, &ip->dbth_pid, sizeof(id->pid)) != 0) - return (0); - if (memcmp(&id->tid, &ip->dbth_tid, sizeof(id->tid)) != 0) - return (0); - return (1); -#endif -} - -static -int __thread_state_cmp(state, ip) - DB_THREAD_STATE state; - DB_THREAD_INFO *ip; -{ - return (ip->dbth_state == state); -} - -/* - * PUBLIC: int __env_set_state __P((DB_ENV *, - * PUBLIC: DB_THREAD_INFO **, DB_THREAD_STATE)); - */ -int -__env_set_state(dbenv, ipp, state) - DB_ENV *dbenv; - DB_THREAD_INFO **ipp; - DB_THREAD_STATE state; -{ - DB_HASHTAB *htab; - DB_MUTEXMGR *mtxmgr; - DB_MUTEXREGION *mtxregion; - DB_THREAD_INFO *ip; - struct __db_threadid id; - REGINFO *infop; - THREAD_INFO *thread; - int ret; - u_int32_t indx; - - htab = (DB_HASHTAB *)dbenv->thr_hashtab; - - dbenv->thread_id(dbenv, &id.pid, &id.tid); - - /* - * Hashing of thread ids. This is simple but could be replaced with - * something more expensive if needed. - */ -#ifdef HAVE_INTEGRAL_THREAD_TYPE - /* - * A thread ID may be a pointer, so explicitly cast to a pointer of - * the appropriate size before doing the bitwise XOR. - */ - indx = (u_int32_t)((uintptr_t)id.pid ^ (uintptr_t)id.tid); -#else - indx = __ham_func5(NULL, &id.tid, sizeof(id.tid)); -#endif - indx %= dbenv->thr_nbucket; - HASHLOOKUP(htab, indx, - __db_thread_info, dbth_links, &id, ip, __thread_id_cmp); -#ifdef DIAGNOSTIC - if (state == THREAD_DIAGNOSTIC) { - *ipp = ip; - return (0); - } -#endif - - ret = 0; - if (ip == NULL) { - mtxmgr = dbenv->mutex_handle; - mtxregion = mtxmgr->reginfo.primary; - infop = &mtxmgr->reginfo; - thread = R_ADDR(infop, mtxregion->thread_off); - MUTEX_SYSTEM_LOCK(dbenv); - - /* - * If we are passed the specified max, try to reclaim one from - * our queue. If failcheck has marked the slot not in use, we - * can take it, otherwise we must call is_alive before freeing - * it. - */ - if (thread->thr_count >= thread->thr_max) { - HASHLOOKUP(htab, indx, __db_thread_info, - dbth_links, THREAD_OUT, ip, __thread_state_cmp); - while (ip != NULL && - ip->dbth_state != THREAD_SLOT_NOT_IN_USE && - (ip->dbth_state != THREAD_OUT || !ALIVE_ON(dbenv) || - dbenv->is_alive(dbenv, - ip->dbth_pid, ip->dbth_tid))) { - ip = SH_TAILQ_NEXT(ip, - dbth_links, __db_thread_info); - } - if (ip != NULL) - goto init; - } - - thread->thr_count++; - if ((ret = __db_shalloc(infop, - sizeof(DB_THREAD_INFO), 0, &ip)) == 0) { - memset(ip, 0, sizeof(*ip)); - /* - * This assumes we can link atomically since we do - * no locking here. We never use the backpointer - * so we only need to be able to write an offset - * atomically. - */ - HASHINSERT(htab, - indx, __db_thread_info, dbth_links, ip); -init: ip->dbth_pid = id.pid; - ip->dbth_tid = id.tid; - ip->dbth_state = state; - } - MUTEX_SYSTEM_UNLOCK(dbenv); - } else - ip->dbth_state = state; - *ipp = ip; - - return (ret); -} - -/* - * __env_thread_id_string -- - * Convert a thread id to a string. - * - * PUBLIC: char *__env_thread_id_string - * PUBLIC: __P((DB_ENV *, pid_t, db_threadid_t, char *)); - */ -char * -__env_thread_id_string(dbenv, pid, tid, buf) - DB_ENV *dbenv; - pid_t pid; - db_threadid_t tid; - char *buf; -{ -#ifdef HAVE_INTEGRAL_THREAD_TYPE -#ifdef UINT64_FMT - char fmt[10]; - - snprintf(fmt, sizeof(fmt), "%s/%s", UINT64_FMT, UINT64_FMT); - snprintf(buf, - DB_THREADID_STRLEN, fmt, (u_int64_t)pid, (u_int64_t)(uintptr_t)tid); -#else - snprintf(buf, DB_THREADID_STRLEN, "%lu/%lu", (u_long)pid, (u_long)tid); -#endif -#else -#ifdef UINT64_FMT - char fmt[10]; - - snprintf(fmt, sizeof(fmt), "%s/TID", UINT64_FMT); - snprintf(buf, DB_THREADID_STRLEN, fmt, (u_int64_t)pid); -#else - snprintf(buf, DB_THREADID_STRLEN, "%lu/TID", (u_long)pid); -#endif -#endif - COMPQUIET(dbenv, NULL); - COMPQUIET(*(u_int8_t *)&tid, 0); - - return (buf); -} diff --git a/storage/bdb/env/env_file.c b/storage/bdb/env/env_file.c deleted file mode 100644 index c5be30cf183..00000000000 --- a/storage/bdb/env/env_file.c +++ /dev/null @@ -1,139 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2002-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: env_file.c,v 12.3 2005/06/16 20:21:56 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" - -/* - * __db_file_extend -- - * Initialize a regular file by writing the last page of the file. - * - * PUBLIC: int __db_file_extend __P((DB_ENV *, DB_FH *, size_t)); - */ -int -__db_file_extend(dbenv, fhp, size) - DB_ENV *dbenv; - DB_FH *fhp; - size_t size; -{ - db_pgno_t pages; - size_t nw; - u_int32_t relative; - int ret; - char buf[8 * 1024]; - - /* - * Extend the file by writing the last page. If the region is >4Gb, - * increment may be larger than the maximum possible seek "relative" - * argument, as it's an unsigned 32-bit value. Break the offset into - * pages of 1MB each so we don't overflow -- (2^20 + 2^32 is bigger - * than any memory I expect to see for awhile). - */ - memset(buf, 0, sizeof(buf)); - - if ((ret = __os_seek(dbenv, fhp, 0, 0, 0, 0, DB_OS_SEEK_END)) != 0) - return (ret); - pages = (db_pgno_t)((size - sizeof(buf)) / MEGABYTE); - relative = (u_int32_t)((size - sizeof(buf)) % MEGABYTE); - if ((ret = __os_seek(dbenv, - fhp, MEGABYTE, pages, relative, 0, DB_OS_SEEK_CUR)) != 0) - return (ret); - if ((ret = __os_write(dbenv, fhp, buf, sizeof(buf), &nw)) != 0) - return (ret); - - return (0); -} - -/* - * __db_file_multi_write -- - * Overwrite a file with multiple passes to corrupt the data. - * - * PUBLIC: int __db_file_multi_write __P((DB_ENV *, const char *)); - */ -int -__db_file_multi_write(dbenv, path) - DB_ENV *dbenv; - const char *path; -{ - DB_FH *fhp; - u_int32_t mbytes, bytes; - int ret; - - if ((ret = __os_open(dbenv, path, DB_OSO_REGION, 0, &fhp)) == 0 && - (ret = __os_ioinfo(dbenv, path, fhp, &mbytes, &bytes, NULL)) == 0) { - /* - * !!! - * Overwrite a regular file with alternating 0xff, 0x00 and 0xff - * byte patterns. Implies a fixed-block filesystem, journaling - * or logging filesystems will require operating system support. - */ - if ((ret = __db_file_write( - dbenv, path, fhp, mbytes, bytes, 255)) != 0) - goto err; - if ((ret = __db_file_write( - dbenv, path, fhp, mbytes, bytes, 0)) != 0) - goto err; - if ((ret = __db_file_write( - dbenv, path, fhp, mbytes, bytes, 255)) != 0) - goto err; - } else - __db_err(dbenv, "%s: %s", path, db_strerror(ret)); - -err: if (fhp != NULL) - (void)__os_closehandle(dbenv, fhp); - return (ret); -} - -/* - * __db_file_write -- - * A single pass over the file, writing the specified byte pattern. - * - * PUBLIC: int __db_file_write __P((DB_ENV *, - * PUBLIC: const char *, DB_FH *, u_int32_t, u_int32_t, int)); - */ -int -__db_file_write(dbenv, path, fhp, mbytes, bytes, pattern) - DB_ENV *dbenv; - const char *path; - DB_FH *fhp; - int pattern; - u_int32_t mbytes, bytes; -{ - size_t len, nw; - int i, ret; - char buf[32 * 1024]; - - if ((ret = __os_seek(dbenv, fhp, 0, 0, 0, 0, DB_OS_SEEK_SET)) != 0) - goto err; - - memset(buf, pattern, sizeof(buf)); - - for (; mbytes > 0; --mbytes) - for (i = MEGABYTE / sizeof(buf); i > 0; --i) - if ((ret = - __os_write(dbenv, fhp, buf, sizeof(buf), &nw)) != 0) - goto err; - for (; bytes > 0; bytes -= (u_int32_t)len) { - len = bytes < sizeof(buf) ? bytes : sizeof(buf); - if ((ret = __os_write(dbenv, fhp, buf, len, &nw)) != 0) - goto err; - } - - if ((ret = __os_fsync(dbenv, fhp)) != 0) -err: __db_err(dbenv, "%s: %s", path, db_strerror(ret)); - - return (ret); -} diff --git a/storage/bdb/env/env_method.c b/storage/bdb/env/env_method.c deleted file mode 100644 index 070cba0467b..00000000000 --- a/storage/bdb/env/env_method.c +++ /dev/null @@ -1,1170 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: env_method.c,v 12.19 2005/11/10 17:12:17 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#ifdef HAVE_RPC -#include <rpc/rpc.h> -#endif - -#include <string.h> -#endif - -#ifdef HAVE_RPC -#include "db_server.h" -#endif - -/* - * This is the file that initializes the global array. Do it this way because - * people keep changing one without changing the other. Having declaration and - * initialization in one file will hopefully fix that. - */ -#define DB_INITIALIZE_DB_GLOBALS 1 - -#include "db_int.h" -#include "dbinc/crypto.h" -#include "dbinc/hmac.h" -#include "dbinc/db_shash.h" -#include "dbinc/db_page.h" -#include "dbinc/db_am.h" -#include "dbinc/lock.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" -#include "dbinc/txn.h" - -#ifdef HAVE_RPC -#include "dbinc_auto/rpc_client_ext.h" -#endif - -static void __env_err __P((const DB_ENV *, int, const char *, ...)); -static void __env_errx __P((const DB_ENV *, const char *, ...)); -static int __env_get_data_dirs __P((DB_ENV *, const char ***)); -static int __env_get_flags __P((DB_ENV *, u_int32_t *)); -static int __env_get_home __P((DB_ENV *, const char **)); -static int __env_get_shm_key __P((DB_ENV *, long *)); -static int __env_get_tmp_dir __P((DB_ENV *, const char **)); -static int __env_get_verbose __P((DB_ENV *, u_int32_t, int *)); -static int __env_init __P((DB_ENV *)); -static void __env_map_flags __P((DB_ENV *, u_int32_t *, u_int32_t *)); -static int __env_set_app_dispatch - __P((DB_ENV *, int (*)(DB_ENV *, DBT *, DB_LSN *, db_recops))); -static int __env_set_feedback __P((DB_ENV *, void (*)(DB_ENV *, int, int))); -static int __env_set_isalive __P((DB_ENV *, int (*)(DB_ENV *, - pid_t, db_threadid_t))); -static int __env_set_thread_id __P((DB_ENV *, void (*)(DB_ENV *, - pid_t *, db_threadid_t *))); -static int __env_set_thread_id_string __P((DB_ENV *, - char * (*)(DB_ENV *, pid_t, db_threadid_t, char *))); -static int __env_set_thread_count __P((DB_ENV *, u_int32_t)); -static int __env_set_rpc_server - __P((DB_ENV *, void *, const char *, long, long, u_int32_t)); - -/* - * db_env_create -- - * DB_ENV constructor. - * - * EXTERN: int db_env_create __P((DB_ENV **, u_int32_t)); - */ -int -db_env_create(dbenvpp, flags) - DB_ENV **dbenvpp; - u_int32_t flags; -{ - DB_ENV *dbenv; - int ret; - - /* - * !!! - * Our caller has not yet had the opportunity to reset the panic - * state or turn off mutex locking, and so we can neither check - * the panic state or acquire a mutex in the DB_ENV create path. - * - * !!! - * We can't call the flags-checking routines, we don't have an - * environment yet. - */ - if (flags != 0 && !LF_ISSET(DB_RPCCLIENT)) - return (EINVAL); - if ((ret = __os_calloc(NULL, 1, sizeof(*dbenv), &dbenv)) != 0) - return (ret); - -#ifdef HAVE_RPC - if (LF_ISSET(DB_RPCCLIENT)) - F_SET(dbenv, DB_ENV_RPCCLIENT); -#endif - if ((ret = __env_init(dbenv)) != 0) { - __os_free(NULL, dbenv); - return (ret); - } - - *dbenvpp = dbenv; - return (0); -} - -/* - * __env_init -- - * Initialize a DB_ENV structure. - */ -static int -__env_init(dbenv) - DB_ENV *dbenv; -{ - /* - * !!! - * Our caller has not yet had the opportunity to reset the panic - * state or turn off mutex locking, and so we can neither check - * the panic state or acquire a mutex in the DB_ENV create path. - * - * Initialize the method handles. - */ - /* DB_ENV PUBLIC HANDLE LIST BEGIN */ - dbenv->close = __env_close_pp; - dbenv->dbremove = __env_dbremove_pp; - dbenv->dbrename = __env_dbrename_pp; - dbenv->err = __env_err; - dbenv->errx = __env_errx; - dbenv->failchk = __env_failchk_pp; - dbenv->fileid_reset = __env_fileid_reset_pp; - dbenv->get_cachesize = __memp_get_cachesize; - dbenv->get_data_dirs = __env_get_data_dirs; - dbenv->get_encrypt_flags = __env_get_encrypt_flags; - dbenv->get_errfile = __env_get_errfile; - dbenv->get_errpfx = __env_get_errpfx; - dbenv->get_flags = __env_get_flags; - dbenv->get_home = __env_get_home; - dbenv->get_lg_bsize = __log_get_lg_bsize; - dbenv->get_lg_dir = __log_get_lg_dir; - dbenv->get_lg_filemode = __log_get_lg_filemode; - dbenv->get_lg_max = __log_get_lg_max; - dbenv->get_lg_regionmax = __log_get_lg_regionmax; - dbenv->get_lk_conflicts = __lock_get_lk_conflicts; - dbenv->get_lk_detect = __lock_get_lk_detect; - dbenv->get_lk_max_lockers = __lock_get_lk_max_lockers; - dbenv->get_lk_max_locks = __lock_get_lk_max_locks; - dbenv->get_lk_max_objects = __lock_get_lk_max_objects; - dbenv->get_mp_max_openfd = __memp_get_mp_max_openfd; - dbenv->get_mp_max_write = __memp_get_mp_max_write; - dbenv->get_mp_mmapsize = __memp_get_mp_mmapsize; - dbenv->get_msgfile = __env_get_msgfile; - dbenv->get_open_flags = __env_get_open_flags; - dbenv->get_rep_limit = __rep_get_limit; - dbenv->get_shm_key = __env_get_shm_key; - dbenv->get_timeout = __lock_get_env_timeout; - dbenv->get_tmp_dir = __env_get_tmp_dir; - dbenv->get_tx_max = __txn_get_tx_max; - dbenv->get_tx_timestamp = __txn_get_tx_timestamp; - dbenv->get_verbose = __env_get_verbose; - dbenv->is_bigendian = __db_isbigendian; - dbenv->lock_detect = __lock_detect_pp; - dbenv->lock_get = __lock_get_pp; - dbenv->lock_id = __lock_id_pp; - dbenv->lock_id_free = __lock_id_free_pp; - dbenv->lock_put = __lock_put_pp; - dbenv->lock_stat = __lock_stat_pp; - dbenv->lock_stat_print = __lock_stat_print_pp; - dbenv->lock_vec = __lock_vec_pp; - dbenv->log_archive = __log_archive_pp; - dbenv->log_cursor = __log_cursor_pp; - dbenv->log_file = __log_file_pp; - dbenv->log_flush = __log_flush_pp; - dbenv->log_printf = __log_printf_capi; - dbenv->log_put = __log_put_pp; - dbenv->log_stat = __log_stat_pp; - dbenv->log_stat_print = __log_stat_print_pp; - dbenv->lsn_reset = __env_lsn_reset_pp; - dbenv->memp_fcreate = __memp_fcreate_pp; - dbenv->memp_register = __memp_register_pp; - dbenv->memp_stat = __memp_stat_pp; - dbenv->memp_stat_print = __memp_stat_print_pp; - dbenv->memp_sync = __memp_sync_pp; - dbenv->memp_trickle = __memp_trickle_pp; - dbenv->mutex_alloc = __mutex_alloc_pp; - dbenv->mutex_free = __mutex_free_pp; - dbenv->mutex_get_align = __mutex_get_align; - dbenv->mutex_get_increment = __mutex_get_increment; - dbenv->mutex_get_max = __mutex_get_max; - dbenv->mutex_get_tas_spins = __mutex_get_tas_spins; - dbenv->mutex_lock = __mutex_lock_pp; - dbenv->mutex_set_align = __mutex_set_align; - dbenv->mutex_set_increment = __mutex_set_increment; - dbenv->mutex_set_max = __mutex_set_max; - dbenv->mutex_set_tas_spins = __mutex_set_tas_spins; - dbenv->mutex_stat = __mutex_stat; - dbenv->mutex_stat_print = __mutex_stat_print; - dbenv->mutex_unlock = __mutex_unlock_pp; - dbenv->open = __env_open_pp; - dbenv->remove = __env_remove; - dbenv->rep_elect = __rep_elect; - dbenv->rep_flush = __rep_flush; - dbenv->rep_get_config = __rep_get_config; - dbenv->rep_process_message = __rep_process_message; - dbenv->rep_set_config = __rep_set_config; - dbenv->rep_start = __rep_start; - dbenv->rep_stat = __rep_stat_pp; - dbenv->rep_stat_print = __rep_stat_print_pp; - dbenv->rep_sync = __rep_sync; - dbenv->set_alloc = __env_set_alloc; - dbenv->set_app_dispatch = __env_set_app_dispatch; - dbenv->set_cachesize = __memp_set_cachesize; - dbenv->set_data_dir = __env_set_data_dir; - dbenv->set_encrypt = __env_set_encrypt; - dbenv->set_errcall = __env_set_errcall; - dbenv->set_errfile = __env_set_errfile; - dbenv->set_errpfx = __env_set_errpfx; - dbenv->set_feedback = __env_set_feedback; - dbenv->set_flags = __env_set_flags; - dbenv->set_intermediate_dir = __env_set_intermediate_dir; - dbenv->set_isalive = __env_set_isalive; - dbenv->set_lg_bsize = __log_set_lg_bsize; - dbenv->set_lg_dir = __log_set_lg_dir; - dbenv->set_lg_filemode = __log_set_lg_filemode; - dbenv->set_lg_max = __log_set_lg_max; - dbenv->set_lg_regionmax = __log_set_lg_regionmax; - dbenv->set_lk_conflicts = __lock_set_lk_conflicts; - dbenv->set_lk_detect = __lock_set_lk_detect; - dbenv->set_lk_max = __lock_set_lk_max; - dbenv->set_lk_max_lockers = __lock_set_lk_max_lockers; - dbenv->set_lk_max_locks = __lock_set_lk_max_locks; - dbenv->set_lk_max_objects = __lock_set_lk_max_objects; - dbenv->set_mp_max_openfd = __memp_set_mp_max_openfd; - dbenv->set_mp_max_write = __memp_set_mp_max_write; - dbenv->set_mp_mmapsize = __memp_set_mp_mmapsize; - dbenv->set_msgcall = __env_set_msgcall; - dbenv->set_msgfile = __env_set_msgfile; - dbenv->set_paniccall = __env_set_paniccall; - dbenv->set_rep_limit = __rep_set_limit; - dbenv->set_rep_request = __rep_set_request; - dbenv->set_rep_transport = __rep_set_rep_transport; - dbenv->set_rpc_server = __env_set_rpc_server; - dbenv->set_shm_key = __env_set_shm_key; - dbenv->set_thread_count = __env_set_thread_count; - dbenv->set_thread_id = __env_set_thread_id; - dbenv->set_thread_id_string = __env_set_thread_id_string; - dbenv->set_timeout = __lock_set_env_timeout; - dbenv->set_tmp_dir = __env_set_tmp_dir; - dbenv->set_tx_max = __txn_set_tx_max; - dbenv->set_tx_timestamp = __txn_set_tx_timestamp; - dbenv->set_verbose = __env_set_verbose; - dbenv->stat_print = __env_stat_print_pp; - dbenv->txn_begin = __txn_begin_pp; - dbenv->txn_checkpoint = __txn_checkpoint_pp; - dbenv->txn_recover = __txn_recover_pp; - dbenv->txn_stat = __txn_stat_pp; - dbenv->txn_stat_print = __txn_stat_print_pp; - /* DB_ENV PUBLIC HANDLE LIST END */ - - /* DB_ENV PRIVATE HANDLE LIST BEGIN */ - dbenv->prdbt = __db_prdbt; - /* DB_ENV PRIVATE HANDLE LIST END */ - - __os_id(NULL, &dbenv->pid_cache, NULL); - dbenv->thread_id = __os_id; - dbenv->thread_id_string = __env_thread_id_string; - dbenv->db_ref = 0; - dbenv->shm_key = INVALID_REGION_SEGID; - - __lock_dbenv_create(dbenv); /* Subsystem specific. */ - __log_dbenv_create(dbenv); - __memp_dbenv_create(dbenv); - __txn_dbenv_create(dbenv); - -#ifdef HAVE_RPC - /* - * RPC specific: must be last, as we replace methods set by the - * access methods. - */ - if (F_ISSET(dbenv, DB_ENV_RPCCLIENT)) { - __dbcl_dbenv_init(dbenv); - /* - * !!! - * We wrap the DB_ENV->open and close methods for RPC, and - * the rpc.src file can't handle that. - */ - dbenv->open = __dbcl_env_open_wrap; - dbenv->close = __dbcl_env_close_wrap; - } -#endif - - return (0); -} - -/* - * __env_err -- - * Error message, including the standard error string. - */ -static void -#ifdef STDC_HEADERS -__env_err(const DB_ENV *dbenv, int error, const char *fmt, ...) -#else -__env_err(dbenv, error, fmt, va_alist) - const DB_ENV *dbenv; - int error; - const char *fmt; - va_dcl -#endif -{ - DB_REAL_ERR(dbenv, error, 1, 1, fmt); -} - -/* - * __env_errx -- - * Error message. - */ -static void -#ifdef STDC_HEADERS -__env_errx(const DB_ENV *dbenv, const char *fmt, ...) -#else -__env_errx(dbenv, fmt, va_alist) - const DB_ENV *dbenv; - const char *fmt; - va_dcl -#endif -{ - DB_REAL_ERR(dbenv, 0, 0, 1, fmt); -} - -static int -__env_get_home(dbenv, homep) - DB_ENV *dbenv; - const char **homep; -{ - ENV_ILLEGAL_BEFORE_OPEN(dbenv, "DB_ENV->get_home"); - *homep = dbenv->db_home; - return (0); -} - -/* - * __env_set_alloc -- - * {DB_ENV,DB}->set_alloc. - * - * PUBLIC: int __env_set_alloc __P((DB_ENV *, void *(*)(size_t), - * PUBLIC: void *(*)(void *, size_t), void (*)(void *))); - */ -int -__env_set_alloc(dbenv, mal_func, real_func, free_func) - DB_ENV *dbenv; - void *(*mal_func) __P((size_t)); - void *(*real_func) __P((void *, size_t)); - void (*free_func) __P((void *)); -{ - ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_alloc"); - - dbenv->db_malloc = mal_func; - dbenv->db_realloc = real_func; - dbenv->db_free = free_func; - return (0); -} - -/* - * __env_set_app_dispatch -- - * Set the transaction abort recover function. - */ -static int -__env_set_app_dispatch(dbenv, app_dispatch) - DB_ENV *dbenv; - int (*app_dispatch) __P((DB_ENV *, DBT *, DB_LSN *, db_recops)); -{ - ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_app_dispatch"); - - dbenv->app_dispatch = app_dispatch; - return (0); -} - -/* - * __env_get_encrypt_flags -- - * {DB_ENV,DB}->get_encrypt_flags. - * - * PUBLIC: int __env_get_encrypt_flags __P((DB_ENV *, u_int32_t *)); - */ -int -__env_get_encrypt_flags(dbenv, flagsp) - DB_ENV *dbenv; - u_int32_t *flagsp; -{ -#ifdef HAVE_CRYPTO - DB_CIPHER *db_cipher; - - db_cipher = dbenv->crypto_handle; - if (db_cipher != NULL && db_cipher->alg == CIPHER_AES) - *flagsp = DB_ENCRYPT_AES; - else - *flagsp = 0; - return (0); -#else - COMPQUIET(flagsp, 0); - __db_err(dbenv, - "library build did not include support for cryptography"); - return (DB_OPNOTSUP); -#endif -} - -/* - * __env_set_encrypt -- - * DB_ENV->set_encrypt. - * - * PUBLIC: int __env_set_encrypt __P((DB_ENV *, const char *, u_int32_t)); - */ -int -__env_set_encrypt(dbenv, passwd, flags) - DB_ENV *dbenv; - const char *passwd; - u_int32_t flags; -{ -#ifdef HAVE_CRYPTO - DB_CIPHER *db_cipher; - int ret; - - ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_encrypt"); -#define OK_CRYPTO_FLAGS (DB_ENCRYPT_AES) - - if (flags != 0 && LF_ISSET(~OK_CRYPTO_FLAGS)) - return (__db_ferr(dbenv, "DB_ENV->set_encrypt", 0)); - - if (passwd == NULL || strlen(passwd) == 0) { - __db_err(dbenv, "Empty password specified to set_encrypt"); - return (EINVAL); - } - if (!CRYPTO_ON(dbenv)) { - if ((ret = __os_calloc(dbenv, 1, sizeof(DB_CIPHER), &db_cipher)) - != 0) - goto err; - dbenv->crypto_handle = db_cipher; - } else - db_cipher = (DB_CIPHER *)dbenv->crypto_handle; - - if (dbenv->passwd != NULL) - __os_free(dbenv, dbenv->passwd); - if ((ret = __os_strdup(dbenv, passwd, &dbenv->passwd)) != 0) { - __os_free(dbenv, db_cipher); - goto err; - } - /* - * We're going to need this often enough to keep around - */ - dbenv->passwd_len = strlen(dbenv->passwd) + 1; - /* - * The MAC key is for checksumming, and is separate from - * the algorithm. So initialize it here, even if they - * are using CIPHER_ANY. - */ - __db_derive_mac((u_int8_t *)dbenv->passwd, - dbenv->passwd_len, db_cipher->mac_key); - switch (flags) { - case 0: - F_SET(db_cipher, CIPHER_ANY); - break; - case DB_ENCRYPT_AES: - if ((ret = __crypto_algsetup(dbenv, db_cipher, CIPHER_AES, 0)) - != 0) - goto err1; - break; - default: /* Impossible. */ - break; - } - return (0); - -err1: - __os_free(dbenv, dbenv->passwd); - __os_free(dbenv, db_cipher); - dbenv->crypto_handle = NULL; -err: - return (ret); -#else - COMPQUIET(passwd, NULL); - COMPQUIET(flags, 0); - - __db_err(dbenv, - "library build did not include support for cryptography"); - return (DB_OPNOTSUP); -#endif -} - -static void -__env_map_flags(dbenv, inflagsp, outflagsp) - DB_ENV *dbenv; - u_int32_t *inflagsp, *outflagsp; -{ - COMPQUIET(dbenv, NULL); - - if (FLD_ISSET(*inflagsp, DB_AUTO_COMMIT)) { - FLD_SET(*outflagsp, DB_ENV_AUTO_COMMIT); - FLD_CLR(*inflagsp, DB_AUTO_COMMIT); - } - if (FLD_ISSET(*inflagsp, DB_CDB_ALLDB)) { - FLD_SET(*outflagsp, DB_ENV_CDB_ALLDB); - FLD_CLR(*inflagsp, DB_CDB_ALLDB); - } - if (FLD_ISSET(*inflagsp, DB_DIRECT_DB)) { - FLD_SET(*outflagsp, DB_ENV_DIRECT_DB); - FLD_CLR(*inflagsp, DB_DIRECT_DB); - } - if (FLD_ISSET(*inflagsp, DB_DIRECT_LOG)) { - FLD_SET(*outflagsp, DB_ENV_DIRECT_LOG); - FLD_CLR(*inflagsp, DB_DIRECT_LOG); - } - if (FLD_ISSET(*inflagsp, DB_DSYNC_DB)) { - FLD_SET(*outflagsp, DB_ENV_DSYNC_DB); - FLD_CLR(*inflagsp, DB_DSYNC_DB); - } - if (FLD_ISSET(*inflagsp, DB_DSYNC_LOG)) { - FLD_SET(*outflagsp, DB_ENV_DSYNC_LOG); - FLD_CLR(*inflagsp, DB_DSYNC_LOG); - } - if (FLD_ISSET(*inflagsp, DB_LOG_AUTOREMOVE)) { - FLD_SET(*outflagsp, DB_ENV_LOG_AUTOREMOVE); - FLD_CLR(*inflagsp, DB_LOG_AUTOREMOVE); - } - if (FLD_ISSET(*inflagsp, DB_LOG_INMEMORY)) { - FLD_SET(*outflagsp, DB_ENV_LOG_INMEMORY); - FLD_CLR(*inflagsp, DB_LOG_INMEMORY); - } - if (FLD_ISSET(*inflagsp, DB_NOLOCKING)) { - FLD_SET(*outflagsp, DB_ENV_NOLOCKING); - FLD_CLR(*inflagsp, DB_NOLOCKING); - } - if (FLD_ISSET(*inflagsp, DB_NOMMAP)) { - FLD_SET(*outflagsp, DB_ENV_NOMMAP); - FLD_CLR(*inflagsp, DB_NOMMAP); - } - if (FLD_ISSET(*inflagsp, DB_NOPANIC)) { - FLD_SET(*outflagsp, DB_ENV_NOPANIC); - FLD_CLR(*inflagsp, DB_NOPANIC); - } - if (FLD_ISSET(*inflagsp, DB_OVERWRITE)) { - FLD_SET(*outflagsp, DB_ENV_OVERWRITE); - FLD_CLR(*inflagsp, DB_OVERWRITE); - } - if (FLD_ISSET(*inflagsp, DB_REGION_INIT)) { - FLD_SET(*outflagsp, DB_ENV_REGION_INIT); - FLD_CLR(*inflagsp, DB_REGION_INIT); - } - if (FLD_ISSET(*inflagsp, DB_TIME_NOTGRANTED)) { - FLD_SET(*outflagsp, DB_ENV_TIME_NOTGRANTED); - FLD_CLR(*inflagsp, DB_TIME_NOTGRANTED); - } - if (FLD_ISSET(*inflagsp, DB_TXN_NOSYNC)) { - FLD_SET(*outflagsp, DB_ENV_TXN_NOSYNC); - FLD_CLR(*inflagsp, DB_TXN_NOSYNC); - } - if (FLD_ISSET(*inflagsp, DB_TXN_WRITE_NOSYNC)) { - FLD_SET(*outflagsp, DB_ENV_TXN_WRITE_NOSYNC); - FLD_CLR(*inflagsp, DB_TXN_WRITE_NOSYNC); - } - if (FLD_ISSET(*inflagsp, DB_YIELDCPU)) { - FLD_SET(*outflagsp, DB_ENV_YIELDCPU); - FLD_CLR(*inflagsp, DB_YIELDCPU); - } -} - -static int -__env_get_flags(dbenv, flagsp) - DB_ENV *dbenv; - u_int32_t *flagsp; -{ - static const u_int32_t env_flags[] = { - DB_AUTO_COMMIT, - DB_CDB_ALLDB, - DB_DIRECT_DB, - DB_DIRECT_LOG, - DB_DSYNC_DB, - DB_DSYNC_LOG, - DB_LOG_AUTOREMOVE, - DB_LOG_INMEMORY, - DB_NOLOCKING, - DB_NOMMAP, - DB_NOPANIC, - DB_OVERWRITE, - DB_REGION_INIT, - DB_TIME_NOTGRANTED, - DB_TXN_NOSYNC, - DB_TXN_WRITE_NOSYNC, - DB_YIELDCPU, - 0 - }; - u_int32_t f, flags, mapped_flag; - int i; - - flags = 0; - for (i = 0; (f = env_flags[i]) != 0; i++) { - mapped_flag = 0; - __env_map_flags(dbenv, &f, &mapped_flag); - DB_ASSERT(f == 0); - if (F_ISSET(dbenv, mapped_flag) == mapped_flag) - LF_SET(env_flags[i]); - } - - /* Some flags are persisted in the regions. */ - if (dbenv->reginfo != NULL && - ((REGENV *)((REGINFO *)dbenv->reginfo)->primary)->panic != 0) { - LF_SET(DB_PANIC_ENVIRONMENT); - } - __log_get_flags(dbenv, &flags); - - *flagsp = flags; - return (0); -} - -/* - * __env_set_flags -- - * DB_ENV->set_flags. - * - * PUBLIC: int __env_set_flags __P((DB_ENV *, u_int32_t, int)); - */ -int -__env_set_flags(dbenv, flags, on) - DB_ENV *dbenv; - u_int32_t flags; - int on; -{ - u_int32_t mapped_flags; - int ret; - -#define OK_FLAGS \ - (DB_AUTO_COMMIT | DB_CDB_ALLDB | DB_DIRECT_DB | DB_DIRECT_LOG | \ - DB_DSYNC_DB | DB_DSYNC_LOG | DB_LOG_AUTOREMOVE | \ - DB_LOG_INMEMORY | DB_NOLOCKING | DB_NOMMAP | DB_NOPANIC | \ - DB_OVERWRITE | DB_PANIC_ENVIRONMENT | DB_REGION_INIT | \ - DB_TIME_NOTGRANTED | DB_TXN_NOSYNC | DB_TXN_WRITE_NOSYNC | \ - DB_YIELDCPU) - - if (LF_ISSET(~OK_FLAGS)) - return (__db_ferr(dbenv, "DB_ENV->set_flags", 0)); - if (on) { - if ((ret = __db_fcchk(dbenv, "DB_ENV->set_flags", - flags, DB_LOG_INMEMORY, DB_TXN_NOSYNC)) != 0) - return (ret); - if ((ret = __db_fcchk(dbenv, "DB_ENV->set_flags", - flags, DB_LOG_INMEMORY, DB_TXN_WRITE_NOSYNC)) != 0) - return (ret); - if ((ret = __db_fcchk(dbenv, "DB_ENV->set_flags", - flags, DB_TXN_NOSYNC, DB_TXN_WRITE_NOSYNC)) != 0) - return (ret); - if (LF_ISSET(DB_DIRECT_DB | - DB_DIRECT_LOG) && __os_have_direct() == 0) { - __db_err(dbenv, - "DB_ENV->set_flags: direct I/O either not configured or not supported"); - return (EINVAL); - } - } - - if (LF_ISSET(DB_CDB_ALLDB)) - ENV_ILLEGAL_AFTER_OPEN(dbenv, - "DB_ENV->set_flags: DB_CDB_ALLDB"); - if (LF_ISSET(DB_PANIC_ENVIRONMENT)) { - ENV_ILLEGAL_BEFORE_OPEN(dbenv, - "DB_ENV->set_flags: DB_PANIC_ENVIRONMENT"); - if (on) { - __db_err(dbenv, "Environment panic set"); - (void)__db_panic(dbenv, EACCES); - } else - __db_panic_set(dbenv, 0); - } - if (LF_ISSET(DB_REGION_INIT)) - ENV_ILLEGAL_AFTER_OPEN(dbenv, - "DB_ENV->set_flags: DB_REGION_INIT"); - if (LF_ISSET(DB_LOG_INMEMORY)) - ENV_ILLEGAL_AFTER_OPEN(dbenv, - "DB_ENV->set_flags: DB_LOG_INMEMORY"); - - /* - * DB_LOG_INMEMORY, DB_TXN_NOSYNC and DB_TXN_WRITE_NOSYNC are - * mutually incompatible. If we're setting one of them, clear all - * current settings. - */ - if (LF_ISSET( - DB_LOG_INMEMORY | DB_TXN_NOSYNC | DB_TXN_WRITE_NOSYNC)) - F_CLR(dbenv, - DB_ENV_LOG_INMEMORY | - DB_ENV_TXN_NOSYNC | DB_ENV_TXN_WRITE_NOSYNC); - - /* Some flags are persisted in the regions. */ - __log_set_flags(dbenv, flags, on); - - mapped_flags = 0; - __env_map_flags(dbenv, &flags, &mapped_flags); - if (on) - F_SET(dbenv, mapped_flags); - else - F_CLR(dbenv, mapped_flags); - - return (0); -} - -static int -__env_get_data_dirs(dbenv, dirpp) - DB_ENV *dbenv; - const char ***dirpp; -{ - *dirpp = (const char **)dbenv->db_data_dir; - return (0); -} - -/* - * __env_set_data_dir -- - * DB_ENV->set_data_dir. - * - * PUBLIC: int __env_set_data_dir __P((DB_ENV *, const char *)); - */ -int -__env_set_data_dir(dbenv, dir) - DB_ENV *dbenv; - const char *dir; -{ - int ret; - - /* - * The array is NULL-terminated so it can be returned by get_data_dirs - * without a length. - */ - -#define DATA_INIT_CNT 20 /* Start with 20 data slots. */ - if (dbenv->db_data_dir == NULL) { - if ((ret = __os_calloc(dbenv, DATA_INIT_CNT, - sizeof(char **), &dbenv->db_data_dir)) != 0) - return (ret); - dbenv->data_cnt = DATA_INIT_CNT; - } else if (dbenv->data_next == dbenv->data_cnt - 2) { - dbenv->data_cnt *= 2; - if ((ret = __os_realloc(dbenv, - (u_int)dbenv->data_cnt * sizeof(char **), - &dbenv->db_data_dir)) != 0) - return (ret); - } - - ret = __os_strdup(dbenv, - dir, &dbenv->db_data_dir[dbenv->data_next++]); - dbenv->db_data_dir[dbenv->data_next] = NULL; - return (ret); -} - -/* - * __env_set_intermediate_dir -- - * DB_ENV->set_intermediate_dir. - * - * !!! - * Undocumented routine allowing applications to configure Berkeley DB to - * create intermediate directories. - * - * PUBLIC: int __env_set_intermediate_dir __P((DB_ENV *, int, u_int32_t)); - */ -int -__env_set_intermediate_dir(dbenv, mode, flags) - DB_ENV *dbenv; - int mode; - u_int32_t flags; -{ - if (flags != 0) - return (__db_ferr(dbenv, "DB_ENV->set_intermediate_dir", 0)); - if (mode == 0) { - __db_err(dbenv, - "DB_ENV->set_intermediate_dir: mode may not be set to 0"); - return (EINVAL); - } - - dbenv->dir_mode = mode; - return (0); -} - -/* - * __env_set_errcall -- - * {DB_ENV,DB}->set_errcall. - * - * PUBLIC: void __env_set_errcall __P((DB_ENV *, - * PUBLIC: void (*)(const DB_ENV *, const char *, const char *))); - */ -void -__env_set_errcall(dbenv, errcall) - DB_ENV *dbenv; - void (*errcall) __P((const DB_ENV *, const char *, const char *)); -{ - dbenv->db_errcall = errcall; -} - -/* - * __env_get_errfile -- - * {DB_ENV,DB}->get_errfile. - * - * PUBLIC: void __env_get_errfile __P((DB_ENV *, FILE **)); - */ -void -__env_get_errfile(dbenv, errfilep) - DB_ENV *dbenv; - FILE **errfilep; -{ - *errfilep = dbenv->db_errfile; -} - -/* - * __env_set_errfile -- - * {DB_ENV,DB}->set_errfile. - * - * PUBLIC: void __env_set_errfile __P((DB_ENV *, FILE *)); - */ -void -__env_set_errfile(dbenv, errfile) - DB_ENV *dbenv; - FILE *errfile; -{ - dbenv->db_errfile = errfile; -} - -/* - * __env_get_errpfx -- - * {DB_ENV,DB}->get_errpfx. - * - * PUBLIC: void __env_get_errpfx __P((DB_ENV *, const char **)); - */ -void -__env_get_errpfx(dbenv, errpfxp) - DB_ENV *dbenv; - const char **errpfxp; -{ - *errpfxp = dbenv->db_errpfx; -} - -/* - * __env_set_errpfx -- - * {DB_ENV,DB}->set_errpfx. - * - * PUBLIC: void __env_set_errpfx __P((DB_ENV *, const char *)); - */ -void -__env_set_errpfx(dbenv, errpfx) - DB_ENV *dbenv; - const char *errpfx; -{ - dbenv->db_errpfx = errpfx; -} - -static int -__env_set_feedback(dbenv, feedback) - DB_ENV *dbenv; - void (*feedback) __P((DB_ENV *, int, int)); -{ - dbenv->db_feedback = feedback; - return (0); -} - -/* - * __env_set_thread_id -- - * DB_ENV->set_thread_id - */ -static int -__env_set_thread_id(dbenv, id) - DB_ENV *dbenv; - void (*id) __P((DB_ENV *, pid_t *, db_threadid_t *)); -{ - dbenv->thread_id = id; - return (0); -} - -/* - * __env_set_threadid_string -- - * DB_ENV->set_threadid_string - */ -static int -__env_set_thread_id_string(dbenv, thread_id_string) - DB_ENV *dbenv; - char *(*thread_id_string) __P((DB_ENV *, pid_t, db_threadid_t, char *)); -{ - dbenv->thread_id_string = thread_id_string; - return (0); -} - -/* - * __env_set_isalive -- - * DB_ENV->set_isalive - */ -static int -__env_set_isalive(dbenv, is_alive) - DB_ENV *dbenv; - int (*is_alive) __P((DB_ENV *, pid_t, db_threadid_t)); -{ - if (F_ISSET((dbenv), DB_ENV_OPEN_CALLED) && - dbenv->thr_nbucket == 0) { - __db_err(dbenv, - "is_alive method specified but no thread region allocated"); - return (EINVAL); - } - dbenv->is_alive = is_alive; - return (0); -} - -/* - * __env_set_thread_count -- - * DB_ENV->set_thread_count - */ -static int -__env_set_thread_count(dbenv, count) - DB_ENV *dbenv; - u_int32_t count; -{ - ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_thread_count"); - dbenv->thr_max = count; - - /* - * Set the number of buckets to be 1/8th the number of - * proposed threads control blocks. This is rather - * arbitrary. - */ - dbenv->thr_nbucket = count / 8; - return (0); -} - -/* - * __env_set_msgcall -- - * {DB_ENV,DB}->set_msgcall. - * - * PUBLIC: void __env_set_msgcall - * PUBLIC: __P((DB_ENV *, void (*)(const DB_ENV *, const char *))); - */ -void -__env_set_msgcall(dbenv, msgcall) - DB_ENV *dbenv; - void (*msgcall) __P((const DB_ENV *, const char *)); -{ - dbenv->db_msgcall = msgcall; -} - -/* - * __env_get_msgfile -- - * {DB_ENV,DB}->get_msgfile. - * - * PUBLIC: void __env_get_msgfile __P((DB_ENV *, FILE **)); - */ -void -__env_get_msgfile(dbenv, msgfilep) - DB_ENV *dbenv; - FILE **msgfilep; -{ - *msgfilep = dbenv->db_msgfile; -} - -/* - * __env_set_msgfile -- - * {DB_ENV,DB}->set_msgfile. - * - * PUBLIC: void __env_set_msgfile __P((DB_ENV *, FILE *)); - */ -void -__env_set_msgfile(dbenv, msgfile) - DB_ENV *dbenv; - FILE *msgfile; -{ - dbenv->db_msgfile = msgfile; -} - -/* - * __env_set_paniccall -- - * {DB_ENV,DB}->set_paniccall. - * - * PUBLIC: int __env_set_paniccall __P((DB_ENV *, void (*)(DB_ENV *, int))); - */ -int -__env_set_paniccall(dbenv, paniccall) - DB_ENV *dbenv; - void (*paniccall) __P((DB_ENV *, int)); -{ - dbenv->db_paniccall = paniccall; - return (0); -} - -static int -__env_get_shm_key(dbenv, shm_keyp) - DB_ENV *dbenv; - long *shm_keyp; /* !!!: really a key_t *. */ -{ - *shm_keyp = dbenv->shm_key; - return (0); -} - -/* - * __env_set_shm_key -- - * DB_ENV->set_shm_key. - * - * PUBLIC: int __env_set_shm_key __P((DB_ENV *, long)); - */ -int -__env_set_shm_key(dbenv, shm_key) - DB_ENV *dbenv; - long shm_key; /* !!!: really a key_t. */ -{ - ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_shm_key"); - - dbenv->shm_key = shm_key; - return (0); -} - -static int -__env_get_tmp_dir(dbenv, dirp) - DB_ENV *dbenv; - const char **dirp; -{ - *dirp = dbenv->db_tmp_dir; - return (0); -} - -/* - * __env_set_tmp_dir -- - * DB_ENV->set_tmp_dir. - * - * PUBLIC: int __env_set_tmp_dir __P((DB_ENV *, const char *)); - */ -int -__env_set_tmp_dir(dbenv, dir) - DB_ENV *dbenv; - const char *dir; -{ - if (dbenv->db_tmp_dir != NULL) - __os_free(dbenv, dbenv->db_tmp_dir); - return (__os_strdup(dbenv, dir, &dbenv->db_tmp_dir)); -} - -static int -__env_get_verbose(dbenv, which, onoffp) - DB_ENV *dbenv; - u_int32_t which; - int *onoffp; -{ - switch (which) { - case DB_VERB_DEADLOCK: - case DB_VERB_RECOVERY: - case DB_VERB_REGISTER: - case DB_VERB_REPLICATION: - case DB_VERB_WAITSFOR: - *onoffp = FLD_ISSET(dbenv->verbose, which) ? 1 : 0; - break; - default: - return (EINVAL); - } - return (0); -} - -/* - * __env_set_verbose -- - * DB_ENV->set_verbose. - * - * PUBLIC: int __env_set_verbose __P((DB_ENV *, u_int32_t, int)); - */ -int -__env_set_verbose(dbenv, which, on) - DB_ENV *dbenv; - u_int32_t which; - int on; -{ - switch (which) { - case DB_VERB_DEADLOCK: - case DB_VERB_RECOVERY: - case DB_VERB_REGISTER: - case DB_VERB_REPLICATION: - case DB_VERB_WAITSFOR: - if (on) - FLD_SET(dbenv->verbose, which); - else - FLD_CLR(dbenv->verbose, which); - break; - default: - return (EINVAL); - } - return (0); -} - -/* - * __db_mi_env -- - * Method illegally called with public environment. - * - * PUBLIC: int __db_mi_env __P((DB_ENV *, const char *)); - */ -int -__db_mi_env(dbenv, name) - DB_ENV *dbenv; - const char *name; -{ - __db_err(dbenv, "%s: method not permitted when environment specified", - name); - return (EINVAL); -} - -/* - * __db_mi_open -- - * Method illegally called after open. - * - * PUBLIC: int __db_mi_open __P((DB_ENV *, const char *, int)); - */ -int -__db_mi_open(dbenv, name, after) - DB_ENV *dbenv; - const char *name; - int after; -{ - __db_err(dbenv, "%s: method not permitted %s handle's open method", - name, after ? "after" : "before"); - return (EINVAL); -} - -/* - * __db_env_config -- - * Method or function called without required configuration. - * - * PUBLIC: int __db_env_config __P((DB_ENV *, char *, u_int32_t)); - */ -int -__db_env_config(dbenv, i, flags) - DB_ENV *dbenv; - char *i; - u_int32_t flags; -{ - char *sub; - - switch (flags) { - case DB_INIT_LOCK: - sub = "locking"; - break; - case DB_INIT_LOG: - sub = "logging"; - break; - case DB_INIT_MPOOL: - sub = "memory pool"; - break; - case DB_INIT_REP: - sub = "replication"; - break; - case DB_INIT_TXN: - sub = "transaction"; - break; - default: - sub = "<unspecified>"; - break; - } - __db_err(dbenv, - "%s interface requires an environment configured for the %s subsystem", - i, sub); - return (EINVAL); -} - -static int -__env_set_rpc_server(dbenv, cl, host, tsec, ssec, flags) - DB_ENV *dbenv; - void *cl; - const char *host; - long tsec, ssec; - u_int32_t flags; -{ - COMPQUIET(host, NULL); - COMPQUIET(cl, NULL); - COMPQUIET(tsec, 0); - COMPQUIET(ssec, 0); - COMPQUIET(flags, 0); - - __db_err(dbenv, "Berkeley DB was not configured for RPC support"); - return (DB_OPNOTSUP); -} diff --git a/storage/bdb/env/env_method.c.b b/storage/bdb/env/env_method.c.b deleted file mode 100644 index b6802b8a77c..00000000000 --- a/storage/bdb/env/env_method.c.b +++ /dev/null @@ -1,643 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2002 - * Sleepycat Software. All rights reserved. - */ - -#include "db_config.h" - -#ifndef lint -static const char revid[] = "$Id: env_method.c,v 11.87 2002/08/29 14:22:21 margo Exp $"; -#endif /* not lint */ - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#ifdef HAVE_RPC -#include <rpc/rpc.h> -#endif - -#include <string.h> -#endif - -/* - * This is the file that initializes the global array. Do it this way because - * people keep changing one without changing the other. Having declaration and - * initialization in one file will hopefully fix that. - */ -#define DB_INITIALIZE_DB_GLOBALS 1 - -#include "db_int.h" -#include "dbinc/crypto.h" -#include "dbinc/hmac.h" -#include "dbinc/db_shash.h" -#include "dbinc/db_page.h" -#include "dbinc/db_am.h" -#include "dbinc/lock.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" -#include "dbinc/rep.h" -#include "dbinc/txn.h" - -#ifdef HAVE_RPC -#include "dbinc_auto/db_server.h" -#include "dbinc_auto/rpc_client_ext.h" -#endif - -static void __dbenv_err __P((const DB_ENV *, int, const char *, ...)); -static void __dbenv_errx __P((const DB_ENV *, const char *, ...)); -static int __dbenv_init __P((DB_ENV *)); -static int __dbenv_set_alloc __P((DB_ENV *, void *(*)(size_t), - void *(*)(void *, size_t), void (*)(void *))); -static int __dbenv_set_app_dispatch __P((DB_ENV *, - int (*)(DB_ENV *, DBT *, DB_LSN *, db_recops))); -static int __dbenv_set_data_dir __P((DB_ENV *, const char *)); -static int __dbenv_set_encrypt __P((DB_ENV *, const char *, u_int32_t)); -static void __dbenv_set_errcall __P((DB_ENV *, void (*)(const char *, char *))); -static void __dbenv_set_errfile __P((DB_ENV *, FILE *)); -static void __dbenv_set_errpfx __P((DB_ENV *, const char *)); -static int __dbenv_set_feedback __P((DB_ENV *, void (*)(DB_ENV *, int, int))); -static int __dbenv_set_flags __P((DB_ENV *, u_int32_t, int)); -static void __dbenv_set_noticecall __P((DB_ENV *, void (*)(DB_ENV *, db_notices))); -static int __dbenv_set_paniccall __P((DB_ENV *, void (*)(DB_ENV *, int))); -static int __dbenv_set_rpc_server_noclnt - __P((DB_ENV *, void *, const char *, long, long, u_int32_t)); -static int __dbenv_set_shm_key __P((DB_ENV *, long)); -static int __dbenv_set_tas_spins __P((DB_ENV *, u_int32_t)); -static int __dbenv_set_tmp_dir __P((DB_ENV *, const char *)); -static int __dbenv_set_verbose __P((DB_ENV *, u_int32_t, int)); - -/* - * db_env_create -- - * DB_ENV constructor. - * - * EXTERN: int db_env_create __P((DB_ENV **, u_int32_t)); - */ -int -db_env_create(dbenvpp, flags) - DB_ENV **dbenvpp; - u_int32_t flags; -{ - DB_ENV *dbenv; - int ret; - - /* - * !!! - * Our caller has not yet had the opportunity to reset the panic - * state or turn off mutex locking, and so we can neither check - * the panic state or acquire a mutex in the DB_ENV create path. - * - * !!! - * We can't call the flags-checking routines, we don't have an - * environment yet. - */ - if (flags != 0 && flags != DB_CLIENT) - return (EINVAL); - - if ((ret = __os_calloc(NULL, 1, sizeof(*dbenv), &dbenv)) != 0) - return (ret); - -#ifdef HAVE_RPC - if (LF_ISSET(DB_CLIENT)) - F_SET(dbenv, DB_ENV_RPCCLIENT); -#endif - ret = __dbenv_init(dbenv); - - if (ret != 0) { - __os_free(NULL, dbenv); - return (ret); - } - - *dbenvpp = dbenv; - return (0); -} - -/* - * __dbenv_init -- - * Initialize a DB_ENV structure. - */ -static int -__dbenv_init(dbenv) - DB_ENV *dbenv; -{ - /* - * !!! - * Our caller has not yet had the opportunity to reset the panic - * state or turn off mutex locking, and so we can neither check - * the panic state or acquire a mutex in the DB_ENV create path. - * - * Set up methods that are the same in both normal and RPC - */ - dbenv->err = __dbenv_err; - dbenv->errx = __dbenv_errx; - dbenv->set_errcall = __dbenv_set_errcall; - dbenv->set_errfile = __dbenv_set_errfile; - dbenv->set_errpfx = __dbenv_set_errpfx; - -#ifdef HAVE_RPC - if (F_ISSET(dbenv, DB_ENV_RPCCLIENT)) { - dbenv->close = __dbcl_env_close; - dbenv->dbremove = __dbcl_env_dbremove; - dbenv->dbrename = __dbcl_env_dbrename; - dbenv->open = __dbcl_env_open_wrap; - dbenv->remove = __dbcl_env_remove; - dbenv->set_alloc = __dbcl_env_alloc; - dbenv->set_app_dispatch = __dbcl_set_app_dispatch; - dbenv->set_data_dir = __dbcl_set_data_dir; - dbenv->set_encrypt = __dbcl_env_encrypt; - dbenv->set_feedback = __dbcl_env_set_feedback; - dbenv->set_flags = __dbcl_env_flags; - dbenv->set_noticecall = __dbcl_env_noticecall; - dbenv->set_paniccall = __dbcl_env_paniccall; - dbenv->set_rpc_server = __dbcl_envrpcserver; - dbenv->set_shm_key = __dbcl_set_shm_key; - dbenv->set_tas_spins = __dbcl_set_tas_spins; - dbenv->set_timeout = __dbcl_set_timeout; - dbenv->set_tmp_dir = __dbcl_set_tmp_dir; - dbenv->set_verbose = __dbcl_set_verbose; - } else { -#endif - dbenv->close = __dbenv_close; - dbenv->dbremove = __dbenv_dbremove; - dbenv->dbrename = __dbenv_dbrename; - dbenv->open = __dbenv_open; - dbenv->remove = __dbenv_remove; - dbenv->set_alloc = __dbenv_set_alloc; - dbenv->set_app_dispatch = __dbenv_set_app_dispatch; - dbenv->set_data_dir = __dbenv_set_data_dir; - dbenv->set_encrypt = __dbenv_set_encrypt; - dbenv->set_feedback = __dbenv_set_feedback; - dbenv->set_flags = __dbenv_set_flags; - dbenv->set_noticecall = __dbcl_env_noticecall; - dbenv->set_paniccall = __dbenv_set_paniccall; - dbenv->set_rpc_server = __dbenv_set_rpc_server_noclnt; - dbenv->set_shm_key = __dbenv_set_shm_key; - dbenv->set_tas_spins = __dbenv_set_tas_spins; - dbenv->set_tmp_dir = __dbenv_set_tmp_dir; - dbenv->set_verbose = __dbenv_set_verbose; -#ifdef HAVE_RPC - } -#endif - dbenv->shm_key = INVALID_REGION_SEGID; - dbenv->db_ref = 0; - - __log_dbenv_create(dbenv); /* Subsystem specific. */ - __lock_dbenv_create(dbenv); - __memp_dbenv_create(dbenv); - __rep_dbenv_create(dbenv); - __txn_dbenv_create(dbenv); - - return (0); -} - -/* - * __dbenv_err -- - * Error message, including the standard error string. - */ -static void -#ifdef __STDC__ -__dbenv_err(const DB_ENV *dbenv, int error, const char *fmt, ...) -#else -__dbenv_err(dbenv, error, fmt, va_alist) - const DB_ENV *dbenv; - int error; - const char *fmt; - va_dcl -#endif -{ - DB_REAL_ERR(dbenv, error, 1, 1, fmt); -} - -/* - * __dbenv_errx -- - * Error message. - */ -static void -#ifdef __STDC__ -__dbenv_errx(const DB_ENV *dbenv, const char *fmt, ...) -#else -__dbenv_errx(dbenv, fmt, va_alist) - const DB_ENV *dbenv; - const char *fmt; - va_dcl -#endif -{ - DB_REAL_ERR(dbenv, 0, 0, 1, fmt); -} - -static int -__dbenv_set_alloc(dbenv, mal_func, real_func, free_func) - DB_ENV *dbenv; - void *(*mal_func) __P((size_t)); - void *(*real_func) __P((void *, size_t)); - void (*free_func) __P((void *)); -{ - ENV_ILLEGAL_AFTER_OPEN(dbenv, "set_alloc"); - - dbenv->db_malloc = mal_func; - dbenv->db_realloc = real_func; - dbenv->db_free = free_func; - return (0); -} - -/* - * __dbenv_set_app_dispatch -- - * Set the transaction abort recover function. - */ -static int -__dbenv_set_app_dispatch(dbenv, app_dispatch) - DB_ENV *dbenv; - int (*app_dispatch) __P((DB_ENV *, DBT *, DB_LSN *, db_recops)); -{ - ENV_ILLEGAL_AFTER_OPEN(dbenv, "set_app_dispatch"); - - dbenv->app_dispatch = app_dispatch; - return (0); -} - -static int -__dbenv_set_encrypt(dbenv, passwd, flags) - DB_ENV *dbenv; - const char *passwd; - u_int32_t flags; -{ -#ifdef HAVE_CRYPTO - DB_CIPHER *db_cipher; - int ret; - - ENV_ILLEGAL_AFTER_OPEN(dbenv, "set_encrypt"); -#define OK_CRYPTO_FLAGS (DB_ENCRYPT_AES) - - if (flags != 0 && LF_ISSET(~OK_CRYPTO_FLAGS)) - return (__db_ferr(dbenv, "DB_ENV->set_encrypt", 0)); - - if (passwd == NULL || strlen(passwd) == 0) { - __db_err(dbenv, "Empty password specified to set_encrypt"); - return (EINVAL); - } - if (!CRYPTO_ON(dbenv)) { - if ((ret = __os_calloc(dbenv, 1, sizeof(DB_CIPHER), &db_cipher)) - != 0) - goto err; - dbenv->crypto_handle = db_cipher; - } else - db_cipher = (DB_CIPHER *)dbenv->crypto_handle; - - if (dbenv->passwd != NULL) - __os_free(dbenv, dbenv->passwd); - if ((ret = __os_strdup(dbenv, passwd, &dbenv->passwd)) != 0) { - __os_free(dbenv, db_cipher); - goto err; - } - /* - * We're going to need this often enough to keep around - */ - dbenv->passwd_len = strlen(dbenv->passwd) + 1; - /* - * The MAC key is for checksumming, and is separate from - * the algorithm. So initialize it here, even if they - * are using CIPHER_ANY. - */ - __db_derive_mac((u_int8_t *)dbenv->passwd, - dbenv->passwd_len, db_cipher->mac_key); - switch (flags) { - case 0: - F_SET(db_cipher, CIPHER_ANY); - break; - case DB_ENCRYPT_AES: - if ((ret = __crypto_algsetup(dbenv, db_cipher, CIPHER_AES, 0)) - != 0) - goto err1; - break; - } - return (0); - -err1: - __os_free(dbenv, dbenv->passwd); - __os_free(dbenv, db_cipher); - dbenv->crypto_handle = NULL; -err: - return (ret); -#else - COMPQUIET(dbenv, NULL); - COMPQUIET(passwd, NULL); - COMPQUIET(flags, 0); - - return (__db_eopnotsup(dbenv)); -#endif -} - -static int -__dbenv_set_flags(dbenv, flags, onoff) - DB_ENV *dbenv; - u_int32_t flags; - int onoff; -{ -#define OK_FLAGS \ - (DB_AUTO_COMMIT | DB_CDB_ALLDB | DB_DIRECT_DB | DB_DIRECT_LOG | \ - DB_NOLOCKING | DB_NOMMAP | DB_NOPANIC | DB_OVERWRITE | \ - DB_PANIC_ENVIRONMENT | DB_REGION_INIT | DB_TXN_NOSYNC | \ - DB_TXN_WRITE_NOSYNC | DB_YIELDCPU) - - if (LF_ISSET(~OK_FLAGS)) - return (__db_ferr(dbenv, "DB_ENV->set_flags", 0)); - if (onoff && LF_ISSET(DB_TXN_WRITE_NOSYNC) && LF_ISSET(DB_TXN_NOSYNC)) - return (__db_ferr(dbenv, "DB_ENV->set_flags", 1)); - - if (LF_ISSET(DB_AUTO_COMMIT)) { - if (onoff) - F_SET(dbenv, DB_ENV_AUTO_COMMIT); - else - F_CLR(dbenv, DB_ENV_AUTO_COMMIT); - } - if (LF_ISSET(DB_CDB_ALLDB)) { - ENV_ILLEGAL_AFTER_OPEN(dbenv, "set_flags: DB_CDB_ALLDB"); - if (onoff) - F_SET(dbenv, DB_ENV_CDB_ALLDB); - else - F_CLR(dbenv, DB_ENV_CDB_ALLDB); - } - if (LF_ISSET(DB_DIRECT_DB)) { - if (onoff) - F_SET(dbenv, DB_ENV_DIRECT_DB); - else - F_CLR(dbenv, DB_ENV_DIRECT_DB); - } - if (LF_ISSET(DB_DIRECT_LOG)) { - if (onoff) - F_SET(dbenv, DB_ENV_DIRECT_LOG); - else - F_CLR(dbenv, DB_ENV_DIRECT_LOG); - } - if (LF_ISSET(DB_NOLOCKING)) { - if (onoff) - F_SET(dbenv, DB_ENV_NOLOCKING); - else - F_CLR(dbenv, DB_ENV_NOLOCKING); - } - if (LF_ISSET(DB_NOMMAP)) { - if (onoff) - F_SET(dbenv, DB_ENV_NOMMAP); - else - F_CLR(dbenv, DB_ENV_NOMMAP); - } - if (LF_ISSET(DB_NOPANIC)) { - if (onoff) - F_SET(dbenv, DB_ENV_NOPANIC); - else - F_CLR(dbenv, DB_ENV_NOPANIC); - } - if (LF_ISSET(DB_OVERWRITE)) { - if (onoff) - F_SET(dbenv, DB_ENV_OVERWRITE); - else - F_CLR(dbenv, DB_ENV_OVERWRITE); - } - if (LF_ISSET(DB_PANIC_ENVIRONMENT)) { - ENV_ILLEGAL_BEFORE_OPEN(dbenv, - "set_flags: DB_PANIC_ENVIRONMENT"); - PANIC_SET(dbenv, onoff); - } - if (LF_ISSET(DB_REGION_INIT)) { - ENV_ILLEGAL_AFTER_OPEN(dbenv, "set_flags: DB_REGION_INIT"); - if (onoff) - F_SET(dbenv, DB_ENV_REGION_INIT); - else - F_CLR(dbenv, DB_ENV_REGION_INIT); - } - if (LF_ISSET(DB_TXN_NOSYNC)) { - if (onoff) - F_SET(dbenv, DB_ENV_TXN_NOSYNC); - else - F_CLR(dbenv, DB_ENV_TXN_NOSYNC); - } - if (LF_ISSET(DB_TXN_WRITE_NOSYNC)) { - if (onoff) - F_SET(dbenv, DB_ENV_TXN_WRITE_NOSYNC); - else - F_CLR(dbenv, DB_ENV_TXN_WRITE_NOSYNC); - } - if (LF_ISSET(DB_YIELDCPU)) { - if (onoff) - F_SET(dbenv, DB_ENV_YIELDCPU); - else - F_CLR(dbenv, DB_ENV_YIELDCPU); - } - return (0); -} - -static int -__dbenv_set_data_dir(dbenv, dir) - DB_ENV *dbenv; - const char *dir; -{ - int ret; - -#define DATA_INIT_CNT 20 /* Start with 20 data slots. */ - if (dbenv->db_data_dir == NULL) { - if ((ret = __os_calloc(dbenv, DATA_INIT_CNT, - sizeof(char **), &dbenv->db_data_dir)) != 0) - return (ret); - dbenv->data_cnt = DATA_INIT_CNT; - } else if (dbenv->data_next == dbenv->data_cnt - 1) { - dbenv->data_cnt *= 2; - if ((ret = __os_realloc(dbenv, - dbenv->data_cnt * sizeof(char **), - &dbenv->db_data_dir)) != 0) - return (ret); - } - return (__os_strdup(dbenv, - dir, &dbenv->db_data_dir[dbenv->data_next++])); -} - -static void -__dbenv_set_errcall(dbenv, errcall) - DB_ENV *dbenv; - void (*errcall) __P((const char *, char *)); -{ - dbenv->db_errcall = errcall; -} - -static void -__dbenv_set_errfile(dbenv, errfile) - DB_ENV *dbenv; - FILE *errfile; -{ - dbenv->db_errfile = errfile; -} - -static void -__dbenv_set_errpfx(dbenv, errpfx) - DB_ENV *dbenv; - const char *errpfx; -{ - dbenv->db_errpfx = errpfx; -} - -static int -__dbenv_set_feedback(dbenv, feedback) - DB_ENV *dbenv; - void (*feedback) __P((DB_ENV *, int, int)); -{ - dbenv->db_feedback = feedback; - return (0); -} - -static void -__dbenv_set_noticecall(dbenv, noticecall) - DB_ENV *dbenv; - void (*noticecall) __P((DB_ENV *, db_notices)); -{ - dbenv->db_noticecall = noticecall; -} - -static int -__dbenv_set_paniccall(dbenv, paniccall) - DB_ENV *dbenv; - void (*paniccall) __P((DB_ENV *, int)); -{ - dbenv->db_paniccall = paniccall; - return (0); -} - -static int -__dbenv_set_shm_key(dbenv, shm_key) - DB_ENV *dbenv; - long shm_key; /* !!!: really a key_t. */ -{ - ENV_ILLEGAL_AFTER_OPEN(dbenv, "set_shm_key"); - - dbenv->shm_key = shm_key; - return (0); -} - -static int -__dbenv_set_tas_spins(dbenv, tas_spins) - DB_ENV *dbenv; - u_int32_t tas_spins; -{ - dbenv->tas_spins = tas_spins; - return (0); -} - -static int -__dbenv_set_tmp_dir(dbenv, dir) - DB_ENV *dbenv; - const char *dir; -{ - if (dbenv->db_tmp_dir != NULL) - __os_free(dbenv, dbenv->db_tmp_dir); - return (__os_strdup(dbenv, dir, &dbenv->db_tmp_dir)); -} - -static int -__dbenv_set_verbose(dbenv, which, onoff) - DB_ENV *dbenv; - u_int32_t which; - int onoff; -{ - switch (which) { - case DB_VERB_CHKPOINT: - case DB_VERB_DEADLOCK: - case DB_VERB_RECOVERY: - case DB_VERB_REPLICATION: - case DB_VERB_WAITSFOR: - if (onoff) - FLD_SET(dbenv->verbose, which); - else - FLD_CLR(dbenv->verbose, which); - break; - default: - return (EINVAL); - } - return (0); -} - -/* - * __db_mi_env -- - * Method illegally called with public environment. - * - * PUBLIC: int __db_mi_env __P((DB_ENV *, const char *)); - */ -int -__db_mi_env(dbenv, name) - DB_ENV *dbenv; - const char *name; -{ - __db_err(dbenv, "%s: method not permitted in shared environment", name); - return (EINVAL); -} - -/* - * __db_mi_open -- - * Method illegally called after open. - * - * PUBLIC: int __db_mi_open __P((DB_ENV *, const char *, int)); - */ -int -__db_mi_open(dbenv, name, after) - DB_ENV *dbenv; - const char *name; - int after; -{ - __db_err(dbenv, "%s: method not permitted %s open", - name, after ? "after" : "before"); - return (EINVAL); -} - -/* - * __db_env_config -- - * Method or function called without required configuration. - * - * PUBLIC: int __db_env_config __P((DB_ENV *, char *, u_int32_t)); - */ -int -__db_env_config(dbenv, i, flags) - DB_ENV *dbenv; - char *i; - u_int32_t flags; -{ - char *sub; - - switch (flags) { - case DB_INIT_LOCK: - sub = "locking"; - break; - case DB_INIT_LOG: - sub = "logging"; - break; - case DB_INIT_MPOOL: - sub = "memory pool"; - break; - case DB_INIT_TXN: - sub = "transaction"; - break; - default: - sub = "<unspecified>"; - break; - } - __db_err(dbenv, - "%s interface requires an environment configured for the %s subsystem", - i, sub); - return (EINVAL); -} - -static int -__dbenv_set_rpc_server_noclnt(dbenv, cl, host, tsec, ssec, flags) - DB_ENV *dbenv; - void *cl; - const char *host; - long tsec, ssec; - u_int32_t flags; -{ - COMPQUIET(host, NULL); - COMPQUIET(cl, NULL); - COMPQUIET(tsec, 0); - COMPQUIET(ssec, 0); - COMPQUIET(flags, 0); - - __db_err(dbenv, - "set_rpc_server method not permitted in non-RPC environment"); - return (__db_eopnotsup(dbenv)); -} diff --git a/storage/bdb/env/env_open.c b/storage/bdb/env/env_open.c deleted file mode 100644 index d00355a7407..00000000000 --- a/storage/bdb/env/env_open.c +++ /dev/null @@ -1,1593 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: env_open.c,v 12.36 2005/10/31 02:22:28 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <ctype.h> -#include <limits.h> -#include <stdlib.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/crypto.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/btree.h" -#include "dbinc/hash.h" -#include "dbinc/fop.h" -#include "dbinc/lock.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" -#include "dbinc/qam.h" -#include "dbinc/txn.h" - -static int __db_parse __P((DB_ENV *, char *)); -static int __db_tmp_open __P((DB_ENV *, u_int32_t, char *, DB_FH **)); -static int __env_config __P((DB_ENV *, const char *, u_int32_t)); -static int __env_refresh __P((DB_ENV *, u_int32_t, int)); -static int __env_remove_int __P((DB_ENV *, const char *, u_int32_t)); - -/* - * db_version -- - * Return version information. - * - * EXTERN: char *db_version __P((int *, int *, int *)); - */ -char * -db_version(majverp, minverp, patchp) - int *majverp, *minverp, *patchp; -{ - if (majverp != NULL) - *majverp = DB_VERSION_MAJOR; - if (minverp != NULL) - *minverp = DB_VERSION_MINOR; - if (patchp != NULL) - *patchp = DB_VERSION_PATCH; - return ((char *)DB_VERSION_STRING); -} - -/* - * __env_open_pp -- - * DB_ENV->open pre/post processing. - * - * PUBLIC: int __env_open_pp __P((DB_ENV *, const char *, u_int32_t, int)); - */ -int -__env_open_pp(dbenv, db_home, flags, mode) - DB_ENV *dbenv; - const char *db_home; - u_int32_t flags; - int mode; -{ - DB_THREAD_INFO *ip; - u_int32_t orig_flags; - int need_recovery, ret, t_ret; - - need_recovery = 0; - -#undef OKFLAGS -#define OKFLAGS \ - (DB_CREATE | DB_INIT_CDB | DB_INIT_LOCK | DB_INIT_LOG | \ - DB_INIT_MPOOL | DB_INIT_REP | DB_INIT_TXN | DB_LOCKDOWN | \ - DB_PRIVATE | DB_RECOVER | DB_RECOVER_FATAL | DB_REGISTER | \ - DB_SYSTEM_MEM | DB_THREAD | DB_USE_ENVIRON | DB_USE_ENVIRON_ROOT) -#undef OKFLAGS_CDB -#define OKFLAGS_CDB \ - (DB_CREATE | DB_INIT_CDB | DB_INIT_MPOOL | DB_LOCKDOWN | \ - DB_PRIVATE | DB_SYSTEM_MEM | DB_THREAD | \ - DB_USE_ENVIRON | DB_USE_ENVIRON_ROOT) - - if ((ret = __db_fchk(dbenv, "DB_ENV->open", flags, OKFLAGS)) != 0) - return (ret); - if ((ret = __db_fcchk( - dbenv, "DB_ENV->open", flags, DB_INIT_CDB, ~OKFLAGS_CDB)) != 0) - return (ret); - if ((ret = __db_fcchk(dbenv, "DB_ENV->open", flags, - DB_PRIVATE, DB_REGISTER | DB_SYSTEM_MEM)) != 0) - return (ret); - if (LF_ISSET(DB_INIT_REP)) { - if (!LF_ISSET(DB_INIT_LOCK)) { - __db_err(dbenv, "replication requires locking support"); - return (EINVAL); - } - if (!LF_ISSET(DB_INIT_TXN)) { - __db_err( - dbenv, "replication requires transaction support"); - return (EINVAL); - } - } - if (LF_ISSET(DB_RECOVER | DB_RECOVER_FATAL)) { - if ((ret = __db_fcchk(dbenv, - "DB_ENV->open", flags, DB_RECOVER, DB_RECOVER_FATAL)) != 0) - return (ret); - if (!LF_ISSET(DB_CREATE)) { - __db_err(dbenv, "recovery requires the create flag"); - return (EINVAL); - } - if (!LF_ISSET(DB_INIT_TXN)) { - __db_err( - dbenv, "recovery requires transaction support"); - return (EINVAL); - } - } - - /* - * Currently we support one kind of mutex that is intra-process only, - * POSIX 1003.1 pthreads, because a variety of systems don't support - * the full pthreads API, and our only alternative is test-and-set. - */ -#ifdef HAVE_MUTEX_THREAD_ONLY - if (!LF_ISSET(DB_PRIVATE)) { - __db_err(dbenv, - "Berkeley DB library configured to support only private environments"); - return (EINVAL); - } -#endif - -#if defined(HAVE_MUTEX_FCNTL) - /* - * !!! - * We need a file descriptor for fcntl(2) locking. We use the file - * handle from the REGENV file for this purpose. - * - * Since we may be using shared memory regions, e.g., shmget(2), and - * not a mapped-in regular file, the backing file may be only a few - * bytes in length. So, this depends on the ability to call fcntl to - * lock file offsets much larger than the actual physical file. I - * think that's safe -- besides, very few systems actually need this - * kind of support, SunOS is the only one still in wide use of which - * I'm aware. - * - * The error case is if an application lacks spinlocks and wants to be - * threaded. That doesn't work because fcntl will lock the underlying - * process, including all its threads. - */ - if (F_ISSET(dbenv, DB_ENV_THREAD)) { - __db_err(dbenv, - "architecture lacks fast mutexes: applications cannot be threaded"); - return (EINVAL); - } -#endif - - if (LF_ISSET(DB_INIT_REP) && !__os_support_replication()) { - __db_err(dbenv, - "Berkeley DB library does not support replication on this system"); - return (EINVAL); - } - - /* - * If we're going to register with the environment, that's the first - * thing we do. - */ - if (LF_ISSET(DB_REGISTER)) { - if (!__os_support_db_register()) { - __db_err(dbenv, - "Berkeley DB library does not support DB_REGISTER on this system"); - return (EINVAL); - } - - if ((ret = - __envreg_register(dbenv, db_home, &need_recovery)) != 0) - return (ret); - if (need_recovery) { - if (!LF_ISSET(DB_RECOVER)) { - __db_err(dbenv, - "No recovery flag was specified, and recovery is needed"); - ret = DB_RUNRECOVERY; - goto err; - } - } else - LF_CLR(DB_RECOVER | DB_RECOVER_FATAL); - } - - /* - * If we're doing recovery, destroy the environment so that we create - * all the regions from scratch. The major concern I have is if the - * application stomps the environment with a rogue pointer. We have - * no way of detecting that, and we could be forced into a situation - * where we start up and then crash, repeatedly. - * - * Note that we do not check any flags like DB_PRIVATE before calling - * remove. We don't care if the current environment was private or - * not, we just want to nail any files that are left-over for whatever - * reason, from whatever session. - */ - if (LF_ISSET(DB_RECOVER | DB_RECOVER_FATAL)) { - orig_flags = dbenv->flags; - if ((ret = __env_remove_int(dbenv, db_home, DB_FORCE)) != 0 || - (ret = __env_refresh(dbenv, orig_flags, 0)) != 0) - goto err; - } - - ret = __env_open(dbenv, db_home, flags, mode); - if (ret == 0 && dbenv->thr_hashtab != NULL && - (t_ret = __env_set_state(dbenv, &ip, THREAD_OUT)) != 0) - ret = t_ret; - -err: if (need_recovery) { - /* - * If recovery succeeded, release our exclusive lock, other - * processes can now proceed. - * - * If recovery failed, unregister now. - */ - if (ret == 0 && (t_ret = __envreg_xunlock(dbenv)) != 0) - ret = t_ret; - if (ret != 0) - (void)__envreg_unregister(dbenv, 1); - } - - return (ret); -} - -/* - * __env_open -- - * DB_ENV->open. - * - * PUBLIC: int __env_open __P((DB_ENV *, const char *, u_int32_t, int)); - */ -int -__env_open(dbenv, db_home, flags, mode) - DB_ENV *dbenv; - const char *db_home; - u_int32_t flags; - int mode; -{ - DB_THREAD_INFO *ip; - REGINFO *infop; - u_int32_t init_flags, orig_flags; - int rep_check, ret; - - orig_flags = dbenv->flags; - rep_check = 0; - ip = NULL; - - /* Initialize the DB_ENV structure. */ - if ((ret = __env_config(dbenv, db_home, flags)) != 0) - goto err; - - /* Convert the DB_ENV->open flags to internal flags. */ - if (LF_ISSET(DB_CREATE)) - F_SET(dbenv, DB_ENV_CREATE); - if (LF_ISSET(DB_LOCKDOWN)) - F_SET(dbenv, DB_ENV_LOCKDOWN); - if (LF_ISSET(DB_PRIVATE)) - F_SET(dbenv, DB_ENV_PRIVATE); - if (LF_ISSET(DB_RECOVER_FATAL)) - F_SET(dbenv, DB_ENV_FATAL); - if (LF_ISSET(DB_SYSTEM_MEM)) - F_SET(dbenv, DB_ENV_SYSTEM_MEM); - if (LF_ISSET(DB_THREAD)) - F_SET(dbenv, DB_ENV_THREAD); - - /* Default permissions are read-write for both owner and group. */ - dbenv->db_mode = mode == 0 ? __db_omode("rw-rw----") : mode; - - /* - * Flags saved in the init_flags field of the environment, representing - * flags to DB_ENV->set_flags and DB_ENV->open that need to be set. - */ -#define DB_INITENV_CDB 0x0001 /* DB_INIT_CDB */ -#define DB_INITENV_CDB_ALLDB 0x0002 /* DB_INIT_CDB_ALLDB */ -#define DB_INITENV_LOCK 0x0004 /* DB_INIT_LOCK */ -#define DB_INITENV_LOG 0x0008 /* DB_INIT_LOG */ -#define DB_INITENV_MPOOL 0x0010 /* DB_INIT_MPOOL */ -#define DB_INITENV_REP 0x0020 /* DB_INIT_REP */ -#define DB_INITENV_TXN 0x0040 /* DB_INIT_TXN */ - - /* - * Create/join the environment. We pass in the flags of interest to - * a thread subsequently joining an environment we create. If we're - * not the ones to create the environment, our flags will be updated - * to match the existing environment. - */ - init_flags = 0; - if (LF_ISSET(DB_INIT_CDB)) - FLD_SET(init_flags, DB_INITENV_CDB); - if (LF_ISSET(DB_INIT_LOCK)) - FLD_SET(init_flags, DB_INITENV_LOCK); - if (LF_ISSET(DB_INIT_LOG)) - FLD_SET(init_flags, DB_INITENV_LOG); - if (LF_ISSET(DB_INIT_MPOOL)) - FLD_SET(init_flags, DB_INITENV_MPOOL); - if (LF_ISSET(DB_INIT_REP)) - FLD_SET(init_flags, DB_INITENV_REP); - if (LF_ISSET(DB_INIT_TXN)) - FLD_SET(init_flags, DB_INITENV_TXN); - if (F_ISSET(dbenv, DB_ENV_CDB_ALLDB)) - FLD_SET(init_flags, DB_INITENV_CDB_ALLDB); - if ((ret = __db_e_attach(dbenv, &init_flags)) != 0) - goto err; - - /* - * __db_e_attach will return the saved init_flags field, which contains - * the DB_INIT_* flags used when the environment was created. - * - * We may be joining an environment -- reset our flags to match the - * ones in the environment. - */ - if (FLD_ISSET(init_flags, DB_INITENV_CDB)) - LF_SET(DB_INIT_CDB); - if (FLD_ISSET(init_flags, DB_INITENV_LOCK)) - LF_SET(DB_INIT_LOCK); - if (FLD_ISSET(init_flags, DB_INITENV_LOG)) - LF_SET(DB_INIT_LOG); - if (FLD_ISSET(init_flags, DB_INITENV_MPOOL)) - LF_SET(DB_INIT_MPOOL); - if (FLD_ISSET(init_flags, DB_INITENV_REP)) - LF_SET(DB_INIT_REP); - if (FLD_ISSET(init_flags, DB_INITENV_TXN)) - LF_SET(DB_INIT_TXN); - if (FLD_ISSET(init_flags, DB_INITENV_CDB_ALLDB) && - (ret = __env_set_flags(dbenv, DB_CDB_ALLDB, 1)) != 0) - goto err; - - /* - * Save the flags matching the database environment: we've replaced - * the argument flags with the flags corresponding to the existing, - * underlying set of subsystems. - */ - dbenv->open_flags = flags; - - /* Initialize for CDB product. */ - if (LF_ISSET(DB_INIT_CDB)) { - LF_SET(DB_INIT_LOCK); - F_SET(dbenv, DB_ENV_CDB); - } - - /* - * The DB_ENV structure has been initialized. This has to be set - * before we start calling into the subsystems, some of them look - * for it. - */ - F_SET(dbenv, DB_ENV_OPEN_CALLED); - - /* - * Initialize the subsystems. - * - * Initialize the mutex regions first. There's no ordering requirement, - * but it's simpler to get this in place so we don't have to keep track - * of mutexes for later allocation, once the mutex region is created we - * can go ahead and do the allocation for real. - */ - if ((ret = __mutex_open(dbenv)) != 0) - goto err; - - /* __mutex_open creates the thread info region, enter it now. */ - ENV_ENTER(dbenv, ip); - - /* - * Initialize the replication area next, so that we can lock out this - * call if we're currently running recovery for replication. - */ - if (LF_ISSET(DB_INIT_REP) && (ret = __rep_open(dbenv)) != 0) - goto err; - - rep_check = IS_ENV_REPLICATED(dbenv) ? 1 : 0; - if (rep_check && (ret = __env_rep_enter(dbenv, 0)) != 0) - goto err; - - if (LF_ISSET(DB_INIT_MPOOL)) - if ((ret = __memp_open(dbenv)) != 0) - goto err; - /* - * Initialize the ciphering area prior to any running of recovery so - * that we can initialize the keys, etc. before recovery. - * - * !!! - * This must be after the mpool init, but before the log initialization - * because log_open may attempt to run log_recover during its open. - */ - if (LF_ISSET(DB_INIT_MPOOL | DB_INIT_LOG | DB_INIT_TXN) && - (ret = __crypto_region_init(dbenv)) != 0) - goto err; - - /* - * Transactions imply logging but do not imply locking. While almost - * all applications want both locking and logging, it would not be - * unreasonable for a single threaded process to want transactions for - * atomicity guarantees, but not necessarily need concurrency. - */ - if (LF_ISSET(DB_INIT_LOG | DB_INIT_TXN)) - if ((ret = __log_open(dbenv)) != 0) - goto err; - if (LF_ISSET(DB_INIT_LOCK)) - if ((ret = __lock_open(dbenv)) != 0) - goto err; - - if (LF_ISSET(DB_INIT_TXN)) { - if ((ret = __txn_open(dbenv)) != 0) - goto err; - - /* - * If the application is running with transactions, initialize - * the function tables. - */ - if ((ret = __bam_init_recover(dbenv, &dbenv->recover_dtab, - &dbenv->recover_dtab_size)) != 0) - goto err; - if ((ret = __crdel_init_recover(dbenv, &dbenv->recover_dtab, - &dbenv->recover_dtab_size)) != 0) - goto err; - if ((ret = __db_init_recover(dbenv, &dbenv->recover_dtab, - &dbenv->recover_dtab_size)) != 0) - goto err; - if ((ret = __dbreg_init_recover(dbenv, &dbenv->recover_dtab, - &dbenv->recover_dtab_size)) != 0) - goto err; - if ((ret = __fop_init_recover(dbenv, &dbenv->recover_dtab, - &dbenv->recover_dtab_size)) != 0) - goto err; - if ((ret = __ham_init_recover(dbenv, &dbenv->recover_dtab, - &dbenv->recover_dtab_size)) != 0) - goto err; - if ((ret = __qam_init_recover(dbenv, &dbenv->recover_dtab, - &dbenv->recover_dtab_size)) != 0) - goto err; - if ((ret = __txn_init_recover(dbenv, &dbenv->recover_dtab, - &dbenv->recover_dtab_size)) != 0) - goto err; - } - - /* - * Initialize the DB list, and its mutex as necessary. If the env - * handle isn't free-threaded we don't need a mutex because there - * will never be more than a single DB handle on the list. If the - * mpool wasn't initialized, then we can't ever open a DB handle. - * - * We also need to initialize the MT mutex as necessary, so do them - * both. - * - * !!! - * This must come after the __memp_open call above because if we are - * recording mutexes for system resources, we will do it in the mpool - * region for environments and db handles. So, the mpool region must - * already be initialized. - */ - LIST_INIT(&dbenv->dblist); - if (LF_ISSET(DB_INIT_MPOOL)) { - if ((ret = __mutex_alloc(dbenv, MTX_ENV_DBLIST, - DB_MUTEX_THREAD, &dbenv->mtx_dblist)) != 0) - goto err; - if ((ret = __mutex_alloc(dbenv, - MTX_TWISTER, DB_MUTEX_THREAD, &dbenv->mtx_mt)) != 0) - goto err; - - /* Register DB's pgin/pgout functions. */ - if ((ret = __memp_register( - dbenv, DB_FTYPE_SET, __db_pgin, __db_pgout)) != 0) - goto err; - } - - /* Perform recovery for any previous run. */ - if (LF_ISSET(DB_RECOVER | DB_RECOVER_FATAL) && - (ret = __db_apprec(dbenv, NULL, NULL, 1, - LF_ISSET(DB_RECOVER | DB_RECOVER_FATAL))) != 0) - goto err; - - /* - * If we've created the regions, are running with transactions, and did - * not just run recovery, we need to log the fact that the transaction - * IDs got reset. - * - * If we ran recovery, there may be prepared-but-not-yet-committed - * transactions that need to be resolved. Recovery resets the minimum - * transaction ID and logs the reset if that's appropriate, so we - * don't need to do anything here in the recover case. - */ - infop = dbenv->reginfo; - if (TXN_ON(dbenv) && - !F_ISSET(dbenv, DB_ENV_LOG_INMEMORY) && - F_ISSET(infop, REGION_CREATE) && - !LF_ISSET(DB_RECOVER | DB_RECOVER_FATAL) && - (ret = __txn_reset(dbenv)) != 0) - goto err; - - /* The database environment is ready for business. */ - if ((ret = __db_e_golive(dbenv)) != 0) - goto err; - - if (rep_check && (ret = __env_db_rep_exit(dbenv)) != 0) - goto err; - - ENV_LEAVE(dbenv, ip); - return (0); - -err: /* - * If we fail after creating the regions, panic and remove them. - * - * !!! - * No need to call __env_db_rep_exit, that work is done by the calls to - * __env_refresh. - */ - infop = dbenv->reginfo; - if (infop != NULL && F_ISSET(infop, REGION_CREATE)) { - ret = __db_panic(dbenv, ret); - - /* Refresh the DB_ENV so we can use it to call remove. */ - (void)__env_refresh(dbenv, orig_flags, rep_check); - (void)__env_remove_int(dbenv, db_home, DB_FORCE); - (void)__env_refresh(dbenv, orig_flags, 0); - } else - (void)__env_refresh(dbenv, orig_flags, rep_check); - - if (ip != NULL) - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __env_remove -- - * DB_ENV->remove. - * - * PUBLIC: int __env_remove __P((DB_ENV *, const char *, u_int32_t)); - */ -int -__env_remove(dbenv, db_home, flags) - DB_ENV *dbenv; - const char *db_home; - u_int32_t flags; -{ - int ret, t_ret; - -#undef OKFLAGS -#define OKFLAGS \ - (DB_FORCE | DB_USE_ENVIRON | DB_USE_ENVIRON_ROOT) - - /* Validate arguments. */ - if ((ret = __db_fchk(dbenv, "DB_ENV->remove", flags, OKFLAGS)) != 0) - return (ret); - - ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->remove"); - - ret = __env_remove_int(dbenv, db_home, flags); - - if ((t_ret = __env_close(dbenv, 0)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __env_remove_int -- - * Discard an environment, internal version. - */ -static int -__env_remove_int(dbenv, db_home, flags) - DB_ENV *dbenv; - const char *db_home; - u_int32_t flags; -{ - int ret; - - /* Initialize the DB_ENV structure. */ - if ((ret = __env_config(dbenv, db_home, flags)) != 0) - return (ret); - - /* The DB_ENV structure has been initialized. */ - F_SET(dbenv, DB_ENV_OPEN_CALLED); - - /* Remove the environment. */ - return (__db_e_remove(dbenv, flags)); -} - -/* - * __env_config -- - * Initialization of the DB_ENV structure, read the DB_CONFIG file. - */ -static int -__env_config(dbenv, db_home, flags) - DB_ENV *dbenv; - const char *db_home; - u_int32_t flags; -{ - FILE *fp; - int ret; - char *p, buf[256]; - - /* - * Set the database home. Do this before calling __db_appname, - * it uses the home directory. - */ - if ((ret = __db_home(dbenv, db_home, flags)) != 0) - return (ret); - - /* Parse the config file. */ - p = NULL; - if ((ret = - __db_appname(dbenv, DB_APP_NONE, "DB_CONFIG", 0, NULL, &p)) != 0) - return (ret); - if (p == NULL) - fp = NULL; - else { - fp = fopen(p, "r"); - __os_free(dbenv, p); - } - - if (fp != NULL) { - while (fgets(buf, sizeof(buf), fp) != NULL) { - if ((p = strchr(buf, '\n')) != NULL) - *p = '\0'; - else if (strlen(buf) + 1 == sizeof(buf)) { - __db_err(dbenv, "DB_CONFIG: line too long"); - (void)fclose(fp); - return (EINVAL); - } - if (buf[0] == '\0' || - buf[0] == '#' || isspace((int)buf[0])) - continue; - - if ((ret = __db_parse(dbenv, buf)) != 0) { - (void)fclose(fp); - return (ret); - } - } - (void)fclose(fp); - } - - /* - * If no temporary directory path was specified in the config file, - * choose one. - */ - if (dbenv->db_tmp_dir == NULL && (ret = __os_tmpdir(dbenv, flags)) != 0) - return (ret); - - return (0); -} - -/* - * __env_close_pp -- - * DB_ENV->close pre/post processor. - * - * PUBLIC: int __env_close_pp __P((DB_ENV *, u_int32_t)); - */ -int -__env_close_pp(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - DB_THREAD_INFO *ip; - int rep_check, ret, t_ret; - - ret = 0; - - PANIC_CHECK(dbenv); - - ENV_ENTER(dbenv, ip); - /* - * Validate arguments, but as a DB_ENV handle destructor, we can't - * fail. - */ - if (flags != 0 && - (t_ret = __db_ferr(dbenv, "DB_ENV->close", 0)) != 0 && ret == 0) - ret = t_ret; - - rep_check = IS_ENV_REPLICATED(dbenv) ? 1 : 0; - if (rep_check && (t_ret = __env_rep_enter(dbenv, 0)) != 0 && ret == 0) - ret = t_ret; - - if ((t_ret = __env_close(dbenv, rep_check)) != 0 && ret == 0) - ret = t_ret; - - /* Don't ENV_LEAVE as we have already detached from the region. */ - return (ret); -} - -/* - * __env_close -- - * DB_ENV->close. - * - * PUBLIC: int __env_close __P((DB_ENV *, int)); - */ -int -__env_close(dbenv, rep_check) - DB_ENV *dbenv; - int rep_check; -{ - int ret, t_ret; - char **p; - - ret = 0; - - /* - * Before checking the reference count, we have to see if we were in - * the middle of restoring transactions and need to close the open - * files. - */ - if (TXN_ON(dbenv) && (t_ret = __txn_preclose(dbenv)) != 0 && ret == 0) - ret = t_ret; - - if (REP_ON(dbenv) && - (t_ret = __rep_preclose(dbenv)) != 0 && ret == 0) - ret = t_ret; - - /* - * Detach from the regions and undo the allocations done by - * DB_ENV->open. - */ - if ((t_ret = __env_refresh(dbenv, 0, rep_check)) != 0 && ret == 0) - ret = t_ret; - - /* Do per-subsystem close. */ - if ((t_ret = __lock_dbenv_close(dbenv)) != 0 && ret == 0) - ret = t_ret; - - if ((t_ret = __rep_dbenv_close(dbenv)) != 0 && ret == 0) - ret = t_ret; - -#ifdef HAVE_CRYPTO - /* - * Crypto comes last, because higher level close functions need - * cryptography. - */ - if ((t_ret = __crypto_dbenv_close(dbenv)) != 0 && ret == 0) - ret = t_ret; -#endif - - /* Release any string-based configuration parameters we've copied. */ - if (dbenv->db_log_dir != NULL) - __os_free(dbenv, dbenv->db_log_dir); - if (dbenv->db_tmp_dir != NULL) - __os_free(dbenv, dbenv->db_tmp_dir); - if (dbenv->db_data_dir != NULL) { - for (p = dbenv->db_data_dir; *p != NULL; ++p) - __os_free(dbenv, *p); - __os_free(dbenv, dbenv->db_data_dir); - } - - /* If we're registered, clean up. */ - if (dbenv->registry != NULL) { - (void)__envreg_unregister(dbenv, 0); - dbenv->registry = NULL; - } - - /* Discard the structure. */ - memset(dbenv, CLEAR_BYTE, sizeof(DB_ENV)); - __os_free(NULL, dbenv); - - return (ret); -} - -/* - * __env_refresh -- - * Refresh the DB_ENV structure, releasing resources allocated by - * DB_ENV->open, and returning it to the state it was in just before - * open was called. (Note that this means that any state set by - * pre-open configuration functions must be preserved.) - */ -static int -__env_refresh(dbenv, orig_flags, rep_check) - DB_ENV *dbenv; - u_int32_t orig_flags; - int rep_check; -{ - DB *ldbp; - DB_THREAD_INFO *ip; - int ret, t_ret; - - ret = 0; - - /* - * Refresh subsystems, in the reverse order they were opened (txn - * must be first, it may want to discard locks and flush the log). - * - * !!! - * Note that these functions, like all of __env_refresh, only undo - * the effects of __env_open. Functions that undo work done by - * db_env_create or by a configuration function should go in - * __env_close. - */ - if (TXN_ON(dbenv) && - (t_ret = __txn_dbenv_refresh(dbenv)) != 0 && ret == 0) - ret = t_ret; - - if (LOGGING_ON(dbenv) && - (t_ret = __log_dbenv_refresh(dbenv)) != 0 && ret == 0) - ret = t_ret; - - /* - * Locking should come after logging, because closing log results - * in files closing which may require locks being released. - */ - if (LOCKING_ON(dbenv)) { - if (!F_ISSET(dbenv, DB_ENV_THREAD) && - dbenv->env_lref != NULL && (t_ret = __lock_id_free(dbenv, - ((DB_LOCKER *)dbenv->env_lref)->id)) != 0 && ret == 0) - ret = t_ret; - dbenv->env_lref = NULL; - - if ((t_ret = __lock_dbenv_refresh(dbenv)) != 0 && ret == 0) - ret = t_ret; - } - - /* - * Discard DB list and its mutex. - * Discard the MT mutex. - * - * !!! - * This must be done before we close the mpool region because we - * may have allocated the DB handle mutex in the mpool region. - * It must be done *after* we close the log region, though, because - * we close databases and try to acquire the mutex when we close - * log file handles. Ick. - */ - if (dbenv->db_ref != 0) { - __db_err(dbenv, - "Database handles still open at environment close"); - for (ldbp = LIST_FIRST(&dbenv->dblist); - ldbp != NULL; ldbp = LIST_NEXT(ldbp, dblistlinks)) - __db_err(dbenv, "Open database handle: %s%s%s", - ldbp->fname == NULL ? "unnamed" : ldbp->fname, - ldbp->dname == NULL ? "" : "/", - ldbp->dname == NULL ? "" : ldbp->dname); - if (ret == 0) - ret = EINVAL; - } - LIST_INIT(&dbenv->dblist); - - if ((t_ret = __mutex_free(dbenv, &dbenv->mtx_dblist)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = __mutex_free(dbenv, &dbenv->mtx_mt)) != 0 && ret == 0) - ret = t_ret; - - if (dbenv->mt != NULL) { - __os_free(dbenv, dbenv->mt); - dbenv->mt = NULL; - } - - if (MPOOL_ON(dbenv)) { - /* - * If it's a private environment, flush the contents to disk. - * Recovery would have put everything back together, but it's - * faster and cleaner to flush instead. - */ - if (F_ISSET(dbenv, DB_ENV_PRIVATE) && - (t_ret = __memp_sync(dbenv, NULL)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = __memp_dbenv_refresh(dbenv)) != 0 && ret == 0) - ret = t_ret; - } - - /* - * If we're included in a shared replication handle count, this - * is our last chance to decrement that count. - * - * !!! - * We can't afford to do anything dangerous after we decrement the - * handle count, of course, as replication may be proceeding with - * client recovery. However, since we're discarding the regions - * as soon as we drop the handle count, there's little opportunity - * to do harm. - */ - if (rep_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - - /* - * Detach from the region. - * - * Must come after we call __env_db_rep_exit above. - */ - __rep_dbenv_refresh(dbenv); - - /* - * Mark the thread as out of the env before we get rid - * of the handles needed to do so. - */ - if (dbenv->thr_hashtab != NULL && - (t_ret = __env_set_state(dbenv, &ip, THREAD_OUT)) != 0 && ret == 0) - ret = t_ret; - - if (MUTEX_ON(dbenv) && - (t_ret = __mutex_dbenv_refresh(dbenv)) != 0 && ret == 0) - ret = t_ret; - - if (dbenv->reginfo != NULL) { - if ((t_ret = __db_e_detach(dbenv, 0)) != 0 && ret == 0) - ret = t_ret; - /* - * !!! - * Don't free dbenv->reginfo or set the reference to NULL, - * that was done by __db_e_detach(). - */ - } - - /* Undo changes and allocations done by __env_open. */ - if (dbenv->db_home != NULL) { - __os_free(dbenv, dbenv->db_home); - dbenv->db_home = NULL; - } - if (dbenv->db_abshome != NULL) { - __os_free(dbenv, dbenv->db_abshome); - dbenv->db_abshome = NULL; - } - if (dbenv->mutex_iq != NULL) { - __os_free(dbenv, dbenv->mutex_iq); - dbenv->mutex_iq = NULL; - } - - dbenv->open_flags = 0; - dbenv->db_mode = 0; - - if (dbenv->recover_dtab != NULL) { - __os_free(dbenv, dbenv->recover_dtab); - dbenv->recover_dtab = NULL; - dbenv->recover_dtab_size = 0; - } - - dbenv->flags = orig_flags; - - return (ret); -} - -#define DB_ADDSTR(add) { \ - /* \ - * The string might be NULL or zero-length, and the p[-1] \ - * might indirect to before the beginning of our buffer. \ - */ \ - if ((add) != NULL && (add)[0] != '\0') { \ - /* If leading slash, start over. */ \ - if (__os_abspath(add)) { \ - p = str; \ - slash = 0; \ - } \ - /* Append to the current string. */ \ - len = strlen(add); \ - if (slash) \ - *p++ = PATH_SEPARATOR[0]; \ - memcpy(p, add, len); \ - p += len; \ - slash = strchr(PATH_SEPARATOR, p[-1]) == NULL; \ - } \ -} - -/* - * __env_get_open_flags - * Retrieve the flags passed to DB_ENV->open. - * - * PUBLIC: int __env_get_open_flags __P((DB_ENV *, u_int32_t *)); - */ -int -__env_get_open_flags(dbenv, flagsp) - DB_ENV *dbenv; - u_int32_t *flagsp; -{ - ENV_ILLEGAL_BEFORE_OPEN(dbenv, "DB_ENV->get_open_flags"); - - *flagsp = dbenv->open_flags; - return (0); -} - -/* - * __db_appname -- - * Given an optional DB environment, directory and file name and type - * of call, build a path based on the DB_ENV->open rules, and return - * it in allocated space. - * - * PUBLIC: int __db_appname __P((DB_ENV *, APPNAME, - * PUBLIC: const char *, u_int32_t, DB_FH **, char **)); - */ -int -__db_appname(dbenv, appname, file, tmp_oflags, fhpp, namep) - DB_ENV *dbenv; - APPNAME appname; - const char *file; - u_int32_t tmp_oflags; - DB_FH **fhpp; - char **namep; -{ - size_t len, str_len; - int data_entry, ret, slash, tmp_create; - const char *a, *b; - char *p, *str; - - a = b = NULL; - data_entry = -1; - tmp_create = 0; - - /* - * We don't return a name when creating temporary files, just a file - * handle. Default to an error now. - */ - if (fhpp != NULL) - *fhpp = NULL; - if (namep != NULL) - *namep = NULL; - - /* - * Absolute path names are never modified. If the file is an absolute - * path, we're done. - */ - if (file != NULL && __os_abspath(file)) - return (__os_strdup(dbenv, file, namep)); - - /* Everything else is relative to the environment home. */ - if (dbenv != NULL) - a = dbenv->db_home; - -retry: /* - * DB_APP_NONE: - * DB_HOME/file - * DB_APP_DATA: - * DB_HOME/DB_DATA_DIR/file - * DB_APP_LOG: - * DB_HOME/DB_LOG_DIR/file - * DB_APP_TMP: - * DB_HOME/DB_TMP_DIR/<create> - */ - switch (appname) { - case DB_APP_NONE: - break; - case DB_APP_DATA: - if (dbenv != NULL && dbenv->db_data_dir != NULL && - (b = dbenv->db_data_dir[++data_entry]) == NULL) { - data_entry = -1; - b = dbenv->db_data_dir[0]; - } - break; - case DB_APP_LOG: - if (dbenv != NULL) - b = dbenv->db_log_dir; - break; - case DB_APP_TMP: - if (dbenv != NULL) - b = dbenv->db_tmp_dir; - tmp_create = 1; - break; - } - - len = - (a == NULL ? 0 : strlen(a) + 1) + - (b == NULL ? 0 : strlen(b) + 1) + - (file == NULL ? 0 : strlen(file) + 1); - - /* - * Allocate space to hold the current path information, as well as any - * temporary space that we're going to need to create a temporary file - * name. - */ -#define DB_TRAIL "BDBXXXXX" - str_len = len + sizeof(DB_TRAIL) + 10; - if ((ret = __os_malloc(dbenv, str_len, &str)) != 0) - return (ret); - - slash = 0; - p = str; - DB_ADDSTR(a); - DB_ADDSTR(b); - DB_ADDSTR(file); - *p = '\0'; - - /* - * If we're opening a data file, see if it exists. If it does, - * return it, otherwise, try and find another one to open. - */ - if (__os_exists(str, NULL) != 0 && data_entry != -1) { - __os_free(dbenv, str); - b = NULL; - goto retry; - } - - /* Create the file if so requested. */ - if (tmp_create && - (ret = __db_tmp_open(dbenv, tmp_oflags, str, fhpp)) != 0) { - __os_free(dbenv, str); - return (ret); - } - - if (namep == NULL) - __os_free(dbenv, str); - else - *namep = str; - return (0); -} - -/* - * __db_home -- - * Find the database home. - * - * PUBLIC: int __db_home __P((DB_ENV *, const char *, u_int32_t)); - */ -int -__db_home(dbenv, db_home, flags) - DB_ENV *dbenv; - const char *db_home; - u_int32_t flags; -{ - int ret; - const char *p; - char path[MAXPATHLEN]; - - /* - * Use db_home by default, this allows utilities to reasonably - * override the environment either explicitly or by using a -h - * option. Otherwise, use the environment if it's permitted - * and initialized. - */ - if ((p = db_home) == NULL && - (LF_ISSET(DB_USE_ENVIRON) || - (LF_ISSET(DB_USE_ENVIRON_ROOT) && __os_isroot())) && - (p = getenv("DB_HOME")) != NULL && p[0] == '\0') { - __db_err(dbenv, "illegal DB_HOME environment variable"); - return (EINVAL); - } - if (p != NULL && (ret = __os_strdup(dbenv, p, &dbenv->db_home)) != 0) - return (ret); - - /* - * Get the absolute pathname of the current directory. We use this - * to build absolute pathnames when removing log files. - * - * XXX - * Can't trust getcwd(3) to set a valid errno, so don't try to display - * one unless we know it's good. It's likely a permissions problem: - * use something bland and useless in the default return value, so we - * don't send somebody off in the wrong direction. - */ - __os_set_errno(0); - if ((p = getcwd(path, sizeof(path))) == NULL) { - if ((ret = __os_get_errno()) == 0) { - __db_err(dbenv, - "no absolute path for the current directory"); - ret = EAGAIN; - } else - __db_err(dbenv, - "no absolute path for the current directory: %s", - db_strerror(ret)); - return (ret); - } - if (p != NULL && (ret = __os_strdup(dbenv, p, &dbenv->db_abshome)) != 0) - return (ret); - - return (0); -} - -#define __DB_OVFL(v, max) \ - if (v > max) { \ - __v = v; \ - __max = max; \ - goto toobig; \ - } - -/* - * __db_parse -- - * Parse a single NAME VALUE pair. - */ -static int -__db_parse(dbenv, s) - DB_ENV *dbenv; - char *s; -{ - u_long __max, __v, v1, v2, v3; - u_int32_t flags; - char *name, *p, *value, v4; - - /* - * !!! - * The constant 40 is hard-coded into format arguments to sscanf - * below, it can't be changed here without changing it there, too. - * The additional bytes are for a trailing nul byte and because we - * are reading user input -- I don't want to risk any off-by-ones. - */ - char arg[40 + 5]; - - /* - * Name/value pairs are parsed as two white-space separated strings. - * Leading and trailing white-space is trimmed from the value, but - * it may contain embedded white-space. Note: we use the isspace(3) - * macro because it's more portable, but that means that you can use - * characters like form-feed to separate the strings. - */ - name = s; - for (p = name; *p != '\0' && !isspace((int)*p); ++p) - ; - if (*p == '\0' || p == name) - goto illegal; - *p = '\0'; - for (++p; isspace((int)*p); ++p) - ; - if (*p == '\0') - goto illegal; - value = p; - for (++p; *p != '\0'; ++p) - ; - for (--p; isspace((int)*p); --p) - ; - ++p; - if (p == value) { -illegal: __db_err(dbenv, "mis-formatted name-value pair: %s", s); - return (EINVAL); - } - *p = '\0'; - - if (strcasecmp(name, "mutex_set_align") == 0) { - if (sscanf(value, "%lu %c", &v1, &v4) != 1) - goto badarg; - __DB_OVFL(v1, UINT32_MAX); - return (__mutex_set_align(dbenv, (u_int32_t)v1)); - } - - if (strcasecmp(name, "mutex_set_increment") == 0) { - if (sscanf(value, "%lu %c", &v1, &v4) != 1) - goto badarg; - __DB_OVFL(v1, UINT32_MAX); - return (__mutex_set_increment(dbenv, (u_int32_t)v1)); - } - - if (strcasecmp(name, "mutex_set_max") == 0) { - if (sscanf(value, "%lu %c", &v1, &v4) != 1) - goto badarg; - __DB_OVFL(v1, UINT32_MAX); - return (__mutex_set_max(dbenv, (u_int32_t)v1)); - } - - if (strcasecmp(name, "mutex_set_tas_spins") == 0) { - if (sscanf(value, "%lu %c", &v1, &v4) != 1) - goto badarg; - __DB_OVFL(v1, UINT32_MAX); - return (__mutex_set_tas_spins(dbenv, (u_int32_t)v1)); - } - - if (strcasecmp(name, "rep_set_config") == 0) { - if (sscanf(value, "%40s %c", arg, &v4) != 1) - goto badarg; - - if (strcasecmp(value, "rep_bulk") == 0) - return (__rep_set_config(dbenv, - DB_REP_CONF_BULK, 1)); - if (strcasecmp(value, "rep_delayclient") == 0) - return (__rep_set_config(dbenv, - DB_REP_CONF_DELAYCLIENT, 1)); - if (strcasecmp(value, "rep_noautoinit") == 0) - return (__rep_set_config(dbenv, - DB_REP_CONF_NOAUTOINIT, 1)); - if (strcasecmp(value, "rep_nowait") == 0) - return (__rep_set_config(dbenv, DB_REP_CONF_NOWAIT, 1)); - goto badarg; - } - - if (strcasecmp(name, "set_cachesize") == 0) { - if (sscanf(value, "%lu %lu %lu %c", &v1, &v2, &v3, &v4) != 3) - goto badarg; - __DB_OVFL(v1, UINT32_MAX); - __DB_OVFL(v2, UINT32_MAX); - __DB_OVFL(v3, 10000); - return (__memp_set_cachesize( - dbenv, (u_int32_t)v1, (u_int32_t)v2, (int)v3)); - } - - if (strcasecmp(name, "set_data_dir") == 0 || - strcasecmp(name, "db_data_dir") == 0) /* Compatibility. */ - return (__env_set_data_dir(dbenv, value)); - - /* Undocumented. */ - if (strcasecmp(name, "set_intermediate_dir") == 0) { - if (sscanf(value, "%lu %c", &v1, &v4) != 1) - goto badarg; -#ifdef INT_MAX - __DB_OVFL(v1, INT_MAX); -#endif - return (__env_set_intermediate_dir(dbenv, (int)v1, 0)); - } - - if (strcasecmp(name, "set_flags") == 0) { - if (sscanf(value, "%40s %c", arg, &v4) != 1) - goto badarg; - - if (strcasecmp(value, "db_auto_commit") == 0) - return (__env_set_flags(dbenv, DB_AUTO_COMMIT, 1)); - if (strcasecmp(value, "db_cdb_alldb") == 0) - return (__env_set_flags(dbenv, DB_CDB_ALLDB, 1)); - if (strcasecmp(value, "db_direct_db") == 0) - return (__env_set_flags(dbenv, DB_DIRECT_DB, 1)); - if (strcasecmp(value, "db_direct_log") == 0) - return (__env_set_flags(dbenv, DB_DIRECT_LOG, 1)); - if (strcasecmp(value, "db_dsync_db") == 0) - return (__env_set_flags(dbenv, DB_DSYNC_DB, 1)); - if (strcasecmp(value, "db_dsync_log") == 0) - return (__env_set_flags(dbenv, DB_DSYNC_LOG, 1)); - if (strcasecmp(value, "db_log_autoremove") == 0) - return (__env_set_flags(dbenv, DB_LOG_AUTOREMOVE, 1)); - if (strcasecmp(value, "db_log_inmemory") == 0) - return (__env_set_flags(dbenv, DB_LOG_INMEMORY, 1)); - if (strcasecmp(value, "db_nolocking") == 0) - return (__env_set_flags(dbenv, DB_NOLOCKING, 1)); - if (strcasecmp(value, "db_nommap") == 0) - return (__env_set_flags(dbenv, DB_NOMMAP, 1)); - if (strcasecmp(value, "db_nopanic") == 0) - return (__env_set_flags(dbenv, DB_NOPANIC, 1)); - if (strcasecmp(value, "db_overwrite") == 0) - return (__env_set_flags(dbenv, DB_OVERWRITE, 1)); - if (strcasecmp(value, "db_region_init") == 0) - return (__env_set_flags(dbenv, DB_REGION_INIT, 1)); - if (strcasecmp(value, "db_txn_nosync") == 0) - return (__env_set_flags(dbenv, DB_TXN_NOSYNC, 1)); - if (strcasecmp(value, "db_txn_write_nosync") == 0) - return ( - __env_set_flags(dbenv, DB_TXN_WRITE_NOSYNC, 1)); - if (strcasecmp(value, "db_yieldcpu") == 0) - return (__env_set_flags(dbenv, DB_YIELDCPU, 1)); - goto badarg; - } - - if (strcasecmp(name, "set_lg_bsize") == 0) { - if (sscanf(value, "%lu %c", &v1, &v4) != 1) - goto badarg; - __DB_OVFL(v1, UINT32_MAX); - return (__log_set_lg_bsize(dbenv, (u_int32_t)v1)); - } - - if (strcasecmp(name, "set_lg_filemode") == 0) { - if (sscanf(value, "%lu %c", &v1, &v4) != 1) - goto badarg; - __DB_OVFL(v1, INT_MAX); - return (__log_set_lg_filemode(dbenv, (int)v1)); - } - - if (strcasecmp(name, "set_lg_max") == 0) { - if (sscanf(value, "%lu %c", &v1, &v4) != 1) - goto badarg; - __DB_OVFL(v1, UINT32_MAX); - return (__log_set_lg_max(dbenv, (u_int32_t)v1)); - } - - if (strcasecmp(name, "set_lg_regionmax") == 0) { - if (sscanf(value, "%lu %c", &v1, &v4) != 1) - goto badarg; - __DB_OVFL(v1, UINT32_MAX); - return (__log_set_lg_regionmax(dbenv, (u_int32_t)v1)); - } - - if (strcasecmp(name, "set_lg_dir") == 0 || - strcasecmp(name, "db_log_dir") == 0) /* Compatibility. */ - return (__log_set_lg_dir(dbenv, value)); - - if (strcasecmp(name, "set_lk_detect") == 0) { - if (sscanf(value, "%40s %c", arg, &v4) != 1) - goto badarg; - if (strcasecmp(value, "db_lock_default") == 0) - flags = DB_LOCK_DEFAULT; - else if (strcasecmp(value, "db_lock_expire") == 0) - flags = DB_LOCK_EXPIRE; - else if (strcasecmp(value, "db_lock_maxlocks") == 0) - flags = DB_LOCK_MAXLOCKS; - else if (strcasecmp(value, "db_lock_maxwrite") == 0) - flags = DB_LOCK_MAXWRITE; - else if (strcasecmp(value, "db_lock_minlocks") == 0) - flags = DB_LOCK_MINLOCKS; - else if (strcasecmp(value, "db_lock_minwrite") == 0) - flags = DB_LOCK_MINWRITE; - else if (strcasecmp(value, "db_lock_oldest") == 0) - flags = DB_LOCK_OLDEST; - else if (strcasecmp(value, "db_lock_random") == 0) - flags = DB_LOCK_RANDOM; - else if (strcasecmp(value, "db_lock_youngest") == 0) - flags = DB_LOCK_YOUNGEST; - else - goto badarg; - return (__lock_set_lk_detect(dbenv, flags)); - } - - if (strcasecmp(name, "set_lk_max") == 0) { - if (sscanf(value, "%lu %c", &v1, &v4) != 1) - goto badarg; - __DB_OVFL(v1, UINT32_MAX); - return (__lock_set_lk_max(dbenv, (u_int32_t)v1)); - } - - if (strcasecmp(name, "set_lk_max_locks") == 0) { - if (sscanf(value, "%lu %c", &v1, &v4) != 1) - goto badarg; - __DB_OVFL(v1, UINT32_MAX); - return (__lock_set_lk_max_locks(dbenv, (u_int32_t)v1)); - } - - if (strcasecmp(name, "set_lk_max_lockers") == 0) { - if (sscanf(value, "%lu %c", &v1, &v4) != 1) - goto badarg; - __DB_OVFL(v1, UINT32_MAX); - return (__lock_set_lk_max_lockers(dbenv, (u_int32_t)v1)); - } - - if (strcasecmp(name, "set_lk_max_objects") == 0) { - if (sscanf(value, "%lu %c", &v1, &v4) != 1) - goto badarg; - __DB_OVFL(v1, UINT32_MAX); - return (__lock_set_lk_max_objects(dbenv, (u_int32_t)v1)); - } - - if (strcasecmp(name, "set_lock_timeout") == 0) { - if (sscanf(value, "%lu %c", &v1, &v4) != 1) - goto badarg; - __DB_OVFL(v1, UINT32_MAX); - return (__lock_set_env_timeout( - dbenv, (u_int32_t)v1, DB_SET_LOCK_TIMEOUT)); - } - - if (strcasecmp(name, "set_mp_max_openfd") == 0) { - if (sscanf(value, "%lu %c", &v1, &v4) != 1) - goto badarg; - __DB_OVFL(v1, INT_MAX); - return (__memp_set_mp_max_openfd(dbenv, (int)v1)); - } - - if (strcasecmp(name, "set_mp_max_write") == 0) { - if (sscanf(value, "%lu %lu %c", &v1, &v2, &v4) != 2) - goto badarg; - __DB_OVFL(v1, INT_MAX); - __DB_OVFL(v2, INT_MAX); - return (__memp_set_mp_max_write(dbenv, (int)v1, (int)v2)); - } - - if (strcasecmp(name, "set_mp_mmapsize") == 0) { - if (sscanf(value, "%lu %c", &v1, &v4) != 1) - goto badarg; - __DB_OVFL(v1, UINT32_MAX); - return (__memp_set_mp_mmapsize(dbenv, (u_int32_t)v1)); - } - - if (strcasecmp(name, "set_region_init") == 0) { - if (sscanf(value, "%lu %c", &v1, &v4) != 1 || v1 != 1) - goto badarg; - return (__env_set_flags( - dbenv, DB_REGION_INIT, v1 == 0 ? 0 : 1)); - } - - if (strcasecmp(name, "set_shm_key") == 0) { - if (sscanf(value, "%lu %c", &v1, &v4) != 1) - goto badarg; - return (__env_set_shm_key(dbenv, (long)v1)); - } - - /* - * The set_tas_spins method has been replaced by mutex_set_tas_spins. - * The set_tas_spins name remains for DB_CONFIG compatibility. - */ - if (strcasecmp(name, "set_tas_spins") == 0) { - if (sscanf(value, "%lu %c", &v1, &v4) != 1) - goto badarg; - __DB_OVFL(v1, UINT32_MAX); - return (__mutex_set_tas_spins(dbenv, (u_int32_t)v1)); - } - - if (strcasecmp(name, "set_tmp_dir") == 0 || - strcasecmp(name, "db_tmp_dir") == 0) /* Compatibility.*/ - return (__env_set_tmp_dir(dbenv, value)); - - if (strcasecmp(name, "set_tx_max") == 0) { - if (sscanf(value, "%lu %c", &v1, &v4) != 1) - goto badarg; - __DB_OVFL(v1, UINT32_MAX); - return (__txn_set_tx_max(dbenv, (u_int32_t)v1)); - } - - if (strcasecmp(name, "set_txn_timeout") == 0) { - if (sscanf(value, "%lu %c", &v1, &v4) != 1) - goto badarg; - __DB_OVFL(v1, UINT32_MAX); - return (__lock_set_env_timeout( - dbenv, (u_int32_t)v1, DB_SET_TXN_TIMEOUT)); - } - - if (strcasecmp(name, "set_verbose") == 0) { - if (sscanf(value, "%40s %c", arg, &v4) != 1) - goto badarg; - - else if (strcasecmp(value, "db_verb_deadlock") == 0) - flags = DB_VERB_DEADLOCK; - else if (strcasecmp(value, "db_verb_recovery") == 0) - flags = DB_VERB_RECOVERY; - else if (strcasecmp(value, "db_verb_register") == 0) - flags = DB_VERB_REGISTER; - else if (strcasecmp(value, "db_verb_replication") == 0) - flags = DB_VERB_REPLICATION; - else if (strcasecmp(value, "db_verb_waitsfor") == 0) - flags = DB_VERB_WAITSFOR; - else - goto badarg; - return (__env_set_verbose(dbenv, flags, 1)); - } - - __db_err(dbenv, "unrecognized name-value pair: %s", s); - return (EINVAL); - -badarg: __db_err(dbenv, "incorrect arguments for name-value pair: %s", s); - return (EINVAL); - -toobig: __db_err(dbenv, - "%s: %lu larger than maximum value %lu", s, __v, __max); - return (EINVAL); -} - -/* - * __db_tmp_open -- - * Create a temporary file. - */ -static int -__db_tmp_open(dbenv, tmp_oflags, path, fhpp) - DB_ENV *dbenv; - u_int32_t tmp_oflags; - char *path; - DB_FH **fhpp; -{ - pid_t pid; - db_threadid_t tid; - int filenum, i, isdir, ret; - char *firstx, *trv; - - /* - * Check the target directory; if you have six X's and it doesn't - * exist, this runs for a *very* long time. - */ - if ((ret = __os_exists(path, &isdir)) != 0) { - __db_err(dbenv, "%s: %s", path, db_strerror(ret)); - return (ret); - } - if (!isdir) { - __db_err(dbenv, "%s: %s", path, db_strerror(EINVAL)); - return (EINVAL); - } - - /* Build the path. */ - (void)strncat(path, PATH_SEPARATOR, 1); - (void)strcat(path, DB_TRAIL); - - /* Replace the X's with the process ID (in decimal). */ - __os_id(dbenv, &pid, &tid); - for (trv = path + strlen(path); *--trv == 'X'; pid /= 10) - *trv = '0' + (u_char)(pid % 10); - firstx = trv + 1; - - /* Loop, trying to open a file. */ - for (filenum = 1;; filenum++) { - if ((ret = __os_open(dbenv, path, - tmp_oflags | DB_OSO_CREATE | DB_OSO_EXCL | DB_OSO_TEMP, - __db_omode(OWNER_RW), fhpp)) == 0) - return (0); - - /* - * !!!: - * If we don't get an EEXIST error, then there's something - * seriously wrong. Unfortunately, if the implementation - * doesn't return EEXIST for O_CREAT and O_EXCL regardless - * of other possible errors, we've lost. - */ - if (ret != EEXIST) { - __db_err(dbenv, - "tmp_open: %s: %s", path, db_strerror(ret)); - return (ret); - } - - /* - * Generate temporary file names in a backwards-compatible way. - * If pid == 12345, the result is: - * <path>/DB12345 (tried above, the first time through). - * <path>/DBa2345 ... <path>/DBz2345 - * <path>/DBaa345 ... <path>/DBaz345 - * <path>/DBba345, and so on. - * - * XXX - * This algorithm is O(n**2) -- that is, creating 100 temporary - * files requires 5,000 opens, creating 1000 files requires - * 500,000. If applications open a lot of temporary files, we - * could improve performance by switching to timestamp-based - * file names. - */ - for (i = filenum, trv = firstx; i > 0; i = (i - 1) / 26) - if (*trv++ == '\0') - return (EINVAL); - - for (i = filenum; i > 0; i = (i - 1) / 26) - *--trv = 'a' + ((i - 1) % 26); - } - /* NOTREACHED */ -} diff --git a/storage/bdb/env/env_recover.c b/storage/bdb/env/env_recover.c deleted file mode 100644 index 7e7ebe9fec9..00000000000 --- a/storage/bdb/env/env_recover.c +++ /dev/null @@ -1,869 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: env_recover.c,v 12.10 2005/10/19 15:14:11 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef lint -static const char copyright[] = - "Copyright (c) 1996-2005\nSleepycat Software Inc. All rights reserved.\n"; -#endif - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#if TIME_WITH_SYS_TIME -#include <sys/time.h> -#include <time.h> -#else -#if HAVE_SYS_TIME_H -#include <sys/time.h> -#else -#include <time.h> -#endif -#endif - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/log.h" -#include "dbinc/txn.h" -#include "dbinc/mp.h" -#include "dbinc/db_am.h" - -static int __db_log_corrupt __P((DB_ENV *, DB_LSN *)); -static int __log_earliest __P((DB_ENV *, DB_LOGC *, int32_t *, DB_LSN *)); -static double __lsn_diff __P((DB_LSN *, DB_LSN *, DB_LSN *, u_int32_t, int)); - -/* - * __db_apprec -- - * Perform recovery. If max_lsn is non-NULL, then we are trying - * to synchronize this system up with another system that has a max - * LSN of max_lsn, so we need to roll back sufficiently far for that - * to work. See __log_backup for details. - * - * PUBLIC: int __db_apprec __P((DB_ENV *, DB_LSN *, DB_LSN *, int, u_int32_t)); - */ -int -__db_apprec(dbenv, max_lsn, trunclsn, update, flags) - DB_ENV *dbenv; - DB_LSN *max_lsn, *trunclsn; - int update; - u_int32_t flags; -{ - DBT data; - DB_LOGC *logc; - DB_LSN ckp_lsn, first_lsn, last_lsn, lowlsn, lsn, stop_lsn, tlsn; - DB_TXNHEAD *txninfo; - DB_TXNREGION *region; - REGENV *renv; - REGINFO *infop; - __txn_ckp_args *ckp_args; - time_t now, tlow; - double nfiles; - u_int32_t hi_txn, log_size, txnid; - int32_t low; - int have_rec, progress, ret, t_ret; - char *p, *pass, t1[60], t2[60]; - - COMPQUIET(nfiles, (double)0.001); - - logc = NULL; - ckp_args = NULL; - hi_txn = TXN_MAXIMUM; - txninfo = NULL; - pass = "initial"; - ZERO_LSN(lsn); - - /* - * XXX - * Get the log size. No locking required because we're single-threaded - * during recovery. - */ - log_size = - ((LOG *)(((DB_LOG *)dbenv->lg_handle)->reginfo.primary))->log_size; - - /* - * If we need to, update the env handle timestamp. - */ - if (update && REP_ON(dbenv)) { - infop = dbenv->reginfo; - renv = infop->primary; - (void)time(&renv->rep_timestamp); - } - - /* Set in-recovery flags. */ - F_SET((DB_LOG *)dbenv->lg_handle, DBLOG_RECOVER); - region = ((DB_TXNMGR *)dbenv->tx_handle)->reginfo.primary; - F_SET(region, TXN_IN_RECOVERY); - - /* Allocate a cursor for the log. */ - if ((ret = __log_cursor(dbenv, &logc)) != 0) - goto err; - - /* - * If the user is specifying recovery to a particular point in time - * or to a particular LSN, find the point to start recovery from. - */ - ZERO_LSN(lowlsn); - if (max_lsn != NULL) { - if ((ret = __log_backup(dbenv, logc, max_lsn, &lowlsn, - CKPLSN_CMP)) != 0) - goto err; - } else if (dbenv->tx_timestamp != 0) { - if ((ret = __log_earliest(dbenv, logc, &low, &lowlsn)) != 0) - goto err; - if ((int32_t)dbenv->tx_timestamp < low) { - (void)snprintf(t1, sizeof(t1), - "%s", ctime(&dbenv->tx_timestamp)); - if ((p = strchr(t1, '\n')) != NULL) - *p = '\0'; - tlow = (time_t)low; - (void)snprintf(t2, sizeof(t2), "%s", ctime(&tlow)); - if ((p = strchr(t2, '\n')) != NULL) - *p = '\0'; - __db_err(dbenv, - "Invalid recovery timestamp %s; earliest time is %s", - t1, t2); - ret = EINVAL; - goto err; - } - } - - /* - * Recovery is done in three passes: - * Pass #0: - * We need to find the position from which we will open files. - * We need to open files beginning with the earlier of the - * most recent checkpoint LSN and a checkpoint LSN before the - * recovery timestamp, if specified. We need to be before the - * most recent checkpoint LSN because we are going to collect - * information about which transactions were begun before we - * start rolling forward. Those that were should never be undone - * because queue cannot use LSNs to determine what operations can - * safely be aborted and it cannot rollback operations in - * transactions for which there may be records not processed - * during recovery. We need to consider earlier points in time - * in case we are recovering to a particular timestamp. - * - * Pass #1: - * Read forward through the log from the position found in pass 0 - * opening and closing files, and recording transactions for which - * we've seen their first record (the transaction's prev_lsn is - * 0,0). At the end of this pass, we know all transactions for - * which we've seen begins and we have the "current" set of files - * open. - * - * Pass #2: - * Read backward through the log undoing any uncompleted TXNs. - * There are four cases: - * 1. If doing catastrophic recovery, we read to the - * beginning of the log - * 2. If we are doing normal reovery, then we have to roll - * back to the most recent checkpoint LSN. - * 3. If we are recovering to a point in time, then we have - * to roll back to the checkpoint whose ckp_lsn is earlier - * than the specified time. __log_earliest will figure - * this out for us. - * 4. If we are recovering back to a particular LSN, then - * we have to roll back to the checkpoint whose ckp_lsn - * is earlier than the max_lsn. __log_backup will figure - * that out for us. - * In case 2, "uncompleted TXNs" include all those who committed - * after the user's specified timestamp. - * - * Pass #3: - * Read forward through the log from the LSN found in pass #2, - * redoing any committed TXNs (which committed after any user- - * specified rollback point). During this pass, checkpoint - * file information is ignored, and file openings and closings - * are redone. - * - * ckp_lsn -- lsn of the last checkpoint or the first in the log. - * first_lsn -- the lsn where the forward passes begin. - * last_lsn -- the last lsn in the log, used for feedback - * lowlsn -- the lsn we are rolling back to, if we are recovering - * to a point in time. - * lsn -- temporary use lsn. - * stop_lsn -- the point at which forward roll should stop - */ - - /* - * Find out the last lsn, so that we can estimate how far along we - * are in recovery. This will help us determine how much log there - * is between the first LSN that we're going to be working with and - * the last one. We assume that each of the three phases takes the - * same amount of time (a false assumption) and then use the %-age - * of the amount of log traversed to figure out how much of the - * pass we've accomplished. - * - * If we can't find any log records, we're kind of done. - */ -#ifdef UMRW - ZERO_LSN(last_lsn); -#endif - memset(&data, 0, sizeof(data)); - if ((ret = __log_c_get(logc, &last_lsn, &data, DB_LAST)) != 0) { - if (ret == DB_NOTFOUND) - ret = 0; - else - __db_err(dbenv, "Last log record not found"); - goto err; - } - - do { - /* txnid is after rectype, which is a u_int32. */ - memcpy(&txnid, - (u_int8_t *)data.data + sizeof(u_int32_t), sizeof(txnid)); - - if (txnid != 0) - break; - } while ((ret = __log_c_get(logc, &lsn, &data, DB_PREV)) == 0); - - /* - * There are no transactions, so there is nothing to do unless - * we're recovering to an LSN. If we are, we need to proceed since - * we'll still need to do a vtruncate based on information we haven't - * yet collected. - */ - if (ret == DB_NOTFOUND) - ret = 0; - else if (ret != 0) - goto err; - - hi_txn = txnid; - - /* - * Pass #0 - * Find the LSN from which we begin OPENFILES. - * - * If this is a catastrophic recovery, or if no checkpoint exists - * in the log, the LSN is the first LSN in the log. - * - * Otherwise, it is the minimum of (1) the LSN in the last checkpoint - * and (2) the LSN in the checkpoint before any specified recovery - * timestamp or max_lsn. - */ - /* - * Get the first LSN in the log; it's an initial default - * even if this is not a catastrophic recovery. - */ - if ((ret = __log_c_get(logc, &ckp_lsn, &data, DB_FIRST)) != 0) { - if (ret == DB_NOTFOUND) - ret = 0; - else - __db_err(dbenv, "First log record not found"); - goto err; - } - first_lsn = ckp_lsn; - have_rec = 1; - - if (!LF_ISSET(DB_RECOVER_FATAL)) { - if ((ret = __txn_getckp(dbenv, &ckp_lsn)) == 0 && - (ret = __log_c_get(logc, &ckp_lsn, &data, DB_SET)) == 0) { - /* We have a recent checkpoint. This is LSN (1). */ - if ((ret = __txn_ckp_read(dbenv, - data.data, &ckp_args)) != 0) { - __db_err(dbenv, - "Invalid checkpoint record at [%ld][%ld]", - (u_long)ckp_lsn.file, - (u_long)ckp_lsn.offset); - goto err; - } - first_lsn = ckp_args->ckp_lsn; - __os_free(dbenv, ckp_args); - have_rec = 0; - } - - /* - * If LSN (2) exists, use it if it's before LSN (1). - * (If LSN (1) doesn't exist, first_lsn is the - * beginning of the log, so will "win" this check.) - * - * XXX - * In the recovery-to-a-timestamp case, lowlsn is chosen by - * __log_earliest, and is the checkpoint LSN of the - * *earliest* checkpoint in the unreclaimed log. I - * (krinsky) believe that we could optimize this by looking - * instead for the LSN of the *latest* checkpoint before - * the timestamp of interest, but I'm not sure that this - * is worth doing right now. (We have to look for lowlsn - * and low anyway, to make sure the requested timestamp is - * somewhere in the logs we have, and all that's required - * is that we pick *some* checkpoint after the beginning of - * the logs and before the timestamp. - */ - if ((dbenv->tx_timestamp != 0 || max_lsn != NULL) && - log_compare(&lowlsn, &first_lsn) < 0) { - DB_ASSERT(have_rec == 0); - first_lsn = lowlsn; - } - } - - /* Get the record at first_lsn if we don't have it already. */ - if (!have_rec && - (ret = __log_c_get(logc, &first_lsn, &data, DB_SET)) != 0) { - __db_err(dbenv, "Checkpoint LSN record [%ld][%ld] not found", - (u_long)first_lsn.file, (u_long)first_lsn.offset); - goto err; - } - - if (dbenv->db_feedback != NULL) { - if (last_lsn.file == first_lsn.file) - nfiles = (double) - (last_lsn.offset - first_lsn.offset) / log_size; - else - nfiles = (double)(last_lsn.file - first_lsn.file) + - (double)((log_size - first_lsn.offset) + - last_lsn.offset) / log_size; - /* We are going to divide by nfiles; make sure it isn't 0. */ - if (nfiles < 0.001) - nfiles = 0.001; - } - - /* Find a low txnid. */ - ret = 0; - if (hi_txn != 0) do { - /* txnid is after rectype, which is a u_int32. */ - memcpy(&txnid, - (u_int8_t *)data.data + sizeof(u_int32_t), sizeof(txnid)); - - if (txnid != 0) - break; - } while ((ret = __log_c_get(logc, &lsn, &data, DB_NEXT)) == 0); - - /* - * There are no transactions and we're not recovering to an LSN (see - * above), so there is nothing to do. - */ - if (ret == DB_NOTFOUND) { - if (log_compare(&lsn, &last_lsn) != 0) - ret = __db_log_corrupt(dbenv, &lsn); - else - ret = 0; - } - - /* Reset to the first lsn. */ - if (ret != 0 || - (ret = __log_c_get(logc, &first_lsn, &data, DB_SET)) != 0) - goto err; - - /* Initialize the transaction list. */ - if ((ret = - __db_txnlist_init(dbenv, txnid, hi_txn, max_lsn, &txninfo)) != 0) - goto err; - - /* - * Pass #1 - * Run forward through the log starting at the first relevant lsn. - */ - if ((ret = __env_openfiles(dbenv, logc, - txninfo, &data, &first_lsn, &last_lsn, nfiles, 1)) != 0) - goto err; - - /* If there were no transactions, then we can bail out early. */ - if (hi_txn == 0 && max_lsn == NULL) - goto done; - - /* - * Pass #2. - * - * We used first_lsn to tell us how far back we need to recover, - * use it here. - */ - - if (FLD_ISSET(dbenv->verbose, DB_VERB_RECOVERY)) - __db_msg(dbenv, "Recovery starting from [%lu][%lu]", - (u_long)first_lsn.file, (u_long)first_lsn.offset); - - pass = "backward"; - for (ret = __log_c_get(logc, &lsn, &data, DB_LAST); - ret == 0 && log_compare(&lsn, &first_lsn) >= 0; - ret = __log_c_get(logc, &lsn, &data, DB_PREV)) { - if (dbenv->db_feedback != NULL) { - progress = 34 + (int)(33 * (__lsn_diff(&first_lsn, - &last_lsn, &lsn, log_size, 0) / nfiles)); - dbenv->db_feedback(dbenv, DB_RECOVER, progress); - } - tlsn = lsn; - ret = __db_dispatch(dbenv, dbenv->recover_dtab, - dbenv->recover_dtab_size, &data, &tlsn, - DB_TXN_BACKWARD_ROLL, txninfo); - if (ret != 0) { - if (ret != DB_TXN_CKP) - goto msgerr; - else - ret = 0; - } - } - if (ret == DB_NOTFOUND) { - if (log_compare(&lsn, &first_lsn) > 0) - ret = __db_log_corrupt(dbenv, &lsn); - else - ret = 0; - } - if (ret != 0) - goto err; - - /* - * Pass #3. If we are recovering to a timestamp or to an LSN, - * we need to make sure that we don't roll-forward beyond that - * point because there may be non-transactional operations (e.g., - * closes that would fail). The last_lsn variable is used for - * feedback calculations, but use it to set an initial stopping - * point for the forward pass, and then reset appropriately to - * derive a real stop_lsn that tells how far the forward pass - * should go. - */ - pass = "forward"; - stop_lsn = last_lsn; - if (max_lsn != NULL || dbenv->tx_timestamp != 0) - stop_lsn = ((DB_TXNHEAD *)txninfo)->maxlsn; - - for (ret = __log_c_get(logc, &lsn, &data, DB_NEXT); - ret == 0; ret = __log_c_get(logc, &lsn, &data, DB_NEXT)) { - if (dbenv->db_feedback != NULL) { - progress = 67 + (int)(33 * (__lsn_diff(&first_lsn, - &last_lsn, &lsn, log_size, 1) / nfiles)); - dbenv->db_feedback(dbenv, DB_RECOVER, progress); - } - tlsn = lsn; - ret = __db_dispatch(dbenv, dbenv->recover_dtab, - dbenv->recover_dtab_size, &data, &tlsn, - DB_TXN_FORWARD_ROLL, txninfo); - if (ret != 0) { - if (ret != DB_TXN_CKP) - goto msgerr; - else - ret = 0; - } - /* - * If we are recovering to a timestamp or an LSN, - * we need to make sure that we don't try to roll - * forward beyond the soon-to-be end of log. - */ - if (log_compare(&lsn, &stop_lsn) >= 0) - break; - - } - if (ret == DB_NOTFOUND) - ret = __db_log_corrupt(dbenv, &lsn); - if (ret != 0) - goto err; - -#ifndef HAVE_FTRUNCATE - /* - * Process any pages that were on the limbo list and move them to - * the free list. Do this before checkpointing the database. - */ - if ((ret = __db_do_the_limbo(dbenv, NULL, NULL, txninfo, - dbenv->tx_timestamp != 0 ? LIMBO_TIMESTAMP : LIMBO_RECOVER)) != 0) - goto err; -#endif - - if (max_lsn == NULL) - region->last_txnid = ((DB_TXNHEAD *)txninfo)->maxid; - - if (dbenv->tx_timestamp != 0) { - /* We are going to truncate, so we'd best close the cursor. */ - if (logc != NULL && (ret = __log_c_close(logc)) != 0) - goto err; - logc = NULL; - /* Flush everything to disk, we are losing the log. */ - if ((ret = __memp_sync(dbenv, NULL)) != 0) - goto err; - region->last_ckp = ((DB_TXNHEAD *)txninfo)->ckplsn; - if ((ret = __log_vtruncate(dbenv, - &((DB_TXNHEAD *)txninfo)->maxlsn, - &((DB_TXNHEAD *)txninfo)->ckplsn, trunclsn)) != 0) - goto err; - -#ifndef HAVE_FTRUNCATE - /* - * Generate logging compensation records. - * If we crash during/after vtruncate we may have - * pages missing from the free list since they - * if we roll things further back from here. - * These pages are only known in memory at this pont. - */ - if ((ret = __db_do_the_limbo(dbenv, - NULL, NULL, txninfo, LIMBO_COMPENSATE)) != 0) - goto err; -#endif - } - -done: - /* Take a checkpoint here to force any dirty data pages to disk. */ - if ((ret = __txn_checkpoint(dbenv, 0, 0, DB_FORCE)) != 0) - goto err; - - /* Close all the db files that are open. */ - if ((ret = __dbreg_close_files(dbenv)) != 0) - goto err; - - if (max_lsn != NULL) { - if (!IS_ZERO_LSN(((DB_TXNHEAD *)txninfo)->ckplsn)) - region->last_ckp = ((DB_TXNHEAD *)txninfo)->ckplsn; - else if ((ret = - __txn_findlastckp(dbenv, ®ion->last_ckp, max_lsn)) != 0) - goto err; - - /* We are going to truncate, so we'd best close the cursor. */ - if (logc != NULL && (ret = __log_c_close(logc)) != 0) - goto err; - if ((ret = __log_vtruncate(dbenv, - max_lsn, &((DB_TXNHEAD *)txninfo)->ckplsn, trunclsn)) != 0) - goto err; - - /* - * Now we need to open files that should be open in order for - * client processing to continue. However, since we've - * truncated the log, we need to recompute from where the - * openfiles pass should begin. - */ - if ((ret = __log_cursor(dbenv, &logc)) != 0) - goto err; - if ((ret = - __log_c_get(logc, &first_lsn, &data, DB_FIRST)) != 0) { - if (ret == DB_NOTFOUND) - ret = 0; - else - __db_err(dbenv, "First log record not found"); - goto err; - } - if ((ret = __txn_getckp(dbenv, &first_lsn)) == 0 && - (ret = __log_c_get(logc, &first_lsn, &data, DB_SET)) == 0) { - /* We have a recent checkpoint. This is LSN (1). */ - if ((ret = __txn_ckp_read(dbenv, - data.data, &ckp_args)) != 0) { - __db_err(dbenv, - "Invalid checkpoint record at [%ld][%ld]", - (u_long)first_lsn.file, - (u_long)first_lsn.offset); - goto err; - } - first_lsn = ckp_args->ckp_lsn; - __os_free(dbenv, ckp_args); - } - if ((ret = __log_c_get(logc, &first_lsn, &data, DB_SET)) != 0) - goto err; - if ((ret = __env_openfiles(dbenv, logc, - txninfo, &data, &first_lsn, NULL, nfiles, 1)) != 0) - goto err; - } else if (region->stat.st_nrestores == 0) { - /* - * If there are no prepared transactions that need resolution, - * we need to reset the transaction ID space and log this fact. - */ - if ((ret = __txn_reset(dbenv)) != 0) - goto err; - } else { - /* - * If we have restored prepared txns then they are in process - * as far as replication is concerned. - */ - if (REP_ON(dbenv)) - ((DB_REP *)dbenv->rep_handle)->region->op_cnt = - region->stat.st_nrestores; - if ((ret = __txn_recycle_id(dbenv)) != 0) - goto err; - } - - if (FLD_ISSET(dbenv->verbose, DB_VERB_RECOVERY)) { - (void)time(&now); - __db_msg(dbenv, "Recovery complete at %.24s", ctime(&now)); - __db_msg(dbenv, "%s %lx %s [%lu][%lu]", - "Maximum transaction ID", - (u_long)(txninfo == NULL ? - TXN_MINIMUM : ((DB_TXNHEAD *)txninfo)->maxid), - "Recovery checkpoint", - (u_long)region->last_ckp.file, - (u_long)region->last_ckp.offset); - } - - if (0) { -msgerr: __db_err(dbenv, - "Recovery function for LSN %lu %lu failed on %s pass", - (u_long)lsn.file, (u_long)lsn.offset, pass); - } - -err: if (logc != NULL && (t_ret = __log_c_close(logc)) != 0 && ret == 0) - ret = t_ret; - - if (txninfo != NULL) - __db_txnlist_end(dbenv, txninfo); - - dbenv->tx_timestamp = 0; - - F_CLR((DB_LOG *)dbenv->lg_handle, DBLOG_RECOVER); - F_CLR(region, TXN_IN_RECOVERY); - - return (ret); -} - -/* - * Figure out how many logfiles we have processed. If we are moving - * forward (is_forward != 0), then we're computing current - low. If - * we are moving backward, we are computing high - current. max is - * the number of bytes per logfile. - */ -static double -__lsn_diff(low, high, current, max, is_forward) - DB_LSN *low, *high, *current; - u_int32_t max; - int is_forward; -{ - double nf; - - /* - * There are three cases in each direction. If you are in the - * same file, then all you need worry about is the difference in - * offsets. If you are in different files, then either your offsets - * put you either more or less than the integral difference in the - * number of files -- we need to handle both of these. - */ - if (is_forward) { - if (current->file == low->file) - nf = (double)(current->offset - low->offset) / max; - else if (current->offset < low->offset) - nf = (double)((current->file - low->file) - 1) + - (double)((max - low->offset) + current->offset) / - max; - else - nf = (double)(current->file - low->file) + - (double)(current->offset - low->offset) / max; - } else { - if (current->file == high->file) - nf = (double)(high->offset - current->offset) / max; - else if (current->offset > high->offset) - nf = (double)((high->file - current->file) - 1) + - (double) - ((max - current->offset) + high->offset) / max; - else - nf = (double)(high->file - current->file) + - (double)(high->offset - current->offset) / max; - } - return (nf); -} - -/* - * __log_backup -- - * - * This is used to find the earliest log record to process when a client - * is trying to sync up with a master whose max LSN is less than this - * client's max lsn; we want to roll back everything after that. - * Also used in the verify phase to walk back via checkpoints. - * - * Find the latest checkpoint whose ckp_lsn is less than the max lsn. - * PUBLIC: int __log_backup __P((DB_ENV *, DB_LOGC *, DB_LSN *, - * PUBLIC: DB_LSN *, u_int32_t)); - */ -int -__log_backup(dbenv, logc, max_lsn, start_lsn, cmp) - DB_ENV *dbenv; - DB_LOGC *logc; - DB_LSN *max_lsn, *start_lsn; - u_int32_t cmp; -{ - DB_LSN cmp_lsn, lsn; - DBT data; - __txn_ckp_args *ckp_args; - int lcmp, ret; - - memset(&data, 0, sizeof(data)); - ckp_args = NULL; - - if (cmp != CKPLSN_CMP && cmp != LASTCKP_CMP) - return (EINVAL); - - if ((ret = __txn_getckp(dbenv, &lsn)) != 0) - goto err; - /* - * Cmp tells us whether to check the ckp_lsn or the last_ckp - * fields in the checkpoint record. - */ - while ((ret = __log_c_get(logc, &lsn, &data, DB_SET)) == 0) { - if ((ret = __txn_ckp_read(dbenv, data.data, &ckp_args)) != 0) - return (ret); - if (cmp == CKPLSN_CMP) { - /* - * Follow checkpoints through the log until - * we find one with a ckp_lsn less than - * or equal max_lsn. - */ - cmp_lsn = ckp_args->ckp_lsn; - lcmp = (log_compare(&cmp_lsn, max_lsn) <= 0); - } else { - /* - * When we're walking back through the checkpoints - * we want the LSN of this checkpoint strictly less - * than the max_lsn (also a ckp LSN). - */ - cmp_lsn = lsn; - lcmp = (log_compare(&cmp_lsn, max_lsn) < 0); - } - if (lcmp) { - *start_lsn = cmp_lsn; - break; - } - - lsn = ckp_args->last_ckp; - /* - * If there are no more checkpoints behind us, we're - * done. Break with DB_NOTFOUND. - */ - if (IS_ZERO_LSN(lsn)) { - ret = DB_NOTFOUND; - break; - } - __os_free(dbenv, ckp_args); - } - - if (ckp_args != NULL) - __os_free(dbenv, ckp_args); - /* - * For CKPLSN_CMP if we walked back through all the checkpoints, - * set the cursor on the first log record. For LASTCKP_CMP - * we want to return 0,0 in start_lsn. - */ -err: if (IS_ZERO_LSN(*start_lsn) && cmp == CKPLSN_CMP && - (ret == 0 || ret == DB_NOTFOUND)) - ret = __log_c_get(logc, start_lsn, &data, DB_FIRST); - return (ret); -} - -/* - * __log_earliest -- - * - * Return the earliest recovery point for the log files present. The - * earliest recovery time is the time stamp of the first checkpoint record - * whose checkpoint LSN is greater than the first LSN we process. - */ -static int -__log_earliest(dbenv, logc, lowtime, lowlsn) - DB_ENV *dbenv; - DB_LOGC *logc; - int32_t *lowtime; - DB_LSN *lowlsn; -{ - DB_LSN first_lsn, lsn; - DBT data; - __txn_ckp_args *ckpargs; - u_int32_t rectype; - int cmp, ret; - - memset(&data, 0, sizeof(data)); - /* - * Read forward through the log looking for the first checkpoint - * record whose ckp_lsn is greater than first_lsn. - */ - - for (ret = __log_c_get(logc, &first_lsn, &data, DB_FIRST); - ret == 0; ret = __log_c_get(logc, &lsn, &data, DB_NEXT)) { - memcpy(&rectype, data.data, sizeof(rectype)); - if (rectype != DB___txn_ckp) - continue; - if ((ret = __txn_ckp_read(dbenv, data.data, &ckpargs)) == 0) { - cmp = log_compare(&ckpargs->ckp_lsn, &first_lsn); - *lowlsn = ckpargs->ckp_lsn; - *lowtime = ckpargs->timestamp; - - __os_free(dbenv, ckpargs); - if (cmp >= 0) - break; - } - } - - return (ret); -} - -/* - * __env_openfiles -- - * Perform the pass of recovery that opens files. This is used - * both during regular recovery and an initial call to txn_recover (since - * we need files open in order to abort prepared, but not yet committed - * transactions). - * - * See the comments in db_apprec for a detailed description of the - * various recovery passes. - * - * If we are not doing feedback processing (i.e., we are doing txn_recover - * processing and in_recovery is zero), then last_lsn can be NULL. - * - * PUBLIC: int __env_openfiles __P((DB_ENV *, DB_LOGC *, - * PUBLIC: void *, DBT *, DB_LSN *, DB_LSN *, double, int)); - */ -int -__env_openfiles(dbenv, logc, txninfo, - data, open_lsn, last_lsn, nfiles, in_recovery) - DB_ENV *dbenv; - DB_LOGC *logc; - void *txninfo; - DBT *data; - DB_LSN *open_lsn, *last_lsn; - int in_recovery; - double nfiles; -{ - DB_LSN lsn, tlsn; - u_int32_t log_size; - int progress, ret; - - /* - * XXX - * Get the log size. No locking required because we're single-threaded - * during recovery. - */ - log_size = - ((LOG *)(((DB_LOG *)dbenv->lg_handle)->reginfo.primary))->log_size; - - lsn = *open_lsn; - for (;;) { - if (in_recovery && dbenv->db_feedback != NULL) { - DB_ASSERT(last_lsn != NULL); - progress = (int)(33 * (__lsn_diff(open_lsn, - last_lsn, &lsn, log_size, 1) / nfiles)); - dbenv->db_feedback(dbenv, DB_RECOVER, progress); - } - tlsn = lsn; - ret = __db_dispatch(dbenv, - dbenv->recover_dtab, dbenv->recover_dtab_size, data, &tlsn, - in_recovery ? DB_TXN_OPENFILES : DB_TXN_POPENFILES, - txninfo); - if (ret != 0 && ret != DB_TXN_CKP) { - __db_err(dbenv, - "Recovery function for LSN %lu %lu failed", - (u_long)lsn.file, (u_long)lsn.offset); - break; - } - if ((ret = __log_c_get(logc, &lsn, data, DB_NEXT)) != 0) { - if (ret == DB_NOTFOUND) { - if (last_lsn != NULL && - log_compare(&lsn, last_lsn) != 0) - ret = __db_log_corrupt(dbenv, &lsn); - else - ret = 0; - } - break; - } - } - - return (ret); -} - -static int -__db_log_corrupt(dbenv, lsnp) - DB_ENV *dbenv; - DB_LSN *lsnp; -{ - __db_err(dbenv, "Log file corrupt at LSN: [%lu][%lu]", - (u_long)lsnp->file, (u_long)lsnp->offset); - return (EINVAL); -} diff --git a/storage/bdb/env/env_region.c b/storage/bdb/env/env_region.c deleted file mode 100644 index 6ef15a13d43..00000000000 --- a/storage/bdb/env/env_region.c +++ /dev/null @@ -1,1195 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: env_region.c,v 12.13 2005/10/21 19:13:01 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#if TIME_WITH_SYS_TIME -#include <sys/time.h> -#include <time.h> -#else -#if HAVE_SYS_TIME_H -#include <sys/time.h> -#else -#include <time.h> -#endif -#endif - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_shash.h" -#include "dbinc/crypto.h" -#include "dbinc/mp.h" - -static void __db_des_destroy __P((DB_ENV *, REGION *)); -static int __db_des_get __P((DB_ENV *, REGINFO *, REGINFO *, REGION **)); -static int __db_e_remfile __P((DB_ENV *)); -static int __db_faultmem __P((DB_ENV *, void *, size_t, int)); - -/* - * __db_e_attach - * Join/create the environment - * - * PUBLIC: int __db_e_attach __P((DB_ENV *, u_int32_t *)); - */ -int -__db_e_attach(dbenv, init_flagsp) - DB_ENV *dbenv; - u_int32_t *init_flagsp; -{ - REGENV *renv; - REGENV_REF ref; - REGINFO *infop; - REGION *rp, tregion; - size_t size; - size_t nrw; - u_int32_t bytes, i, mbytes, nregions; - u_int retry_cnt; - int majver, minver, patchver, ret, segid; - char buf[sizeof(DB_REGION_FMT) + 20]; - - /* Initialization */ - retry_cnt = 0; - - /* Repeated initialization. */ -loop: renv = NULL; - - /* Set up the DB_ENV's REG_INFO structure. */ - if ((ret = __os_calloc(dbenv, 1, sizeof(REGINFO), &infop)) != 0) - return (ret); - infop->dbenv = dbenv; - infop->type = REGION_TYPE_ENV; - infop->id = REGION_ID_ENV; - infop->flags = REGION_JOIN_OK; - if (F_ISSET(dbenv, DB_ENV_CREATE)) - F_SET(infop, REGION_CREATE_OK); - - /* - * We have to single-thread the creation of the REGENV region. Once - * it exists, we can serialize using region mutexes, but until then - * we have to be the only player in the game. - * - * If this is a private environment, we are only called once and there - * are no possible race conditions. - * - * If this is a public environment, we use the filesystem to ensure - * the creation of the environment file is single-threaded. - */ - if (F_ISSET(dbenv, DB_ENV_PRIVATE)) { - if ((ret = __os_strdup(dbenv, - "process-private", &infop->name)) != 0) - goto err; - goto creation; - } - - /* Build the region name. */ - (void)snprintf(buf, sizeof(buf), "%s", DB_REGION_ENV); - if ((ret = __db_appname(dbenv, - DB_APP_NONE, buf, 0, NULL, &infop->name)) != 0) - goto err; - - /* - * Try to create the file, if we have the authority. We have to ensure - * that multiple threads/processes attempting to simultaneously create - * the file are properly ordered. Open using the O_CREAT and O_EXCL - * flags so that multiple attempts to create the region will return - * failure in all but one. POSIX 1003.1 requires that EEXIST be the - * errno return value -- I sure hope they're right. - */ - if (F_ISSET(dbenv, DB_ENV_CREATE)) { - if ((ret = __os_open(dbenv, infop->name, - DB_OSO_CREATE | DB_OSO_EXCL | DB_OSO_REGION, - dbenv->db_mode, &dbenv->lockfhp)) == 0) - goto creation; - if (ret != EEXIST) { - __db_err(dbenv, - "%s: %s", infop->name, db_strerror(ret)); - goto err; - } - } - - /* - * If we couldn't create the file, try and open it. (If that fails, - * we're done.) - */ - if ((ret = __os_open( - dbenv, infop->name, DB_OSO_REGION, 0, &dbenv->lockfhp)) != 0) - goto err; - - /* The region exists, it's not okay to recreate it. */ - F_CLR(infop, REGION_CREATE_OK); - - /* - * !!! - * The region may be in system memory not backed by the filesystem - * (more specifically, not backed by this file), and we're joining - * it. In that case, the process that created it will have written - * out a REGENV_REF structure as its only contents. We read that - * structure before we do anything further, e.g., we can't just map - * that file in and then figure out what's going on. - * - * All of this noise is because some systems don't have a coherent VM - * and buffer cache, and what's worse, when you mix operations on the - * VM and buffer cache, half the time you hang the system. - * - * If the file is the size of an REGENV_REF structure, then we know - * the real region is in some other memory. (The only way you get a - * file that size is to deliberately write it, as it's smaller than - * any possible disk sector created by writing a file or mapping the - * file into memory.) In which case, retrieve the structure from the - * file and use it to acquire the referenced memory. - * - * If the structure is larger than a REGENV_REF structure, then this - * file is backing the shared memory region, and we just map it into - * memory. - * - * And yes, this makes me want to take somebody and kill them. (I - * digress -- but you have no freakin' idea. This is unbelievably - * stupid and gross, and I've probably spent six months of my life, - * now, trying to make different versions of it work.) - */ - if ((ret = __os_ioinfo(dbenv, infop->name, - dbenv->lockfhp, &mbytes, &bytes, NULL)) != 0) { - __db_err(dbenv, "%s: %s", infop->name, db_strerror(ret)); - goto err; - } - - /* - * !!! - * A size_t is OK -- regions get mapped into memory, and so can't - * be larger than a size_t. - */ - size = mbytes * MEGABYTE + bytes; - - /* - * If the size is less than the size of a REGENV_REF structure, the - * region (or, possibly, the REGENV_REF structure) has not yet been - * completely written. Shouldn't be possible, but there's no reason - * not to wait awhile and try again. - * - * Otherwise, if the size is the size of a REGENV_REF structure, - * read it into memory and use it as a reference to the real region. - */ - if (size <= sizeof(ref)) { - if (size != sizeof(ref)) - goto retry; - - if ((ret = __os_read(dbenv, dbenv->lockfhp, &ref, - sizeof(ref), &nrw)) != 0 || nrw < (size_t)sizeof(ref)) { - if (ret == 0) - ret = EIO; - __db_err(dbenv, - "%s: unable to read system-memory information from: %s", - infop->name, db_strerror(ret)); - goto err; - } - size = ref.size; - segid = ref.segid; - - F_SET(dbenv, DB_ENV_SYSTEM_MEM); - } else if (F_ISSET(dbenv, DB_ENV_SYSTEM_MEM)) { - ret = EINVAL; - __db_err(dbenv, - "%s: existing environment not created in system memory: %s", - infop->name, db_strerror(ret)); - goto err; - } else - segid = INVALID_REGION_SEGID; - -#ifndef HAVE_MUTEX_FCNTL - /* - * If we're not doing fcntl locking, we can close the file handle. We - * no longer need it and the less contact between the buffer cache and - * the VM, the better. - */ - (void)__os_closehandle(dbenv, dbenv->lockfhp); - dbenv->lockfhp = NULL; -#endif - - /* Call the region join routine to acquire the region. */ - memset(&tregion, 0, sizeof(tregion)); - tregion.size = (roff_t)size; - tregion.segid = segid; - if ((ret = __os_r_attach(dbenv, infop, &tregion)) != 0) - goto err; - - /* - * The environment's REGENV structure has to live at offset 0 instead - * of the usual shalloc information. Set the primary reference and - * correct the "addr" value to reference the shalloc region. Note, - * this means that all of our offsets (R_ADDR/R_OFFSET) get shifted - * as well, but that should be fine. - */ - infop->primary = infop->addr; - infop->addr = (u_int8_t *)infop->addr + sizeof(REGENV); - renv = infop->primary; - - /* - * Make sure the region matches our build. Special case a region - * that's all nul bytes, just treat it like any other corruption. - * - * !!! - * We don't display the major/minor version from the environment, - * because it may be in a different place in the two regions. - */ - if (renv->majver != DB_VERSION_MAJOR || - renv->minver != DB_VERSION_MINOR) { - if (renv->majver != 0 || renv->minver != 0) { - __db_err(dbenv, - "Program version %d.%d doesn't match environment version %d.%d", - DB_VERSION_MAJOR, DB_VERSION_MINOR, - renv->majver, renv->minver); - ret = DB_VERSION_MISMATCH; - } else - ret = EINVAL; - goto err; - } - - /* - * Check if the environment has had a catastrophic failure. - * - * Check the magic number to ensure the region is initialized. If the - * magic number isn't set, the lock may not have been initialized, and - * an attempt to use it could lead to random behavior. - * - * The panic and magic values aren't protected by any lock, so we never - * use them in any check that's more complex than set/not-set. - * - * !!! - * I'd rather play permissions games using the underlying file, but I - * can't because Windows/NT filesystems won't open files mode 0. - */ - if (renv->panic && !F_ISSET(dbenv, DB_ENV_NOPANIC)) { - ret = __db_panic_msg(dbenv); - goto err; - } - if (renv->magic != DB_REGION_MAGIC) - goto retry; - - /* - * Get a reference to the underlying REGION information for this - * environment. - */ - if ((ret = __db_des_get(dbenv, infop, infop, &rp)) != 0 || rp == NULL) - goto find_err; - infop->rp = rp; - - /* - * There's still a possibility for inconsistent data. When we acquired - * the size of the region and attached to it, it might have still been - * growing as part of its creation. We can detect this by checking the - * size we originally found against the region's current size. (The - * region's current size has to be final, the creator finished growing - * it before setting the magic number in the region.) - */ - if (rp->size != size) - goto retry; - - /* Increment the reference count. */ - MUTEX_LOCK(dbenv, renv->mtx_regenv); - ++renv->refcnt; - MUTEX_UNLOCK(dbenv, renv->mtx_regenv); - - /* - * Check our callers configuration flags, it's an error to configure - * incompatible or additional subsystems in an existing environment. - * Return the total set of flags to the caller so they initialize the - * correct set of subsystems. - */ - if (init_flagsp != NULL) { - FLD_CLR(*init_flagsp, renv->init_flags); - if (*init_flagsp != 0) { - __db_err(dbenv, - "configured environment flags incompatible with existing environment"); - ret = EINVAL; - goto err; - } - *init_flagsp = renv->init_flags; - } - - /* - * Fault the pages into memory. Note, do this AFTER releasing the - * lock, because we're only reading the pages, not writing them. - */ - (void)__db_faultmem(dbenv, infop->primary, rp->size, 0); - - /* Everything looks good, we're done. */ - dbenv->reginfo = infop; - return (0); - -creation: - /* Create the environment region. */ - F_SET(infop, REGION_CREATE); - - /* - * Allocate room for REGION structures plus overhead. - * - * XXX - * Overhead is so high because encryption passwds are stored in the - * base environment region, as are replication vote arrays. This is - * a bug, not a feature, replication needs its own region. - */ - memset(&tregion, 0, sizeof(tregion)); - nregions = dbenv->mp_ncache + 10; - tregion.size = - (roff_t)(nregions * sizeof(REGION) + dbenv->passwd_len + 16 * 1024); - tregion.segid = INVALID_REGION_SEGID; - if ((ret = __os_r_attach(dbenv, infop, &tregion)) != 0) - goto err; - - /* - * Fault the pages into memory. Note, do this BEFORE we initialize - * anything, because we're writing the pages, not just reading them. - */ - (void)__db_faultmem(dbenv, infop->addr, tregion.size, 1); - - /* - * The first object in the region is the REGENV structure. This is - * different from the other regions, and, from everything else in - * this region, where all objects are allocated from the pool, i.e., - * there aren't any fixed locations. The remaining space is made - * available for later allocation. - * - * The allocation space must be size_t aligned, because that's what - * the initialization routine is going to store there. To make sure - * that happens, the REGENV structure was padded with a final size_t. - * No other region needs to worry about it because all of them treat - * the entire region as allocation space. - * - * Set the primary reference and correct the "addr" value to reference - * the shalloc region. Note, this requires that we "uncorrect" it at - * region detach, and that all of our offsets (R_ADDR/R_OFFSET) will be - * shifted as well, but that should be fine. - */ - infop->primary = infop->addr; - infop->addr = (u_int8_t *)infop->addr + sizeof(REGENV); - __db_shalloc_init(infop, tregion.size - sizeof(REGENV)); - - /* - * Initialize the rest of the REGENV structure. (Don't set the magic - * number to the correct value, that would validate the environment). - */ - renv = infop->primary; - renv->magic = 0; - renv->panic = 0; - - (void)db_version(&majver, &minver, &patchver); - renv->majver = (u_int32_t)majver; - renv->minver = (u_int32_t)minver; - renv->patchver = (u_int32_t)patchver; - - (void)time(&renv->timestamp); - __os_unique_id(dbenv, &renv->envid); - - if ((ret = __mutex_alloc( - dbenv, MTX_ENV_REGION, 0, &renv->mtx_regenv)) != 0) - goto err; - renv->refcnt = 1; - - /* - * Initialize init_flags to store the flags that any other environment - * handle that uses DB_JOINENV to join this environment will need. - */ - renv->init_flags = (init_flagsp == NULL) ? 0 : *init_flagsp; - - /* - * Set up the region array. We use an array rather than a linked list - * as we have to traverse this list after failure in some cases, and - * we don't want to infinitely loop should the application fail while - * we're manipulating the list. - */ - renv->region_cnt = nregions; - if ((ret = - __db_shalloc(infop, nregions * sizeof(REGION), 0, &rp)) != 0) { - __db_err(dbenv, "unable to create new master region array: %s", - db_strerror(ret)); - goto err; - } - renv->region_off = R_OFFSET(infop, rp); - for (i = 0; i < nregions; ++i, ++rp) - rp->id = INVALID_REGION_ID; - - renv->cipher_off = INVALID_ROFF; - - renv->rep_off = INVALID_ROFF; - renv->flags = 0; - renv->op_timestamp = renv->rep_timestamp = 0; - - /* - * Get the underlying REGION structure for this environment. Note, - * we created the underlying OS region before we acquired the REGION - * structure, which is backwards from the normal procedure. Update - * the REGION structure. - */ - if ((ret = __db_des_get(dbenv, infop, infop, &rp)) != 0) { -find_err: __db_err(dbenv, "%s: unable to find environment", infop->name); - if (ret == 0) - ret = EINVAL; - goto err; - } - infop->rp = rp; - rp->size = tregion.size; - rp->segid = tregion.segid; - - /* - * !!! - * If we create an environment where regions are public and in system - * memory, we have to inform processes joining the environment how to - * attach to the shared memory segment. So, we write the shared memory - * identifier into the file, to be read by those other processes. - * - * XXX - * This is really OS-layer information, but I can't see any easy way - * to move it down there without passing down information that it has - * no right to know, e.g., that this is the one-and-only REGENV region - * and not some other random region. - */ - if (tregion.segid != INVALID_REGION_SEGID) { - ref.size = tregion.size; - ref.segid = tregion.segid; - if ((ret = __os_write( - dbenv, dbenv->lockfhp, &ref, sizeof(ref), &nrw)) != 0) { - __db_err(dbenv, - "%s: unable to write out public environment ID: %s", - infop->name, db_strerror(ret)); - goto err; - } - } - -#ifndef HAVE_MUTEX_FCNTL - /* - * If we're not doing fcntl locking, we can close the file handle. We - * no longer need it and the less contact between the buffer cache and - * the VM, the better. - */ - if (dbenv->lockfhp != NULL) { - (void)__os_closehandle(dbenv, dbenv->lockfhp); - dbenv->lockfhp = NULL; - } -#endif - - /* Everything looks good, we're done. */ - dbenv->reginfo = infop; - return (0); - -err: -retry: /* Close any open file handle. */ - if (dbenv->lockfhp != NULL) { - (void)__os_closehandle(dbenv, dbenv->lockfhp); - dbenv->lockfhp = NULL; - } - - /* - * If we joined or created the region, detach from it. If we created - * it, destroy it. Note, there's a path in the above code where we're - * using a temporary REGION structure because we haven't yet allocated - * the real one. In that case the region address (addr) will be filled - * in, but the REGION pointer (rp) won't. Fix it. - */ - if (infop->addr != NULL) { - if (infop->rp == NULL) - infop->rp = &tregion; - - /* Reset the addr value that we "corrected" above. */ - infop->addr = infop->primary; - (void)__os_r_detach(dbenv, - infop, F_ISSET(infop, REGION_CREATE)); - } - - /* Free the allocated name and/or REGINFO structure. */ - if (infop->name != NULL) - __os_free(dbenv, infop->name); - __os_free(dbenv, infop); - - /* If we had a temporary error, wait awhile and try again. */ - if (ret == 0) { - if (++retry_cnt > 3) { - __db_err(dbenv, "unable to join the environment"); - ret = EAGAIN; - } else { - __os_sleep(dbenv, retry_cnt * 3, 0); - goto loop; - } - } - - return (ret); -} - -/* - * __db_e_golive -- - * Turn on the created environment. - * - * PUBLIC: int __db_e_golive __P((DB_ENV *)); - */ -int -__db_e_golive(dbenv) - DB_ENV *dbenv; -{ - REGENV *renv; - REGINFO *infop; - - infop = dbenv->reginfo; - renv = infop->primary; - - /* If we didn't create the region, there's no need for further work. */ - if (!F_ISSET(infop, REGION_CREATE)) - return (0); - - /* - * Validate the file. All other threads of control are waiting - * on this value to be written -- "Let slip the hounds of war!" - */ - renv->magic = DB_REGION_MAGIC; - - return (0); -} - -/* - * __db_e_detach -- - * Detach from the environment. - * - * PUBLIC: int __db_e_detach __P((DB_ENV *, int)); - */ -int -__db_e_detach(dbenv, destroy) - DB_ENV *dbenv; - int destroy; -{ - REGENV *renv; - REGINFO *infop; - REGION rp; - int ret, t_ret; - - infop = dbenv->reginfo; - renv = infop->primary; - ret = 0; - - if (F_ISSET(dbenv, DB_ENV_PRIVATE)) - destroy = 1; - - /* Decrement the reference count. */ - MUTEX_LOCK(dbenv, renv->mtx_regenv); - if (renv->refcnt == 0) - __db_err(dbenv, "environment reference count went negative"); - else - --renv->refcnt; - MUTEX_UNLOCK(dbenv, renv->mtx_regenv); - - /* Close the locking file handle. */ - if (dbenv->lockfhp != NULL) { - if ((t_ret = - __os_closehandle(dbenv, dbenv->lockfhp)) != 0 && ret == 0) - ret = t_ret; - dbenv->lockfhp = NULL; - } - - /* - * Release the region, and kill our reference. - */ - if (destroy) { -#ifdef HAVE_CRYPTO - /* - * Destroy any system resources the crypto subsystem may have - * acquired. - */ - if ((t_ret = __crypto_region_destroy(dbenv)) != 0 && ret == 0) - ret = t_ret; -#endif - /* - * Destroy any system resources the replication subsystem may - * have acquired. - */ - if ((t_ret = __rep_region_destroy(dbenv)) != 0 && ret == 0) - ret = t_ret; - - /* - * Free the REGION array. - * - * The actual underlying region structure is allocated from the - * primary shared region, and we're about to free it. Save a - * copy on our stack for the REGINFO to reference when it calls - * down into the OS layer to release the shared memory segment. - */ - rp = *infop->rp; - infop->rp = &rp; - - if (renv->region_off != INVALID_ROFF) - __db_shalloc_free( - infop, R_ADDR(infop, renv->region_off)); - - /* Discard any mutex resources we may have acquired. */ - if ((t_ret = - __mutex_free(dbenv, &renv->mtx_regenv)) != 0 && ret == 0) - ret = t_ret; - } - - /* - * Set the DB_ENV->reginfo field to NULL. First, DB_ENV->remove calls - * __env_remove to do the region remove, and __envremove attached and - * then detaches from the region. We don't want to return to - * DB_ENV->remove with a non-NULL DB_ENV->reginfo field because it will - * attempt to detach again as part of its cleanup. - * - * Second, DB code uses DB_ENV->reginfo to decide if it's OK to read - * the underlying region. We're about to destroy what it references, - * so it needs to be cleared. - */ - dbenv->reginfo = NULL; - - /* Reset the addr value that we "corrected" above. */ - infop->addr = infop->primary; - - if ((t_ret = __os_r_detach(dbenv, infop, destroy)) != 0 && ret == 0) - ret = t_ret; - if (infop->name != NULL) - __os_free(dbenv, infop->name); - - /* Discard the DB_ENV->reginfo field's memory. */ - __os_free(dbenv, infop); - - return (ret); -} - -/* - * __db_e_remove -- - * Discard an environment if it's not in use. - * - * PUBLIC: int __db_e_remove __P((DB_ENV *, u_int32_t)); - */ -int -__db_e_remove(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - REGENV *renv; - REGINFO *infop, reginfo; - REGION *rp; - u_int32_t db_env_reset, i; - int ret; - - db_env_reset = F_ISSET(dbenv, DB_ENV_NOLOCKING | DB_ENV_NOPANIC); - - /* - * This routine has to walk a nasty line between not looking into - * the environment (which may be corrupted after an app or system - * crash), and removing everything that needs removing. What we - * do is: - * 1. Connect to the environment. - * 2. If the environment is in use (reference count is non-zero), - * return EBUSY. - * 3. Panic it and overwrite the magic number so any threads of - * control attempting to connect (or racing with us) backoff - * and retry or just die. - * 4. Walk the array of regions. Connect to each region and then - * disconnect with the destroy flag set. This shouldn't cause - * any problems, even if the region is corrupted, because we - * never look inside the region (with the single exception of - * mutex regions on systems where we have to return resources - * to the underlying system). - * 5. Walk the list of files in the directory, unlinking any - * files that match a region name. Unlink the environment - * file last. - * - * If the force flag is set, we do not acquire any locks during this - * process. - * - * We're going to panic the environment, so we'll want to ignore that - * flag. - */ - if (LF_ISSET(DB_FORCE)) - F_SET(dbenv, DB_ENV_NOLOCKING); - F_SET(dbenv, DB_ENV_NOPANIC); - - /* Join the environment. */ - if ((ret = __db_e_attach(dbenv, NULL)) != 0) { - /* - * If we can't join it, we assume that's because it doesn't - * exist. It would be better to know why we failed, but it - * probably isn't important. - */ - ret = 0; - if (LF_ISSET(DB_FORCE)) - goto remfiles; - goto done; - } - - infop = dbenv->reginfo; - renv = infop->primary; - - /* Lock the environment. */ - MUTEX_LOCK(dbenv, renv->mtx_regenv); - - /* - * If it's in use, we're done unless we're forcing the issue or the - * environment has panic'd. (Presumably, if the environment panic'd, - * the thread holding the reference count may not have cleaned up.) - */ - if (renv->refcnt == 1 || renv->panic == 1 || LF_ISSET(DB_FORCE)) { - /* - * Set the panic flag and overwrite the magic number. - * - * !!! - * From this point on, there's no going back, we pretty - * much ignore errors, and just whack on whatever we can. - */ - renv->magic = 0; - renv->panic = 1; - - /* - * Unlock the environment -- nobody should need this lock - * because we've poisoned the pool. - */ - MUTEX_UNLOCK(dbenv, renv->mtx_regenv); - - /* Attach to each sub-region and destroy it. */ - for (rp = R_ADDR(infop, renv->region_off), - i = 0; i < renv->region_cnt; ++i, ++rp) { - if (rp->id == INVALID_REGION_ID || - rp->type == REGION_TYPE_ENV) - continue; - /* - * !!! - * The REGION_CREATE_OK flag is set for Windows/95 -- - * regions are zero'd out when the last reference to - * the region goes away, in which case the underlying - * OS region code requires callers be prepared to - * create the region in order to join it. - */ - memset(®info, 0, sizeof(reginfo)); - reginfo.id = rp->id; - reginfo.flags = REGION_CREATE_OK; - - /* - * If we get here and can't attach and/or detach to the - * region, it's a mess. Ignore errors, there's nothing - * we can do about them. - */ - if (__db_r_attach(dbenv, ®info, 0) != 0) - continue; - -#ifdef HAVE_MUTEX_SYSTEM_RESOURCES - /* - * If destroying the mutex region, return any system - * resources to the system. - */ - if (reginfo.type == REGION_TYPE_MUTEX) - __mutex_resource_return(dbenv, ®info); -#endif - (void)__db_r_detach(dbenv, ®info, 1); - } - - /* Destroy the environment's region. */ - (void)__db_e_detach(dbenv, 1); - - /* Discard any remaining physical files. */ -remfiles: (void)__db_e_remfile(dbenv); - } else { - /* Unlock the environment. */ - MUTEX_UNLOCK(dbenv, renv->mtx_regenv); - - /* Discard the environment. */ - (void)__db_e_detach(dbenv, 0); - - ret = EBUSY; - } - -done: F_CLR(dbenv, DB_ENV_NOLOCKING | DB_ENV_NOPANIC); - F_SET(dbenv, db_env_reset); - - return (ret); -} - -/* - * __db_e_remfile -- - * Discard any region files in the filesystem. - */ -static int -__db_e_remfile(dbenv) - DB_ENV *dbenv; -{ - int cnt, fcnt, lastrm, ret; - const char *dir; - char saved_char, *p, **names, *path, buf[sizeof(DB_REGION_FMT) + 20]; - - /* Get the full path of a file in the environment. */ - (void)snprintf(buf, sizeof(buf), "%s", DB_REGION_ENV); - if ((ret = __db_appname(dbenv, DB_APP_NONE, buf, 0, NULL, &path)) != 0) - return (ret); - - /* Get the parent directory for the environment. */ - if ((p = __db_rpath(path)) == NULL) { - p = path; - saved_char = *p; - - dir = PATH_DOT; - } else { - saved_char = *p; - *p = '\0'; - - dir = path; - } - - /* Get the list of file names. */ - if ((ret = __os_dirlist(dbenv, dir, &names, &fcnt)) != 0) - __db_err(dbenv, "%s: %s", dir, db_strerror(ret)); - - /* Restore the path, and free it. */ - *p = saved_char; - __os_free(dbenv, path); - - if (ret != 0) - return (ret); - - /* - * Remove files from the region directory. - */ - for (lastrm = -1, cnt = fcnt; --cnt >= 0;) { - /* Skip anything outside our name space. */ - if (strncmp(names[cnt], - DB_REGION_PREFIX, sizeof(DB_REGION_PREFIX) - 1)) - continue; - - /* Skip queue extent files. */ - if (strncmp(names[cnt], "__dbq.", 6) == 0) - continue; - - /* Skip registry files. */ - if (strncmp(names[cnt], "__db.register", 13) == 0) - continue; - - /* Skip replication files. */ - if (strncmp(names[cnt], "__db.rep.", 9) == 0) - continue; - - /* - * Remove the primary environment region last, because it's - * the key to this whole mess. - */ - if (strcmp(names[cnt], DB_REGION_ENV) == 0) { - lastrm = cnt; - continue; - } - - /* Remove the file. */ - if (__db_appname(dbenv, - DB_APP_NONE, names[cnt], 0, NULL, &path) == 0) { - /* - * Overwrite region files. Temporary files would have - * been maintained in encrypted format, so there's no - * reason to overwrite them. This is not an exact - * check on the file being a region file, but it's - * not likely to be wrong, and the worst thing that can - * happen is we overwrite a file that didn't need to be - * overwritten. - */ - if (F_ISSET(dbenv, DB_ENV_OVERWRITE) && - strlen(names[cnt]) == DB_REGION_NAME_LENGTH) - (void)__db_file_multi_write(dbenv, path); - (void)__os_unlink(dbenv, path); - __os_free(dbenv, path); - } - } - - if (lastrm != -1) - if (__db_appname(dbenv, - DB_APP_NONE, names[lastrm], 0, NULL, &path) == 0) { - if (F_ISSET(dbenv, DB_ENV_OVERWRITE)) - (void)__db_file_multi_write(dbenv, path); - (void)__os_unlink(dbenv, path); - __os_free(dbenv, path); - } - __os_dirfree(dbenv, names, fcnt); - - return (0); -} - -/* - * __db_r_attach - * Join/create a region. - * - * PUBLIC: int __db_r_attach __P((DB_ENV *, REGINFO *, size_t)); - */ -int -__db_r_attach(dbenv, infop, size) - DB_ENV *dbenv; - REGINFO *infop; - size_t size; -{ - REGION *rp; - int ret; - char buf[sizeof(DB_REGION_FMT) + 20]; - - /* - * Find or create a REGION structure for this region. If we create - * it, the REGION_CREATE flag will be set in the infop structure. - */ - F_CLR(infop, REGION_CREATE); - if ((ret = __db_des_get(dbenv, dbenv->reginfo, infop, &rp)) != 0) - return (ret); - infop->dbenv = dbenv; - infop->rp = rp; - infop->type = rp->type; - infop->id = rp->id; - - /* - * __db_des_get may have created the region and reset the create - * flag. If we're creating the region, set the desired size. - */ - if (F_ISSET(infop, REGION_CREATE)) - rp->size = (roff_t)size; - - /* Join/create the underlying region. */ - (void)snprintf(buf, sizeof(buf), DB_REGION_FMT, infop->id); - if ((ret = __db_appname(dbenv, - DB_APP_NONE, buf, 0, NULL, &infop->name)) != 0) - goto err; - if ((ret = __os_r_attach(dbenv, infop, rp)) != 0) - goto err; - - /* - * Fault the pages into memory. Note, do this BEFORE we initialize - * anything because we're writing pages in created regions, not just - * reading them. - */ - (void)__db_faultmem(dbenv, - infop->addr, rp->size, F_ISSET(infop, REGION_CREATE)); - - /* - * !!! - * The underlying layer may have just decided that we are going - * to create the region. There are various system issues that - * can result in a useless region that requires re-initialization. - * - * If we created the region, initialize it for allocation. - */ - if (F_ISSET(infop, REGION_CREATE)) - __db_shalloc_init(infop, rp->size); - - return (0); - -err: /* Discard the underlying region. */ - if (infop->addr != NULL) - (void)__os_r_detach(dbenv, - infop, F_ISSET(infop, REGION_CREATE)); - infop->rp = NULL; - infop->id = INVALID_REGION_ID; - - /* Discard the REGION structure if we created it. */ - if (F_ISSET(infop, REGION_CREATE)) { - __db_des_destroy(dbenv, rp); - F_CLR(infop, REGION_CREATE); - } - - return (ret); -} - -/* - * __db_r_detach -- - * Detach from a region. - * - * PUBLIC: int __db_r_detach __P((DB_ENV *, REGINFO *, int)); - */ -int -__db_r_detach(dbenv, infop, destroy) - DB_ENV *dbenv; - REGINFO *infop; - int destroy; -{ - REGION *rp; - int ret; - - rp = infop->rp; - if (F_ISSET(dbenv, DB_ENV_PRIVATE)) - destroy = 1; - - /* - * When discarding the regions as we shut down a database environment, - * discard any allocated shared memory segments. This is the last time - * we use them, and db_region_destroy is the last region-specific call - * we make. - */ - if (F_ISSET(dbenv, DB_ENV_PRIVATE) && infop->primary != NULL) - __db_shalloc_free(infop, infop->primary); - - /* Detach from the underlying OS region. */ - ret = __os_r_detach(dbenv, infop, destroy); - - /* If we destroyed the region, discard the REGION structure. */ - if (destroy) - __db_des_destroy(dbenv, rp); - - /* Destroy the structure. */ - if (infop->name != NULL) - __os_free(dbenv, infop->name); - - return (ret); -} - -/* - * __db_des_get -- - * Return a reference to the shared information for a REGION, - * optionally creating a new entry. - */ -static int -__db_des_get(dbenv, env_infop, infop, rpp) - DB_ENV *dbenv; - REGINFO *env_infop, *infop; - REGION **rpp; -{ - REGENV *renv; - REGION *rp, *empty_slot, *first_type; - u_int32_t i, maxid; - - *rpp = NULL; - renv = env_infop->primary; - - /* - * If the caller wants to join a region, walk through the existing - * regions looking for a matching ID (if ID specified) or matching - * type (if type specified). If we return based on a matching type - * return the "primary" region, that is, the first region that was - * created of this type. - * - * Track the first empty slot and maximum region ID for new region - * allocation. - * - * MaxID starts at REGION_ID_ENV, the ID of the primary environment. - */ - maxid = REGION_ID_ENV; - empty_slot = first_type = NULL; - for (rp = R_ADDR(env_infop, renv->region_off), - i = 0; i < renv->region_cnt; ++i, ++rp) { - if (rp->id == INVALID_REGION_ID) { - if (empty_slot == NULL) - empty_slot = rp; - continue; - } - if (infop->id != INVALID_REGION_ID) { - if (infop->id == rp->id) - break; - continue; - } - if (infop->type == rp->type && - F_ISSET(infop, REGION_JOIN_OK) && - (first_type == NULL || first_type->id > rp->id)) - first_type = rp; - - if (rp->id > maxid) - maxid = rp->id; - } - - /* If we found a matching ID (or a matching type), return it. */ - if (i >= renv->region_cnt) - rp = first_type; - if (rp != NULL) { - *rpp = rp; - return (0); - } - - /* - * If we didn't find a region and we don't have permission to create - * the region, fail. The caller generates any error message. - */ - if (!F_ISSET(infop, REGION_CREATE_OK)) - return (ENOENT); - - /* - * If we didn't find a region and don't have room to create the region - * fail with an error message, there's a sizing problem. - */ - if (empty_slot == NULL) { - __db_err(dbenv, "no room remaining for additional REGIONs"); - return (ENOENT); - } - - /* - * Initialize a REGION structure for the caller. If id was set, use - * that value, otherwise we use the next available ID. - */ - memset(empty_slot, 0, sizeof(REGION)); - empty_slot->segid = INVALID_REGION_SEGID; - - /* - * Set the type and ID; if no region ID was specified, - * allocate one. - */ - empty_slot->type = infop->type; - empty_slot->id = infop->id == INVALID_REGION_ID ? maxid + 1 : infop->id; - - F_SET(infop, REGION_CREATE); - - *rpp = empty_slot; - return (0); -} - -/* - * __db_des_destroy -- - * Destroy a reference to a REGION. - */ -static void -__db_des_destroy(dbenv, rp) - DB_ENV *dbenv; - REGION *rp; -{ - COMPQUIET(dbenv, NULL); - - rp->id = INVALID_REGION_ID; -} - -/* - * __db_faultmem -- - * Fault the region into memory. - */ -static int -__db_faultmem(dbenv, addr, size, created) - DB_ENV *dbenv; - void *addr; - size_t size; - int created; -{ - int ret; - u_int8_t *p, *t; - - /* Ignore heap regions. */ - if (F_ISSET(dbenv, DB_ENV_PRIVATE)) - return (0); - - /* - * It's sometimes significantly faster to page-fault in all of the - * region's pages before we run the application, as we see nasty - * side-effects when we page-fault while holding various locks, i.e., - * the lock takes a long time to acquire because of the underlying - * page fault, and the other threads convoy behind the lock holder. - * - * If we created the region, we write a non-zero value so that the - * system can't cheat. If we're just joining the region, we can - * only read the value and try to confuse the compiler sufficiently - * that it doesn't figure out that we're never really using it. - * - * Touch every page (assuming pages are 512B, the smallest VM page - * size used in any general purpose processor). - */ - ret = 0; - if (F_ISSET(dbenv, DB_ENV_REGION_INIT)) { - if (created) - for (p = addr, - t = (u_int8_t *)addr + size; p < t; p += 512) - p[0] = 0xdb; - else - for (p = addr, - t = (u_int8_t *)addr + size; p < t; p += 512) - ret |= p[0]; - } - - return (ret); -} diff --git a/storage/bdb/env/env_register.c b/storage/bdb/env/env_register.c deleted file mode 100644 index a5001d2e5f1..00000000000 --- a/storage/bdb/env/env_register.c +++ /dev/null @@ -1,421 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2004-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: env_register.c,v 1.15 2005/10/07 20:21:27 ubell Exp $ - */ -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" - -#define REGISTER_FILE "__db.register" - -#define PID_EMPTY "X%23lu\n" /* An unused PID entry. */ -#define PID_FMT "%24lu\n" /* File PID format. */ -#define PID_ISEMPTY(p) (p[0] == 'X') -#define PID_LEN 25 /* Length of PID line. */ - -#define REGISTRY_LOCK(dbenv, pos, nowait) \ - __os_fdlock(dbenv, (dbenv)->registry, (off_t)(pos), 1, nowait) -#define REGISTRY_UNLOCK(dbenv, pos) \ - __os_fdlock(dbenv, (dbenv)->registry, (off_t)(pos), 0, 0) -#define REGISTRY_EXCL_LOCK(dbenv, nowait) \ - REGISTRY_LOCK(dbenv, 1, nowait) -#define REGISTRY_EXCL_UNLOCK(dbenv) \ - REGISTRY_UNLOCK(dbenv, 1) - -static int __envreg_add __P((DB_ENV *, int *)); - -/* - * Support for portable, multi-process database environment locking, based on - * the Subversion SR (#11511). - * - * The registry feature is configured by specifying the DB_REGISTER flag to the - * DbEnv.open method. If DB_REGISTER is specified, DB opens the registry file - * in the database environment home directory. The registry file is formatted - * as follows: - * - * 12345 # process ID slot 1 - * X # empty slot - * 12346 # process ID slot 2 - * X # empty slot - * 12347 # process ID slot 3 - * 12348 # process ID slot 4 - * X 12349 # empty slot - * X # empty slot - * - * All lines are fixed-length. All lines are process ID slots. Empty slots - * are marked with leading non-digit characters. - * - * To modify the file, you get an exclusive lock on the first byte of the file. - * - * While holding any DbEnv handle, each process has an exclusive lock on the - * first byte of a process ID slot. There is a restriction on having more - * than one DbEnv handle open at a time, because Berkeley DB uses per-process - * locking to implement this feature, that is, a process may never have more - * than a single slot locked. - * - * This work requires that if a process dies or the system crashes, locks held - * by the dying processes will be dropped. (We can't use system shared - * memory-backed or filesystem-backed locks because they're persistent when a - * process dies.) On POSIX systems, we use fcntl(2) locks; on Win32 we have - * LockFileEx/UnlockFile, except for Win/9X and Win/ME which have to loop on - * Lockfile/UnlockFile. - * - * We could implement the same solution with flock locking instead of fcntl, - * but flock would require a separate file for each process of control (and - * probably each DbEnv handle) in the database environment, which is fairly - * ugly. - * - * Whenever a process opens a new DbEnv handle, it walks the registry file and - * verifies it CANNOT acquire the lock for any non-empty slot. If a lock for - * a non-empty slot is available, we know a process died holding an open handle, - * and recovery needs to be run. - * - * There can still be processes running in the environment when we recover it, - * and, in fact, there can still be processes running in the old environment - * after we're up and running in a new one. This is safe because performing - * recovery panics (and removes) the existing environment, so the window of - * vulnerability is small. Further, we check the panic flag in the DB API - * methods, when waking from spinning on a mutex, and whenever we're about to - * write to disk). The only window of corruption is if the write check of the - * panic were to complete, the region subsequently be recovered, and then the - * write continues. That's very, very unlikely to happen. This vulnerability - * already exists in Berkeley DB, too, the registry code doesn't make it any - * worse than it already is. - */ -/* - * __envreg_register -- - * Register a DB_ENV handle. - * - * PUBLIC: int __envreg_register __P((DB_ENV *, const char *, int *)); - */ -int -__envreg_register(dbenv, db_home, need_recoveryp) - DB_ENV *dbenv; - const char *db_home; - int *need_recoveryp; -{ - pid_t pid; - db_threadid_t tid; - u_int32_t bytes, mbytes; - int ret; - char path[MAXPATHLEN]; - - *need_recoveryp = 0; - dbenv->thread_id(dbenv, &pid, &tid); - - if (FLD_ISSET(dbenv->verbose, DB_VERB_REGISTER)) - __db_msg(dbenv, "%lu: register environment", (u_long)pid); - - /* Build the path name and open the registry file. */ - (void)snprintf(path, sizeof(path), "%s/%s", db_home, REGISTER_FILE); - if ((ret = __os_open(dbenv, path, - DB_OSO_CREATE, __db_omode("rw-rw----"), &dbenv->registry)) != 0) - goto err; - - /* - * Wait for an exclusive lock on the file. - * - * !!! - * We're locking bytes that don't yet exist, but that's OK as far as - * I know. - */ - if ((ret = REGISTRY_EXCL_LOCK(dbenv, 0)) != 0) - goto err; - - /* - * If the file size is 0, initialize the file. - * - * Run recovery if we create the file, that means we can clean up the - * system by removing the registry file and restarting the application. - */ - if ((ret = __os_ioinfo( - dbenv, path, dbenv->registry, &mbytes, &bytes, NULL)) != 0) - goto err; - if (mbytes == 0 && bytes == 0) { - if (FLD_ISSET(dbenv->verbose, DB_VERB_REGISTER)) - __db_msg(dbenv, - "%lu: creating %s", (u_long)pid, path); - *need_recoveryp = 1; - } - - /* Register this process. */ - if ((ret = __envreg_add(dbenv, need_recoveryp)) != 0) - goto err; - - /* - * Release our exclusive lock if we don't need to run recovery. If - * we need to run recovery, DB_ENV->open will call back into register - * code once recovery has completed. - */ - if (*need_recoveryp == 0 && (ret = REGISTRY_EXCL_UNLOCK(dbenv)) != 0) - goto err; - - if (0) { -err: *need_recoveryp = 0; - - /* - * !!! - * Closing the file handle must release all of our locks. - */ - (void)__os_closehandle(dbenv, dbenv->registry); - dbenv->registry = NULL; - } - - return (ret); -} - -/* - * __envreg_add -- - * Add the process' pid to the register. - */ -static int -__envreg_add(dbenv, need_recoveryp) - DB_ENV *dbenv; - int *need_recoveryp; -{ - pid_t pid; - db_threadid_t tid; - off_t end, pos; - size_t nr, nw; - u_int lcnt; - u_int32_t bytes, mbytes; - int need_recovery, ret; - char *p, buf[256], pid_buf[256]; - - need_recovery = 0; - COMPQUIET(p, NULL); - - /* Get a copy of our process ID. */ - dbenv->thread_id(dbenv, &pid, &tid); - snprintf(pid_buf, sizeof(pid_buf), PID_FMT, (u_long)pid); - - if (FLD_ISSET(dbenv->verbose, DB_VERB_REGISTER)) - __db_msg(dbenv, "===== %lu: before add", (u_long)pid); - - /* - * Read the file. Skip empty slots, and check that a lock is held - * for any allocated slots. An allocated slot which we can lock - * indicates a process died holding a handle and recovery needs to - * be run. - */ - for (lcnt = 0;; ++lcnt) { - if ((ret = __os_read( - dbenv, dbenv->registry, buf, PID_LEN, &nr)) != 0) - return (ret); - if (nr == 0) - break; - if (nr != PID_LEN) - goto corrupt; - - if (FLD_ISSET( - dbenv->verbose, DB_VERB_REGISTER) && PID_ISEMPTY(buf)) { - __db_msg(dbenv, "%02u: EMPTY", lcnt); - continue; - } - - /* - * !!! - * DB_REGISTER is implemented using per-process locking, only - * a single DB_ENV handle may be open per process. Enforce - * that restriction. - */ - if (memcmp(buf, pid_buf, PID_LEN) == 0) { - __db_err(dbenv, - "DB_REGISTER limits each process to a single open DB_ENV handle"); - return (EINVAL); - } - - if (FLD_ISSET(dbenv->verbose, DB_VERB_REGISTER)) { - for (p = buf; *p == ' ';) - ++p; - buf[nr - 1] = '\0'; - } - - pos = (off_t)lcnt * PID_LEN; - if (REGISTRY_LOCK(dbenv, pos, 1) == 0) { - if ((ret = REGISTRY_UNLOCK(dbenv, pos)) != 0) - return (ret); - - if (FLD_ISSET(dbenv->verbose, DB_VERB_REGISTER)) - __db_msg(dbenv, "%02u: %s: FAILED", lcnt, p); - - need_recovery = 1; - break; - } else - if (FLD_ISSET(dbenv->verbose, DB_VERB_REGISTER)) - __db_msg(dbenv, "%02u: %s: LOCKED", lcnt, p); - } - - /* - * If we have to perform recovery... - * - * Mark all slots empty. Registry ignores empty slots we can't lock, - * so it doesn't matter if any of the processes are in the middle of - * exiting Berkeley DB -- they'll discard their lock when they exit. - */ - if (need_recovery) { - /* Figure out how big the file is. */ - if ((ret = __os_ioinfo( - dbenv, NULL, dbenv->registry, &mbytes, &bytes, NULL)) != 0) - return (ret); - end = (off_t)mbytes * MEGABYTE + bytes; - - /* Confirm the file is of a reasonable size. */ - DB_ASSERT(end % PID_LEN == 0); - - /* - * Seek to the beginning of the file and overwrite slots to - * the end of the file. - */ - if ((ret = __os_seek( - dbenv, dbenv->registry, 0, 0, 0, 0, DB_OS_SEEK_SET)) != 0) - return (ret); - snprintf(buf, sizeof(buf), PID_EMPTY, (u_long)0); - for (lcnt = (u_int)end / PID_LEN; lcnt > 0; --lcnt) - if ((ret = __os_write( - dbenv, dbenv->registry, buf, PID_LEN, &nw)) != 0 || - nw != PID_LEN) - goto corrupt; - } - - /* - * Seek to the first process slot and add ourselves to the first empty - * slot we can lock. - */ - if ((ret = __os_seek( - dbenv, dbenv->registry, 0, 0, 0, 0, DB_OS_SEEK_SET)) != 0) - return (ret); - for (lcnt = 0;; ++lcnt) { - if ((ret = __os_read( - dbenv, dbenv->registry, buf, PID_LEN, &nr)) != 0) - return (ret); - if (nr == PID_LEN && !PID_ISEMPTY(buf)) - continue; - pos = (off_t)lcnt * PID_LEN; - if (REGISTRY_LOCK(dbenv, pos, 1) == 0) { - if (FLD_ISSET(dbenv->verbose, DB_VERB_REGISTER)) - __db_msg(dbenv, - "%lu: locking slot %02u at offset %lu", - (u_long)pid, lcnt, (u_long)pos); - - if ((ret = __os_seek(dbenv, dbenv->registry, - 0, 0, (u_int32_t)pos, 0, DB_OS_SEEK_SET)) != 0 || - (ret = __os_write(dbenv, - dbenv->registry, pid_buf, PID_LEN, &nw)) != 0 || - nw != PID_LEN) - return (ret); - dbenv->registry_off = (u_int32_t)pos; - break; - } - } - - if (need_recovery) - *need_recoveryp = 1; - - if (0) { -corrupt: __db_err(dbenv, "%s: file contents corrupted", REGISTER_FILE); - return (ret == 0 ? EACCES : ret); - } - - return (ret); -} - -/* - * __envreg_unregister -- - * Unregister a DB_ENV handle. - * - * PUBLIC: int __envreg_unregister __P((DB_ENV *, int)); - */ -int -__envreg_unregister(dbenv, recovery_failed) - DB_ENV *dbenv; - int recovery_failed; -{ - size_t nw; - int ret, t_ret; - char buf[256]; - - ret = 0; - - /* - * If recovery failed, we want to drop our locks and return, but still - * make sure any subsequent process doesn't decide everything is just - * fine and try to get into the database environment. In the case of - * an error, discard our locks, but leave our slot filled-in. - */ - if (recovery_failed) - goto err; - - /* - * Why isn't an exclusive lock necessary to discard a DB_ENV handle? - * - * We mark our process ID slot empty before we discard the process slot - * lock, and threads of control reviewing the register file ignore any - * slots which they can't lock. - */ - snprintf(buf, sizeof(buf), PID_EMPTY, (u_long)0); - if ((ret = __os_seek(dbenv, dbenv->registry, - 0, 0, dbenv->registry_off, 0, DB_OS_SEEK_SET)) != 0 || - (ret = __os_write( - dbenv, dbenv->registry, buf, PID_LEN, &nw)) != 0 || - nw != PID_LEN) - goto err; - - /* - * !!! - * This code assumes that closing the file descriptor discards all - * held locks. - * - * !!! - * There is an ordering problem here -- in the case of a process that - * failed in recovery, we're unlocking both the exclusive lock and our - * slot lock. If the OS unlocked the exclusive lock and then allowed - * another thread of control to acquire the exclusive lock before also - * also releasing our slot lock, we could race. That can't happen, I - * don't think. - */ -err: if ((t_ret = - __os_closehandle(dbenv, dbenv->registry)) != 0 && ret == 0) - ret = t_ret; - - dbenv->registry = NULL; - return (ret); -} - -/* - * __envreg_xunlock -- - * Discard the exclusive lock held by the DB_ENV handle. - * - * PUBLIC: int __envreg_xunlock __P((DB_ENV *)); - */ -int -__envreg_xunlock(dbenv) - DB_ENV *dbenv; -{ - pid_t pid; - db_threadid_t tid; - int ret; - - dbenv->thread_id(dbenv, &pid, &tid); - - if (FLD_ISSET(dbenv->verbose, DB_VERB_REGISTER)) - __db_msg(dbenv, - "%lu: recovery completed, unlocking", (u_long)pid); - - if ((ret = REGISTRY_EXCL_UNLOCK(dbenv)) == 0) - return (ret); - - __db_err(dbenv, - "%s: exclusive file unlock: %s", REGISTER_FILE, db_strerror(ret)); - return (__db_panic(dbenv, ret)); -} diff --git a/storage/bdb/env/env_stat.c b/storage/bdb/env/env_stat.c deleted file mode 100644 index 57130773fa7..00000000000 --- a/storage/bdb/env/env_stat.c +++ /dev/null @@ -1,651 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: env_stat.c,v 12.23 2005/11/01 00:44:25 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#include "string.h" - -#if TIME_WITH_SYS_TIME -#include <sys/time.h> -#include <time.h> -#else -#if HAVE_SYS_TIME_H -#include <sys/time.h> -#else -#include <time.h> -#endif -#endif -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/db_am.h" -#include "dbinc/lock.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" -#include "dbinc/txn.h" - -#ifdef HAVE_STATISTICS -static int __env_print_all __P((DB_ENV *, u_int32_t)); -static int __env_print_stats __P((DB_ENV *, u_int32_t)); -static int __env_print_threads __P((DB_ENV *)); -static int __env_stat_print __P((DB_ENV *, u_int32_t)); -static char *__env_thread_state_print __P((DB_THREAD_STATE)); -static const char * - __reg_type __P((reg_type_t)); - -/* - * __env_stat_print_pp -- - * DB_ENV->stat_print pre/post processor. - * - * PUBLIC: int __env_stat_print_pp __P((DB_ENV *, u_int32_t)); - */ -int -__env_stat_print_pp(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - DB_THREAD_INFO *ip; - int ret; - - PANIC_CHECK(dbenv); - ENV_ILLEGAL_BEFORE_OPEN(dbenv, "DB_ENV->stat_print"); - - if ((ret = __db_fchk(dbenv, "DB_ENV->stat_print", - flags, DB_STAT_ALL | DB_STAT_CLEAR | DB_STAT_SUBSYSTEM)) != 0) - return (ret); - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, (__env_stat_print(dbenv, flags)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __env_stat_print -- - * DB_ENV->stat_print method. - */ -static int -__env_stat_print(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - time_t now; - int ret; - - (void)time(&now); - __db_msg(dbenv, "%.24s\tLocal time", ctime(&now)); - - if ((ret = __env_print_stats(dbenv, flags)) != 0) - return (ret); - - if (LF_ISSET(DB_STAT_ALL) && - (ret = __env_print_all(dbenv, flags)) != 0) - return (ret); - - if ((ret = __env_print_threads(dbenv)) != 0) - return (ret); - - if (!LF_ISSET(DB_STAT_SUBSYSTEM)) - return (0); - - /* The subsystems don't know anything about DB_STAT_SUBSYSTEM. */ - LF_CLR(DB_STAT_SUBSYSTEM); - - if (MUTEX_ON(dbenv)) { - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - if ((ret = __mutex_stat_print(dbenv, flags)) != 0) - return (ret); - } - - if (LOGGING_ON(dbenv)) { - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - if ((ret = __log_stat_print(dbenv, flags)) != 0) - return (ret); - - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - if ((ret = __dbreg_stat_print(dbenv, flags)) != 0) - return (ret); - } - - if (LOCKING_ON(dbenv)) { - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - if ((ret = __lock_stat_print(dbenv, flags)) != 0) - return (ret); - } - - if (MPOOL_ON(dbenv)) { - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - if ((ret = __memp_stat_print(dbenv, flags)) != 0) - return (ret); - } - - if (REP_ON(dbenv)) { - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - if ((ret = __rep_stat_print(dbenv, flags)) != 0) - return (ret); - } - - if (TXN_ON(dbenv)) { - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - if ((ret = __txn_stat_print(dbenv, flags)) != 0) - return (ret); - } - - return (0); -} - -/* - * __env_print_stats -- - * Display the default environment statistics. - * - */ -static int -__env_print_stats(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - REGENV *renv; - REGINFO *infop; - - infop = dbenv->reginfo; - renv = infop->primary; - - if (LF_ISSET(DB_STAT_ALL)) { - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_msg(dbenv, "Default database environment information:"); - } - STAT_HEX("Magic number", renv->magic); - STAT_LONG("Panic value", renv->panic); - __db_msg(dbenv, "%d.%d.%d\tEnvironment version", - renv->majver, renv->minver, renv->patchver); - __db_msg(dbenv, "%.24s\tCreation time", ctime(&renv->timestamp)); - STAT_HEX("Environment ID", renv->envid); - __mutex_print_debug_single(dbenv, - "Primary region allocation and reference count mutex", - renv->mtx_regenv, flags); - STAT_LONG("References", renv->refcnt); - - return (0); -} - -/* - * __env_print_all -- - * Display the debugging environment statistics. - */ -static int -__env_print_all(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - static const FN fn[] = { - { DB_ENV_AUTO_COMMIT, "DB_ENV_AUTO_COMMIT" }, - { DB_ENV_CDB, "DB_ENV_CDB" }, - { DB_ENV_CDB_ALLDB, "DB_ENV_CDB_ALLDB" }, - { DB_ENV_CREATE, "DB_ENV_CREATE" }, - { DB_ENV_DBLOCAL, "DB_ENV_DBLOCAL" }, - { DB_ENV_DIRECT_DB, "DB_ENV_DIRECT_DB" }, - { DB_ENV_DIRECT_LOG, "DB_ENV_DIRECT_LOG" }, - { DB_ENV_DSYNC_DB, "DB_ENV_DSYNC_DB" }, - { DB_ENV_DSYNC_LOG, "DB_ENV_DSYNC_LOG" }, - { DB_ENV_FATAL, "DB_ENV_FATAL" }, - { DB_ENV_LOCKDOWN, "DB_ENV_LOCKDOWN" }, - { DB_ENV_LOG_AUTOREMOVE, "DB_ENV_LOG_AUTOREMOVE" }, - { DB_ENV_LOG_INMEMORY, "DB_ENV_LOG_INMEMORY" }, - { DB_ENV_NOLOCKING, "DB_ENV_NOLOCKING" }, - { DB_ENV_NOMMAP, "DB_ENV_NOMMAP" }, - { DB_ENV_NOPANIC, "DB_ENV_NOPANIC" }, - { DB_ENV_OPEN_CALLED, "DB_ENV_OPEN_CALLED" }, - { DB_ENV_OVERWRITE, "DB_ENV_OVERWRITE" }, - { DB_ENV_PRIVATE, "DB_ENV_PRIVATE" }, - { DB_ENV_REGION_INIT, "DB_ENV_REGION_INIT" }, - { DB_ENV_RPCCLIENT, "DB_ENV_RPCCLIENT" }, - { DB_ENV_RPCCLIENT_GIVEN, "DB_ENV_RPCCLIENT_GIVEN" }, - { DB_ENV_SYSTEM_MEM, "DB_ENV_SYSTEM_MEM" }, - { DB_ENV_THREAD, "DB_ENV_THREAD" }, - { DB_ENV_TIME_NOTGRANTED, "DB_ENV_TIME_NOTGRANTED" }, - { DB_ENV_TXN_NOSYNC, "DB_ENV_TXN_NOSYNC" }, - { DB_ENV_TXN_WRITE_NOSYNC, "DB_ENV_TXN_WRITE_NOSYNC" }, - { DB_ENV_YIELDCPU, "DB_ENV_YIELDCPU" }, - { 0, NULL } - }; - static const FN ofn[] = { - { DB_CREATE, "DB_CREATE" }, - { DB_FORCE, "DB_FORCE" }, - { DB_INIT_CDB, "DB_INIT_CDB" }, - { DB_INIT_LOCK, "DB_INIT_LOCK" }, - { DB_INIT_LOG, "DB_INIT_LOG" }, - { DB_INIT_MPOOL, "DB_INIT_MPOOL" }, - { DB_INIT_REP, "DB_INIT_REP" }, - { DB_INIT_TXN, "DB_INIT_TXN" }, - { DB_LOCKDOWN, "DB_LOCKDOWN" }, - { DB_NOMMAP, "DB_NOMMAP" }, - { DB_PRIVATE, "DB_PRIVATE" }, - { DB_RDONLY, "DB_RDONLY" }, - { DB_RECOVER, "DB_RECOVER" }, - { DB_RECOVER_FATAL, "DB_RECOVER_FATAL" }, - { DB_SYSTEM_MEM, "DB_SYSTEM_MEM" }, - { DB_THREAD, "DB_THREAD" }, - { DB_TRUNCATE, "DB_TRUNCATE" }, - { DB_TXN_NOSYNC, "DB_TXN_NOSYNC" }, - { DB_USE_ENVIRON, "DB_USE_ENVIRON" }, - { DB_USE_ENVIRON_ROOT, "DB_USE_ENVIRON_ROOT" }, - { 0, NULL } - }; - static const FN vfn[] = { - { DB_VERB_DEADLOCK, "DB_VERB_DEADLOCK" }, - { DB_VERB_RECOVERY, "DB_VERB_RECOVERY" }, - { DB_VERB_REGISTER, "DB_VERB_REGISTER" }, - { DB_VERB_REPLICATION, "DB_VERB_REPLICATION" }, - { DB_VERB_WAITSFOR, "DB_VERB_WAITSFOR" }, - { 0, NULL } - }; - static const FN regenvfn[] = { - { DB_REGENV_REPLOCKED, "DB_REGENV_REPLOCKED" }, - { 0, NULL } - }; - DB_MSGBUF mb; - REGENV *renv; - REGINFO *infop; - REGION *rp; - u_int32_t i; - char **p; - - infop = dbenv->reginfo; - renv = infop->primary; - DB_MSGBUF_INIT(&mb); - - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_prflags(dbenv, - NULL, renv->init_flags, ofn, NULL, "\tInitialization flags"); - STAT_ULONG("Region slots", renv->region_cnt); - __db_prflags(dbenv, - NULL, renv->flags, regenvfn, NULL, "\tReplication flags"); - __db_msg(dbenv, "%.24s\tOperation timestamp", - renv->op_timestamp == 0 ? "!Set" : ctime(&renv->op_timestamp)); - __db_msg(dbenv, "%.24s\tReplication timestamp", - renv->rep_timestamp == 0 ? "!Set" : ctime(&renv->rep_timestamp)); - - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_msg(dbenv, "Per region database environment information:"); - for (rp = R_ADDR(infop, renv->region_off), - i = 0; i < renv->region_cnt; ++i, ++rp) { - if (rp->id == INVALID_REGION_ID) - continue; - __db_msg(dbenv, "%s Region:", __reg_type(rp->type)); - STAT_LONG("Region ID", rp->id); - STAT_LONG("Segment ID", rp->segid); - __db_dlbytes(dbenv, - "Size", (u_long)0, (u_long)0, (u_long)rp->size); - } - - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_msg(dbenv, "DB_ENV handle information:"); - STAT_ISSET("Errfile", dbenv->db_errfile); - STAT_STRING("Errpfx", dbenv->db_errpfx); - STAT_ISSET("Errcall", dbenv->db_errcall); - STAT_ISSET("Feedback", dbenv->db_feedback); - STAT_ISSET("Panic", dbenv->db_paniccall); - STAT_ISSET("Malloc", dbenv->db_malloc); - STAT_ISSET("Realloc", dbenv->db_realloc); - STAT_ISSET("Free", dbenv->db_free); - __db_prflags(dbenv, NULL, dbenv->verbose, vfn, NULL, "\tVerbose flags"); - - STAT_ISSET("App private", dbenv->app_private); - STAT_ISSET("App dispatch", dbenv->app_dispatch); - STAT_STRING("Home", dbenv->db_home); - STAT_STRING("Log dir", dbenv->db_log_dir); - STAT_STRING("Tmp dir", dbenv->db_tmp_dir); - if (dbenv->db_data_dir == NULL) - STAT_ISSET("Data dir", dbenv->db_data_dir); - else { - for (p = dbenv->db_data_dir; *p != NULL; ++p) - __db_msgadd(dbenv, &mb, "%s\tData dir", *p); - DB_MSGBUF_FLUSH(dbenv, &mb); - } - STAT_FMT("Mode", "%#o", int, dbenv->db_mode); - __db_prflags(dbenv, NULL, dbenv->open_flags, ofn, NULL, "\tOpen flags"); - STAT_ISSET("Lockfhp", dbenv->lockfhp); - STAT_ISSET("Recovery table", dbenv->recover_dtab); - STAT_ULONG("Number of recovery table slots", dbenv->recover_dtab_size); - STAT_ISSET("RPC client", dbenv->cl_handle); - STAT_LONG("RPC client ID", dbenv->cl_id); - STAT_LONG("DB reference count", dbenv->db_ref); - STAT_LONG("Shared memory key", dbenv->shm_key); - __mutex_print_debug_single( - dbenv, "DB handle mutex", dbenv->mtx_dblist, flags); - - STAT_ISSET("api1 internal", dbenv->api1_internal); - STAT_ISSET("api2 internal", dbenv->api2_internal); - STAT_ISSET("password", dbenv->passwd); - STAT_ISSET("crypto handle", dbenv->crypto_handle); - __mutex_print_debug_single(dbenv, "MT mutex", dbenv->mtx_mt, flags); - - __db_prflags(dbenv, NULL, dbenv->flags, fn, NULL, "\tFlags"); - - return (0); -} - -static char * -__env_thread_state_print(state) - DB_THREAD_STATE state; -{ - switch (state) { - case THREAD_ACTIVE: - return ("active"); - case THREAD_BLOCKED: - return ("blocked"); - case THREAD_OUT: - return ("out"); - default: - return ("unknown"); - } -} - -/* - * __env_print_threads -- - * Display the current active threads - * - */ -static int -__env_print_threads(dbenv) - DB_ENV *dbenv; -{ - DB_HASHTAB *htab; - DB_THREAD_INFO *ip; - u_int32_t i; - char buf[DB_THREADID_STRLEN]; - - htab = (DB_HASHTAB *)dbenv->thr_hashtab; - __db_msg(dbenv, "Thread status blocks:"); - for (i = 0; i < dbenv->thr_nbucket; i++) { - for (ip = SH_TAILQ_FIRST(&htab[i], __db_thread_info); - ip != NULL; - ip = SH_TAILQ_NEXT(ip, dbth_links, __db_thread_info)) { - if (ip->dbth_state == THREAD_SLOT_NOT_IN_USE) - continue; - __db_msg(dbenv, "\tprocess/thread %s: %s", - dbenv->thread_id_string( - dbenv, ip->dbth_pid, ip->dbth_tid, buf), - __env_thread_state_print(ip->dbth_state)); - } - } - return (0); -} - -/* - * __db_print_fh -- - * Print out a file handle. - * - * PUBLIC: void __db_print_fh __P((DB_ENV *, const char *, DB_FH *, u_int32_t)); - */ -void -__db_print_fh(dbenv, tag, fh, flags) - DB_ENV *dbenv; - const char *tag; - DB_FH *fh; - u_int32_t flags; -{ - static const FN fn[] = { - { DB_FH_NOSYNC, "DB_FH_NOSYNC" }, - { DB_FH_OPENED, "DB_FH_OPENED" }, - { DB_FH_UNLINK, "DB_FH_UNLINK" }, - { 0, NULL } - }; - - if (fh == NULL) { - STAT_ISSET(tag, fh); - return; - } - - __mutex_print_debug_single( - dbenv, "file-handle.mutex", fh->mtx_fh, flags); - - STAT_LONG("file-handle.reference count", fh->ref); - STAT_LONG("file-handle.file descriptor", fh->fd); - STAT_STRING("file-handle.file name", fh->name); - - STAT_ULONG("file-handle.page number", fh->pgno); - STAT_ULONG("file-handle.page size", fh->pgsize); - STAT_ULONG("file-handle.page offset", fh->offset); - - __db_prflags(dbenv, NULL, fh->flags, fn, NULL, "\tfile-handle.flags"); -} - -/* - * __db_print_fileid -- - * Print out a file ID. - * - * PUBLIC: void __db_print_fileid __P((DB_ENV *, u_int8_t *, const char *)); - */ -void -__db_print_fileid(dbenv, id, suffix) - DB_ENV *dbenv; - u_int8_t *id; - const char *suffix; -{ - DB_MSGBUF mb; - int i; - - if (id == NULL) { - STAT_ISSET("ID", id); - return; - } - - DB_MSGBUF_INIT(&mb); - for (i = 0; i < DB_FILE_ID_LEN; ++i, ++id) { - __db_msgadd(dbenv, &mb, "%x", (u_int)*id); - if (i < DB_FILE_ID_LEN - 1) - __db_msgadd(dbenv, &mb, " "); - } - if (suffix != NULL) - __db_msgadd(dbenv, &mb, "%s", suffix); - DB_MSGBUF_FLUSH(dbenv, &mb); -} - -/* - * __db_dl -- - * Display a big value. - * - * PUBLIC: void __db_dl __P((DB_ENV *, const char *, u_long)); - */ -void -__db_dl(dbenv, msg, value) - DB_ENV *dbenv; - const char *msg; - u_long value; -{ - /* - * Two formats: if less than 10 million, display as the number, if - * greater than 10 million display as ###M. - */ - if (value < 10000000) - __db_msg(dbenv, "%lu\t%s", value, msg); - else - __db_msg(dbenv, "%luM\t%s (%lu)", value / 1000000, msg, value); -} - -/* - * __db_dl_pct -- - * Display a big value, and related percentage. - * - * PUBLIC: void __db_dl_pct - * PUBLIC: __P((DB_ENV *, const char *, u_long, int, const char *)); - */ -void -__db_dl_pct(dbenv, msg, value, pct, tag) - DB_ENV *dbenv; - const char *msg, *tag; - u_long value; - int pct; -{ - DB_MSGBUF mb; - - DB_MSGBUF_INIT(&mb); - - /* - * Two formats: if less than 10 million, display as the number, if - * greater than 10 million, round it off and display as ###M. - */ - if (value < 10000000) - __db_msgadd(dbenv, &mb, "%lu\t%s", value, msg); - else - __db_msgadd(dbenv, - &mb, "%luM\t%s", (value + 500000) / 1000000, msg); - if (tag == NULL) - __db_msgadd(dbenv, &mb, " (%d%%)", pct); - else - __db_msgadd(dbenv, &mb, " (%d%% %s)", pct, tag); - - DB_MSGBUF_FLUSH(dbenv, &mb); -} - -/* - * __db_dlbytes -- - * Display a big number of bytes. - * - * PUBLIC: void __db_dlbytes - * PUBLIC: __P((DB_ENV *, const char *, u_long, u_long, u_long)); - */ -void -__db_dlbytes(dbenv, msg, gbytes, mbytes, bytes) - DB_ENV *dbenv; - const char *msg; - u_long gbytes, mbytes, bytes; -{ - DB_MSGBUF mb; - const char *sep; - - DB_MSGBUF_INIT(&mb); - - /* Normalize the values. */ - while (bytes >= MEGABYTE) { - ++mbytes; - bytes -= MEGABYTE; - } - while (mbytes >= GIGABYTE / MEGABYTE) { - ++gbytes; - mbytes -= GIGABYTE / MEGABYTE; - } - - if (gbytes == 0 && mbytes == 0 && bytes == 0) - __db_msgadd(dbenv, &mb, "0"); - else { - sep = ""; - if (gbytes > 0) { - __db_msgadd(dbenv, &mb, "%luGB", gbytes); - sep = " "; - } - if (mbytes > 0) { - __db_msgadd(dbenv, &mb, "%s%luMB", sep, mbytes); - sep = " "; - } - if (bytes >= 1024) { - __db_msgadd(dbenv, &mb, "%s%luKB", sep, bytes / 1024); - bytes %= 1024; - sep = " "; - } - if (bytes > 0) - __db_msgadd(dbenv, &mb, "%s%luB", sep, bytes); - } - - __db_msgadd(dbenv, &mb, "\t%s", msg); - - DB_MSGBUF_FLUSH(dbenv, &mb); -} - -/* - * __db_print_reginfo -- - * Print out underlying shared region information. - * - * PUBLIC: void __db_print_reginfo __P((DB_ENV *, REGINFO *, const char *)); - */ -void -__db_print_reginfo(dbenv, infop, s) - DB_ENV *dbenv; - REGINFO *infop; - const char *s; -{ - static const FN fn[] = { - { REGION_CREATE, "REGION_CREATE" }, - { REGION_CREATE_OK, "REGION_CREATE_OK" }, - { REGION_JOIN_OK, "REGION_JOIN_OK" }, - { 0, NULL } - }; - - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_msg(dbenv, "%s REGINFO information:", s); - STAT_STRING("Region type", __reg_type(infop->type)); - STAT_ULONG("Region ID", infop->id); - STAT_STRING("Region name", infop->name); - STAT_POINTER("Original region address", infop->addr_orig); - STAT_POINTER("Region address", infop->addr); - STAT_POINTER("Region primary address", infop->primary); - STAT_ULONG("Region maximum allocation", infop->max_alloc); - STAT_ULONG("Region allocated", infop->max_alloc); - - __db_prflags(dbenv, NULL, infop->flags, fn, NULL, "\tRegion flags"); -} - -/* - * __reg_type -- - * Return the region type string. - */ -static const char * -__reg_type(t) - reg_type_t t; -{ - switch (t) { - case REGION_TYPE_ENV: - return ("Environment"); - case REGION_TYPE_LOCK: - return ("Lock"); - case REGION_TYPE_LOG: - return ("Log"); - case REGION_TYPE_MPOOL: - return ("Mpool"); - case REGION_TYPE_MUTEX: - return ("Mutex"); - case REGION_TYPE_TXN: - return ("Transaction"); - case INVALID_REGION_TYPE: - return ("Invalid"); - } - return ("Unknown"); -} - -#else /* !HAVE_STATISTICS */ - -/* - * __db_stat_not_built -- - * Common error routine when library not built with statistics. - * - * PUBLIC: int __db_stat_not_built __P((DB_ENV *)); - */ -int -__db_stat_not_built(dbenv) - DB_ENV *dbenv; -{ - __db_err(dbenv, "Library build did not include statistics support"); - return (DB_OPNOTSUP); -} - -int -__env_stat_print_pp(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - COMPQUIET(flags, 0); - - return (__db_stat_not_built(dbenv)); -} -#endif diff --git a/storage/bdb/fileops/fileops.src b/storage/bdb/fileops/fileops.src deleted file mode 100644 index 9a1822c94f7..00000000000 --- a/storage/bdb/fileops/fileops.src +++ /dev/null @@ -1,111 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2001-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: fileops.src,v 12.2 2005/06/16 20:22:47 bostic Exp $ - */ - -PREFIX __fop -DBPRIVATE - -INCLUDE #ifndef NO_SYSTEM_INCLUDES -INCLUDE #include <sys/types.h> -INCLUDE -INCLUDE #include <ctype.h> -INCLUDE #include <string.h> -INCLUDE #endif -INCLUDE -INCLUDE #include "db_int.h" -INCLUDE #include "dbinc/crypto.h" -INCLUDE #include "dbinc/db_page.h" -INCLUDE #include "dbinc/db_am.h" -INCLUDE #include "dbinc/log.h" -INCLUDE #include "dbinc/txn.h" -INCLUDE #include "dbinc/fop.h" -INCLUDE - -/* - * create -- create a file system object. - * - * name: name in the file system - * appname: indicates if the name needs to go through __db_appname - * mode: file system mode - */ -BEGIN create 143 -DBT name DBT s -ARG appname u_int32_t lu -ARG mode u_int32_t o -END - -/* - * remove -- remove a file system object. - * - * name: name in the file system - * appname: indicates if the name needs to go through __db_appname - */ -BEGIN remove 144 -DBT name DBT s -DBT fid DBT s -ARG appname u_int32_t lu -END - -/* - * write: log the writing of data into an object. - * - * name: file containing the page. - * appname: indicates if the name needs to go through __db_appname - * pgsize: page size. - * pageno: page number in the file. - * offset: offset on the page. - * page: the actual meta-data page. - * flag: non-0 indicates that this is a tempfile, so we needn't undo - * these modifications (we'll toss the file). - */ -BEGIN write 145 -DBT name DBT s -ARG appname u_int32_t lu -ARG pgsize u_int32_t lu -ARG pageno db_pgno_t lu -ARG offset u_int32_t lu -PGDBT page DBT s -ARG flag u_int32_t lu -END - -/* - * rename: move a file from one name to another. - * The appname value indicates if this is a path name that should be used - * directly (i.e., no interpretation) or if it is a pathname that should - * be interpreted via calls to __db_appname. The fileid is the 20-byte - * DB fileid of the file being renamed. We need to check it on recovery - * so that we don't inadvertently overwrite good files. - */ -BEGIN rename 146 -DBT oldname DBT s -DBT newname DBT s -DBT fileid DBT s -ARG appname u_int32_t lu -END - -/* - * File removal record. This is a DB-level log record that indicates - * we've just completed some form of file removal. The purpose of this - * log record is to logically identify the particular instance of the - * named file so that during recovery, in deciding if we should roll-forward - * a remove or a rename, we can make sure that we don't roll one forward and - * delete or overwrite the wrong file. - * real_fid: The 20-byte unique file identifier of the original file being - * removed. - * tmp_fid: The unique fid of the tmp file that is removed. - * name: The pre- __db_appname name of the file - * child: The transaction that removed or renamed the file. - */ - */ -BEGIN file_remove 141 -DBT real_fid DBT s -DBT tmp_fid DBT s -DBT name DBT s -ARG appname u_int32_t lu -ARG child u_int32_t lx -END diff --git a/storage/bdb/fileops/fop_basic.c b/storage/bdb/fileops/fop_basic.c deleted file mode 100644 index d4202aa36a1..00000000000 --- a/storage/bdb/fileops/fop_basic.c +++ /dev/null @@ -1,302 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2001-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: fop_basic.c,v 12.8 2005/10/12 17:52:16 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <string.h> -#include <sys/types.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/fop.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" -#include "dbinc/txn.h" -#include "dbinc/db_am.h" - -/* - * The transactional guarantees Berkeley DB provides for file - * system level operations (database physical file create, delete, - * rename) are based on our understanding of current file system - * semantics; a system that does not provide these semantics and - * guarantees could be in danger. - * - * First, as in standard database changes, fsync and fdatasync must - * work: when applied to the log file, the records written into the - * log must be transferred to stable storage. - * - * Second, it must not be possible for the log file to be removed - * without previous file system level operations being flushed to - * stable storage. Berkeley DB applications write log records - * describing file system operations into the log, then perform the - * file system operation, then commit the enclosing transaction - * (which flushes the log file to stable storage). Subsequently, - * a database environment checkpoint may make it possible for the - * application to remove the log file containing the record of the - * file system operation. DB's transactional guarantees for file - * system operations require the log file removal not succeed until - * all previous filesystem operations have been flushed to stable - * storage. In other words, the flush of the log file, or the - * removal of the log file, must block until all previous - * filesystem operations have been flushed to stable storage. This - * semantic is not, as far as we know, required by any existing - * standards document, but we have never seen a filesystem where - * it does not apply. - */ - -/* - * __fop_create -- - * Create a (transactionally protected) file system object. This is used - * to create DB files now, potentially blobs, queue extents and anything - * else you wish to store in a file system object. - * - * PUBLIC: int __fop_create __P((DB_ENV *, - * PUBLIC: DB_TXN *, DB_FH **, const char *, APPNAME, int, u_int32_t)); - */ -int -__fop_create(dbenv, txn, fhpp, name, appname, mode, flags) - DB_ENV *dbenv; - DB_TXN *txn; - DB_FH **fhpp; - const char *name; - APPNAME appname; - int mode; - u_int32_t flags; -{ - DB_FH *fhp; - DB_LSN lsn; - DBT data; - int ret; - char *real_name; - - real_name = NULL; - fhp = NULL; - - if ((ret = - __db_appname(dbenv, appname, name, 0, NULL, &real_name)) != 0) - return (ret); - - if (mode == 0) - mode = __db_omode(OWNER_RW); - - if (DBENV_LOGGING(dbenv)) { - memset(&data, 0, sizeof(data)); - data.data = (void *)name; - data.size = (u_int32_t)strlen(name) + 1; - if ((ret = __fop_create_log(dbenv, txn, &lsn, - flags | DB_FLUSH, - &data, (u_int32_t)appname, (u_int32_t)mode)) != 0) - goto err; - } - - DB_ENV_TEST_RECOVERY(dbenv, DB_TEST_POSTLOG, ret, name); - - if (fhpp == NULL) - fhpp = &fhp; - ret = __os_open( - dbenv, real_name, DB_OSO_CREATE | DB_OSO_EXCL, mode, fhpp); - -err: -DB_TEST_RECOVERY_LABEL - if (fhpp == &fhp && fhp != NULL) - (void)__os_closehandle(dbenv, fhp); - if (real_name != NULL) - __os_free(dbenv, real_name); - return (ret); -} - -/* - * __fop_remove -- - * Remove a file system object. - * - * PUBLIC: int __fop_remove __P((DB_ENV *, - * PUBLIC: DB_TXN *, u_int8_t *, const char *, APPNAME, u_int32_t)); - */ -int -__fop_remove(dbenv, txn, fileid, name, appname, flags) - DB_ENV *dbenv; - DB_TXN *txn; - u_int8_t *fileid; - const char *name; - APPNAME appname; - u_int32_t flags; -{ - DB_LSN lsn; - DBT fdbt, ndbt; - char *real_name; - int ret; - - real_name = NULL; - - if ((ret = - __db_appname(dbenv, appname, name, 0, NULL, &real_name)) != 0) - goto err; - - if (txn == NULL) { - if (fileid != NULL && (ret = __memp_nameop( - dbenv, fileid, NULL, real_name, NULL, 0)) != 0) - goto err; - } else { - if (DBENV_LOGGING(dbenv)) { - memset(&fdbt, 0, sizeof(ndbt)); - fdbt.data = fileid; - fdbt.size = fileid == NULL ? 0 : DB_FILE_ID_LEN; - memset(&ndbt, 0, sizeof(ndbt)); - ndbt.data = (void *)name; - ndbt.size = (u_int32_t)strlen(name) + 1; - if ((ret = __fop_remove_log(dbenv, txn, &lsn, - flags, &ndbt, &fdbt, (u_int32_t)appname)) != 0) - goto err; - } - ret = __txn_remevent(dbenv, txn, real_name, fileid, 0); - } - -err: if (real_name != NULL) - __os_free(dbenv, real_name); - return (ret); -} - -/* - * __fop_write - * - * Write "size" bytes from "buf" to file "name" beginning at offset "off." - * If the file is open, supply a handle in fhp. Istmp indicate if this is - * an operation that needs to be undone in the face of failure (i.e., if - * this is a write to a temporary file, we're simply going to remove the - * file, so don't worry about undoing the write). - * - * Currently, we *only* use this with istmp true. If we need more general - * handling, then we'll have to zero out regions on abort (and possibly - * log the before image of the data in the log record). - * - * PUBLIC: int __fop_write __P((DB_ENV *, - * PUBLIC: DB_TXN *, const char *, APPNAME, DB_FH *, u_int32_t, db_pgno_t, - * PUBLIC: u_int32_t, u_int8_t *, u_int32_t, u_int32_t, u_int32_t)); - */ -int -__fop_write(dbenv, - txn, name, appname, fhp, pgsize, pageno, off, buf, size, istmp, flags) - DB_ENV *dbenv; - DB_TXN *txn; - const char *name; - APPNAME appname; - DB_FH *fhp; - u_int32_t pgsize; - db_pgno_t pageno; - u_int32_t off; - u_int8_t *buf; - u_int32_t size, istmp, flags; -{ - DB_LSN lsn; - DBT data, namedbt; - size_t nbytes; - int local_open, ret, t_ret; - char *real_name; - - DB_ASSERT(istmp != 0); - - ret = local_open = 0; - real_name = NULL; - - if ((ret = - __db_appname(dbenv, appname, name, 0, NULL, &real_name)) != 0) - return (ret); - - if (DBENV_LOGGING(dbenv)) { - memset(&data, 0, sizeof(data)); - data.data = buf; - data.size = size; - memset(&namedbt, 0, sizeof(namedbt)); - namedbt.data = (void *)name; - namedbt.size = (u_int32_t)strlen(name) + 1; - if ((ret = __fop_write_log(dbenv, txn, - &lsn, flags, &namedbt, (u_int32_t)appname, - pgsize, pageno, off, &data, istmp)) != 0) - goto err; - } - - if (fhp == NULL) { - /* File isn't open; we need to reopen it. */ - if ((ret = __os_open(dbenv, real_name, 0, 0, &fhp)) != 0) - goto err; - local_open = 1; - } - - /* Seek to offset. */ - if ((ret = __os_seek(dbenv, - fhp, pgsize, pageno, off, 0, DB_OS_SEEK_SET)) != 0) - goto err; - - /* Now do the write. */ - if ((ret = __os_write(dbenv, fhp, buf, size, &nbytes)) != 0) - goto err; - -err: if (local_open && - (t_ret = __os_closehandle(dbenv, fhp)) != 0 && ret == 0) - ret = t_ret; - - if (real_name != NULL) - __os_free(dbenv, real_name); - return (ret); -} - -/* - * __fop_rename -- - * Change a file's name. - * - * PUBLIC: int __fop_rename __P((DB_ENV *, DB_TXN *, - * PUBLIC: const char *, const char *, u_int8_t *, APPNAME, u_int32_t)); - */ -int -__fop_rename(dbenv, txn, oldname, newname, fid, appname, flags) - DB_ENV *dbenv; - DB_TXN *txn; - const char *oldname; - const char *newname; - u_int8_t *fid; - APPNAME appname; - u_int32_t flags; -{ - DB_LSN lsn; - DBT fiddbt, new, old; - int ret; - char *n, *o; - - o = n = NULL; - if ((ret = __db_appname(dbenv, appname, oldname, 0, NULL, &o)) != 0) - goto err; - if ((ret = __db_appname(dbenv, appname, newname, 0, NULL, &n)) != 0) - goto err; - - if (DBENV_LOGGING(dbenv)) { - memset(&old, 0, sizeof(old)); - memset(&new, 0, sizeof(new)); - memset(&fiddbt, 0, sizeof(fiddbt)); - old.data = (void *)oldname; - old.size = (u_int32_t)strlen(oldname) + 1; - new.data = (void *)newname; - new.size = (u_int32_t)strlen(newname) + 1; - fiddbt.data = fid; - fiddbt.size = DB_FILE_ID_LEN; - if ((ret = __fop_rename_log(dbenv, txn, &lsn, flags | DB_FLUSH, - &old, &new, &fiddbt, (u_int32_t)appname)) != 0) - goto err; - } - - ret = __memp_nameop(dbenv, fid, newname, o, n, 0); - -err: if (o != NULL) - __os_free(dbenv, o); - if (n != NULL) - __os_free(dbenv, n); - return (ret); -} diff --git a/storage/bdb/fileops/fop_rec.c b/storage/bdb/fileops/fop_rec.c deleted file mode 100644 index bccf89ae1ab..00000000000 --- a/storage/bdb/fileops/fop_rec.c +++ /dev/null @@ -1,390 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2001-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: fop_rec.c,v 12.6 2005/10/12 17:52:16 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/fop.h" -#include "dbinc/db_am.h" -#include "dbinc/mp.h" -#include "dbinc/txn.h" - -/* - * The transactional guarantees Berkeley DB provides for file - * system level operations (database physical file create, delete, - * rename) are based on our understanding of current file system - * semantics; a system that does not provide these semantics and - * guarantees could be in danger. - * - * First, as in standard database changes, fsync and fdatasync must - * work: when applied to the log file, the records written into the - * log must be transferred to stable storage. - * - * Second, it must not be possible for the log file to be removed - * without previous file system level operations being flushed to - * stable storage. Berkeley DB applications write log records - * describing file system operations into the log, then perform the - * file system operation, then commit the enclosing transaction - * (which flushes the log file to stable storage). Subsequently, - * a database environment checkpoint may make it possible for the - * application to remove the log file containing the record of the - * file system operation. DB's transactional guarantees for file - * system operations require the log file removal not succeed until - * all previous filesystem operations have been flushed to stable - * storage. In other words, the flush of the log file, or the - * removal of the log file, must block until all previous - * filesystem operations have been flushed to stable storage. This - * semantic is not, as far as we know, required by any existing - * standards document, but we have never seen a filesystem where - * it does not apply. - */ - -/* - * __fop_create_recover -- - * Recovery function for create. - * - * PUBLIC: int __fop_create_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__fop_create_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - DB_FH *fhp; - __fop_create_args *argp; - char *real_name; - int ret; - - real_name = NULL; - COMPQUIET(info, NULL); - REC_PRINT(__fop_create_print); - REC_NOOP_INTRO(__fop_create_read); - - if ((ret = __db_appname(dbenv, (APPNAME)argp->appname, - (const char *)argp->name.data, 0, NULL, &real_name)) != 0) - goto out; - - if (DB_UNDO(op)) - (void)__os_unlink(dbenv, real_name); - else if (DB_REDO(op)) { - if ((ret = __os_open(dbenv, real_name, - DB_OSO_CREATE | DB_OSO_EXCL, (int)argp->mode, &fhp)) == 0) - (void)__os_closehandle(dbenv, fhp); - else - goto out; - } - - *lsnp = argp->prev_lsn; - -out: if (real_name != NULL) - __os_free(dbenv, real_name); - - REC_NOOP_CLOSE; -} - -/* - * __fop_remove_recover -- - * Recovery function for remove. - * - * PUBLIC: int __fop_remove_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__fop_remove_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __fop_remove_args *argp; - char *real_name; - int ret; - - real_name = NULL; - COMPQUIET(info, NULL); - REC_PRINT(__fop_remove_print); - REC_NOOP_INTRO(__fop_remove_read); - - if ((ret = __db_appname(dbenv, (APPNAME)argp->appname, - (const char *)argp->name.data, 0, NULL, &real_name)) != 0) - goto out; - - /* Its ok if the file is not there. */ - if (DB_REDO(op)) - (void)__memp_nameop(dbenv, - (u_int8_t *)argp->fid.data, NULL, real_name, NULL, 0); - - *lsnp = argp->prev_lsn; -out: if (real_name != NULL) - __os_free(dbenv, real_name); - REC_NOOP_CLOSE; -} - -/* - * __fop_write_recover -- - * Recovery function for writechunk. - * - * PUBLIC: int __fop_write_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__fop_write_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __fop_write_args *argp; - int ret; - - COMPQUIET(info, NULL); - REC_PRINT(__fop_write_print); - REC_NOOP_INTRO(__fop_write_read); - - ret = 0; - if (DB_UNDO(op)) - DB_ASSERT(argp->flag != 0); - else if (DB_REDO(op)) - ret = __fop_write(dbenv, - argp->txnid, argp->name.data, (APPNAME)argp->appname, - NULL, argp->pgsize, argp->pageno, argp->offset, - argp->page.data, argp->page.size, argp->flag, 0); - - if (ret == 0) - *lsnp = argp->prev_lsn; - REC_NOOP_CLOSE; -} - -/* - * __fop_rename_recover -- - * Recovery function for rename. - * - * PUBLIC: int __fop_rename_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__fop_rename_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __fop_rename_args *argp; - DB_FH *fhp; - DBMETA *meta; - char *real_new, *real_old, *src; - int ret; - u_int8_t *fileid, mbuf[DBMETASIZE]; - - real_new = NULL; - real_old = NULL; - ret = 0; - fhp = NULL; - meta = (DBMETA *)&mbuf[0]; - - COMPQUIET(info, NULL); - REC_PRINT(__fop_rename_print); - REC_NOOP_INTRO(__fop_rename_read); - fileid = argp->fileid.data; - - if ((ret = __db_appname(dbenv, (APPNAME)argp->appname, - (const char *)argp->newname.data, 0, NULL, &real_new)) != 0) - goto out; - if ((ret = __db_appname(dbenv, (APPNAME)argp->appname, - (const char *)argp->oldname.data, 0, NULL, &real_old)) != 0) - goto out; - - /* - * Verify that we are manipulating the correct file. We should always - * be OK on an ABORT or an APPLY, but during recovery, we have to - * check. - */ - if (op != DB_TXN_ABORT && op != DB_TXN_APPLY) { - src = DB_UNDO(op) ? real_new : real_old; - /* - * Interpret any error as meaning that the file either doesn't - * exist, doesn't have a meta-data page, or is in some other - * way, shape or form, incorrect, so that we should not restore - * it. - */ - if (__os_open(dbenv, src, 0, 0, &fhp) != 0) - goto done; - if (__fop_read_meta(dbenv, - src, mbuf, DBMETASIZE, fhp, 1, NULL) != 0) - goto done; - if (__db_chk_meta(dbenv, NULL, meta, 1) != 0) - goto done; - if (memcmp(argp->fileid.data, meta->uid, DB_FILE_ID_LEN) != 0) - goto done; - (void)__os_closehandle(dbenv, fhp); - fhp = NULL; - if (DB_REDO(op)) { - /* - * Check to see if the target file exists. If it - * does and it does not have the proper id then - * it is a later version. We just remove the source - * file since the state of the world is beyond this - * point. - */ - if (__os_open(dbenv, real_new, 0, 0, &fhp) == 0 && - __fop_read_meta(dbenv, src, mbuf, - DBMETASIZE, fhp, 1, NULL) == 0 && - __db_chk_meta(dbenv, NULL, meta, 1) == 0 && - memcmp(argp->fileid.data, - meta->uid, DB_FILE_ID_LEN) != 0) { - (void)__memp_nameop(dbenv, - fileid, NULL, real_old, NULL, 0); - goto done; - } - } - } - - if (DB_UNDO(op)) - (void)__memp_nameop(dbenv, fileid, - (const char *)argp->oldname.data, real_new, real_old, 0); - if (DB_REDO(op)) - (void)__memp_nameop(dbenv, fileid, - (const char *)argp->newname.data, real_old, real_new, 0); - -done: *lsnp = argp->prev_lsn; -out: if (real_new != NULL) - __os_free(dbenv, real_new); - if (real_old != NULL) - __os_free(dbenv, real_old); - if (fhp != NULL) - (void)__os_closehandle(dbenv, fhp); - - REC_NOOP_CLOSE; -} - -/* - * __fop_file_remove_recover -- - * Recovery function for file_remove. On the REDO pass, we need to - * make sure no one recreated the file while we weren't looking. On an - * undo pass must check if the file we are interested in is the one that - * exists and then set the status of the child transaction depending on - * what we find out. - * - * PUBLIC: int __fop_file_remove_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__fop_file_remove_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __fop_file_remove_args *argp; - DBMETA *meta; - DB_FH *fhp; - char *real_name; - int is_real, is_tmp, ret; - size_t len; - u_int8_t mbuf[DBMETASIZE]; - u_int32_t cstat, ret_stat; - - fhp = NULL; - is_real = is_tmp = 0; - real_name = NULL; - meta = (DBMETA *)&mbuf[0]; - REC_PRINT(__fop_file_remove_print); - REC_NOOP_INTRO(__fop_file_remove_read); - - /* - * This record is only interesting on the backward, forward, and - * apply phases. - */ - if (op != DB_TXN_BACKWARD_ROLL && - op != DB_TXN_FORWARD_ROLL && op != DB_TXN_APPLY) - goto done; - - if ((ret = __db_appname(dbenv, - (APPNAME)argp->appname, argp->name.data, 0, NULL, &real_name)) != 0) - goto out; - - /* Verify that we are manipulating the correct file. */ - len = 0; - if (__os_open(dbenv, real_name, 0, 0, &fhp) != 0 || - (ret = __fop_read_meta(dbenv, real_name, - mbuf, DBMETASIZE, fhp, 1, &len)) != 0) { - /* - * If len is non-zero, then the file exists and has something - * in it, but that something isn't a full meta-data page, so - * this is very bad. Bail out! - */ - if (len != 0) - goto out; - - /* File does not exist. */ - cstat = TXN_EXPECTED; - } else { - /* - * We can ignore errors here since we'll simply fail the - * checks below and assume this is the wrong file. - */ - (void)__db_chk_meta(dbenv, NULL, meta, 1); - is_real = - memcmp(argp->real_fid.data, meta->uid, DB_FILE_ID_LEN) == 0; - is_tmp = - memcmp(argp->tmp_fid.data, meta->uid, DB_FILE_ID_LEN) == 0; - - if (!is_real && !is_tmp) - /* File exists, but isn't what we were removing. */ - cstat = TXN_IGNORE; - else - /* File exists and is the one that we were removing. */ - cstat = TXN_COMMIT; - } - if (fhp != NULL) { - (void)__os_closehandle(dbenv, fhp); - fhp = NULL; - } - - if (DB_UNDO(op)) { - /* On the backward pass, we leave a note for the child txn. */ - if ((ret = __db_txnlist_update(dbenv, - info, argp->child, cstat, NULL, &ret_stat, 1)) != 0) - goto out; - } else if (DB_REDO(op)) { - /* - * On the forward pass, check if someone recreated the - * file while we weren't looking. - */ - if (cstat == TXN_COMMIT) - (void)__memp_nameop(dbenv, - is_real ? argp->real_fid.data : argp->tmp_fid.data, - NULL, real_name, NULL, 0); - } - -done: *lsnp = argp->prev_lsn; - ret = 0; - -out: if (real_name != NULL) - __os_free(dbenv, real_name); - if (fhp != NULL) - (void)__os_closehandle(dbenv, fhp); - REC_NOOP_CLOSE; -} diff --git a/storage/bdb/fileops/fop_util.c b/storage/bdb/fileops/fop_util.c deleted file mode 100644 index 179452f23db..00000000000 --- a/storage/bdb/fileops/fop_util.c +++ /dev/null @@ -1,1737 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2001-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: fop_util.c,v 12.19 2005/10/27 01:26:00 mjc Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/db_am.h" -#include "dbinc/hash.h" -#include "dbinc/fop.h" -#include "dbinc/lock.h" -#include "dbinc/mp.h" -#include "dbinc/log.h" -#include "dbinc/txn.h" - -static int __fop_set_pgsize __P((DB *, DB_FH *, const char *)); -static int __fop_inmem_create __P((DB *, const char *, DB_TXN *, u_int32_t)); -static int __fop_inmem_dummy __P((DB *, DB_TXN *, const char *, u_int8_t *)); -static int __fop_inmem_read_meta __P((DB *, const char *, u_int32_t)); -static int __fop_inmem_swap __P((DB *, DB *, DB_TXN *, - const char *, const char *, const char *, u_int32_t)); -static int __fop_ondisk_dummy __P((DB *, - DB_TXN *, const char *, u_int8_t *, u_int32_t)); -static int __fop_ondisk_swap __P((DB *, DB *, DB_TXN *, - const char *, const char *, const char *, u_int32_t, u_int32_t)); - -/* - * Acquire the environment meta-data lock. The parameters are the - * environment (ENV), the locker id to use in acquiring the lock (ID) - * and a pointer to a DB_LOCK. - * - * !!! - * Turn off locking for Critical Path. The application must do its own - * synchronization of open/create. Two threads creating and opening a - * file at the same time may have unpredictable results. - */ -#ifdef CRITICALPATH_10266 -#define GET_ENVLOCK(ENV, ID, L) (0) -#else -#define GET_ENVLOCK(ENV, ID, L) do { \ - DBT __dbt; \ - u_int32_t __lockval; \ - \ - if (LOCKING_ON((ENV))) { \ - __lockval = 1; \ - __dbt.data = &__lockval; \ - __dbt.size = sizeof(__lockval); \ - if ((ret = __lock_get((ENV), (ID), \ - 0, &__dbt, DB_LOCK_WRITE, (L))) != 0) \ - goto err; \ - } \ -} while (0) -#endif - -#define RESET_MPF(D, F) do { \ - (void)__memp_fclose((D)->mpf, (F)); \ - (D)->mpf = NULL; \ - F_CLR((D), DB_AM_OPEN_CALLED); \ - if ((ret = __memp_fcreate((D)->dbenv, &(D)->mpf)) != 0) \ - goto err; \ -} while (0) - -/* - * If we open a file handle and our caller is doing fcntl(2) locking, - * we can't close the handle because that would discard the caller's - * lock. Save it until we close or refresh the DB handle. - */ -#define CLOSE_HANDLE(D, F) { \ - if ((F) != NULL) { \ - if (LF_ISSET(DB_FCNTL_LOCKING)) \ - (D)->saved_open_fhp = (F); \ - else if ((t_ret = \ - __os_closehandle((D)->dbenv, (F))) != 0) { \ - if (ret == 0) \ - ret = t_ret; \ - goto err; \ - } \ - (F) = NULL; \ - } \ -} - -/* - * __fop_lock_handle -- - * - * Get the handle lock for a database. If the envlock is specified, do this - * as a lock_vec call that releases the environment lock before acquiring the - * handle lock. - * - * PUBLIC: int __fop_lock_handle __P((DB_ENV *, - * PUBLIC: DB *, u_int32_t, db_lockmode_t, DB_LOCK *, u_int32_t)); - * - */ -int -__fop_lock_handle(dbenv, dbp, locker, mode, elockp, flags) - DB_ENV *dbenv; - DB *dbp; - u_int32_t locker; - db_lockmode_t mode; - DB_LOCK *elockp; - u_int32_t flags; -{ - DBT fileobj; - DB_LOCKREQ reqs[2], *ereq; - DB_LOCK_ILOCK lock_desc; - int ret; - - if (!LOCKING_ON(dbenv) || - F_ISSET(dbp, DB_AM_COMPENSATE | DB_AM_RECOVER)) - return (0); - - /* - * If we are in recovery, the only locking we should be - * doing is on the global environment. - */ - if (IS_RECOVERING(dbenv)) - return (elockp == NULL ? 0 : __ENV_LPUT(dbenv, *elockp)); - - memcpy(lock_desc.fileid, dbp->fileid, DB_FILE_ID_LEN); - lock_desc.pgno = dbp->meta_pgno; - lock_desc.type = DB_HANDLE_LOCK; - - memset(&fileobj, 0, sizeof(fileobj)); - fileobj.data = &lock_desc; - fileobj.size = sizeof(lock_desc); - DB_TEST_SUBLOCKS(dbenv, flags); - if (elockp == NULL) - ret = __lock_get(dbenv, locker, - flags, &fileobj, mode, &dbp->handle_lock); - else { - reqs[0].op = DB_LOCK_PUT; - reqs[0].lock = *elockp; - reqs[1].op = DB_LOCK_GET; - reqs[1].mode = mode; - reqs[1].obj = &fileobj; - reqs[1].timeout = 0; - if ((ret = __lock_vec(dbenv, - locker, flags, reqs, 2, &ereq)) == 0) { - dbp->handle_lock = reqs[1].lock; - LOCK_INIT(*elockp); - } else if (ereq != reqs) - LOCK_INIT(*elockp); - } - - dbp->cur_lid = locker; - return (ret); -} - -/* - * __fop_file_setup -- - * - * Perform all the needed checking and locking to open up or create a - * file. - * - * There's a reason we don't push this code down into the buffer cache. - * The problem is that there's no information external to the file that - * we can use as a unique ID. UNIX has dev/inode pairs, but they are - * not necessarily unique after reboot, if the file was mounted via NFS. - * Windows has similar problems, as the FAT filesystem doesn't maintain - * dev/inode numbers across reboot. So, we must get something from the - * file we can use to ensure that, even after a reboot, the file we're - * joining in the cache is the right file for us to join. The solution - * we use is to maintain a file ID that's stored in the database, and - * that's why we have to open and read the file before calling into the - * buffer cache or obtaining a lock (we use this unique fileid to lock - * as well as to identify like files in the cache). - * - * There are a couple of idiosyncrasies that this code must support, in - * particular, DB_TRUNCATE and DB_FCNTL_LOCKING. First, we disallow - * DB_TRUNCATE in the presence of transactions, since opening a file with - * O_TRUNC will result in data being lost in an unrecoverable fashion. - * We also disallow DB_TRUNCATE if locking is enabled, because even in - * the presence of locking, we cannot avoid race conditions, so allowing - * DB_TRUNCATE with locking would be misleading. See SR [#7345] for more - * details. - * - * However, if you are running with neither locking nor transactions, then - * you can specify DB_TRUNCATE, and if you do so, we will truncate the file - * regardless of its contents. - * - * FCNTL locking introduces another set of complications. First, the only - * reason we support the DB_FCNTL_LOCKING flag is for historic compatibility - * with programs like Sendmail and Postfix. In these cases, the caller may - * already have a lock on the file; we need to make sure that any file handles - * we open remain open, because if we were to close them, the lock held by the - * caller would go away. Furthermore, Sendmail and/or Postfix need the ability - * to create databases in empty files. So, when you're doing FCNTL locking, - * it's reasonable that you are trying to create a database into a 0-length - * file and we allow it, while under normal conditions, we do not create - * databases if the files already exist and are not Berkeley DB files. - * - * PUBLIC: int __fop_file_setup __P((DB *, - * PUBLIC: DB_TXN *, const char *, int, u_int32_t, u_int32_t *)); - */ -int -__fop_file_setup(dbp, txn, name, mode, flags, retidp) - DB *dbp; - DB_TXN *txn; - const char *name; - int mode; - u_int32_t flags, *retidp; -{ - DB_ENV *dbenv; - DB_FH *fhp; - DB_LOCK elock; - DB_TXN *stxn; - DBTYPE save_type; - size_t len; - u_int32_t dflags, locker, oflags; - u_int8_t mbuf[DBMETASIZE]; - int created_locker, create_ok, ret, retries, t_ret, tmp_created; - int truncating, was_inval; - char *real_name, *real_tmpname, *tmpname; - - *retidp = TXN_INVALID; - - dbenv = dbp->dbenv; - fhp = NULL; - LOCK_INIT(elock); - stxn = NULL; - created_locker = tmp_created = truncating = was_inval = 0; - real_name = real_tmpname = tmpname = NULL; - dflags = F_ISSET(dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0; - - ret = 0; - retries = 0; - save_type = dbp->type; - - /* - * Get a lockerid for this handle. There are paths through queue - * rename and remove where this dbp already has a locker, so make - * sure we don't clobber it and conflict. - */ - if (LOCKING_ON(dbenv) && - !F_ISSET(dbp, DB_AM_COMPENSATE) && - !F_ISSET(dbp, DB_AM_RECOVER) && - dbp->lid == DB_LOCK_INVALIDID) { - if ((ret = __lock_id(dbenv, &dbp->lid, NULL)) != 0) - goto err; - created_locker = 1; - } - LOCK_INIT(dbp->handle_lock); - - locker = txn == NULL ? dbp->lid : txn->txnid; - - oflags = 0; - if (F_ISSET(dbp, DB_AM_INMEM)) - real_name = (char *)name; - else { - /* Get the real backing file name. */ - if ((ret = __db_appname(dbenv, - DB_APP_DATA, name, 0, NULL, &real_name)) != 0) - goto err; - - /* Fill in the default file mode. */ - if (mode == 0) - mode = __db_omode("rw-rw----"); - - if (LF_ISSET(DB_RDONLY)) - oflags |= DB_OSO_RDONLY; - if (LF_ISSET(DB_TRUNCATE)) - oflags |= DB_OSO_TRUNC; - } - - retries = 0; - create_ok = LF_ISSET(DB_CREATE); - LF_CLR(DB_CREATE); - -retry: - /* - * If we cannot create the file, only retry a few times. We - * think we might be in a race with another create, but it could - * be that the backup filename exists (that is, is left over from - * a previous crash). - */ - if (++retries > DB_RETRY) { - __db_err(dbenv, "__fop_file_setup: Retry limit (%d) exceeded", - DB_RETRY); - goto err; - } - if (!F_ISSET(dbp, DB_AM_COMPENSATE) && !F_ISSET(dbp, DB_AM_RECOVER)) - GET_ENVLOCK(dbenv, locker, &elock); - if (name == NULL) - ret = ENOENT; - else if (F_ISSET(dbp, DB_AM_INMEM)) { - ret = __db_dbenv_mpool(dbp, name, flags); - /* - * We are using __db_dbenv_open as a check for existence. - * However, db_dbenv_mpool does an actual open and there - * are scenarios where the object exists, but cannot be - * opened, because our settings don't match those internally. - * We need to check for that explicitly. We'll need the - * mpool open to read the meta-data page, so we're going to - * have to temporarily turn this dbp into an UNKNOWN one. - */ - if (ret == EINVAL) { - was_inval = 1; - save_type = dbp->type; - dbp->type = DB_UNKNOWN; - ret = __db_dbenv_mpool(dbp, name, flags); - dbp->type = save_type; - } - } else - ret = __os_exists(real_name, NULL); - - if (ret == 0) { - /* - * If the file exists, there are 5 possible cases: - * 1. DB_EXCL was specified so this is an error, unless - * this is a file left around after a rename and we - * are in the same transaction. This gets decomposed - * into several subcases, because we check for various - * errors before we know we're in rename. - * 2. We are truncating, and it doesn't matter what kind - * of file it is, we should open/create it. - * 3. It is 0-length, we are not doing transactions (i.e., - * we are sendmail), we should open/create into it. - * -- on-disk files only! - * 4. Is it a Berkeley DB file and we should simply open it. - * 5. It is not a BDB file and we should return an error. - */ - - /* Open file (if there is one). */ -reopen: if (!F_ISSET(dbp, DB_AM_INMEM) && - (ret = __os_open(dbenv, real_name, oflags, 0, &fhp)) != 0) - goto err; - - /* Case 2: DB_TRUNCATE: we must do the creation in place. */ - if (LF_ISSET(DB_TRUNCATE)) { - if (LF_ISSET(DB_EXCL)) { - /* Case 1a: DB_EXCL and DB_TRUNCATE. */ - ret = EEXIST; - goto err; - } - tmpname = (char *)name; - goto creat2; - } - - /* Cases 1,3-5: we need to read the meta-data page. */ - if (F_ISSET(dbp, DB_AM_INMEM)) - ret = __fop_inmem_read_meta(dbp, name, flags); - else { - ret = __fop_read_meta(dbenv, real_name, mbuf, - sizeof(mbuf), fhp, - LF_ISSET(DB_FCNTL_LOCKING) && txn == NULL ? 1 : 0, - &len); - - /* Case 3: 0-length, no txns. */ - if (ret != 0 && len == 0 && txn == NULL) { - if (LF_ISSET(DB_EXCL)) { - /* - * Case 1b: DB_EXCL and - * 0-lenth file exists. - */ - ret = EEXIST; - goto err; - } - tmpname = (char *)name; - goto creat2; - } - - /* Case 4: This is a valid file. */ - if (ret == 0) - ret = __db_meta_setup(dbenv, dbp, - real_name, (DBMETA *)mbuf, flags, 1); - - } - - /* Case 5: Invalid file. */ - if (ret != 0) - goto err; - - /* Now, get our handle lock. */ - if ((ret = __fop_lock_handle(dbenv, - dbp, locker, DB_LOCK_READ, NULL, DB_LOCK_NOWAIT)) == 0) { - if ((ret = __ENV_LPUT(dbenv, elock)) != 0) - goto err; - } else if (ret != DB_LOCK_NOTGRANTED || - (txn != NULL && F_ISSET(txn, TXN_NOWAIT))) - goto err; - else { - /* - * We were unable to acquire the handle lock without - * blocking. The fact that we are blocking might mean - * that someone else is trying to delete the file. - * Since some platforms cannot delete files while they - * are open (Windows), we are going to have to close - * the file. This would be a problem if we were doing - * FCNTL locking, because our closing the handle would - * release the FCNTL locks. Fortunately, if we are - * doing FCNTL locking, then we should never fail to - * acquire our handle lock, so we should never get here. - * We assert it here to make sure we aren't destroying - * any application level FCNTL semantics. - */ - DB_ASSERT(!LF_ISSET(DB_FCNTL_LOCKING)); - if (!F_ISSET(dbp, DB_AM_INMEM)) { - if ((ret = __os_closehandle(dbenv, fhp)) != 0) - goto err; - fhp = NULL; - } - if ((ret = __fop_lock_handle(dbenv, - dbp, locker, DB_LOCK_READ, &elock, 0)) != 0) { - if (F_ISSET(dbp, DB_AM_INMEM)) - RESET_MPF(dbp, 0); - goto err; - } - - /* - * It's possible that our DBP was initialized - * with a different file last time we opened it. - * Therefore, we need to reset the DBP type and then - * re-read the meta-data page and reset any other - * fields that __db_meta_setup initializes. We - * need to shut down this dbp and reopen for in-memory - * named databases. Unfortunately __db_refresh is - * pretty aggressive at the shutting down, so we need - * to do a bunch of restoration. - * XXX it would be nice to pull refresh apart into - * the stuff you need to do to call __db_env_mpool - * and the stuff you can really throw away. - */ - if (F_ISSET(dbp, DB_AM_INMEM)) { - if ((ret = __db_refresh(dbp, - txn, DB_NOSYNC, NULL, 1)) != 0) - goto err; - ret = __db_dbenv_mpool(dbp, name, flags); - } else - ret = __os_open(dbenv, real_name, 0, 0, &fhp); - - if (ret != 0) { - if ((ret = - __ENV_LPUT(dbenv, dbp->handle_lock)) != 0) { - LOCK_INIT(dbp->handle_lock); - goto err; - } - goto retry; - } - - dbp->type = save_type; - if (F_ISSET(dbp, DB_AM_INMEM)) - ret = __fop_inmem_read_meta(dbp, name, flags); - else if ((ret = - __fop_read_meta(dbenv, real_name, mbuf, - sizeof(mbuf), fhp, - LF_ISSET(DB_FCNTL_LOCKING) && txn == NULL ? 1 : 0, - &len)) != 0 || - (ret = __db_meta_setup(dbenv, dbp, real_name, - (DBMETA *)mbuf, flags, 1)) != 0) - goto err; - - } - - /* If we got here, then we have the handle lock. */ - - /* - * Check for a file in the midst of a rename. If we find that - * the file is in the midst of a rename, it must be the case - * that it is in our current transaction (else we would still - * be blocking), so we can continue along and create a new file - * with the same name. In that case, we have to close the file - * handle because we reuse it below. This is a case where - * a 'was_inval' above is OK. - */ - if (F_ISSET(dbp, DB_AM_IN_RENAME)) { - was_inval = 0; - if (create_ok) { - if (F_ISSET(dbp, DB_AM_INMEM)) { - RESET_MPF(dbp, DB_MPOOL_DISCARD); - } else if ((ret = - __os_closehandle(dbenv, fhp)) != 0) - goto err; - LF_SET(DB_CREATE); - goto create; - } else { - ret = ENOENT; - goto err; - } - } - - /* If we get here, a was_inval is bad. */ - if (was_inval) { - ret = EINVAL; - goto err; - } - - /* - * Now, case 1: check for DB_EXCL, because the file that exists - * is not in the middle of a rename, so we have an error. This - * is a weird case, but we need to make sure that we don't - * continue to hold the handle lock, since technically, we - * should not have been allowed to open it. - */ - if (LF_ISSET(DB_EXCL)) { - ret = __ENV_LPUT(dbenv, dbp->handle_lock); - LOCK_INIT(dbp->handle_lock); - if (ret == 0) - ret = EEXIST; - goto err; - } - goto done; - } - - /* File does not exist. */ -#ifdef HAVE_VXWORKS - /* - * VxWorks can return file-system specific error codes if the - * file does not exist, not ENOENT. - */ - if (!create_ok) -#else - if (!create_ok || ret != ENOENT) -#endif - goto err; - LF_SET(DB_CREATE); - ret = 0; - - /* - * We need to create file, which means that we need to set up the file, - * the fileid and the locks. Then we need to call the appropriate - * routines to create meta-data pages. For in-memory files, we retain - * the environment lock, while for on-disk files, we drop the env lock - * and create into a temporary. - */ - if (!F_ISSET(dbp, DB_AM_INMEM) && - (ret = __ENV_LPUT(dbenv, elock)) != 0) - goto err; - -create: if (txn != NULL && IS_REP_CLIENT(dbenv)) { - __db_err(dbenv, - "Transactional create on replication client disallowed"); - ret = EINVAL; - goto err; - } - - if (F_ISSET(dbp, DB_AM_INMEM)) - ret = __fop_inmem_create(dbp, name, txn, flags); - else { - if ((ret = __db_backup_name(dbenv, name, txn, &tmpname)) != 0) - goto err; - if (TXN_ON(dbenv) && txn != NULL && - (ret = __txn_begin(dbenv, txn, &stxn, 0)) != 0) - goto err; - if ((ret = __fop_create(dbenv, - stxn, &fhp, tmpname, DB_APP_DATA, mode, dflags)) != 0) { - /* - * If we don't have transactions there is a race on - * creating the temp file. - */ - if (!TXN_ON(dbenv) && ret == EEXIST) { - __os_free(dbenv, tmpname); - tmpname = NULL; - __os_yield(dbenv, 1); - goto retry; - } - goto err; - } - tmp_created = 1; - } - -creat2: if (!F_ISSET(dbp, DB_AM_INMEM)) { - if ((ret = __db_appname(dbenv, - DB_APP_DATA, tmpname, 0, NULL, &real_tmpname)) != 0) - goto err; - - /* Set the pagesize if it isn't yet set. */ - if (dbp->pgsize == 0 && - (ret = __fop_set_pgsize(dbp, fhp, real_tmpname)) != 0) - goto errmsg; - - /* Construct a file_id. */ - if ((ret = - __os_fileid(dbenv, real_tmpname, 1, dbp->fileid)) != 0) - goto errmsg; - } - - if ((ret = __db_new_file(dbp, - F_ISSET(dbp, DB_AM_INMEM) ? txn : stxn, fhp, tmpname)) != 0) - goto err; - - /* - * We need to close the handle here on platforms where remove and - * rename fail if a handle is open (including Windows). - */ - CLOSE_HANDLE(dbp, fhp); - - /* - * Now move the file into place unless we are creating in place (because - * we created a database in a file that started out 0-length). If - * this is an in-memory file, we may or may not hold the environment - * lock depending on how we got here. - */ - if (!F_ISSET(dbp, DB_AM_COMPENSATE) && - !F_ISSET(dbp, DB_AM_RECOVER) && !LOCK_ISSET(elock)) - GET_ENVLOCK(dbenv, locker, &elock); - - if (F_ISSET(dbp, DB_AM_IN_RENAME)) { - F_CLR(dbp, DB_AM_IN_RENAME); - __txn_remrem(dbenv, txn, real_name); - } else if (name == tmpname) { - /* We created it in place. */ - } else if (!F_ISSET(dbp, DB_AM_INMEM) && - __os_exists(real_name, NULL) == 0) { - /* - * Someone managed to create the file; remove our temp - * and try to open the file that now exists. - */ - (void)__fop_remove(dbenv, - NULL, dbp->fileid, tmpname, DB_APP_DATA, dflags); - (void)__ENV_LPUT(dbenv, dbp->handle_lock); - LOCK_INIT(dbp->handle_lock); - - if (stxn != NULL) { - ret = __txn_abort(stxn); - stxn = NULL; - } - if (ret != 0) - goto err; - goto reopen; - } - - if (name != NULL && (ret = __fop_lock_handle(dbenv, - dbp, locker, DB_LOCK_WRITE, &elock, NOWAIT_FLAG(txn))) != 0) - goto err; - if (tmpname != NULL && tmpname != name && (ret = __fop_rename(dbenv, - stxn, tmpname, name, dbp->fileid, DB_APP_DATA, dflags)) != 0) - goto err; - - if (stxn != NULL) { - *retidp = stxn->txnid; - ret = __txn_commit(stxn, 0); - stxn = NULL; - } else - *retidp = TXN_INVALID; - - if (ret != 0) - goto err; - - F_SET(dbp, DB_AM_CREATED); - - if (0) { -errmsg: __db_err(dbenv, "%s: %s", name, db_strerror(ret)); - -err: CLOSE_HANDLE(dbp, fhp); - if (stxn != NULL) - (void)__txn_abort(stxn); - if (tmp_created && txn == NULL) - (void)__fop_remove(dbenv, - NULL, NULL, tmpname, DB_APP_DATA, dflags); - if (txn == NULL) - (void)__ENV_LPUT(dbenv, dbp->handle_lock); - (void)__ENV_LPUT(dbenv, elock); - if (created_locker) { - (void)__lock_id_free(dbenv, dbp->lid); - dbp->lid = DB_LOCK_INVALIDID; - } - } - -done: /* - * There are cases where real_name and tmpname take on the - * exact same string, so we need to make sure that we do not - * free twice. - */ - if (!truncating && tmpname != NULL && tmpname != name) - __os_free(dbenv, tmpname); - if (real_name != name && real_name != NULL) - __os_free(dbenv, real_name); - if (real_tmpname != NULL) - __os_free(dbenv, real_tmpname); - CLOSE_HANDLE(dbp, fhp); - - return (ret); -} - -/* - * __fop_set_pgsize -- - * Set the page size based on file information. - */ -static int -__fop_set_pgsize(dbp, fhp, name) - DB *dbp; - DB_FH *fhp; - const char *name; -{ - DB_ENV *dbenv; - u_int32_t iopsize; - int ret; - - dbenv = dbp->dbenv; - - /* - * Use the filesystem's optimum I/O size as the pagesize if a pagesize - * not specified. Some filesystems have 64K as their optimum I/O size, - * but as that results in fairly large default caches, we limit the - * default pagesize to 16K. - */ - if ((ret = __os_ioinfo(dbenv, name, fhp, NULL, NULL, &iopsize)) != 0) { - __db_err(dbenv, "%s: %s", name, db_strerror(ret)); - return (ret); - } - if (iopsize < 512) - iopsize = 512; - if (iopsize > 16 * 1024) - iopsize = 16 * 1024; - - /* - * Sheer paranoia, but we don't want anything that's not a power-of-2 - * (we rely on that for alignment of various types on the pages), and - * we want a multiple of the sector size as well. If the value - * we got out of __os_ioinfo looks bad, use a default instead. - */ - if (!IS_VALID_PAGESIZE(iopsize)) - iopsize = DB_DEF_IOSIZE; - - dbp->pgsize = iopsize; - F_SET(dbp, DB_AM_PGDEF); - - return (0); -} - -/* - * __fop_subdb_setup -- - * - * Subdb setup is significantly simpler than file setup. In terms of - * locking, for the duration of the operation/transaction, the locks on - * the meta-data page will suffice to protect us from simultaneous operations - * on the sub-database. Before we complete the operation though, we'll get a - * handle lock on the subdatabase so that on one else can try to remove it - * while we've got it open. We use an object that looks like the meta-data - * page lock with a different type (DB_HANDLE_LOCK) for the long-term handle. - * locks. - * - * PUBLIC: int __fop_subdb_setup __P((DB *, DB_TXN *, - * PUBLIC: const char *, const char *, int, u_int32_t)); - */ -int -__fop_subdb_setup(dbp, txn, mname, name, mode, flags) - DB *dbp; - DB_TXN *txn; - const char *mname, *name; - int mode; - u_int32_t flags; -{ - DB *mdbp; - DB_ENV *dbenv; - db_lockmode_t lkmode; - int ret, t_ret; - - mdbp = NULL; - dbenv = dbp->dbenv; - - if ((ret = __db_master_open(dbp, txn, mname, flags, mode, &mdbp)) != 0) - return (ret); - /* - * If we created this file, then we need to set the DISCARD flag so - * that if we fail in the middle of this routine, we discard from the - * mpool any pages that we just created. - */ - if (F_ISSET(mdbp, DB_AM_CREATED)) - F_SET(mdbp, DB_AM_DISCARD); - - /* - * We are going to close this instance of the master, so we can - * steal its handle instead of reopening a handle on the database. - */ - if (LF_ISSET(DB_FCNTL_LOCKING)) { - dbp->saved_open_fhp = mdbp->saved_open_fhp; - mdbp->saved_open_fhp = NULL; - } - - /* Copy the pagesize and set the sub-database flag. */ - dbp->pgsize = mdbp->pgsize; - F_SET(dbp, DB_AM_SUBDB); - - if (name != NULL && (ret = __db_master_update(mdbp, dbp, txn, - name, dbp->type, MU_OPEN, NULL, flags)) != 0) - goto err; - - /* - * Hijack the master's locker ID as well, so that our locks don't - * conflict with the master's. Since we're closing the master, - * that lid would just have been freed anyway. Once we've gotten - * the locker id, we need to acquire the handle lock for this - * subdatabase. - */ - dbp->lid = mdbp->lid; - mdbp->lid = DB_LOCK_INVALIDID; - - DB_TEST_RECOVERY(dbp, DB_TEST_POSTLOG, ret, mname); - - /* - * We copy our fileid from our master so that we all open - * the same file in mpool. We'll use the meta-pgno to lock - * so that we end up with different handle locks. - */ - - memcpy(dbp->fileid, mdbp->fileid, DB_FILE_ID_LEN); - lkmode = F_ISSET(dbp, DB_AM_CREATED) || LF_ISSET(DB_WRITEOPEN) ? - DB_LOCK_WRITE : DB_LOCK_READ; - if ((ret = __fop_lock_handle(dbenv, dbp, - txn == NULL ? dbp->lid : txn->txnid, lkmode, NULL, - NOWAIT_FLAG(txn))) != 0) - goto err; - - if ((ret = __db_init_subdb(mdbp, dbp, name, txn)) != 0) { - /* - * If there was no transaction and we created this database, - * then we need to undo the update of the master database. - */ - if (F_ISSET(dbp, DB_AM_CREATED) && txn == NULL) - (void)__db_master_update(mdbp, dbp, txn, - name, dbp->type, MU_REMOVE, NULL, 0); - F_CLR(dbp, DB_AM_CREATED); - goto err; - } - - /* - * XXX - * This should have been done at the top of this routine. The problem - * is that __db_init_subdb() uses "standard" routines to process the - * meta-data page and set information in the DB handle based on it. - * Those routines have to deal with swapped pages and will normally set - * the DB_AM_SWAP flag. However, we use the master's metadata page and - * that has already been swapped, so they get the is-swapped test wrong. - */ - F_CLR(dbp, DB_AM_SWAP); - F_SET(dbp, F_ISSET(mdbp, DB_AM_SWAP)); - - /* - * In the file create case, these happen in separate places so we have - * two different tests. They end up in the same place for subdbs, but - * for compatibility with file testing, we put them both here anyway. - */ - DB_TEST_RECOVERY(dbp, DB_TEST_POSTLOGMETA, ret, mname); - DB_TEST_RECOVERY(dbp, DB_TEST_POSTSYNC, ret, mname); - - /* - * File exists and we have the appropriate locks; we should now - * process a normal open. - */ - if (F_ISSET(mdbp, DB_AM_CREATED)) { - F_SET(dbp, DB_AM_CREATED_MSTR); - F_CLR(mdbp, DB_AM_DISCARD); - } - - if (0) { -err: -DB_TEST_RECOVERY_LABEL - if (txn == NULL) - (void)__ENV_LPUT(dbenv, dbp->handle_lock); - } - - /* - * The master's handle lock is under the control of the - * subdb (it acquired the master's locker). We want to - * keep the master's handle lock so that no one can remove - * the file while the subdb is open. If we register the - * trade event and then invalidate the copy of the lock - * in the master's handle, that will accomplish this. However, - * before we register this event, we'd better remove any - * events that we've already registered for the master. - */ - if (!F_ISSET(dbp, DB_AM_RECOVER) && txn != NULL) { - /* Unregister old master events. */ - __txn_remlock(dbenv, - txn, &mdbp->handle_lock, DB_LOCK_INVALIDID); - - /* Now register the new event. */ - if ((t_ret = __txn_lockevent(dbenv, txn, dbp, - &mdbp->handle_lock, dbp->lid == DB_LOCK_INVALIDID ? - mdbp->lid : dbp->lid)) != 0 && ret == 0) - ret = t_ret; - } - LOCK_INIT(mdbp->handle_lock); - - /* - * If the master was created, we need to sync so that the metadata - * page is correct on disk for recovery, since it isn't read through - * mpool. If we're opening a subdb in an existing file, we can skip - * the sync. - */ - if ((t_ret =__db_close(mdbp, txn, - F_ISSET(dbp, DB_AM_CREATED_MSTR) ? 0 : DB_NOSYNC)) != 0 && - ret == 0) - ret = t_ret; - return (ret); -} - -/* - * __fop_remove_setup -- - * Open handle appropriately and lock for removal of a database file. - * - * PUBLIC: int __fop_remove_setup __P((DB *, - * PUBLIC: DB_TXN *, const char *, u_int32_t)); - */ -int -__fop_remove_setup(dbp, txn, name, flags) - DB *dbp; - DB_TXN *txn; - const char *name; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_FH *fhp; - DB_LOCK elock; - u_int32_t refcnt; - u_int8_t mbuf[DBMETASIZE]; - int ret; - - COMPQUIET(flags, 0); - dbenv = dbp->dbenv; - PANIC_CHECK(dbenv); - LOCK_INIT(elock); - fhp = NULL; - ret = 0; - - /* Create locker if necessary. */ -retry: if (LOCKING_ON(dbenv)) { - if (txn != NULL) - dbp->lid = txn->txnid; - else if (dbp->lid == DB_LOCK_INVALIDID) { - if ((ret = __lock_id(dbenv, &dbp->lid, NULL)) != 0) - goto err; - } - } - - /* - * We are about to open a file handle and then possibly close it. - * We cannot close handles if we are doing FCNTL locking. However, - * there is no way to pass the FCNTL flag into this routine via the - * user API. The only way we can get in here and be doing FCNTL - * locking is if we are trying to clean up an open that was called - * with FCNTL locking. In that case, the save_fhp should already be - * set. So, we use that field to tell us if we need to make sure - * that we shouldn't close the handle. - */ - fhp = dbp->saved_open_fhp; - DB_ASSERT(LF_ISSET(DB_FCNTL_LOCKING) || fhp == NULL); - - /* - * Lock environment to protect file open. That will enable us to - * read the meta-data page and get the fileid so that we can lock - * the handle. - */ - GET_ENVLOCK(dbenv, dbp->lid, &elock); - - /* Open database. */ - if (F_ISSET(dbp, DB_AM_INMEM)) - ret = __db_dbenv_mpool(dbp, name, flags); - else if (fhp == NULL) - ret = __os_open(dbenv, name, DB_OSO_RDONLY, 0, &fhp); - if (ret != 0) - goto err; - - /* Get meta-data */ - if (F_ISSET(dbp, DB_AM_INMEM)) - ret = __fop_inmem_read_meta(dbp, name, flags); - else if ((ret = __fop_read_meta(dbenv, - name, mbuf, sizeof(mbuf), fhp, 0, NULL)) == 0) - ret = __db_meta_setup(dbenv, - dbp, name, (DBMETA *)mbuf, flags, 1); - if (ret != 0) - goto err; - - /* - * Now, get the handle lock. We first try with NOWAIT, because if - * we have to wait, we're going to have to close the file and reopen - * it, so that if there is someone else removing it, our open doesn't - * prevent that. - */ - if ((ret = __fop_lock_handle(dbenv, - dbp, dbp->lid, DB_LOCK_WRITE, NULL, DB_LOCK_NOWAIT)) != 0) { - /* - * Close the file, block on the lock, clean up the dbp, and - * then start all over again. - */ - if (!F_ISSET(dbp, DB_AM_INMEM) && !LF_ISSET(DB_FCNTL_LOCKING)) { - (void)__os_closehandle(dbenv, fhp); - fhp = NULL; - } - if (ret != DB_LOCK_NOTGRANTED || - (txn != NULL && F_ISSET(txn, TXN_NOWAIT))) - goto err; - else if ((ret = __fop_lock_handle(dbenv, - dbp, dbp->lid, DB_LOCK_WRITE, &elock, 0)) != 0) - goto err; - - if (F_ISSET(dbp, DB_AM_INMEM)) { - (void)__lock_put(dbenv, &dbp->handle_lock); - (void)__db_refresh(dbp, txn, DB_NOSYNC, NULL, 1); - } else { - if (txn != NULL) - dbp->lid = DB_LOCK_INVALIDID; - (void)__db_refresh(dbp, txn, DB_NOSYNC, NULL, 0); - } - goto retry; - } else if ((ret = __ENV_LPUT(dbenv, elock)) != 0) - goto err; - - /* Check if the file is already open. */ - if ((ret = __memp_get_refcnt(dbenv, dbp->fileid, &refcnt)) != 0) - goto err; - - /* - * Now, error check. If the file is already open, then we must have - * it open (since we got the lock) and we need to panic, because this - * is a self deadlock and the application has a bug. If the file isn't - * open, but it's in the midst of a rename then this file doesn't - * really exist. Note that in-memory files will always have an - * artificially incremented ref count. - */ - if ((F_ISSET(dbp, DB_AM_INMEM) && refcnt != 2) || - (!F_ISSET(dbp, DB_AM_INMEM) && refcnt != 0)) { - __db_err(dbenv, -"Attempting to remove file open in current transaction causing self-deadlock"); - ret = __db_panic(dbenv, DB_LOCK_DEADLOCK); - } else if (F_ISSET(dbp, DB_AM_IN_RENAME)) - ret = ENOENT; - - if (0) { -err: (void)__ENV_LPUT(dbenv, elock); - } - if (fhp != NULL && !LF_ISSET(DB_FCNTL_LOCKING)) - (void)__os_closehandle(dbenv, fhp); - /* - * If this is a real file and we are going to proceed with the removal, - * then we need to make sure that we don't leave any pages around in the - * mpool since the file is closed and will be reopened again before - * access. However, this might be an in-memory file, in which case - * we will handle the discard from the mpool later as it's the "real" - * removal of the database. - */ - if (ret == 0 && !F_ISSET(dbp, DB_AM_INMEM)) - F_SET(dbp, DB_AM_DISCARD); - return (ret); -} - -/* - * __fop_read_meta -- - * Read the meta-data page from a file and return it in buf. - * - * PUBLIC: int __fop_read_meta __P((DB_ENV *, const char *, - * PUBLIC: u_int8_t *, size_t, DB_FH *, int, size_t *)); - */ -int -__fop_read_meta(dbenv, name, buf, size, fhp, errok, nbytesp) - DB_ENV *dbenv; - const char *name; - u_int8_t *buf; - size_t size; - DB_FH *fhp; - int errok; - size_t *nbytesp; -{ - size_t nr; - int ret; - - /* - * Our caller wants to know the number of bytes read, even if we - * return an error. - */ - if (nbytesp != NULL) - *nbytesp = 0; - - nr = 0; - ret = __os_read(dbenv, fhp, buf, size, &nr); - if (nbytesp != NULL) - *nbytesp = nr; - - if (ret != 0) { - if (!errok) - __db_err(dbenv, "%s: %s", name, db_strerror(ret)); - goto err; - } - - if (nr != size) { - if (!errok) - __db_err(dbenv, - "%s: unexpected file type or format", name); - ret = EINVAL; - } - -err: - return (ret); -} - -/* - * __fop_dummy -- - * This implements the creation and name swapping of dummy files that - * we use for remove and rename (remove is simply a rename with a delayed - * remove). - * - * PUBLIC: int __fop_dummy __P((DB *, - * PUBLIC: DB_TXN *, const char *, const char *, u_int32_t)); - */ -int -__fop_dummy(dbp, txn, old, new, flags) - DB *dbp; - DB_TXN *txn; - const char *old, *new; - u_int32_t flags; -{ - DB *tmpdbp; - DB_ENV *dbenv; - DB_TXN *stxn; - char *back; - int ret, t_ret; - u_int8_t mbuf[DBMETASIZE]; - u_int32_t locker; - - dbenv = dbp->dbenv; - back = NULL; - stxn = NULL; - tmpdbp = NULL; - - DB_ASSERT(txn != NULL); - locker = txn->txnid; - - /* - * Begin sub transaction to encapsulate the rename. Note that we - * expect the inmem_swap calls to complete the sub-transaction, - * aborting on error and committing on success. - */ - if (TXN_ON(dbenv) && (ret = __txn_begin(dbenv, txn, &stxn, 0)) != 0) - goto err; - - /* We need to create a dummy file as a place holder. */ - if ((ret = __db_backup_name(dbenv, new, stxn, &back)) != 0) - goto err; - /* Create a dummy dbp handle. */ - if ((ret = db_create(&tmpdbp, dbenv, 0)) != 0) - goto err; - - memset(mbuf, 0, sizeof(mbuf)); - ret = F_ISSET(dbp, DB_AM_INMEM) ? - __fop_inmem_dummy(tmpdbp, stxn, back, mbuf) : - __fop_ondisk_dummy(tmpdbp, stxn, back, mbuf, flags); - - if (ret != 0) - goto err; - - ret = F_ISSET(dbp, DB_AM_INMEM) ? - __fop_inmem_swap(dbp, tmpdbp, stxn, old, new, back, locker) : - __fop_ondisk_swap(dbp, tmpdbp, stxn, old, new, back, locker, flags); - stxn = NULL; - if (ret != 0) - goto err; - -err: if (stxn != NULL) - (void)__txn_abort(stxn); - if (tmpdbp != NULL && - (t_ret = __db_close(tmpdbp, NULL, 0)) != 0 && ret == 0) - ret = t_ret; - if (back != NULL) - __os_free(dbenv, back); - return (ret); -} - -/* - * __fop_dbrename -- - * Do the appropriate file locking and file system operations - * to effect a dbrename in the absence of transactions (__fop_dummy - * and the subsequent calls in __db_rename do the work for the - * transactional case). - * - * PUBLIC: int __fop_dbrename __P((DB *, const char *, const char *)); - */ -int -__fop_dbrename(dbp, old, new) - DB *dbp; - const char *old, *new; -{ - DB_ENV *dbenv; - DB_LOCK elock; - char *real_new, *real_old; - int ret, t_ret; - - dbenv = dbp->dbenv; - real_new = NULL; - real_old = NULL; - LOCK_INIT(elock); - - if (F_ISSET(dbp, DB_AM_INMEM)) { - real_new = (char *)new; - real_old = (char *)old; - } else { - /* Get full names. */ - if ((ret = __db_appname(dbenv, - DB_APP_DATA, new, 0, NULL, &real_new)) != 0) - goto err; - - if ((ret = __db_appname(dbenv, - DB_APP_DATA, old, 0, NULL, &real_old)) != 0) - goto err; - - } - - /* - * It is an error to rename a file over one that already exists, - * as that wouldn't be transaction-safe. We check explicitly - * for ondisk files, but it's done memp_nameop for in-memory ones. - */ - GET_ENVLOCK(dbenv, dbp->lid, &elock); - ret = F_ISSET(dbp, DB_AM_INMEM) ? ENOENT : - __os_exists(real_new, NULL); - - if (ret == 0) { - ret = EEXIST; - __db_err(dbenv, "rename: file %s exists", real_new); - goto err; - } - - ret = __memp_nameop(dbenv, - dbp->fileid, new, real_old, real_new, F_ISSET(dbp, DB_AM_INMEM)); - -err: if ((t_ret = __ENV_LPUT(dbenv, elock)) != 0 && ret == 0) - ret = t_ret; - if (!F_ISSET(dbp, DB_AM_INMEM) && real_old != NULL) - __os_free(dbenv, real_old); - if (!F_ISSET(dbp, DB_AM_INMEM) && real_new != NULL) - __os_free(dbenv, real_new); - return (ret); -} - -static int -__fop_inmem_create(dbp, name, txn, flags) - DB *dbp; - const char *name; - DB_TXN *txn; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_LSN lsn; - DBT fid_dbt, name_dbt; - int ret; - int32_t lfid; - u_int32_t *p32; - - dbenv = dbp->dbenv; - - MAKE_INMEM(dbp); - - /* Set the pagesize if it isn't yet set. */ - if (dbp->pgsize == 0) - dbp->pgsize = DB_DEF_IOSIZE; - - /* - * Construct a file_id. - * - * If this file has no name, then we only need a fileid for locking. - * If this file has a name, we need the fileid both for locking and - * matching in the memory pool. So, with unnamed in-memory databases, - * use a lock_id. For named in-memory files, we need to find a value - * that we can use to uniquely identify a name/fid pair. We use a - * combination of a unique id (__os_unique_id) and a hash of the - * original name. - */ - if (name == NULL) { - if (LOCKING_ON(dbenv) && (ret = - __lock_id(dbenv, (u_int32_t *)dbp->fileid, NULL)) != 0) - goto err; - } else { - p32 = (u_int32_t *)(&dbp->fileid[0]); - __os_unique_id(dbenv, p32); - p32++; - (void)strncpy( - (char *)p32, name, DB_FILE_ID_LEN - sizeof(u_int32_t)); - dbp->preserve_fid = 1; - - if (DBENV_LOGGING(dbenv) && dbp->log_filename != NULL) - memcpy(dbp->log_filename->ufid, - dbp->fileid, DB_FILE_ID_LEN); - } - - /* Now, set the fileid. */ - if ((ret = __memp_set_fileid(dbp->mpf, dbp->fileid)) != 0) - goto err; - - if ((ret = __db_dbenv_mpool(dbp, name, flags)) != 0) - goto err; - - if (name != NULL && DBENV_LOGGING(dbenv)) { - memset(&name_dbt, 0, sizeof(name_dbt)); - name_dbt.data = (void *)name; - name_dbt.size = (u_int32_t)strlen(name) + 1; - memset(&fid_dbt, 0, sizeof(fid_dbt)); - fid_dbt.data = dbp->fileid; - fid_dbt.size = DB_FILE_ID_LEN; - lfid = dbp->log_filename == NULL ? - DB_LOGFILEID_INVALID : dbp->log_filename->id; - if ((ret = __crdel_inmem_create_log(dbenv, txn, - &lsn, 0, lfid, &name_dbt, &fid_dbt, dbp->pgsize)) != 0) - goto err; - } - - F_SET(dbp, DB_AM_CREATED); - -err: - return (ret); -} - -static int -__fop_inmem_read_meta(dbp, name, flags) - DB *dbp; - const char *name; - u_int32_t flags; -{ - DBMETA *metap; - db_pgno_t pgno; - int ret, t_ret; - - pgno = PGNO_BASE_MD; - if ((ret = __memp_fget(dbp->mpf, &pgno, 0, &metap)) != 0) - return (ret); - ret = __db_meta_setup(dbp->dbenv, dbp, name, metap, flags, 1); - - if ((t_ret = __memp_fput(dbp->mpf, metap, 0)) && ret == 0) - ret = t_ret; - - return (ret); -} - -static int -__fop_ondisk_dummy(dbp, txn, name, mbuf, flags) - DB *dbp; - DB_TXN *txn; - const char *name; - u_int8_t *mbuf; - u_int32_t flags; -{ - DB_ENV *dbenv; - int ret; - char *realname; - u_int32_t dflags; - - realname = NULL; - dbenv = dbp->dbenv; - dflags = F_ISSET(dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0; - - if ((ret = __db_appname(dbenv, - DB_APP_DATA, name, flags, NULL, &realname)) != 0) - goto err; - - if ((ret = __fop_create(dbenv, - txn, NULL, name, DB_APP_DATA, 0, dflags)) != 0) - goto err; - - if ((ret = - __os_fileid(dbenv, realname, 1, ((DBMETA *)mbuf)->uid)) != 0) - goto err; - - ((DBMETA *)mbuf)->magic = DB_RENAMEMAGIC; - if ((ret = __fop_write(dbenv, txn, name, - DB_APP_DATA, NULL, 0, 0, 0, mbuf, DBMETASIZE, 1, dflags)) != 0) - goto err; - - memcpy(dbp->fileid, ((DBMETA *)mbuf)->uid, DB_FILE_ID_LEN); - -err: if (realname != NULL) - __os_free(dbenv, realname); - - return (ret); -} - -static int -__fop_inmem_dummy(dbp, txn, name, mbuf) - DB *dbp; - DB_TXN *txn; - const char *name; - u_int8_t *mbuf; -{ - DBMETA *metap; - db_pgno_t pgno; - int ret, t_ret; - - if ((ret = __fop_inmem_create(dbp, name, txn, DB_CREATE)) != 0) - return (ret); - - pgno = PGNO_BASE_MD; - if ((ret = - __memp_fget(dbp->mpf, &pgno, DB_MPOOL_CREATE, &metap)) != 0) - return (ret); - /* Check file existed. */ - if (metap->magic != 0) - ret = EEXIST; - else - metap->magic = DB_RENAMEMAGIC; - - /* Copy the fileid onto the meta-data page. */ - memcpy(metap->uid, dbp->fileid, DB_FILE_ID_LEN); - - if ((t_ret = __memp_fput(dbp->mpf, - metap, ret == 0 ? DB_MPOOL_DIRTY : DB_MPOOL_DISCARD)) != 0 && - ret == 0) - ret = t_ret; - - if (ret != 0) - goto err; - - ((DBMETA *)mbuf)->magic = DB_RENAMEMAGIC; - -err: return (ret); -} - -static int -__fop_ondisk_swap(dbp, tmpdbp, txn, old, new, back, locker, flags) - DB *dbp, *tmpdbp; - DB_TXN *txn; - const char *old, *new, *back; - u_int32_t locker, flags; -{ - DB_ENV *dbenv; - DB_FH *fhp; - DB_LOCK elock; - DB_LSN lsn; - DBT fiddbt, namedbt, tmpdbt; - DB_TXN *parent; - char *realold, *realnew; - int ret, t_ret; - u_int8_t mbuf[DBMETASIZE]; - u_int32_t child_txnid, dflags; - - DB_ASSERT(txn != NULL); - DB_ASSERT(old != NULL); - - dbenv = dbp->dbenv; - realold = realnew = NULL; - LOCK_INIT(elock); - fhp = NULL; - dflags = F_ISSET(dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0; - - if ((ret = - __db_appname(dbenv, DB_APP_DATA, new, 0, NULL, &realnew)) != 0) - goto err; - - /* Now, lock the name space while we initialize this file. */ -retry: GET_ENVLOCK(dbenv, locker, &elock); - if (__os_exists(realnew, NULL) == 0) { - /* - * It is possible that the only reason this file exists is - * because we've done a previous rename of it and we have - * left a placeholder here. We need to check for that case - * and allow this rename to succeed if that's the case. - */ - if ((ret = __os_open(dbenv, realnew, 0, 0, &fhp)) != 0) - goto err; - if ((ret = __fop_read_meta(dbenv, - realnew, mbuf, sizeof(mbuf), fhp, 0, NULL)) != 0 || - (ret = __db_meta_setup(dbenv, - tmpdbp, realnew, (DBMETA *)mbuf, 0, 1)) != 0) { - ret = EEXIST; - goto err; - } - - /* - * Now, try to acquire the handle lock. If the handle is locked - * by our current, transaction, then we'll get it and life is - * good. - * - * Alternately, it's not locked at all, we'll get the lock, but - * we will realize it exists and consider this an error. - * - * However, if it's held by another transaction, then there - * could be two different scenarios: 1) the file is in the - * midst of being created or deleted and when that transaction - * is over, we might be able to proceed. 2) the file is open - * and exists and we should report an error. In order to - * distinguish these two cases, we do the following. First, we - * try to acquire a READLOCK. If the handle is in the midst of - * being created, then we'll block because a writelock is held. - * In that case, we should request a blocking write, and when we - * get the lock, we should then go back and check to see if the - * object exists and start all over again. - * - * If we got the READLOCK, then either no one is holding the - * lock or someone has an open handle and the fact that the file - * exists is problematic. So, in this case, we request the - * WRITELOCK non-blocking -- if it succeeds, we're golden. If - * it fails, then the file exists and we return EEXIST. - */ - if ((ret = __fop_lock_handle(dbenv, - tmpdbp, locker, DB_LOCK_READ, NULL, DB_LOCK_NOWAIT)) != 0) { - /* - * Someone holds a writelock. Try for the WRITELOCK - * and after we get it, retry. - */ - if ((ret = __fop_lock_handle(dbenv, tmpdbp, - locker, DB_LOCK_WRITE, &elock, 0)) != 0) - goto err; - - /* - * We now have the write lock; release it and start - * over. - */ - (void)__lock_put(dbenv, &tmpdbp->handle_lock); - (void)__db_refresh(tmpdbp, NULL, 0, NULL, 0); - goto retry; - } else { - /* We got the read lock; try to upgrade it. */ - ret = __fop_lock_handle(dbenv, - tmpdbp, locker, DB_LOCK_WRITE, - NULL, DB_LOCK_UPGRADE | DB_LOCK_NOWAIT); - if (ret != 0) { - /* - * We did not get the writelock, so someone - * has the handle open. This is an error. - */ - (void)__lock_put(dbenv, &tmpdbp->handle_lock); - ret = EEXIST; - } else if (F_ISSET(tmpdbp, DB_AM_IN_RENAME)) - /* We got the lock and are renaming it. */ - ret = 0; - else { /* We got the lock, but the file exists. */ - (void)__lock_put(dbenv, &tmpdbp->handle_lock); - ret = EEXIST; - } - } - if ((t_ret = __os_closehandle(dbenv, fhp)) != 0 && ret == 0) - ret = t_ret; - fhp = NULL; - if (ret != 0) - goto err; - } - - /* - * While we have the namespace locked, do the renames and then - * swap for the handle lock. - */ - if ((ret = __fop_rename(dbenv, - txn, old, new, dbp->fileid, DB_APP_DATA, dflags)) != 0) - goto err; - if ((ret = __fop_rename(dbenv, - txn, back, old, tmpdbp->fileid, DB_APP_DATA, dflags)) != 0) - goto err; - if ((ret = __fop_lock_handle(dbenv, - tmpdbp, locker, DB_LOCK_WRITE, &elock, NOWAIT_FLAG(txn))) != 0) - goto err; - - /* - * We just acquired a transactional lock on the tmp handle. - * We need to null out the tmp handle's lock so that it - * doesn't create problems for us in the close path. - */ - LOCK_INIT(tmpdbp->handle_lock); - - /* Commit the child. */ - child_txnid = txn->txnid; - parent = txn->parent; - ret = __txn_commit(txn, 0); - txn = NULL; - - /* Now log the child information in the parent. */ - memset(&fiddbt, 0, sizeof(fiddbt)); - memset(&tmpdbt, 0, sizeof(fiddbt)); - memset(&namedbt, 0, sizeof(namedbt)); - fiddbt.data = dbp->fileid; - fiddbt.size = DB_FILE_ID_LEN; - tmpdbt.data = tmpdbp->fileid; - tmpdbt.size = DB_FILE_ID_LEN; - namedbt.data = (void *)old; - namedbt.size = (u_int32_t)strlen(old) + 1; - if ((t_ret = __fop_file_remove_log(dbenv, - parent, &lsn, 0, &fiddbt, &tmpdbt, &namedbt, - (u_int32_t)DB_APP_DATA, child_txnid)) != 0 && ret == 0) - ret = t_ret; - - /* This is a delayed delete of the dummy file. */ - if ((ret = __db_appname(dbenv, - DB_APP_DATA, old, flags, NULL, &realold)) != 0) - goto err; - - if ((ret = __txn_remevent(dbenv, parent, realold, NULL, 0)) != 0) - goto err; - -err: if (txn != NULL) /* Ret must already be set, so void abort. */ - (void)__txn_abort(txn); - - (void)__ENV_LPUT(dbenv, elock); - if (realnew != NULL) - __os_free(dbenv, realnew); - if (realold != NULL) - __os_free(dbenv, realold); - return (ret); -} - -static int -__fop_inmem_swap(olddbp, backdbp, txn, old, new, back, locker) - DB *olddbp, *backdbp; - DB_TXN *txn; - const char *old, *new, *back; - u_int32_t locker; -{ - DB_ENV *dbenv; - DB_LOCK elock; - DB_LSN lsn; - DB_TXN *parent; - DBT fid_dbt, n1_dbt, n2_dbt; - DB *tmpdbp; - int ret, t_ret; - - dbenv = olddbp->dbenv; - parent = txn->parent; -retry: LOCK_INIT(elock); - if ((ret = db_create(&tmpdbp, dbenv, 0)) != 0) - return (ret); - MAKE_INMEM(tmpdbp); - - GET_ENVLOCK(dbenv, locker, &elock); - if ((ret = __db_dbenv_mpool(tmpdbp, new, 0)) == 0) { - /* - * It is possible that the only reason this database exists is - * because we've done a previous rename of it and we have - * left a placeholder here. We need to check for that case - * and allow this rename to succeed if that's the case. - */ - - if ((ret = __fop_inmem_read_meta(tmpdbp, new, 0)) != 0) { - ret = EEXIST; - goto err; - } - - /* - * Now, try to acquire the handle lock. If it's from our txn, - * then we'll get the lock. If it's not, then someone else has - * it locked. See the comments in __fop_ondisk_swap for - * details. - */ - if ((ret = __fop_lock_handle(dbenv, - tmpdbp, locker, DB_LOCK_READ, NULL, DB_LOCK_NOWAIT)) != 0) { - /* - * Someone holds a writelock. Try for the WRITELOCK - * and after we get it, retry. - */ - if ((ret = __fop_lock_handle(dbenv, tmpdbp, - locker, DB_LOCK_WRITE, &elock, 0)) != 0) - goto err; - - /* We now have the write lock; release it and start over. */ - (void)__lock_put(dbenv, &tmpdbp->handle_lock); - (void)__db_close(tmpdbp, NULL, DB_NOSYNC); - (void)__ENV_LPUT(dbenv, elock); - goto retry; - } else { - (void)__lock_put(dbenv, &tmpdbp->handle_lock); - if (!F_ISSET(tmpdbp, DB_AM_IN_RENAME)) - ret = EEXIST; - } - if (ret != 0) - goto err; - } - - /* Log the renames. */ - if (LOGGING_ON(dbenv)) { - /* Rename old to new. */ - memset(&fid_dbt, 0, sizeof(fid_dbt)); - fid_dbt.data = olddbp->fileid; - fid_dbt.size = DB_FILE_ID_LEN; - memset(&n1_dbt, 0, sizeof(n1_dbt)); - n1_dbt.data = (void *)old; - n1_dbt.size = (u_int32_t)strlen(old) + 1; - memset(&n2_dbt, 0, sizeof(n2_dbt)); - n2_dbt.data = (void *)new; - n2_dbt.size = (u_int32_t)strlen(new) + 1; - if ((ret = __crdel_inmem_rename_log(dbenv, txn, &lsn, 0, - &n1_dbt, &n2_dbt, &fid_dbt)) != 0) - goto err; - - /* Rename back to old */ - fid_dbt.data = backdbp->fileid; - n2_dbt.data = (char *)back; - n2_dbt.size = (u_int32_t)strlen(back) + 1; - if ((ret = __crdel_inmem_rename_log(dbenv, txn, &lsn, 0, - &n2_dbt, &n1_dbt, &fid_dbt)) != 0) - goto err; - } - - /* - * While we have the namespace locked, do the renames and then - * swap for the handle lock. If we ran into a file in the midst - * of rename, then we need to delete it first, else nameop is - * going to consider it an error. - */ - if (F_ISSET(tmpdbp, DB_AM_IN_RENAME)) { - if ((ret = __memp_nameop(dbenv, - tmpdbp->fileid, NULL, new, NULL, 1)) != 0) - goto err; - __txn_remrem(dbenv, parent, new); - } - - if ((ret = __memp_nameop(dbenv, olddbp->fileid, new, old, new, 1)) != 0) - goto err; - if ((ret = - __memp_nameop(dbenv, backdbp->fileid, old, back, old, 1)) != 0) - goto err; - - if ((ret = __fop_lock_handle(dbenv, - tmpdbp, locker, DB_LOCK_WRITE, &elock, 0)) != 0) - goto err; - - /* - * We just acquired a transactional lock on the tmp handle. - * We need to null out the tmp handle's lock so that it - * doesn't create problems for us in the close path. - */ - LOCK_INIT(tmpdbp->handle_lock); - - DB_ASSERT(txn != NULL); - - /* Commit the child. */ - ret = __txn_commit(txn, 0); - txn = NULL; - - if ((ret = __db_inmem_remove(backdbp, parent, old)) != 0) - goto err; - -err: (void)__ENV_LPUT(dbenv, elock); - - if (txn != NULL) - (void)__txn_abort(txn); - - if ((t_ret = __db_close(tmpdbp, NULL, 0)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} diff --git a/storage/bdb/hash/hash.c b/storage/bdb/hash/hash.c deleted file mode 100644 index 2d622249699..00000000000 --- a/storage/bdb/hash/hash.c +++ /dev/null @@ -1,2116 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994 - * Margo Seltzer. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Margo Seltzer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: hash.c,v 12.10 2005/10/20 18:57:07 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/btree.h" -#include "dbinc/hash.h" -#include "dbinc/lock.h" -#include "dbinc/mp.h" - -static int __ham_bulk __P((DBC *, DBT *, u_int32_t)); -static int __ham_c_close __P((DBC *, db_pgno_t, int *)); -static int __ham_c_del __P((DBC *)); -static int __ham_c_destroy __P((DBC *)); -static int __ham_c_get __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *)); -static int __ham_c_put __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *)); -static int __ham_c_writelock __P((DBC *)); -static int __ham_dup_return __P((DBC *, DBT *, u_int32_t)); -static int __ham_expand_table __P((DBC *)); -static int __ham_lookup __P((DBC *, - const DBT *, u_int32_t, db_lockmode_t, db_pgno_t *)); -static int __ham_overwrite __P((DBC *, DBT *, u_int32_t)); - -/* - * __ham_quick_delete -- - * This function is called by __db_del when the appropriate conditions - * are met, and it performs the delete in the optimized way. - * - * PUBLIC: int __ham_quick_delete __P((DBC *)); - */ -int -__ham_quick_delete(dbc) - DBC *dbc; -{ - int ret, t_ret; - - /* - * When performing a DB->del operation not involving secondary indices - * and not removing an off-page duplicate tree, we can speed things up - * substantially by removing the entire duplicate set, if any is - * present, in one operation, rather than by conjuring up and deleting - * each of the items individually. (All are stored in one big HKEYDATA - * structure.) We don't bother to distinguish on-page duplicate sets - * from single, non-dup items; they're deleted in exactly the same way. - * - * The cursor should be set to the first item in the duplicate set, or - * to the sole key/data pair when the key does not have a duplicate set, - * before the function is called. - * - * We do not need to call CDB_LOCKING_INIT, __db_del calls here with - * a write cursor. - * - * Assert we're initialized, but not to an off-page duplicate. - * Assert we're not using secondary indices. - */ - DB_ASSERT(IS_INITIALIZED(dbc)); - DB_ASSERT(dbc->internal->opd == NULL); - DB_ASSERT(!F_ISSET(dbc->dbp, DB_AM_SECONDARY)); - DB_ASSERT(LIST_FIRST(&dbc->dbp->s_secondaries) == NULL); - - if ((ret = __ham_get_meta(dbc)) != 0) - return (ret); - - if ((ret = __ham_c_writelock(dbc)) == 0) - ret = __ham_del_pair(dbc, 1); - - if ((t_ret = __ham_release_meta(dbc)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* ****************** CURSORS ********************************** */ -/* - * __ham_c_init -- - * Initialize the hash-specific portion of a cursor. - * - * PUBLIC: int __ham_c_init __P((DBC *)); - */ -int -__ham_c_init(dbc) - DBC *dbc; -{ - DB_ENV *dbenv; - HASH_CURSOR *new_curs; - int ret; - - dbenv = dbc->dbp->dbenv; - if ((ret = __os_calloc(dbenv, - 1, sizeof(struct cursor_t), &new_curs)) != 0) - return (ret); - if ((ret = __os_malloc(dbenv, - dbc->dbp->pgsize, &new_curs->split_buf)) != 0) { - __os_free(dbenv, new_curs); - return (ret); - } - - dbc->internal = (DBC_INTERNAL *) new_curs; - dbc->c_close = __db_c_close_pp; - dbc->c_count = __db_c_count_pp; - dbc->c_del = __db_c_del_pp; - dbc->c_dup = __db_c_dup_pp; - dbc->c_get = __db_c_get_pp; - dbc->c_pget = __db_c_pget_pp; - dbc->c_put = __db_c_put_pp; - dbc->c_am_bulk = __ham_bulk; - dbc->c_am_close = __ham_c_close; - dbc->c_am_del = __ham_c_del; - dbc->c_am_destroy = __ham_c_destroy; - dbc->c_am_get = __ham_c_get; - dbc->c_am_put = __ham_c_put; - dbc->c_am_writelock = __ham_c_writelock; - - return (__ham_item_init(dbc)); -} - -/* - * __ham_c_close -- - * Close down the cursor from a single use. - */ -static int -__ham_c_close(dbc, root_pgno, rmroot) - DBC *dbc; - db_pgno_t root_pgno; - int *rmroot; -{ - DB_MPOOLFILE *mpf; - HASH_CURSOR *hcp; - HKEYDATA *dp; - db_lockmode_t lock_mode; - int doroot, gotmeta, ret, t_ret; - u_int32_t dirty; - - COMPQUIET(rmroot, 0); - mpf = dbc->dbp->mpf; - dirty = 0; - doroot = gotmeta = ret = 0; - hcp = (HASH_CURSOR *) dbc->internal; - - /* Check for off page dups. */ - if (dbc->internal->opd != NULL) { - if ((ret = __ham_get_meta(dbc)) != 0) - goto done; - gotmeta = 1; - lock_mode = DB_LOCK_READ; - - /* To support dirty reads we must reget the write lock. */ - if (F_ISSET(dbc->dbp, DB_AM_READ_UNCOMMITTED) && - F_ISSET((BTREE_CURSOR *) - dbc->internal->opd->internal, C_DELETED)) - lock_mode = DB_LOCK_WRITE; - - if ((ret = __ham_get_cpage(dbc, lock_mode)) != 0) - goto out; - dp = (HKEYDATA *)H_PAIRDATA(dbc->dbp, hcp->page, hcp->indx); - - /* If it's not a dup we aborted before we changed it. */ - if (HPAGE_PTYPE(dp) == H_OFFDUP) - memcpy(&root_pgno, - HOFFPAGE_PGNO(dp), sizeof(db_pgno_t)); - else - root_pgno = PGNO_INVALID; - - if ((ret = - hcp->opd->c_am_close(hcp->opd, root_pgno, &doroot)) != 0) - goto out; - if (doroot != 0) { - if ((ret = __ham_del_pair(dbc, 1)) != 0) - goto out; - dirty = DB_MPOOL_DIRTY; - } - } - -out: if (hcp->page != NULL && (t_ret = - __memp_fput(mpf, hcp->page, dirty)) != 0 && ret == 0) - ret = t_ret; - if (gotmeta != 0 && (t_ret = __ham_release_meta(dbc)) != 0 && ret == 0) - ret = t_ret; - -done: if ((t_ret = __ham_item_init(dbc)) != 0 && ret == 0) - ret = t_ret; - return (ret); -} - -/* - * __ham_c_destroy -- - * Cleanup the access method private part of a cursor. - */ -static int -__ham_c_destroy(dbc) - DBC *dbc; -{ - HASH_CURSOR *hcp; - - hcp = (HASH_CURSOR *)dbc->internal; - if (hcp->split_buf != NULL) - __os_free(dbc->dbp->dbenv, hcp->split_buf); - __os_free(dbc->dbp->dbenv, hcp); - - return (0); -} - -/* - * __ham_c_count -- - * Return a count of on-page duplicates. - * - * PUBLIC: int __ham_c_count __P((DBC *, db_recno_t *)); - */ -int -__ham_c_count(dbc, recnop) - DBC *dbc; - db_recno_t *recnop; -{ - DB *dbp; - DB_MPOOLFILE *mpf; - HASH_CURSOR *hcp; - db_indx_t len; - db_recno_t recno; - int ret, t_ret; - u_int8_t *p, *pend; - - dbp = dbc->dbp; - mpf = dbp->mpf; - hcp = (HASH_CURSOR *)dbc->internal; - - recno = 0; - - if ((ret = __ham_get_cpage(dbc, DB_LOCK_READ)) != 0) - return (ret); - if (hcp->indx >= NUM_ENT(hcp->page)) { - *recnop = 0; - goto err; - } - - switch (HPAGE_PTYPE(H_PAIRDATA(dbp, hcp->page, hcp->indx))) { - case H_KEYDATA: - case H_OFFPAGE: - recno = 1; - break; - case H_DUPLICATE: - p = HKEYDATA_DATA(H_PAIRDATA(dbp, hcp->page, hcp->indx)); - pend = p + - LEN_HDATA(dbp, hcp->page, dbp->pgsize, hcp->indx); - for (; p < pend; recno++) { - /* p may be odd, so copy rather than just dereffing */ - memcpy(&len, p, sizeof(db_indx_t)); - p += 2 * sizeof(db_indx_t) + len; - } - - break; - default: - ret = __db_pgfmt(dbp->dbenv, hcp->pgno); - goto err; - } - - *recnop = recno; - -err: if ((t_ret = __memp_fput(mpf, hcp->page, 0)) != 0 && ret == 0) - ret = t_ret; - hcp->page = NULL; - return (ret); -} - -static int -__ham_c_del(dbc) - DBC *dbc; -{ - DB *dbp; - DBT repldbt; - DB_MPOOLFILE *mpf; - HASH_CURSOR *hcp; - int ret, t_ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - hcp = (HASH_CURSOR *)dbc->internal; - - if (F_ISSET(hcp, H_DELETED)) - return (DB_NOTFOUND); - - if ((ret = __ham_get_meta(dbc)) != 0) - goto out; - - if ((ret = __ham_get_cpage(dbc, DB_LOCK_WRITE)) != 0) - goto out; - - /* Off-page duplicates. */ - if (HPAGE_TYPE(dbp, hcp->page, H_DATAINDEX(hcp->indx)) == H_OFFDUP) - goto out; - - if (F_ISSET(hcp, H_ISDUP)) { /* On-page duplicate. */ - if (hcp->dup_off == 0 && - DUP_SIZE(hcp->dup_len) == LEN_HDATA(dbp, hcp->page, - hcp->hdr->dbmeta.pagesize, hcp->indx)) - ret = __ham_del_pair(dbc, 1); - else { - repldbt.flags = 0; - F_SET(&repldbt, DB_DBT_PARTIAL); - repldbt.doff = hcp->dup_off; - repldbt.dlen = DUP_SIZE(hcp->dup_len); - repldbt.size = 0; - repldbt.data = HKEYDATA_DATA(H_PAIRDATA(dbp, hcp->page, - hcp->indx)); - if ((ret = __ham_replpair(dbc, &repldbt, 0)) == 0) { - hcp->dup_tlen -= DUP_SIZE(hcp->dup_len); - F_SET(hcp, H_DELETED); - ret = __ham_c_update(dbc, - DUP_SIZE(hcp->dup_len), 0, 1); - } - } - - } else /* Not a duplicate */ - ret = __ham_del_pair(dbc, 1); - -out: if (hcp->page != NULL) { - if ((t_ret = __memp_fput(mpf, - hcp->page, ret == 0 ? DB_MPOOL_DIRTY : 0)) != 0 && ret == 0) - ret = t_ret; - hcp->page = NULL; - } - if ((t_ret = __ham_release_meta(dbc)) != 0 && ret == 0) - ret = t_ret; - return (ret); -} - -/* - * __ham_c_dup -- - * Duplicate a hash cursor, such that the new one holds appropriate - * locks for the position of the original. - * - * PUBLIC: int __ham_c_dup __P((DBC *, DBC *)); - */ -int -__ham_c_dup(orig_dbc, new_dbc) - DBC *orig_dbc, *new_dbc; -{ - HASH_CURSOR *orig, *new; - int ret; - - orig = (HASH_CURSOR *)orig_dbc->internal; - new = (HASH_CURSOR *)new_dbc->internal; - - new->bucket = orig->bucket; - new->lbucket = orig->lbucket; - new->dup_off = orig->dup_off; - new->dup_len = orig->dup_len; - new->dup_tlen = orig->dup_tlen; - - if (F_ISSET(orig, H_DELETED)) - F_SET(new, H_DELETED); - if (F_ISSET(orig, H_ISDUP)) - F_SET(new, H_ISDUP); - - /* - * If the old cursor held a lock and we're not in transactions, get one - * for the new one. The reason that we don't need a new lock if we're - * in a transaction is because we already hold a lock and will continue - * to do so until commit, so there is no point in re-acquiring it. We - * don't know if the old lock was a read or write lock, but it doesn't - * matter. We'll get a read lock. We know that this locker already - * holds a lock of the correct type, so if we need a write lock and - * request it, we know that we'll get it. - */ - if (orig_dbc->txn == NULL && LOCK_ISSET(orig->lock)) - if ((ret = __ham_lock_bucket(new_dbc, DB_LOCK_READ)) != 0) - return (ret); - - return (0); -} - -static int -__ham_c_get(dbc, key, data, flags, pgnop) - DBC *dbc; - DBT *key; - DBT *data; - u_int32_t flags; - db_pgno_t *pgnop; -{ - DB *dbp; - DB_MPOOLFILE *mpf; - HASH_CURSOR *hcp; - db_lockmode_t lock_type; - int get_key, ret, t_ret; - - hcp = (HASH_CURSOR *)dbc->internal; - dbp = dbc->dbp; - mpf = dbp->mpf; - - /* Clear OR'd in additional bits so we can check for flag equality. */ - if (F_ISSET(dbc, DBC_RMW)) - lock_type = DB_LOCK_WRITE; - else - lock_type = DB_LOCK_READ; - - if ((ret = __ham_get_meta(dbc)) != 0) - return (ret); - hcp->seek_size = 0; - - ret = 0; - get_key = 1; - switch (flags) { - case DB_PREV_NODUP: - F_SET(hcp, H_NEXT_NODUP); - /* FALLTHROUGH */ - case DB_PREV: - if (IS_INITIALIZED(dbc)) { - ret = __ham_item_prev(dbc, lock_type, pgnop); - break; - } - /* FALLTHROUGH */ - case DB_LAST: - ret = __ham_item_last(dbc, lock_type, pgnop); - break; - case DB_NEXT_NODUP: - F_SET(hcp, H_NEXT_NODUP); - /* FALLTHROUGH */ - case DB_NEXT: - if (IS_INITIALIZED(dbc)) { - ret = __ham_item_next(dbc, lock_type, pgnop); - break; - } - /* FALLTHROUGH */ - case DB_FIRST: - ret = __ham_item_first(dbc, lock_type, pgnop); - break; - case DB_NEXT_DUP: - /* cgetchk has already determined that the cursor is set. */ - F_SET(hcp, H_DUPONLY); - ret = __ham_item_next(dbc, lock_type, pgnop); - break; - case DB_SET: - case DB_SET_RANGE: - case DB_GET_BOTH: - case DB_GET_BOTH_RANGE: - ret = __ham_lookup(dbc, key, 0, lock_type, pgnop); - get_key = 0; - break; - case DB_GET_BOTHC: - F_SET(hcp, H_DUPONLY); - - ret = __ham_item_next(dbc, lock_type, pgnop); - get_key = 0; - break; - case DB_CURRENT: - /* cgetchk has already determined that the cursor is set. */ - if (F_ISSET(hcp, H_DELETED)) { - ret = DB_KEYEMPTY; - goto err; - } - - ret = __ham_item(dbc, lock_type, pgnop); - break; - default: - ret = __db_unknown_flag(dbp->dbenv, "__ham_c_get", flags); - break; - } - - /* - * Must always enter this loop to do error handling and - * check for big key/data pair. - */ - for (;;) { - if (ret != 0 && ret != DB_NOTFOUND) - goto err; - else if (F_ISSET(hcp, H_OK)) { - if (*pgnop == PGNO_INVALID) - ret = __ham_dup_return(dbc, data, flags); - break; - } else if (!F_ISSET(hcp, H_NOMORE)) { - __db_err(dbp->dbenv, - "H_NOMORE returned to __ham_c_get"); - ret = EINVAL; - break; - } - - /* - * Ran out of entries in a bucket; change buckets. - */ - switch (flags) { - case DB_LAST: - case DB_PREV: - case DB_PREV_NODUP: - ret = __memp_fput(mpf, hcp->page, 0); - hcp->page = NULL; - if (hcp->bucket == 0) { - ret = DB_NOTFOUND; - hcp->pgno = PGNO_INVALID; - goto err; - } - F_CLR(hcp, H_ISDUP); - hcp->bucket--; - hcp->indx = NDX_INVALID; - hcp->pgno = BUCKET_TO_PAGE(hcp, hcp->bucket); - if (ret == 0) - ret = __ham_item_prev(dbc, - lock_type, pgnop); - break; - case DB_FIRST: - case DB_NEXT: - case DB_NEXT_NODUP: - ret = __memp_fput(mpf, hcp->page, 0); - hcp->page = NULL; - hcp->indx = NDX_INVALID; - hcp->bucket++; - F_CLR(hcp, H_ISDUP); - hcp->pgno = BUCKET_TO_PAGE(hcp, hcp->bucket); - if (hcp->bucket > hcp->hdr->max_bucket) { - ret = DB_NOTFOUND; - hcp->pgno = PGNO_INVALID; - goto err; - } - if (ret == 0) - ret = __ham_item_next(dbc, - lock_type, pgnop); - break; - case DB_GET_BOTH: - case DB_GET_BOTHC: - case DB_GET_BOTH_RANGE: - case DB_NEXT_DUP: - case DB_SET: - case DB_SET_RANGE: - /* Key not found. */ - ret = DB_NOTFOUND; - goto err; - case DB_CURRENT: - /* - * This should only happen if you are doing - * deletes and reading with concurrent threads - * and not doing proper locking. We return - * the same error code as we would if the - * cursor were deleted. - */ - ret = DB_KEYEMPTY; - goto err; - default: - DB_ASSERT(0); - } - } - - if (get_key == 0) - F_SET(key, DB_DBT_ISSET); - -err: if ((t_ret = __ham_release_meta(dbc)) != 0 && ret == 0) - ret = t_ret; - - F_CLR(hcp, H_DUPONLY); - F_CLR(hcp, H_NEXT_NODUP); - - return (ret); -} - -/* - * __ham_bulk -- Return bulk data from a hash table. - */ -static int -__ham_bulk(dbc, data, flags) - DBC *dbc; - DBT *data; - u_int32_t flags; -{ - DB *dbp; - DB_MPOOLFILE *mpf; - HASH_CURSOR *cp; - PAGE *pg; - db_indx_t dup_len, dup_off, dup_tlen, indx, *inp; - db_lockmode_t lock_mode; - db_pgno_t pgno; - int32_t *endp, *offp, *saveoff; - u_int32_t key_off, key_size, pagesize, size, space; - u_int8_t *dbuf, *dp, *hk, *np, *tmp; - int is_dup, is_key; - int need_pg, next_key, no_dup, ret, t_ret; - - ret = 0; - key_off = 0; - dup_len = dup_off = dup_tlen = 0; - size = 0; - dbp = dbc->dbp; - pagesize = dbp->pgsize; - mpf = dbp->mpf; - cp = (HASH_CURSOR *)dbc->internal; - is_key = LF_ISSET(DB_MULTIPLE_KEY) ? 1 : 0; - next_key = is_key && LF_ISSET(DB_OPFLAGS_MASK) != DB_NEXT_DUP; - no_dup = LF_ISSET(DB_OPFLAGS_MASK) == DB_NEXT_NODUP; - dbuf = data->data; - np = dp = dbuf; - - /* Keep track of space that is left. There is an termination entry */ - space = data->ulen; - space -= sizeof(*offp); - - /* Build the offset/size table from the end up. */ - endp = (int32_t *) ((u_int8_t *)dbuf + data->ulen); - endp--; - offp = endp; - - key_size = 0; - lock_mode = F_ISSET(dbc, DBC_RMW) ? DB_LOCK_WRITE: DB_LOCK_READ; - -next_pg: - need_pg = 1; - indx = cp->indx; - pg = cp->page; - inp = P_INP(dbp, pg); - - do { - if (is_key) { - hk = H_PAIRKEY(dbp, pg, indx); - if (HPAGE_PTYPE(hk) == H_OFFPAGE) { - memcpy(&key_size, - HOFFPAGE_TLEN(hk), sizeof(u_int32_t)); - memcpy(&pgno, - HOFFPAGE_PGNO(hk), sizeof(db_pgno_t)); - size = key_size; - if (key_size > space) - goto get_key_space; - if ((ret = __bam_bulk_overflow( - dbc, key_size, pgno, np)) != 0) - return (ret); - space -= key_size; - key_off = (u_int32_t)(np - dbuf); - np += key_size; - } else { - if (need_pg) { - dp = np; - size = pagesize - HOFFSET(pg); - if (space < size) { -get_key_space: - if (offp == endp) { - data->size = (u_int32_t) - DB_ALIGN(size + - pagesize, 1024); - return - (DB_BUFFER_SMALL); - } - goto back_up; - } - memcpy(dp, - (u_int8_t *)pg + HOFFSET(pg), size); - need_pg = 0; - space -= size; - np += size; - } - key_size = LEN_HKEY(dbp, pg, pagesize, indx); - key_off = ((inp[indx] - HOFFSET(pg)) + - (u_int32_t)(dp - dbuf)) + - SSZA(HKEYDATA, data); - } - } - - hk = H_PAIRDATA(dbp, pg, indx); - switch (HPAGE_PTYPE(hk)) { - case H_DUPLICATE: - case H_KEYDATA: - if (need_pg) { - dp = np; - size = pagesize - HOFFSET(pg); - if (space < size) { -back_up: - if (indx != 0) { - indx -= 2; - /* XXX - * It's not clear that this is - * the right way to fix this, - * but here goes. - * If we are backing up onto a - * duplicate, then we need to - * position ourselves at the - * end of the duplicate set. - * We probably need to make - * this work for H_OFFDUP too. - * It might be worth making a - * dummy cursor and calling - * __ham_item_prev. - */ - tmp = H_PAIRDATA(dbp, pg, indx); - if (HPAGE_PTYPE(tmp) == - H_DUPLICATE) { - dup_off = dup_tlen = - LEN_HDATA(dbp, pg, - pagesize, indx + 1); - memcpy(&dup_len, - HKEYDATA_DATA(tmp), - sizeof(db_indx_t)); - } else { - is_dup = 0; - dup_len = 0; - dup_off = 0; - dup_tlen = 0; - F_CLR(cp, H_ISDUP); - } - goto get_space; - } - /* indx == 0 */ - cp->dup_len = dup_len; - cp->dup_off = dup_off; - cp->dup_tlen = dup_tlen; - if ((ret = __ham_item_prev(dbc, - lock_mode, &pgno)) != 0) { - if (ret != DB_NOTFOUND) - return (ret); - if ((ret = __memp_fput(mpf, - cp->page, 0)) != 0) - return (ret); - cp->page = NULL; - if (cp->bucket == 0) { - cp->indx = indx = - NDX_INVALID; - goto get_space; - } - if ((ret = - __ham_get_meta(dbc)) != 0) - return (ret); - - cp->bucket--; - cp->pgno = BUCKET_TO_PAGE(cp, - cp->bucket); - cp->indx = NDX_INVALID; - if ((ret = __ham_release_meta( - dbc)) != 0) - return (ret); - if ((ret = __ham_item_prev(dbc, - lock_mode, &pgno)) != 0) - return (ret); - } - indx = cp->indx; -get_space: - /* - * See if we put any data in the buffer. - */ - if (offp >= endp || - F_ISSET(dbc, DBC_TRANSIENT)) { - data->size = (u_int32_t) - DB_ALIGN(size + - data->ulen - space, 1024); - return (DB_BUFFER_SMALL); - } - /* - * Don't continue; we're all out - * of space, even though we're - * returning success. - */ - next_key = 0; - break; - } - memcpy(dp, (u_int8_t *)pg + HOFFSET(pg), size); - need_pg = 0; - space -= size; - np += size; - } - - /* - * We're about to crack the offset(s) and length(s) - * out of an H_KEYDATA or H_DUPLICATE item. - * There are three cases: - * 1. We were moved into a duplicate set by - * the standard hash cursor code. Respect - * the dup_off and dup_tlen we were given. - * 2. We stumbled upon a duplicate set while - * walking the page on our own. We need to - * recognize it as a dup and set dup_off and - * dup_tlen. - * 3. The current item is not a dup. - */ - if (F_ISSET(cp, H_ISDUP)) { - /* Case 1 */ - is_dup = 1; - dup_len = cp->dup_len; - dup_off = cp->dup_off; - dup_tlen = cp->dup_tlen; - } else if (HPAGE_PTYPE(hk) == H_DUPLICATE) { - /* Case 2 */ - is_dup = 1; - /* - * If we run out of memory and bail, - * make sure the fact we're in a dup set - * isn't ignored later. - */ - F_SET(cp, H_ISDUP); - dup_off = 0; - memcpy(&dup_len, - HKEYDATA_DATA(hk), sizeof(db_indx_t)); - dup_tlen = LEN_HDATA(dbp, pg, pagesize, indx); - } else { - /* Case 3 */ - is_dup = 0; - dup_len = 0; - dup_off = 0; - dup_tlen = 0; - } - - do { - space -= (is_key ? 4 : 2) * sizeof(*offp); - size += (is_key ? 4 : 2) * sizeof(*offp); - /* - * Since space is an unsigned, if we happen - * to wrap, then this comparison will turn out - * to be true. XXX Wouldn't it be better to - * simply check above that space is greater than - * the value we're about to subtract??? - */ - if (space > data->ulen) { - if (!is_dup || dup_off == 0) - goto back_up; - dup_off -= (db_indx_t) - DUP_SIZE((u_int32_t)offp[1]); - goto get_space; - } - if (is_key) { - *offp-- = (int32_t)key_off; - *offp-- = (int32_t)key_size; - } - if (is_dup) { - *offp-- = (int32_t)( - ((inp[indx + 1] - HOFFSET(pg)) + - dp - dbuf) + SSZA(HKEYDATA, data) + - dup_off + sizeof(db_indx_t)); - memcpy(&dup_len, - HKEYDATA_DATA(hk) + dup_off, - sizeof(db_indx_t)); - dup_off += DUP_SIZE(dup_len); - *offp-- = dup_len; - } else { - *offp-- = (int32_t)( - ((inp[indx + 1] - HOFFSET(pg)) + - dp - dbuf) + SSZA(HKEYDATA, data)); - *offp-- = LEN_HDATA(dbp, pg, - pagesize, indx); - } - } while (is_dup && dup_off < dup_tlen && no_dup == 0); - F_CLR(cp, H_ISDUP); - break; - case H_OFFDUP: - memcpy(&pgno, HOFFPAGE_PGNO(hk), sizeof(db_pgno_t)); - space -= 2 * sizeof(*offp); - if (space > data->ulen) - goto back_up; - - if (is_key) { - space -= 2 * sizeof(*offp); - if (space > data->ulen) - goto back_up; - *offp-- = (int32_t)key_off; - *offp-- = (int32_t)key_size; - } - saveoff = offp; - if ((ret = __bam_bulk_duplicates(dbc, - pgno, dbuf, is_key ? offp + 2 : NULL, - &offp, &np, &space, no_dup)) != 0) { - if (ret == DB_BUFFER_SMALL) { - size = space; - space = 0; - if (is_key && saveoff == offp) { - offp += 2; - goto back_up; - } - goto get_space; - } - return (ret); - } - break; - case H_OFFPAGE: - space -= (is_key ? 4 : 2) * sizeof(*offp); - if (space > data->ulen) - goto back_up; - - memcpy(&size, HOFFPAGE_TLEN(hk), sizeof(u_int32_t)); - memcpy(&pgno, HOFFPAGE_PGNO(hk), sizeof(db_pgno_t)); - if (size > space) - goto back_up; - - if ((ret = - __bam_bulk_overflow(dbc, size, pgno, np)) != 0) - return (ret); - - if (is_key) { - *offp-- = (int32_t)key_off; - *offp-- = (int32_t)key_size; - } - - *offp-- = (int32_t)(np - dbuf); - *offp-- = (int32_t)size; - - np += size; - space -= size; - break; - default: - /* Do nothing. */ - break; - } - } while (next_key && (indx += 2) < NUM_ENT(pg)); - - cp->indx = indx; - cp->dup_len = dup_len; - cp->dup_off = dup_off; - cp->dup_tlen = dup_tlen; - - /* If we are off the page then try to the next page. */ - if (ret == 0 && next_key && indx >= NUM_ENT(pg)) { - if ((ret = __ham_item_next(dbc, lock_mode, &pgno)) == 0) - goto next_pg; - if (ret != DB_NOTFOUND) - return (ret); - if ((ret = __memp_fput(dbc->dbp->mpf, cp->page, 0)) != 0) - return (ret); - cp->page = NULL; - if ((ret = __ham_get_meta(dbc)) != 0) - return (ret); - - cp->bucket++; - if (cp->bucket > cp->hdr->max_bucket) { - /* - * Restore cursor to its previous state. We're past - * the last item in the last bucket, so the next - * DBC->c_get(DB_NEXT) will return DB_NOTFOUND. - */ - cp->bucket--; - ret = DB_NOTFOUND; - } else { - /* - * Start on the next bucket. - * - * Note that if this new bucket happens to be empty, - * but there's another non-empty bucket after it, - * we'll return early. This is a rare case, and we - * don't guarantee any particular number of keys - * returned on each call, so just let the next call - * to bulk get move forward by yet another bucket. - */ - cp->pgno = BUCKET_TO_PAGE(cp, cp->bucket); - cp->indx = NDX_INVALID; - F_CLR(cp, H_ISDUP); - ret = __ham_item_next(dbc, lock_mode, &pgno); - } - - if ((t_ret = __ham_release_meta(dbc)) != 0) - return (t_ret); - if (ret == 0) - goto next_pg; - if (ret != DB_NOTFOUND) - return (ret); - } - *offp = -1; - return (0); -} - -static int -__ham_c_put(dbc, key, data, flags, pgnop) - DBC *dbc; - DBT *key; - DBT *data; - u_int32_t flags; - db_pgno_t *pgnop; -{ - DB *dbp; - DB_MPOOLFILE *mpf; - DBT tmp_val, *myval; - HASH_CURSOR *hcp; - u_int32_t nbytes; - int ret, t_ret; - - /* - * The compiler doesn't realize that we only use this when ret is - * equal to 0 and that if ret is equal to 0, that we must have set - * myval. So, we initialize it here to shut the compiler up. - */ - COMPQUIET(myval, NULL); - - dbp = dbc->dbp; - mpf = dbp->mpf; - hcp = (HASH_CURSOR *)dbc->internal; - - if (F_ISSET(hcp, H_DELETED) && - flags != DB_KEYFIRST && flags != DB_KEYLAST) - return (DB_NOTFOUND); - - if ((ret = __ham_get_meta(dbc)) != 0) - goto err1; - - switch (flags) { - case DB_KEYLAST: - case DB_KEYFIRST: - case DB_NODUPDATA: - nbytes = (ISBIG(hcp, key->size) ? HOFFPAGE_PSIZE : - HKEYDATA_PSIZE(key->size)) + - (ISBIG(hcp, data->size) ? HOFFPAGE_PSIZE : - HKEYDATA_PSIZE(data->size)); - if ((ret = __ham_lookup(dbc, - key, nbytes, DB_LOCK_WRITE, pgnop)) == DB_NOTFOUND) { - ret = 0; - if (hcp->seek_found_page != PGNO_INVALID && - hcp->seek_found_page != hcp->pgno) { - if ((ret = __memp_fput(mpf, hcp->page, 0)) != 0) - goto err2; - hcp->page = NULL; - hcp->pgno = hcp->seek_found_page; - hcp->indx = NDX_INVALID; - } - - if (F_ISSET(data, DB_DBT_PARTIAL) && data->doff != 0) { - /* - * A partial put, but the key does not exist - * and we are not beginning the write at 0. - * We must create a data item padded up to doff - * and then write the new bytes represented by - * val. - */ - if ((ret = __ham_init_dbt(dbp->dbenv, &tmp_val, - data->size + data->doff, - &dbc->my_rdata.data, - &dbc->my_rdata.ulen)) == 0) { - memset(tmp_val.data, 0, data->doff); - memcpy((u_int8_t *)tmp_val.data + - data->doff, data->data, data->size); - myval = &tmp_val; - } - } else - myval = (DBT *)data; - - if (ret == 0) - ret = __ham_add_el(dbc, key, myval, H_KEYDATA); - goto done; - } - break; - case DB_BEFORE: - case DB_AFTER: - case DB_CURRENT: - ret = __ham_item(dbc, DB_LOCK_WRITE, pgnop); - break; - default: - ret = __db_unknown_flag(dbp->dbenv, "__ham_c_put", flags); - break; - } - - if (*pgnop == PGNO_INVALID && ret == 0) { - if (flags == DB_CURRENT || - ((flags == DB_KEYFIRST || - flags == DB_KEYLAST || flags == DB_NODUPDATA) && - !(F_ISSET(dbp, DB_AM_DUP) || F_ISSET(key, DB_DBT_DUPOK)))) - ret = __ham_overwrite(dbc, data, flags); - else - ret = __ham_add_dup(dbc, data, flags, pgnop); - } - -done: if (hcp->page != NULL) { - if ((t_ret = __memp_fput(mpf, - hcp->page, DB_MPOOL_DIRTY)) != 0 && ret == 0) - ret = t_ret; - if (t_ret == 0) - hcp->page = NULL; - } - - if (ret == 0 && F_ISSET(hcp, H_EXPAND)) { - ret = __ham_expand_table(dbc); - F_CLR(hcp, H_EXPAND); - /* If we are out of space, ignore the error. */ - if (ret == ENOSPC && dbc->txn == NULL) - ret = 0; - } - -err2: if ((t_ret = __ham_release_meta(dbc)) != 0 && ret == 0) - ret = t_ret; - -err1: return (ret); -} - -/********************************* UTILITIES ************************/ - -/* - * __ham_expand_table -- - */ -static int -__ham_expand_table(dbc) - DBC *dbc; -{ - DB *dbp; - DB_LOCK metalock; - DB_LSN lsn; - DB_MPOOLFILE *mpf; - DBMETA *mmeta; - HASH_CURSOR *hcp; - PAGE *h; - db_pgno_t pgno, mpgno; - u_int32_t dirty_meta, logn, newalloc, new_bucket, old_bucket; - int got_meta, new_double, ret, t_ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - hcp = (HASH_CURSOR *)dbc->internal; - if ((ret = __ham_dirty_meta(dbc)) != 0) - return (ret); - - LOCK_INIT(metalock); - mmeta = (DBMETA *) hcp->hdr; - mpgno = mmeta->pgno; - h = NULL; - dirty_meta = newalloc = 0; - got_meta = 0; - - /* - * If the split point is about to increase, make sure that we - * have enough extra pages. The calculation here is weird. - * We'd like to do this after we've upped max_bucket, but it's - * too late then because we've logged the meta-data split. What - * we'll do between then and now is increment max bucket and then - * see what the log of one greater than that is; here we have to - * look at the log of max + 2. VERY NASTY STUFF. - * - * We figure out what we need to do, then we log it, then request - * the pages from mpool. We don't want to fail after extending - * the file. - * - * If the page we are about to split into has already been allocated, - * then we simply need to get it to get its LSN. If it hasn't yet - * been allocated, then we know it's LSN (0,0). - */ - - new_bucket = hcp->hdr->max_bucket + 1; - old_bucket = new_bucket & hcp->hdr->low_mask; - - new_double = hcp->hdr->max_bucket == hcp->hdr->high_mask; - logn = __db_log2(new_bucket); - - if (!new_double || hcp->hdr->spares[logn + 1] != PGNO_INVALID) { - /* Page exists; get it so we can get its LSN */ - pgno = BUCKET_TO_PAGE(hcp, new_bucket); - if ((ret = - __memp_fget(mpf, &pgno, DB_MPOOL_CREATE, &h)) != 0) - goto err; - lsn = h->lsn; - } else { - /* Get the master meta-data page to do allocation. */ - if (F_ISSET(dbp, DB_AM_SUBDB)) { - mpgno = PGNO_BASE_MD; - if ((ret = __db_lget(dbc, - 0, mpgno, DB_LOCK_WRITE, 0, &metalock)) != 0) - goto err; - if ((ret = __memp_fget(mpf, &mpgno, 0, &mmeta)) != 0) - goto err; - got_meta = 1; - } - pgno = mmeta->last_pgno + 1; - ZERO_LSN(lsn); - newalloc = 1; - } - - /* Log the meta-data split first. */ - if (DBC_LOGGING(dbc)) { - /* - * We always log the page number of the first page of - * the allocation group. However, the LSN that we log - * is either the LSN on the first page (if we did not - * do the actual allocation here) or the LSN on the last - * page of the unit (if we did do the allocation here). - */ - if ((ret = __ham_metagroup_log(dbp, dbc->txn, - &lsn, 0, hcp->hdr->max_bucket, mpgno, &mmeta->lsn, - hcp->hdr->dbmeta.pgno, &hcp->hdr->dbmeta.lsn, - pgno, &lsn, newalloc, mmeta->last_pgno)) != 0) - goto err; - } else - LSN_NOT_LOGGED(lsn); - - hcp->hdr->dbmeta.lsn = lsn; - - if (new_double && hcp->hdr->spares[logn + 1] == PGNO_INVALID) { - /* - * We need to begin a new doubling and we have not allocated - * any pages yet. Read the last page in and initialize it to - * make the allocation contiguous. The pgno we calculated - * above is the first page allocated. The entry in spares is - * that page number minus any buckets already allocated (it - * simplifies bucket to page transaction). After we've set - * that, we calculate the last pgno. - */ - - pgno += hcp->hdr->max_bucket; - - if ((ret = __memp_fget(mpf, &pgno, DB_MPOOL_CREATE, &h)) != 0) - goto err; - - hcp->hdr->spares[logn + 1] = - (pgno - new_bucket) - hcp->hdr->max_bucket; - mmeta->last_pgno = pgno; - mmeta->lsn = lsn; - dirty_meta = DB_MPOOL_DIRTY; - - P_INIT(h, dbp->pgsize, - pgno, PGNO_INVALID, PGNO_INVALID, 0, P_HASH); - } - - /* Write out whatever page we ended up modifying. */ - h->lsn = lsn; - if ((ret = __memp_fput(mpf, h, DB_MPOOL_DIRTY)) != 0) - goto err; - h = NULL; - - /* - * Update the meta-data page of this hash database. - */ - hcp->hdr->max_bucket = new_bucket; - if (new_double) { - hcp->hdr->low_mask = hcp->hdr->high_mask; - hcp->hdr->high_mask = new_bucket | hcp->hdr->low_mask; - } - - /* Relocate records to the new bucket */ - ret = __ham_split_page(dbc, old_bucket, new_bucket); - -err: if (got_meta) - if ((t_ret = - __memp_fput(mpf, mmeta, dirty_meta)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = __TLPUT(dbc, metalock)) != 0 && ret == 0) - ret = t_ret; - if (h != NULL) - if ((t_ret = __memp_fput(mpf, h, 0)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * PUBLIC: u_int32_t __ham_call_hash __P((DBC *, u_int8_t *, u_int32_t)); - */ -u_int32_t -__ham_call_hash(dbc, k, len) - DBC *dbc; - u_int8_t *k; - u_int32_t len; -{ - DB *dbp; - HASH_CURSOR *hcp; - HASH *hashp; - u_int32_t n, bucket; - - dbp = dbc->dbp; - hcp = (HASH_CURSOR *)dbc->internal; - hashp = dbp->h_internal; - - n = (u_int32_t)(hashp->h_hash(dbp, k, len)); - - bucket = n & hcp->hdr->high_mask; - if (bucket > hcp->hdr->max_bucket) - bucket = bucket & hcp->hdr->low_mask; - return (bucket); -} - -/* - * Check for duplicates, and call __db_ret appropriately. Release - * everything held by the cursor. - */ -static int -__ham_dup_return(dbc, val, flags) - DBC *dbc; - DBT *val; - u_int32_t flags; -{ - DB *dbp; - HASH_CURSOR *hcp; - PAGE *pp; - DBT *myval, tmp_val; - db_indx_t ndx; - db_pgno_t pgno; - u_int32_t off, tlen; - u_int8_t *hk, type; - int cmp, ret; - db_indx_t len; - - /* Check for duplicate and return the first one. */ - dbp = dbc->dbp; - hcp = (HASH_CURSOR *)dbc->internal; - ndx = H_DATAINDEX(hcp->indx); - type = HPAGE_TYPE(dbp, hcp->page, ndx); - pp = hcp->page; - myval = val; - - /* - * There are 4 cases: - * 1. We are not in duplicate, simply return; the upper layer - * will do the right thing. - * 2. We are looking at keys and stumbled onto a duplicate. - * 3. We are in the middle of a duplicate set. (ISDUP set) - * 4. We need to check for particular data match. - */ - - /* We should never get here with off-page dups. */ - DB_ASSERT(type != H_OFFDUP); - - /* Case 1 */ - if (type != H_DUPLICATE && flags != DB_GET_BOTH && - flags != DB_GET_BOTHC && flags != DB_GET_BOTH_RANGE) - return (0); - - /* - * Here we check for the case where we just stumbled onto a - * duplicate. In this case, we do initialization and then - * let the normal duplicate code handle it. (Case 2) - */ - if (!F_ISSET(hcp, H_ISDUP) && type == H_DUPLICATE) { - F_SET(hcp, H_ISDUP); - hcp->dup_tlen = LEN_HDATA(dbp, hcp->page, - hcp->hdr->dbmeta.pagesize, hcp->indx); - hk = H_PAIRDATA(dbp, hcp->page, hcp->indx); - if (flags == DB_LAST || - flags == DB_PREV || flags == DB_PREV_NODUP) { - hcp->dup_off = 0; - do { - memcpy(&len, - HKEYDATA_DATA(hk) + hcp->dup_off, - sizeof(db_indx_t)); - hcp->dup_off += DUP_SIZE(len); - } while (hcp->dup_off < hcp->dup_tlen); - hcp->dup_off -= DUP_SIZE(len); - } else { - memcpy(&len, - HKEYDATA_DATA(hk), sizeof(db_indx_t)); - hcp->dup_off = 0; - } - hcp->dup_len = len; - } - - /* - * If we are retrieving a specific key/data pair, then we - * may need to adjust the cursor before returning data. - * Case 4 - */ - if (flags == DB_GET_BOTH || - flags == DB_GET_BOTHC || flags == DB_GET_BOTH_RANGE) { - if (F_ISSET(hcp, H_ISDUP)) { - /* - * If we're doing a join, search forward from the - * current position, not the beginning of the dup set. - */ - if (flags == DB_GET_BOTHC) - F_SET(hcp, H_CONTINUE); - - __ham_dsearch(dbc, val, &off, &cmp, flags); - - /* - * This flag is set nowhere else and is safe to - * clear unconditionally. - */ - F_CLR(hcp, H_CONTINUE); - hcp->dup_off = off; - } else { - hk = H_PAIRDATA(dbp, hcp->page, hcp->indx); - if (((HKEYDATA *)hk)->type == H_OFFPAGE) { - memcpy(&tlen, - HOFFPAGE_TLEN(hk), sizeof(u_int32_t)); - memcpy(&pgno, - HOFFPAGE_PGNO(hk), sizeof(db_pgno_t)); - if ((ret = __db_moff(dbp, val, - pgno, tlen, dbp->dup_compare, &cmp)) != 0) - return (ret); - } else { - /* - * We do not zero tmp_val since the comparison - * routines may only look at data and size. - */ - tmp_val.data = HKEYDATA_DATA(hk); - tmp_val.size = LEN_HDATA(dbp, hcp->page, - dbp->pgsize, hcp->indx); - cmp = dbp->dup_compare == NULL ? - __bam_defcmp(dbp, &tmp_val, val) : - dbp->dup_compare(dbp, &tmp_val, val); - } - } - - if (cmp != 0) - return (DB_NOTFOUND); - } - - /* - * If we're doing a bulk get, we don't want to actually return - * the data: __ham_bulk will take care of cracking out the - * duplicates appropriately. - * - * The rest of this function calculates partial offsets and - * handles the actual __db_ret, so just return if - * DB_MULTIPLE(_KEY) is set. - */ - if (F_ISSET(dbc, DBC_MULTIPLE | DBC_MULTIPLE_KEY)) - return (0); - - /* - * Now, everything is initialized, grab a duplicate if - * necessary. - */ - if (F_ISSET(hcp, H_ISDUP)) { /* Case 3 */ - /* - * Copy the DBT in case we are retrieving into user - * memory and we need the parameters for it. If the - * user requested a partial, then we need to adjust - * the user's parameters to get the partial of the - * duplicate which is itself a partial. - */ - memcpy(&tmp_val, val, sizeof(*val)); - - if (F_ISSET(&tmp_val, DB_DBT_PARTIAL)) { - /* - * Take the user's length unless it would go - * beyond the end of the duplicate. - */ - if (tmp_val.doff > hcp->dup_len) - tmp_val.dlen = 0; - else if (tmp_val.dlen + tmp_val.doff > hcp->dup_len) - tmp_val.dlen = hcp->dup_len - tmp_val.doff; - - } else { - F_SET(&tmp_val, DB_DBT_PARTIAL); - tmp_val.dlen = hcp->dup_len; - tmp_val.doff = 0; - } - - /* - * Set offset to the appropriate place within the - * current duplicate -- need to take into account - * both the dup_off and the current duplicate's - * length. - */ - tmp_val.doff += hcp->dup_off + sizeof(db_indx_t); - - myval = &tmp_val; - } - - /* - * Finally, if we had a duplicate, pp, ndx, and myval should be - * set appropriately. - */ - if ((ret = __db_ret(dbp, pp, ndx, myval, &dbc->rdata->data, - &dbc->rdata->ulen)) != 0) - return (ret); - - /* - * In case we sent a temporary off to db_ret, set the real - * return values. - */ - val->data = myval->data; - val->size = myval->size; - - F_SET(val, DB_DBT_ISSET); - - return (0); -} - -static int -__ham_overwrite(dbc, nval, flags) - DBC *dbc; - DBT *nval; - u_int32_t flags; -{ - DB *dbp; - DB_ENV *dbenv; - HASH_CURSOR *hcp; - DBT *myval, tmp_val, tmp_val2; - void *newrec; - u_int8_t *hk, *p; - u_int32_t len, nondup_size; - db_indx_t newsize; - int ret; - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - hcp = (HASH_CURSOR *)dbc->internal; - if (F_ISSET(hcp, H_ISDUP)) { - /* - * This is an overwrite of a duplicate. We should never - * be off-page at this point. - */ - DB_ASSERT(hcp->opd == NULL); - /* On page dups */ - if (F_ISSET(nval, DB_DBT_PARTIAL)) { - /* - * We're going to have to get the current item, then - * construct the record, do any padding and do a - * replace. - */ - memset(&tmp_val, 0, sizeof(tmp_val)); - if ((ret = - __ham_dup_return(dbc, &tmp_val, DB_CURRENT)) != 0) - return (ret); - - /* Figure out new size. */ - nondup_size = tmp_val.size; - newsize = nondup_size; - - /* - * Three cases: - * 1. strictly append (may need to allocate space - * for pad bytes; really gross). - * 2. overwrite some and append. - * 3. strictly overwrite. - */ - if (nval->doff > nondup_size) - newsize += - ((nval->doff - nondup_size) + nval->size); - else if (nval->doff + nval->dlen > nondup_size) - newsize += nval->size - - (nondup_size - nval->doff); - else - newsize += nval->size - nval->dlen; - - /* - * Make sure that the new size doesn't put us over - * the onpage duplicate size in which case we need - * to convert to off-page duplicates. - */ - if (ISBIG(hcp, - (hcp->dup_tlen - nondup_size) + newsize)) { - if ((ret = __ham_dup_convert(dbc)) != 0) - return (ret); - return (hcp->opd->c_am_put(hcp->opd, - NULL, nval, flags, NULL)); - } - - if ((ret = __os_malloc(dbp->dbenv, - DUP_SIZE(newsize), &newrec)) != 0) - return (ret); - memset(&tmp_val2, 0, sizeof(tmp_val2)); - F_SET(&tmp_val2, DB_DBT_PARTIAL); - - /* Construct the record. */ - p = newrec; - /* Initial size. */ - memcpy(p, &newsize, sizeof(db_indx_t)); - p += sizeof(db_indx_t); - - /* First part of original record. */ - len = nval->doff > tmp_val.size - ? tmp_val.size : nval->doff; - memcpy(p, tmp_val.data, len); - p += len; - - if (nval->doff > tmp_val.size) { - /* Padding */ - memset(p, 0, nval->doff - tmp_val.size); - p += nval->doff - tmp_val.size; - } - - /* New bytes */ - memcpy(p, nval->data, nval->size); - p += nval->size; - - /* End of original record (if there is any) */ - if (nval->doff + nval->dlen < tmp_val.size) { - len = (tmp_val.size - nval->doff) - nval->dlen; - memcpy(p, (u_int8_t *)tmp_val.data + - nval->doff + nval->dlen, len); - p += len; - } - - /* Final size. */ - memcpy(p, &newsize, sizeof(db_indx_t)); - - /* - * Make sure that the caller isn't corrupting - * the sort order. - */ - if (dbp->dup_compare != NULL) { - tmp_val2.data = - (u_int8_t *)newrec + sizeof(db_indx_t); - tmp_val2.size = newsize; - if (dbp->dup_compare( - dbp, &tmp_val, &tmp_val2) != 0) { - __os_free(dbenv, newrec); - return (__db_duperr(dbp, flags)); - } - } - - tmp_val2.data = newrec; - tmp_val2.size = DUP_SIZE(newsize); - tmp_val2.doff = hcp->dup_off; - tmp_val2.dlen = DUP_SIZE(hcp->dup_len); - - ret = __ham_replpair(dbc, &tmp_val2, 0); - __os_free(dbenv, newrec); - - /* Update cursor */ - if (ret != 0) - return (ret); - - if (newsize > nondup_size) - hcp->dup_tlen += (newsize - nondup_size); - else - hcp->dup_tlen -= (nondup_size - newsize); - hcp->dup_len = newsize; - return (0); - } else { - /* Check whether we need to convert to off page. */ - if (ISBIG(hcp, - (hcp->dup_tlen - hcp->dup_len) + nval->size)) { - if ((ret = __ham_dup_convert(dbc)) != 0) - return (ret); - return (hcp->opd->c_am_put(hcp->opd, - NULL, nval, flags, NULL)); - } - - /* Make sure we maintain sort order. */ - if (dbp->dup_compare != NULL) { - tmp_val2.data = - HKEYDATA_DATA(H_PAIRDATA(dbp, hcp->page, - hcp->indx)) + hcp->dup_off + - sizeof(db_indx_t); - tmp_val2.size = hcp->dup_len; - if (dbp->dup_compare( - dbp, nval, &tmp_val2) != 0) { - __db_err(dbenv, - "Existing data sorts differently from put data"); - return (EINVAL); - } - } - /* Overwriting a complete duplicate. */ - if ((ret = - __ham_make_dup(dbp->dbenv, nval, &tmp_val, - &dbc->my_rdata.data, &dbc->my_rdata.ulen)) != 0) - return (ret); - /* Now fix what we are replacing. */ - tmp_val.doff = hcp->dup_off; - tmp_val.dlen = DUP_SIZE(hcp->dup_len); - - /* Update cursor */ - if (nval->size > hcp->dup_len) - hcp->dup_tlen += (nval->size - hcp->dup_len); - else - hcp->dup_tlen -= (hcp->dup_len - nval->size); - hcp->dup_len = (db_indx_t)nval->size; - } - myval = &tmp_val; - } else if (!F_ISSET(nval, DB_DBT_PARTIAL)) { - /* Put/overwrite */ - memcpy(&tmp_val, nval, sizeof(*nval)); - F_SET(&tmp_val, DB_DBT_PARTIAL); - tmp_val.doff = 0; - hk = H_PAIRDATA(dbp, hcp->page, hcp->indx); - if (HPAGE_PTYPE(hk) == H_OFFPAGE) - memcpy(&tmp_val.dlen, - HOFFPAGE_TLEN(hk), sizeof(u_int32_t)); - else - tmp_val.dlen = LEN_HDATA(dbp, hcp->page, - hcp->hdr->dbmeta.pagesize, hcp->indx); - myval = &tmp_val; - } else - /* Regular partial put */ - myval = nval; - - return (__ham_replpair(dbc, myval, 0)); -} - -/* - * Given a key and a cursor, sets the cursor to the page/ndx on which - * the key resides. If the key is found, the cursor H_OK flag is set - * and the pagep, bndx, pgno (dpagep, dndx, dpgno) fields are set. - * If the key is not found, the H_OK flag is not set. If the sought - * field is non-0, the pagep, bndx, pgno (dpagep, dndx, dpgno) fields - * are set indicating where an add might take place. If it is 0, - * non of the cursor pointer field are valid. - */ -static int -__ham_lookup(dbc, key, sought, mode, pgnop) - DBC *dbc; - const DBT *key; - u_int32_t sought; - db_lockmode_t mode; - db_pgno_t *pgnop; -{ - DB *dbp; - HASH_CURSOR *hcp; - db_pgno_t pgno; - u_int32_t tlen; - int match, ret; - u_int8_t *hk, *dk; - - dbp = dbc->dbp; - hcp = (HASH_CURSOR *)dbc->internal; - /* - * Set up cursor so that we're looking for space to add an item - * as we cycle through the pages looking for the key. - */ - if ((ret = __ham_item_reset(dbc)) != 0) - return (ret); - hcp->seek_size = sought; - - hcp->bucket = __ham_call_hash(dbc, (u_int8_t *)key->data, key->size); - hcp->pgno = BUCKET_TO_PAGE(hcp, hcp->bucket); - - for (;;) { - *pgnop = PGNO_INVALID; - if ((ret = __ham_item_next(dbc, mode, pgnop)) != 0) - return (ret); - - if (F_ISSET(hcp, H_NOMORE)) - break; - - hk = H_PAIRKEY(dbp, hcp->page, hcp->indx); - switch (HPAGE_PTYPE(hk)) { - case H_OFFPAGE: - memcpy(&tlen, HOFFPAGE_TLEN(hk), sizeof(u_int32_t)); - if (tlen == key->size) { - memcpy(&pgno, - HOFFPAGE_PGNO(hk), sizeof(db_pgno_t)); - if ((ret = __db_moff(dbp, - key, pgno, tlen, NULL, &match)) != 0) - return (ret); - if (match == 0) - goto found_key; - } - break; - case H_KEYDATA: - if (key->size == - LEN_HKEY(dbp, hcp->page, dbp->pgsize, hcp->indx) && - memcmp(key->data, - HKEYDATA_DATA(hk), key->size) == 0) { - /* Found the key, check for data type. */ -found_key: F_SET(hcp, H_OK); - dk = H_PAIRDATA(dbp, hcp->page, hcp->indx); - if (HPAGE_PTYPE(dk) == H_OFFDUP) - memcpy(pgnop, HOFFDUP_PGNO(dk), - sizeof(db_pgno_t)); - return (0); - } - break; - case H_DUPLICATE: - case H_OFFDUP: - /* - * These are errors because keys are never - * duplicated, only data items are. - */ - return (__db_pgfmt(dbp->dbenv, PGNO(hcp->page))); - default: - return (__db_pgfmt(dbp->dbenv, PGNO(hcp->page))); - } - } - - /* - * Item was not found. - */ - - if (sought != 0) - return (ret); - - return (ret); -} - -/* - * __ham_init_dbt -- - * Initialize a dbt using some possibly already allocated storage - * for items. - * - * PUBLIC: int __ham_init_dbt __P((DB_ENV *, - * PUBLIC: DBT *, u_int32_t, void **, u_int32_t *)); - */ -int -__ham_init_dbt(dbenv, dbt, size, bufp, sizep) - DB_ENV *dbenv; - DBT *dbt; - u_int32_t size; - void **bufp; - u_int32_t *sizep; -{ - int ret; - - memset(dbt, 0, sizeof(*dbt)); - if (*sizep < size) { - if ((ret = __os_realloc(dbenv, size, bufp)) != 0) { - *sizep = 0; - return (ret); - } - *sizep = size; - } - dbt->data = *bufp; - dbt->size = size; - return (0); -} - -/* - * Adjust the cursor after an insert or delete. The cursor passed is - * the one that was operated upon; we just need to check any of the - * others. - * - * len indicates the length of the item added/deleted - * add indicates if the item indicated by the cursor has just been - * added (add == 1) or deleted (add == 0). - * dup indicates if the addition occurred into a duplicate set. - * - * PUBLIC: int __ham_c_update - * PUBLIC: __P((DBC *, u_int32_t, int, int)); - */ -int -__ham_c_update(dbc, len, add, is_dup) - DBC *dbc; - u_int32_t len; - int add, is_dup; -{ - DB *dbp, *ldbp; - DBC *cp; - DB_ENV *dbenv; - DB_LSN lsn; - DB_TXN *my_txn; - HASH_CURSOR *hcp, *lcp; - int found, ret; - u_int32_t order; - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - hcp = (HASH_CURSOR *)dbc->internal; - - /* - * Adjustment will only be logged if this is a subtransaction. - * Only subtransactions can abort and effect their parent - * transactions cursors. - */ - - my_txn = IS_SUBTRANSACTION(dbc->txn) ? dbc->txn : NULL; - found = 0; - - MUTEX_LOCK(dbenv, dbenv->mtx_dblist); - - /* - * Calculate the order of this deleted record. - * This will be one greater than any cursor that is pointing - * at this record and already marked as deleted. - */ - order = 0; - if (!add) { - order = 1; - for (ldbp = __dblist_get(dbenv, dbp->adj_fileid); - ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid; - ldbp = LIST_NEXT(ldbp, dblistlinks)) { - MUTEX_LOCK(dbenv, dbp->mutex); - for (cp = TAILQ_FIRST(&ldbp->active_queue); cp != NULL; - cp = TAILQ_NEXT(cp, links)) { - if (cp == dbc || cp->dbtype != DB_HASH) - continue; - lcp = (HASH_CURSOR *)cp->internal; - if (F_ISSET(lcp, H_DELETED) && - hcp->pgno == lcp->pgno && - hcp->indx == lcp->indx && - order <= lcp->order && - (!is_dup || hcp->dup_off == lcp->dup_off)) - order = lcp->order + 1; - } - MUTEX_UNLOCK(dbenv, dbp->mutex); - } - hcp->order = order; - } - - for (ldbp = __dblist_get(dbenv, dbp->adj_fileid); - ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid; - ldbp = LIST_NEXT(ldbp, dblistlinks)) { - MUTEX_LOCK(dbenv, dbp->mutex); - for (cp = TAILQ_FIRST(&ldbp->active_queue); cp != NULL; - cp = TAILQ_NEXT(cp, links)) { - if (cp == dbc || cp->dbtype != DB_HASH) - continue; - - lcp = (HASH_CURSOR *)cp->internal; - - if (lcp->pgno != hcp->pgno || lcp->indx == NDX_INVALID) - continue; - - if (my_txn != NULL && cp->txn != my_txn) - found = 1; - - if (!is_dup) { - if (add) { - /* - * This routine is not called to add - * non-dup records which are always put - * at the end. It is only called from - * recovery in this case and the - * cursor will be marked deleted. - * We are "undeleting" so unmark all - * cursors with the same order. - */ - if (lcp->indx == hcp->indx && - F_ISSET(lcp, H_DELETED)) { - if (lcp->order == hcp->order) - F_CLR(lcp, H_DELETED); - else if (lcp->order > - hcp->order) { - - /* - * If we've moved this cursor's - * index, split its order - * number--i.e., decrement it by - * enough so that the lowest - * cursor moved has order 1. - * cp_arg->order is the split - * point, so decrement by one - * less than that. - */ - lcp->order -= - (hcp->order - 1); - lcp->indx += 2; - } - } else if (lcp->indx >= hcp->indx) - lcp->indx += 2; - - } else { - if (lcp->indx > hcp->indx) { - lcp->indx -= 2; - if (lcp->indx == hcp->indx && - F_ISSET(lcp, H_DELETED)) - lcp->order += order; - } else if (lcp->indx == hcp->indx && - !F_ISSET(lcp, H_DELETED)) { - F_SET(lcp, H_DELETED); - F_CLR(lcp, H_ISDUP); - lcp->order = order; - } - } - } else if (lcp->indx == hcp->indx) { - /* - * Handle duplicates. This routine is - * only called for on page dups. - * Off page dups are handled by btree/rtree - * code. - */ - if (add) { - lcp->dup_tlen += len; - if (lcp->dup_off == hcp->dup_off && - F_ISSET(hcp, H_DELETED) && - F_ISSET(lcp, H_DELETED)) { - /* Abort of a delete. */ - if (lcp->order == hcp->order) - F_CLR(lcp, H_DELETED); - else if (lcp->order > - hcp->order) { - lcp->order -= - (hcp->order -1); - lcp->dup_off += len; - } - } else if (lcp->dup_off >= hcp->dup_off) - lcp->dup_off += len; - } else { - lcp->dup_tlen -= len; - if (lcp->dup_off > hcp->dup_off) { - lcp->dup_off -= len; - if (lcp->dup_off == - hcp->dup_off && - F_ISSET(lcp, H_DELETED)) - lcp->order += order; - } else if (lcp->dup_off == - hcp->dup_off && - !F_ISSET(lcp, H_DELETED)) { - F_SET(lcp, H_DELETED); - lcp->order = order; - } - } - } - } - MUTEX_UNLOCK(dbenv, dbp->mutex); - } - MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist); - - if (found != 0 && DBC_LOGGING(dbc)) { - if ((ret = __ham_curadj_log(dbp, my_txn, &lsn, 0, hcp->pgno, - hcp->indx, len, hcp->dup_off, add, is_dup, order)) != 0) - return (ret); - } - - return (0); -} - -/* - * __ham_get_clist -- - * - * Get a list of cursors either on a particular bucket or on a particular - * page and index combination. The former is so that we can update - * cursors on a split. The latter is so we can update cursors when we - * move items off page. - * - * PUBLIC: int __ham_get_clist __P((DB *, db_pgno_t, u_int32_t, DBC ***)); - */ -int -__ham_get_clist(dbp, pgno, indx, listp) - DB *dbp; - db_pgno_t pgno; - u_int32_t indx; - DBC ***listp; -{ - DB *ldbp; - DBC *cp; - DB_ENV *dbenv; - u_int nalloc, nused; - int ret; - - /* - * Assume that finding anything is the exception, so optimize for - * the case where there aren't any. - */ - nalloc = nused = 0; - *listp = NULL; - dbenv = dbp->dbenv; - - MUTEX_LOCK(dbenv, dbenv->mtx_dblist); - for (ldbp = __dblist_get(dbenv, dbp->adj_fileid); - ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid; - ldbp = LIST_NEXT(ldbp, dblistlinks)) { - MUTEX_LOCK(dbenv, dbp->mutex); - for (cp = TAILQ_FIRST(&ldbp->active_queue); cp != NULL; - cp = TAILQ_NEXT(cp, links)) - /* - * We match if cp->pgno matches the specified - * pgno, and if either the cp->indx matches - * or we weren't given an index. - */ - if (cp->internal->pgno == pgno && - (indx == NDX_INVALID || - cp->internal->indx == indx)) { - if (nused >= nalloc) { - nalloc += 10; - if ((ret = __os_realloc(dbp->dbenv, - nalloc * sizeof(HASH_CURSOR *), - listp)) != 0) - goto err; - } - (*listp)[nused++] = cp; - } - - MUTEX_UNLOCK(dbp->dbenv, dbp->mutex); - } - MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist); - - if (listp != NULL) { - if (nused >= nalloc) { - nalloc++; - if ((ret = __os_realloc(dbp->dbenv, - nalloc * sizeof(HASH_CURSOR *), listp)) != 0) - return (ret); - } - (*listp)[nused] = NULL; - } - return (0); -err: - MUTEX_UNLOCK(dbp->dbenv, dbp->mutex); - MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist); - return (ret); -} - -static int -__ham_c_writelock(dbc) - DBC *dbc; -{ - DB_LOCK tmp_lock; - HASH_CURSOR *hcp; - int ret; - - /* - * All we need do is acquire the lock and let the off-page - * dup tree do its thing. - */ - if (!STD_LOCKING(dbc)) - return (0); - - hcp = (HASH_CURSOR *)dbc->internal; - ret = 0; - if ((!LOCK_ISSET(hcp->lock) || hcp->lock_mode != DB_LOCK_WRITE)) { - tmp_lock = hcp->lock; - if ((ret = __ham_lock_bucket(dbc, DB_LOCK_WRITE)) == 0 && - tmp_lock.mode != DB_LOCK_WWRITE) - ret = __LPUT(dbc, tmp_lock); - } - return (ret); -} diff --git a/storage/bdb/hash/hash.src b/storage/bdb/hash/hash.src deleted file mode 100644 index 9c415a30418..00000000000 --- a/storage/bdb/hash/hash.src +++ /dev/null @@ -1,267 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: hash.src,v 12.1 2005/06/16 20:22:50 bostic Exp $ - */ -/* - * Copyright (c) 1995, 1996 - * Margo Seltzer. All rights reserved. - */ -/* - * Copyright (c) 1995, 1996 - * The President and Fellows of Harvard University. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Margo Seltzer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -PREFIX __ham -DBPRIVATE - -INCLUDE #ifndef NO_SYSTEM_INCLUDES -INCLUDE #include <sys/types.h> -INCLUDE -INCLUDE #include <ctype.h> -INCLUDE #include <string.h> -INCLUDE #endif -INCLUDE -INCLUDE #include "db_int.h" -INCLUDE #include "dbinc/crypto.h" -INCLUDE #include "dbinc/db_page.h" -INCLUDE #include "dbinc/db_dispatch.h" -INCLUDE #include "dbinc/db_am.h" -INCLUDE #include "dbinc/hash.h" -INCLUDE #include "dbinc/log.h" -INCLUDE #include "dbinc/txn.h" -INCLUDE - -/* - * HASH-insdel: used for hash to insert/delete a pair of entries onto a master - * page. The pair might be regular key/data pairs or they might be the - * structures that refer to off page items, duplicates or offpage duplicates. - * opcode - PUTPAIR/DELPAIR + big masks - * fileid - identifies the file referenced - * pgno - page within file - * ndx - index on the page of the item being added (item index) - * pagelsn - lsn on the page before the update - * key - the key being inserted - * data - the data being inserted - */ -BEGIN insdel 21 -ARG opcode u_int32_t lu -DB fileid int32_t ld -ARG pgno db_pgno_t lu -ARG ndx u_int32_t lu -POINTER pagelsn DB_LSN * lu -DBT key DBT s -DBT data DBT s -END - -/* - * Used to add and remove overflow pages. - * prev_pgno is the previous page that is going to get modified to - * point to this one. If this is the first page in a chain - * then prev_pgno should be PGNO_INVALID. - * new_pgno is the page being allocated. - * next_pgno is the page that follows this one. On allocation, - * this should be PGNO_INVALID. For deletes, it may exist. - * pagelsn is the old lsn on the page. - */ -BEGIN newpage 22 -ARG opcode u_int32_t lu -DB fileid int32_t ld -ARG prev_pgno db_pgno_t lu -POINTER prevlsn DB_LSN * lu -ARG new_pgno db_pgno_t lu -POINTER pagelsn DB_LSN * lu -ARG next_pgno db_pgno_t lu -POINTER nextlsn DB_LSN * lu -END - -/* - * Splitting requires two types of log messages. The second logs the - * data on the original page. To redo the split, we have to visit the - * new page (pages) and add the items back on the page if they are not - * yet there. - */ -BEGIN splitdata 24 -DB fileid int32_t ld -ARG opcode u_int32_t lu -ARG pgno db_pgno_t lu -PGDBT pageimage DBT s -POINTER pagelsn DB_LSN * lu -END - -/* - * HASH-replace: is used for hash to handle partial puts that only - * affect a single master page. - * fileid - identifies the file referenced - * pgno - page within file - * ndx - index on the page of the item being modified (item index) - * pagelsn - lsn on the page before the update - * off - offset in the old item where the new item is going. - * olditem - DBT that describes the part of the item being replaced. - * newitem - DBT of the new item. - * makedup - this was a replacement that made an item a duplicate. - */ -BEGIN replace 25 -DB fileid int32_t ld -ARG pgno db_pgno_t lu -ARG ndx u_int32_t lu -POINTER pagelsn DB_LSN * lu -ARG off int32_t ld -DBT olditem DBT s -DBT newitem DBT s -ARG makedup u_int32_t lu -END - -/* - * Used when we empty the first page in a bucket and there are pages after - * it. The page after it gets copied into the bucket page (since bucket - * pages have to be in fixed locations). - * pgno: the bucket page - * pagelsn: the old LSN on the bucket page - * next_pgno: the page number of the next page - * nnext_pgno: page after next_pgno (may need to change its prev) - * nnextlsn: the LSN of nnext_pgno. - */ -BEGIN copypage 28 -DB fileid int32_t ld -ARG pgno db_pgno_t lu -POINTER pagelsn DB_LSN * lu -ARG next_pgno db_pgno_t lu -POINTER nextlsn DB_LSN * lu -ARG nnext_pgno db_pgno_t lu -POINTER nnextlsn DB_LSN * lu -PGDBT page DBT s -END - -/* - * This record logs the meta-data aspects of a split operation. It has enough - * information so that we can record both an individual page allocation as well - * as a group allocation which we do because in sub databases, the pages in - * a hash doubling, must be contiguous. If we do a group allocation, the - * number of pages allocated is bucket + 1, pgno is the page number of the - * first newly allocated bucket. - * - * bucket: Old maximum bucket number. - * mmpgno: Master meta-data page number (0 if same as mpgno). - * mmetalsn: Lsn of the master meta-data page. - * mpgno: Meta-data page number. - * metalsn: Lsn of the meta-data page. - * pgno: Page allocated to bucket + 1 (first newly allocated page) - * pagelsn: Lsn of either the first page allocated (if newalloc == 0) or - * the last page allocated (if newalloc == 1). - * newalloc: 1 indicates that this record did the actual allocation; - * 0 indicates that the pages were already allocated from a - * previous (failed) allocation. - * last_pgno: the last page in the file before this op. - */ -BEGIN metagroup 29 -DB fileid int32_t ld -ARG bucket u_int32_t lu -ARG mmpgno db_pgno_t lu -POINTER mmetalsn DB_LSN * lu -ARG mpgno db_pgno_t lu -POINTER metalsn DB_LSN * lu -ARG pgno db_pgno_t lu -POINTER pagelsn DB_LSN * lu -ARG newalloc u_int32_t lu -ARG last_pgno db_pgno_t lu -END - -/* - * groupalloc - * - * This is used in conjunction with MPOOL_NEW_GROUP when we are creating - * a new database to make sure that we recreate or reclaim free pages - * when we allocate a chunk of contiguous ones during database creation. - * - * pgno: meta-data page number - * metalsn: meta-data lsn - * start_pgno: starting page number - * num: number of allocated pages - * last_pgno: the last page in the file before this op. - */ -BEGIN groupalloc 32 -DB fileid int32_t ld -POINTER meta_lsn DB_LSN * lu -ARG start_pgno db_pgno_t lu -ARG num u_int32_t lu -ARG free db_pgno_t lu -ARG last_pgno db_pgno_t lu -END - -/* - * Records for backing out cursor adjustment. - * curadj - added or deleted a record or a dup - * within a record. - * pgno - page that was effected - * indx - indx of recrod effected. - * len - if a dup its length. - * dup_off - if a dup its offset - * add - 1 if add 0 if delete - * is_dup - 1 if dup 0 otherwise. - * order - order assigned to this deleted record or dup. - * - * chgpg - rmoved a page, move the records to a new page - * mode - CHGPG page was deleted or records move to new page. - * - SPLIT we split a bucket - * - DUP we convered to off page duplicates. - * old_pgno, new_pgno - old and new page numbers. - * old_index, new_index - old and new index numbers, NDX_INVALID if - * it effects all records on the page. - * For three opcodes new in 3.3 (DB_HAM_DELFIRSTPG, DELMIDPG, - * and DELLASTPG), we overload old_indx and new_indx to avoid - * needing a new log record type: old_indx stores the only - * indx of interest to these records, and new_indx stores the - * order that's assigned to the lowest deleted record we're - * moving. - */ -BEGIN curadj 33 -DB fileid int32_t ld -ARG pgno db_pgno_t lu -ARG indx u_int32_t lu -ARG len u_int32_t lu -ARG dup_off u_int32_t lu -ARG add int ld -ARG is_dup int ld -ARG order u_int32_t lu -END - -BEGIN chgpg 34 -DB fileid int32_t ld -ARG mode db_ham_mode ld -ARG old_pgno db_pgno_t lu -ARG new_pgno db_pgno_t lu -ARG old_indx u_int32_t lu -ARG new_indx u_int32_t lu -END - diff --git a/storage/bdb/hash/hash_conv.c b/storage/bdb/hash/hash_conv.c deleted file mode 100644 index f84ec745744..00000000000 --- a/storage/bdb/hash/hash_conv.c +++ /dev/null @@ -1,115 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: hash_conv.c,v 12.1 2005/06/16 20:22:50 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_swap.h" -#include "dbinc/hash.h" - -/* - * __ham_pgin -- - * Convert host-specific page layout from the host-independent format - * stored on disk. - * - * PUBLIC: int __ham_pgin __P((DB_ENV *, DB *, db_pgno_t, void *, DBT *)); - */ -int -__ham_pgin(dbenv, dummydbp, pg, pp, cookie) - DB_ENV *dbenv; - DB *dummydbp; - db_pgno_t pg; - void *pp; - DBT *cookie; -{ - DB_PGINFO *pginfo; - PAGE *h; - - h = pp; - pginfo = (DB_PGINFO *)cookie->data; - - /* - * The hash access method does blind reads of pages, causing them - * to be created. If the type field isn't set it's one of them, - * initialize the rest of the page and return. - */ - if (h->type != P_HASHMETA && h->pgno == PGNO_INVALID) { - P_INIT(pp, (db_indx_t)pginfo->db_pagesize, - pg, PGNO_INVALID, PGNO_INVALID, 0, P_HASH); - return (0); - } - - if (!F_ISSET(pginfo, DB_AM_SWAP)) - return (0); - - return (h->type == P_HASHMETA ? __ham_mswap(pp) : - __db_byteswap(dbenv, dummydbp, pg, pp, pginfo->db_pagesize, 1)); -} - -/* - * __ham_pgout -- - * Convert host-specific page layout to the host-independent format - * stored on disk. - * - * PUBLIC: int __ham_pgout __P((DB_ENV *, DB *, db_pgno_t, void *, DBT *)); - */ -int -__ham_pgout(dbenv, dummydbp, pg, pp, cookie) - DB_ENV *dbenv; - DB *dummydbp; - db_pgno_t pg; - void *pp; - DBT *cookie; -{ - DB_PGINFO *pginfo; - PAGE *h; - - pginfo = (DB_PGINFO *)cookie->data; - if (!F_ISSET(pginfo, DB_AM_SWAP)) - return (0); - - h = pp; - return (h->type == P_HASHMETA ? __ham_mswap(pp) : - __db_byteswap(dbenv, dummydbp, pg, pp, pginfo->db_pagesize, 0)); -} - -/* - * __ham_mswap -- - * Swap the bytes on the hash metadata page. - * - * PUBLIC: int __ham_mswap __P((void *)); - */ -int -__ham_mswap(pg) - void *pg; -{ - u_int8_t *p; - int i; - - __db_metaswap(pg); - - p = (u_int8_t *)pg + sizeof(DBMETA); - - SWAP32(p); /* max_bucket */ - SWAP32(p); /* high_mask */ - SWAP32(p); /* low_mask */ - SWAP32(p); /* ffactor */ - SWAP32(p); /* nelem */ - SWAP32(p); /* h_charkey */ - for (i = 0; i < NCACHED; ++i) - SWAP32(p); /* spares */ - p += 59 * sizeof(u_int32_t); /* unused */ - SWAP32(p); /* crypto_magic */ - return (0); -} diff --git a/storage/bdb/hash/hash_dup.c b/storage/bdb/hash/hash_dup.c deleted file mode 100644 index 127c3d87a56..00000000000 --- a/storage/bdb/hash/hash_dup.c +++ /dev/null @@ -1,886 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Margo Seltzer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: hash_dup.c,v 12.3 2005/07/20 16:51:41 bostic Exp $ - */ - -#include "db_config.h" - -/* - * PACKAGE: hashing - * - * DESCRIPTION: - * Manipulation of duplicates for the hash package. - */ - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/hash.h" -#include "dbinc/btree.h" -#include "dbinc/mp.h" - -static int __ham_c_chgpg __P((DBC *, - db_pgno_t, u_int32_t, db_pgno_t, u_int32_t)); -static int __ham_check_move __P((DBC *, u_int32_t)); -static int __ham_dcursor __P((DBC *, db_pgno_t, u_int32_t)); -static int __ham_move_offpage __P((DBC *, PAGE *, u_int32_t, db_pgno_t)); - -/* - * Called from hash_access to add a duplicate key. nval is the new - * value that we want to add. The flags correspond to the flag values - * to cursor_put indicating where to add the new element. - * There are 4 cases. - * Case 1: The existing duplicate set already resides on a separate page. - * We return and let the common code handle this. - * Case 2: The element is small enough to just be added to the existing set. - * Case 3: The element is large enough to be a big item, so we're going to - * have to push the set onto a new page. - * Case 4: The element is large enough to push the duplicate set onto a - * separate page. - * - * PUBLIC: int __ham_add_dup __P((DBC *, DBT *, u_int32_t, db_pgno_t *)); - */ -int -__ham_add_dup(dbc, nval, flags, pgnop) - DBC *dbc; - DBT *nval; - u_int32_t flags; - db_pgno_t *pgnop; -{ - DB *dbp; - DBT pval, tmp_val; - DB_MPOOLFILE *mpf; - HASH_CURSOR *hcp; - u_int32_t add_bytes, new_size; - int cmp, ret; - u_int8_t *hk; - - dbp = dbc->dbp; - mpf = dbp->mpf; - hcp = (HASH_CURSOR *)dbc->internal; - - DB_ASSERT(flags != DB_CURRENT); - - add_bytes = nval->size + - (F_ISSET(nval, DB_DBT_PARTIAL) ? nval->doff : 0); - add_bytes = DUP_SIZE(add_bytes); - - if ((ret = __ham_check_move(dbc, add_bytes)) != 0) - return (ret); - - /* - * Check if resulting duplicate set is going to need to go - * onto a separate duplicate page. If so, convert the - * duplicate set and add the new one. After conversion, - * hcp->dndx is the first free ndx or the index of the - * current pointer into the duplicate set. - */ - hk = H_PAIRDATA(dbp, hcp->page, hcp->indx); - /* Add the len bytes to the current singleton. */ - if (HPAGE_PTYPE(hk) != H_DUPLICATE) - add_bytes += DUP_SIZE(0); - new_size = - LEN_HKEYDATA(dbp, hcp->page, dbp->pgsize, H_DATAINDEX(hcp->indx)) + - add_bytes; - - /* - * We convert to off-page duplicates if the item is a big item, - * the addition of the new item will make the set large, or - * if there isn't enough room on this page to add the next item. - */ - if (HPAGE_PTYPE(hk) != H_OFFDUP && - (HPAGE_PTYPE(hk) == H_OFFPAGE || ISBIG(hcp, new_size) || - add_bytes > P_FREESPACE(dbp, hcp->page))) { - - if ((ret = __ham_dup_convert(dbc)) != 0) - return (ret); - return (hcp->opd->c_am_put(hcp->opd, - NULL, nval, flags, NULL)); - } - - /* There are two separate cases here: on page and off page. */ - if (HPAGE_PTYPE(hk) != H_OFFDUP) { - if (HPAGE_PTYPE(hk) != H_DUPLICATE) { - pval.flags = 0; - pval.data = HKEYDATA_DATA(hk); - pval.size = LEN_HDATA(dbp, hcp->page, dbp->pgsize, - hcp->indx); - if ((ret = __ham_make_dup(dbp->dbenv, - &pval, &tmp_val, &dbc->my_rdata.data, - &dbc->my_rdata.ulen)) != 0 || (ret = - __ham_replpair(dbc, &tmp_val, 1)) != 0) - return (ret); - hk = H_PAIRDATA(dbp, hcp->page, hcp->indx); - HPAGE_PTYPE(hk) = H_DUPLICATE; - - /* - * Update the cursor position since we now are in - * duplicates. - */ - F_SET(hcp, H_ISDUP); - hcp->dup_off = 0; - hcp->dup_len = pval.size; - hcp->dup_tlen = DUP_SIZE(hcp->dup_len); - } - - /* Now make the new entry a duplicate. */ - if ((ret = __ham_make_dup(dbp->dbenv, nval, - &tmp_val, &dbc->my_rdata.data, &dbc->my_rdata.ulen)) != 0) - return (ret); - - tmp_val.dlen = 0; - switch (flags) { /* On page. */ - case DB_KEYFIRST: - case DB_KEYLAST: - case DB_NODUPDATA: - if (dbp->dup_compare != NULL) { - __ham_dsearch(dbc, - nval, &tmp_val.doff, &cmp, flags); - - /* dup dups are not supported w/ sorted dups */ - if (cmp == 0) - return (__db_duperr(dbp, flags)); - } else { - hcp->dup_tlen = LEN_HDATA(dbp, hcp->page, - dbp->pgsize, hcp->indx); - hcp->dup_len = nval->size; - F_SET(hcp, H_ISDUP); - if (flags == DB_KEYFIRST) - hcp->dup_off = tmp_val.doff = 0; - else - hcp->dup_off = - tmp_val.doff = hcp->dup_tlen; - } - break; - case DB_BEFORE: - tmp_val.doff = hcp->dup_off; - break; - case DB_AFTER: - tmp_val.doff = hcp->dup_off + DUP_SIZE(hcp->dup_len); - break; - default: - DB_ASSERT(0); - return (EINVAL); - } - - /* Add the duplicate. */ - ret = __ham_replpair(dbc, &tmp_val, 0); - if (ret == 0) - ret = __memp_fset(mpf, hcp->page, DB_MPOOL_DIRTY); - if (ret != 0) - return (ret); - - /* Now, update the cursor if necessary. */ - switch (flags) { - case DB_AFTER: - hcp->dup_off += DUP_SIZE(hcp->dup_len); - hcp->dup_len = nval->size; - hcp->dup_tlen += (db_indx_t)DUP_SIZE(nval->size); - break; - case DB_BEFORE: - case DB_KEYFIRST: - case DB_KEYLAST: - case DB_NODUPDATA: - hcp->dup_tlen += (db_indx_t)DUP_SIZE(nval->size); - hcp->dup_len = nval->size; - break; - default: - DB_ASSERT(0); - return (EINVAL); - } - ret = __ham_c_update(dbc, tmp_val.size, 1, 1); - return (ret); - } - - /* - * If we get here, then we're on duplicate pages; set pgnop and - * return so the common code can handle it. - */ - memcpy(pgnop, HOFFDUP_PGNO(H_PAIRDATA(dbp, hcp->page, hcp->indx)), - sizeof(db_pgno_t)); - - return (ret); -} - -/* - * Convert an on-page set of duplicates to an offpage set of duplicates. - * - * PUBLIC: int __ham_dup_convert __P((DBC *)); - */ -int -__ham_dup_convert(dbc) - DBC *dbc; -{ - BOVERFLOW bo; - DB *dbp; - DBC **hcs; - DBT dbt; - DB_LSN lsn; - DB_MPOOLFILE *mpf; - HASH_CURSOR *hcp; - HOFFPAGE ho; - PAGE *dp; - db_indx_t i, len, off; - int c, ret, t_ret; - u_int8_t *p, *pend; - - dbp = dbc->dbp; - mpf = dbp->mpf; - hcp = (HASH_CURSOR *)dbc->internal; - - /* - * Create a new page for the duplicates. - */ - if ((ret = __db_new(dbc, - dbp->dup_compare == NULL ? P_LRECNO : P_LDUP, &dp)) != 0) - return (ret); - P_INIT(dp, dbp->pgsize, - dp->pgno, PGNO_INVALID, PGNO_INVALID, LEAFLEVEL, TYPE(dp)); - - /* - * Get the list of cursors that may need to be updated. - */ - if ((ret = __ham_get_clist(dbp, - PGNO(hcp->page), (u_int32_t)hcp->indx, &hcs)) != 0) - goto err; - - /* - * Now put the duplicates onto the new page. - */ - dbt.flags = 0; - switch (HPAGE_PTYPE(H_PAIRDATA(dbp, hcp->page, hcp->indx))) { - case H_KEYDATA: - /* Simple case, one key on page; move it to dup page. */ - dbt.size = LEN_HDATA(dbp, hcp->page, dbp->pgsize, hcp->indx); - dbt.data = HKEYDATA_DATA(H_PAIRDATA(dbp, hcp->page, hcp->indx)); - ret = __db_pitem(dbc, - dp, 0, BKEYDATA_SIZE(dbt.size), NULL, &dbt); - goto finish; - case H_OFFPAGE: - /* Simple case, one key on page; move it to dup page. */ - memcpy(&ho, P_ENTRY(dbp, hcp->page, H_DATAINDEX(hcp->indx)), - HOFFPAGE_SIZE); - UMRW_SET(bo.unused1); - B_TSET(bo.type, ho.type, 0); - UMRW_SET(bo.unused2); - bo.pgno = ho.pgno; - bo.tlen = ho.tlen; - dbt.size = BOVERFLOW_SIZE; - dbt.data = &bo; - - ret = __db_pitem(dbc, dp, 0, dbt.size, &dbt, NULL); -finish: if (ret == 0) { - if ((ret = __memp_fset(mpf, dp, DB_MPOOL_DIRTY)) != 0) - break; - - /* Update any other cursors. */ - if (hcs != NULL && DBC_LOGGING(dbc) && - IS_SUBTRANSACTION(dbc->txn)) { - if ((ret = __ham_chgpg_log(dbp, dbc->txn, - &lsn, 0, DB_HAM_DUP, PGNO(hcp->page), - PGNO(dp), hcp->indx, 0)) != 0) - break; - } - for (c = 0; hcs != NULL && hcs[c] != NULL; c++) - if ((ret = __ham_dcursor(hcs[c], - PGNO(dp), 0)) != 0) - break; - } - break; - case H_DUPLICATE: - p = HKEYDATA_DATA(H_PAIRDATA(dbp, hcp->page, hcp->indx)); - pend = p + - LEN_HDATA(dbp, hcp->page, dbp->pgsize, hcp->indx); - - /* - * We need to maintain the duplicate cursor position. - * Keep track of where we are in the duplicate set via - * the offset, and when it matches the one in the cursor, - * set the off-page duplicate cursor index to the current - * index. - */ - for (off = 0, i = 0; p < pend; i++) { - memcpy(&len, p, sizeof(db_indx_t)); - dbt.size = len; - p += sizeof(db_indx_t); - dbt.data = p; - p += len + sizeof(db_indx_t); - if ((ret = __db_pitem(dbc, dp, - i, BKEYDATA_SIZE(dbt.size), NULL, &dbt)) != 0) - break; - - /* Update any other cursors */ - if (hcs != NULL && DBC_LOGGING(dbc) && - IS_SUBTRANSACTION(dbc->txn)) { - if ((ret = __ham_chgpg_log(dbp, dbc->txn, - &lsn, 0, DB_HAM_DUP, PGNO(hcp->page), - PGNO(dp), hcp->indx, i)) != 0) - break; - } - for (c = 0; hcs != NULL && hcs[c] != NULL; c++) - if (((HASH_CURSOR *)(hcs[c]->internal))->dup_off - == off && (ret = __ham_dcursor(hcs[c], - PGNO(dp), i)) != 0) - goto err; - off += len + 2 * sizeof(db_indx_t); - } - break; - default: - ret = __db_pgfmt(dbp->dbenv, hcp->pgno); - break; - } - - /* - * Now attach this to the source page in place of the old duplicate - * item. - */ - if (ret == 0) - ret = __ham_move_offpage(dbc, hcp->page, - (u_int32_t)H_DATAINDEX(hcp->indx), PGNO(dp)); - -err: if (ret == 0) - ret = __memp_fset(mpf, hcp->page, DB_MPOOL_DIRTY); - - if ((t_ret = __memp_fput( - mpf, dp, ret == 0 ? DB_MPOOL_DIRTY : 0)) != 0 && ret == 0) - ret = t_ret; - - if (ret == 0) - hcp->dup_tlen = hcp->dup_off = hcp->dup_len = 0; - - if (hcs != NULL) - __os_free(dbp->dbenv, hcs); - - return (ret); -} - -/* - * __ham_make_dup - * - * Take a regular dbt and make it into a duplicate item with all the partial - * information set appropriately. If the incoming dbt is a partial, assume - * we are creating a new entry and make sure that we do any initial padding. - * - * PUBLIC: int __ham_make_dup __P((DB_ENV *, - * PUBLIC: const DBT *, DBT *d, void **, u_int32_t *)); - */ -int -__ham_make_dup(dbenv, notdup, duplicate, bufp, sizep) - DB_ENV *dbenv; - const DBT *notdup; - DBT *duplicate; - void **bufp; - u_int32_t *sizep; -{ - db_indx_t tsize, item_size; - int ret; - u_int8_t *p; - - item_size = (db_indx_t)notdup->size; - if (F_ISSET(notdup, DB_DBT_PARTIAL)) - item_size += notdup->doff; - - tsize = DUP_SIZE(item_size); - if ((ret = __ham_init_dbt(dbenv, duplicate, tsize, bufp, sizep)) != 0) - return (ret); - - duplicate->dlen = 0; - duplicate->flags = notdup->flags; - F_SET(duplicate, DB_DBT_PARTIAL); - - p = duplicate->data; - memcpy(p, &item_size, sizeof(db_indx_t)); - p += sizeof(db_indx_t); - if (F_ISSET(notdup, DB_DBT_PARTIAL)) { - memset(p, 0, notdup->doff); - p += notdup->doff; - } - memcpy(p, notdup->data, notdup->size); - p += notdup->size; - memcpy(p, &item_size, sizeof(db_indx_t)); - - duplicate->doff = 0; - duplicate->dlen = notdup->size; - - return (0); -} - -/* - * __ham_check_move -- - * - * Check if we can do whatever we need to on this page. If not, - * then we'll have to move the current element to a new page. - */ -static int -__ham_check_move(dbc, add_len) - DBC *dbc; - u_int32_t add_len; -{ - DB *dbp; - DBT k, d; - DB_LSN new_lsn; - DB_MPOOLFILE *mpf; - HASH_CURSOR *hcp; - PAGE *next_pagep; - db_pgno_t next_pgno; - u_int32_t new_datalen, old_len, rectype; - u_int8_t *hk; - int ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - hcp = (HASH_CURSOR *)dbc->internal; - - hk = H_PAIRDATA(dbp, hcp->page, hcp->indx); - - /* - * If the item is already off page duplicates or an offpage item, - * then we know we can do whatever we need to do in-place - */ - if (HPAGE_PTYPE(hk) == H_OFFDUP || HPAGE_PTYPE(hk) == H_OFFPAGE) - return (0); - - old_len = - LEN_HITEM(dbp, hcp->page, dbp->pgsize, H_DATAINDEX(hcp->indx)); - new_datalen = (old_len - HKEYDATA_SIZE(0)) + add_len; - if (HPAGE_PTYPE(hk) != H_DUPLICATE) - new_datalen += DUP_SIZE(0); - - /* - * We need to add a new page under two conditions: - * 1. The addition makes the total data length cross the BIG - * threshold and the OFFDUP structure won't fit on this page. - * 2. The addition does not make the total data cross the - * threshold, but the new data won't fit on the page. - * If neither of these is true, then we can return. - */ - if (ISBIG(hcp, new_datalen) && (old_len > HOFFDUP_SIZE || - HOFFDUP_SIZE - old_len <= P_FREESPACE(dbp, hcp->page))) - return (0); - - if (!ISBIG(hcp, new_datalen) && - (new_datalen - old_len) <= P_FREESPACE(dbp, hcp->page)) - return (0); - - /* - * If we get here, then we need to move the item to a new page. - * Check if there are more pages in the chain. We now need to - * update new_datalen to include the size of both the key and - * the data that we need to move. - */ - - new_datalen = ISBIG(hcp, new_datalen) ? - HOFFDUP_SIZE : HKEYDATA_SIZE(new_datalen); - new_datalen += - LEN_HITEM(dbp, hcp->page, dbp->pgsize, H_KEYINDEX(hcp->indx)); - - next_pagep = NULL; - for (next_pgno = NEXT_PGNO(hcp->page); next_pgno != PGNO_INVALID; - next_pgno = NEXT_PGNO(next_pagep)) { - if (next_pagep != NULL && - (ret = __memp_fput(mpf, next_pagep, 0)) != 0) - return (ret); - - if ((ret = __memp_fget(mpf, - &next_pgno, DB_MPOOL_CREATE, &next_pagep)) != 0) - return (ret); - - if (P_FREESPACE(dbp, next_pagep) >= new_datalen) - break; - } - - /* No more pages, add one. */ - if (next_pagep == NULL && (ret = __ham_add_ovflpage(dbc, - hcp->page, 0, &next_pagep)) != 0) - return (ret); - - /* Add new page at the end of the chain. */ - if (P_FREESPACE(dbp, next_pagep) < new_datalen && (ret = - __ham_add_ovflpage(dbc, next_pagep, 1, &next_pagep)) != 0) { - (void)__memp_fput(mpf, next_pagep, 0); - return (ret); - } - - /* Copy the item to the new page. */ - if (DBC_LOGGING(dbc)) { - rectype = PUTPAIR; - k.flags = 0; - d.flags = 0; - if (HPAGE_PTYPE( - H_PAIRKEY(dbp, hcp->page, hcp->indx)) == H_OFFPAGE) { - rectype |= PAIR_KEYMASK; - k.data = H_PAIRKEY(dbp, hcp->page, hcp->indx); - k.size = HOFFPAGE_SIZE; - } else { - k.data = - HKEYDATA_DATA(H_PAIRKEY(dbp, hcp->page, hcp->indx)); - k.size = - LEN_HKEY(dbp, hcp->page, dbp->pgsize, hcp->indx); - } - - if (HPAGE_PTYPE(hk) == H_OFFPAGE) { - rectype |= PAIR_DATAMASK; - d.data = H_PAIRDATA(dbp, hcp->page, hcp->indx); - d.size = HOFFPAGE_SIZE; - } else { - if (HPAGE_PTYPE(H_PAIRDATA(dbp, - hcp->page, hcp->indx)) == H_DUPLICATE) - rectype |= PAIR_DUPMASK; - d.data = HKEYDATA_DATA( - H_PAIRDATA(dbp, hcp->page, hcp->indx)); - d.size = LEN_HDATA(dbp, hcp->page, - dbp->pgsize, hcp->indx); - } - - if ((ret = __ham_insdel_log(dbp, - dbc->txn, &new_lsn, 0, rectype, PGNO(next_pagep), - (u_int32_t)NUM_ENT(next_pagep), &LSN(next_pagep), - &k, &d)) != 0) { - (void)__memp_fput(mpf, next_pagep, 0); - return (ret); - } - } else - LSN_NOT_LOGGED(new_lsn); - - /* Move lsn onto page. */ - LSN(next_pagep) = new_lsn; /* Structure assignment. */ - - __ham_copy_item(dbp, hcp->page, H_KEYINDEX(hcp->indx), next_pagep); - __ham_copy_item(dbp, hcp->page, H_DATAINDEX(hcp->indx), next_pagep); - - /* - * We've just manually inserted a key and set of data onto - * next_pagep; however, it's possible that our caller will - * return without further modifying the new page, for instance - * if DB_NODUPDATA is set and our new item is a duplicate duplicate. - * Thus, to be on the safe side, we need to mark the page dirty - * here. [#2996] - * - * Note that __ham_del_pair should dirty the page we're moving - * the items from, so we need only dirty the new page ourselves. - */ - if ((ret = __memp_fset(mpf, next_pagep, DB_MPOOL_DIRTY)) != 0) - goto out; - - /* Update all cursors that used to point to this item. */ - if ((ret = __ham_c_chgpg(dbc, PGNO(hcp->page), H_KEYINDEX(hcp->indx), - PGNO(next_pagep), NUM_ENT(next_pagep) - 2)) != 0) - goto out; - - /* Now delete the pair from the current page. */ - ret = __ham_del_pair(dbc, 0); - - /* - * __ham_del_pair decremented nelem. This is incorrect; we - * manually copied the element elsewhere, so the total number - * of elements hasn't changed. Increment it again. - * - * !!! - * Note that we still have the metadata page pinned, and - * __ham_del_pair dirtied it, so we don't need to set the dirty - * flag again. - */ - if (!STD_LOCKING(dbc)) - hcp->hdr->nelem++; - -out: - (void)__memp_fput(mpf, hcp->page, DB_MPOOL_DIRTY); - hcp->page = next_pagep; - hcp->pgno = PGNO(hcp->page); - hcp->indx = NUM_ENT(hcp->page) - 2; - F_SET(hcp, H_EXPAND); - F_CLR(hcp, H_DELETED); - - return (ret); -} - -/* - * __ham_move_offpage -- - * Replace an onpage set of duplicates with the OFFDUP structure - * that references the duplicate page. - * - * XXX - * This is really just a special case of __onpage_replace; we should - * probably combine them. - * - */ -static int -__ham_move_offpage(dbc, pagep, ndx, pgno) - DBC *dbc; - PAGE *pagep; - u_int32_t ndx; - db_pgno_t pgno; -{ - DB *dbp; - DBT new_dbt; - DBT old_dbt; - HOFFDUP od; - db_indx_t i, *inp; - int32_t difflen; - u_int8_t *src; - int ret; - - dbp = dbc->dbp; - od.type = H_OFFDUP; - UMRW_SET(od.unused[0]); - UMRW_SET(od.unused[1]); - UMRW_SET(od.unused[2]); - od.pgno = pgno; - ret = 0; - - if (DBC_LOGGING(dbc)) { - new_dbt.data = &od; - new_dbt.size = HOFFDUP_SIZE; - old_dbt.data = P_ENTRY(dbp, pagep, ndx); - old_dbt.size = LEN_HITEM(dbp, pagep, dbp->pgsize, ndx); - if ((ret = __ham_replace_log(dbp, dbc->txn, &LSN(pagep), 0, - PGNO(pagep), (u_int32_t)ndx, &LSN(pagep), -1, - &old_dbt, &new_dbt, 0)) != 0) - return (ret); - } else - LSN_NOT_LOGGED(LSN(pagep)); - - /* - * difflen is the difference in the lengths, and so may be negative. - * We know that the difference between two unsigned lengths from a - * database page will fit into an int32_t. - */ - difflen = - (int32_t)LEN_HITEM(dbp, pagep, dbp->pgsize, ndx) - - (int32_t)HOFFDUP_SIZE; - if (difflen != 0) { - /* Copy data. */ - inp = P_INP(dbp, pagep); - src = (u_int8_t *)(pagep) + HOFFSET(pagep); - memmove(src + difflen, src, inp[ndx] - HOFFSET(pagep)); - HOFFSET(pagep) += difflen; - - /* Update index table. */ - for (i = ndx; i < NUM_ENT(pagep); i++) - inp[i] += difflen; - } - - /* Now copy the offdup entry onto the page. */ - memcpy(P_ENTRY(dbp, pagep, ndx), &od, HOFFDUP_SIZE); - return (ret); -} - -/* - * __ham_dsearch: - * Locate a particular duplicate in a duplicate set. Make sure that - * we exit with the cursor set appropriately. - * - * PUBLIC: void __ham_dsearch - * PUBLIC: __P((DBC *, DBT *, u_int32_t *, int *, u_int32_t)); - */ -void -__ham_dsearch(dbc, dbt, offp, cmpp, flags) - DBC *dbc; - DBT *dbt; - u_int32_t *offp, flags; - int *cmpp; -{ - DB *dbp; - HASH_CURSOR *hcp; - DBT cur; - db_indx_t i, len; - int (*func) __P((DB *, const DBT *, const DBT *)); - u_int8_t *data; - - dbp = dbc->dbp; - hcp = (HASH_CURSOR *)dbc->internal; - func = dbp->dup_compare == NULL ? __bam_defcmp : dbp->dup_compare; - - i = F_ISSET(hcp, H_CONTINUE) ? hcp->dup_off: 0; - data = HKEYDATA_DATA(H_PAIRDATA(dbp, hcp->page, hcp->indx)) + i; - hcp->dup_tlen = LEN_HDATA(dbp, hcp->page, dbp->pgsize, hcp->indx); - len = hcp->dup_len; - while (i < hcp->dup_tlen) { - memcpy(&len, data, sizeof(db_indx_t)); - data += sizeof(db_indx_t); - cur.data = data; - cur.size = (u_int32_t)len; - - /* - * If we find an exact match, we're done. If in a sorted - * duplicate set and the item is larger than our test item, - * we're done. In the latter case, if permitting partial - * matches, it's not a failure. - */ - *cmpp = func(dbp, dbt, &cur); - if (*cmpp == 0) - break; - if (*cmpp < 0 && dbp->dup_compare != NULL) { - if (flags == DB_GET_BOTH_RANGE) - *cmpp = 0; - break; - } - - i += len + 2 * sizeof(db_indx_t); - data += len + sizeof(db_indx_t); - } - - *offp = i; - hcp->dup_off = i; - hcp->dup_len = len; - F_SET(hcp, H_ISDUP); -} - -/* - * __ham_dcursor -- - * - * Create an off page duplicate cursor for this cursor. - */ -static int -__ham_dcursor(dbc, pgno, indx) - DBC *dbc; - db_pgno_t pgno; - u_int32_t indx; -{ - DB *dbp; - HASH_CURSOR *hcp; - BTREE_CURSOR *dcp; - int ret; - - dbp = dbc->dbp; - hcp = (HASH_CURSOR *)dbc->internal; - - if ((ret = __db_c_newopd(dbc, pgno, hcp->opd, &hcp->opd)) != 0) - return (ret); - - dcp = (BTREE_CURSOR *)hcp->opd->internal; - dcp->pgno = pgno; - dcp->indx = indx; - - if (dbp->dup_compare == NULL) { - /* - * Converting to off-page Recno trees is tricky. The - * record number for the cursor is the index + 1 (to - * convert to 1-based record numbers). - */ - dcp->recno = indx + 1; - } - - /* - * Transfer the deleted flag from the top-level cursor to the - * created one. - */ - if (F_ISSET(hcp, H_DELETED)) { - F_SET(dcp, C_DELETED); - F_CLR(hcp, H_DELETED); - } - - return (0); -} - -/* - * __ham_c_chgpg -- - * Adjust the cursors after moving an item to a new page. We only - * move cursors that are pointing at this one item and are not - * deleted; since we only touch non-deleted cursors, and since - * (by definition) no item existed at the pgno/indx we're moving the - * item to, we're guaranteed that all the cursors we affect here or - * on abort really do refer to this one item. - */ -static int -__ham_c_chgpg(dbc, old_pgno, old_index, new_pgno, new_index) - DBC *dbc; - db_pgno_t old_pgno, new_pgno; - u_int32_t old_index, new_index; -{ - DB *dbp, *ldbp; - DB_ENV *dbenv; - DB_LSN lsn; - DB_TXN *my_txn; - DBC *cp; - HASH_CURSOR *hcp; - int found, ret; - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - - my_txn = IS_SUBTRANSACTION(dbc->txn) ? dbc->txn : NULL; - found = 0; - - MUTEX_LOCK(dbenv, dbenv->mtx_dblist); - for (ldbp = __dblist_get(dbenv, dbp->adj_fileid); - ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid; - ldbp = LIST_NEXT(ldbp, dblistlinks)) { - MUTEX_LOCK(dbenv, dbp->mutex); - for (cp = TAILQ_FIRST(&ldbp->active_queue); cp != NULL; - cp = TAILQ_NEXT(cp, links)) { - if (cp == dbc || cp->dbtype != DB_HASH) - continue; - - hcp = (HASH_CURSOR *)cp->internal; - - /* - * If a cursor is deleted, it doesn't refer to this - * item--it just happens to have the same indx, but - * it points to a former neighbor. Don't move it. - */ - if (F_ISSET(hcp, H_DELETED)) - continue; - - if (hcp->pgno == old_pgno) { - if (hcp->indx == old_index) { - hcp->pgno = new_pgno; - hcp->indx = new_index; - } else - continue; - if (my_txn != NULL && cp->txn != my_txn) - found = 1; - } - } - MUTEX_UNLOCK(dbenv, dbp->mutex); - } - MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist); - - if (found != 0 && DBC_LOGGING(dbc)) { - if ((ret = __ham_chgpg_log(dbp, my_txn, &lsn, 0, DB_HAM_CHGPG, - old_pgno, new_pgno, old_index, new_index)) != 0) - return (ret); - } - return (0); -} diff --git a/storage/bdb/hash/hash_func.c b/storage/bdb/hash/hash_func.c deleted file mode 100644 index c7094017d92..00000000000 --- a/storage/bdb/hash/hash_func.c +++ /dev/null @@ -1,245 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993 - * Margo Seltzer. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Margo Seltzer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: hash_func.c,v 12.1 2005/06/16 20:22:52 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/hash.h" - -/* - * __ham_func2 -- - * Phong Vo's linear congruential hash. - * - * PUBLIC: u_int32_t __ham_func2 __P((DB *, const void *, u_int32_t)); - */ -#define DCHARHASH(h, c) ((h) = 0x63c63cd9*(h) + 0x9c39c33d + (c)) - -u_int32_t -__ham_func2(dbp, key, len) - DB *dbp; - const void *key; - u_int32_t len; -{ - const u_int8_t *e, *k; - u_int32_t h; - u_int8_t c; - - if (dbp != NULL) - COMPQUIET(dbp, NULL); - - k = key; - e = k + len; - for (h = 0; k != e;) { - c = *k++; - if (!c && k > e) - break; - DCHARHASH(h, c); - } - return (h); -} - -/* - * __ham_func3 -- - * Ozan Yigit's original sdbm hash. - * - * Ugly, but fast. Break the string up into 8 byte units. On the first time - * through the loop get the "leftover bytes" (strlen % 8). On every other - * iteration, perform 8 HASHC's so we handle all 8 bytes. Essentially, this - * saves us 7 cmp & branch instructions. - * - * PUBLIC: u_int32_t __ham_func3 __P((DB *, const void *, u_int32_t)); - */ -u_int32_t -__ham_func3(dbp, key, len) - DB *dbp; - const void *key; - u_int32_t len; -{ - const u_int8_t *k; - u_int32_t n, loop; - - if (dbp != NULL) - COMPQUIET(dbp, NULL); - - if (len == 0) - return (0); - -#define HASHC n = *k++ + 65599 * n - n = 0; - k = key; - - loop = (len + 8 - 1) >> 3; - switch (len & (8 - 1)) { - case 0: - do { - HASHC; - case 7: - HASHC; - case 6: - HASHC; - case 5: - HASHC; - case 4: - HASHC; - case 3: - HASHC; - case 2: - HASHC; - case 1: - HASHC; - } while (--loop); - } - return (n); -} - -/* - * __ham_func4 -- - * Chris Torek's hash function. Although this function performs only - * slightly worse than __ham_func5 on strings, it performs horribly on - * numbers. - * - * PUBLIC: u_int32_t __ham_func4 __P((DB *, const void *, u_int32_t)); - */ -u_int32_t -__ham_func4(dbp, key, len) - DB *dbp; - const void *key; - u_int32_t len; -{ - const u_int8_t *k; - u_int32_t h, loop; - - if (dbp != NULL) - COMPQUIET(dbp, NULL); - - if (len == 0) - return (0); - -#define HASH4a h = (h << 5) - h + *k++; -#define HASH4b h = (h << 5) + h + *k++; -#define HASH4 HASH4b - h = 0; - k = key; - - loop = (len + 8 - 1) >> 3; - switch (len & (8 - 1)) { - case 0: - do { - HASH4; - case 7: - HASH4; - case 6: - HASH4; - case 5: - HASH4; - case 4: - HASH4; - case 3: - HASH4; - case 2: - HASH4; - case 1: - HASH4; - } while (--loop); - } - return (h); -} - -/* - * Fowler/Noll/Vo hash - * - * The basis of the hash algorithm was taken from an idea sent by email to the - * IEEE Posix P1003.2 mailing list from Phong Vo (kpv@research.att.com) and - * Glenn Fowler (gsf@research.att.com). Landon Curt Noll (chongo@toad.com) - * later improved on their algorithm. - * - * The magic is in the interesting relationship between the special prime - * 16777619 (2^24 + 403) and 2^32 and 2^8. - * - * This hash produces the fewest collisions of any function that we've seen so - * far, and works well on both numbers and strings. - * - * PUBLIC: u_int32_t __ham_func5 __P((DB *, const void *, u_int32_t)); - */ -u_int32_t -__ham_func5(dbp, key, len) - DB *dbp; - const void *key; - u_int32_t len; -{ - const u_int8_t *k, *e; - u_int32_t h; - - if (dbp != NULL) - COMPQUIET(dbp, NULL); - - k = key; - e = k + len; - for (h = 0; k < e; ++k) { - h *= 16777619; - h ^= *k; - } - return (h); -} - -/* - * __ham_test -- - * - * PUBLIC: u_int32_t __ham_test __P((DB *, const void *, u_int32_t)); - */ -u_int32_t -__ham_test(dbp, key, len) - DB *dbp; - const void *key; - u_int32_t len; -{ - COMPQUIET(dbp, NULL); - COMPQUIET(len, 0); - return ((u_int32_t)*(char *)key); -} diff --git a/storage/bdb/hash/hash_meta.c b/storage/bdb/hash/hash_meta.c deleted file mode 100644 index 010e0da3ddf..00000000000 --- a/storage/bdb/hash/hash_meta.c +++ /dev/null @@ -1,104 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: hash_meta.c,v 12.1 2005/06/16 20:22:52 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/hash.h" -#include "dbinc/lock.h" -#include "dbinc/mp.h" - -/* - * Acquire the meta-data page. - * - * PUBLIC: int __ham_get_meta __P((DBC *)); - */ -int -__ham_get_meta(dbc) - DBC *dbc; -{ - DB *dbp; - DB_MPOOLFILE *mpf; - HASH *hashp; - HASH_CURSOR *hcp; - int ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - hashp = dbp->h_internal; - hcp = (HASH_CURSOR *)dbc->internal; - - if ((ret = __db_lget(dbc, 0, - hashp->meta_pgno, DB_LOCK_READ, 0, &hcp->hlock)) != 0) - return (ret); - - if ((ret = __memp_fget(mpf, - &hashp->meta_pgno, DB_MPOOL_CREATE, &(hcp->hdr))) != 0) - (void)__LPUT(dbc, hcp->hlock); - - return (ret); -} - -/* - * Release the meta-data page. - * - * PUBLIC: int __ham_release_meta __P((DBC *)); - */ -int -__ham_release_meta(dbc) - DBC *dbc; -{ - DB_MPOOLFILE *mpf; - HASH_CURSOR *hcp; - - mpf = dbc->dbp->mpf; - hcp = (HASH_CURSOR *)dbc->internal; - - if (hcp->hdr) - (void)__memp_fput(mpf, hcp->hdr, - F_ISSET(hcp, H_DIRTY) ? DB_MPOOL_DIRTY : 0); - hcp->hdr = NULL; - F_CLR(hcp, H_DIRTY); - - return (__TLPUT(dbc, hcp->hlock)); -} - -/* - * Mark the meta-data page dirty. - * - * PUBLIC: int __ham_dirty_meta __P((DBC *)); - */ -int -__ham_dirty_meta(dbc) - DBC *dbc; -{ - DB *dbp; - HASH *hashp; - HASH_CURSOR *hcp; - int ret; - - dbp = dbc->dbp; - hashp = dbp->h_internal; - hcp = (HASH_CURSOR *)dbc->internal; - - ret = 0; - - ret = __db_lget(dbc, LCK_COUPLE, - hashp->meta_pgno, DB_LOCK_WRITE, 0, &hcp->hlock); - - if (ret == 0) - F_SET(hcp, H_DIRTY); - return (ret); -} diff --git a/storage/bdb/hash/hash_method.c b/storage/bdb/hash/hash_method.c deleted file mode 100644 index 96e3e5d0875..00000000000 --- a/storage/bdb/hash/hash_method.c +++ /dev/null @@ -1,162 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: hash_method.c,v 12.1 2005/06/16 20:22:53 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/hash.h" - -static int __ham_set_h_ffactor __P((DB *, u_int32_t)); -static int __ham_set_h_hash - __P((DB *, u_int32_t(*)(DB *, const void *, u_int32_t))); -static int __ham_set_h_nelem __P((DB *, u_int32_t)); - -/* - * __ham_db_create -- - * Hash specific initialization of the DB structure. - * - * PUBLIC: int __ham_db_create __P((DB *)); - */ -int -__ham_db_create(dbp) - DB *dbp; -{ - HASH *hashp; - int ret; - - if ((ret = __os_malloc(dbp->dbenv, - sizeof(HASH), &dbp->h_internal)) != 0) - return (ret); - - hashp = dbp->h_internal; - - hashp->h_nelem = 0; /* Defaults. */ - hashp->h_ffactor = 0; - hashp->h_hash = NULL; - - dbp->get_h_ffactor = __ham_get_h_ffactor; - dbp->set_h_ffactor = __ham_set_h_ffactor; - dbp->set_h_hash = __ham_set_h_hash; - dbp->get_h_nelem = __ham_get_h_nelem; - dbp->set_h_nelem = __ham_set_h_nelem; - - return (0); -} - -/* - * PUBLIC: int __ham_db_close __P((DB *)); - */ -int -__ham_db_close(dbp) - DB *dbp; -{ - if (dbp->h_internal == NULL) - return (0); - __os_free(dbp->dbenv, dbp->h_internal); - dbp->h_internal = NULL; - return (0); -} - -/* - * __ham_get_h_ffactor -- - * - * PUBLIC: int __ham_get_h_ffactor __P((DB *, u_int32_t *)); - */ -int -__ham_get_h_ffactor(dbp, h_ffactorp) - DB *dbp; - u_int32_t *h_ffactorp; -{ - HASH *hashp; - - hashp = dbp->h_internal; - *h_ffactorp = hashp->h_ffactor; - return (0); -} - -/* - * __ham_set_h_ffactor -- - * Set the fill factor. - */ -static int -__ham_set_h_ffactor(dbp, h_ffactor) - DB *dbp; - u_int32_t h_ffactor; -{ - HASH *hashp; - - DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_h_ffactor"); - DB_ILLEGAL_METHOD(dbp, DB_OK_HASH); - - hashp = dbp->h_internal; - hashp->h_ffactor = h_ffactor; - return (0); -} - -/* - * __ham_set_h_hash -- - * Set the hash function. - */ -static int -__ham_set_h_hash(dbp, func) - DB *dbp; - u_int32_t (*func) __P((DB *, const void *, u_int32_t)); -{ - HASH *hashp; - - DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_h_hash"); - DB_ILLEGAL_METHOD(dbp, DB_OK_HASH); - - hashp = dbp->h_internal; - hashp->h_hash = func; - return (0); -} - -/* - * __db_get_h_nelem -- - * - * PUBLIC: int __ham_get_h_nelem __P((DB *, u_int32_t *)); - */ -int -__ham_get_h_nelem(dbp, h_nelemp) - DB *dbp; - u_int32_t *h_nelemp; -{ - HASH *hashp; - - DB_ILLEGAL_METHOD(dbp, DB_OK_HASH); - - hashp = dbp->h_internal; - *h_nelemp = hashp->h_nelem; - return (0); -} - -/* - * __ham_set_h_nelem -- - * Set the table size. - */ -static int -__ham_set_h_nelem(dbp, h_nelem) - DB *dbp; - u_int32_t h_nelem; -{ - HASH *hashp; - - DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_h_nelem"); - DB_ILLEGAL_METHOD(dbp, DB_OK_HASH); - - hashp = dbp->h_internal; - hashp->h_nelem = h_nelem; - return (0); -} diff --git a/storage/bdb/hash/hash_open.c b/storage/bdb/hash/hash_open.c deleted file mode 100644 index 91ad4b45a45..00000000000 --- a/storage/bdb/hash/hash_open.c +++ /dev/null @@ -1,559 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994 - * Margo Seltzer. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Margo Seltzer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: hash_open.c,v 12.7 2005/11/09 14:19:51 margo Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/crypto.h" -#include "dbinc/db_page.h" -#include "dbinc/hash.h" -#include "dbinc/log.h" -#include "dbinc/db_shash.h" -#include "dbinc/lock.h" -#include "dbinc/mp.h" -#include "dbinc/btree.h" -#include "dbinc/fop.h" - -static db_pgno_t __ham_init_meta __P((DB *, HMETA *, db_pgno_t, DB_LSN *)); - -/* - * __ham_open -- - * - * PUBLIC: int __ham_open __P((DB *, - * PUBLIC: DB_TXN *, const char * name, db_pgno_t, u_int32_t)); - */ -int -__ham_open(dbp, txn, name, base_pgno, flags) - DB *dbp; - DB_TXN *txn; - const char *name; - db_pgno_t base_pgno; - u_int32_t flags; -{ - DB_ENV *dbenv; - DBC *dbc; - HASH_CURSOR *hcp; - HASH *hashp; - int ret, t_ret; - - dbenv = dbp->dbenv; - dbc = NULL; - - /* - * Get a cursor. If DB_CREATE is specified, we may be creating - * pages, and to do that safely in CDB we need a write cursor. - * In STD_LOCKING mode, we'll synchronize using the meta page - * lock instead. - */ - if ((ret = __db_cursor(dbp, - txn, &dbc, LF_ISSET(DB_CREATE) && CDB_LOCKING(dbenv) ? - DB_WRITECURSOR : 0)) != 0) - return (ret); - - hcp = (HASH_CURSOR *)dbc->internal; - hashp = dbp->h_internal; - hashp->meta_pgno = base_pgno; - if ((ret = __ham_get_meta(dbc)) != 0) - goto err1; - - /* Initialize the hdr structure. */ - if (hcp->hdr->dbmeta.magic == DB_HASHMAGIC) { - /* File exists, verify the data in the header. */ - if (hashp->h_hash == NULL) - hashp->h_hash = hcp->hdr->dbmeta.version < 5 - ? __ham_func4 : __ham_func5; - if (!F_ISSET(dbp, DB_AM_RDONLY) && !IS_RECOVERING(dbenv) && - hashp->h_hash(dbp, - CHARKEY, sizeof(CHARKEY)) != hcp->hdr->h_charkey) { - __db_err(dbp->dbenv, - "hash: incompatible hash function"); - ret = EINVAL; - goto err2; - } - hashp->h_nelem = hcp->hdr->nelem; - if (F_ISSET(&hcp->hdr->dbmeta, DB_HASH_DUP)) - F_SET(dbp, DB_AM_DUP); - if (F_ISSET(&hcp->hdr->dbmeta, DB_HASH_DUPSORT)) - F_SET(dbp, DB_AM_DUPSORT); - if (F_ISSET(&hcp->hdr->dbmeta, DB_HASH_SUBDB)) - F_SET(dbp, DB_AM_SUBDB); - - } else if (!IS_RECOVERING(dbenv) && !F_ISSET(dbp, DB_AM_RECOVER)) { - __db_err(dbp->dbenv, - "%s: Invalid hash meta page %d", name, base_pgno); - ret = EINVAL; - } - -err2: /* Release the meta data page */ - if ((t_ret = __ham_release_meta(dbc)) != 0 && ret == 0) - ret = t_ret; -err1: if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __ham_metachk -- - * - * PUBLIC: int __ham_metachk __P((DB *, const char *, HMETA *)); - */ -int -__ham_metachk(dbp, name, hashm) - DB *dbp; - const char *name; - HMETA *hashm; -{ - DB_ENV *dbenv; - u_int32_t vers; - int ret; - - dbenv = dbp->dbenv; - - /* - * At this point, all we know is that the magic number is for a Hash. - * Check the version, the database may be out of date. - */ - vers = hashm->dbmeta.version; - if (F_ISSET(dbp, DB_AM_SWAP)) - M_32_SWAP(vers); - switch (vers) { - case 4: - case 5: - case 6: - __db_err(dbenv, - "%s: hash version %lu requires a version upgrade", - name, (u_long)vers); - return (DB_OLD_VERSION); - case 7: - case 8: - break; - default: - __db_err(dbenv, - "%s: unsupported hash version: %lu", name, (u_long)vers); - return (EINVAL); - } - - /* Swap the page if we need to. */ - if (F_ISSET(dbp, DB_AM_SWAP) && (ret = __ham_mswap((PAGE *)hashm)) != 0) - return (ret); - - /* Check the type. */ - if (dbp->type != DB_HASH && dbp->type != DB_UNKNOWN) - return (EINVAL); - dbp->type = DB_HASH; - DB_ILLEGAL_METHOD(dbp, DB_OK_HASH); - - /* - * Check application info against metadata info, and set info, flags, - * and type based on metadata info. - */ - if ((ret = __db_fchk(dbenv, - "DB->open", hashm->dbmeta.flags, - DB_HASH_DUP | DB_HASH_SUBDB | DB_HASH_DUPSORT)) != 0) - return (ret); - - if (F_ISSET(&hashm->dbmeta, DB_HASH_DUP)) - F_SET(dbp, DB_AM_DUP); - else - if (F_ISSET(dbp, DB_AM_DUP)) { - __db_err(dbenv, - "%s: DB_DUP specified to open method but not set in database", - name); - return (EINVAL); - } - - if (F_ISSET(&hashm->dbmeta, DB_HASH_SUBDB)) - F_SET(dbp, DB_AM_SUBDB); - else - if (F_ISSET(dbp, DB_AM_SUBDB)) { - __db_err(dbenv, - "%s: multiple databases specified but not supported in file", - name); - return (EINVAL); - } - - if (F_ISSET(&hashm->dbmeta, DB_HASH_DUPSORT)) { - if (dbp->dup_compare == NULL) - dbp->dup_compare = __bam_defcmp; - } else - if (dbp->dup_compare != NULL) { - __db_err(dbenv, - "%s: duplicate sort function specified but not set in database", - name); - return (EINVAL); - } - - /* Set the page size. */ - dbp->pgsize = hashm->dbmeta.pagesize; - - /* Copy the file's ID. */ - memcpy(dbp->fileid, hashm->dbmeta.uid, DB_FILE_ID_LEN); - - return (0); -} - -/* - * __ham_init_meta -- - * - * Initialize a hash meta-data page. We assume that the meta-data page is - * contiguous with the initial buckets that we create. If that turns out - * to be false, we'll fix it up later. Return the initial number of buckets - * allocated. - */ -static db_pgno_t -__ham_init_meta(dbp, meta, pgno, lsnp) - DB *dbp; - HMETA *meta; - db_pgno_t pgno; - DB_LSN *lsnp; -{ - HASH *hashp; - db_pgno_t nbuckets; - u_int i, l2; - - hashp = dbp->h_internal; - if (hashp->h_hash == NULL) - hashp->h_hash = DB_HASHVERSION < 5 ? __ham_func4 : __ham_func5; - - if (hashp->h_nelem != 0 && hashp->h_ffactor != 0) { - hashp->h_nelem = (hashp->h_nelem - 1) / hashp->h_ffactor + 1; - l2 = __db_log2(hashp->h_nelem > 2 ? hashp->h_nelem : 2); - } else - l2 = 1; - nbuckets = (db_pgno_t)(1 << l2); - - memset(meta, 0, sizeof(HMETA)); - meta->dbmeta.lsn = *lsnp; - meta->dbmeta.pgno = pgno; - meta->dbmeta.magic = DB_HASHMAGIC; - meta->dbmeta.version = DB_HASHVERSION; - meta->dbmeta.pagesize = dbp->pgsize; - if (F_ISSET(dbp, DB_AM_CHKSUM)) - FLD_SET(meta->dbmeta.metaflags, DBMETA_CHKSUM); - if (F_ISSET(dbp, DB_AM_ENCRYPT)) { - meta->dbmeta.encrypt_alg = - ((DB_CIPHER *)dbp->dbenv->crypto_handle)->alg; - DB_ASSERT(meta->dbmeta.encrypt_alg != 0); - meta->crypto_magic = meta->dbmeta.magic; - } - meta->dbmeta.type = P_HASHMETA; - meta->dbmeta.free = PGNO_INVALID; - meta->dbmeta.last_pgno = pgno; - meta->max_bucket = nbuckets - 1; - meta->high_mask = nbuckets - 1; - meta->low_mask = (nbuckets >> 1) - 1; - meta->ffactor = hashp->h_ffactor; - meta->nelem = hashp->h_nelem; - meta->h_charkey = hashp->h_hash(dbp, CHARKEY, sizeof(CHARKEY)); - memcpy(meta->dbmeta.uid, dbp->fileid, DB_FILE_ID_LEN); - - if (F_ISSET(dbp, DB_AM_DUP)) - F_SET(&meta->dbmeta, DB_HASH_DUP); - if (F_ISSET(dbp, DB_AM_SUBDB)) - F_SET(&meta->dbmeta, DB_HASH_SUBDB); - if (dbp->dup_compare != NULL) - F_SET(&meta->dbmeta, DB_HASH_DUPSORT); - - /* - * Create the first and second buckets pages so that we have the - * page numbers for them and we can store that page number in the - * meta-data header (spares[0]). - */ - meta->spares[0] = pgno + 1; - - /* Fill in the last fields of the meta data page. */ - for (i = 1; i <= l2; i++) - meta->spares[i] = meta->spares[0]; - for (; i < NCACHED; i++) - meta->spares[i] = PGNO_INVALID; - - return (nbuckets); -} - -/* - * __ham_new_file -- - * Create the necessary pages to begin a new database file. If name - * is NULL, then this is an unnamed file, the mpf has been set in the dbp - * and we simply create the pages using mpool. In this case, we don't log - * because we never have to redo an unnamed create and the undo simply - * frees resources. - * - * This code appears more complex than it is because of the two cases (named - * and unnamed). The way to read the code is that for each page being created, - * there are three parts: 1) a "get page" chunk (which either uses malloc'd - * memory or calls __memp_fget), 2) the initialization, and 3) the "put page" - * chunk which either does a fop write or an __memp_fput. - * - * PUBLIC: int __ham_new_file __P((DB *, DB_TXN *, DB_FH *, const char *)); - */ -int -__ham_new_file(dbp, txn, fhp, name) - DB *dbp; - DB_TXN *txn; - DB_FH *fhp; - const char *name; -{ - DB_ENV *dbenv; - DB_LSN lsn; - DB_MPOOLFILE *mpf; - DB_PGINFO pginfo; - DBT pdbt; - HMETA *meta; - PAGE *page; - int ret; - db_pgno_t lpgno; - void *buf; - - dbenv = dbp->dbenv; - mpf = dbp->mpf; - meta = NULL; - page = NULL; - buf = NULL; - - if (F_ISSET(dbp, DB_AM_INMEM)) { - /* Build meta-data page. */ - lpgno = PGNO_BASE_MD; - if ((ret = - __memp_fget(mpf, &lpgno, DB_MPOOL_CREATE, &meta)) != 0) - return (ret); - LSN_NOT_LOGGED(lsn); - lpgno = __ham_init_meta(dbp, meta, PGNO_BASE_MD, &lsn); - meta->dbmeta.last_pgno = lpgno; - if ((ret = __db_log_page(dbp, - txn, &lsn, meta->dbmeta.pgno, (PAGE *)meta)) != 0) - goto err; - ret = __memp_fput(mpf, meta, DB_MPOOL_DIRTY); - meta = NULL; - if (ret != 0) - goto err; - - /* Allocate the final hash bucket. */ - if ((ret = - __memp_fget(mpf, &lpgno, DB_MPOOL_CREATE, &page)) != 0) - goto err; - P_INIT(page, - dbp->pgsize, lpgno, PGNO_INVALID, PGNO_INVALID, 0, P_HASH); - LSN_NOT_LOGGED(page->lsn); - if ((ret = - __db_log_page(dbp, txn, &page->lsn, lpgno, page)) != 0) - goto err; - ret = __memp_fput(mpf, page, DB_MPOOL_DIRTY); - page = NULL; - if (ret != 0) - goto err; - } else { - memset(&pdbt, 0, sizeof(pdbt)); - - /* Build meta-data page. */ - pginfo.db_pagesize = dbp->pgsize; - pginfo.type = dbp->type; - pginfo.flags = - F_ISSET(dbp, (DB_AM_CHKSUM | DB_AM_ENCRYPT | DB_AM_SWAP)); - pdbt.data = &pginfo; - pdbt.size = sizeof(pginfo); - if ((ret = __os_calloc(dbp->dbenv, 1, dbp->pgsize, &buf)) != 0) - return (ret); - meta = (HMETA *)buf; - LSN_NOT_LOGGED(lsn); - lpgno = __ham_init_meta(dbp, meta, PGNO_BASE_MD, &lsn); - meta->dbmeta.last_pgno = lpgno; - if ((ret = __db_pgout(dbenv, PGNO_BASE_MD, meta, &pdbt)) != 0) - goto err; - if ((ret = __fop_write(dbenv, txn, name, DB_APP_DATA, fhp, - dbp->pgsize, 0, 0, buf, dbp->pgsize, 1, F_ISSET( - dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0)) != 0) - goto err; - meta = NULL; - - /* Allocate the final hash bucket. */ -#ifdef DIAGNOSTIC - memset(buf, 0, dbp->pgsize); -#endif - page = (PAGE *)buf; - P_INIT(page, - dbp->pgsize, lpgno, PGNO_INVALID, PGNO_INVALID, 0, P_HASH); - LSN_NOT_LOGGED(page->lsn); - if ((ret = __db_pgout(dbenv, lpgno, buf, &pdbt)) != 0) - goto err; - if ((ret = __fop_write(dbenv, txn, name, DB_APP_DATA, fhp, - dbp->pgsize, lpgno, 0, buf, dbp->pgsize, 1, F_ISSET( - dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0)) != 0) - goto err; - page = NULL; - } - -err: if (buf != NULL) - __os_free(dbenv, buf); - else { - if (meta != NULL) - (void)__memp_fput(mpf, meta, 0); - if (page != NULL) - (void)__memp_fput(mpf, page, 0); - } - return (ret); -} - -/* - * __ham_new_subdb -- - * Create the necessary pages to begin a new subdatabase. - * - * PUBLIC: int __ham_new_subdb __P((DB *, DB *, DB_TXN *)); - */ -int -__ham_new_subdb(mdbp, dbp, txn) - DB *mdbp, *dbp; - DB_TXN *txn; -{ - DBC *dbc; - DB_ENV *dbenv; - DB_LOCK metalock, mmlock; - DB_LSN lsn; - DB_MPOOLFILE *mpf; - DBMETA *mmeta; - HMETA *meta; - PAGE *h; - int i, ret, t_ret; - db_pgno_t lpgno, mpgno; - - dbenv = mdbp->dbenv; - mpf = mdbp->mpf; - dbc = NULL; - meta = NULL; - mmeta = NULL; - LOCK_INIT(metalock); - LOCK_INIT(mmlock); - - if ((ret = __db_cursor(mdbp, txn, - &dbc, CDB_LOCKING(dbenv) ? DB_WRITECURSOR : 0)) != 0) - return (ret); - - /* Get and lock the new meta data page. */ - if ((ret = __db_lget(dbc, - 0, dbp->meta_pgno, DB_LOCK_WRITE, 0, &metalock)) != 0) - goto err; - if ((ret = - __memp_fget(mpf, &dbp->meta_pgno, DB_MPOOL_CREATE, &meta)) != 0) - goto err; - - /* Initialize the new meta-data page. */ - lsn = meta->dbmeta.lsn; - lpgno = __ham_init_meta(dbp, meta, dbp->meta_pgno, &lsn); - - /* - * We are about to allocate a set of contiguous buckets (lpgno - * worth). We need to get the master meta-data page to figure - * out where these pages are and to allocate them. So, lock and - * get the master meta data page. - */ - mpgno = PGNO_BASE_MD; - if ((ret = __db_lget(dbc, 0, mpgno, DB_LOCK_WRITE, 0, &mmlock)) != 0) - goto err; - if ((ret = __memp_fget(mpf, &mpgno, 0, &mmeta)) != 0) - goto err; - - /* - * Now update the hash meta-data page to reflect where the first - * set of buckets are actually located. - */ - meta->spares[0] = mmeta->last_pgno + 1; - for (i = 0; i < NCACHED && meta->spares[i] != PGNO_INVALID; i++) - meta->spares[i] = meta->spares[0]; - - /* The new meta data page is now complete; log it. */ - if ((ret = __db_log_page(mdbp, - txn, &meta->dbmeta.lsn, dbp->meta_pgno, (PAGE *)meta)) != 0) - goto err; - - /* Reflect the group allocation. */ - if (DBENV_LOGGING(dbenv)) - if ((ret = __ham_groupalloc_log(mdbp, txn, - &LSN(mmeta), 0, &LSN(mmeta), meta->spares[0], - meta->max_bucket + 1, mmeta->free, mmeta->last_pgno)) != 0) - goto err; - - /* Release the new meta-data page. */ - if ((ret = __memp_fput(mpf, meta, DB_MPOOL_DIRTY)) != 0) - goto err; - meta = NULL; - - lpgno += mmeta->last_pgno; - - /* Now allocate the final hash bucket. */ - if ((ret = __memp_fget(mpf, &lpgno, DB_MPOOL_CREATE, &h)) != 0) - goto err; - - mmeta->last_pgno = lpgno; - P_INIT(h, dbp->pgsize, lpgno, PGNO_INVALID, PGNO_INVALID, 0, P_HASH); - LSN(h) = LSN(mmeta); - if ((ret = __memp_fput(mpf, h, DB_MPOOL_DIRTY)) != 0) - goto err; - - /* Now put the master-metadata page back. */ - if ((ret = __memp_fput(mpf, mmeta, DB_MPOOL_DIRTY)) != 0) - goto err; - mmeta = NULL; - -err: - if (mmeta != NULL) - if ((t_ret = __memp_fput(mpf, mmeta, 0)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = __LPUT(dbc, mmlock)) != 0 && ret == 0) - ret = t_ret; - if (meta != NULL) - if ((t_ret = __memp_fput(mpf, meta, 0)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0) - ret = t_ret; - if (dbc != NULL) - if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0) - ret = t_ret; - return (ret); -} diff --git a/storage/bdb/hash/hash_page.c b/storage/bdb/hash/hash_page.c deleted file mode 100644 index 769a874f4e0..00000000000 --- a/storage/bdb/hash/hash_page.c +++ /dev/null @@ -1,1956 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994 - * Margo Seltzer. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Margo Seltzer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: hash_page.c,v 12.7 2005/10/13 22:22:43 ubell Exp $ - */ - -#include "db_config.h" - -/* - * PACKAGE: hashing - * - * DESCRIPTION: - * Page manipulation for hashing package. - */ - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/hash.h" -#include "dbinc/lock.h" -#include "dbinc/mp.h" - -static int __ham_c_delpg - __P((DBC *, db_pgno_t, db_pgno_t, u_int32_t, db_ham_mode, u_int32_t *)); - -/* - * PUBLIC: int __ham_item __P((DBC *, db_lockmode_t, db_pgno_t *)); - */ -int -__ham_item(dbc, mode, pgnop) - DBC *dbc; - db_lockmode_t mode; - db_pgno_t *pgnop; -{ - DB *dbp; - HASH_CURSOR *hcp; - db_pgno_t next_pgno; - int ret; - - dbp = dbc->dbp; - hcp = (HASH_CURSOR *)dbc->internal; - - if (F_ISSET(hcp, H_DELETED)) { - __db_err(dbp->dbenv, "Attempt to return a deleted item"); - return (EINVAL); - } - F_CLR(hcp, H_OK | H_NOMORE); - - /* Check if we need to get a page for this cursor. */ - if ((ret = __ham_get_cpage(dbc, mode)) != 0) - return (ret); - -recheck: - /* Check if we are looking for space in which to insert an item. */ - if (hcp->seek_size && hcp->seek_found_page == PGNO_INVALID && - hcp->seek_size < P_FREESPACE(dbp, hcp->page)) - hcp->seek_found_page = hcp->pgno; - - /* Check for off-page duplicates. */ - if (hcp->indx < NUM_ENT(hcp->page) && - HPAGE_TYPE(dbp, hcp->page, H_DATAINDEX(hcp->indx)) == H_OFFDUP) { - memcpy(pgnop, - HOFFDUP_PGNO(H_PAIRDATA(dbp, hcp->page, hcp->indx)), - sizeof(db_pgno_t)); - F_SET(hcp, H_OK); - return (0); - } - - /* Check if we need to go on to the next page. */ - if (F_ISSET(hcp, H_ISDUP)) - /* - * ISDUP is set, and offset is at the beginning of the datum. - * We need to grab the length of the datum, then set the datum - * pointer to be the beginning of the datum. - */ - memcpy(&hcp->dup_len, - HKEYDATA_DATA(H_PAIRDATA(dbp, hcp->page, hcp->indx)) + - hcp->dup_off, sizeof(db_indx_t)); - - if (hcp->indx >= (db_indx_t)NUM_ENT(hcp->page)) { - /* Fetch next page. */ - if (NEXT_PGNO(hcp->page) == PGNO_INVALID) { - F_SET(hcp, H_NOMORE); - return (DB_NOTFOUND); - } - next_pgno = NEXT_PGNO(hcp->page); - hcp->indx = 0; - if ((ret = __ham_next_cpage(dbc, next_pgno, 0)) != 0) - return (ret); - goto recheck; - } - - F_SET(hcp, H_OK); - return (0); -} - -/* - * PUBLIC: int __ham_item_reset __P((DBC *)); - */ -int -__ham_item_reset(dbc) - DBC *dbc; -{ - DB *dbp; - DB_MPOOLFILE *mpf; - HASH_CURSOR *hcp; - int ret, t_ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - hcp = (HASH_CURSOR *)dbc->internal; - - ret = 0; - if (hcp->page != NULL) - ret = __memp_fput(mpf, hcp->page, 0); - - if ((t_ret = __ham_item_init(dbc)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * PUBLIC: int __ham_item_init __P((DBC *)); - */ -int -__ham_item_init(dbc) - DBC *dbc; -{ - HASH_CURSOR *hcp; - int ret; - - hcp = (HASH_CURSOR *)dbc->internal; - - /* - * If this cursor still holds any locks, we must release them if - * we are not running with transactions. - */ - ret = __TLPUT(dbc, hcp->lock); - - /* - * The following fields must *not* be initialized here because they - * may have meaning across inits. - * hlock, hdr, split_buf, stats - */ - hcp->bucket = BUCKET_INVALID; - hcp->lbucket = BUCKET_INVALID; - LOCK_INIT(hcp->lock); - hcp->lock_mode = DB_LOCK_NG; - hcp->dup_off = 0; - hcp->dup_len = 0; - hcp->dup_tlen = 0; - hcp->seek_size = 0; - hcp->seek_found_page = PGNO_INVALID; - hcp->flags = 0; - - hcp->pgno = PGNO_INVALID; - hcp->indx = NDX_INVALID; - hcp->page = NULL; - - return (ret); -} - -/* - * Returns the last item in a bucket. - * - * PUBLIC: int __ham_item_last __P((DBC *, db_lockmode_t, db_pgno_t *)); - */ -int -__ham_item_last(dbc, mode, pgnop) - DBC *dbc; - db_lockmode_t mode; - db_pgno_t *pgnop; -{ - HASH_CURSOR *hcp; - int ret; - - hcp = (HASH_CURSOR *)dbc->internal; - if ((ret = __ham_item_reset(dbc)) != 0) - return (ret); - - hcp->bucket = hcp->hdr->max_bucket; - hcp->pgno = BUCKET_TO_PAGE(hcp, hcp->bucket); - F_SET(hcp, H_OK); - return (__ham_item_prev(dbc, mode, pgnop)); -} - -/* - * PUBLIC: int __ham_item_first __P((DBC *, db_lockmode_t, db_pgno_t *)); - */ -int -__ham_item_first(dbc, mode, pgnop) - DBC *dbc; - db_lockmode_t mode; - db_pgno_t *pgnop; -{ - HASH_CURSOR *hcp; - int ret; - - hcp = (HASH_CURSOR *)dbc->internal; - if ((ret = __ham_item_reset(dbc)) != 0) - return (ret); - F_SET(hcp, H_OK); - hcp->bucket = 0; - hcp->pgno = BUCKET_TO_PAGE(hcp, hcp->bucket); - return (__ham_item_next(dbc, mode, pgnop)); -} - -/* - * __ham_item_prev -- - * Returns a pointer to key/data pair on a page. In the case of - * bigkeys, just returns the page number and index of the bigkey - * pointer pair. - * - * PUBLIC: int __ham_item_prev __P((DBC *, db_lockmode_t, db_pgno_t *)); - */ -int -__ham_item_prev(dbc, mode, pgnop) - DBC *dbc; - db_lockmode_t mode; - db_pgno_t *pgnop; -{ - DB *dbp; - HASH_CURSOR *hcp; - db_pgno_t next_pgno; - int ret; - - hcp = (HASH_CURSOR *)dbc->internal; - dbp = dbc->dbp; - - /* - * There are 5 cases for backing up in a hash file. - * Case 1: In the middle of a page, no duplicates, just dec the index. - * Case 2: In the middle of a duplicate set, back up one. - * Case 3: At the beginning of a duplicate set, get out of set and - * back up to next key. - * Case 4: At the beginning of a page; go to previous page. - * Case 5: At the beginning of a bucket; go to prev bucket. - */ - F_CLR(hcp, H_OK | H_NOMORE | H_DELETED); - - if ((ret = __ham_get_cpage(dbc, mode)) != 0) - return (ret); - - /* - * First handle the duplicates. Either you'll get the key here - * or you'll exit the duplicate set and drop into the code below - * to handle backing up through keys. - */ - if (!F_ISSET(hcp, H_NEXT_NODUP) && F_ISSET(hcp, H_ISDUP)) { - if (HPAGE_TYPE(dbp, hcp->page, H_DATAINDEX(hcp->indx)) == - H_OFFDUP) { - memcpy(pgnop, - HOFFDUP_PGNO(H_PAIRDATA(dbp, hcp->page, hcp->indx)), - sizeof(db_pgno_t)); - F_SET(hcp, H_OK); - return (0); - } - - /* Duplicates are on-page. */ - if (hcp->dup_off != 0) { - memcpy(&hcp->dup_len, HKEYDATA_DATA( - H_PAIRDATA(dbp, hcp->page, hcp->indx)) - + hcp->dup_off - sizeof(db_indx_t), - sizeof(db_indx_t)); - hcp->dup_off -= - DUP_SIZE(hcp->dup_len); - return (__ham_item(dbc, mode, pgnop)); - } - } - - /* - * If we get here, we are not in a duplicate set, and just need - * to back up the cursor. There are still three cases: - * midpage, beginning of page, beginning of bucket. - */ - - if (F_ISSET(hcp, H_DUPONLY)) { - F_CLR(hcp, H_OK); - F_SET(hcp, H_NOMORE); - return (0); - } else - /* - * We are no longer in a dup set; flag this so the dup code - * will reinitialize should we stumble upon another one. - */ - F_CLR(hcp, H_ISDUP); - - if (hcp->indx == 0) { /* Beginning of page. */ - hcp->pgno = PREV_PGNO(hcp->page); - if (hcp->pgno == PGNO_INVALID) { - /* Beginning of bucket. */ - F_SET(hcp, H_NOMORE); - return (DB_NOTFOUND); - } else if ((ret = - __ham_next_cpage(dbc, hcp->pgno, 0)) != 0) - return (ret); - else - hcp->indx = NUM_ENT(hcp->page); - } - - /* - * Either we've got the cursor set up to be decremented, or we - * have to find the end of a bucket. - */ - if (hcp->indx == NDX_INVALID) { - DB_ASSERT(hcp->page != NULL); - - hcp->indx = NUM_ENT(hcp->page); - for (next_pgno = NEXT_PGNO(hcp->page); - next_pgno != PGNO_INVALID; - next_pgno = NEXT_PGNO(hcp->page)) { - if ((ret = __ham_next_cpage(dbc, next_pgno, 0)) != 0) - return (ret); - hcp->indx = NUM_ENT(hcp->page); - } - - if (hcp->indx == 0) { - /* Bucket was empty. */ - F_SET(hcp, H_NOMORE); - return (DB_NOTFOUND); - } - } - - hcp->indx -= 2; - - return (__ham_item(dbc, mode, pgnop)); -} - -/* - * Sets the cursor to the next key/data pair on a page. - * - * PUBLIC: int __ham_item_next __P((DBC *, db_lockmode_t, db_pgno_t *)); - */ -int -__ham_item_next(dbc, mode, pgnop) - DBC *dbc; - db_lockmode_t mode; - db_pgno_t *pgnop; -{ - HASH_CURSOR *hcp; - int ret; - - hcp = (HASH_CURSOR *)dbc->internal; - - if ((ret = __ham_get_cpage(dbc, mode)) != 0) - return (ret); - - /* - * Deleted on-page duplicates are a weird case. If we delete the last - * one, then our cursor is at the very end of a duplicate set and - * we actually need to go on to the next key. - */ - if (F_ISSET(hcp, H_DELETED)) { - if (hcp->indx != NDX_INVALID && - F_ISSET(hcp, H_ISDUP) && - HPAGE_TYPE(dbc->dbp, hcp->page, H_DATAINDEX(hcp->indx)) - == H_DUPLICATE && hcp->dup_tlen == hcp->dup_off) { - if (F_ISSET(hcp, H_DUPONLY)) { - F_CLR(hcp, H_OK); - F_SET(hcp, H_NOMORE); - return (0); - } else { - F_CLR(hcp, H_ISDUP); - hcp->indx += 2; - } - } else if (!F_ISSET(hcp, H_ISDUP) && F_ISSET(hcp, H_DUPONLY)) { - F_CLR(hcp, H_OK); - F_SET(hcp, H_NOMORE); - return (0); - } else if (F_ISSET(hcp, H_ISDUP) && - F_ISSET(hcp, H_NEXT_NODUP)) { - F_CLR(hcp, H_ISDUP); - hcp->indx += 2; - } - F_CLR(hcp, H_DELETED); - } else if (hcp->indx == NDX_INVALID) { - hcp->indx = 0; - F_CLR(hcp, H_ISDUP); - } else if (F_ISSET(hcp, H_NEXT_NODUP)) { - hcp->indx += 2; - F_CLR(hcp, H_ISDUP); - } else if (F_ISSET(hcp, H_ISDUP) && hcp->dup_tlen != 0) { - if (hcp->dup_off + DUP_SIZE(hcp->dup_len) >= - hcp->dup_tlen && F_ISSET(hcp, H_DUPONLY)) { - F_CLR(hcp, H_OK); - F_SET(hcp, H_NOMORE); - return (0); - } - hcp->dup_off += DUP_SIZE(hcp->dup_len); - if (hcp->dup_off >= hcp->dup_tlen) { - F_CLR(hcp, H_ISDUP); - hcp->indx += 2; - } - } else if (F_ISSET(hcp, H_DUPONLY)) { - F_CLR(hcp, H_OK); - F_SET(hcp, H_NOMORE); - return (0); - } else { - hcp->indx += 2; - F_CLR(hcp, H_ISDUP); - } - - return (__ham_item(dbc, mode, pgnop)); -} - -/* - * PUBLIC: void __ham_putitem __P((DB *, PAGE *p, const DBT *, int)); - * - * This is a little bit sleazy in that we're overloading the meaning - * of the H_OFFPAGE type here. When we recover deletes, we have the - * entire entry instead of having only the DBT, so we'll pass type - * H_OFFPAGE to mean, "copy the whole entry" as opposed to constructing - * an H_KEYDATA around it. - */ -void -__ham_putitem(dbp, p, dbt, type) - DB *dbp; - PAGE *p; - const DBT *dbt; - int type; -{ - u_int16_t n, off; - db_indx_t *inp; - - n = NUM_ENT(p); - inp = P_INP(dbp, p); - - /* Put the item element on the page. */ - if (type == H_OFFPAGE) { - off = HOFFSET(p) - dbt->size; - HOFFSET(p) = inp[n] = off; - memcpy(P_ENTRY(dbp, p, n), dbt->data, dbt->size); - } else { - off = HOFFSET(p) - HKEYDATA_SIZE(dbt->size); - HOFFSET(p) = inp[n] = off; - PUT_HKEYDATA(P_ENTRY(dbp, p, n), dbt->data, dbt->size, type); - } - - /* Adjust page info. */ - NUM_ENT(p) += 1; -} - -/* - * PUBLIC: void __ham_reputpair __P((DB *, PAGE *, - * PUBLIC: u_int32_t, const DBT *, const DBT *)); - * - * This is a special case to restore a key/data pair to its original - * location during recovery. We are guaranteed that the pair fits - * on the page and is not the last pair on the page (because if it's - * the last pair, the normal insert works). - */ -void -__ham_reputpair(dbp, p, ndx, key, data) - DB *dbp; - PAGE *p; - u_int32_t ndx; - const DBT *key, *data; -{ - db_indx_t i, *inp, movebytes, newbytes; - size_t psize; - u_int8_t *from; - - psize = dbp->pgsize; - inp = P_INP(dbp, p); - /* First shuffle the existing items up on the page. */ - movebytes = (db_indx_t)( - (ndx == 0 ? psize : inp[H_DATAINDEX(ndx - 2)]) - HOFFSET(p)); - newbytes = key->size + data->size; - from = (u_int8_t *)p + HOFFSET(p); - memmove(from - newbytes, from, movebytes); - - /* - * Adjust the indices and move them up 2 spaces. Note that we - * have to check the exit condition inside the loop just in case - * we are dealing with index 0 (db_indx_t's are unsigned). - */ - for (i = NUM_ENT(p) - 1; ; i-- ) { - inp[i + 2] = inp[i] - newbytes; - if (i == H_KEYINDEX(ndx)) - break; - } - - /* Put the key and data on the page. */ - inp[H_KEYINDEX(ndx)] = (db_indx_t)( - (ndx == 0 ? psize : inp[H_DATAINDEX(ndx - 2)]) - key->size); - inp[H_DATAINDEX(ndx)] = inp[H_KEYINDEX(ndx)] - data->size; - memcpy(P_ENTRY(dbp, p, H_KEYINDEX(ndx)), key->data, key->size); - memcpy(P_ENTRY(dbp, p, H_DATAINDEX(ndx)), data->data, data->size); - - /* Adjust page info. */ - HOFFSET(p) -= newbytes; - NUM_ENT(p) += 2; -} - -/* - * PUBLIC: int __ham_del_pair __P((DBC *, int)); - */ -int -__ham_del_pair(dbc, reclaim_page) - DBC *dbc; - int reclaim_page; -{ - DB *dbp; - DBT data_dbt, key_dbt; - DB_LSN new_lsn, *n_lsn, tmp_lsn; - DB_MPOOLFILE *mpf; - HASH_CURSOR *hcp; - PAGE *n_pagep, *nn_pagep, *p, *p_pagep; - db_ham_mode op; - db_indx_t ndx; - db_pgno_t chg_pgno, pgno, tmp_pgno; - u_int32_t order; - int ret, t_ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - hcp = (HASH_CURSOR *)dbc->internal; - n_pagep = p_pagep = nn_pagep = NULL; - ndx = hcp->indx; - - if (hcp->page == NULL && (ret = __memp_fget( - mpf, &hcp->pgno, DB_MPOOL_CREATE, &hcp->page)) != 0) - return (ret); - p = hcp->page; - - /* - * We optimize for the normal case which is when neither the key nor - * the data are large. In this case, we write a single log record - * and do the delete. If either is large, we'll call __big_delete - * to remove the big item and then update the page to remove the - * entry referring to the big item. - */ - if (HPAGE_PTYPE(H_PAIRKEY(dbp, p, ndx)) == H_OFFPAGE) { - memcpy(&pgno, HOFFPAGE_PGNO(P_ENTRY(dbp, p, H_KEYINDEX(ndx))), - sizeof(db_pgno_t)); - ret = __db_doff(dbc, pgno); - } else - ret = 0; - - if (ret == 0) - switch (HPAGE_PTYPE(H_PAIRDATA(dbp, p, ndx))) { - case H_OFFPAGE: - memcpy(&pgno, - HOFFPAGE_PGNO(P_ENTRY(dbp, p, H_DATAINDEX(ndx))), - sizeof(db_pgno_t)); - ret = __db_doff(dbc, pgno); - break; - case H_OFFDUP: - case H_DUPLICATE: - /* - * If we delete a pair that is/was a duplicate, then - * we had better clear the flag so that we update the - * cursor appropriately. - */ - F_CLR(hcp, H_ISDUP); - break; - default: - /* No-op */ - break; - } - - if (ret) - return (ret); - - /* Now log the delete off this page. */ - if (DBC_LOGGING(dbc)) { - key_dbt.data = P_ENTRY(dbp, p, H_KEYINDEX(ndx)); - key_dbt.size = LEN_HITEM(dbp, p, dbp->pgsize, H_KEYINDEX(ndx)); - data_dbt.data = P_ENTRY(dbp, p, H_DATAINDEX(ndx)); - data_dbt.size = - LEN_HITEM(dbp, p, dbp->pgsize, H_DATAINDEX(ndx)); - - if ((ret = __ham_insdel_log(dbp, - dbc->txn, &new_lsn, 0, DELPAIR, PGNO(p), (u_int32_t)ndx, - &LSN(p), &key_dbt, &data_dbt)) != 0) - return (ret); - } else - LSN_NOT_LOGGED(new_lsn); - - /* Move lsn onto page. */ - LSN(p) = new_lsn; - - /* Do the delete. */ - __ham_dpair(dbp, p, ndx); - - /* - * Mark item deleted so that we don't try to return it, and - * so that we update the cursor correctly on the next call - * to next. - */ - F_SET(hcp, H_DELETED); - F_CLR(hcp, H_OK); - - /* - * Update cursors that are on the page where the delete happend. - */ - if ((ret = __ham_c_update(dbc, 0, 0, 0)) != 0) - return (ret); - - /* - * If we are locking, we will not maintain this, because it is - * a hot spot. - * - * XXX - * Perhaps we can retain incremental numbers and apply them later. - */ - if (!STD_LOCKING(dbc)) { - --hcp->hdr->nelem; - if ((ret = __ham_dirty_meta(dbc)) != 0) - return (ret); - } - - /* - * If we need to reclaim the page, then check if the page is empty. - * There are two cases. If it's empty and it's not the first page - * in the bucket (i.e., the bucket page) then we can simply remove - * it. If it is the first chain in the bucket, then we need to copy - * the second page into it and remove the second page. - * If its the only page in the bucket we leave it alone. - */ - if (!reclaim_page || - NUM_ENT(p) != 0 || - (PREV_PGNO(p) == PGNO_INVALID && NEXT_PGNO(p) == PGNO_INVALID)) - return (__memp_fset(mpf, p, DB_MPOOL_DIRTY)); - - if (PREV_PGNO(p) == PGNO_INVALID) { - /* - * First page in chain is empty and we know that there - * are more pages in the chain. - */ - if ((ret = __memp_fget(mpf, &NEXT_PGNO(p), 0, &n_pagep)) != 0) - return (ret); - - if (NEXT_PGNO(n_pagep) != PGNO_INVALID && (ret = - __memp_fget(mpf, &NEXT_PGNO(n_pagep), 0, &nn_pagep)) != 0) - goto err; - - if (DBC_LOGGING(dbc)) { - key_dbt.data = n_pagep; - key_dbt.size = dbp->pgsize; - if ((ret = __ham_copypage_log(dbp, - dbc->txn, &new_lsn, 0, PGNO(p), - &LSN(p), PGNO(n_pagep), &LSN(n_pagep), - NEXT_PGNO(n_pagep), - nn_pagep == NULL ? NULL : &LSN(nn_pagep), - &key_dbt)) != 0) - goto err; - } else - LSN_NOT_LOGGED(new_lsn); - - /* Move lsn onto page. */ - LSN(p) = new_lsn; /* Structure assignment. */ - LSN(n_pagep) = new_lsn; - if (NEXT_PGNO(n_pagep) != PGNO_INVALID) - LSN(nn_pagep) = new_lsn; - - if (nn_pagep != NULL) { - PREV_PGNO(nn_pagep) = PGNO(p); - if ((ret = - __memp_fput(mpf, nn_pagep, DB_MPOOL_DIRTY)) != 0) { - nn_pagep = NULL; - goto err; - } - } - - tmp_pgno = PGNO(p); - tmp_lsn = LSN(p); - memcpy(p, n_pagep, dbp->pgsize); - PGNO(p) = tmp_pgno; - LSN(p) = tmp_lsn; - PREV_PGNO(p) = PGNO_INVALID; - - /* - * Update cursors to reflect the fact that records - * on the second page have moved to the first page. - */ - if ((ret = __ham_c_delpg(dbc, PGNO(n_pagep), - PGNO(p), 0, DB_HAM_DELFIRSTPG, &order)) != 0) - goto err; - - /* - * Update the cursor to reflect its new position. - */ - hcp->indx = 0; - hcp->pgno = PGNO(p); - hcp->order += order; - - if ((ret = __memp_fset(mpf, p, DB_MPOOL_DIRTY)) != 0) - goto err; - if ((ret = __db_free(dbc, n_pagep)) != 0) { - n_pagep = NULL; - goto err; - } - } else { - if ((ret = __memp_fget(mpf, &PREV_PGNO(p), 0, &p_pagep)) != 0) - goto err; - - if (NEXT_PGNO(p) != PGNO_INVALID) { - if ((ret = - __memp_fget(mpf, &NEXT_PGNO(p), 0, &n_pagep)) != 0) - goto err; - n_lsn = &LSN(n_pagep); - } else { - n_pagep = NULL; - n_lsn = NULL; - } - - NEXT_PGNO(p_pagep) = NEXT_PGNO(p); - if (n_pagep != NULL) - PREV_PGNO(n_pagep) = PGNO(p_pagep); - - if (DBC_LOGGING(dbc)) { - if ((ret = __ham_newpage_log(dbp, dbc->txn, - &new_lsn, 0, DELOVFL, PREV_PGNO(p), &LSN(p_pagep), - PGNO(p), &LSN(p), NEXT_PGNO(p), n_lsn)) != 0) - goto err; - } else - LSN_NOT_LOGGED(new_lsn); - - /* Move lsn onto page. */ - LSN(p_pagep) = new_lsn; /* Structure assignment. */ - if (n_pagep) - LSN(n_pagep) = new_lsn; - LSN(p) = new_lsn; - - if (NEXT_PGNO(p) == PGNO_INVALID) { - /* - * There is no next page; put the cursor on the - * previous page as if we'd deleted the last item - * on that page, with index after the last valid - * entry. - * - * The deleted flag was set up above. - */ - hcp->pgno = PGNO(p_pagep); - hcp->indx = NUM_ENT(p_pagep); - op = DB_HAM_DELLASTPG; - } else { - /* - * There is a next page, so put the cursor at - * the beginning of it. - */ - hcp->pgno = NEXT_PGNO(p); - hcp->indx = 0; - op = DB_HAM_DELMIDPG; - } - - /* - * Since we are about to delete the cursor page and we have - * just moved the cursor, we need to make sure that the - * old page pointer isn't left hanging around in the cursor. - */ - hcp->page = NULL; - chg_pgno = PGNO(p); - ret = __db_free(dbc, p); - if ((t_ret = - __memp_fput(mpf, p_pagep, DB_MPOOL_DIRTY)) != 0 && ret == 0) - ret = t_ret; - if (n_pagep != NULL && (t_ret = - __memp_fput(mpf, n_pagep, DB_MPOOL_DIRTY)) != 0 && ret == 0) - ret = t_ret; - if (ret != 0) - return (ret); - if ((ret = __ham_c_delpg(dbc, - chg_pgno, hcp->pgno, hcp->indx, op, &order)) != 0) - return (ret); - hcp->order += order; - } - return (ret); - -err: /* Clean up any pages. */ - if (n_pagep != NULL) - (void)__memp_fput(mpf, n_pagep, 0); - if (nn_pagep != NULL) - (void)__memp_fput(mpf, nn_pagep, 0); - if (p_pagep != NULL) - (void)__memp_fput(mpf, p_pagep, 0); - return (ret); -} - -/* - * __ham_replpair -- - * Given the key data indicated by the cursor, replace part/all of it - * according to the fields in the dbt. - * - * PUBLIC: int __ham_replpair __P((DBC *, DBT *, u_int32_t)); - */ -int -__ham_replpair(dbc, dbt, make_dup) - DBC *dbc; - DBT *dbt; - u_int32_t make_dup; -{ - DB *dbp; - DBT old_dbt, tdata, tmp; - DB_ENV *dbenv; - DB_LSN new_lsn; - HASH_CURSOR *hcp; - u_int32_t change; - u_int32_t dup_flag, len, memsize, newlen; - int beyond_eor, is_big, is_plus, ret, type; - u_int8_t *beg, *dest, *end, *hk, *src; - void *memp; - - /* - * Items that were already offpage (ISBIG) were handled before - * we get in here. So, we need only handle cases where the old - * key is on a regular page. That leaves us 6 cases: - * 1. Original data onpage; new data is smaller - * 2. Original data onpage; new data is the same size - * 3. Original data onpage; new data is bigger, but not ISBIG, - * fits on page - * 4. Original data onpage; new data is bigger, but not ISBIG, - * does not fit on page - * 5. Original data onpage; New data is an off-page item. - * 6. Original data was offpage; new item is smaller. - * - * Cases 1-3 are essentially the same (and should be the common case). - * We handle 4-6 as delete and add. - */ - dbp = dbc->dbp; - dbenv = dbp->dbenv; - hcp = (HASH_CURSOR *)dbc->internal; - - /* - * We need to compute the number of bytes that we are adding or - * removing from the entry. Normally, we can simply substract - * the number of bytes we are replacing (dbt->dlen) from the - * number of bytes we are inserting (dbt->size). However, if - * we are doing a partial put off the end of a record, then this - * formula doesn't work, because we are essentially adding - * new bytes. - */ - if (dbt->size > dbt->dlen) { - change = dbt->size - dbt->dlen; - is_plus = 1; - } else { - change = dbt->dlen - dbt->size; - is_plus = 0; - } - - hk = H_PAIRDATA(dbp, hcp->page, hcp->indx); - is_big = HPAGE_PTYPE(hk) == H_OFFPAGE; - - if (is_big) - memcpy(&len, HOFFPAGE_TLEN(hk), sizeof(u_int32_t)); - else - len = LEN_HKEYDATA(dbp, hcp->page, - dbp->pgsize, H_DATAINDEX(hcp->indx)); - - beyond_eor = dbt->doff + dbt->dlen > len; - if (beyond_eor) { - /* - * The change is beyond the end of record. If change - * is a positive number, we can simply add the extension - * to it. However, if change is negative, then we need - * to figure out if the extension is larger than the - * negative change. - */ - if (is_plus) - change += dbt->doff + dbt->dlen - len; - else if (dbt->doff + dbt->dlen - len > change) { - /* Extension bigger than change */ - is_plus = 1; - change = (dbt->doff + dbt->dlen - len) - change; - } else /* Extension is smaller than change. */ - change -= (dbt->doff + dbt->dlen - len); - } - - newlen = (is_plus ? len + change : len - change); - if (ISBIG(hcp, newlen) || - (is_plus && change > P_FREESPACE(dbp, hcp->page)) || - beyond_eor || is_big) { - /* - * If we are in cases 4 or 5 then is_plus will be true. - * If we don't have a transaction then we cannot roll back, - * make sure there is enough room for the new page. - */ - if (is_plus && dbc->txn == NULL && - dbp->mpf->mfp->maxpgno != 0 && - dbp->mpf->mfp->maxpgno == dbp->mpf->mfp->last_pgno) - return (__db_space_err(dbp)); - /* - * Cases 4-6 -- two subcases. - * A. This is not really a partial operation, but an overwrite. - * Simple del and add works. - * B. This is a partial and we need to construct the data that - * we are really inserting (yuck). - * In both cases, we need to grab the key off the page (in - * some cases we could do this outside of this routine; for - * cleanliness we do it here. If you happen to be on a big - * key, this could be a performance hit). - */ - memset(&tmp, 0, sizeof(tmp)); - if ((ret = - __db_ret(dbp, hcp->page, H_KEYINDEX(hcp->indx), - &tmp, &dbc->my_rkey.data, &dbc->my_rkey.ulen)) != 0) - return (ret); - - /* Preserve duplicate info. */ - dup_flag = F_ISSET(hcp, H_ISDUP); - if (dbt->doff == 0 && dbt->dlen == len) { - ret = __ham_del_pair(dbc, 0); - if (ret == 0) - ret = __ham_add_el(dbc, - &tmp, dbt, dup_flag ? H_DUPLICATE : H_KEYDATA); - } else { /* Case B */ - type = HPAGE_PTYPE(hk) != H_OFFPAGE ? - HPAGE_PTYPE(hk) : H_KEYDATA; - memset(&tdata, 0, sizeof(tdata)); - memp = NULL; - memsize = 0; - if ((ret = __db_ret(dbp, hcp->page, - H_DATAINDEX(hcp->indx), &tdata, &memp, &memsize)) - != 0) - goto err; - - /* Now we can delete the item. */ - if ((ret = __ham_del_pair(dbc, 0)) != 0) { - __os_free(dbenv, memp); - goto err; - } - - /* Now shift old data around to make room for new. */ - if (is_plus) { - if ((ret = __os_realloc(dbenv, - tdata.size + change, &tdata.data)) != 0) - return (ret); - memp = tdata.data; - memsize = tdata.size + change; - memset((u_int8_t *)tdata.data + tdata.size, - 0, change); - } - end = (u_int8_t *)tdata.data + tdata.size; - - src = (u_int8_t *)tdata.data + dbt->doff + dbt->dlen; - if (src < end && tdata.size > dbt->doff + dbt->dlen) { - len = tdata.size - (dbt->doff + dbt->dlen); - if (is_plus) - dest = src + change; - else - dest = src - change; - memmove(dest, src, len); - } - memcpy((u_int8_t *)tdata.data + dbt->doff, - dbt->data, dbt->size); - if (is_plus) - tdata.size += change; - else - tdata.size -= change; - - /* Now add the pair. */ - ret = __ham_add_el(dbc, &tmp, &tdata, type); - __os_free(dbenv, memp); - } - F_SET(hcp, dup_flag); -err: return (ret); - } - - /* - * Set up pointer into existing data. Do it before the log - * message so we can use it inside of the log setup. - */ - beg = HKEYDATA_DATA(H_PAIRDATA(dbp, hcp->page, hcp->indx)); - beg += dbt->doff; - - /* - * If we are going to have to move bytes at all, figure out - * all the parameters here. Then log the call before moving - * anything around. - */ - if (DBC_LOGGING(dbc)) { - old_dbt.data = beg; - old_dbt.size = dbt->dlen; - if ((ret = __ham_replace_log(dbp, - dbc->txn, &new_lsn, 0, PGNO(hcp->page), - (u_int32_t)H_DATAINDEX(hcp->indx), &LSN(hcp->page), - (int32_t)dbt->doff, &old_dbt, dbt, make_dup)) != 0) - return (ret); - - } else - LSN_NOT_LOGGED(new_lsn); - - LSN(hcp->page) = new_lsn; /* Structure assignment. */ - - __ham_onpage_replace(dbp, hcp->page, (u_int32_t)H_DATAINDEX(hcp->indx), - (int32_t)dbt->doff, change, is_plus, dbt); - - return (0); -} - -/* - * Replace data on a page with new data, possibly growing or shrinking what's - * there. This is called on two different occasions. On one (from replpair) - * we are interested in changing only the data. On the other (from recovery) - * we are replacing the entire data (header and all) with a new element. In - * the latter case, the off argument is negative. - * pagep: the page that we're changing - * ndx: page index of the element that is growing/shrinking. - * off: Offset at which we are beginning the replacement. - * change: the number of bytes (+ or -) that the element is growing/shrinking. - * dbt: the new data that gets written at beg. - * - * PUBLIC: void __ham_onpage_replace __P((DB *, PAGE *, u_int32_t, - * PUBLIC: int32_t, u_int32_t, int, DBT *)); - */ -void -__ham_onpage_replace(dbp, pagep, ndx, off, change, is_plus, dbt) - DB *dbp; - PAGE *pagep; - u_int32_t ndx; - int32_t off; - u_int32_t change; - int is_plus; - DBT *dbt; -{ - db_indx_t i, *inp; - int32_t len; - size_t pgsize; - u_int8_t *src, *dest; - int zero_me; - - pgsize = dbp->pgsize; - inp = P_INP(dbp, pagep); - if (change != 0) { - zero_me = 0; - src = (u_int8_t *)(pagep) + HOFFSET(pagep); - if (off < 0) - len = inp[ndx] - HOFFSET(pagep); - else if ((u_int32_t)off >= - LEN_HKEYDATA(dbp, pagep, pgsize, ndx)) { - len = (int32_t)(HKEYDATA_DATA(P_ENTRY(dbp, pagep, ndx)) - + LEN_HKEYDATA(dbp, pagep, pgsize, ndx) - src); - zero_me = 1; - } else - len = (int32_t)( - (HKEYDATA_DATA(P_ENTRY(dbp, pagep, ndx)) + off) - - src); - if (is_plus) - dest = src - change; - else - dest = src + change; - memmove(dest, src, (size_t)len); - if (zero_me) - memset(dest + len, 0, change); - - /* Now update the indices. */ - for (i = ndx; i < NUM_ENT(pagep); i++) { - if (is_plus) - inp[i] -= change; - else - inp[i] += change; - } - if (is_plus) - HOFFSET(pagep) -= change; - else - HOFFSET(pagep) += change; - } - if (off >= 0) - memcpy(HKEYDATA_DATA(P_ENTRY(dbp, pagep, ndx)) + off, - dbt->data, dbt->size); - else - memcpy(P_ENTRY(dbp, pagep, ndx), dbt->data, dbt->size); -} - -/* - * PUBLIC: int __ham_split_page __P((DBC *, u_int32_t, u_int32_t)); - */ -int -__ham_split_page(dbc, obucket, nbucket) - DBC *dbc; - u_int32_t obucket, nbucket; -{ - DB *dbp; - DBC **carray; - DBT key, page_dbt; - DB_ENV *dbenv; - DB_LOCK block; - DB_LSN new_lsn; - DB_MPOOLFILE *mpf; - HASH_CURSOR *hcp, *cp; - PAGE **pp, *old_pagep, *temp_pagep, *new_pagep; - db_indx_t n; - db_pgno_t bucket_pgno, npgno, next_pgno; - u_int32_t big_len, len; - int found, i, ret, t_ret; - void *big_buf; - - dbp = dbc->dbp; - carray = NULL; - dbenv = dbp->dbenv; - mpf = dbp->mpf; - hcp = (HASH_CURSOR *)dbc->internal; - temp_pagep = old_pagep = new_pagep = NULL; - npgno = PGNO_INVALID; - LOCK_INIT(block); - - bucket_pgno = BUCKET_TO_PAGE(hcp, obucket); - if ((ret = __db_lget(dbc, - 0, bucket_pgno, DB_LOCK_WRITE, 0, &block)) != 0) - goto err; - if ((ret = __memp_fget(mpf, - &bucket_pgno, DB_MPOOL_CREATE, &old_pagep)) != 0) - goto err; - - /* Properly initialize the new bucket page. */ - npgno = BUCKET_TO_PAGE(hcp, nbucket); - if ((ret = __memp_fget(mpf, &npgno, DB_MPOOL_CREATE, &new_pagep)) != 0) - goto err; - P_INIT(new_pagep, - dbp->pgsize, npgno, PGNO_INVALID, PGNO_INVALID, 0, P_HASH); - - temp_pagep = hcp->split_buf; - memcpy(temp_pagep, old_pagep, dbp->pgsize); - - if (DBC_LOGGING(dbc)) { - page_dbt.size = dbp->pgsize; - page_dbt.data = old_pagep; - if ((ret = __ham_splitdata_log(dbp, - dbc->txn, &new_lsn, 0, SPLITOLD, - PGNO(old_pagep), &page_dbt, &LSN(old_pagep))) != 0) - goto err; - } else - LSN_NOT_LOGGED(new_lsn); - - LSN(old_pagep) = new_lsn; /* Structure assignment. */ - - P_INIT(old_pagep, dbp->pgsize, PGNO(old_pagep), PGNO_INVALID, - PGNO_INVALID, 0, P_HASH); - - big_len = 0; - big_buf = NULL; - key.flags = 0; - while (temp_pagep != NULL) { - if ((ret = __ham_get_clist(dbp, - PGNO(temp_pagep), NDX_INVALID, &carray)) != 0) - goto err; - - for (n = 0; n < (db_indx_t)NUM_ENT(temp_pagep); n += 2) { - if ((ret = __db_ret(dbp, temp_pagep, - H_KEYINDEX(n), &key, &big_buf, &big_len)) != 0) - goto err; - - if (__ham_call_hash(dbc, key.data, key.size) == obucket) - pp = &old_pagep; - else - pp = &new_pagep; - - /* - * Figure out how many bytes we need on the new - * page to store the key/data pair. - */ - len = LEN_HITEM(dbp, temp_pagep, dbp->pgsize, - H_DATAINDEX(n)) + - LEN_HITEM(dbp, temp_pagep, dbp->pgsize, - H_KEYINDEX(n)) + - 2 * sizeof(db_indx_t); - - if (P_FREESPACE(dbp, *pp) < len) { - if (DBC_LOGGING(dbc)) { - page_dbt.size = dbp->pgsize; - page_dbt.data = *pp; - if ((ret = __ham_splitdata_log(dbp, - dbc->txn, &new_lsn, 0, - SPLITNEW, PGNO(*pp), &page_dbt, - &LSN(*pp))) != 0) - goto err; - } else - LSN_NOT_LOGGED(new_lsn); - LSN(*pp) = new_lsn; - if ((ret = - __ham_add_ovflpage(dbc, *pp, 1, pp)) != 0) - goto err; - } - - /* Check if we need to update a cursor. */ - if (carray != NULL) { - found = 0; - for (i = 0; carray[i] != NULL; i++) { - cp = - (HASH_CURSOR *)carray[i]->internal; - if (cp->pgno == PGNO(temp_pagep) && - cp->indx == n) { - cp->pgno = PGNO(*pp); - cp->indx = NUM_ENT(*pp); - found = 1; - } - } - if (found && DBC_LOGGING(dbc) && - IS_SUBTRANSACTION(dbc->txn)) { - if ((ret = - __ham_chgpg_log(dbp, - dbc->txn, &new_lsn, 0, - DB_HAM_SPLIT, PGNO(temp_pagep), - PGNO(*pp), n, NUM_ENT(*pp))) != 0) - goto err; - } - } - __ham_copy_item(dbp, temp_pagep, H_KEYINDEX(n), *pp); - __ham_copy_item(dbp, temp_pagep, H_DATAINDEX(n), *pp); - } - next_pgno = NEXT_PGNO(temp_pagep); - - /* Clear temp_page; if it's a link overflow page, free it. */ - if (PGNO(temp_pagep) != bucket_pgno && (ret = - __db_free(dbc, temp_pagep)) != 0) { - temp_pagep = NULL; - goto err; - } - - if (next_pgno == PGNO_INVALID) - temp_pagep = NULL; - else if ((ret = __memp_fget( - mpf, &next_pgno, DB_MPOOL_CREATE, &temp_pagep)) != 0) - goto err; - - if (temp_pagep != NULL) { - if (DBC_LOGGING(dbc)) { - page_dbt.size = dbp->pgsize; - page_dbt.data = temp_pagep; - if ((ret = __ham_splitdata_log(dbp, - dbc->txn, &new_lsn, 0, - SPLITOLD, PGNO(temp_pagep), - &page_dbt, &LSN(temp_pagep))) != 0) - goto err; - } else - LSN_NOT_LOGGED(new_lsn); - LSN(temp_pagep) = new_lsn; - } - - if (carray != NULL) /* We never knew its size. */ - __os_free(dbenv, carray); - carray = NULL; - } - if (big_buf != NULL) - __os_free(dbenv, big_buf); - - /* - * If the original bucket spanned multiple pages, then we've got - * a pointer to a page that used to be on the bucket chain. It - * should be deleted. - */ - if (temp_pagep != NULL && PGNO(temp_pagep) != bucket_pgno && - (ret = __db_free(dbc, temp_pagep)) != 0) { - temp_pagep = NULL; - goto err; - } - - /* - * Write new buckets out. - */ - if (DBC_LOGGING(dbc)) { - page_dbt.size = dbp->pgsize; - page_dbt.data = old_pagep; - if ((ret = __ham_splitdata_log(dbp, dbc->txn, - &new_lsn, 0, SPLITNEW, PGNO(old_pagep), &page_dbt, - &LSN(old_pagep))) != 0) - goto err; - LSN(old_pagep) = new_lsn; - - page_dbt.data = new_pagep; - if ((ret = __ham_splitdata_log(dbp, dbc->txn, &new_lsn, 0, - SPLITNEW, PGNO(new_pagep), &page_dbt, - &LSN(new_pagep))) != 0) - goto err; - LSN(new_pagep) = new_lsn; - } else { - LSN_NOT_LOGGED(LSN(old_pagep)); - LSN_NOT_LOGGED(LSN(new_pagep)); - } - - ret = __memp_fput(mpf, old_pagep, DB_MPOOL_DIRTY); - if ((t_ret = - __memp_fput(mpf, new_pagep, DB_MPOOL_DIRTY)) != 0 && ret == 0) - ret = t_ret; - - if (0) { -err: if (old_pagep != NULL) - (void)__memp_fput(mpf, old_pagep, DB_MPOOL_DIRTY); - if (new_pagep != NULL) { - P_INIT(new_pagep, dbp->pgsize, - npgno, PGNO_INVALID, PGNO_INVALID, 0, P_HASH); - (void)__memp_fput(mpf, new_pagep, DB_MPOOL_DIRTY); - } - if (temp_pagep != NULL && PGNO(temp_pagep) != bucket_pgno) - (void)__memp_fput(mpf, temp_pagep, DB_MPOOL_DIRTY); - } - if ((t_ret = __TLPUT(dbc, block)) != 0 && ret == 0) - ret = t_ret; - if (carray != NULL) /* We never knew its size. */ - __os_free(dbenv, carray); - return (ret); -} - -/* - * Add the given pair to the page. The page in question may already be - * held (i.e. it was already gotten). If it is, then the page is passed - * in via the pagep parameter. On return, pagep will contain the page - * to which we just added something. This allows us to link overflow - * pages and return the new page having correctly put the last page. - * - * PUBLIC: int __ham_add_el __P((DBC *, const DBT *, const DBT *, int)); - */ -int -__ham_add_el(dbc, key, val, type) - DBC *dbc; - const DBT *key, *val; - int type; -{ - const DBT *pkey, *pdata; - DB *dbp; - DBT key_dbt, data_dbt; - DB_LSN new_lsn; - DB_MPOOLFILE *mpf; - HASH_CURSOR *hcp; - HOFFPAGE doff, koff; - db_pgno_t next_pgno, pgno; - u_int32_t data_size, key_size; - u_int32_t pages, pagespace, pairsize, rectype; - int do_expand, is_keybig, is_databig, ret; - int key_type, data_type; - - dbp = dbc->dbp; - mpf = dbp->mpf; - hcp = (HASH_CURSOR *)dbc->internal; - do_expand = 0; - - pgno = hcp->seek_found_page != PGNO_INVALID ? - hcp->seek_found_page : hcp->pgno; - if (hcp->page == NULL && - (ret = __memp_fget(mpf, &pgno, DB_MPOOL_CREATE, &hcp->page)) != 0) - return (ret); - - key_size = HKEYDATA_PSIZE(key->size); - data_size = HKEYDATA_PSIZE(val->size); - is_keybig = ISBIG(hcp, key->size); - is_databig = ISBIG(hcp, val->size); - if (is_keybig) - key_size = HOFFPAGE_PSIZE; - if (is_databig) - data_size = HOFFPAGE_PSIZE; - - pairsize = key_size + data_size; - - /* Advance to first page in chain with room for item. */ - while (H_NUMPAIRS(hcp->page) && NEXT_PGNO(hcp->page) != PGNO_INVALID) { - /* - * This may not be the end of the chain, but the pair may fit - * anyway. Check if it's a bigpair that fits or a regular - * pair that fits. - */ - if (P_FREESPACE(dbp, hcp->page) >= pairsize) - break; - next_pgno = NEXT_PGNO(hcp->page); - if ((ret = __ham_next_cpage(dbc, next_pgno, 0)) != 0) - return (ret); - } - - /* - * Check if we need to allocate a new page. - */ - if (P_FREESPACE(dbp, hcp->page) < pairsize) { - do_expand = 1; - if ((ret = __ham_add_ovflpage(dbc, - (PAGE *)hcp->page, 1, (PAGE **)&hcp->page)) != 0) - return (ret); - hcp->pgno = PGNO(hcp->page); - } - - /* - * If we don't have a transaction then make sure we will not - * run out of file space before updating the key or data. - */ - if (dbc->txn == NULL && - dbp->mpf->mfp->maxpgno != 0 && (is_keybig || is_databig)) { - pagespace = P_MAXSPACE(dbp, dbp->pgsize); - pages = 0; - if (is_databig) - pages = ((data_size - 1) / pagespace) + 1; - if (is_keybig) { - pages += ((key->size - 1) / pagespace) + 1; - if (pages > - (dbp->mpf->mfp->maxpgno - dbp->mpf->mfp->last_pgno)) - return (__db_space_err(dbp)); - } - } - - /* - * Update cursor. - */ - hcp->indx = NUM_ENT(hcp->page); - F_CLR(hcp, H_DELETED); - if (is_keybig) { - koff.type = H_OFFPAGE; - UMRW_SET(koff.unused[0]); - UMRW_SET(koff.unused[1]); - UMRW_SET(koff.unused[2]); - if ((ret = __db_poff(dbc, key, &koff.pgno)) != 0) - return (ret); - koff.tlen = key->size; - key_dbt.data = &koff; - key_dbt.size = sizeof(koff); - pkey = &key_dbt; - key_type = H_OFFPAGE; - } else { - pkey = key; - key_type = H_KEYDATA; - } - - if (is_databig) { - doff.type = H_OFFPAGE; - UMRW_SET(doff.unused[0]); - UMRW_SET(doff.unused[1]); - UMRW_SET(doff.unused[2]); - if ((ret = __db_poff(dbc, val, &doff.pgno)) != 0) - return (ret); - doff.tlen = val->size; - data_dbt.data = &doff; - data_dbt.size = sizeof(doff); - pdata = &data_dbt; - data_type = H_OFFPAGE; - } else { - pdata = val; - data_type = type; - } - - if (DBC_LOGGING(dbc)) { - rectype = PUTPAIR; - if (is_databig) - rectype |= PAIR_DATAMASK; - if (is_keybig) - rectype |= PAIR_KEYMASK; - if (type == H_DUPLICATE) - rectype |= PAIR_DUPMASK; - - if ((ret = __ham_insdel_log(dbp, dbc->txn, &new_lsn, 0, - rectype, PGNO(hcp->page), (u_int32_t)NUM_ENT(hcp->page), - &LSN(hcp->page), pkey, pdata)) != 0) - return (ret); - } else - LSN_NOT_LOGGED(new_lsn); - - /* Move lsn onto page. */ - LSN(hcp->page) = new_lsn; /* Structure assignment. */ - - __ham_putitem(dbp, hcp->page, pkey, key_type); - __ham_putitem(dbp, hcp->page, pdata, data_type); - - /* - * For splits, we are going to update item_info's page number - * field, so that we can easily return to the same page the - * next time we come in here. For other operations, this shouldn't - * matter, since odds are this is the last thing that happens before - * we return to the user program. - */ - hcp->pgno = PGNO(hcp->page); - - /* - * XXX - * Maybe keep incremental numbers here. - */ - if (!STD_LOCKING(dbc)) { - hcp->hdr->nelem++; - if ((ret = __ham_dirty_meta(dbc)) != 0) - return (ret); - } - - if (do_expand || (hcp->hdr->ffactor != 0 && - (u_int32_t)H_NUMPAIRS(hcp->page) > hcp->hdr->ffactor)) - F_SET(hcp, H_EXPAND); - return (0); -} - -/* - * Special __putitem call used in splitting -- copies one entry to - * another. Works for all types of hash entries (H_OFFPAGE, H_KEYDATA, - * H_DUPLICATE, H_OFFDUP). Since we log splits at a high level, we - * do not need to do any logging here. - * - * PUBLIC: void __ham_copy_item __P((DB *, PAGE *, u_int32_t, PAGE *)); - */ -void -__ham_copy_item(dbp, src_page, src_ndx, dest_page) - DB *dbp; - PAGE *src_page; - u_int32_t src_ndx; - PAGE *dest_page; -{ - u_int32_t len; - size_t pgsize; - void *src, *dest; - db_indx_t *inp; - - pgsize = dbp->pgsize; - inp = P_INP(dbp, dest_page); - /* - * Copy the key and data entries onto this new page. - */ - src = P_ENTRY(dbp, src_page, src_ndx); - - /* Set up space on dest. */ - len = (u_int32_t)LEN_HITEM(dbp, src_page, pgsize, src_ndx); - HOFFSET(dest_page) -= len; - inp[NUM_ENT(dest_page)] = HOFFSET(dest_page); - dest = P_ENTRY(dbp, dest_page, NUM_ENT(dest_page)); - NUM_ENT(dest_page)++; - - memcpy(dest, src, len); -} - -/* - * - * Returns: - * 0 on success -- pp points to new page. - * errno on error -- pp not valid. - * - * PUBLIC: int __ham_add_ovflpage __P((DBC *, PAGE *, int, PAGE **)); - */ -int -__ham_add_ovflpage(dbc, pagep, release, pp) - DBC *dbc; - PAGE *pagep; - int release; - PAGE **pp; -{ - DB *dbp; - DB_LSN new_lsn; - DB_MPOOLFILE *mpf; - PAGE *new_pagep; - int ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - - if ((ret = __db_new(dbc, P_HASH, &new_pagep)) != 0) - return (ret); - - if (DBC_LOGGING(dbc)) { - if ((ret = __ham_newpage_log(dbp, dbc->txn, &new_lsn, 0, - PUTOVFL, PGNO(pagep), &LSN(pagep), PGNO(new_pagep), - &LSN(new_pagep), PGNO_INVALID, NULL)) != 0) { - (void)__memp_fput(mpf, pagep, DB_MPOOL_DIRTY); - return (ret); - } - } else - LSN_NOT_LOGGED(new_lsn); - - /* Move lsn onto page. */ - LSN(pagep) = LSN(new_pagep) = new_lsn; - NEXT_PGNO(pagep) = PGNO(new_pagep); - - PREV_PGNO(new_pagep) = PGNO(pagep); - - if (release) - ret = __memp_fput(mpf, pagep, DB_MPOOL_DIRTY); - - *pp = new_pagep; - return (ret); -} - -/* - * PUBLIC: int __ham_get_cpage __P((DBC *, db_lockmode_t)); - */ -int -__ham_get_cpage(dbc, mode) - DBC *dbc; - db_lockmode_t mode; -{ - DB *dbp; - DB_LOCK tmp_lock; - DB_MPOOLFILE *mpf; - HASH_CURSOR *hcp; - int ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - hcp = (HASH_CURSOR *)dbc->internal; - ret = 0; - - /* - * There are four cases with respect to buckets and locks. - * 1. If there is no lock held, then if we are locking, we should - * get the lock. - * 2. If there is a lock held, it's for the current bucket, and it's - * for the right mode, we don't need to do anything. - * 3. If there is a lock held for the current bucket but it's not - * strong enough, we need to upgrade. - * 4. If there is a lock, but it's for a different bucket, then we need - * to release the existing lock and get a new lock. - */ - LOCK_INIT(tmp_lock); - if (STD_LOCKING(dbc)) { - if (hcp->lbucket != hcp->bucket) { /* Case 4 */ - if ((ret = __TLPUT(dbc, hcp->lock)) != 0) - return (ret); - LOCK_INIT(hcp->lock); - } - - /* - * See if we have the right lock. If we are doing - * dirty reads we assume the write lock has been downgraded. - */ - if ((LOCK_ISSET(hcp->lock) && - ((hcp->lock_mode == DB_LOCK_READ || - F_ISSET(dbp, DB_AM_READ_UNCOMMITTED)) && - mode == DB_LOCK_WRITE))) { - /* Case 3. */ - tmp_lock = hcp->lock; - LOCK_INIT(hcp->lock); - } - - /* Acquire the lock. */ - if (!LOCK_ISSET(hcp->lock)) - /* Cases 1, 3, and 4. */ - if ((ret = __ham_lock_bucket(dbc, mode)) != 0) - return (ret); - - if (ret == 0) { - hcp->lock_mode = mode; - hcp->lbucket = hcp->bucket; - /* Case 3: release the original lock. */ - if ((ret = __ENV_LPUT(dbp->dbenv, tmp_lock)) != 0) - return (ret); - } else if (LOCK_ISSET(tmp_lock)) - hcp->lock = tmp_lock; - } - - if (ret == 0 && hcp->page == NULL) { - if (hcp->pgno == PGNO_INVALID) - hcp->pgno = BUCKET_TO_PAGE(hcp, hcp->bucket); - if ((ret = __memp_fget(mpf, - &hcp->pgno, DB_MPOOL_CREATE, &hcp->page)) != 0) - return (ret); - } - - return (0); -} - -/* - * Get a new page at the cursor, putting the last page if necessary. - * If the flag is set to H_ISDUP, then we are talking about the - * duplicate page, not the main page. - * - * PUBLIC: int __ham_next_cpage __P((DBC *, db_pgno_t, int)); - */ -int -__ham_next_cpage(dbc, pgno, dirty) - DBC *dbc; - db_pgno_t pgno; - int dirty; -{ - DB *dbp; - DB_MPOOLFILE *mpf; - HASH_CURSOR *hcp; - PAGE *p; - int ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - hcp = (HASH_CURSOR *)dbc->internal; - - if (hcp->page != NULL && (ret = - __memp_fput(mpf, hcp->page, dirty ? DB_MPOOL_DIRTY : 0)) != 0) - return (ret); - hcp->page = NULL; - - if ((ret = __memp_fget(mpf, &pgno, DB_MPOOL_CREATE, &p)) != 0) - return (ret); - - hcp->page = p; - hcp->pgno = pgno; - hcp->indx = 0; - - return (0); -} - -/* - * __ham_lock_bucket -- - * Get the lock on a particular bucket. - * - * PUBLIC: int __ham_lock_bucket __P((DBC *, db_lockmode_t)); - */ -int -__ham_lock_bucket(dbc, mode) - DBC *dbc; - db_lockmode_t mode; -{ - HASH_CURSOR *hcp; - db_pgno_t pgno; - int gotmeta, ret; - - hcp = (HASH_CURSOR *)dbc->internal; - gotmeta = hcp->hdr == NULL ? 1 : 0; - if (gotmeta) - if ((ret = __ham_get_meta(dbc)) != 0) - return (ret); - pgno = BUCKET_TO_PAGE(hcp, hcp->bucket); - if (gotmeta) - if ((ret = __ham_release_meta(dbc)) != 0) - return (ret); - - ret = __db_lget(dbc, 0, pgno, mode, 0, &hcp->lock); - - hcp->lock_mode = mode; - return (ret); -} - -/* - * __ham_dpair -- - * Delete a pair on a page, paying no attention to what the pair - * represents. The caller is responsible for freeing up duplicates - * or offpage entries that might be referenced by this pair. - * - * Recovery assumes that this may be called without the metadata - * page pinned. - * - * PUBLIC: void __ham_dpair __P((DB *, PAGE *, u_int32_t)); - */ -void -__ham_dpair(dbp, p, indx) - DB *dbp; - PAGE *p; - u_int32_t indx; -{ - db_indx_t delta, n, *inp; - u_int8_t *dest, *src; - - inp = P_INP(dbp, p); - /* - * Compute "delta", the amount we have to shift all of the - * offsets. To find the delta, we just need to calculate - * the size of the pair of elements we are removing. - */ - delta = H_PAIRSIZE(dbp, p, dbp->pgsize, indx); - - /* - * The hard case: we want to remove something other than - * the last item on the page. We need to shift data and - * offsets down. - */ - if ((db_indx_t)indx != NUM_ENT(p) - 2) { - /* - * Move the data: src is the first occupied byte on - * the page. (Length is delta.) - */ - src = (u_int8_t *)p + HOFFSET(p); - - /* - * Destination is delta bytes beyond src. This might - * be an overlapping copy, so we have to use memmove. - */ - dest = src + delta; - memmove(dest, src, inp[H_DATAINDEX(indx)] - HOFFSET(p)); - } - - /* Adjust page metadata. */ - HOFFSET(p) = HOFFSET(p) + delta; - NUM_ENT(p) = NUM_ENT(p) - 2; - - /* Adjust the offsets. */ - for (n = (db_indx_t)indx; n < (db_indx_t)(NUM_ENT(p)); n++) - inp[n] = inp[n + 2] + delta; - -} - -/* - * __ham_c_delpg -- - * - * Adjust the cursors after we've emptied a page in a bucket, taking - * care that when we move cursors pointing to deleted items, their - * orders don't collide with the orders of cursors on the page we move - * them to (since after this function is called, cursors with the same - * index on the two pages will be otherwise indistinguishable--they'll - * all have pgno new_pgno). There are three cases: - * - * 1) The emptied page is the first page in the bucket. In this - * case, we've copied all the items from the second page into the - * first page, so the first page is new_pgno and the second page is - * old_pgno. new_pgno is empty, but can have deleted cursors - * pointing at indx 0, so we need to be careful of the orders - * there. This is DB_HAM_DELFIRSTPG. - * - * 2) The page is somewhere in the middle of a bucket. Our caller - * can just delete such a page, so it's old_pgno. old_pgno is - * empty, but may have deleted cursors pointing at indx 0, so we - * need to be careful of indx 0 when we move those cursors to - * new_pgno. This is DB_HAM_DELMIDPG. - * - * 3) The page is the last in a bucket. Again the empty page is - * old_pgno, and again it should only have cursors that are deleted - * and at indx == 0. This time, though, there's no next page to - * move them to, so we set them to indx == num_ent on the previous - * page--and indx == num_ent is the index whose cursors we need to - * be careful of. This is DB_HAM_DELLASTPG. - */ -static int -__ham_c_delpg(dbc, old_pgno, new_pgno, num_ent, op, orderp) - DBC *dbc; - db_pgno_t old_pgno, new_pgno; - u_int32_t num_ent; - db_ham_mode op; - u_int32_t *orderp; -{ - DB *dbp, *ldbp; - DB_ENV *dbenv; - DB_LSN lsn; - DB_TXN *my_txn; - DBC *cp; - HASH_CURSOR *hcp; - int found, ret; - db_indx_t indx; - u_int32_t order; - - /* Which is the worrisome index? */ - indx = (op == DB_HAM_DELLASTPG) ? num_ent : 0; - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - - my_txn = IS_SUBTRANSACTION(dbc->txn) ? dbc->txn : NULL; - found = 0; - - MUTEX_LOCK(dbenv, dbenv->mtx_dblist); - /* - * Find the highest order of any cursor our movement - * may collide with. - */ - order = 1; - for (ldbp = __dblist_get(dbenv, dbp->adj_fileid); - ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid; - ldbp = LIST_NEXT(ldbp, dblistlinks)) { - MUTEX_LOCK(dbenv, dbp->mutex); - for (cp = TAILQ_FIRST(&ldbp->active_queue); cp != NULL; - cp = TAILQ_NEXT(cp, links)) { - if (cp == dbc || cp->dbtype != DB_HASH) - continue; - hcp = (HASH_CURSOR *)cp->internal; - if (hcp->pgno == new_pgno) { - if (hcp->indx == indx && - F_ISSET(hcp, H_DELETED) && - hcp->order >= order) - order = hcp->order + 1; - DB_ASSERT(op != DB_HAM_DELFIRSTPG || - hcp->indx == NDX_INVALID || - (hcp->indx == 0 && - F_ISSET(hcp, H_DELETED))); - } - } - MUTEX_UNLOCK(dbenv, dbp->mutex); - } - - for (ldbp = __dblist_get(dbenv, dbp->adj_fileid); - ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid; - ldbp = LIST_NEXT(ldbp, dblistlinks)) { - MUTEX_LOCK(dbenv, dbp->mutex); - for (cp = TAILQ_FIRST(&ldbp->active_queue); cp != NULL; - cp = TAILQ_NEXT(cp, links)) { - if (cp == dbc || cp->dbtype != DB_HASH) - continue; - - hcp = (HASH_CURSOR *)cp->internal; - - if (hcp->pgno == old_pgno) { - switch (op) { - case DB_HAM_DELFIRSTPG: - /* - * We're moving all items, - * regardless of index. - */ - hcp->pgno = new_pgno; - - /* - * But we have to be careful of - * the order values. - */ - if (hcp->indx == indx) - hcp->order += order; - break; - case DB_HAM_DELMIDPG: - hcp->pgno = new_pgno; - DB_ASSERT(hcp->indx == 0 && - F_ISSET(hcp, H_DELETED)); - hcp->order += order; - break; - case DB_HAM_DELLASTPG: - hcp->pgno = new_pgno; - DB_ASSERT(hcp->indx == 0 && - F_ISSET(hcp, H_DELETED)); - hcp->indx = indx; - hcp->order += order; - break; - default: - DB_ASSERT(0); - return (__db_panic(dbenv, EINVAL)); - } - if (my_txn != NULL && cp->txn != my_txn) - found = 1; - } - } - MUTEX_UNLOCK(dbenv, dbp->mutex); - } - MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist); - - if (found != 0 && DBC_LOGGING(dbc)) { - if ((ret = __ham_chgpg_log(dbp, my_txn, &lsn, 0, op, - old_pgno, new_pgno, indx, order)) != 0) - return (ret); - } - *orderp = order; - return (0); -} diff --git a/storage/bdb/hash/hash_rec.c b/storage/bdb/hash/hash_rec.c deleted file mode 100644 index d8db8690590..00000000000 --- a/storage/bdb/hash/hash_rec.c +++ /dev/null @@ -1,1206 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1995, 1996 - * Margo Seltzer. All rights reserved. - */ -/* - * Copyright (c) 1995, 1996 - * The President and Fellows of Harvard University. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Margo Seltzer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: hash_rec.c,v 12.7 2005/09/28 17:44:52 margo Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/btree.h" -#include "dbinc/hash.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" - -static int __ham_alloc_pages __P((DB *, __ham_groupalloc_args *, DB_LSN *)); - -/* - * __ham_insdel_recover -- - * - * PUBLIC: int __ham_insdel_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__ham_insdel_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __ham_insdel_args *argp; - DB *file_dbp; - DBC *dbc; - DB_MPOOLFILE *mpf; - PAGE *pagep; - u_int32_t flags, opcode; - int cmp_n, cmp_p, ret, type; - - pagep = NULL; - COMPQUIET(info, NULL); - - REC_PRINT(__ham_insdel_print); - REC_INTRO(__ham_insdel_read, 1, 0); - - if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) { - if (DB_UNDO(op)) { - if (ret == DB_PAGE_NOTFOUND) - goto done; - else { - ret = __db_pgerr(file_dbp, argp->pgno, ret); - goto out; - } - } -#ifdef HAVE_FTRUNCATE - /* If the page is not here then it was later truncated. */ - if (!IS_ZERO_LSN(argp->pagelsn)) - goto done; -#endif - /* - * This page was created by a group allocation and - * the file may not have been extend yet. - * Create the page if necessary. - */ - if ((ret = __memp_fget(mpf, - &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) { - ret = __db_pgerr(file_dbp, argp->pgno, ret); - goto out; - } - } - - cmp_n = log_compare(lsnp, &LSN(pagep)); - cmp_p = log_compare(&LSN(pagep), &argp->pagelsn); - CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->pagelsn); - /* - * Two possible things going on: - * redo a delete/undo a put: delete the item from the page. - * redo a put/undo a delete: add the item to the page. - * If we are undoing a delete, then the information logged is the - * entire entry off the page, not just the data of a dbt. In - * this case, we want to copy it back onto the page verbatim. - * We do this by calling __putitem with the type H_OFFPAGE instead - * of H_KEYDATA. - */ - - opcode = OPCODE_OF(argp->opcode); - flags = 0; - if ((opcode == DELPAIR && cmp_n == 0 && DB_UNDO(op)) || - (opcode == PUTPAIR && cmp_p == 0 && DB_REDO(op))) { - /* - * Need to redo a PUT or undo a delete. If we are undoing a - * delete, we've got to restore the item back to its original - * position. That's a royal pain in the butt (because we do - * not store item lengths on the page), but there's no choice. - */ - if (opcode != DELPAIR || - argp->ndx == (u_int32_t)NUM_ENT(pagep)) { - __ham_putitem(file_dbp, pagep, &argp->key, - DB_UNDO(op) || PAIR_ISKEYBIG(argp->opcode) ? - H_OFFPAGE : H_KEYDATA); - - if (PAIR_ISDATADUP(argp->opcode)) - type = H_DUPLICATE; - else if (DB_UNDO(op) || PAIR_ISDATABIG(argp->opcode)) - type = H_OFFPAGE; - else - type = H_KEYDATA; - __ham_putitem(file_dbp, pagep, &argp->data, type); - } else - __ham_reputpair(file_dbp, pagep, - argp->ndx, &argp->key, &argp->data); - - LSN(pagep) = DB_REDO(op) ? *lsnp : argp->pagelsn; - flags = DB_MPOOL_DIRTY; - - } else if ((opcode == DELPAIR && cmp_p == 0 && DB_REDO(op)) || - (opcode == PUTPAIR && cmp_n == 0 && DB_UNDO(op))) { - /* Need to undo a put or redo a delete. */ - __ham_dpair(file_dbp, pagep, argp->ndx); - LSN(pagep) = DB_REDO(op) ? *lsnp : argp->pagelsn; - flags = DB_MPOOL_DIRTY; - } - - if ((ret = __memp_fput(mpf, pagep, flags)) != 0) - goto out; - pagep = NULL; - - /* Return the previous LSN. */ -done: *lsnp = argp->prev_lsn; - ret = 0; - -out: if (pagep != NULL) - (void)__memp_fput(mpf, pagep, 0); - REC_CLOSE; -} - -/* - * __ham_newpage_recover -- - * This log message is used when we add/remove overflow pages. This - * message takes care of the pointer chains, not the data on the pages. - * - * PUBLIC: int __ham_newpage_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__ham_newpage_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __ham_newpage_args *argp; - DB *file_dbp; - DBC *dbc; - DB_MPOOLFILE *mpf; - PAGE *pagep; - u_int32_t flags; - int cmp_n, cmp_p, ret; - - pagep = NULL; - COMPQUIET(info, NULL); - - REC_PRINT(__ham_newpage_print); - REC_INTRO(__ham_newpage_read, 1, 0); - - REC_FGET(mpf, argp->new_pgno, &pagep, ppage); - - /* - * There are potentially three pages we need to check: the one - * that we created/deleted, the one before it and the one after - * it. - */ - - cmp_n = log_compare(lsnp, &LSN(pagep)); - cmp_p = log_compare(&LSN(pagep), &argp->pagelsn); - CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->pagelsn); - - flags = 0; - if ((cmp_p == 0 && DB_REDO(op) && argp->opcode == PUTOVFL) || - (cmp_n == 0 && DB_UNDO(op) && argp->opcode == DELOVFL)) { - /* Redo a create new page or undo a delete new page. */ - P_INIT(pagep, file_dbp->pgsize, argp->new_pgno, - argp->prev_pgno, argp->next_pgno, 0, P_HASH); - flags = DB_MPOOL_DIRTY; - } else if ((cmp_p == 0 && DB_REDO(op) && argp->opcode == DELOVFL) || - (cmp_n == 0 && DB_UNDO(op) && argp->opcode == PUTOVFL)) { - /* - * Redo a delete or undo a create new page. All we - * really need to do is change the LSN. - */ - flags = DB_MPOOL_DIRTY; - } - - if (flags) - LSN(pagep) = DB_REDO(op) ? *lsnp : argp->pagelsn; - - if ((ret = __memp_fput(mpf, pagep, flags)) != 0) - goto out; - pagep = NULL; - - /* Now do the prev page. */ -ppage: if (argp->prev_pgno != PGNO_INVALID) { - REC_FGET(mpf, argp->prev_pgno, &pagep, npage); - - cmp_n = log_compare(lsnp, &LSN(pagep)); - cmp_p = log_compare(&LSN(pagep), &argp->prevlsn); - CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->prevlsn); - flags = 0; - - if ((cmp_p == 0 && DB_REDO(op) && argp->opcode == PUTOVFL) || - (cmp_n == 0 && DB_UNDO(op) && argp->opcode == DELOVFL)) { - /* Redo a create new page or undo a delete new page. */ - pagep->next_pgno = argp->new_pgno; - flags = DB_MPOOL_DIRTY; - } else if ((cmp_p == 0 && - DB_REDO(op) && argp->opcode == DELOVFL) || - (cmp_n == 0 && DB_UNDO(op) && argp->opcode == PUTOVFL)) { - /* Redo a delete or undo a create new page. */ - pagep->next_pgno = argp->next_pgno; - flags = DB_MPOOL_DIRTY; - } - - if (flags) - LSN(pagep) = DB_REDO(op) ? *lsnp : argp->prevlsn; - - if ((ret = __memp_fput(mpf, pagep, flags)) != 0) - goto out; - pagep = NULL; - } - - /* Now time to do the next page */ -npage: if (argp->next_pgno != PGNO_INVALID) { - REC_FGET(mpf, argp->next_pgno, &pagep, done); - - cmp_n = log_compare(lsnp, &LSN(pagep)); - cmp_p = log_compare(&LSN(pagep), &argp->nextlsn); - CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->nextlsn); - flags = 0; - - if ((cmp_p == 0 && DB_REDO(op) && argp->opcode == PUTOVFL) || - (cmp_n == 0 && DB_UNDO(op) && argp->opcode == DELOVFL)) { - /* Redo a create new page or undo a delete new page. */ - pagep->prev_pgno = argp->new_pgno; - flags = DB_MPOOL_DIRTY; - } else if ((cmp_p == 0 && - DB_REDO(op) && argp->opcode == DELOVFL) || - (cmp_n == 0 && DB_UNDO(op) && argp->opcode == PUTOVFL)) { - /* Redo a delete or undo a create new page. */ - pagep->prev_pgno = argp->prev_pgno; - flags = DB_MPOOL_DIRTY; - } - - if (flags) - LSN(pagep) = DB_REDO(op) ? *lsnp : argp->nextlsn; - - if ((ret = __memp_fput(mpf, pagep, flags)) != 0) - goto out; - pagep = NULL; - } -done: *lsnp = argp->prev_lsn; - ret = 0; - -out: if (pagep != NULL) - (void)__memp_fput(mpf, pagep, 0); - REC_CLOSE; -} - -/* - * __ham_replace_recover -- - * This log message refers to partial puts that are local to a single - * page. You can think of them as special cases of the more general - * insdel log message. - * - * PUBLIC: int __ham_replace_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__ham_replace_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __ham_replace_args *argp; - DB *file_dbp; - DBC *dbc; - DB_MPOOLFILE *mpf; - DBT dbt; - PAGE *pagep; - u_int32_t flags; - u_int32_t change; - int cmp_n, cmp_p, is_plus, ret; - u_int8_t *hk; - - pagep = NULL; - COMPQUIET(info, NULL); - - REC_PRINT(__ham_replace_print); - REC_INTRO(__ham_replace_read, 1, 0); - - REC_FGET(mpf, argp->pgno, &pagep, done); - - cmp_n = log_compare(lsnp, &LSN(pagep)); - cmp_p = log_compare(&LSN(pagep), &argp->pagelsn); - CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->pagelsn); - - memset(&dbt, 0, sizeof(dbt)); - flags = 0; - - /* - * Before we know the direction of the transformation we will - * determine the size differential; then once we know if we are - * redoing or undoing, we'll adjust the sign (is_plus) appropriately. - */ - if (argp->newitem.size > argp->olditem.size) { - change = argp->newitem.size - argp->olditem.size; - is_plus = 1; - } else { - change = argp->olditem.size - argp->newitem.size; - is_plus = 0; - } - if (cmp_p == 0 && DB_REDO(op)) { - /* Reapply the change as specified. */ - dbt.data = argp->newitem.data; - dbt.size = argp->newitem.size; - LSN(pagep) = *lsnp; - /* - * The is_plus flag is set properly to reflect - * newitem.size - olditem.size. - */ - flags = DB_MPOOL_DIRTY; - } else if (cmp_n == 0 && DB_UNDO(op)) { - /* Undo the already applied change. */ - dbt.data = argp->olditem.data; - dbt.size = argp->olditem.size; - /* - * Invert is_plus to reflect sign of - * olditem.size - newitem.size. - */ - is_plus = !is_plus; - LSN(pagep) = argp->pagelsn; - flags = DB_MPOOL_DIRTY; - } - - if (flags) { - __ham_onpage_replace(file_dbp, pagep, - argp->ndx, argp->off, change, is_plus, &dbt); - if (argp->makedup) { - hk = P_ENTRY(file_dbp, pagep, argp->ndx); - if (DB_REDO(op)) - HPAGE_PTYPE(hk) = H_DUPLICATE; - else - HPAGE_PTYPE(hk) = H_KEYDATA; - } - } - - if ((ret = __memp_fput(mpf, pagep, flags)) != 0) - goto out; - pagep = NULL; - -done: *lsnp = argp->prev_lsn; - ret = 0; - -out: if (pagep != NULL) - (void)__memp_fput(mpf, pagep, 0); - REC_CLOSE; -} - -/* - * __ham_splitdata_recover -- - * - * PUBLIC: int __ham_splitdata_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__ham_splitdata_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __ham_splitdata_args *argp; - DB *file_dbp; - DBC *dbc; - DB_MPOOLFILE *mpf; - PAGE *pagep; - u_int32_t flags; - int cmp_n, cmp_p, ret; - - pagep = NULL; - COMPQUIET(info, NULL); - - REC_PRINT(__ham_splitdata_print); - REC_INTRO(__ham_splitdata_read, 1, 0); - - if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) { - if (DB_UNDO(op)) { - if (ret == DB_PAGE_NOTFOUND) - goto done; - else { - ret = __db_pgerr(file_dbp, argp->pgno, ret); - goto out; - } - } -#ifdef HAVE_FTRUNCATE - /* If the page is not here then it was later truncated. */ - if (!IS_ZERO_LSN(argp->pagelsn)) - goto done; -#endif - /* - * This page was created by a group allocation and - * the file may not have been extend yet. - * Create the page if necessary. - */ - if ((ret = __memp_fget(mpf, - &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) { - ret = __db_pgerr(file_dbp, argp->pgno, ret); - goto out; - } - } - - cmp_n = log_compare(lsnp, &LSN(pagep)); - cmp_p = log_compare(&LSN(pagep), &argp->pagelsn); - CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->pagelsn); - - /* - * There are two types of log messages here, one for the old page - * and one for the new pages created. The original image in the - * SPLITOLD record is used for undo. The image in the SPLITNEW - * is used for redo. We should never have a case where there is - * a redo operation and the SPLITOLD record is on disk, but not - * the SPLITNEW record. Therefore, we only have work to do when - * redo NEW messages and undo OLD messages, but we have to update - * LSNs in both cases. - */ - flags = 0; - if (cmp_p == 0 && DB_REDO(op)) { - if (argp->opcode == SPLITNEW) - /* Need to redo the split described. */ - memcpy(pagep, argp->pageimage.data, - argp->pageimage.size); - LSN(pagep) = *lsnp; - flags = DB_MPOOL_DIRTY; - } else if (cmp_n == 0 && DB_UNDO(op)) { - if (argp->opcode == SPLITOLD) { - /* Put back the old image. */ - memcpy(pagep, argp->pageimage.data, - argp->pageimage.size); - } else - P_INIT(pagep, file_dbp->pgsize, argp->pgno, - PGNO_INVALID, PGNO_INVALID, 0, P_HASH); - LSN(pagep) = argp->pagelsn; - flags = DB_MPOOL_DIRTY; - } - if ((ret = __memp_fput(mpf, pagep, flags)) != 0) - goto out; - pagep = NULL; - -done: *lsnp = argp->prev_lsn; - ret = 0; - -out: if (pagep != NULL) - (void)__memp_fput(mpf, pagep, 0); - REC_CLOSE; -} - -/* - * __ham_copypage_recover -- - * Recovery function for copypage. - * - * PUBLIC: int __ham_copypage_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__ham_copypage_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __ham_copypage_args *argp; - DB *file_dbp; - DBC *dbc; - DB_MPOOLFILE *mpf; - PAGE *pagep; - u_int32_t flags; - int cmp_n, cmp_p, ret; - - pagep = NULL; - COMPQUIET(info, NULL); - - REC_PRINT(__ham_copypage_print); - REC_INTRO(__ham_copypage_read, 1, 0); - - flags = 0; - - /* This is the bucket page. */ - REC_FGET(mpf, argp->pgno, &pagep, donext); - - cmp_n = log_compare(lsnp, &LSN(pagep)); - cmp_p = log_compare(&LSN(pagep), &argp->pagelsn); - CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->pagelsn); - - if (cmp_p == 0 && DB_REDO(op)) { - /* Need to redo update described. */ - memcpy(pagep, argp->page.data, argp->page.size); - PGNO(pagep) = argp->pgno; - PREV_PGNO(pagep) = PGNO_INVALID; - LSN(pagep) = *lsnp; - flags = DB_MPOOL_DIRTY; - } else if (cmp_n == 0 && DB_UNDO(op)) { - /* Need to undo update described. */ - P_INIT(pagep, file_dbp->pgsize, argp->pgno, PGNO_INVALID, - argp->next_pgno, 0, P_HASH); - LSN(pagep) = argp->pagelsn; - flags = DB_MPOOL_DIRTY; - } - if ((ret = __memp_fput(mpf, pagep, flags)) != 0) - goto out; - pagep = NULL; - -donext: /* Now fix up the "next" page. */ - REC_FGET(mpf, argp->next_pgno, &pagep, do_nn); - - /* For REDO just update the LSN. For UNDO copy page back. */ - cmp_n = log_compare(lsnp, &LSN(pagep)); - cmp_p = log_compare(&LSN(pagep), &argp->nextlsn); - CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->nextlsn); - flags = 0; - if (cmp_p == 0 && DB_REDO(op)) { - LSN(pagep) = *lsnp; - flags = DB_MPOOL_DIRTY; - } else if (cmp_n == 0 && DB_UNDO(op)) { - /* Need to undo update described. */ - memcpy(pagep, argp->page.data, argp->page.size); - flags = DB_MPOOL_DIRTY; - } - if ((ret = __memp_fput(mpf, pagep, flags)) != 0) - goto out; - pagep = NULL; - - /* Now fix up the next's next page. */ -do_nn: if (argp->nnext_pgno == PGNO_INVALID) - goto done; - - REC_FGET(mpf, argp->nnext_pgno, &pagep, done); - - cmp_n = log_compare(lsnp, &LSN(pagep)); - cmp_p = log_compare(&LSN(pagep), &argp->nnextlsn); - CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->nnextlsn); - - flags = 0; - if (cmp_p == 0 && DB_REDO(op)) { - /* Need to redo update described. */ - PREV_PGNO(pagep) = argp->pgno; - LSN(pagep) = *lsnp; - flags = DB_MPOOL_DIRTY; - } else if (cmp_n == 0 && DB_UNDO(op)) { - /* Need to undo update described. */ - PREV_PGNO(pagep) = argp->next_pgno; - LSN(pagep) = argp->nnextlsn; - flags = DB_MPOOL_DIRTY; - } - if ((ret = __memp_fput(mpf, pagep, flags)) != 0) - goto out; - pagep = NULL; - -done: *lsnp = argp->prev_lsn; - ret = 0; - -out: if (pagep != NULL) - (void)__memp_fput(mpf, pagep, 0); - REC_CLOSE; -} - -/* - * __ham_metagroup_recover -- - * Recovery function for metagroup. - * - * PUBLIC: int __ham_metagroup_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__ham_metagroup_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __ham_metagroup_args *argp; - HASH_CURSOR *hcp; - DB *file_dbp; - DBMETA *mmeta; - DBC *dbc; - DB_MPOOLFILE *mpf; - PAGE *pagep; - db_pgno_t pgno; - u_int32_t flags, mmeta_flags; - int cmp_n, cmp_p, did_alloc, did_recover, groupgrow, ret; - - COMPQUIET(info, NULL); - mmeta_flags = 0; - did_alloc = 0; - mmeta = NULL; - REC_PRINT(__ham_metagroup_print); - REC_INTRO(__ham_metagroup_read, 1, 1); - - /* - * This logs the virtual create of pages pgno to pgno + bucket - * If HAVE_FTRUNCATE is not supported the mpool page-allocation is not - * transaction protected, we can never undo it. Even in an abort, - * we have to allocate these pages to the hash table if they - * were actually created. In particular, during disaster - * recovery the metapage may be before this point if we - * are rolling backward. If the file has not been extended - * then the metapage could not have been updated. - * The log record contains: - * bucket: old maximum bucket - * pgno: page number of the new bucket. - * We round up on log calculations, so we can figure out if we are - * about to double the hash table if argp->bucket+1 is a power of 2. - * If it is, then we are allocating an entire doubling of pages, - * otherwise, we are simply allocated one new page. - */ - groupgrow = - (u_int32_t)(1 << __db_log2(argp->bucket + 1)) == argp->bucket + 1; - pgno = argp->pgno; - if (argp->newalloc) - pgno += argp->bucket; - - flags = 0; - pagep = NULL; -#ifndef HAVE_FTRUNCATE - flags = DB_MPOOL_CREATE; -#endif - ret = __memp_fget(mpf, &pgno, flags, &pagep); - -#ifdef HAVE_FTRUNCATE - /* If we are undoing, then we don't want to create the page. */ - if (ret != 0 && DB_REDO(op)) - ret = __memp_fget(mpf, &pgno, DB_MPOOL_CREATE, &pagep); - else if (ret == DB_PAGE_NOTFOUND) - goto do_meta; -#endif - if (ret != 0) { - if (ret != ENOSPC) - goto out; - pgno = 0; - goto do_meta; - } - - /* - * When we get here then either we did not grow the file - * (groupgrow == 0) or we did grow the file and the allocation - * of those new pages succeeded. - */ - did_alloc = groupgrow; - - cmp_n = log_compare(lsnp, &LSN(pagep)); - cmp_p = log_compare(&LSN(pagep), &argp->pagelsn); - CHECK_LSN(dbenv, op, cmp_p, &LSN(pagep), &argp->pagelsn); - - flags = 0; - if (cmp_p == 0 && DB_REDO(op)) { - pagep->lsn = *lsnp; - flags = DB_MPOOL_DIRTY; - } else if (cmp_n == 0 && DB_UNDO(op)) { -#ifdef HAVE_FTRUNCATE - /* If this record allocated the pages give them back. */ - if (argp->newalloc) { - if (pagep != NULL && (ret = - __memp_fput(mpf, pagep, DB_MPOOL_DISCARD)) != 0) - goto out; - pagep = NULL; - if ((ret = __memp_ftruncate(mpf, argp->pgno, 0)) != 0) - goto out; - } else -#endif - { - /* - * Otherwise just roll the page back to its - * previous state. - */ - pagep->lsn = argp->pagelsn; - flags = DB_MPOOL_DIRTY; - } - } - if (pagep != NULL && (ret = __memp_fput(mpf, pagep, flags)) != 0) - goto out; - -do_meta: - /* Now we have to update the meta-data page. */ - hcp = (HASH_CURSOR *)dbc->internal; - if ((ret = __ham_get_meta(dbc)) != 0) - goto out; - cmp_n = log_compare(lsnp, &hcp->hdr->dbmeta.lsn); - cmp_p = log_compare(&hcp->hdr->dbmeta.lsn, &argp->metalsn); - CHECK_LSN(dbenv, op, cmp_p, &hcp->hdr->dbmeta.lsn, &argp->metalsn); - did_recover = 0; - if (cmp_p == 0 && DB_REDO(op)) { - /* Redo the actual updating of bucket counts. */ - ++hcp->hdr->max_bucket; - if (groupgrow) { - hcp->hdr->low_mask = hcp->hdr->high_mask; - hcp->hdr->high_mask = - (argp->bucket + 1) | hcp->hdr->low_mask; - } - hcp->hdr->dbmeta.lsn = *lsnp; - did_recover = 1; - } else if (cmp_n == 0 && DB_UNDO(op)) { - /* Undo the actual updating of bucket counts. */ - hcp->hdr->max_bucket = argp->bucket; - if (groupgrow) { - hcp->hdr->high_mask = argp->bucket; - hcp->hdr->low_mask = hcp->hdr->high_mask >> 1; - } - hcp->hdr->dbmeta.lsn = argp->metalsn; - did_recover = 1; - } - - /* - * Now we need to fix up the spares array. Each entry in the - * spares array indicates the beginning page number for the - * indicated doubling. We need to fill this in whenever the - * spares array is invalid, if we never reclaim pages then - * we have to allocate the pages to the spares array in both - * the redo and undo cases. - */ - if (did_alloc && -#ifdef HAVE_FTRUNCATE - !DB_UNDO(op) && -#endif - hcp->hdr->spares[__db_log2(argp->bucket + 1) + 1] == PGNO_INVALID) { - hcp->hdr->spares[__db_log2(argp->bucket + 1) + 1] = - (argp->pgno - argp->bucket) - 1; - did_recover = 1; - } -#ifdef HAVE_FTRUNCATE - if (cmp_n == 0 && groupgrow && DB_UNDO(op)) { - hcp->hdr->spares[ - __db_log2(argp->bucket + 1) + 1] = PGNO_INVALID; - did_recover = 1; - } -#endif - - /* - * Finally, we need to potentially fix up the last_pgno field - * in the master meta-data page (which may or may not be the - * same as the hash header page). - */ - if (argp->mmpgno != argp->mpgno) { - if ((ret = __memp_fget(mpf, &argp->mmpgno, 0, &mmeta)) != 0) - goto out; - mmeta_flags = 0; - cmp_n = log_compare(lsnp, &mmeta->lsn); - cmp_p = log_compare(&mmeta->lsn, &argp->mmetalsn); - if (cmp_p == 0 && DB_REDO(op)) - mmeta->lsn = *lsnp; - else if (cmp_n == 0 && DB_UNDO(op)) - mmeta->lsn = argp->mmetalsn; - } else - mmeta = (DBMETA *)hcp->hdr; - -#ifdef HAVE_FTRUNCATE - if (cmp_n == 0 && DB_UNDO(op)) - mmeta->last_pgno = argp->last_pgno; - else if (DB_REDO(op)) -#endif - if (mmeta->last_pgno < pgno) - mmeta->last_pgno = pgno; - mmeta_flags = DB_MPOOL_DIRTY; - - if (argp->mmpgno != argp->mpgno && - (ret = __memp_fput(mpf, mmeta, mmeta_flags)) != 0) - goto out; - mmeta = NULL; - - if (did_recover) - F_SET(hcp, H_DIRTY); - -done: *lsnp = argp->prev_lsn; - ret = 0; - -out: if (mmeta != NULL) - (void)__memp_fput(mpf, mmeta, 0); - if (dbc != NULL) - (void)__ham_release_meta(dbc); - if (ret == ENOENT && op == DB_TXN_BACKWARD_ALLOC) - ret = 0; - - REC_CLOSE; -} - -/* - * __ham_groupalloc_recover -- - * Recover the batch creation of a set of pages for a new database. - * - * PUBLIC: int __ham_groupalloc_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__ham_groupalloc_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __ham_groupalloc_args *argp; - DBMETA *mmeta; - DB_MPOOLFILE *mpf; - DB *file_dbp; - DBC *dbc; - PAGE *pagep; - db_pgno_t pgno; - int cmp_n, cmp_p, modified, ret; - - mmeta = NULL; - modified = 0; - REC_PRINT(__ham_groupalloc_print); - REC_INTRO(__ham_groupalloc_read, 0, 0); - - pgno = PGNO_BASE_MD; - if ((ret = __memp_fget(mpf, &pgno, 0, &mmeta)) != 0) { - if (DB_REDO(op)) { - ret = __db_pgerr(file_dbp, pgno, ret); - goto out; - } else - goto done; - } - - cmp_n = log_compare(lsnp, &LSN(mmeta)); - cmp_p = log_compare(&LSN(mmeta), &argp->meta_lsn); - CHECK_LSN(dbenv, op, cmp_p, &LSN(mmeta), &argp->meta_lsn); - - /* - * Basically, we used mpool to allocate a chunk of pages. - * We need to either add those to a free list (in the undo - * case) or initialize them (in the redo case). - * - * If we are redoing and this is a hash subdatabase, it's possible - * that the pages were never allocated, so we'd better check for - * that and handle it here. - */ - pgno = argp->start_pgno + argp->num - 1; - if (DB_REDO(op)) { - if ((ret = __ham_alloc_pages(file_dbp, argp, lsnp)) != 0) - goto out; - if (cmp_p == 0) { - LSN(mmeta) = *lsnp; - modified = 1; - } - } else if (DB_UNDO(op)) { - /* - * Fetch the last page and determine if it is in - * the post allocation state. - */ - pagep = NULL; - if ((ret = __memp_fget(mpf, &pgno, 0, &pagep)) == 0) { - if (log_compare(&pagep->lsn, lsnp) != 0) { - if ((ret = __memp_fput(mpf, - pagep, DB_MPOOL_DISCARD)) != 0) - goto out; - pagep = NULL; - } - } else if (ret != DB_PAGE_NOTFOUND) - goto out; -#ifdef HAVE_FTRUNCATE - COMPQUIET(info, NULL); - /* - * If the last page was allocated then truncate back - * to the first page. - */ - if (pagep != NULL) { - if ((ret = - __memp_fput(mpf, pagep, DB_MPOOL_DISCARD)) != 0) - goto out; - if ((ret = - __memp_ftruncate(mpf, argp->start_pgno, 0)) != 0) - goto out; - } - - /* - * If we are rolling back the metapage, then make - * sure it reflects the the correct last_pgno. - */ - if (cmp_n == 0) { - mmeta->last_pgno = argp->last_pgno; - modified = 1; - } - pgno = 0; -#else - /* - * Reset the last page back to its preallocation state. - */ - if (pagep != NULL) { - if (log_compare(&pagep->lsn, lsnp) == 0) - ZERO_LSN(pagep->lsn); - - if ((ret = - __memp_fput(mpf, pagep, DB_MPOOL_DIRTY)) != 0) - goto out; - } - /* - * Put the pages into the limbo list and free them later. - */ - if ((ret = __db_add_limbo(dbenv, - info, argp->fileid, argp->start_pgno, argp->num)) != 0) - goto out; -#endif - if (cmp_n == 0) { - LSN(mmeta) = argp->meta_lsn; - modified = 1; - } - } - - /* - * In both REDO and UNDO, we have grown the file and need to make - * sure that last_pgno is correct. If we HAVE_FTRUNCATE pgno - * will only be valid on REDO. - */ - if (pgno > mmeta->last_pgno) { - mmeta->last_pgno = pgno; - modified = 1; - } - -done: if (ret == 0) - *lsnp = argp->prev_lsn; - ret = 0; - -out: if (mmeta != NULL) - (void)__memp_fput(mpf, mmeta, modified ? DB_MPOOL_DIRTY : 0); - - if (ret == ENOENT && op == DB_TXN_BACKWARD_ALLOC) - ret = 0; - REC_CLOSE; -} - -/* - * __ham_alloc_pages -- - * - * Called during redo of a file create. We create new pages in the file - * using the MPOOL_NEW_GROUP flag. We then log the meta-data page with a - * __crdel_metasub message. If we manage to crash without the newly written - * pages getting to disk (I'm not sure this can happen anywhere except our - * test suite?!), then we need to go through a recreate the final pages. - * Hash normally has holes in its files and handles them appropriately. - */ -static int -__ham_alloc_pages(dbp, argp, lsnp) - DB *dbp; - __ham_groupalloc_args *argp; - DB_LSN *lsnp; -{ - DB_MPOOLFILE *mpf; - PAGE *pagep; - db_pgno_t pgno; - int ret; - - mpf = dbp->mpf; - - /* Read the last page of the allocation. */ - pgno = argp->start_pgno + argp->num - 1; - - /* If the page exists, and it has been initialized, then we're done. */ - if ((ret = __memp_fget(mpf, &pgno, 0, &pagep)) == 0) { - if (NUM_ENT(pagep) == 0 && IS_ZERO_LSN(pagep->lsn)) - goto reinit_page; - if ((ret = __memp_fput(mpf, pagep, 0)) != 0) - return (ret); - return (0); - } - - /* Had to create the page. */ - if ((ret = __memp_fget(mpf, &pgno, DB_MPOOL_CREATE, &pagep)) != 0) - return (__db_pgerr(dbp, pgno, ret)); - -reinit_page: - /* Initialize the newly allocated page. */ - P_INIT(pagep, dbp->pgsize, pgno, PGNO_INVALID, PGNO_INVALID, 0, P_HASH); - pagep->lsn = *lsnp; - - if ((ret = __memp_fput(mpf, pagep, DB_MPOOL_DIRTY)) != 0) - return (ret); - - return (0); -} - -/* - * __ham_curadj_recover -- - * Undo cursor adjustments if a subtransaction fails. - * - * PUBLIC: int __ham_curadj_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__ham_curadj_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __ham_curadj_args *argp; - DB_MPOOLFILE *mpf; - DB *file_dbp; - DBC *dbc; - int ret; - HASH_CURSOR *hcp; - - COMPQUIET(info, NULL); - REC_PRINT(__ham_curadj_print); - REC_INTRO(__ham_curadj_read, 0, 1); - - if (op != DB_TXN_ABORT) - goto done; - - /* - * Undo the adjustment by reinitializing the the cursor to look like - * the one that was used to do the adjustment, then we invert the - * add so that undo the adjustment. - */ - hcp = (HASH_CURSOR *)dbc->internal; - hcp->pgno = argp->pgno; - hcp->indx = argp->indx; - hcp->dup_off = argp->dup_off; - hcp->order = argp->order; - if (!argp->add) - F_SET(hcp, H_DELETED); - (void)__ham_c_update(dbc, argp->len, !argp->add, argp->is_dup); - -done: *lsnp = argp->prev_lsn; -out: REC_CLOSE; -} - -/* - * __ham_chgpg_recover -- - * Undo cursor adjustments if a subtransaction fails. - * - * PUBLIC: int __ham_chgpg_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__ham_chgpg_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __ham_chgpg_args *argp; - BTREE_CURSOR *opdcp; - DB_MPOOLFILE *mpf; - DB *file_dbp, *ldbp; - DBC *dbc; - int ret; - DBC *cp; - HASH_CURSOR *lcp; - u_int32_t order, indx; - - COMPQUIET(info, NULL); - REC_PRINT(__ham_chgpg_print); - REC_INTRO(__ham_chgpg_read, 0, 0); - - if (op != DB_TXN_ABORT) - goto done; - - /* Overloaded fields for DB_HAM_DEL*PG */ - indx = argp->old_indx; - order = argp->new_indx; - - MUTEX_LOCK(dbenv, dbenv->mtx_dblist); - for (ldbp = __dblist_get(dbenv, file_dbp->adj_fileid); - ldbp != NULL && ldbp->adj_fileid == file_dbp->adj_fileid; - ldbp = LIST_NEXT(ldbp, dblistlinks)) { - MUTEX_LOCK(dbenv, file_dbp->mutex); - - for (cp = TAILQ_FIRST(&ldbp->active_queue); cp != NULL; - cp = TAILQ_NEXT(cp, links)) { - lcp = (HASH_CURSOR *)cp->internal; - - switch (argp->mode) { - case DB_HAM_DELFIRSTPG: - if (lcp->pgno != argp->new_pgno) - break; - if (lcp->indx != indx || - !F_ISSET(lcp, H_DELETED) || - lcp->order >= order) { - lcp->pgno = argp->old_pgno; - if (lcp->indx == indx) - lcp->order -= order; - } - break; - case DB_HAM_DELMIDPG: - case DB_HAM_DELLASTPG: - if (lcp->pgno == argp->new_pgno && - lcp->indx == indx && - F_ISSET(lcp, H_DELETED) && - lcp->order >= order) { - lcp->pgno = argp->old_pgno; - lcp->order -= order; - lcp->indx = 0; - } - break; - case DB_HAM_CHGPG: - /* - * If we're doing a CHGPG, we're undoing - * the move of a non-deleted item to a - * new page. Any cursors with the deleted - * flag set do not belong to this item; - * don't touch them. - */ - if (F_ISSET(lcp, H_DELETED)) - break; - /* FALLTHROUGH */ - case DB_HAM_SPLIT: - if (lcp->pgno == argp->new_pgno && - lcp->indx == argp->new_indx) { - lcp->indx = argp->old_indx; - lcp->pgno = argp->old_pgno; - } - break; - case DB_HAM_DUP: - if (lcp->opd == NULL) - break; - opdcp = (BTREE_CURSOR *)lcp->opd->internal; - if (opdcp->pgno != argp->new_pgno || - opdcp->indx != argp->new_indx) - break; - - if (F_ISSET(opdcp, C_DELETED)) - F_SET(lcp, H_DELETED); - /* - * We can't close a cursor while we have the - * dbp mutex locked, since c_close reacquires - * it. It should be safe to drop the mutex - * here, though, since newly opened cursors - * are put only at the end of the tailq and - * the cursor we're adjusting can't be closed - * under us. - */ - MUTEX_UNLOCK(dbenv, file_dbp->mutex); - if ((ret = __db_c_close(lcp->opd)) != 0) - goto out; - MUTEX_LOCK(dbenv, file_dbp->mutex); - lcp->opd = NULL; - break; - } - } - MUTEX_UNLOCK(dbenv, file_dbp->mutex); - } - MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist); - -done: *lsnp = argp->prev_lsn; -out: REC_CLOSE; -} diff --git a/storage/bdb/hash/hash_reclaim.c b/storage/bdb/hash/hash_reclaim.c deleted file mode 100644 index 20f354d9838..00000000000 --- a/storage/bdb/hash/hash_reclaim.c +++ /dev/null @@ -1,94 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: hash_reclaim.c,v 12.2 2005/06/16 20:22:53 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/hash.h" - -/* - * __ham_reclaim -- - * Reclaim the pages from a subdatabase and return them to the - * parent free list. For now, we link each freed page on the list - * separately. If people really store hash databases in subdatabases - * and do a lot of creates and deletes, this is going to be a problem, - * because hash needs chunks of contiguous storage. We may eventually - * need to go to a model where we maintain the free list with chunks of - * contiguous pages as well. - * - * PUBLIC: int __ham_reclaim __P((DB *, DB_TXN *txn)); - */ -int -__ham_reclaim(dbp, txn) - DB *dbp; - DB_TXN *txn; -{ - DBC *dbc; - HASH_CURSOR *hcp; - int ret; - - /* Open up a cursor that we'll use for traversing. */ - if ((ret = __db_cursor(dbp, txn, &dbc, 0)) != 0) - return (ret); - hcp = (HASH_CURSOR *)dbc->internal; - - if ((ret = __ham_get_meta(dbc)) != 0) - goto err; - - if ((ret = __ham_traverse(dbc, - DB_LOCK_WRITE, __db_reclaim_callback, dbc, 1)) != 0) - goto err; - if ((ret = __db_c_close(dbc)) != 0) - goto err; - if ((ret = __ham_release_meta(dbc)) != 0) - goto err; - return (0); - -err: if (hcp->hdr != NULL) - (void)__ham_release_meta(dbc); - (void)__db_c_close(dbc); - return (ret); -} - -/* - * __ham_truncate -- - * Reclaim the pages from a subdatabase and return them to the - * parent free list. - * - * PUBLIC: int __ham_truncate __P((DBC *, u_int32_t *)); - */ -int -__ham_truncate(dbc, countp) - DBC *dbc; - u_int32_t *countp; -{ - db_trunc_param trunc; - int ret, t_ret; - - if ((ret = __ham_get_meta(dbc)) != 0) - return (ret); - - trunc.count = 0; - trunc.dbc = dbc; - - ret = __ham_traverse(dbc, - DB_LOCK_WRITE, __db_truncate_callback, &trunc, 1); - - if ((t_ret = __ham_release_meta(dbc)) != 0 && ret == 0) - ret = t_ret; - - if (countp != NULL) - *countp = trunc.count; - return (ret); -} diff --git a/storage/bdb/hash/hash_stat.c b/storage/bdb/hash/hash_stat.c deleted file mode 100644 index 1771c2a2296..00000000000 --- a/storage/bdb/hash/hash_stat.c +++ /dev/null @@ -1,507 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: hash_stat.c,v 12.1 2005/06/16 20:22:53 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/btree.h" -#include "dbinc/hash.h" -#include "dbinc/mp.h" - -#ifdef HAVE_STATISTICS -static int __ham_stat_callback __P((DB *, PAGE *, void *, int *)); - -/* - * __ham_stat -- - * Gather/print the hash statistics - * - * PUBLIC: int __ham_stat __P((DBC *, void *, u_int32_t)); - */ -int -__ham_stat(dbc, spp, flags) - DBC *dbc; - void *spp; - u_int32_t flags; -{ - DB *dbp; - DB_ENV *dbenv; - DB_HASH_STAT *sp; - DB_MPOOLFILE *mpf; - HASH_CURSOR *hcp; - PAGE *h; - db_pgno_t pgno; - int ret; - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - - mpf = dbp->mpf; - sp = NULL; - - hcp = (HASH_CURSOR *)dbc->internal; - - if ((ret = __ham_get_meta(dbc)) != 0) - goto err; - - /* Allocate and clear the structure. */ - if ((ret = __os_umalloc(dbenv, sizeof(*sp), &sp)) != 0) - goto err; - memset(sp, 0, sizeof(*sp)); - /* Copy the fields that we have. */ - sp->hash_nkeys = hcp->hdr->dbmeta.key_count; - sp->hash_ndata = hcp->hdr->dbmeta.record_count; - sp->hash_pagesize = dbp->pgsize; - sp->hash_buckets = hcp->hdr->max_bucket + 1; - sp->hash_magic = hcp->hdr->dbmeta.magic; - sp->hash_version = hcp->hdr->dbmeta.version; - sp->hash_metaflags = hcp->hdr->dbmeta.flags; - sp->hash_ffactor = hcp->hdr->ffactor; - - if (flags == DB_FAST_STAT || flags == DB_CACHED_COUNTS) - goto done; - - /* Walk the free list, counting pages. */ - for (sp->hash_free = 0, pgno = hcp->hdr->dbmeta.free; - pgno != PGNO_INVALID;) { - ++sp->hash_free; - - if ((ret = __memp_fget(mpf, &pgno, 0, &h)) != 0) - goto err; - - pgno = h->next_pgno; - (void)__memp_fput(mpf, h, 0); - } - - /* Now traverse the rest of the table. */ - sp->hash_nkeys = 0; - sp->hash_ndata = 0; - if ((ret = __ham_traverse(dbc, - DB_LOCK_READ, __ham_stat_callback, sp, 0)) != 0) - goto err; - - if (!F_ISSET(dbp, DB_AM_RDONLY)) { - if ((ret = __ham_dirty_meta(dbc)) != 0) - goto err; - hcp->hdr->dbmeta.key_count = sp->hash_nkeys; - hcp->hdr->dbmeta.record_count = sp->hash_ndata; - } - -done: if ((ret = __ham_release_meta(dbc)) != 0) - goto err; - - *(DB_HASH_STAT **)spp = sp; - return (0); - -err: if (sp != NULL) - __os_ufree(dbenv, sp); - - if (hcp->hdr != NULL) - (void)__ham_release_meta(dbc); - - return (ret); -} - -/* - * __ham_stat_print -- - * Display hash statistics. - * - * PUBLIC: int __ham_stat_print __P((DBC *, u_int32_t)); - */ -int -__ham_stat_print(dbc, flags) - DBC *dbc; - u_int32_t flags; -{ - static const FN fn[] = { - { DB_HASH_DUP, "duplicates" }, - { DB_HASH_SUBDB, "multiple-databases" }, - { DB_HASH_DUPSORT, "sorted duplicates" }, - { 0, NULL } - }; - DB *dbp; - DB_ENV *dbenv; - DB_HASH_STAT *sp; - int lorder, ret; - const char *s; - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - - if ((ret = __ham_stat(dbc, &sp, 0)) != 0) - return (ret); - - if (LF_ISSET(DB_STAT_ALL)) { - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_msg(dbenv, "Default Hash database information:"); - } - __db_msg(dbenv, "%lx\tHash magic number", (u_long)sp->hash_magic); - __db_msg(dbenv, - "%lu\tHash version number", (u_long)sp->hash_version); - (void)__db_get_lorder(dbp, &lorder); - switch (lorder) { - case 1234: - s = "Little-endian"; - break; - case 4321: - s = "Big-endian"; - break; - default: - s = "Unrecognized byte order"; - break; - } - __db_msg(dbenv, "%s\tByte order", s); - __db_prflags(dbenv, NULL, sp->hash_metaflags, fn, NULL, "\tFlags"); - __db_dl(dbenv, - "Underlying database page size", (u_long)sp->hash_pagesize); - __db_dl(dbenv, "Specified fill factor", (u_long)sp->hash_ffactor); - __db_dl(dbenv, - "Number of keys in the database", (u_long)sp->hash_nkeys); - __db_dl(dbenv, - "Number of data items in the database", (u_long)sp->hash_ndata); - - __db_dl(dbenv, "Number of hash buckets", (u_long)sp->hash_buckets); - __db_dl_pct(dbenv, "Number of bytes free on bucket pages", - (u_long)sp->hash_bfree, DB_PCT_PG( - sp->hash_bfree, sp->hash_buckets, sp->hash_pagesize), "ff"); - - __db_dl(dbenv, - "Number of overflow pages", (u_long)sp->hash_bigpages); - __db_dl_pct(dbenv, "Number of bytes free in overflow pages", - (u_long)sp->hash_big_bfree, DB_PCT_PG( - sp->hash_big_bfree, sp->hash_bigpages, sp->hash_pagesize), "ff"); - - __db_dl(dbenv, - "Number of bucket overflow pages", (u_long)sp->hash_overflows); - __db_dl_pct(dbenv, - "Number of bytes free in bucket overflow pages", - (u_long)sp->hash_ovfl_free, DB_PCT_PG( - sp->hash_ovfl_free, sp->hash_overflows, sp->hash_pagesize), "ff"); - - __db_dl(dbenv, "Number of duplicate pages", (u_long)sp->hash_dup); - __db_dl_pct(dbenv, "Number of bytes free in duplicate pages", - (u_long)sp->hash_dup_free, DB_PCT_PG( - sp->hash_dup_free, sp->hash_dup, sp->hash_pagesize), "ff"); - - __db_dl(dbenv, - "Number of pages on the free list", (u_long)sp->hash_free); - - __os_ufree(dbenv, sp); - - return (0); -} - -static int -__ham_stat_callback(dbp, pagep, cookie, putp) - DB *dbp; - PAGE *pagep; - void *cookie; - int *putp; -{ - DB_HASH_STAT *sp; - DB_BTREE_STAT bstat; - db_indx_t indx, len, off, tlen, top; - u_int8_t *hk; - int ret; - - *putp = 0; - sp = cookie; - - switch (pagep->type) { - case P_INVALID: - /* - * Hash pages may be wholly zeroed; this is not a bug. - * Obviously such pages have no data, so we can just proceed. - */ - break; - case P_HASH: - /* - * We count the buckets and the overflow pages - * separately and tally their bytes separately - * as well. We need to figure out if this page - * is a bucket. - */ - if (PREV_PGNO(pagep) == PGNO_INVALID) - sp->hash_bfree += P_FREESPACE(dbp, pagep); - else { - sp->hash_overflows++; - sp->hash_ovfl_free += P_FREESPACE(dbp, pagep); - } - top = NUM_ENT(pagep); - /* Correct for on-page duplicates and deleted items. */ - for (indx = 0; indx < top; indx += P_INDX) { - switch (*H_PAIRDATA(dbp, pagep, indx)) { - case H_OFFDUP: - break; - case H_OFFPAGE: - case H_KEYDATA: - sp->hash_ndata++; - break; - case H_DUPLICATE: - tlen = LEN_HDATA(dbp, pagep, 0, indx); - hk = H_PAIRDATA(dbp, pagep, indx); - for (off = 0; off < tlen; - off += len + 2 * sizeof(db_indx_t)) { - sp->hash_ndata++; - memcpy(&len, - HKEYDATA_DATA(hk) - + off, sizeof(db_indx_t)); - } - break; - default: - return (__db_pgfmt(dbp->dbenv, PGNO(pagep))); - } - } - sp->hash_nkeys += H_NUMPAIRS(pagep); - break; - case P_IBTREE: - case P_IRECNO: - case P_LBTREE: - case P_LRECNO: - case P_LDUP: - /* - * These are all btree pages; get a correct - * cookie and call them. Then add appropriate - * fields into our stat structure. - */ - memset(&bstat, 0, sizeof(bstat)); - if ((ret = __bam_stat_callback(dbp, pagep, &bstat, putp)) != 0) - return (ret); - sp->hash_dup++; - sp->hash_dup_free += bstat.bt_leaf_pgfree + - bstat.bt_dup_pgfree + bstat.bt_int_pgfree; - sp->hash_ndata += bstat.bt_ndata; - break; - case P_OVERFLOW: - sp->hash_bigpages++; - sp->hash_big_bfree += P_OVFLSPACE(dbp, dbp->pgsize, pagep); - break; - default: - return (__db_pgfmt(dbp->dbenv, PGNO(pagep))); - } - - return (0); -} - -/* - * __ham_print_cursor -- - * Display the current cursor. - * - * PUBLIC: void __ham_print_cursor __P((DBC *)); - */ -void -__ham_print_cursor(dbc) - DBC *dbc; -{ - static const FN fn[] = { - { H_CONTINUE, "H_CONTINUE" }, - { H_DELETED, "H_DELETED" }, - { H_DIRTY, "H_DIRTY" }, - { H_DUPONLY, "H_DUPONLY" }, - { H_EXPAND, "H_EXPAND" }, - { H_ISDUP, "H_ISDUP" }, - { H_NEXT_NODUP, "H_NEXT_NODUP" }, - { H_NOMORE, "H_NOMORE" }, - { H_OK, "H_OK" }, - { 0, NULL } - }; - DB_ENV *dbenv; - HASH_CURSOR *cp; - - dbenv = dbc->dbp->dbenv; - cp = (HASH_CURSOR *)dbc->internal; - - STAT_ULONG("Bucket traversing", cp->bucket); - STAT_ULONG("Bucket locked", cp->lbucket); - STAT_ULONG("Duplicate set offset", cp->dup_off); - STAT_ULONG("Current duplicate length", cp->dup_len); - STAT_ULONG("Total duplicate set length", cp->dup_tlen); - STAT_ULONG("Bytes needed for add", cp->seek_size); - STAT_ULONG("Page on which we can insert", cp->seek_found_page); - STAT_ULONG("Order", cp->order); - __db_prflags(dbenv, NULL, cp->flags, fn, NULL, "\tInternal Flags"); -} - -#else /* !HAVE_STATISTICS */ - -int -__ham_stat(dbc, spp, flags) - DBC *dbc; - void *spp; - u_int32_t flags; -{ - COMPQUIET(spp, NULL); - COMPQUIET(flags, 0); - - return (__db_stat_not_built(dbc->dbp->dbenv)); -} -#endif - -/* - * __ham_traverse - * Traverse an entire hash table. We use the callback so that we - * can use this both for stat collection and for deallocation. - * - * PUBLIC: int __ham_traverse __P((DBC *, db_lockmode_t, - * PUBLIC: int (*)(DB *, PAGE *, void *, int *), void *, int)); - */ -int -__ham_traverse(dbc, mode, callback, cookie, look_past_max) - DBC *dbc; - db_lockmode_t mode; - int (*callback) __P((DB *, PAGE *, void *, int *)); - void *cookie; - int look_past_max; -{ - DB *dbp; - DBC *opd; - DB_MPOOLFILE *mpf; - HASH_CURSOR *hcp; - HKEYDATA *hk; - db_pgno_t pgno, opgno; - int did_put, i, ret, t_ret; - u_int32_t bucket, spares_entry; - - dbp = dbc->dbp; - opd = NULL; - mpf = dbp->mpf; - hcp = (HASH_CURSOR *)dbc->internal; - ret = 0; - - /* - * In a perfect world, we could simply read each page in the file - * and look at its page type to tally the information necessary. - * Unfortunately, the bucket locking that hash tables do to make - * locking easy, makes this a pain in the butt. We have to traverse - * duplicate, overflow and big pages from the bucket so that we - * don't access anything that isn't properly locked. - * - */ - for (bucket = 0;; bucket++) { - /* - * We put the loop exit condition check here, because - * it made for a really vile extended ?: that made SCO's - * compiler drop core. - * - * If look_past_max is not set, we can stop at max_bucket; - * if it is set, we need to include pages that are part of - * the current doubling but beyond the highest bucket we've - * split into, as well as pages from a "future" doubling - * that may have been created within an aborted - * transaction. To do this, keep looping (and incrementing - * bucket) until the corresponding spares array entries - * cease to be defined. - */ - if (look_past_max) { - spares_entry = __db_log2(bucket + 1); - if (spares_entry >= NCACHED || - hcp->hdr->spares[spares_entry] == 0) - break; - } else { - if (bucket > hcp->hdr->max_bucket) - break; - } - - hcp->bucket = bucket; - hcp->pgno = pgno = BUCKET_TO_PAGE(hcp, bucket); - for (ret = __ham_get_cpage(dbc, mode); ret == 0; - ret = __ham_next_cpage(dbc, pgno, 0)) { - - /* - * If we are cleaning up pages past the max_bucket, - * then they may be on the free list and have their - * next pointers set, but they should be ignored. In - * fact, we really ought to just skip anybody who is - * not a valid page. - */ - if (TYPE(hcp->page) == P_INVALID) - break; - pgno = NEXT_PGNO(hcp->page); - - /* - * Go through each item on the page checking for - * duplicates (in which case we have to count the - * duplicate pages) or big key/data items (in which - * case we have to count those pages). - */ - for (i = 0; i < NUM_ENT(hcp->page); i++) { - hk = (HKEYDATA *)P_ENTRY(dbp, hcp->page, i); - switch (HPAGE_PTYPE(hk)) { - case H_OFFDUP: - memcpy(&opgno, HOFFDUP_PGNO(hk), - sizeof(db_pgno_t)); - if ((ret = __db_c_newopd(dbc, - opgno, NULL, &opd)) != 0) - return (ret); - if ((ret = __bam_traverse(opd, - DB_LOCK_READ, opgno, - callback, cookie)) - != 0) - goto err; - if ((ret = __db_c_close(opd)) != 0) - return (ret); - opd = NULL; - break; - case H_OFFPAGE: - /* - * We are about to get a big page - * which will use the same spot that - * the current page uses, so we need - * to restore the current page before - * looking at it again. - */ - memcpy(&opgno, HOFFPAGE_PGNO(hk), - sizeof(db_pgno_t)); - if ((ret = __db_traverse_big(dbp, - opgno, callback, cookie)) != 0) - goto err; - break; - case H_KEYDATA: - case H_DUPLICATE: - break; - default: - DB_ASSERT(0); - ret = EINVAL; - goto err; - - } - } - - /* Call the callback on main pages. */ - if ((ret = callback(dbp, - hcp->page, cookie, &did_put)) != 0) - goto err; - - if (did_put) - hcp->page = NULL; - if (pgno == PGNO_INVALID) - break; - } - if (ret != 0) - goto err; - - if (hcp->page != NULL) { - if ((ret = __memp_fput(mpf, hcp->page, 0)) != 0) - return (ret); - hcp->page = NULL; - } - - } -err: if (opd != NULL && - (t_ret = __db_c_close(opd)) != 0 && ret == 0) - ret = t_ret; - return (ret); -} diff --git a/storage/bdb/hash/hash_stub.c b/storage/bdb/hash/hash_stub.c deleted file mode 100644 index da6791bc5c5..00000000000 --- a/storage/bdb/hash/hash_stub.c +++ /dev/null @@ -1,391 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: hash_stub.c,v 12.1 2005/06/16 20:22:54 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef HAVE_HASH -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/hash.h" - -/* - * If the library wasn't compiled with the Hash access method, various - * routines aren't available. Stub them here, returning an appropriate - * error. - */ - -/* - * __db_nohasham -- - * Error when a Berkeley DB build doesn't include the access method. - * - * PUBLIC: int __db_no_hash_am __P((DB_ENV *)); - */ -int -__db_no_hash_am(dbenv) - DB_ENV *dbenv; -{ - __db_err(dbenv, - "library build did not include support for the Hash access method"); - return (DB_OPNOTSUP); -} - -int -__ham_30_hashmeta(dbp, real_name, obuf) - DB *dbp; - char *real_name; - u_int8_t *obuf; -{ - COMPQUIET(real_name, NULL); - COMPQUIET(obuf, NULL); - return (__db_no_hash_am(dbp->dbenv)); -} - -int -__ham_30_sizefix(dbp, fhp, realname, metabuf) - DB *dbp; - DB_FH *fhp; - char *realname; - u_int8_t *metabuf; -{ - COMPQUIET(fhp, NULL); - COMPQUIET(realname, NULL); - COMPQUIET(metabuf, NULL); - return (__db_no_hash_am(dbp->dbenv)); -} - -int -__ham_31_hash(dbp, real_name, flags, fhp, h, dirtyp) - DB *dbp; - char *real_name; - u_int32_t flags; - DB_FH *fhp; - PAGE *h; - int *dirtyp; -{ - COMPQUIET(real_name, NULL); - COMPQUIET(flags, 0); - COMPQUIET(fhp, NULL); - COMPQUIET(h, NULL); - COMPQUIET(dirtyp, NULL); - return (__db_no_hash_am(dbp->dbenv)); -} - -int -__ham_31_hashmeta(dbp, real_name, flags, fhp, h, dirtyp) - DB *dbp; - char *real_name; - u_int32_t flags; - DB_FH *fhp; - PAGE *h; - int *dirtyp; -{ - COMPQUIET(real_name, NULL); - COMPQUIET(flags, 0); - COMPQUIET(fhp, NULL); - COMPQUIET(h, NULL); - COMPQUIET(dirtyp, NULL); - return (__db_no_hash_am(dbp->dbenv)); -} - -int -__ham_c_count(dbc, recnop) - DBC *dbc; - db_recno_t *recnop; -{ - COMPQUIET(recnop, NULL); - return (__db_no_hash_am(dbc->dbp->dbenv)); -} - -int -__ham_c_dup(orig_dbc, new_dbc) - DBC *orig_dbc, *new_dbc; -{ - COMPQUIET(new_dbc, NULL); - return (__db_no_hash_am(orig_dbc->dbp->dbenv)); -} - -int -__ham_c_init(dbc) - DBC *dbc; -{ - return (__db_no_hash_am(dbc->dbp->dbenv)); -} - -int -__ham_db_close(dbp) - DB *dbp; -{ - COMPQUIET(dbp, NULL); - return (0); -} - -int -__ham_db_create(dbp) - DB *dbp; -{ - COMPQUIET(dbp, NULL); - return (0); -} - -int -__ham_init_print(dbenv, dtabp, dtabsizep) - DB_ENV *dbenv; - int (***dtabp)__P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - size_t *dtabsizep; -{ - COMPQUIET(dbenv, NULL); - COMPQUIET(dtabp, NULL); - COMPQUIET(dtabsizep, NULL); - return (0); -} - -int -__ham_init_recover(dbenv, dtabp, dtabsizep) - DB_ENV *dbenv; - int (***dtabp)__P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - size_t *dtabsizep; -{ - COMPQUIET(dbenv, NULL); - COMPQUIET(dtabp, NULL); - COMPQUIET(dtabsizep, NULL); - return (0); -} - -int -__ham_meta2pgset(dbp, vdp, hmeta, flags, pgset) - DB *dbp; - VRFY_DBINFO *vdp; - HMETA *hmeta; - u_int32_t flags; - DB *pgset; -{ - COMPQUIET(vdp, NULL); - COMPQUIET(hmeta, NULL); - COMPQUIET(flags, 0); - COMPQUIET(pgset, NULL); - return (__db_no_hash_am(dbp->dbenv)); -} - -int -__ham_metachk(dbp, name, hashm) - DB *dbp; - const char *name; - HMETA *hashm; -{ - COMPQUIET(name, NULL); - COMPQUIET(hashm, NULL); - return (__db_no_hash_am(dbp->dbenv)); -} - -int -__ham_new_file(dbp, txn, fhp, name) - DB *dbp; - DB_TXN *txn; - DB_FH *fhp; - const char *name; -{ - COMPQUIET(txn, NULL); - COMPQUIET(fhp, NULL); - COMPQUIET(name, NULL); - return (__db_no_hash_am(dbp->dbenv)); -} - -int -__ham_new_subdb(mdbp, dbp, txn) - DB *mdbp, *dbp; - DB_TXN *txn; -{ - COMPQUIET(dbp, NULL); - COMPQUIET(txn, NULL); - return (__db_no_hash_am(mdbp->dbenv)); -} - -int -__ham_open(dbp, txn, name, base_pgno, flags) - DB *dbp; - DB_TXN *txn; - const char *name; - db_pgno_t base_pgno; - u_int32_t flags; -{ - COMPQUIET(txn, NULL); - COMPQUIET(name, NULL); - COMPQUIET(base_pgno, 0); - COMPQUIET(flags, 0); - return (__db_no_hash_am(dbp->dbenv)); -} - -int -__ham_pgin(dbenv, dummydbp, pg, pp, cookie) - DB_ENV *dbenv; - DB *dummydbp; - db_pgno_t pg; - void *pp; - DBT *cookie; -{ - COMPQUIET(dummydbp, NULL); - COMPQUIET(pg, 0); - COMPQUIET(pp, NULL); - COMPQUIET(cookie, NULL); - return (__db_no_hash_am(dbenv)); -} - -int -__ham_pgout(dbenv, dummydbp, pg, pp, cookie) - DB_ENV *dbenv; - DB *dummydbp; - db_pgno_t pg; - void *pp; - DBT *cookie; -{ - COMPQUIET(dummydbp, NULL); - COMPQUIET(pg, 0); - COMPQUIET(pp, NULL); - COMPQUIET(cookie, NULL); - return (__db_no_hash_am(dbenv)); -} - -void -__ham_print_cursor(dbc) - DBC *dbc; -{ - (void)__db_no_hash_am(dbc->dbp->dbenv); -} - -int -__ham_quick_delete(dbc) - DBC *dbc; -{ - return (__db_no_hash_am(dbc->dbp->dbenv)); -} - -int -__ham_reclaim(dbp, txn) - DB *dbp; - DB_TXN *txn; -{ - COMPQUIET(txn, NULL); - return (__db_no_hash_am(dbp->dbenv)); -} - -int -__ham_salvage(dbp, vdp, pgno, h, handle, callback, flags) - DB *dbp; - VRFY_DBINFO *vdp; - db_pgno_t pgno; - PAGE *h; - void *handle; - int (*callback) __P((void *, const void *)); - u_int32_t flags; -{ - COMPQUIET(vdp, NULL); - COMPQUIET(pgno, 0); - COMPQUIET(h, NULL); - COMPQUIET(handle, NULL); - COMPQUIET(callback, NULL); - COMPQUIET(flags, 0); - return (__db_no_hash_am(dbp->dbenv)); -} - -int -__ham_stat(dbc, spp, flags) - DBC *dbc; - void *spp; - u_int32_t flags; -{ - COMPQUIET(spp, NULL); - COMPQUIET(flags, 0); - return (__db_no_hash_am(dbc->dbp->dbenv)); -} - -int -__ham_stat_print(dbc, flags) - DBC *dbc; - u_int32_t flags; -{ - COMPQUIET(flags, 0); - return (__db_no_hash_am(dbc->dbp->dbenv)); -} - -int -__ham_truncate(dbc, countp) - DBC *dbc; - u_int32_t *countp; -{ - COMPQUIET(dbc, NULL); - COMPQUIET(countp, NULL); - return (__db_no_hash_am(dbc->dbp->dbenv)); -} - -int -__ham_vrfy(dbp, vdp, h, pgno, flags) - DB *dbp; - VRFY_DBINFO *vdp; - PAGE *h; - db_pgno_t pgno; - u_int32_t flags; -{ - COMPQUIET(vdp, NULL); - COMPQUIET(h, NULL); - COMPQUIET(pgno, 0); - COMPQUIET(flags, 0); - return (__db_no_hash_am(dbp->dbenv)); -} - -int -__ham_vrfy_hashing(dbp, nentries, m, thisbucket, pgno, flags, hfunc) - DB *dbp; - u_int32_t nentries; - HMETA *m; - u_int32_t thisbucket; - db_pgno_t pgno; - u_int32_t flags; - u_int32_t (*hfunc) __P((DB *, const void *, u_int32_t)); -{ - COMPQUIET(nentries, 0); - COMPQUIET(m, NULL); - COMPQUIET(thisbucket, 0); - COMPQUIET(pgno, 0); - COMPQUIET(flags, 0); - COMPQUIET(hfunc, NULL); - return (__db_no_hash_am(dbp->dbenv)); -} - -int -__ham_vrfy_meta(dbp, vdp, m, pgno, flags) - DB *dbp; - VRFY_DBINFO *vdp; - HMETA *m; - db_pgno_t pgno; - u_int32_t flags; -{ - COMPQUIET(vdp, NULL); - COMPQUIET(m, NULL); - COMPQUIET(pgno, 0); - COMPQUIET(flags, 0); - return (__db_no_hash_am(dbp->dbenv)); -} - -int -__ham_vrfy_structure(dbp, vdp, meta_pgno, flags) - DB *dbp; - VRFY_DBINFO *vdp; - db_pgno_t meta_pgno; - u_int32_t flags; -{ - COMPQUIET(vdp, NULL); - COMPQUIET(meta_pgno, 0); - COMPQUIET(flags, 0); - return (__db_no_hash_am(dbp->dbenv)); -} -#endif /* !HAVE_HASH */ diff --git a/storage/bdb/hash/hash_upgrade.c b/storage/bdb/hash/hash_upgrade.c deleted file mode 100644 index 4d7f705b178..00000000000 --- a/storage/bdb/hash/hash_upgrade.c +++ /dev/null @@ -1,264 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: hash_upgrade.c,v 12.1 2005/06/16 20:22:54 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/hash.h" -#include "dbinc/db_upgrade.h" - -/* - * __ham_30_hashmeta -- - * Upgrade the database from version 4/5 to version 6. - * - * PUBLIC: int __ham_30_hashmeta __P((DB *, char *, u_int8_t *)); - */ -int -__ham_30_hashmeta(dbp, real_name, obuf) - DB *dbp; - char *real_name; - u_int8_t *obuf; -{ - DB_ENV *dbenv; - HASHHDR *oldmeta; - HMETA30 newmeta; - u_int32_t *o_spares, *n_spares; - u_int32_t fillf, i, maxb, max_entry, nelem; - int ret; - - dbenv = dbp->dbenv; - memset(&newmeta, 0, sizeof(newmeta)); - - oldmeta = (HASHHDR *)obuf; - - /* - * The first 32 bytes are similar. The only change is the version - * and that we removed the ovfl_point and have the page type now. - */ - - newmeta.dbmeta.lsn = oldmeta->lsn; - newmeta.dbmeta.pgno = oldmeta->pgno; - newmeta.dbmeta.magic = oldmeta->magic; - newmeta.dbmeta.version = 6; - newmeta.dbmeta.pagesize = oldmeta->pagesize; - newmeta.dbmeta.type = P_HASHMETA; - - /* Move flags */ - newmeta.dbmeta.flags = oldmeta->flags; - - /* Copy the free list, which has changed its name but works the same. */ - newmeta.dbmeta.free = oldmeta->last_freed; - - /* Copy: max_bucket, high_mask, low-mask, ffactor, nelem, h_charkey */ - newmeta.max_bucket = oldmeta->max_bucket; - newmeta.high_mask = oldmeta->high_mask; - newmeta.low_mask = oldmeta->low_mask; - newmeta.ffactor = oldmeta->ffactor; - newmeta.nelem = oldmeta->nelem; - newmeta.h_charkey = oldmeta->h_charkey; - - /* - * There was a bug in 2.X versions where the nelem could go negative. - * In general, this is considered "bad." If it does go negative - * (that is, very large and positive), we'll die trying to dump and - * load this database. So, let's see if we can fix it here. - */ - nelem = newmeta.nelem; - fillf = newmeta.ffactor; - maxb = newmeta.max_bucket; - - if ((fillf != 0 && fillf * maxb < 2 * nelem) || - (fillf == 0 && nelem > 0x8000000)) - newmeta.nelem = 0; - - /* - * We now have to convert the spares array. The old spares array - * contained the total number of extra pages allocated prior to - * the bucket that begins the next doubling. The new spares array - * contains the page number of the first bucket in the next doubling - * MINUS the bucket number of that bucket. - */ - o_spares = oldmeta->spares; - n_spares = newmeta.spares; - max_entry = __db_log2(maxb + 1); /* highest spares entry in use */ - n_spares[0] = 1; - for (i = 1; i < NCACHED && i <= max_entry; i++) - n_spares[i] = 1 + o_spares[i - 1]; - - /* Replace the unique ID. */ - if ((ret = __os_fileid(dbenv, real_name, 1, newmeta.dbmeta.uid)) != 0) - return (ret); - - /* Overwrite the original. */ - memcpy(oldmeta, &newmeta, sizeof(newmeta)); - - return (0); -} - -/* - * __ham_30_sizefix -- - * Make sure that all hash pages belonging to the current - * hash doubling are within the bounds of the file. - * - * PUBLIC: int __ham_30_sizefix __P((DB *, DB_FH *, char *, u_int8_t *)); - */ -int -__ham_30_sizefix(dbp, fhp, realname, metabuf) - DB *dbp; - DB_FH *fhp; - char *realname; - u_int8_t *metabuf; -{ - u_int8_t buf[DB_MAX_PGSIZE]; - DB_ENV *dbenv; - HMETA30 *meta; - db_pgno_t last_actual, last_desired; - int ret; - size_t nw; - u_int32_t pagesize; - - dbenv = dbp->dbenv; - memset(buf, 0, DB_MAX_PGSIZE); - - meta = (HMETA30 *)metabuf; - pagesize = meta->dbmeta.pagesize; - - /* - * Get the last page number. To do this, we'll need dbp->pgsize - * to be set right, so slam it into place. - */ - dbp->pgsize = pagesize; - if ((ret = __db_lastpgno(dbp, realname, fhp, &last_actual)) != 0) - return (ret); - - /* - * The last bucket in the doubling is equal to high_mask; calculate - * the page number that implies. - */ - last_desired = BS_TO_PAGE(meta->high_mask, meta->spares); - - /* - * If last_desired > last_actual, we need to grow the file. Write - * a zeroed page where last_desired would go. - */ - if (last_desired > last_actual) { - if ((ret = __os_seek(dbenv, - fhp, pagesize, last_desired, 0, 0, DB_OS_SEEK_SET)) != 0) - return (ret); - if ((ret = __os_write(dbenv, fhp, buf, pagesize, &nw)) != 0) - return (ret); - } - - return (0); -} - -/* - * __ham_31_hashmeta -- - * Upgrade the database from version 6 to version 7. - * - * PUBLIC: int __ham_31_hashmeta - * PUBLIC: __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *)); - */ -int -__ham_31_hashmeta(dbp, real_name, flags, fhp, h, dirtyp) - DB *dbp; - char *real_name; - u_int32_t flags; - DB_FH *fhp; - PAGE *h; - int *dirtyp; -{ - HMETA31 *newmeta; - HMETA30 *oldmeta; - - COMPQUIET(dbp, NULL); - COMPQUIET(real_name, NULL); - COMPQUIET(fhp, NULL); - - newmeta = (HMETA31 *)h; - oldmeta = (HMETA30 *)h; - - /* - * Copy the fields down the page. - * The fields may overlap so start at the bottom and use memmove(). - */ - memmove(newmeta->spares, oldmeta->spares, sizeof(oldmeta->spares)); - newmeta->h_charkey = oldmeta->h_charkey; - newmeta->nelem = oldmeta->nelem; - newmeta->ffactor = oldmeta->ffactor; - newmeta->low_mask = oldmeta->low_mask; - newmeta->high_mask = oldmeta->high_mask; - newmeta->max_bucket = oldmeta->max_bucket; - memmove(newmeta->dbmeta.uid, - oldmeta->dbmeta.uid, sizeof(oldmeta->dbmeta.uid)); - newmeta->dbmeta.flags = oldmeta->dbmeta.flags; - newmeta->dbmeta.record_count = 0; - newmeta->dbmeta.key_count = 0; - ZERO_LSN(newmeta->dbmeta.unused3); - - /* Update the version. */ - newmeta->dbmeta.version = 7; - - /* Upgrade the flags. */ - if (LF_ISSET(DB_DUPSORT)) - F_SET(&newmeta->dbmeta, DB_HASH_DUPSORT); - - *dirtyp = 1; - return (0); -} - -/* - * __ham_31_hash -- - * Upgrade the database hash leaf pages. - * - * PUBLIC: int __ham_31_hash - * PUBLIC: __P((DB *, char *, u_int32_t, DB_FH *, PAGE *, int *)); - */ -int -__ham_31_hash(dbp, real_name, flags, fhp, h, dirtyp) - DB *dbp; - char *real_name; - u_int32_t flags; - DB_FH *fhp; - PAGE *h; - int *dirtyp; -{ - HKEYDATA *hk; - db_pgno_t pgno, tpgno; - db_indx_t indx; - int ret; - - COMPQUIET(flags, 0); - - ret = 0; - for (indx = 0; indx < NUM_ENT(h); indx += 2) { - hk = (HKEYDATA *)H_PAIRDATA(dbp, h, indx); - if (HPAGE_PTYPE(hk) == H_OFFDUP) { - memcpy(&pgno, HOFFDUP_PGNO(hk), sizeof(db_pgno_t)); - tpgno = pgno; - if ((ret = __db_31_offdup(dbp, real_name, fhp, - LF_ISSET(DB_DUPSORT) ? 1 : 0, &tpgno)) != 0) - break; - if (pgno != tpgno) { - *dirtyp = 1; - memcpy(HOFFDUP_PGNO(hk), - &tpgno, sizeof(db_pgno_t)); - } - } - } - - return (ret); -} diff --git a/storage/bdb/hash/hash_verify.c b/storage/bdb/hash/hash_verify.c deleted file mode 100644 index de82103430a..00000000000 --- a/storage/bdb/hash/hash_verify.c +++ /dev/null @@ -1,1080 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: hash_verify.c,v 12.8 2005/06/16 20:22:54 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/db_verify.h" -#include "dbinc/btree.h" -#include "dbinc/hash.h" -#include "dbinc/mp.h" - -static int __ham_dups_unsorted __P((DB *, u_int8_t *, u_int32_t)); -static int __ham_vrfy_bucket __P((DB *, VRFY_DBINFO *, HMETA *, u_int32_t, - u_int32_t)); -static int __ham_vrfy_item __P((DB *, - VRFY_DBINFO *, db_pgno_t, PAGE *, u_int32_t, u_int32_t)); - -/* - * __ham_vrfy_meta -- - * Verify the hash-specific part of a metadata page. - * - * Note that unlike btree, we don't save things off, because we - * will need most everything again to verify each page and the - * amount of state here is significant. - * - * PUBLIC: int __ham_vrfy_meta __P((DB *, VRFY_DBINFO *, HMETA *, - * PUBLIC: db_pgno_t, u_int32_t)); - */ -int -__ham_vrfy_meta(dbp, vdp, m, pgno, flags) - DB *dbp; - VRFY_DBINFO *vdp; - HMETA *m; - db_pgno_t pgno; - u_int32_t flags; -{ - HASH *hashp; - VRFY_PAGEINFO *pip; - int i, ret, t_ret, isbad; - u_int32_t pwr, mbucket; - u_int32_t (*hfunc) __P((DB *, const void *, u_int32_t)); - - if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) - return (ret); - isbad = 0; - - hashp = dbp->h_internal; - - if (hashp != NULL && hashp->h_hash != NULL) - hfunc = hashp->h_hash; - else - hfunc = __ham_func5; - - /* - * If we haven't already checked the common fields in pagezero, - * check them. - */ - if (!F_ISSET(pip, VRFY_INCOMPLETE) && - (ret = __db_vrfy_meta(dbp, vdp, &m->dbmeta, pgno, flags)) != 0) { - if (ret == DB_VERIFY_BAD) - isbad = 1; - else - goto err; - } - - /* h_charkey */ - if (!LF_ISSET(DB_NOORDERCHK)) - if (m->h_charkey != hfunc(dbp, CHARKEY, sizeof(CHARKEY))) { - EPRINT((dbp->dbenv, -"Page %lu: database has custom hash function; reverify with DB_NOORDERCHK set", - (u_long)pgno)); - /* - * Return immediately; this is probably a sign of user - * error rather than database corruption, so we want to - * avoid extraneous errors. - */ - isbad = 1; - goto err; - } - - /* max_bucket must be less than the last pgno. */ - if (m->max_bucket > vdp->last_pgno) { - EPRINT((dbp->dbenv, - "Page %lu: Impossible max_bucket %lu on meta page", - (u_long)pgno, (u_long)m->max_bucket)); - /* - * Most other fields depend somehow on max_bucket, so - * we just return--there will be lots of extraneous - * errors. - */ - isbad = 1; - goto err; - } - - /* - * max_bucket, high_mask and low_mask: high_mask must be one - * less than the next power of two above max_bucket, and - * low_mask must be one less than the power of two below it. - */ - pwr = (m->max_bucket == 0) ? 1 : 1 << __db_log2(m->max_bucket + 1); - if (m->high_mask != pwr - 1) { - EPRINT((dbp->dbenv, - "Page %lu: incorrect high_mask %lu, should be %lu", - (u_long)pgno, (u_long)m->high_mask, (u_long)pwr - 1)); - isbad = 1; - } - pwr >>= 1; - if (m->low_mask != pwr - 1) { - EPRINT((dbp->dbenv, - "Page %lu: incorrect low_mask %lu, should be %lu", - (u_long)pgno, (u_long)m->low_mask, (u_long)pwr - 1)); - isbad = 1; - } - - /* ffactor: no check possible. */ - pip->h_ffactor = m->ffactor; - - /* - * nelem: just make sure it's not astronomical for now. This is the - * same check that hash_upgrade does, since there was a bug in 2.X - * which could make nelem go "negative". - */ - if (m->nelem > 0x80000000) { - EPRINT((dbp->dbenv, - "Page %lu: suspiciously high nelem of %lu", - (u_long)pgno, (u_long)m->nelem)); - isbad = 1; - pip->h_nelem = 0; - } else - pip->h_nelem = m->nelem; - - /* flags */ - if (F_ISSET(&m->dbmeta, DB_HASH_DUP)) - F_SET(pip, VRFY_HAS_DUPS); - if (F_ISSET(&m->dbmeta, DB_HASH_DUPSORT)) - F_SET(pip, VRFY_HAS_DUPSORT); - /* XXX: Why is the DB_HASH_SUBDB flag necessary? */ - - /* spares array */ - for (i = 0; m->spares[i] != 0 && i < NCACHED; i++) { - /* - * We set mbucket to the maximum bucket that would use a given - * spares entry; we want to ensure that it's always less - * than last_pgno. - */ - mbucket = (1 << i) - 1; - if (BS_TO_PAGE(mbucket, m->spares) > vdp->last_pgno) { - EPRINT((dbp->dbenv, - "Page %lu: spares array entry %d is invalid", - (u_long)pgno, i)); - isbad = 1; - } - } - -err: if ((t_ret = - __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0 && ret == 0) - ret = t_ret; - if (LF_ISSET(DB_SALVAGE) && - (t_ret = __db_salvage_markdone(vdp, pgno)) != 0 && ret == 0) - ret = t_ret; - return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); -} - -/* - * __ham_vrfy -- - * Verify hash page. - * - * PUBLIC: int __ham_vrfy __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, - * PUBLIC: u_int32_t)); - */ -int -__ham_vrfy(dbp, vdp, h, pgno, flags) - DB *dbp; - VRFY_DBINFO *vdp; - PAGE *h; - db_pgno_t pgno; - u_int32_t flags; -{ - VRFY_PAGEINFO *pip; - u_int32_t ent, himark, inpend; - db_indx_t *inp; - int isbad, ret, t_ret; - - isbad = 0; - if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) - return (ret); - - if (TYPE(h) != P_HASH) { - TYPE_ERR_PRINT(dbp->dbenv, "__ham_vrfy", pgno, TYPE(h)); - DB_ASSERT(0); - ret = EINVAL; - goto err; - } - - /* Verify and save off fields common to all PAGEs. */ - if ((ret = __db_vrfy_datapage(dbp, vdp, h, pgno, flags)) != 0) { - if (ret == DB_VERIFY_BAD) - isbad = 1; - else - goto err; - } - - /* - * Verify inp[]. Each offset from 0 to NUM_ENT(h) must be lower - * than the previous one, higher than the current end of the inp array, - * and lower than the page size. - * - * In any case, we return immediately if things are bad, as it would - * be unsafe to proceed. - */ - inp = P_INP(dbp, h); - for (ent = 0, himark = dbp->pgsize, - inpend = (u_int32_t)((u_int8_t *)inp - (u_int8_t *)h); - ent < NUM_ENT(h); ent++) - if (inp[ent] >= himark) { - EPRINT((dbp->dbenv, - "Page %lu: item %lu is out of order or nonsensical", - (u_long)pgno, (u_long)ent)); - isbad = 1; - goto err; - } else if (inpend >= himark) { - EPRINT((dbp->dbenv, - "Page %lu: entries array collided with data", - (u_long)pgno)); - isbad = 1; - goto err; - - } else { - himark = inp[ent]; - inpend += sizeof(db_indx_t); - if ((ret = __ham_vrfy_item( - dbp, vdp, pgno, h, ent, flags)) != 0) - goto err; - } - -err: if ((t_ret = - __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0 && ret == 0) - ret = t_ret; - return (ret == 0 && isbad == 1 ? DB_VERIFY_BAD : ret); -} - -/* - * __ham_vrfy_item -- - * Given a hash page and an offset, sanity-check the item itself, - * and save off any overflow items or off-page dup children as necessary. - */ -static int -__ham_vrfy_item(dbp, vdp, pgno, h, i, flags) - DB *dbp; - VRFY_DBINFO *vdp; - db_pgno_t pgno; - PAGE *h; - u_int32_t i, flags; -{ - HOFFPAGE hop; - HOFFDUP hod; - VRFY_CHILDINFO child; - VRFY_PAGEINFO *pip; - db_indx_t offset, len, dlen, elen; - int ret, t_ret; - u_int8_t *databuf; - - if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) - return (ret); - - switch (HPAGE_TYPE(dbp, h, i)) { - case H_KEYDATA: - /* Nothing to do here--everything but the type field is data */ - break; - case H_DUPLICATE: - /* Are we a datum or a key? Better be the former. */ - if (i % 2 == 0) { - EPRINT((dbp->dbenv, - "Page %lu: hash key stored as duplicate item %lu", - (u_long)pip->pgno, (u_long)i)); - } - /* - * Dups are encoded as a series within a single HKEYDATA, - * in which each dup is surrounded by a copy of its length - * on either side (so that the series can be walked in either - * direction. We loop through this series and make sure - * each dup is reasonable. - * - * Note that at this point, we've verified item i-1, so - * it's safe to use LEN_HKEYDATA (which looks at inp[i-1]). - */ - len = LEN_HKEYDATA(dbp, h, dbp->pgsize, i); - databuf = HKEYDATA_DATA(P_ENTRY(dbp, h, i)); - for (offset = 0; offset < len; offset += DUP_SIZE(dlen)) { - memcpy(&dlen, databuf + offset, sizeof(db_indx_t)); - - /* Make sure the length is plausible. */ - if (offset + DUP_SIZE(dlen) > len) { - EPRINT((dbp->dbenv, - "Page %lu: duplicate item %lu has bad length", - (u_long)pip->pgno, (u_long)i)); - ret = DB_VERIFY_BAD; - goto err; - } - - /* - * Make sure the second copy of the length is the - * same as the first. - */ - memcpy(&elen, - databuf + offset + dlen + sizeof(db_indx_t), - sizeof(db_indx_t)); - if (elen != dlen) { - EPRINT((dbp->dbenv, - "Page %lu: duplicate item %lu has two different lengths", - (u_long)pip->pgno, (u_long)i)); - ret = DB_VERIFY_BAD; - goto err; - } - } - F_SET(pip, VRFY_HAS_DUPS); - if (!LF_ISSET(DB_NOORDERCHK) && - __ham_dups_unsorted(dbp, databuf, len)) - F_SET(pip, VRFY_DUPS_UNSORTED); - break; - case H_OFFPAGE: - /* Offpage item. Make sure pgno is sane, save off. */ - memcpy(&hop, P_ENTRY(dbp, h, i), HOFFPAGE_SIZE); - if (!IS_VALID_PGNO(hop.pgno) || hop.pgno == pip->pgno || - hop.pgno == PGNO_INVALID) { - EPRINT((dbp->dbenv, - "Page %lu: offpage item %lu has bad pgno %lu", - (u_long)pip->pgno, (u_long)i, (u_long)hop.pgno)); - ret = DB_VERIFY_BAD; - goto err; - } - memset(&child, 0, sizeof(VRFY_CHILDINFO)); - child.pgno = hop.pgno; - child.type = V_OVERFLOW; - child.tlen = hop.tlen; /* This will get checked later. */ - if ((ret = __db_vrfy_childput(vdp, pip->pgno, &child)) != 0) - goto err; - break; - case H_OFFDUP: - /* Offpage duplicate item. Same drill. */ - memcpy(&hod, P_ENTRY(dbp, h, i), HOFFDUP_SIZE); - if (!IS_VALID_PGNO(hod.pgno) || hod.pgno == pip->pgno || - hod.pgno == PGNO_INVALID) { - EPRINT((dbp->dbenv, - "Page %lu: offpage item %lu has bad page number", - (u_long)pip->pgno, (u_long)i)); - ret = DB_VERIFY_BAD; - goto err; - } - memset(&child, 0, sizeof(VRFY_CHILDINFO)); - child.pgno = hod.pgno; - child.type = V_DUPLICATE; - if ((ret = __db_vrfy_childput(vdp, pip->pgno, &child)) != 0) - goto err; - F_SET(pip, VRFY_HAS_DUPS); - break; - default: - EPRINT((dbp->dbenv, - "Page %lu: item %lu has bad type", - (u_long)pip->pgno, (u_long)i)); - ret = DB_VERIFY_BAD; - break; - } - -err: if ((t_ret = - __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0 && ret == 0) - ret = t_ret; - return (ret); -} - -/* - * __ham_vrfy_structure -- - * Verify the structure of a hash database. - * - * PUBLIC: int __ham_vrfy_structure __P((DB *, VRFY_DBINFO *, db_pgno_t, - * PUBLIC: u_int32_t)); - */ -int -__ham_vrfy_structure(dbp, vdp, meta_pgno, flags) - DB *dbp; - VRFY_DBINFO *vdp; - db_pgno_t meta_pgno; - u_int32_t flags; -{ - DB *pgset; - DB_MPOOLFILE *mpf; - HMETA *m; - PAGE *h; - VRFY_PAGEINFO *pip; - int isbad, p, ret, t_ret; - db_pgno_t pgno; - u_int32_t bucket, spares_entry; - - mpf = dbp->mpf; - pgset = vdp->pgset; - h = NULL; - ret = isbad = 0; - - if ((ret = __db_vrfy_pgset_get(pgset, meta_pgno, &p)) != 0) - return (ret); - if (p != 0) { - EPRINT((dbp->dbenv, - "Page %lu: Hash meta page referenced twice", - (u_long)meta_pgno)); - return (DB_VERIFY_BAD); - } - if ((ret = __db_vrfy_pgset_inc(pgset, meta_pgno)) != 0) - return (ret); - - /* Get the meta page; we'll need it frequently. */ - if ((ret = __memp_fget(mpf, &meta_pgno, 0, &m)) != 0) - return (ret); - - /* Loop through bucket by bucket. */ - for (bucket = 0; bucket <= m->max_bucket; bucket++) - if ((ret = - __ham_vrfy_bucket(dbp, vdp, m, bucket, flags)) != 0) { - if (ret == DB_VERIFY_BAD) - isbad = 1; - else - goto err; - } - - /* - * There may be unused hash pages corresponding to buckets - * that have been allocated but not yet used. These may be - * part of the current doubling above max_bucket, or they may - * correspond to buckets that were used in a transaction - * that then aborted. - * - * Loop through them, as far as the spares array defines them, - * and make sure they're all empty. - * - * Note that this should be safe, since we've already verified - * that the spares array is sane. - */ - for (bucket = m->max_bucket + 1; spares_entry = __db_log2(bucket + 1), - spares_entry < NCACHED && m->spares[spares_entry] != 0; bucket++) { - pgno = BS_TO_PAGE(bucket, m->spares); - if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) - goto err; - - /* It's okay if these pages are totally zeroed; unmark it. */ - F_CLR(pip, VRFY_IS_ALLZEROES); - - /* It's also OK if this page is simply invalid. */ - if (pip->type == P_INVALID) { - if ((ret = __db_vrfy_putpageinfo(dbp->dbenv, - vdp, pip)) != 0) - goto err; - continue; - } - - if (pip->type != P_HASH) { - EPRINT((dbp->dbenv, - "Page %lu: hash bucket %lu maps to non-hash page", - (u_long)pgno, (u_long)bucket)); - isbad = 1; - } else if (pip->entries != 0) { - EPRINT((dbp->dbenv, - "Page %lu: non-empty page in unused hash bucket %lu", - (u_long)pgno, (u_long)bucket)); - isbad = 1; - } else { - if ((ret = __db_vrfy_pgset_get(pgset, pgno, &p)) != 0) - goto err; - if (p != 0) { - EPRINT((dbp->dbenv, - "Page %lu: above max_bucket referenced", - (u_long)pgno)); - isbad = 1; - } else { - if ((ret = - __db_vrfy_pgset_inc(pgset, pgno)) != 0) - goto err; - if ((ret = __db_vrfy_putpageinfo(dbp->dbenv, - vdp, pip)) != 0) - goto err; - continue; - } - } - - /* If we got here, it's an error. */ - (void)__db_vrfy_putpageinfo(dbp->dbenv, vdp, pip); - goto err; - } - -err: if ((t_ret = __memp_fput(mpf, m, 0)) != 0) - return (t_ret); - if (h != NULL && (t_ret = __memp_fput(mpf, h, 0)) != 0) - return (t_ret); - return ((isbad == 1 && ret == 0) ? DB_VERIFY_BAD: ret); -} - -/* - * __ham_vrfy_bucket -- - * Verify a given bucket. - */ -static int -__ham_vrfy_bucket(dbp, vdp, m, bucket, flags) - DB *dbp; - VRFY_DBINFO *vdp; - HMETA *m; - u_int32_t bucket, flags; -{ - HASH *hashp; - VRFY_CHILDINFO *child; - VRFY_PAGEINFO *mip, *pip; - int ret, t_ret, isbad, p; - db_pgno_t pgno, next_pgno; - DBC *cc; - u_int32_t (*hfunc) __P((DB *, const void *, u_int32_t)); - - isbad = 0; - pip = NULL; - cc = NULL; - - hashp = dbp->h_internal; - if (hashp != NULL && hashp->h_hash != NULL) - hfunc = hashp->h_hash; - else - hfunc = __ham_func5; - - if ((ret = __db_vrfy_getpageinfo(vdp, PGNO(m), &mip)) != 0) - return (ret); - - /* Calculate the first pgno for this bucket. */ - pgno = BS_TO_PAGE(bucket, m->spares); - - if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) - goto err; - - /* Make sure we got a plausible page number. */ - if (pgno > vdp->last_pgno || pip->type != P_HASH) { - EPRINT((dbp->dbenv, - "Page %lu: impossible first page in bucket %lu", - (u_long)pgno, (u_long)bucket)); - /* Unsafe to continue. */ - isbad = 1; - goto err; - } - - if (pip->prev_pgno != PGNO_INVALID) { - EPRINT((dbp->dbenv, - "Page %lu: first page in hash bucket %lu has a prev_pgno", - (u_long)pgno, (u_long)bucket)); - isbad = 1; - } - - /* - * Set flags for dups and sorted dups. - */ - flags |= F_ISSET(mip, VRFY_HAS_DUPS) ? ST_DUPOK : 0; - flags |= F_ISSET(mip, VRFY_HAS_DUPSORT) ? ST_DUPSORT : 0; - - /* Loop until we find a fatal bug, or until we run out of pages. */ - for (;;) { - /* Provide feedback on our progress to the application. */ - if (!LF_ISSET(DB_SALVAGE)) - __db_vrfy_struct_feedback(dbp, vdp); - - if ((ret = __db_vrfy_pgset_get(vdp->pgset, pgno, &p)) != 0) - goto err; - if (p != 0) { - EPRINT((dbp->dbenv, - "Page %lu: hash page referenced twice", - (u_long)pgno)); - isbad = 1; - /* Unsafe to continue. */ - goto err; - } else if ((ret = __db_vrfy_pgset_inc(vdp->pgset, pgno)) != 0) - goto err; - - /* - * Hash pages that nothing has ever hashed to may never - * have actually come into existence, and may appear to be - * entirely zeroed. This is acceptable, and since there's - * no real way for us to know whether this has actually - * occurred, we clear the "wholly zeroed" flag on every - * hash page. A wholly zeroed page, by nature, will appear - * to have no flags set and zero entries, so should - * otherwise verify correctly. - */ - F_CLR(pip, VRFY_IS_ALLZEROES); - - /* If we have dups, our meta page had better know about it. */ - if (F_ISSET(pip, VRFY_HAS_DUPS) && - !F_ISSET(mip, VRFY_HAS_DUPS)) { - EPRINT((dbp->dbenv, - "Page %lu: duplicates present in non-duplicate database", - (u_long)pgno)); - isbad = 1; - } - - /* - * If the database has sorted dups, this page had better - * not have unsorted ones. - */ - if (F_ISSET(mip, VRFY_HAS_DUPSORT) && - F_ISSET(pip, VRFY_DUPS_UNSORTED)) { - EPRINT((dbp->dbenv, - "Page %lu: unsorted dups in sorted-dup database", - (u_long)pgno)); - isbad = 1; - } - - /* Walk overflow chains and offpage dup trees. */ - if ((ret = __db_vrfy_childcursor(vdp, &cc)) != 0) - goto err; - for (ret = __db_vrfy_ccset(cc, pip->pgno, &child); ret == 0; - ret = __db_vrfy_ccnext(cc, &child)) - if (child->type == V_OVERFLOW) { - if ((ret = __db_vrfy_ovfl_structure(dbp, vdp, - child->pgno, child->tlen, - flags | ST_OVFL_LEAF)) != 0) { - if (ret == DB_VERIFY_BAD) - isbad = 1; - else - goto err; - } - } else if (child->type == V_DUPLICATE) { - if ((ret = __db_vrfy_duptype(dbp, - vdp, child->pgno, flags)) != 0) { - isbad = 1; - continue; - } - if ((ret = __bam_vrfy_subtree(dbp, vdp, - child->pgno, NULL, NULL, - flags | ST_RECNUM | ST_DUPSET | ST_TOPLEVEL, - NULL, NULL, NULL)) != 0) { - if (ret == DB_VERIFY_BAD) - isbad = 1; - else - goto err; - } - } - if ((ret = __db_vrfy_ccclose(cc)) != 0) - goto err; - cc = NULL; - - /* If it's safe to check that things hash properly, do so. */ - if (isbad == 0 && !LF_ISSET(DB_NOORDERCHK) && - (ret = __ham_vrfy_hashing(dbp, pip->entries, - m, bucket, pgno, flags, hfunc)) != 0) { - if (ret == DB_VERIFY_BAD) - isbad = 1; - else - goto err; - } - - next_pgno = pip->next_pgno; - ret = __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip); - - pip = NULL; - if (ret != 0) - goto err; - - if (next_pgno == PGNO_INVALID) - break; /* End of the bucket. */ - - /* We already checked this, but just in case... */ - if (!IS_VALID_PGNO(next_pgno)) { - DB_ASSERT(0); - EPRINT((dbp->dbenv, - "Page %lu: hash page has bad next_pgno", - (u_long)pgno)); - isbad = 1; - goto err; - } - - if ((ret = __db_vrfy_getpageinfo(vdp, next_pgno, &pip)) != 0) - goto err; - - if (pip->prev_pgno != pgno) { - EPRINT((dbp->dbenv, - "Page %lu: hash page has bad prev_pgno", - (u_long)next_pgno)); - isbad = 1; - } - pgno = next_pgno; - } - -err: if (cc != NULL && ((t_ret = __db_vrfy_ccclose(cc)) != 0) && ret == 0) - ret = t_ret; - if (mip != NULL && ((t_ret = - __db_vrfy_putpageinfo(dbp->dbenv, vdp, mip)) != 0) && ret == 0) - ret = t_ret; - if (pip != NULL && ((t_ret = - __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0) && ret == 0) - ret = t_ret; - return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); -} - -/* - * __ham_vrfy_hashing -- - * Verify that all items on a given hash page hash correctly. - * - * PUBLIC: int __ham_vrfy_hashing __P((DB *, - * PUBLIC: u_int32_t, HMETA *, u_int32_t, db_pgno_t, u_int32_t, - * PUBLIC: u_int32_t (*) __P((DB *, const void *, u_int32_t)))); - */ -int -__ham_vrfy_hashing(dbp, nentries, m, thisbucket, pgno, flags, hfunc) - DB *dbp; - u_int32_t nentries; - HMETA *m; - u_int32_t thisbucket; - db_pgno_t pgno; - u_int32_t flags; - u_int32_t (*hfunc) __P((DB *, const void *, u_int32_t)); -{ - DBT dbt; - DB_MPOOLFILE *mpf; - PAGE *h; - db_indx_t i; - int ret, t_ret, isbad; - u_int32_t hval, bucket; - - mpf = dbp->mpf; - ret = isbad = 0; - - memset(&dbt, 0, sizeof(DBT)); - F_SET(&dbt, DB_DBT_REALLOC); - - if ((ret = __memp_fget(mpf, &pgno, 0, &h)) != 0) - return (ret); - - for (i = 0; i < nentries; i += 2) { - /* - * We've already verified the page integrity and that of any - * overflow chains linked off it; it is therefore safe to use - * __db_ret. It's also not all that much slower, since we have - * to copy every hash item to deal with alignment anyway; we - * can tweak this a bit if this proves to be a bottleneck, - * but for now, take the easy route. - */ - if ((ret = __db_ret(dbp, h, i, &dbt, NULL, NULL)) != 0) - goto err; - hval = hfunc(dbp, dbt.data, dbt.size); - - bucket = hval & m->high_mask; - if (bucket > m->max_bucket) - bucket = bucket & m->low_mask; - - if (bucket != thisbucket) { - EPRINT((dbp->dbenv, - "Page %lu: item %lu hashes incorrectly", - (u_long)pgno, (u_long)i)); - isbad = 1; - } - } - -err: if (dbt.data != NULL) - __os_ufree(dbp->dbenv, dbt.data); - if ((t_ret = __memp_fput(mpf, h, 0)) != 0) - return (t_ret); - - return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); -} - -/* - * __ham_salvage -- - * Safely dump out anything that looks like a key on an alleged - * hash page. - * - * PUBLIC: int __ham_salvage __P((DB *, VRFY_DBINFO *, db_pgno_t, PAGE *, - * PUBLIC: void *, int (*)(void *, const void *), u_int32_t)); - */ -int -__ham_salvage(dbp, vdp, pgno, h, handle, callback, flags) - DB *dbp; - VRFY_DBINFO *vdp; - db_pgno_t pgno; - PAGE *h; - void *handle; - int (*callback) __P((void *, const void *)); - u_int32_t flags; -{ - DBT dbt, unkdbt; - db_pgno_t dpgno; - int ret, err_ret, t_ret; - u_int32_t himark, i; - u_int8_t *hk, *p; - void *buf; - db_indx_t dlen, len, tlen; - - memset(&dbt, 0, sizeof(DBT)); - dbt.flags = DB_DBT_REALLOC; - - memset(&unkdbt, 0, sizeof(DBT)); - unkdbt.size = (u_int32_t)strlen("UNKNOWN") + 1; - unkdbt.data = "UNKNOWN"; - - err_ret = 0; - - /* - * Allocate a buffer for overflow items. Start at one page; - * __db_safe_goff will realloc as needed. - */ - if ((ret = __os_malloc(dbp->dbenv, dbp->pgsize, &buf)) != 0) - return (ret); - - himark = dbp->pgsize; - for (i = 0;; i++) { - /* If we're not aggressive, break when we hit NUM_ENT(h). */ - if (!LF_ISSET(DB_AGGRESSIVE) && i >= NUM_ENT(h)) - break; - - /* Verify the current item. */ - ret = __db_vrfy_inpitem(dbp, - h, pgno, i, 0, flags, &himark, NULL); - /* If this returned a fatality, it's time to break. */ - if (ret == DB_VERIFY_FATAL) - break; - - if (ret == 0) { - /* Set len to total entry length. */ - len = LEN_HITEM(dbp, h, dbp->pgsize, i); - hk = P_ENTRY(dbp, h, i); - if (len == 0 || len > dbp->pgsize || - (u_int32_t)(hk + len - (u_int8_t *)h) > - dbp->pgsize) { - /* Item is unsafely large; skip it. */ - err_ret = DB_VERIFY_BAD; - continue; - } - switch (HPAGE_PTYPE(hk)) { - default: - if (!LF_ISSET(DB_AGGRESSIVE)) - break; - err_ret = DB_VERIFY_BAD; - break; - case H_KEYDATA: - /* Update len to size of item. */ - len = LEN_HKEYDATA(dbp, h, dbp->pgsize, i); -keydata: memcpy(buf, HKEYDATA_DATA(hk), len); - dbt.size = len; - dbt.data = buf; - if ((ret = __db_vrfy_prdbt(&dbt, - 0, " ", handle, callback, 0, vdp)) != 0) - err_ret = ret; - break; - case H_OFFPAGE: - if (len < HOFFPAGE_SIZE) { - err_ret = DB_VERIFY_BAD; - continue; - } - memcpy(&dpgno, - HOFFPAGE_PGNO(hk), sizeof(dpgno)); - if ((ret = __db_safe_goff(dbp, vdp, - dpgno, &dbt, &buf, flags)) != 0) { - err_ret = ret; - (void)__db_vrfy_prdbt(&unkdbt, 0, " ", - handle, callback, 0, vdp); - break; - } - if ((ret = __db_vrfy_prdbt(&dbt, - 0, " ", handle, callback, 0, vdp)) != 0) - err_ret = ret; - break; - case H_OFFDUP: - if (len < HOFFDUP_SIZE) { - err_ret = DB_VERIFY_BAD; - continue; - } - memcpy(&dpgno, - HOFFDUP_PGNO(hk), sizeof(dpgno)); - /* UNKNOWN iff pgno is bad or we're a key. */ - if (!IS_VALID_PGNO(dpgno) || (i % 2 == 0)) { - if ((ret = - __db_vrfy_prdbt(&unkdbt, 0, " ", - handle, callback, 0, vdp)) != 0) - err_ret = ret; - } else if ((ret = __db_salvage_duptree(dbp, - vdp, dpgno, &dbt, handle, callback, - flags | SA_SKIPFIRSTKEY)) != 0) - err_ret = ret; - break; - case H_DUPLICATE: - len = LEN_HKEYDATA(dbp, h, dbp->pgsize, i); - /* - * We're a key; printing dups will seriously - * foul the output. If we're being aggressive, - * pretend this is a key and let the app. - * programmer sort out the mess. - */ - if (i % 2 == 0) { - err_ret = ret; - if (LF_ISSET(DB_AGGRESSIVE)) - goto keydata; - break; - } - - /* - * Check if too small to have any data. - * But first, we have to update the len to - * reflect the size of the data not the - * size of the on-page entry. - */ - if (len < - HKEYDATA_SIZE(2 * sizeof(db_indx_t))) { - err_ret = DB_VERIFY_BAD; - continue; - } - - /* Loop until we hit the total length. */ - for (tlen = 0; tlen + sizeof(db_indx_t) < len; - tlen += dlen) { - p = HKEYDATA_DATA(hk) + tlen; - tlen += sizeof(db_indx_t); - memcpy(&dlen, p, sizeof(db_indx_t)); - p += sizeof(db_indx_t); - /* - * If dlen is too long, print all the - * rest of the dup set in a chunk. - */ - if (dlen + tlen > len) - dlen = len - tlen; - memcpy(buf, p, dlen); - dbt.size = dlen; - dbt.data = buf; - if ((ret = __db_vrfy_prdbt(&dbt, 0, " ", - handle, callback, 0, vdp)) != 0) - err_ret = ret; - tlen += sizeof(db_indx_t); - } - break; - } - } - } - - __os_free(dbp->dbenv, buf); - if ((t_ret = __db_salvage_markdone(vdp, pgno)) != 0) - return (t_ret); - return ((ret == 0 && err_ret != 0) ? err_ret : ret); -} - -/* - * __ham_meta2pgset -- - * Return the set of hash pages corresponding to the given - * known-good meta page. - * - * PUBLIC: int __ham_meta2pgset __P((DB *, VRFY_DBINFO *, HMETA *, u_int32_t, - * PUBLIC: DB *)); - */ -int __ham_meta2pgset(dbp, vdp, hmeta, flags, pgset) - DB *dbp; - VRFY_DBINFO *vdp; - HMETA *hmeta; - u_int32_t flags; - DB *pgset; -{ - DB_MPOOLFILE *mpf; - PAGE *h; - db_pgno_t pgno; - u_int32_t bucket, totpgs; - int ret, val; - - /* - * We don't really need flags, but leave them for consistency with - * __bam_meta2pgset. - */ - COMPQUIET(flags, 0); - - DB_ASSERT(pgset != NULL); - - mpf = dbp->mpf; - totpgs = 0; - - /* - * Loop through all the buckets, pushing onto pgset the corresponding - * page(s) for each one. - */ - for (bucket = 0; bucket <= hmeta->max_bucket; bucket++) { - pgno = BS_TO_PAGE(bucket, hmeta->spares); - - /* - * We know the initial pgno is safe because the spares array has - * been verified. - * - * Safely walk the list of pages in this bucket. - */ - for (;;) { - if ((ret = __memp_fget(mpf, &pgno, 0, &h)) != 0) - return (ret); - if (TYPE(h) == P_HASH) { - - /* - * Make sure we don't go past the end of - * pgset. - */ - if (++totpgs > vdp->last_pgno) { - (void)__memp_fput(mpf, h, 0); - return (DB_VERIFY_BAD); - } - if ((ret = - __db_vrfy_pgset_inc(pgset, pgno)) != 0) { - (void)__memp_fput(mpf, h, 0); - return (ret); - } - - pgno = NEXT_PGNO(h); - } else - pgno = PGNO_INVALID; - - if ((ret = __memp_fput(mpf, h, 0)) != 0) - return (ret); - - /* If the new pgno is wonky, go onto the next bucket. */ - if (!IS_VALID_PGNO(pgno) || - pgno == PGNO_INVALID) - break; - - /* - * If we've touched this page before, we have a cycle; - * go on to the next bucket. - */ - if ((ret = __db_vrfy_pgset_get(pgset, pgno, &val)) != 0) - return (ret); - if (val != 0) - break; - } - } - return (0); -} - -/* - * __ham_dups_unsorted -- - * Takes a known-safe hash duplicate set and its total length. - * Returns 1 if there are out-of-order duplicates in this set, - * 0 if there are not. - */ -static int -__ham_dups_unsorted(dbp, buf, len) - DB *dbp; - u_int8_t *buf; - u_int32_t len; -{ - DBT a, b; - db_indx_t offset, dlen; - int (*func) __P((DB *, const DBT *, const DBT *)); - - memset(&a, 0, sizeof(DBT)); - memset(&b, 0, sizeof(DBT)); - - func = (dbp->dup_compare == NULL) ? __bam_defcmp : dbp->dup_compare; - - /* - * Loop through the dup set until we hit the end or we find - * a pair of dups that's out of order. b is always the current - * dup, a the one before it. - */ - for (offset = 0; offset < len; offset += DUP_SIZE(dlen)) { - memcpy(&dlen, buf + offset, sizeof(db_indx_t)); - b.data = buf + offset + sizeof(db_indx_t); - b.size = dlen; - - if (a.data != NULL && func(dbp, &a, &b) > 0) - return (1); - - a.data = b.data; - a.size = b.size; - } - - return (0); -} diff --git a/storage/bdb/hmac/hmac.c b/storage/bdb/hmac/hmac.c deleted file mode 100644 index b2874f74ee8..00000000000 --- a/storage/bdb/hmac/hmac.c +++ /dev/null @@ -1,205 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2001-2005 - * Sleepycat Software. All rights reserved. - * - * Some parts of this code originally written by Adam Stubblefield, - * -- astubble@rice.edu. - * - * $Id: hmac.c,v 12.1 2005/06/16 20:22:55 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/crypto.h" -#include "dbinc/db_page.h" /* for hash.h only */ -#include "dbinc/hash.h" -#include "dbinc/hmac.h" - -#define HMAC_OUTPUT_SIZE 20 -#define HMAC_BLOCK_SIZE 64 - -static void __db_hmac __P((u_int8_t *, u_int8_t *, size_t, u_int8_t *)); - -/* - * !!! - * All of these functions use a ctx structure on the stack. The __db_SHA1Init - * call does not initialize the 64-byte buffer portion of it. The - * underlying SHA1 functions will properly pad the buffer if the data length - * is less than 64-bytes, so there isn't a chance of reading uninitialized - * memory. Although it would be cleaner to do a memset(ctx.buffer, 0, 64) - * we do not want to incur that penalty if we don't have to for performance. - */ - -/* - * __db_hmac -- - * Do a hashed MAC. - */ -static void -__db_hmac(k, data, data_len, mac) - u_int8_t *k, *data, *mac; - size_t data_len; -{ - SHA1_CTX ctx; - u_int8_t key[HMAC_BLOCK_SIZE]; - u_int8_t ipad[HMAC_BLOCK_SIZE]; - u_int8_t opad[HMAC_BLOCK_SIZE]; - u_int8_t tmp[HMAC_OUTPUT_SIZE]; - int i; - - memset(key, 0x00, HMAC_BLOCK_SIZE); - memset(ipad, 0x36, HMAC_BLOCK_SIZE); - memset(opad, 0x5C, HMAC_BLOCK_SIZE); - - memcpy(key, k, HMAC_OUTPUT_SIZE); - - for (i = 0; i < HMAC_BLOCK_SIZE; i++) { - ipad[i] ^= key[i]; - opad[i] ^= key[i]; - } - - __db_SHA1Init(&ctx); - __db_SHA1Update(&ctx, ipad, HMAC_BLOCK_SIZE); - __db_SHA1Update(&ctx, data, data_len); - __db_SHA1Final(tmp, &ctx); - __db_SHA1Init(&ctx); - __db_SHA1Update(&ctx, opad, HMAC_BLOCK_SIZE); - __db_SHA1Update(&ctx, tmp, HMAC_OUTPUT_SIZE); - __db_SHA1Final(mac, &ctx); - return; -} - -/* - * __db_chksum -- - * Create a MAC/SHA1 checksum. - * - * PUBLIC: void __db_chksum __P((u_int8_t *, size_t, u_int8_t *, u_int8_t *)); - */ -void -__db_chksum(data, data_len, mac_key, store) - u_int8_t *data; - size_t data_len; - u_int8_t *mac_key; - u_int8_t *store; -{ - int sumlen; - u_int32_t hash4; - u_int8_t tmp[DB_MAC_KEY]; - - /* - * Since the checksum might be on a page of data we are checksumming - * we might be overwriting after checksumming, we zero-out the - * checksum value so that we can have a known value there when - * we verify the checksum. - */ - if (mac_key == NULL) - sumlen = sizeof(u_int32_t); - else - sumlen = DB_MAC_KEY; - memset(store, 0, sumlen); - if (mac_key == NULL) { - /* Just a hash, no MAC */ - hash4 = __ham_func4(NULL, data, (u_int32_t)data_len); - memcpy(store, &hash4, sumlen); - } else { - memset(tmp, 0, DB_MAC_KEY); - __db_hmac(mac_key, data, data_len, tmp); - memcpy(store, tmp, sumlen); - } - return; -} -/* - * __db_derive_mac -- - * Create a MAC/SHA1 key. - * - * PUBLIC: void __db_derive_mac __P((u_int8_t *, size_t, u_int8_t *)); - */ -void -__db_derive_mac(passwd, plen, mac_key) - u_int8_t *passwd; - size_t plen; - u_int8_t *mac_key; -{ - SHA1_CTX ctx; - - /* Compute the MAC key. mac_key must be 20 bytes. */ - __db_SHA1Init(&ctx); - __db_SHA1Update(&ctx, passwd, plen); - __db_SHA1Update(&ctx, (u_int8_t *)DB_MAC_MAGIC, strlen(DB_MAC_MAGIC)); - __db_SHA1Update(&ctx, passwd, plen); - __db_SHA1Final(mac_key, &ctx); - - return; -} - -/* - * __db_check_chksum -- - * Verify a checksum. - * - * Return 0 on success, >0 (errno) on error, -1 on checksum mismatch. - * - * PUBLIC: int __db_check_chksum __P((DB_ENV *, - * PUBLIC: DB_CIPHER *, u_int8_t *, void *, size_t, int)); - */ -int -__db_check_chksum(dbenv, db_cipher, chksum, data, data_len, is_hmac) - DB_ENV *dbenv; - DB_CIPHER *db_cipher; - u_int8_t *chksum; - void *data; - size_t data_len; - int is_hmac; -{ - int ret; - size_t sum_len; - u_int32_t hash4; - u_int8_t *mac_key, old[DB_MAC_KEY], new[DB_MAC_KEY]; - - /* - * If we are just doing checksumming and not encryption, then checksum - * is 4 bytes. Otherwise, it is DB_MAC_KEY size. Check for illegal - * combinations of crypto/non-crypto checksums. - */ - if (is_hmac == 0) { - if (db_cipher != NULL) { - __db_err(dbenv, - "Unencrypted checksum with a supplied encryption key"); - return (EINVAL); - } - sum_len = sizeof(u_int32_t); - mac_key = NULL; - } else { - if (db_cipher == NULL) { - __db_err(dbenv, - "Encrypted checksum: no encryption key specified"); - return (EINVAL); - } - sum_len = DB_MAC_KEY; - mac_key = db_cipher->mac_key; - } - - /* - * !!! - * Since the checksum might be on the page, we need to have known data - * there so that we can generate the same original checksum. We zero - * it out, just like we do in __db_chksum above. - */ - memcpy(old, chksum, sum_len); - memset(chksum, 0, sum_len); - if (mac_key == NULL) { - /* Just a hash, no MAC */ - hash4 = __ham_func4(NULL, data, (u_int32_t)data_len); - ret = memcmp((u_int32_t *)old, &hash4, sum_len) ? -1 : 0; - } else { - __db_hmac(mac_key, data, data_len, new); - ret = memcmp(old, new, sum_len) ? -1 : 0; - } - - return (ret); -} diff --git a/storage/bdb/hmac/sha1.c b/storage/bdb/hmac/sha1.c deleted file mode 100644 index 839b97b8355..00000000000 --- a/storage/bdb/hmac/sha1.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * $Id: sha1.c,v 12.0 2004/11/17 03:43:56 bostic Exp $ - */ - -#include "db_config.h" - -/* -SHA-1 in C -By Steve Reid <sreid@sea-to-sky.net> -100% Public Domain - ------------------ -Modified 7/98 -By James H. Brown <jbrown@burgoyne.com> -Still 100% Public Domain - -Corrected a problem which generated improper hash values on 16 bit machines -Routine SHA1Update changed from - void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int -len) -to - void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned -long len) - -The 'len' parameter was declared an int which works fine on 32 bit machines. -However, on 16 bit machines an int is too small for the shifts being done -against -it. This caused the hash function to generate incorrect values if len was -greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update(). - -Since the file IO in main() reads 16K at a time, any file 8K or larger would -be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million -"a"s). - -I also changed the declaration of variables i & j in SHA1Update to -unsigned long from unsigned int for the same reason. - -These changes should make no difference to any 32 bit implementations since -an -int and a long are the same size in those environments. - --- -I also corrected a few compiler warnings generated by Borland C. -1. Added #include <process.h> for exit() prototype -2. Removed unused variable 'j' in SHA1Final -3. Changed exit(0) to return(0) at end of main. - -ALL changes I made can be located by searching for comments containing 'JHB' ------------------ -Modified 8/98 -By Steve Reid <sreid@sea-to-sky.net> -Still 100% public domain - -1- Removed #include <process.h> and used return() instead of exit() -2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall) -3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net - ------------------ -Modified 4/01 -By Saul Kravitz <Saul.Kravitz@celera.com> -Still 100% PD -Modified to run on Compaq Alpha hardware. - - -*/ - -/* -Test Vectors (from FIPS PUB 180-1) -"abc" - A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D -"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" - 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 -A million repetitions of "a" - 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F -*/ - -#define SHA1HANDSOFF - -#ifndef NO_SYSTEM_INCLUDES -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/hmac.h" - -/* #include <process.h> */ /* prototype for exit() - JHB */ -/* Using return() instead of exit() - SWR */ - -#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) - -/* blk0() and blk() perform the initial expand. */ -/* I got the idea of expanding during the round function from SSLeay */ -#define blk0(i) is_bigendian ? block->l[i] : \ - (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ - |(rol(block->l[i],8)&0x00FF00FF)) -#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ - ^block->l[(i+2)&15]^block->l[i&15],1)) - -/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ -#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); -#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); -#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); -#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); -#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); - - -#ifdef VERBOSE /* SAK */ -static void __db_SHAPrintContext __P((SHA1_CTX *, char *)); -static void -__db_SHAPrintContext(context, msg) - SHA1_CTX *context; - char *msg; -{ - printf("%s (%d,%d) %x %x %x %x %x\n", - msg, - context->count[0], context->count[1], - context->state[0], - context->state[1], - context->state[2], - context->state[3], - context->state[4]); -} -#endif - -/* Hash a single 512-bit block. This is the core of the algorithm. */ - -/* - * __db_SHA1Transform -- - * - * PUBLIC: void __db_SHA1Transform __P((u_int32_t *, unsigned char *)); - */ -void -__db_SHA1Transform(state, buffer) - u_int32_t *state; - unsigned char *buffer; -{ -u_int32_t a, b, c, d, e; -typedef union { - unsigned char c[64]; - u_int32_t l[16]; -} CHAR64LONG16; -CHAR64LONG16* block; -static int is_bigendian = -1; -#ifdef SHA1HANDSOFF - unsigned char workspace[64]; - - block = (CHAR64LONG16*)workspace; - memcpy(block, buffer, 64); -#else - block = (CHAR64LONG16*)buffer; -#endif - if (is_bigendian == -1) - is_bigendian = __db_isbigendian(); - /* Copy context->state[] to working vars */ - a = state[0]; - b = state[1]; - c = state[2]; - d = state[3]; - e = state[4]; - /* 4 rounds of 20 operations each. Loop unrolled. */ - R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); - R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); - R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); - R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); - R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); - R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); - R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); - R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); - R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); - R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); - R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); - R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); - R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); - R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); - R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); - R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); - R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); - R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); - R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); - R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); - /* Add the working vars back into context.state[] */ - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - state[4] += e; - /* Wipe variables */ - a = b = c = d = e = 0; -} - - -/* SHA1Init - Initialize new context */ - -/* - * __db_SHA1Init -- - * Initialize new context - * - * PUBLIC: void __db_SHA1Init __P((SHA1_CTX *)); - */ -void -__db_SHA1Init(context) - SHA1_CTX *context; -{ - /* SHA1 initialization constants */ - context->state[0] = 0x67452301; - context->state[1] = 0xEFCDAB89; - context->state[2] = 0x98BADCFE; - context->state[3] = 0x10325476; - context->state[4] = 0xC3D2E1F0; - context->count[0] = context->count[1] = 0; -} - - -/* Run your data through this. */ - -/* - * __db_SHA1Update -- - * Run your data through this. - * - * PUBLIC: void __db_SHA1Update __P((SHA1_CTX *, unsigned char *, - * PUBLIC: size_t)); - */ -void -__db_SHA1Update(context, data, len) - SHA1_CTX *context; - unsigned char *data; - size_t len; -{ -u_int32_t i, j; /* JHB */ - -#ifdef VERBOSE - __db_SHAPrintContext(context, "before"); -#endif - j = (context->count[0] >> 3) & 63; - if ((context->count[0] += (u_int32_t)len << 3) < (len << 3)) context->count[1]++; - context->count[1] += (u_int32_t)(len >> 29); - if ((j + len) > 63) { - memcpy(&context->buffer[j], data, (i = 64-j)); - __db_SHA1Transform(context->state, context->buffer); - for ( ; i + 63 < len; i += 64) { - __db_SHA1Transform(context->state, &data[i]); - } - j = 0; - } - else i = 0; - memcpy(&context->buffer[j], &data[i], len - i); -#ifdef VERBOSE - __db_SHAPrintContext(context, "after "); -#endif -} - - -/* Add padding and return the message digest. */ - -/* - * __db_SHA1Final -- - * Add padding and return the message digest. - * - * PUBLIC: void __db_SHA1Final __P((unsigned char *, SHA1_CTX *)); - */ -void -__db_SHA1Final(digest, context) - unsigned char *digest; - SHA1_CTX *context; -{ -u_int32_t i; /* JHB */ -unsigned char finalcount[8]; - - for (i = 0; i < 8; i++) { - finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] - >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ - } - __db_SHA1Update(context, (unsigned char *)"\200", 1); - while ((context->count[0] & 504) != 448) { - __db_SHA1Update(context, (unsigned char *)"\0", 1); - } - __db_SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() -*/ - for (i = 0; i < 20; i++) { - digest[i] = (unsigned char) - ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); - } - /* Wipe variables */ - i = 0; /* JHB */ - memset(context->buffer, 0, 64); - memset(context->state, 0, 20); - memset(context->count, 0, 8); - memset(finalcount, 0, 8); /* SWR */ -#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */ - __db_SHA1Transform(context->state, context->buffer); -#endif -} - -/*************************************************************/ - diff --git a/storage/bdb/hsearch/hsearch.c b/storage/bdb/hsearch/hsearch.c deleted file mode 100644 index f9cd03e66a1..00000000000 --- a/storage/bdb/hsearch/hsearch.c +++ /dev/null @@ -1,158 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993 - * Margo Seltzer. All rights reserved. - */ -/* - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Margo Seltzer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: hsearch.c,v 12.2 2005/06/16 20:22:56 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#define DB_DBM_HSEARCH 1 -#include "db_int.h" - -static DB *dbp; -static ENTRY retval; - -/* - * Translate HSEARCH calls into DB calls so that DB doesn't step on the - * application's name space. - * - * EXTERN: #if DB_DBM_HSEARCH != 0 - * - * EXTERN: int __db_hcreate __P((size_t)); - * EXTERN: ENTRY *__db_hsearch __P((ENTRY, ACTION)); - * EXTERN: void __db_hdestroy __P((void)); - * - * EXTERN: #endif - */ -int -__db_hcreate(nel) - size_t nel; -{ - int ret; - - if ((ret = db_create(&dbp, NULL, 0)) != 0) { - __os_set_errno(ret); - return (1); - } - - if ((ret = dbp->set_pagesize(dbp, 512)) != 0 || - (ret = dbp->set_h_ffactor(dbp, 16)) != 0 || - (ret = dbp->set_h_nelem(dbp, (u_int32_t)nel)) != 0 || - (ret = dbp->open(dbp, NULL, - NULL, NULL, DB_HASH, DB_CREATE, __db_omode(OWNER_RW))) != 0) - __os_set_errno(ret); - - /* - * !!! - * Hsearch returns 0 on error, not 1. - */ - return (ret == 0 ? 1 : 0); -} - -ENTRY * -__db_hsearch(item, action) - ENTRY item; - ACTION action; -{ - DBT key, val; - int ret; - - if (dbp == NULL) { - __os_set_errno(EINVAL); - return (NULL); - } - memset(&key, 0, sizeof(key)); - memset(&val, 0, sizeof(val)); - key.data = item.key; - key.size = (u_int32_t)strlen(item.key) + 1; - - switch (action) { - case ENTER: - val.data = item.data; - val.size = (u_int32_t)strlen(item.data) + 1; - - /* - * Try and add the key to the database. If we fail because - * the key already exists, return the existing key. - */ - if ((ret = - dbp->put(dbp, NULL, &key, &val, DB_NOOVERWRITE)) == 0) - break; - if (ret == DB_KEYEXIST && - (ret = dbp->get(dbp, NULL, &key, &val, 0)) == 0) - break; - /* - * The only possible DB error is DB_NOTFOUND, and it can't - * happen. Check for a DB error, and lie if we find one. - */ - __os_set_errno(ret > 0 ? ret : EINVAL); - return (NULL); - case FIND: - if ((ret = dbp->get(dbp, NULL, &key, &val, 0)) != 0) { - if (ret != DB_NOTFOUND) - __os_set_errno(ret); - return (NULL); - } - item.data = (char *)val.data; - break; - default: - __os_set_errno(EINVAL); - return (NULL); - } - retval.key = item.key; - retval.data = item.data; - return (&retval); -} - -void -__db_hdestroy() -{ - if (dbp != NULL) { - (void)dbp->close(dbp, 0); - dbp = NULL; - } -} diff --git a/storage/bdb/lock/Design b/storage/bdb/lock/Design deleted file mode 100644 index 0fcdca2a211..00000000000 --- a/storage/bdb/lock/Design +++ /dev/null @@ -1,301 +0,0 @@ -# $Id: Design,v 12.0 2004/11/17 03:44:06 bostic Exp $ - -Synchronization in the Locking Subsystem - -This is a document that describes how we implemented fine-grain locking -in the lock manager (that is, locking on a hash bucket level instead of -locking the entire region). We found that the increase in concurrency -was not sufficient to warrant the increase in complexity or the additional -cost of performing each lock operation. Therefore, we don't use this -any more. Should we have to do fine-grain locking in a future release, -this would be a reasonable starting point. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -1. Data structures -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -The lock manager maintains 3 different structures: - -Objects (__db_lockobj): - Describes an object that is locked. When used with DB, this consists - of a __db_ilock (a file identifier and a page number). - -Lockers (__db_locker): - Identifies a specific locker ID and maintains the head of a list of - locks held by a locker (for using during transaction commit/abort). - -Locks (__db_lock): - Describes a particular object lock held on behalf of a particular - locker id. - -Objects and Lockers reference Locks. - -These structures are organized via two synchronized hash tables. Each -hash table consists of two physical arrays: the array of actual hash -buckets and an array of mutexes so we can lock individual buckets, rather -than the whole table. - -One hash table contains Objects and the other hash table contains Lockers. -Objects contain two lists of locks, waiters and holders: holders currently -hold a lock on the Object, waiters are lock waiting to be granted. -Lockers are a single linked list that connects the Locks held on behalf -of the specific locker ID. - -In the diagram below: - -Locker ID #1 holds a lock on Object #1 (L1) and Object #2 (L5), and is -waiting on a lock on Object #1 (L3). - -Locker ID #2 holds a lock on Object #1 (L2) and is waiting on a lock for -Object #2 (L7). - -Locker ID #3 is waiting for a lock on Object #2 (L6). - - OBJECT ----------------------- - HASH | | - ----|------------- | - ________ _______ | | ________ | | - | |-->| O1 |--|---|-->| O2 | | | - |_______| |_____| | | |______| V | - | | W H--->L1->L2 W H--->L5 | holders - |_______| | | | | V - | | ------->L3 \ ------->L6------>L7 waiters - |_______| / \ \ - . . / \ \ - . . | \ \ - . . | \ ----------- - |_______| | -------------- | - | | ____|____ ___|_____ _|______ - |_______| | | | | | | - | | | LID1 | | LID2 | | LID3 | - |_______| |_______| |_______| |______| - ^ ^ ^ - | | | - ___|________________________|________|___ - LOCKER | | | | | | | | | - HASH | | | | | | | | | - | | | | | | | | | - |____|____|____|____|____|____|____|____| - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -2. Synchronization -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -There are four types of mutexes in the subsystem. - -Object mutexes; - These map one-to-one to each bucket in the Object hash table. - Holding a mutex on an Object bucket secures all the Objects in - that bucket as well as the Lock structures linked from those - Objects. All fields in the Locks EXCEPT the Locker links (the - links that attach Locks by Locker ID) are protected by these - mutexes. - -Locker mutexes: - These map one-to-one to each bucket in the Locker hash table. - Holding a mutex on a Locker bucket secures the Locker structures - and the Locker links in the Locks. - -Memory mutex: - This mutex allows calls to allocate/free memory, i.e. calls to - __db_shalloc and __db_shalloc_free, as well as manipulation of - the Object, Locker and Lock free lists. - -Region mutex: - This mutex is currently only used to protect the locker ids. - It may also be needed later to provide exclusive access to - the region for deadlock detection. - -Creating or removing a Lock requires locking both the Object lock and the -Locker lock (and eventually the shalloc lock to return the item to the -free list). - -The locking hierarchy is as follows: - - The Region mutex may never be acquired after any other mutex. - - The Object mutex may be acquired after the Region mutex. - - The Locker mutex may be acquired after the Region and Object - mutexes. - - The Memory mutex may be acquired after any mutex. - -So, if both and Object mutex and a Locker mutex are going to be acquired, -the Object mutex must be acquired first. - -The Memory mutex may be acquired after any other mutex, but no other mutexes -can be acquired once the Memory mutex is held. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -3. The algorithms: -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -The locking subsystem supports four basic operations: - Get a Lock (lock_get) - - Release a Lock (lock_put) - - Release all the Locks on a specific Object (lock_vec) - - Release all the Locks for a specific Locker (lock_vec) - -Get a lock: - Acquire Object bucket mutex. - Acquire Locker bucket mutex. - - Acquire Memory mutex. - If the Object does not exist - Take an Object off the freelist. - If the Locker doesn't exist - Take a Locker off the freelist. - Take a Lock off the free list. - Release Memory mutex. - - Add Lock to the Object list. - Add Lock to the Locker list. - Release Locker bucket mutex - - If the lock cannot be granted - Release Object bucket mutex - Acquire lock mutex (blocks) - - Acquire Object bucket mutex - If lock acquisition did not succeed (e.g, deadlock) - Acquire Locker bucket mutex - If locker should be destroyed - Remove locker from hash table - Acquire Memory mutex - Return locker to free list - Release Memory mutex - Release Locker bucket mutex - - If object should be released - Acquire Memory mutex - Return object to free list - Release Memory mutex - - Release Object bucket mutex - -Release a lock: - Acquire Object bucket mutex. - (Requires that we be able to find the Object hash bucket - without looking inside the Lock itself.) - - If releasing a single lock and the user provided generation number - doesn't match the Lock's generation number, the Lock has been reused - and we return failure. - - Enter lock_put_internal: - if the Lock is still on the Object's lists: - Increment Lock's generation number. - Remove Lock from the Object's list (NULL link fields). - Promote locks for the Object. - - Enter locker_list_removal - Acquire Locker bucket mutex. - If Locker doesn't exist: - Release Locker bucket mutex - Release Object bucket mutex - Return error. - Else if Locker marked as deleted: - dont_release = TRUE - Else - Remove Lock from Locker list. - If Locker has no more locks - Remove Locker from table. - Acquire Memory mutex. - Return Locker to free list - Release Memory mutex - Release Locker bucket mutex. - Exit locker_list_removal - - If (!dont_release) - Acquire Memory mutex - Return Lock to free list - Release Memory mutex - - Exit lock_put_internal - - Release Object bucket mutex - -Release all the Locks on a specific Object (lock_vec, DB_PUT_ALL_OBJ): - - Acquire Object bucket mutex. - - For each lock on the waiter list: - lock_put_internal - For each lock on the holder list: - lock_put_internal - - Release Object bucket mutex. - -Release all the Locks for a specific Locker (lock_vec, DB_PUT_ALL): - - Acquire Locker bucket mutex. - Mark Locker deleted. - Release Locker mutex. - - For each lock on the Locker's list: - Remove from locker's list - (The lock could get put back on the free list in - lock_put and then could get reallocated and the - act of setting its locker links could clobber us.) - Perform "Release a Lock" above: skip locker_list_removal. - - Acquire Locker bucket mutex. - Remove Locker - Release Locker mutex. - - Acquire Memory mutex - Return Locker to free list - Release Memory mutex - -Deadlock detection (lock_detect): - - For each bucket in Object table - Acquire the Object bucket mutex. - create waitsfor - - For each bucket in Object table - Release the Object mutex. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -FAQ: -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -Q: Why do you need generation numbers? -A: If a lock has been released due to a transaction abort (potentially in a - different process), and then lock is released by a thread of control - unaware of the abort, the lock might have potentially been re-allocated - to a different object. The generation numbers detect this problem. - - Note, we assume that reads/writes of lock generation numbers are atomic, - if they are not, it is theoretically possible that a re-allocated lock - could be mistaken for another lock. - -Q: Why is is safe to walk the Locker list without holding any mutexes at - all? -A: Locks are created with both the Object and Locker bucket mutexes held. - Once created, they removed in two ways: - - a) when a specific Lock is released, in which case, the Object and - Locker bucket mutexes are again held, and - - b) when all Locks for a specific Locker Id is released. - - In case b), the Locker bucket mutex is held while the Locker chain is - marked as "destroyed", which blocks any further access to the Locker - chain. Then, each individual Object bucket mutex is acquired when each - individual Lock is removed. - -Q: What are the implications of doing fine grain locking? - -A: Since we no longer globally lock the entire region, lock_vec will no - longer be atomic. We still execute the items in a lock_vec in order, - so things like lock-coupling still work, but you can't make any - guarantees about atomicity. - -Q: How do I configure for FINE_GRAIN locking? - -A: We currently do not support any automatic configuration for FINE_GRAIN - locking. When we do, will need to document that atomicity discussion - listed above (it is bug-report #553). diff --git a/storage/bdb/lock/lock.c b/storage/bdb/lock/lock.c deleted file mode 100644 index c3e0173f05c..00000000000 --- a/storage/bdb/lock/lock.c +++ /dev/null @@ -1,1670 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: lock.c,v 12.19 2005/10/15 15:16:57 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_shash.h" -#include "dbinc/lock.h" -#include "dbinc/log.h" - -static int __lock_freelock __P((DB_LOCKTAB *, - struct __db_lock *, u_int32_t, u_int32_t)); -static int __lock_getobj - __P((DB_LOCKTAB *, const DBT *, u_int32_t, int, DB_LOCKOBJ **)); -static int __lock_inherit_locks __P ((DB_LOCKTAB *, u_int32_t, u_int32_t)); -static int __lock_is_parent __P((DB_LOCKTAB *, u_int32_t, DB_LOCKER *)); -static int __lock_put_internal __P((DB_LOCKTAB *, - struct __db_lock *, u_int32_t, u_int32_t)); -static int __lock_put_nolock __P((DB_ENV *, DB_LOCK *, int *, u_int32_t)); -static int __lock_remove_waiter __P((DB_LOCKTAB *, - DB_LOCKOBJ *, struct __db_lock *, db_status_t)); -static int __lock_trade __P((DB_ENV *, DB_LOCK *, u_int32_t)); - -static const char __db_lock_invalid[] = "%s: Lock is no longer valid"; -static const char __db_locker_invalid[] = "Locker is not valid"; - -/* - * __lock_vec_pp -- - * DB_ENV->lock_vec pre/post processing. - * - * PUBLIC: int __lock_vec_pp __P((DB_ENV *, - * PUBLIC: u_int32_t, u_int32_t, DB_LOCKREQ *, int, DB_LOCKREQ **)); - */ -int -__lock_vec_pp(dbenv, locker, flags, list, nlist, elistp) - DB_ENV *dbenv; - u_int32_t locker, flags; - int nlist; - DB_LOCKREQ *list, **elistp; -{ - DB_THREAD_INFO *ip; - int ret; - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, - dbenv->lk_handle, "DB_ENV->lock_vec", DB_INIT_LOCK); - - /* Validate arguments. */ - if ((ret = __db_fchk(dbenv, - "DB_ENV->lock_vec", flags, DB_LOCK_NOWAIT)) != 0) - return (ret); - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, - (__lock_vec(dbenv, locker, flags, list, nlist, elistp)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __lock_vec -- - * DB_ENV->lock_vec. - * - * Vector lock routine. This function takes a set of operations - * and performs them all at once. In addition, lock_vec provides - * functionality for lock inheritance, releasing all locks for a - * given locker (used during transaction commit/abort), releasing - * all locks on a given object, and generating debugging information. - * - * PUBLIC: int __lock_vec __P((DB_ENV *, - * PUBLIC: u_int32_t, u_int32_t, DB_LOCKREQ *, int, DB_LOCKREQ **)); - */ -int -__lock_vec(dbenv, locker, flags, list, nlist, elistp) - DB_ENV *dbenv; - u_int32_t locker, flags; - int nlist; - DB_LOCKREQ *list, **elistp; -{ - struct __db_lock *lp, *next_lock; - DB_LOCK lock; - DB_LOCKER *sh_locker; - DB_LOCKOBJ *sh_obj; - DB_LOCKREGION *region; - DB_LOCKTAB *lt; - DBT *objlist, *np; - u_int32_t lndx, ndx; - int did_abort, i, ret, run_dd, upgrade, writes; - - /* Check if locks have been globally turned off. */ - if (F_ISSET(dbenv, DB_ENV_NOLOCKING)) - return (0); - - lt = dbenv->lk_handle; - region = lt->reginfo.primary; - - run_dd = 0; - LOCK_SYSTEM_LOCK(dbenv); - for (i = 0, ret = 0; i < nlist && ret == 0; i++) - switch (list[i].op) { - case DB_LOCK_GET_TIMEOUT: - LF_SET(DB_LOCK_SET_TIMEOUT); - /* FALLTHROUGH */ - case DB_LOCK_GET: - if (IS_RECOVERING(dbenv)) { - LOCK_INIT(list[i].lock); - break; - } - ret = __lock_get_internal(lt, - locker, flags, list[i].obj, - list[i].mode, list[i].timeout, &list[i].lock); - break; - case DB_LOCK_INHERIT: - ret = __lock_inherit_locks(lt, locker, flags); - break; - case DB_LOCK_PUT: - ret = __lock_put_nolock(dbenv, - &list[i].lock, &run_dd, flags); - break; - case DB_LOCK_PUT_ALL: - case DB_LOCK_PUT_READ: - case DB_LOCK_UPGRADE_WRITE: - /* - * Get the locker and mark it as deleted. This - * allows us to traverse the locker links without - * worrying that someone else is deleting locks out - * from under us. Since the locker may hold no - * locks (i.e., you could call abort before you've - * done any work), it's perfectly reasonable for there - * to be no locker; this is not an error. - */ - LOCKER_LOCK(lt, region, locker, ndx); - if ((ret = __lock_getlocker(lt, - locker, ndx, 0, &sh_locker)) != 0 || - sh_locker == NULL || - F_ISSET(sh_locker, DB_LOCKER_DELETED)) - /* - * If ret is set, then we'll generate an - * error. If it's not set, we have nothing - * to do. - */ - break; - upgrade = 0; - writes = 1; - if (list[i].op == DB_LOCK_PUT_READ) - writes = 0; - else if (list[i].op == DB_LOCK_UPGRADE_WRITE) { - if (F_ISSET(sh_locker, DB_LOCKER_DIRTY)) - upgrade = 1; - writes = 0; - } - objlist = list[i].obj; - if (objlist != NULL) { - /* - * We know these should be ilocks, - * but they could be something else, - * so allocate room for the size too. - */ - objlist->size = - sh_locker->nwrites * sizeof(DBT); - if ((ret = __os_malloc(dbenv, - objlist->size, &objlist->data)) != 0) - goto up_done; - memset(objlist->data, 0, objlist->size); - np = (DBT *) objlist->data; - } else - np = NULL; - - F_SET(sh_locker, DB_LOCKER_DELETED); - - /* Now traverse the locks, releasing each one. */ - for (lp = SH_LIST_FIRST(&sh_locker->heldby, __db_lock); - lp != NULL; lp = next_lock) { - sh_obj = (DB_LOCKOBJ *) - ((u_int8_t *)lp + lp->obj); - next_lock = SH_LIST_NEXT(lp, - locker_links, __db_lock); - if (writes == 1 || - lp->mode == DB_LOCK_READ || - lp->mode == DB_LOCK_READ_UNCOMMITTED) { - SH_LIST_REMOVE(lp, - locker_links, __db_lock); - sh_obj = (DB_LOCKOBJ *) - ((u_int8_t *)lp + lp->obj); - SHOBJECT_LOCK(lt, region, sh_obj, lndx); - /* - * We are not letting lock_put_internal - * unlink the lock, so we'll have to - * update counts here. - */ - sh_locker->nlocks--; - if (IS_WRITELOCK(lp->mode)) - sh_locker->nwrites--; - ret = __lock_put_internal(lt, lp, - lndx, DB_LOCK_FREE | DB_LOCK_DOALL); - if (ret != 0) - break; - continue; - } - if (objlist != NULL) { - DB_ASSERT((char *)np < - (char *)objlist->data + - objlist->size); - np->data = SH_DBT_PTR(&sh_obj->lockobj); - np->size = sh_obj->lockobj.size; - np++; - } - } - if (ret != 0) - goto up_done; - - if (objlist != NULL) - if ((ret = __lock_fix_list(dbenv, - objlist, sh_locker->nwrites)) != 0) - goto up_done; - switch (list[i].op) { - case DB_LOCK_UPGRADE_WRITE: - if (upgrade != 1) - goto up_done; - for (lp = SH_LIST_FIRST( - &sh_locker->heldby, __db_lock); - lp != NULL; - lp = SH_LIST_NEXT(lp, - locker_links, __db_lock)) { - if (lp->mode != DB_LOCK_WWRITE) - continue; - lock.off = R_OFFSET(<->reginfo, lp); - lock.gen = lp->gen; - F_SET(sh_locker, DB_LOCKER_INABORT); - if ((ret = __lock_get_internal(lt, - locker, flags | DB_LOCK_UPGRADE, - NULL, DB_LOCK_WRITE, 0, &lock)) !=0) - break; - } - up_done: - /* FALLTHROUGH */ - case DB_LOCK_PUT_READ: - case DB_LOCK_PUT_ALL: - F_CLR(sh_locker, DB_LOCKER_DELETED); - break; - default: - break; - } - break; - case DB_LOCK_PUT_OBJ: - /* Remove all the locks associated with an object. */ - OBJECT_LOCK(lt, region, list[i].obj, ndx); - if ((ret = __lock_getobj(lt, list[i].obj, - ndx, 0, &sh_obj)) != 0 || sh_obj == NULL) { - if (ret == 0) - ret = EINVAL; - break; - } - - /* - * Go through both waiters and holders. Don't bother - * to run promotion, because everyone is getting - * released. The processes waiting will still get - * awakened as their waiters are released. - */ - for (lp = SH_TAILQ_FIRST(&sh_obj->waiters, __db_lock); - ret == 0 && lp != NULL; - lp = SH_TAILQ_FIRST(&sh_obj->waiters, __db_lock)) - ret = __lock_put_internal(lt, lp, ndx, - DB_LOCK_UNLINK | - DB_LOCK_NOPROMOTE | DB_LOCK_DOALL); - - /* - * On the last time around, the object will get - * reclaimed by __lock_put_internal, structure the - * loop carefully so we do not get bitten. - */ - for (lp = SH_TAILQ_FIRST(&sh_obj->holders, __db_lock); - ret == 0 && lp != NULL; - lp = next_lock) { - next_lock = SH_TAILQ_NEXT(lp, links, __db_lock); - ret = __lock_put_internal(lt, lp, ndx, - DB_LOCK_UNLINK | - DB_LOCK_NOPROMOTE | DB_LOCK_DOALL); - } - break; - - case DB_LOCK_TIMEOUT: - ret = __lock_set_timeout_internal(dbenv, - locker, 0, DB_SET_TXN_NOW); - break; - - case DB_LOCK_TRADE: - /* - * INTERNAL USE ONLY. - * Change the holder of the lock described in - * list[i].lock to the locker-id specified by - * the locker parameter. - */ - /* - * You had better know what you're doing here. - * We are trading locker-id's on a lock to - * facilitate file locking on open DB handles. - * We do not do any conflict checking on this, - * so heaven help you if you use this flag under - * any other circumstances. - */ - ret = __lock_trade(dbenv, &list[i].lock, locker); - break; -#if defined(DEBUG) && defined(HAVE_STATISTICS) - case DB_LOCK_DUMP: - /* Find the locker. */ - LOCKER_LOCK(lt, region, locker, ndx); - if ((ret = __lock_getlocker(lt, - locker, ndx, 0, &sh_locker)) != 0 || - sh_locker == NULL || - F_ISSET(sh_locker, DB_LOCKER_DELETED)) - break; - - for (lp = SH_LIST_FIRST(&sh_locker->heldby, __db_lock); - lp != NULL; - lp = SH_LIST_NEXT(lp, locker_links, __db_lock)) { - __lock_printlock(lt, NULL, lp, 1); - } - break; -#endif - default: - __db_err(dbenv, - "Invalid lock operation: %d", list[i].op); - ret = EINVAL; - break; - } - - if (ret == 0 && region->detect != DB_LOCK_NORUN && - (region->need_dd || LOCK_TIME_ISVALID(®ion->next_timeout))) - run_dd = 1; - LOCK_SYSTEM_UNLOCK(dbenv); - - if (run_dd) - (void)__lock_detect(dbenv, region->detect, &did_abort); - - if (ret != 0 && elistp != NULL) - *elistp = &list[i - 1]; - - return (ret); -} - -/* - * __lock_get_pp -- - * DB_ENV->lock_get pre/post processing. - * - * PUBLIC: int __lock_get_pp __P((DB_ENV *, - * PUBLIC: u_int32_t, u_int32_t, const DBT *, db_lockmode_t, DB_LOCK *)); - */ -int -__lock_get_pp(dbenv, locker, flags, obj, lock_mode, lock) - DB_ENV *dbenv; - u_int32_t locker, flags; - const DBT *obj; - db_lockmode_t lock_mode; - DB_LOCK *lock; -{ - DB_THREAD_INFO *ip; - int ret; - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, - dbenv->lk_handle, "DB_ENV->lock_get", DB_INIT_LOCK); - - /* Validate arguments. */ - if ((ret = __db_fchk(dbenv, "DB_ENV->lock_get", flags, - DB_LOCK_NOWAIT | DB_LOCK_UPGRADE | DB_LOCK_SWITCH)) != 0) - return (ret); - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, - (__lock_get(dbenv, locker, flags, obj, lock_mode, lock)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __lock_get -- - * DB_ENV->lock_get. - * - * PUBLIC: int __lock_get __P((DB_ENV *, - * PUBLIC: u_int32_t, u_int32_t, const DBT *, db_lockmode_t, DB_LOCK *)); - */ -int -__lock_get(dbenv, locker, flags, obj, lock_mode, lock) - DB_ENV *dbenv; - u_int32_t locker, flags; - const DBT *obj; - db_lockmode_t lock_mode; - DB_LOCK *lock; -{ - DB_LOCKTAB *lt; - int ret; - - lt = dbenv->lk_handle; - - if (IS_RECOVERING(dbenv)) { - LOCK_INIT(*lock); - return (0); - } - - LOCK_SYSTEM_LOCK(dbenv); - ret = __lock_get_internal(lt, locker, flags, obj, lock_mode, 0, lock); - LOCK_SYSTEM_UNLOCK(dbenv); - return (ret); -} - -/* - * __lock_get_internal -- - * All the work for lock_get (and for the GET option of lock_vec) is done - * inside of lock_get_internal. - * - * PUBLIC: int __lock_get_internal __P((DB_LOCKTAB *, u_int32_t, u_int32_t, - * PUBLIC: const DBT *, db_lockmode_t, db_timeout_t, DB_LOCK *)); - */ -int -__lock_get_internal(lt, locker, flags, obj, lock_mode, timeout, lock) - DB_LOCKTAB *lt; - u_int32_t locker, flags; - const DBT *obj; - db_lockmode_t lock_mode; - db_timeout_t timeout; - DB_LOCK *lock; -{ - struct __db_lock *newl, *lp; - DB_ENV *dbenv; - DB_LOCKER *sh_locker; - DB_LOCKOBJ *sh_obj; - DB_LOCKREGION *region; - DB_THREAD_INFO *ip; - u_int32_t holder, locker_ndx, obj_ndx; - int did_abort, ihold, grant_dirty, no_dd, ret, t_ret; - - /* - * We decide what action to take based on what locks are already held - * and what locks are in the wait queue. - */ - enum { - GRANT, /* Grant the lock. */ - UPGRADE, /* Upgrade the lock. */ - HEAD, /* Wait at head of wait queue. */ - SECOND, /* Wait as the second waiter. */ - TAIL /* Wait at tail of the wait queue. */ - } action; - - dbenv = lt->dbenv; - region = lt->reginfo.primary; - - /* Check if locks have been globally turned off. */ - if (F_ISSET(dbenv, DB_ENV_NOLOCKING)) - return (0); - - no_dd = ret = 0; - newl = NULL; - - /* Check that the lock mode is valid. */ - if (lock_mode >= (db_lockmode_t)region->stat.st_nmodes) { - __db_err(dbenv, "DB_ENV->lock_get: invalid lock mode %lu", - (u_long)lock_mode); - return (EINVAL); - } - if (LF_ISSET(DB_LOCK_UPGRADE)) - region->stat.st_nupgrade++; - else if (!LF_ISSET(DB_LOCK_SWITCH)) - region->stat.st_nrequests++; - - if (obj == NULL) { - DB_ASSERT(LOCK_ISSET(*lock)); - lp = R_ADDR(<->reginfo, lock->off); - sh_obj = (DB_LOCKOBJ *)((u_int8_t *)lp + lp->obj); - } else { - /* Allocate a shared memory new object. */ - OBJECT_LOCK(lt, region, obj, lock->ndx); - if ((ret = __lock_getobj(lt, obj, lock->ndx, 1, &sh_obj)) != 0) - goto err; - } - - /* - * If we are not going to reuse this lock, invalidate it - * so that if we fail it will not look like a valid lock. - */ - if (!LF_ISSET(DB_LOCK_UPGRADE | DB_LOCK_SWITCH)) - LOCK_INIT(*lock); - - /* Get the locker, we may need it to find our parent. */ - LOCKER_LOCK(lt, region, locker, locker_ndx); - if ((ret = __lock_getlocker(lt, locker, - locker_ndx, locker > DB_LOCK_MAXID ? 1 : 0, &sh_locker)) != 0) { - /* - * XXX - * We cannot tell if we created the object or not, so we don't - * kow if we should free it or not. - */ - goto err; - } - - if (sh_locker == NULL) { - __db_err(dbenv, "Locker does not exist"); - ret = EINVAL; - goto err; - } - - /* - * Figure out if we can grant this lock or if it should wait. - * By default, we can grant the new lock if it does not conflict with - * anyone on the holders list OR anyone on the waiters list. - * The reason that we don't grant if there's a conflict is that - * this can lead to starvation (a writer waiting on a popularly - * read item will never be granted). The downside of this is that - * a waiting reader can prevent an upgrade from reader to writer, - * which is not uncommon. - * - * There are two exceptions to the no-conflict rule. First, if - * a lock is held by the requesting locker AND the new lock does - * not conflict with any other holders, then we grant the lock. - * The most common place this happens is when the holder has a - * WRITE lock and a READ lock request comes in for the same locker. - * If we do not grant the read lock, then we guarantee deadlock. - * Second, dirty readers are granted if at all possible while - * avoiding starvation, see below. - * - * In case of conflict, we put the new lock on the end of the waiters - * list, unless we are upgrading or this is a dirty reader in which - * case the locker goes at or near the front of the list. - */ - ihold = 0; - grant_dirty = 0; - holder = 0; - - /* - * SWITCH is a special case, used by the queue access method - * when we want to get an entry which is past the end of the queue. - * We have a DB_READ_LOCK and need to switch it to DB_LOCK_WAIT and - * join the waiters queue. This must be done as a single operation - * so that another locker cannot get in and fail to wake us up. - */ - if (LF_ISSET(DB_LOCK_SWITCH)) - lp = NULL; - else - lp = SH_TAILQ_FIRST(&sh_obj->holders, __db_lock); - for (; lp != NULL; lp = SH_TAILQ_NEXT(lp, links, __db_lock)) { - DB_ASSERT(lp->status != DB_LSTAT_FREE); - if (locker == lp->holder) { - if (lp->mode == lock_mode && - lp->status == DB_LSTAT_HELD) { - if (LF_ISSET(DB_LOCK_UPGRADE)) - goto upgrade; - - /* - * Lock is held, so we can increment the - * reference count and return this lock - * to the caller. We do not count reference - * increments towards the locks held by - * the locker. - */ - lp->refcount++; - lock->off = R_OFFSET(<->reginfo, lp); - lock->gen = lp->gen; - lock->mode = lp->mode; - goto done; - } else { - ihold = 1; - } - } else if (__lock_is_parent(lt, lp->holder, sh_locker)) - ihold = 1; - else if (CONFLICTS(lt, region, lp->mode, lock_mode)) - break; - else if (lp->mode == DB_LOCK_READ || - lp->mode == DB_LOCK_WWRITE) { - grant_dirty = 1; - holder = lp->holder; - } - } - - /* - * If there are conflicting holders we will have to wait. An upgrade - * or dirty reader goes to the head of the queue, everyone else to the - * back. - */ - if (lp != NULL) { - if (LF_ISSET(DB_LOCK_UPGRADE) || - lock_mode == DB_LOCK_READ_UNCOMMITTED) - action = HEAD; - else - action = TAIL; - } else { - if (LF_ISSET(DB_LOCK_SWITCH)) - action = TAIL; - else if (LF_ISSET(DB_LOCK_UPGRADE)) - action = UPGRADE; - else if (ihold) - action = GRANT; - else { - /* - * Look for conflicting waiters. - */ - for (lp = SH_TAILQ_FIRST(&sh_obj->waiters, __db_lock); - lp != NULL; - lp = SH_TAILQ_NEXT(lp, links, __db_lock)) { - if (CONFLICTS(lt, region, lp->mode, - lock_mode) && locker != lp->holder) - break; - } - /* - * If there are no conflicting holders or waiters, - * then we grant. Normally when we wait, we - * wait at the end (TAIL). However, the goal of - * DIRTY_READ locks to allow forward progress in the - * face of updating transactions, so we try to allow - * all DIRTY_READ requests to proceed as rapidly - * as possible, so long as we can prevent starvation. - * - * When determining how to queue a DIRTY_READ - * request: - * - * 1. If there is a waiting upgrading writer, - * then we enqueue the dirty reader BEHIND it - * (second in the queue). - * 2. Else, if the current holders are either - * READ or WWRITE, we grant - * 3. Else queue SECOND i.e., behind the first - * waiter. - * - * The end result is that dirty_readers get to run - * so long as other lockers are blocked. Once - * there is a locker which is only waiting on - * dirty readers then they queue up behind that - * locker so that it gets to run. In general - * this locker will be a WRITE which will shortly - * get downgraded to a WWRITE, permitting the - * DIRTY locks to be granted. - */ - if (lp == NULL) - action = GRANT; - else if (grant_dirty && - lock_mode == DB_LOCK_READ_UNCOMMITTED) { - /* - * An upgrade will be at the head of the - * queue. - */ - lp = SH_TAILQ_FIRST( - &sh_obj->waiters, __db_lock); - if (lp->mode == DB_LOCK_WRITE && - lp->holder == holder) - action = SECOND; - else - action = GRANT; - } else if (lock_mode == DB_LOCK_READ_UNCOMMITTED) - action = SECOND; - else - action = TAIL; - } - } - - switch (action) { - case HEAD: - case TAIL: - case SECOND: - case GRANT: - /* Allocate a new lock. */ - if ((newl = - SH_TAILQ_FIRST(®ion->free_locks, __db_lock)) == NULL) - return (__lock_nomem(dbenv, "locks")); - SH_TAILQ_REMOVE(®ion->free_locks, newl, links, __db_lock); - - /* Update new lock statistics. */ - if (++region->stat.st_nlocks > region->stat.st_maxnlocks) - region->stat.st_maxnlocks = region->stat.st_nlocks; - - /* - * Allocate a mutex if we do not have a mutex backing the lock. - * - * Use the lock mutex to block the thread; lock the mutex - * when it is allocated so that we will block when we try - * to lock it again. We will wake up when another thread - * grants the lock and releases the mutex. We leave it - * locked for the next use of this lock object. - */ - if (newl->mtx_lock == MUTEX_INVALID) { - if ((ret = __mutex_alloc(dbenv, MTX_LOGICAL_LOCK, - DB_MUTEX_LOGICAL_LOCK | DB_MUTEX_SELF_BLOCK, - &newl->mtx_lock)) != 0) - goto err; - MUTEX_LOCK(dbenv, newl->mtx_lock); - } - - newl->holder = locker; - newl->refcount = 1; - newl->mode = lock_mode; - newl->obj = (roff_t)SH_PTR_TO_OFF(newl, sh_obj); - /* - * Now, insert the lock onto its locker's list. - * If the locker does not currently hold any locks, - * there's no reason to run a deadlock - * detector, save that information. - */ - no_dd = sh_locker->master_locker == INVALID_ROFF && - SH_LIST_FIRST( - &sh_locker->child_locker, __db_locker) == NULL && - SH_LIST_FIRST(&sh_locker->heldby, __db_lock) == NULL; - - SH_LIST_INSERT_HEAD( - &sh_locker->heldby, newl, locker_links, __db_lock); - break; - - case UPGRADE: -upgrade: lp = R_ADDR(<->reginfo, lock->off); - if (IS_WRITELOCK(lock_mode) && !IS_WRITELOCK(lp->mode)) - sh_locker->nwrites++; - lp->mode = lock_mode; - goto done; - } - - switch (action) { - case UPGRADE: - DB_ASSERT(0); - break; - case GRANT: - newl->status = DB_LSTAT_HELD; - SH_TAILQ_INSERT_TAIL(&sh_obj->holders, newl, links); - break; - case HEAD: - case TAIL: - case SECOND: - if (LF_ISSET(DB_LOCK_NOWAIT)) { - ret = DB_LOCK_NOTGRANTED; - region->stat.st_lock_nowait++; - goto err; - } - if ((lp = SH_TAILQ_FIRST(&sh_obj->waiters, __db_lock)) == NULL) - SH_TAILQ_INSERT_HEAD(®ion->dd_objs, - sh_obj, dd_links, __db_lockobj); - switch (action) { - case HEAD: - SH_TAILQ_INSERT_HEAD( - &sh_obj->waiters, newl, links, __db_lock); - break; - case SECOND: - SH_TAILQ_INSERT_AFTER( - &sh_obj->waiters, lp, newl, links, __db_lock); - break; - case TAIL: - SH_TAILQ_INSERT_TAIL(&sh_obj->waiters, newl, links); - break; - default: - DB_ASSERT(0); - } - - /* If we are switching drop the lock we had. */ - if (LF_ISSET(DB_LOCK_SWITCH) && - (ret = __lock_put_nolock(dbenv, - lock, &ihold, DB_LOCK_NOWAITERS)) != 0) { - (void)__lock_remove_waiter( - lt, sh_obj, newl, DB_LSTAT_FREE); - goto err; - } - - /* - * First check to see if this txn has expired. - * If not then see if the lock timeout is past - * the expiration of the txn, if it is, use - * the txn expiration time. lk_expire is passed - * to avoid an extra call to get the time. - */ - if (__lock_expired(dbenv, - &sh_locker->lk_expire, &sh_locker->tx_expire)) { - newl->status = DB_LSTAT_EXPIRED; - sh_locker->lk_expire = sh_locker->tx_expire; - - /* We are done. */ - goto expired; - } - - /* - * If a timeout was specified in this call then it - * takes priority. If a lock timeout has been specified - * for this transaction then use that, otherwise use - * the global timeout value. - */ - if (!LF_ISSET(DB_LOCK_SET_TIMEOUT)) { - if (F_ISSET(sh_locker, DB_LOCKER_TIMEOUT)) - timeout = sh_locker->lk_timeout; - else - timeout = region->lk_timeout; - } - if (timeout != 0) - __lock_expires(dbenv, &sh_locker->lk_expire, timeout); - else - LOCK_SET_TIME_INVALID(&sh_locker->lk_expire); - - if (LOCK_TIME_ISVALID(&sh_locker->tx_expire) && - (timeout == 0 || __lock_expired(dbenv, - &sh_locker->lk_expire, &sh_locker->tx_expire))) - sh_locker->lk_expire = sh_locker->tx_expire; - if (LOCK_TIME_ISVALID(&sh_locker->lk_expire) && - (!LOCK_TIME_ISVALID(®ion->next_timeout) || - LOCK_TIME_GREATER( - ®ion->next_timeout, &sh_locker->lk_expire))) - region->next_timeout = sh_locker->lk_expire; - - newl->status = DB_LSTAT_WAITING; - region->stat.st_lock_wait++; - /* We are about to block, deadlock detector must run. */ - region->need_dd = 1; - - LOCK_SYSTEM_UNLOCK(dbenv); - - /* - * Before waiting, see if the deadlock detector should run. - */ - if (region->detect != DB_LOCK_NORUN && !no_dd) - (void)__lock_detect(dbenv, region->detect, &did_abort); - - ip = NULL; - if (dbenv->thr_hashtab != NULL && - (ret = __env_set_state(dbenv, &ip, THREAD_BLOCKED)) != 0) - goto err; - MUTEX_LOCK(dbenv, newl->mtx_lock); - if (ip != NULL) - ip->dbth_state = THREAD_ACTIVE; - - LOCK_SYSTEM_LOCK(dbenv); - - /* Turn off lock timeout. */ - if (newl->status != DB_LSTAT_EXPIRED) - LOCK_SET_TIME_INVALID(&sh_locker->lk_expire); - - switch (newl->status) { - case DB_LSTAT_ABORTED: - ret = DB_LOCK_DEADLOCK; - goto err; - case DB_LSTAT_EXPIRED: -expired: SHOBJECT_LOCK(lt, region, sh_obj, obj_ndx); - if ((ret = __lock_put_internal(lt, newl, - obj_ndx, DB_LOCK_UNLINK | DB_LOCK_FREE)) != 0) - break; - if (LOCK_TIME_EQUAL( - &sh_locker->lk_expire, &sh_locker->tx_expire)) - region->stat.st_ntxntimeouts++; - else - region->stat.st_nlocktimeouts++; - return (DB_LOCK_NOTGRANTED); - case DB_LSTAT_PENDING: - if (LF_ISSET(DB_LOCK_UPGRADE)) { - /* - * The lock just granted got put on the holders - * list. Since we're upgrading some other lock, - * we've got to remove it here. - */ - SH_TAILQ_REMOVE( - &sh_obj->holders, newl, links, __db_lock); - /* - * Ensure the object is not believed to be on - * the object's lists, if we're traversing by - * locker. - */ - newl->links.stqe_prev = -1; - goto upgrade; - } else - newl->status = DB_LSTAT_HELD; - break; - case DB_LSTAT_FREE: - case DB_LSTAT_HELD: - case DB_LSTAT_WAITING: - default: - __db_err(dbenv, - "Unexpected lock status: %d", (int)newl->status); - ret = __db_panic(dbenv, EINVAL); - goto err; - } - } - - lock->off = R_OFFSET(<->reginfo, newl); - lock->gen = newl->gen; - lock->mode = newl->mode; - sh_locker->nlocks++; - if (IS_WRITELOCK(newl->mode)) { - sh_locker->nwrites++; - if (newl->mode == DB_LOCK_WWRITE) - F_SET(sh_locker, DB_LOCKER_DIRTY); - } - - return (0); - -done: - ret = 0; -err: - if (newl != NULL && - (t_ret = __lock_freelock(lt, newl, locker, - DB_LOCK_FREE | DB_LOCK_UNLINK)) != 0 && ret == 0) - ret = t_ret; - return (ret); -} - -/* - * __lock_put_pp -- - * DB_ENV->lock_put pre/post processing. - * - * PUBLIC: int __lock_put_pp __P((DB_ENV *, DB_LOCK *)); - */ -int -__lock_put_pp(dbenv, lock) - DB_ENV *dbenv; - DB_LOCK *lock; -{ - DB_THREAD_INFO *ip; - int ret; - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, - dbenv->lk_handle, "DB_LOCK->lock_put", DB_INIT_LOCK); - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, (__lock_put(dbenv, lock)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __lock_put -- - * - * PUBLIC: int __lock_put __P((DB_ENV *, DB_LOCK *)); - * Internal lock_put interface. - */ -int -__lock_put(dbenv, lock) - DB_ENV *dbenv; - DB_LOCK *lock; -{ - DB_LOCKTAB *lt; - int ret, run_dd; - - if (IS_RECOVERING(dbenv)) - return (0); - - lt = dbenv->lk_handle; - - LOCK_SYSTEM_LOCK(dbenv); - ret = __lock_put_nolock(dbenv, lock, &run_dd, 0); - LOCK_SYSTEM_UNLOCK(dbenv); - - /* - * Only run the lock detector if put told us to AND we are running - * in auto-detect mode. If we are not running in auto-detect, then - * a call to lock_detect here will 0 the need_dd bit, but will not - * actually abort anything. - */ - if (ret == 0 && run_dd) - (void)__lock_detect(dbenv, - ((DB_LOCKREGION *)lt->reginfo.primary)->detect, NULL); - return (ret); -} - -static int -__lock_put_nolock(dbenv, lock, runp, flags) - DB_ENV *dbenv; - DB_LOCK *lock; - int *runp; - u_int32_t flags; -{ - struct __db_lock *lockp; - DB_LOCKREGION *region; - DB_LOCKTAB *lt; - int ret; - - /* Check if locks have been globally turned off. */ - if (F_ISSET(dbenv, DB_ENV_NOLOCKING)) - return (0); - - lt = dbenv->lk_handle; - region = lt->reginfo.primary; - - lockp = R_ADDR(<->reginfo, lock->off); - if (lock->gen != lockp->gen) { - __db_err(dbenv, __db_lock_invalid, "DB_LOCK->lock_put"); - LOCK_INIT(*lock); - return (EINVAL); - } - - ret = __lock_put_internal(lt, - lockp, lock->ndx, flags | DB_LOCK_UNLINK | DB_LOCK_FREE); - LOCK_INIT(*lock); - - *runp = 0; - if (ret == 0 && region->detect != DB_LOCK_NORUN && - (region->need_dd || LOCK_TIME_ISVALID(®ion->next_timeout))) - *runp = 1; - - return (ret); -} - -/* - * __lock_downgrade -- - * - * Used to downgrade locks. Currently this is used in three places: 1) by the - * Concurrent Data Store product to downgrade write locks back to iwrite locks - * and 2) to downgrade write-handle locks to read-handle locks at the end of - * an open/create. 3) To downgrade write locks to was_write to support dirty - * reads. - * - * PUBLIC: int __lock_downgrade __P((DB_ENV *, - * PUBLIC: DB_LOCK *, db_lockmode_t, u_int32_t)); - */ -int -__lock_downgrade(dbenv, lock, new_mode, flags) - DB_ENV *dbenv; - DB_LOCK *lock; - db_lockmode_t new_mode; - u_int32_t flags; -{ - struct __db_lock *lockp; - DB_LOCKER *sh_locker; - DB_LOCKOBJ *obj; - DB_LOCKREGION *region; - DB_LOCKTAB *lt; - u_int32_t indx; - int ret; - - PANIC_CHECK(dbenv); - ret = 0; - - /* Check if locks have been globally turned off. */ - if (F_ISSET(dbenv, DB_ENV_NOLOCKING)) - return (0); - - lt = dbenv->lk_handle; - region = lt->reginfo.primary; - - if (!LF_ISSET(DB_LOCK_NOREGION)) - LOCK_SYSTEM_LOCK(dbenv); - - region->stat.st_ndowngrade++; - - lockp = R_ADDR(<->reginfo, lock->off); - if (lock->gen != lockp->gen) { - __db_err(dbenv, __db_lock_invalid, "lock_downgrade"); - ret = EINVAL; - goto out; - } - - LOCKER_LOCK(lt, region, lockp->holder, indx); - - if ((ret = __lock_getlocker(lt, lockp->holder, - indx, 0, &sh_locker)) != 0 || sh_locker == NULL) { - if (ret == 0) - ret = EINVAL; - __db_err(dbenv, __db_locker_invalid); - goto out; - } - if (IS_WRITELOCK(lockp->mode) && !IS_WRITELOCK(new_mode)) - sh_locker->nwrites--; - - lockp->mode = new_mode; - lock->mode = new_mode; - - /* Get the object associated with this lock. */ - obj = (DB_LOCKOBJ *)((u_int8_t *)lockp + lockp->obj); - ret = __lock_promote(lt, obj, NULL, LF_ISSET(DB_LOCK_NOWAITERS)); - -out: if (!LF_ISSET(DB_LOCK_NOREGION)) - LOCK_SYSTEM_UNLOCK(dbenv); - - return (ret); -} - -static int -__lock_put_internal(lt, lockp, obj_ndx, flags) - DB_LOCKTAB *lt; - struct __db_lock *lockp; - u_int32_t obj_ndx, flags; -{ - DB_LOCKOBJ *sh_obj; - DB_LOCKREGION *region; - int ret, state_changed; - - region = lt->reginfo.primary; - ret = state_changed = 0; - - if (!OBJ_LINKS_VALID(lockp)) { - /* - * Someone removed this lock while we were doing a release - * by locker id. We are trying to free this lock, but it's - * already been done; all we need to do is return it to the - * free list. - */ - (void)__lock_freelock(lt, lockp, 0, DB_LOCK_FREE); - return (0); - } - - if (LF_ISSET(DB_LOCK_DOALL)) - region->stat.st_nreleases += lockp->refcount; - else - region->stat.st_nreleases++; - - if (!LF_ISSET(DB_LOCK_DOALL) && lockp->refcount > 1) { - lockp->refcount--; - return (0); - } - - /* Increment generation number. */ - lockp->gen++; - - /* Get the object associated with this lock. */ - sh_obj = (DB_LOCKOBJ *)((u_int8_t *)lockp + lockp->obj); - - /* - * Remove this lock from its holders/waitlist. Set its status - * to ABORTED. It may get freed below, but if not then the - * waiter has been aborted (it will panic if the lock is - * free). - */ - if (lockp->status != DB_LSTAT_HELD && - lockp->status != DB_LSTAT_PENDING) { - if ((ret = __lock_remove_waiter( - lt, sh_obj, lockp, DB_LSTAT_ABORTED)) != 0) - return (ret); - } else { - SH_TAILQ_REMOVE(&sh_obj->holders, lockp, links, __db_lock); - lockp->links.stqe_prev = -1; - } - - if (LF_ISSET(DB_LOCK_NOPROMOTE)) - state_changed = 0; - else - if ((ret = __lock_promote(lt, sh_obj, &state_changed, - LF_ISSET(DB_LOCK_NOWAITERS))) != 0) - return (ret); - - /* Check if object should be reclaimed. */ - if (SH_TAILQ_FIRST(&sh_obj->holders, __db_lock) == NULL && - SH_TAILQ_FIRST(&sh_obj->waiters, __db_lock) == NULL) { - HASHREMOVE_EL(lt->obj_tab, - obj_ndx, __db_lockobj, links, sh_obj); - if (sh_obj->lockobj.size > sizeof(sh_obj->objdata)) - __db_shalloc_free(<->reginfo, - SH_DBT_PTR(&sh_obj->lockobj)); - SH_TAILQ_INSERT_HEAD( - ®ion->free_objs, sh_obj, links, __db_lockobj); - region->stat.st_nobjects--; - state_changed = 1; - } - - /* Free lock. */ - if (LF_ISSET(DB_LOCK_UNLINK | DB_LOCK_FREE)) - ret = __lock_freelock(lt, lockp, lockp->holder, flags); - - /* - * If we did not promote anyone; we need to run the deadlock - * detector again. - */ - if (state_changed == 0) - region->need_dd = 1; - - return (ret); -} - -/* - * __lock_freelock -- - * Free a lock. Unlink it from its locker if necessary. - * - */ -static int -__lock_freelock(lt, lockp, locker, flags) - DB_LOCKTAB *lt; - struct __db_lock *lockp; - u_int32_t locker, flags; -{ - DB_ENV *dbenv; - DB_LOCKER *sh_locker; - DB_LOCKREGION *region; - u_int32_t indx; - int ret; - - dbenv = lt->dbenv; - region = lt->reginfo.primary; - - if (LF_ISSET(DB_LOCK_UNLINK)) { - LOCKER_LOCK(lt, region, locker, indx); - if ((ret = __lock_getlocker(lt, - locker, indx, 0, &sh_locker)) != 0 || sh_locker == NULL) { - __db_err(dbenv, __db_locker_invalid); - return (ret == 0 ? EINVAL : ret); - } - - SH_LIST_REMOVE(lockp, locker_links, __db_lock); - if (lockp->status == DB_LSTAT_HELD) { - sh_locker->nlocks--; - if (IS_WRITELOCK(lockp->mode)) - sh_locker->nwrites--; - } - } - - if (LF_ISSET(DB_LOCK_FREE)) { - /* - * If the lock is not held we cannot be sure of its mutex - * state so we just destroy it and let it be re-created - * when needed. - */ - if (lockp->mtx_lock != MUTEX_INVALID && - lockp->status != DB_LSTAT_HELD && - lockp->status != DB_LSTAT_EXPIRED && - (ret = __mutex_free(dbenv, &lockp->mtx_lock)) != 0) - return (ret); - lockp->status = DB_LSTAT_FREE; - SH_TAILQ_INSERT_HEAD( - ®ion->free_locks, lockp, links, __db_lock); - region->stat.st_nlocks--; - } - - return (0); -} - -/* - * __lock_getobj -- - * Get an object in the object hash table. The create parameter - * indicates if the object should be created if it doesn't exist in - * the table. - * - * This must be called with the object bucket locked. - */ -static int -__lock_getobj(lt, obj, ndx, create, retp) - DB_LOCKTAB *lt; - const DBT *obj; - u_int32_t ndx; - int create; - DB_LOCKOBJ **retp; -{ - DB_ENV *dbenv; - DB_LOCKOBJ *sh_obj; - DB_LOCKREGION *region; - int ret; - void *p; - - dbenv = lt->dbenv; - region = lt->reginfo.primary; - - /* Look up the object in the hash table. */ - HASHLOOKUP(lt->obj_tab, - ndx, __db_lockobj, links, obj, sh_obj, __lock_cmp); - - /* - * If we found the object, then we can just return it. If - * we didn't find the object, then we need to create it. - */ - if (sh_obj == NULL && create) { - /* Create new object and then insert it into hash table. */ - if ((sh_obj = - SH_TAILQ_FIRST(®ion->free_objs, __db_lockobj)) == NULL) { - ret = __lock_nomem(lt->dbenv, "object entries"); - goto err; - } - - /* - * If we can fit this object in the structure, do so instead - * of shalloc-ing space for it. - */ - if (obj->size <= sizeof(sh_obj->objdata)) - p = sh_obj->objdata; - else if ((ret = - __db_shalloc(<->reginfo, obj->size, 0, &p)) != 0) { - __db_err(dbenv, "No space for lock object storage"); - goto err; - } - - memcpy(p, obj->data, obj->size); - - SH_TAILQ_REMOVE( - ®ion->free_objs, sh_obj, links, __db_lockobj); - if (++region->stat.st_nobjects > region->stat.st_maxnobjects) - region->stat.st_maxnobjects = region->stat.st_nobjects; - - SH_TAILQ_INIT(&sh_obj->waiters); - SH_TAILQ_INIT(&sh_obj->holders); - sh_obj->lockobj.size = obj->size; - sh_obj->lockobj.off = - (roff_t)SH_PTR_TO_OFF(&sh_obj->lockobj, p); - - HASHINSERT(lt->obj_tab, ndx, __db_lockobj, links, sh_obj); - } - - *retp = sh_obj; - return (0); - -err: return (ret); -} - -/* - * __lock_is_parent -- - * Given a locker and a transaction, return 1 if the locker is - * an ancestor of the designated transaction. This is used to determine - * if we should grant locks that appear to conflict, but don't because - * the lock is already held by an ancestor. - */ -static int -__lock_is_parent(lt, locker, sh_locker) - DB_LOCKTAB *lt; - u_int32_t locker; - DB_LOCKER *sh_locker; -{ - DB_LOCKER *parent; - - parent = sh_locker; - while (parent->parent_locker != INVALID_ROFF) { - parent = R_ADDR(<->reginfo, parent->parent_locker); - if (parent->id == locker) - return (1); - } - - return (0); -} - -/* - * __lock_locker_is_parent -- - * Determine if "locker" is an ancestor of "child". - * *retp == 1 if so, 0 otherwise. - * - * PUBLIC: int __lock_locker_is_parent - * PUBLIC: __P((DB_ENV *, u_int32_t, u_int32_t, int *)); - */ -int -__lock_locker_is_parent(dbenv, locker, child, retp) - DB_ENV *dbenv; - u_int32_t locker, child; - int *retp; -{ - DB_LOCKER *sh_locker; - DB_LOCKREGION *region; - DB_LOCKTAB *lt; - u_int32_t locker_ndx; - int ret; - - lt = dbenv->lk_handle; - region = lt->reginfo.primary; - - LOCKER_LOCK(lt, region, child, locker_ndx); - if ((ret = - __lock_getlocker(lt, child, locker_ndx, 0, &sh_locker)) != 0) { - __db_err(dbenv, __db_locker_invalid); - return (ret); - } - - /* - * The locker may not exist for this transaction, if not then it has - * no parents. - */ - if (sh_locker == NULL) - *retp = 0; - else - *retp = __lock_is_parent(lt, locker, sh_locker); - return (0); -} - -/* - * __lock_inherit_locks -- - * Called on child commit to merge child's locks with parent's. - */ -static int -__lock_inherit_locks(lt, locker, flags) - DB_LOCKTAB *lt; - u_int32_t locker; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_LOCKER *sh_locker, *sh_parent; - DB_LOCKOBJ *obj; - DB_LOCKREGION *region; - int ret; - struct __db_lock *hlp, *lp; - u_int32_t ndx; - - region = lt->reginfo.primary; - dbenv = lt->dbenv; - - /* - * Get the committing locker and mark it as deleted. - * This allows us to traverse the locker links without - * worrying that someone else is deleting locks out - * from under us. However, if the locker doesn't - * exist, that just means that the child holds no - * locks, so inheritance is easy! - */ - LOCKER_LOCK(lt, region, locker, ndx); - if ((ret = __lock_getlocker(lt, - locker, ndx, 0, &sh_locker)) != 0 || - sh_locker == NULL || - F_ISSET(sh_locker, DB_LOCKER_DELETED)) { - if (ret == 0 && sh_locker != NULL) - ret = EINVAL; - __db_err(dbenv, __db_locker_invalid); - return (ret); - } - - /* Make sure we are a child transaction. */ - if (sh_locker->parent_locker == INVALID_ROFF) { - __db_err(dbenv, "Not a child transaction"); - return (EINVAL); - } - sh_parent = R_ADDR(<->reginfo, sh_locker->parent_locker); - F_SET(sh_locker, DB_LOCKER_DELETED); - - /* - * Now, lock the parent locker; move locks from - * the committing list to the parent's list. - */ - LOCKER_LOCK(lt, region, locker, ndx); - if (F_ISSET(sh_parent, DB_LOCKER_DELETED)) { - if (ret == 0) { - __db_err(dbenv, - "Parent locker is not valid"); - ret = EINVAL; - } - return (ret); - } - - /* - * In order to make it possible for a parent to have - * many, many children who lock the same objects, and - * not require an inordinate number of locks, we try - * to merge the child's locks with its parent's. - */ - for (lp = SH_LIST_FIRST(&sh_locker->heldby, __db_lock); - lp != NULL; - lp = SH_LIST_FIRST(&sh_locker->heldby, __db_lock)) { - SH_LIST_REMOVE(lp, locker_links, __db_lock); - - /* See if the parent already has a lock. */ - obj = (DB_LOCKOBJ *)((u_int8_t *)lp + lp->obj); - for (hlp = SH_TAILQ_FIRST(&obj->holders, __db_lock); - hlp != NULL; - hlp = SH_TAILQ_NEXT(hlp, links, __db_lock)) - if (hlp->holder == sh_parent->id && - lp->mode == hlp->mode) - break; - - if (hlp != NULL) { - /* Parent already holds lock. */ - hlp->refcount += lp->refcount; - - /* Remove lock from object list and free it. */ - DB_ASSERT(lp->status == DB_LSTAT_HELD); - SH_TAILQ_REMOVE(&obj->holders, lp, links, __db_lock); - (void)__lock_freelock(lt, lp, locker, DB_LOCK_FREE); - } else { - /* Just move lock to parent chains. */ - SH_LIST_INSERT_HEAD(&sh_parent->heldby, - lp, locker_links, __db_lock); - lp->holder = sh_parent->id; - } - - /* - * We may need to promote regardless of whether we simply - * moved the lock to the parent or changed the parent's - * reference count, because there might be a sibling waiting, - * who will now be allowed to make forward progress. - */ - if ((ret = __lock_promote( - lt, obj, NULL, LF_ISSET(DB_LOCK_NOWAITERS))) != 0) - return (ret); - } - - /* Transfer child counts to parent. */ - sh_parent->nlocks += sh_locker->nlocks; - sh_parent->nwrites += sh_locker->nwrites; - - return (ret); -} - -/* - * __lock_promote -- - * - * Look through the waiters and holders lists and decide which (if any) - * locks can be promoted. Promote any that are eligible. - * - * PUBLIC: int __lock_promote - * PUBLIC: __P((DB_LOCKTAB *, DB_LOCKOBJ *, int *, u_int32_t)); - */ -int -__lock_promote(lt, obj, state_changedp, flags) - DB_LOCKTAB *lt; - DB_LOCKOBJ *obj; - int *state_changedp; - u_int32_t flags; -{ - struct __db_lock *lp_w, *lp_h, *next_waiter; - DB_LOCKER *sh_locker; - DB_LOCKREGION *region; - u_int32_t locker_ndx; - int had_waiters, state_changed; - - region = lt->reginfo.primary; - had_waiters = 0; - - /* - * We need to do lock promotion. We also need to determine if we're - * going to need to run the deadlock detector again. If we release - * locks, and there are waiters, but no one gets promoted, then we - * haven't fundamentally changed the lockmgr state, so we may still - * have a deadlock and we have to run again. However, if there were - * no waiters, or we actually promoted someone, then we are OK and we - * don't have to run it immediately. - * - * During promotion, we look for state changes so we can return this - * information to the caller. - */ - - for (lp_w = SH_TAILQ_FIRST(&obj->waiters, __db_lock), - state_changed = lp_w == NULL; - lp_w != NULL; - lp_w = next_waiter) { - had_waiters = 1; - next_waiter = SH_TAILQ_NEXT(lp_w, links, __db_lock); - - /* Waiter may have aborted or expired. */ - if (lp_w->status != DB_LSTAT_WAITING) - continue; - /* Are we switching locks? */ - if (LF_ISSET(DB_LOCK_NOWAITERS) && lp_w->mode == DB_LOCK_WAIT) - continue; - - for (lp_h = SH_TAILQ_FIRST(&obj->holders, __db_lock); - lp_h != NULL; - lp_h = SH_TAILQ_NEXT(lp_h, links, __db_lock)) { - if (lp_h->holder != lp_w->holder && - CONFLICTS(lt, region, lp_h->mode, lp_w->mode)) { - LOCKER_LOCK(lt, - region, lp_w->holder, locker_ndx); - if ((__lock_getlocker(lt, lp_w->holder, - locker_ndx, 0, &sh_locker)) != 0) { - __db_err(lt->dbenv, - "Locker %#lx missing", - (u_long)lp_w->holder); - return (__db_panic(lt->dbenv, EINVAL)); - } - if (!__lock_is_parent(lt, - lp_h->holder, sh_locker)) - break; - } - } - if (lp_h != NULL) /* Found a conflict. */ - break; - - /* No conflict, promote the waiting lock. */ - SH_TAILQ_REMOVE(&obj->waiters, lp_w, links, __db_lock); - lp_w->status = DB_LSTAT_PENDING; - SH_TAILQ_INSERT_TAIL(&obj->holders, lp_w, links); - - /* Wake up waiter. */ - MUTEX_UNLOCK(lt->dbenv, lp_w->mtx_lock); - state_changed = 1; - } - - /* - * If this object had waiters and doesn't any more, then we need - * to remove it from the dd_obj list. - */ - if (had_waiters && SH_TAILQ_FIRST(&obj->waiters, __db_lock) == NULL) - SH_TAILQ_REMOVE(®ion->dd_objs, obj, dd_links, __db_lockobj); - - if (state_changedp != NULL) - *state_changedp = state_changed; - - return (0); -} - -/* - * __lock_remove_waiter -- - * Any lock on the waitlist has a process waiting for it. Therefore, - * we can't return the lock to the freelist immediately. Instead, we can - * remove the lock from the list of waiters, set the status field of the - * lock, and then let the process waking up return the lock to the - * free list. - * - * This must be called with the Object bucket locked. - */ -static int -__lock_remove_waiter(lt, sh_obj, lockp, status) - DB_LOCKTAB *lt; - DB_LOCKOBJ *sh_obj; - struct __db_lock *lockp; - db_status_t status; -{ - DB_LOCKREGION *region; - int do_wakeup; - - region = lt->reginfo.primary; - - do_wakeup = lockp->status == DB_LSTAT_WAITING; - - SH_TAILQ_REMOVE(&sh_obj->waiters, lockp, links, __db_lock); - lockp->links.stqe_prev = -1; - lockp->status = status; - if (SH_TAILQ_FIRST(&sh_obj->waiters, __db_lock) == NULL) - SH_TAILQ_REMOVE( - ®ion->dd_objs, - sh_obj, dd_links, __db_lockobj); - - /* - * Wake whoever is waiting on this lock. - */ - if (do_wakeup) - MUTEX_UNLOCK(lt->dbenv, lockp->mtx_lock); - - return (0); -} - -/* - * __lock_trade -- - * - * Trade locker ids on a lock. This is used to reassign file locks from - * a transactional locker id to a long-lived locker id. This should be - * called with the region mutex held. - */ -static int -__lock_trade(dbenv, lock, new_locker) - DB_ENV *dbenv; - DB_LOCK *lock; - u_int32_t new_locker; -{ - struct __db_lock *lp; - DB_LOCKREGION *region; - DB_LOCKTAB *lt; - DB_LOCKER *sh_locker; - int ret; - u_int32_t locker_ndx; - - lt = dbenv->lk_handle; - region = lt->reginfo.primary; - lp = R_ADDR(<->reginfo, lock->off); - - /* If the lock is already released, simply return. */ - if (lp->gen != lock->gen) - return (DB_NOTFOUND); - - /* Make sure that we can get new locker and add this lock to it. */ - LOCKER_LOCK(lt, region, new_locker, locker_ndx); - if ((ret = - __lock_getlocker(lt, new_locker, locker_ndx, 0, &sh_locker)) != 0) - return (ret); - - if (sh_locker == NULL) { - __db_err(dbenv, "Locker does not exist"); - return (EINVAL); - } - - /* Remove the lock from its current locker. */ - if ((ret = __lock_freelock(lt, lp, lp->holder, DB_LOCK_UNLINK)) != 0) - return (ret); - - /* Add lock to its new locker. */ - SH_LIST_INSERT_HEAD(&sh_locker->heldby, lp, locker_links, __db_lock); - sh_locker->nlocks++; - if (IS_WRITELOCK(lp->mode)) - sh_locker->nwrites++; - lp->holder = new_locker; - - return (0); -} diff --git a/storage/bdb/lock/lock_deadlock.c b/storage/bdb/lock/lock_deadlock.c deleted file mode 100644 index 17aa6e5af12..00000000000 --- a/storage/bdb/lock/lock_deadlock.c +++ /dev/null @@ -1,979 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: lock_deadlock.c,v 12.10 2005/10/07 20:21:30 ubell Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_shash.h" -#include "dbinc/lock.h" -#include "dbinc/log.h" -#include "dbinc/txn.h" - -#define ISSET_MAP(M, N) ((M)[(N) / 32] & (1 << ((N) % 32))) - -#define CLEAR_MAP(M, N) { \ - u_int32_t __i; \ - for (__i = 0; __i < (N); __i++) \ - (M)[__i] = 0; \ -} - -#define SET_MAP(M, B) ((M)[(B) / 32] |= (1 << ((B) % 32))) -#define CLR_MAP(M, B) ((M)[(B) / 32] &= ~((u_int)1 << ((B) % 32))) - -#define OR_MAP(D, S, N) { \ - u_int32_t __i; \ - for (__i = 0; __i < (N); __i++) \ - D[__i] |= S[__i]; \ -} -#define BAD_KILLID 0xffffffff - -typedef struct { - int valid; - int self_wait; - int in_abort; - u_int32_t count; - u_int32_t id; - roff_t last_lock; - roff_t last_obj; - u_int32_t last_locker_id; - db_pgno_t pgno; -} locker_info; - -static int __dd_abort __P((DB_ENV *, locker_info *, int *)); -static int __dd_build __P((DB_ENV *, - u_int32_t, u_int32_t **, u_int32_t *, u_int32_t *, locker_info **)); -static int __dd_find __P((DB_ENV *, - u_int32_t *, locker_info *, u_int32_t, u_int32_t, u_int32_t ***)); -static int __dd_isolder __P((u_int32_t, u_int32_t, u_int32_t, u_int32_t)); -static int __dd_verify __P((locker_info *, u_int32_t *, u_int32_t *, - u_int32_t *, u_int32_t, u_int32_t, u_int32_t)); - -#ifdef DIAGNOSTIC -static void __dd_debug - __P((DB_ENV *, locker_info *, u_int32_t *, u_int32_t, u_int32_t)); -#endif - -/* - * __lock_detect_pp -- - * DB_ENV->lock_detect pre/post processing. - * - * PUBLIC: int __lock_detect_pp __P((DB_ENV *, u_int32_t, u_int32_t, int *)); - */ -int -__lock_detect_pp(dbenv, flags, atype, abortp) - DB_ENV *dbenv; - u_int32_t flags, atype; - int *abortp; -{ - DB_THREAD_INFO *ip; - int ret; - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, - dbenv->lk_handle, "DB_ENV->lock_detect", DB_INIT_LOCK); - - /* Validate arguments. */ - if ((ret = __db_fchk(dbenv, "DB_ENV->lock_detect", flags, 0)) != 0) - return (ret); - switch (atype) { - case DB_LOCK_DEFAULT: - case DB_LOCK_EXPIRE: - case DB_LOCK_MAXLOCKS: - case DB_LOCK_MAXWRITE: - case DB_LOCK_MINLOCKS: - case DB_LOCK_MINWRITE: - case DB_LOCK_OLDEST: - case DB_LOCK_RANDOM: - case DB_LOCK_YOUNGEST: - break; - default: - __db_err(dbenv, - "DB_ENV->lock_detect: unknown deadlock detection mode specified"); - return (EINVAL); - } - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, (__lock_detect(dbenv, atype, abortp)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __lock_detect -- - * DB_ENV->lock_detect. - * - * PUBLIC: int __lock_detect __P((DB_ENV *, u_int32_t, int *)); - */ -int -__lock_detect(dbenv, atype, abortp) - DB_ENV *dbenv; - u_int32_t atype; - int *abortp; -{ - DB_LOCKREGION *region; - DB_LOCKTAB *lt; - db_timeval_t now; - locker_info *idmap; - u_int32_t *bitmap, *copymap, **deadp, **free_me, *tmpmap; - u_int32_t i, cid, keeper, killid, limit, nalloc, nlockers; - u_int32_t lock_max, txn_max; - int ret, status; - - /* - * If this environment is a replication client, then we must use the - * MINWRITE detection discipline. - */ - if (__rep_is_client(dbenv)) - atype = DB_LOCK_MINWRITE; - - free_me = NULL; - - lt = dbenv->lk_handle; - if (abortp != NULL) - *abortp = 0; - - /* Check if a detector run is necessary. */ - LOCK_SYSTEM_LOCK(dbenv); - - /* Make a pass only if auto-detect would run. */ - region = lt->reginfo.primary; - - LOCK_SET_TIME_INVALID(&now); - if (region->need_dd == 0 && - (!LOCK_TIME_ISVALID(®ion->next_timeout) || - !__lock_expired(dbenv, &now, ®ion->next_timeout))) { - LOCK_SYSTEM_UNLOCK(dbenv); - return (0); - } - if (region->need_dd == 0) - atype = DB_LOCK_EXPIRE; - - /* Reset need_dd, so we know we've run the detector. */ - region->need_dd = 0; - - /* Build the waits-for bitmap. */ - ret = __dd_build(dbenv, atype, &bitmap, &nlockers, &nalloc, &idmap); - lock_max = region->stat.st_cur_maxid; - LOCK_SYSTEM_UNLOCK(dbenv); - if (ret != 0 || atype == DB_LOCK_EXPIRE) - return (ret); - - /* If there are no lockers, there are no deadlocks. */ - if (nlockers == 0) - return (0); - -#ifdef DIAGNOSTIC - if (FLD_ISSET(dbenv->verbose, DB_VERB_WAITSFOR)) - __dd_debug(dbenv, idmap, bitmap, nlockers, nalloc); -#endif - - /* Now duplicate the bitmaps so we can verify deadlock participants. */ - if ((ret = __os_calloc(dbenv, (size_t)nlockers, - sizeof(u_int32_t) * nalloc, ©map)) != 0) - goto err; - memcpy(copymap, bitmap, nlockers * sizeof(u_int32_t) * nalloc); - - if ((ret = __os_calloc(dbenv, sizeof(u_int32_t), nalloc, &tmpmap)) != 0) - goto err1; - - /* Find a deadlock. */ - if ((ret = - __dd_find(dbenv, bitmap, idmap, nlockers, nalloc, &deadp)) != 0) - return (ret); - - /* - * We need the cur_maxid from the txn region as well. In order - * to avoid tricky synchronization between the lock and txn - * regions, we simply unlock the lock region and then lock the - * txn region. This introduces a small window during which the - * transaction system could then wrap. We're willing to return - * the wrong answer for "oldest" or "youngest" in those rare - * circumstances. - */ - if (TXN_ON(dbenv)) { - TXN_SYSTEM_LOCK(dbenv); - txn_max = ((DB_TXNREGION *)((DB_TXNMGR *) - dbenv->tx_handle)->reginfo.primary)->cur_maxid; - TXN_SYSTEM_UNLOCK(dbenv); - } else - txn_max = TXN_MAXIMUM; - - killid = BAD_KILLID; - free_me = deadp; - for (; *deadp != NULL; deadp++) { - if (abortp != NULL) - ++*abortp; - killid = (u_int32_t)(*deadp - bitmap) / nalloc; - limit = killid; - - /* - * There are cases in which our general algorithm will - * fail. Returning 1 from verify indicates that the - * particular locker is not only involved in a deadlock, - * but that killing him will allow others to make forward - * progress. Unfortunately, there are cases where we need - * to abort someone, but killing them will not necessarily - * ensure forward progress (imagine N readers all trying to - * acquire a write lock). - * killid is only set to lockers that pass the db_verify test. - * keeper will hold the best candidate even if it does - * not pass db_verify. Once we fill in killid then we do - * not need a keeper, but we keep updating it anyway. - */ - - keeper = idmap[killid].in_abort == 0 ? killid : BAD_KILLID; - if (keeper == BAD_KILLID || - __dd_verify(idmap, *deadp, - tmpmap, copymap, nlockers, nalloc, keeper) == 0) - killid = BAD_KILLID; - - if (killid != BAD_KILLID && - (atype == DB_LOCK_DEFAULT || atype == DB_LOCK_RANDOM)) - goto dokill; - - /* - * Start with the id that we know is deadlocked, then examine - * all other set bits and see if any are a better candidate - * for abortion and they are genuinely part of the deadlock. - * The definition of "best": - * MAXLOCKS: maximum count - * MAXWRITE: maximum write count - * MINLOCKS: minimum count - * MINWRITE: minimum write count - * OLDEST: smallest id - * YOUNGEST: largest id - */ - for (i = (limit + 1) % nlockers; - i != limit; - i = (i + 1) % nlockers) { - if (!ISSET_MAP(*deadp, i) || idmap[i].in_abort) - continue; - - /* - * Determine if we have a verified candidate - * in killid, if not then compare with the - * non-verified candidate in keeper. - */ - if (killid == BAD_KILLID) { - if (keeper == BAD_KILLID) - goto use_next; - else - cid = keeper; - } else - cid = killid; - - switch (atype) { - case DB_LOCK_OLDEST: - if (__dd_isolder(idmap[cid].id, - idmap[i].id, lock_max, txn_max)) - continue; - break; - case DB_LOCK_YOUNGEST: - if (__dd_isolder(idmap[i].id, - idmap[cid].id, lock_max, txn_max)) - continue; - break; - case DB_LOCK_MAXLOCKS: - if (idmap[i].count < idmap[cid].count) - continue; - break; - case DB_LOCK_MAXWRITE: - if (idmap[i].count < idmap[cid].count) - continue; - break; - case DB_LOCK_MINLOCKS: - case DB_LOCK_MINWRITE: - if (idmap[i].count > idmap[cid].count) - continue; - break; - case DB_LOCK_DEFAULT: - case DB_LOCK_RANDOM: - goto dokill; - - default: - killid = BAD_KILLID; - ret = EINVAL; - goto dokill; - } - -use_next: keeper = i; - if (__dd_verify(idmap, *deadp, - tmpmap, copymap, nlockers, nalloc, i)) - killid = i; - } - -dokill: if (killid == BAD_KILLID) { - if (keeper == BAD_KILLID) - /* - * It's conceivable that under XA, the - * locker could have gone away. - */ - continue; - else { - /* - * Removing a single locker will not - * break the deadlock, signal to run - * detection again. - */ - LOCK_SYSTEM_LOCK(dbenv); - region->need_dd = 1; - LOCK_SYSTEM_UNLOCK(dbenv); - killid = keeper; - } - } - - /* Kill the locker with lockid idmap[killid]. */ - if ((ret = __dd_abort(dbenv, &idmap[killid], &status)) != 0) - break; - - /* - * It's possible that the lock was already aborted; this isn't - * necessarily a problem, so do not treat it as an error. - */ - if (status != 0) { - if (status != DB_ALREADY_ABORTED) - __db_err(dbenv, - "warning: unable to abort locker %lx", - (u_long)idmap[killid].id); - } else if (FLD_ISSET(dbenv->verbose, DB_VERB_DEADLOCK)) - __db_msg(dbenv, - "Aborting locker %lx", (u_long)idmap[killid].id); - } - __os_free(dbenv, tmpmap); -err1: __os_free(dbenv, copymap); - -err: if (free_me != NULL) - __os_free(dbenv, free_me); - __os_free(dbenv, bitmap); - __os_free(dbenv, idmap); - - return (ret); -} - -/* - * ======================================================================== - * Utilities - */ - -#define DD_INVALID_ID ((u_int32_t) -1) - -static int -__dd_build(dbenv, atype, bmp, nlockers, allocp, idmap) - DB_ENV *dbenv; - u_int32_t atype, **bmp, *nlockers, *allocp; - locker_info **idmap; -{ - struct __db_lock *lp; - DB_LOCKER *lip, *lockerp, *child; - DB_LOCKOBJ *op, *lo; - DB_LOCKREGION *region; - DB_LOCKTAB *lt; - locker_info *id_array; - db_timeval_t now, min_timeout; - u_int32_t *bitmap, count, dd, *entryp, id, ndx, nentries, *tmpmap; - u_int8_t *pptr; - int is_first, ret; - - lt = dbenv->lk_handle; - region = lt->reginfo.primary; - LOCK_SET_TIME_INVALID(&now); - LOCK_SET_TIME_MAX(&min_timeout); - - /* - * While we always check for expired timeouts, if we are called with - * DB_LOCK_EXPIRE, then we are only checking for timeouts (i.e., not - * doing deadlock detection at all). If we aren't doing real deadlock - * detection, then we can skip a significant, amount of the processing. - * In particular we do not build the conflict array and our caller - * needs to expect this. - */ - if (atype == DB_LOCK_EXPIRE) { - for (op = SH_TAILQ_FIRST(®ion->dd_objs, __db_lockobj); - op != NULL; - op = SH_TAILQ_NEXT(op, dd_links, __db_lockobj)) - for (lp = SH_TAILQ_FIRST(&op->waiters, __db_lock); - lp != NULL; - lp = SH_TAILQ_NEXT(lp, links, __db_lock)) { - LOCKER_LOCK(lt, region, lp->holder, ndx); - if ((ret = __lock_getlocker(lt, - lp->holder, ndx, 0, &lockerp)) != 0) - continue; - if (lp->status == DB_LSTAT_WAITING) { - if (__lock_expired(dbenv, - &now, &lockerp->lk_expire)) { - lp->status = DB_LSTAT_EXPIRED; - MUTEX_UNLOCK( - dbenv, lp->mtx_lock); - continue; - } - if (LOCK_TIME_GREATER( - &min_timeout, &lockerp->lk_expire)) - min_timeout = - lockerp->lk_expire; - } - } - goto done; - } - - /* - * We'll check how many lockers there are, add a few more in for - * good measure and then allocate all the structures. Then we'll - * verify that we have enough room when we go back in and get the - * mutex the second time. - */ -retry: count = region->stat.st_nlockers; - if (count == 0) { - *nlockers = 0; - return (0); - } - - if (FLD_ISSET(dbenv->verbose, DB_VERB_DEADLOCK)) - __db_msg(dbenv, "%lu lockers", (u_long)count); - - count += 20; - nentries = (u_int32_t)DB_ALIGN(count, 32) / 32; - - /* - * Allocate enough space for a count by count bitmap matrix. - * - * XXX - * We can probably save the malloc's between iterations just - * reallocing if necessary because count grew by too much. - */ - if ((ret = __os_calloc(dbenv, (size_t)count, - sizeof(u_int32_t) * nentries, &bitmap)) != 0) - return (ret); - - if ((ret = __os_calloc(dbenv, - sizeof(u_int32_t), nentries, &tmpmap)) != 0) { - __os_free(dbenv, bitmap); - return (ret); - } - - if ((ret = __os_calloc(dbenv, - (size_t)count, sizeof(locker_info), &id_array)) != 0) { - __os_free(dbenv, bitmap); - __os_free(dbenv, tmpmap); - return (ret); - } - - /* - * Now go back in and actually fill in the matrix. - */ - if (region->stat.st_nlockers > count) { - __os_free(dbenv, bitmap); - __os_free(dbenv, tmpmap); - __os_free(dbenv, id_array); - goto retry; - } - - /* - * First we go through and assign each locker a deadlock detector id. - */ - for (id = 0, lip = SH_TAILQ_FIRST(®ion->lockers, __db_locker); - lip != NULL; - lip = SH_TAILQ_NEXT(lip, ulinks, __db_locker)) { - if (lip->master_locker == INVALID_ROFF) { - lip->dd_id = id++; - id_array[lip->dd_id].id = lip->id; - switch (atype) { - case DB_LOCK_MINLOCKS: - case DB_LOCK_MAXLOCKS: - id_array[lip->dd_id].count = lip->nlocks; - break; - case DB_LOCK_MINWRITE: - case DB_LOCK_MAXWRITE: - id_array[lip->dd_id].count = lip->nwrites; - break; - default: - break; - } - if (F_ISSET(lip, DB_LOCKER_INABORT)) - id_array[lip->dd_id].in_abort = 1; - } else - lip->dd_id = DD_INVALID_ID; - - } - - /* - * We only need consider objects that have waiters, so we use - * the list of objects with waiters (dd_objs) instead of traversing - * the entire hash table. For each object, we traverse the waiters - * list and add an entry in the waitsfor matrix for each waiter/holder - * combination. - */ - for (op = SH_TAILQ_FIRST(®ion->dd_objs, __db_lockobj); - op != NULL; op = SH_TAILQ_NEXT(op, dd_links, __db_lockobj)) { - CLEAR_MAP(tmpmap, nentries); - - /* - * First we go through and create a bit map that - * represents all the holders of this object. - */ - for (lp = SH_TAILQ_FIRST(&op->holders, __db_lock); - lp != NULL; - lp = SH_TAILQ_NEXT(lp, links, __db_lock)) { - LOCKER_LOCK(lt, region, lp->holder, ndx); - if ((ret = __lock_getlocker(lt, - lp->holder, ndx, 0, &lockerp)) != 0) - continue; - - if (lockerp->dd_id == DD_INVALID_ID) { - dd = ((DB_LOCKER *)R_ADDR(<->reginfo, - lockerp->master_locker))->dd_id; - lockerp->dd_id = dd; - switch (atype) { - case DB_LOCK_MINLOCKS: - case DB_LOCK_MAXLOCKS: - id_array[dd].count += lockerp->nlocks; - break; - case DB_LOCK_MINWRITE: - case DB_LOCK_MAXWRITE: - id_array[dd].count += lockerp->nwrites; - break; - default: - break; - } - if (F_ISSET(lockerp, DB_LOCKER_INABORT)) - id_array[dd].in_abort = 1; - - } else - dd = lockerp->dd_id; - id_array[dd].valid = 1; - - /* - * If the holder has already been aborted, then - * we should ignore it for now. - */ - if (lp->status == DB_LSTAT_HELD) - SET_MAP(tmpmap, dd); - } - - /* - * Next, for each waiter, we set its row in the matrix - * equal to the map of holders we set up above. - */ - for (is_first = 1, - lp = SH_TAILQ_FIRST(&op->waiters, __db_lock); - lp != NULL; - is_first = 0, - lp = SH_TAILQ_NEXT(lp, links, __db_lock)) { - LOCKER_LOCK(lt, region, lp->holder, ndx); - if ((ret = __lock_getlocker(lt, - lp->holder, ndx, 0, &lockerp)) != 0) - continue; - if (lp->status == DB_LSTAT_WAITING) { - if (__lock_expired(dbenv, - &now, &lockerp->lk_expire)) { - lp->status = DB_LSTAT_EXPIRED; - MUTEX_UNLOCK(dbenv, lp->mtx_lock); - continue; - } - if (LOCK_TIME_GREATER( - &min_timeout, &lockerp->lk_expire)) - min_timeout = lockerp->lk_expire; - } - - if (lockerp->dd_id == DD_INVALID_ID) { - dd = ((DB_LOCKER *)R_ADDR(<->reginfo, - lockerp->master_locker))->dd_id; - lockerp->dd_id = dd; - switch (atype) { - case DB_LOCK_MINLOCKS: - case DB_LOCK_MAXLOCKS: - id_array[dd].count += lockerp->nlocks; - break; - case DB_LOCK_MINWRITE: - case DB_LOCK_MAXWRITE: - id_array[dd].count += lockerp->nwrites; - break; - default: - break; - } - } else - dd = lockerp->dd_id; - id_array[dd].valid = 1; - - /* - * If the transaction is pending abortion, then - * ignore it on this iteration. - */ - if (lp->status != DB_LSTAT_WAITING) - continue; - - entryp = bitmap + (nentries * dd); - OR_MAP(entryp, tmpmap, nentries); - /* - * If this is the first waiter on the queue, - * then we remove the waitsfor relationship - * with oneself. However, if it's anywhere - * else on the queue, then we have to keep - * it and we have an automatic deadlock. - */ - if (is_first) { - if (ISSET_MAP(entryp, dd)) - id_array[dd].self_wait = 1; - CLR_MAP(entryp, dd); - } - } - } - - /* Now for each locker; record its last lock. */ - for (id = 0; id < count; id++) { - if (!id_array[id].valid) - continue; - LOCKER_LOCK(lt, region, id_array[id].id, ndx); - if ((ret = __lock_getlocker(lt, - id_array[id].id, ndx, 0, &lockerp)) != 0) { - __db_err(dbenv, - "No locks for locker %lu", (u_long)id_array[id].id); - continue; - } - - /* - * If this is a master transaction, try to - * find one of its children's locks first, - * as they are probably more recent. - */ - child = SH_LIST_FIRST(&lockerp->child_locker, __db_locker); - if (child != NULL) { - do { - lp = SH_LIST_FIRST(&child->heldby, __db_lock); - if (lp != NULL && - lp->status == DB_LSTAT_WAITING) { - id_array[id].last_locker_id = child->id; - goto get_lock; - } - child = SH_LIST_NEXT( - child, child_link, __db_locker); - } while (child != NULL); - } - lp = SH_LIST_FIRST(&lockerp->heldby, __db_lock); - if (lp != NULL) { - id_array[id].last_locker_id = lockerp->id; -get_lock: id_array[id].last_lock = R_OFFSET(<->reginfo, lp); - id_array[id].last_obj = lp->obj; - lo = (DB_LOCKOBJ *)((u_int8_t *)lp + lp->obj); - pptr = SH_DBT_PTR(&lo->lockobj); - if (lo->lockobj.size >= sizeof(db_pgno_t)) - memcpy(&id_array[id].pgno, - pptr, sizeof(db_pgno_t)); - else - id_array[id].pgno = 0; - } - } - - /* - * Pass complete, reset the deadlock detector bit. - */ - region->need_dd = 0; - - /* - * Now we can release everything except the bitmap matrix that we - * created. - */ - *nlockers = id; - *idmap = id_array; - *bmp = bitmap; - *allocp = nentries; - __os_free(dbenv, tmpmap); -done: if (LOCK_TIME_ISVALID(®ion->next_timeout)) { - if (LOCK_TIME_ISMAX(&min_timeout)) - LOCK_SET_TIME_INVALID(®ion->next_timeout); - else - region->next_timeout = min_timeout; - } - return (0); -} - -static int -__dd_find(dbenv, bmp, idmap, nlockers, nalloc, deadp) - DB_ENV *dbenv; - u_int32_t *bmp, nlockers, nalloc; - locker_info *idmap; - u_int32_t ***deadp; -{ - u_int32_t i, j, k, *mymap, *tmpmap, **retp; - u_int ndead, ndeadalloc; - int ret; - -#undef INITIAL_DEAD_ALLOC -#define INITIAL_DEAD_ALLOC 8 - - ndeadalloc = INITIAL_DEAD_ALLOC; - ndead = 0; - if ((ret = __os_malloc(dbenv, - ndeadalloc * sizeof(u_int32_t *), &retp)) != 0) - return (ret); - - /* - * For each locker, OR in the bits from the lockers on which that - * locker is waiting. - */ - for (mymap = bmp, i = 0; i < nlockers; i++, mymap += nalloc) { - if (!idmap[i].valid) - continue; - for (j = 0; j < nlockers; j++) { - if (!ISSET_MAP(mymap, j)) - continue; - - /* Find the map for this bit. */ - tmpmap = bmp + (nalloc * j); - OR_MAP(mymap, tmpmap, nalloc); - if (!ISSET_MAP(mymap, i)) - continue; - - /* Make sure we leave room for NULL. */ - if (ndead + 2 >= ndeadalloc) { - ndeadalloc <<= 1; - /* - * If the alloc fails, then simply return the - * deadlocks that we already have. - */ - if (__os_realloc(dbenv, - ndeadalloc * sizeof(u_int32_t), - &retp) != 0) { - retp[ndead] = NULL; - *deadp = retp; - return (0); - } - } - retp[ndead++] = mymap; - - /* Mark all participants in this deadlock invalid. */ - for (k = 0; k < nlockers; k++) - if (ISSET_MAP(mymap, k)) - idmap[k].valid = 0; - break; - } - } - retp[ndead] = NULL; - *deadp = retp; - return (0); -} - -static int -__dd_abort(dbenv, info, statusp) - DB_ENV *dbenv; - locker_info *info; - int *statusp; -{ - struct __db_lock *lockp; - DB_LOCKER *lockerp; - DB_LOCKOBJ *sh_obj; - DB_LOCKREGION *region; - DB_LOCKTAB *lt; - u_int32_t ndx; - int ret; - - *statusp = 0; - - lt = dbenv->lk_handle; - region = lt->reginfo.primary; - ret = 0; - - LOCK_SYSTEM_LOCK(dbenv); - - /* - * Get the locker. If it's gone or was aborted while we were - * detecting, return that. - */ - LOCKER_LOCK(lt, region, info->last_locker_id, ndx); - if ((ret = __lock_getlocker(lt, - info->last_locker_id, ndx, 0, &lockerp)) != 0) - goto err; - if (lockerp == NULL || F_ISSET(lockerp, DB_LOCKER_INABORT)) { - *statusp = DB_ALREADY_ABORTED; - goto out; - } - - /* - * Find the locker's last lock. It is possible for this lock to have - * been freed, either though a timeout or another detector run. - */ - if ((lockp = SH_LIST_FIRST(&lockerp->heldby, __db_lock)) == NULL) { - *statusp = DB_ALREADY_ABORTED; - goto out; - } - if (R_OFFSET(<->reginfo, lockp) != info->last_lock || - lockp->holder != lockerp->id || - lockp->obj != info->last_obj || lockp->status != DB_LSTAT_WAITING) { - *statusp = DB_ALREADY_ABORTED; - goto out; - } - - sh_obj = (DB_LOCKOBJ *)((u_int8_t *)lockp + lockp->obj); - - /* Abort lock, take it off list, and wake up this lock. */ - SHOBJECT_LOCK(lt, region, sh_obj, ndx); - lockp->status = DB_LSTAT_ABORTED; - SH_TAILQ_REMOVE(&sh_obj->waiters, lockp, links, __db_lock); - - /* - * Either the waiters list is now empty, in which case we remove - * it from dd_objs, or it is not empty, in which case we need to - * do promotion. - */ - if (SH_TAILQ_FIRST(&sh_obj->waiters, __db_lock) == NULL) - SH_TAILQ_REMOVE(®ion->dd_objs, - sh_obj, dd_links, __db_lockobj); - else - ret = __lock_promote(lt, sh_obj, NULL, 0); - MUTEX_UNLOCK(dbenv, lockp->mtx_lock); - - region->stat.st_ndeadlocks++; -err: -out: LOCK_SYSTEM_UNLOCK(dbenv); - return (ret); -} - -#ifdef DIAGNOSTIC -static void -__dd_debug(dbenv, idmap, bitmap, nlockers, nalloc) - DB_ENV *dbenv; - locker_info *idmap; - u_int32_t *bitmap, nlockers, nalloc; -{ - DB_MSGBUF mb; - u_int32_t i, j, *mymap; - - DB_MSGBUF_INIT(&mb); - - __db_msg(dbenv, "Waitsfor array\nWaiter:\tWaiting on:"); - for (mymap = bitmap, i = 0; i < nlockers; i++, mymap += nalloc) { - if (!idmap[i].valid) - continue; - - __db_msgadd(dbenv, &mb, /* Waiter. */ - "%lx/%lu:\t", (u_long)idmap[i].id, (u_long)idmap[i].pgno); - for (j = 0; j < nlockers; j++) - if (ISSET_MAP(mymap, j)) - __db_msgadd(dbenv, - &mb, " %lx", (u_long)idmap[j].id); - __db_msgadd(dbenv, &mb, " %lu", (u_long)idmap[i].last_lock); - DB_MSGBUF_FLUSH(dbenv, &mb); - } -} -#endif - -/* - * Given a bitmap that contains a deadlock, verify that the bit - * specified in the which parameter indicates a transaction that - * is actually deadlocked. Return 1 if really deadlocked, 0 otherwise. - * deadmap -- the array that identified the deadlock. - * tmpmap -- a copy of the initial bitmaps from the dd_build phase. - * origmap -- a temporary bit map into which we can OR things. - * nlockers -- the number of actual lockers under consideration. - * nalloc -- the number of words allocated for the bitmap. - * which -- the locker in question. - */ -static int -__dd_verify(idmap, deadmap, tmpmap, origmap, nlockers, nalloc, which) - locker_info *idmap; - u_int32_t *deadmap, *tmpmap, *origmap; - u_int32_t nlockers, nalloc, which; -{ - u_int32_t *tmap; - u_int32_t j; - int count; - - memset(tmpmap, 0, sizeof(u_int32_t) * nalloc); - - /* - * In order for "which" to be actively involved in - * the deadlock, removing him from the evaluation - * must remove the deadlock. So, we OR together everyone - * except which; if all the participants still have their - * bits set, then the deadlock persists and which does - * not participate. If the deadlock does not persist - * then "which" does participate. - */ - count = 0; - for (j = 0; j < nlockers; j++) { - if (!ISSET_MAP(deadmap, j) || j == which) - continue; - - /* Find the map for this bit. */ - tmap = origmap + (nalloc * j); - - /* - * We special case the first waiter who is also a holder, so - * we don't automatically call that a deadlock. However, if - * it really is a deadlock, we need the bit set now so that - * we treat the first waiter like other waiters. - */ - if (idmap[j].self_wait) - SET_MAP(tmap, j); - OR_MAP(tmpmap, tmap, nalloc); - count++; - } - - if (count == 1) - return (1); - - /* - * Now check the resulting map and see whether - * all participants still have their bit set. - */ - for (j = 0; j < nlockers; j++) { - if (!ISSET_MAP(deadmap, j) || j == which) - continue; - if (!ISSET_MAP(tmpmap, j)) - return (1); - } - return (0); -} - -/* - * __dd_isolder -- - * - * Figure out the relative age of two lockers. We make all lockers - * older than all transactions, because that's how it's worked - * historically (because lockers are lower ids). - */ -static int -__dd_isolder(a, b, lock_max, txn_max) - u_int32_t a, b; - u_int32_t lock_max, txn_max; -{ - u_int32_t max; - - /* Check for comparing lock-id and txnid. */ - if (a <= DB_LOCK_MAXID && b > DB_LOCK_MAXID) - return (1); - if (b <= DB_LOCK_MAXID && a > DB_LOCK_MAXID) - return (0); - - /* In the same space; figure out which one. */ - max = txn_max; - if (a <= DB_LOCK_MAXID) - max = lock_max; - - /* - * We can't get a 100% correct ordering, because we don't know - * where the current interval started and if there were older - * lockers outside the interval. We do the best we can. - */ - - /* - * Check for a wrapped case with ids above max. - */ - if (a > max && b < max) - return (1); - if (b > max && a < max) - return (0); - - return (a < b); -} diff --git a/storage/bdb/lock/lock_failchk.c b/storage/bdb/lock/lock_failchk.c deleted file mode 100644 index 8dcdadcc5b1..00000000000 --- a/storage/bdb/lock/lock_failchk.c +++ /dev/null @@ -1,105 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2005 - * Sleepycat Software. All rights reserved. - * - * $Id: lock_failchk.c,v 12.3 2005/10/14 15:06:44 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_shash.h" -#include "dbinc/lock.h" -#include "dbinc/txn.h" - -/* - * __lock_failchk -- - * Check for locks held by dead threads of control. - * - * PUBLIC: int __lock_failchk __P((DB_ENV *)); - */ -int -__lock_failchk(dbenv) - DB_ENV *dbenv; -{ - DB_LOCKER *lip; - DB_LOCKREGION *lrp; - DB_LOCKREQ request; - DB_LOCKTAB *lt; - u_int32_t i; - int ret; - char buf[DB_THREADID_STRLEN]; - - lt = dbenv->lk_handle; - lrp = lt->reginfo.primary; - -retry: LOCK_SYSTEM_LOCK(dbenv); - - ret = 0; - for (i = 0; i < lrp->locker_t_size; i++) - for (lip = - SH_TAILQ_FIRST(<->locker_tab[i], __db_locker); - lip != NULL; - lip = SH_TAILQ_NEXT(lip, links, __db_locker)) { - /* - * If the locker is transactional, we can ignore it; - * __txn_failchk aborts any transactions the locker - * is involved in. - */ - if (lip->id >= TXN_MINIMUM) - continue; - - /* If the locker is still alive, it's not a problem. */ - if (dbenv->is_alive(dbenv, lip->pid, lip->tid)) - continue; - - /* - * We can only deal with read locks. If the locker - * holds write locks we have to assume a Berkeley DB - * operation was interrupted with only 1-of-N pages - * modified. - */ - if (lip->nwrites != 0) { - ret = __db_failed(dbenv, - "locker has write locks", - lip->pid, lip->tid); - break; - } - - /* - * Discard the locker and its read locks. - */ - __db_msg(dbenv, "Freeing locks for locker %#lx: %s", - (u_long)lip->id, dbenv->thread_id_string( - dbenv, lip->pid, lip->tid, buf)); - LOCK_SYSTEM_UNLOCK(dbenv); - memset(&request, 0, sizeof(request)); - request.op = DB_LOCK_PUT_ALL; - if ((ret = __lock_vec( - dbenv, lip->id, 0, &request, 1, NULL)) != 0) - return (ret); - - /* - * This locker is most likely referenced by a cursor - * which is owned by a dead thread. Normally the - * cursor would be available for other threads - * but we assume the dead thread will never release - * it. - */ - if ((ret = __lock_freefamilylocker(lt, lip->id)) != 0) - return (ret); - goto retry; - } - - LOCK_SYSTEM_UNLOCK(dbenv); - - return (ret); -} diff --git a/storage/bdb/lock/lock_id.c b/storage/bdb/lock/lock_id.c deleted file mode 100644 index 3e6789b0663..00000000000 --- a/storage/bdb/lock/lock_id.c +++ /dev/null @@ -1,422 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: lock_id.c,v 12.10 2005/10/14 15:15:16 ubell Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#include <stdlib.h> -#endif - -#include "db_int.h" -#include "dbinc/db_shash.h" -#include "dbinc/lock.h" -#include "dbinc/log.h" - -/* - * __lock_id_pp -- - * DB_ENV->lock_id pre/post processing. - * - * PUBLIC: int __lock_id_pp __P((DB_ENV *, u_int32_t *)); - */ -int -__lock_id_pp(dbenv, idp) - DB_ENV *dbenv; - u_int32_t *idp; -{ - DB_THREAD_INFO *ip; - int ret; - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, - dbenv->lk_handle, "DB_ENV->lock_id", DB_INIT_LOCK); - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, (__lock_id(dbenv, idp, NULL)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __lock_id -- - * DB_ENV->lock_id. - * - * PUBLIC: int __lock_id __P((DB_ENV *, u_int32_t *, DB_LOCKER **)); - */ -int -__lock_id(dbenv, idp, lkp) - DB_ENV *dbenv; - u_int32_t *idp; - DB_LOCKER **lkp; -{ - DB_LOCKER *lk; - DB_LOCKTAB *lt; - DB_LOCKREGION *region; - u_int32_t id, *ids, locker_ndx; - int nids, ret; - - lt = dbenv->lk_handle; - region = lt->reginfo.primary; - ret = 0; - - id = DB_LOCK_INVALIDID; - lk = NULL; - - LOCK_SYSTEM_LOCK(dbenv); - - /* - * Allocate a new lock id. If we wrap around then we find the minimum - * currently in use and make sure we can stay below that. This code is - * similar to code in __txn_begin_int for recovering txn ids. - * - * Our current valid range can span the maximum valid value, so check - * for it and wrap manually. - */ - if (region->stat.st_id == DB_LOCK_MAXID && - region->stat.st_cur_maxid != DB_LOCK_MAXID) - region->stat.st_id = DB_LOCK_INVALIDID; - if (region->stat.st_id == region->stat.st_cur_maxid) { - if ((ret = __os_malloc(dbenv, - sizeof(u_int32_t) * region->stat.st_nlockers, &ids)) != 0) - goto err; - nids = 0; - for (lk = SH_TAILQ_FIRST(®ion->lockers, __db_locker); - lk != NULL; - lk = SH_TAILQ_NEXT(lk, ulinks, __db_locker)) - ids[nids++] = lk->id; - region->stat.st_id = DB_LOCK_INVALIDID; - region->stat.st_cur_maxid = DB_LOCK_MAXID; - if (nids != 0) - __db_idspace(ids, nids, - ®ion->stat.st_id, ®ion->stat.st_cur_maxid); - __os_free(dbenv, ids); - } - id = ++region->stat.st_id; - - /* Allocate a locker for this id. */ - LOCKER_LOCK(lt, region, id, locker_ndx); - ret = __lock_getlocker(lt, id, locker_ndx, 1, &lk); - -err: LOCK_SYSTEM_UNLOCK(dbenv); - - if (idp) - *idp = id; - if (lkp) - *lkp = lk; - return (ret); -} - -/* - * __lock_set_thread_id -- - * Set the thread_id in an existing locker. - * PUBLIC: void __lock_set_thread_id __P((DB_LOCKER *, pid_t, db_threadid_t)); - */ -void -__lock_set_thread_id(lref, pid, tid) - DB_LOCKER *lref; - pid_t pid; - db_threadid_t tid; -{ - lref->pid = pid; - lref->tid = tid; -} - -/* - * __lock_id_free_pp -- - * DB_ENV->lock_id_free pre/post processing. - * - * PUBLIC: int __lock_id_free_pp __P((DB_ENV *, u_int32_t)); - */ -int -__lock_id_free_pp(dbenv, id) - DB_ENV *dbenv; - u_int32_t id; -{ - DB_THREAD_INFO *ip; - int ret; - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, - dbenv->lk_handle, "DB_ENV->lock_id_free", DB_INIT_LOCK); - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, (__lock_id_free(dbenv, id)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __lock_id_free -- - * Free a locker id. - * - * PUBLIC: int __lock_id_free __P((DB_ENV *, u_int32_t)); - */ -int -__lock_id_free(dbenv, id) - DB_ENV *dbenv; - u_int32_t id; -{ - DB_LOCKER *sh_locker; - DB_LOCKTAB *lt; - DB_LOCKREGION *region; - u_int32_t locker_ndx; - int ret; - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, - dbenv->lk_handle, "DB_ENV->lock_id_free", DB_INIT_LOCK); - - lt = dbenv->lk_handle; - region = lt->reginfo.primary; - - LOCK_SYSTEM_LOCK(dbenv); - LOCKER_LOCK(lt, region, id, locker_ndx); - if ((ret = __lock_getlocker(lt, id, locker_ndx, 0, &sh_locker)) != 0) - goto err; - - if (sh_locker == NULL) { - __db_err(dbenv, "Unknown locker ID: %lx", (u_long)id); - ret = EINVAL; - goto err; - } - - if (sh_locker->nlocks != 0) { - __db_err(dbenv, "Locker still has locks"); - ret = EINVAL; - goto err; - } - - __lock_freelocker(lt, region, sh_locker, locker_ndx); - -err: LOCK_SYSTEM_UNLOCK(dbenv); - return (ret); -} - -/* - * __lock_id_set -- - * Set the current locker ID and current maximum unused ID (for - * testing purposes only). - * - * PUBLIC: int __lock_id_set __P((DB_ENV *, u_int32_t, u_int32_t)); - */ -int -__lock_id_set(dbenv, cur_id, max_id) - DB_ENV *dbenv; - u_int32_t cur_id, max_id; -{ - DB_LOCKTAB *lt; - DB_LOCKREGION *region; - - ENV_REQUIRES_CONFIG(dbenv, - dbenv->lk_handle, "lock_id_set", DB_INIT_LOCK); - - lt = dbenv->lk_handle; - region = lt->reginfo.primary; - region->stat.st_id = cur_id; - region->stat.st_cur_maxid = max_id; - - return (0); -} - -/* - * __lock_getlocker -- - * Get a locker in the locker hash table. The create parameter - * indicates if the locker should be created if it doesn't exist in - * the table. - * - * This must be called with the locker bucket locked. - * - * PUBLIC: int __lock_getlocker __P((DB_LOCKTAB *, - * PUBLIC: u_int32_t, u_int32_t, int, DB_LOCKER **)); - */ -int -__lock_getlocker(lt, locker, indx, create, retp) - DB_LOCKTAB *lt; - u_int32_t locker, indx; - int create; - DB_LOCKER **retp; -{ - DB_ENV *dbenv; - DB_LOCKER *sh_locker; - DB_LOCKREGION *region; - - dbenv = lt->dbenv; - region = lt->reginfo.primary; - - HASHLOOKUP(lt->locker_tab, - indx, __db_locker, links, locker, sh_locker, __lock_locker_cmp); - - /* - * If we found the locker, then we can just return it. If - * we didn't find the locker, then we need to create it. - */ - if (sh_locker == NULL && create) { - /* Create new locker and then insert it into hash table. */ - if ((sh_locker = SH_TAILQ_FIRST( - ®ion->free_lockers, __db_locker)) == NULL) - return (__lock_nomem(dbenv, "locker entries")); - SH_TAILQ_REMOVE( - ®ion->free_lockers, sh_locker, links, __db_locker); - if (++region->stat.st_nlockers > region->stat.st_maxnlockers) - region->stat.st_maxnlockers = region->stat.st_nlockers; - - sh_locker->id = locker; - dbenv->thread_id(dbenv, &sh_locker->pid, &sh_locker->tid); - sh_locker->dd_id = 0; - sh_locker->master_locker = INVALID_ROFF; - sh_locker->parent_locker = INVALID_ROFF; - SH_LIST_INIT(&sh_locker->child_locker); - sh_locker->flags = 0; - SH_LIST_INIT(&sh_locker->heldby); - sh_locker->nlocks = 0; - sh_locker->nwrites = 0; - sh_locker->lk_timeout = 0; - LOCK_SET_TIME_INVALID(&sh_locker->tx_expire); - LOCK_SET_TIME_INVALID(&sh_locker->lk_expire); - - HASHINSERT(lt->locker_tab, indx, __db_locker, links, sh_locker); - SH_TAILQ_INSERT_HEAD(®ion->lockers, - sh_locker, ulinks, __db_locker); - } - - *retp = sh_locker; - return (0); -} - -/* - * __lock_addfamilylocker - * Put a locker entry in for a child transaction. - * - * PUBLIC: int __lock_addfamilylocker __P((DB_ENV *, u_int32_t, u_int32_t)); - */ -int -__lock_addfamilylocker(dbenv, pid, id) - DB_ENV *dbenv; - u_int32_t pid, id; -{ - DB_LOCKER *lockerp, *mlockerp; - DB_LOCKREGION *region; - DB_LOCKTAB *lt; - u_int32_t ndx; - int ret; - - lt = dbenv->lk_handle; - region = lt->reginfo.primary; - LOCK_SYSTEM_LOCK(dbenv); - - /* get/create the parent locker info */ - LOCKER_LOCK(lt, region, pid, ndx); - if ((ret = __lock_getlocker(lt, pid, ndx, 1, &mlockerp)) != 0) - goto err; - - /* - * We assume that only one thread can manipulate - * a single transaction family. - * Therefore the master locker cannot go away while - * we manipulate it, nor can another child in the - * family be created at the same time. - */ - LOCKER_LOCK(lt, region, id, ndx); - if ((ret = __lock_getlocker(lt, id, ndx, 1, &lockerp)) != 0) - goto err; - - /* Point to our parent. */ - lockerp->parent_locker = R_OFFSET(<->reginfo, mlockerp); - - /* See if this locker is the family master. */ - if (mlockerp->master_locker == INVALID_ROFF) - lockerp->master_locker = R_OFFSET(<->reginfo, mlockerp); - else { - lockerp->master_locker = mlockerp->master_locker; - mlockerp = R_ADDR(<->reginfo, mlockerp->master_locker); - } - - /* - * Link the child at the head of the master's list. - * The guess is when looking for deadlock that - * the most recent child is the one thats blocked. - */ - SH_LIST_INSERT_HEAD( - &mlockerp->child_locker, lockerp, child_link, __db_locker); - -err: LOCK_SYSTEM_UNLOCK(dbenv); - - return (ret); -} - -/* - * __lock_freefamilylocker - * Remove a locker from the hash table and its family. - * - * This must be called without the locker bucket locked. - * - * PUBLIC: int __lock_freefamilylocker __P((DB_LOCKTAB *, u_int32_t)); - */ -int -__lock_freefamilylocker(lt, locker) - DB_LOCKTAB *lt; - u_int32_t locker; -{ - DB_ENV *dbenv; - DB_LOCKER *sh_locker; - DB_LOCKREGION *region; - u_int32_t indx; - int ret; - - dbenv = lt->dbenv; - region = lt->reginfo.primary; - - LOCK_SYSTEM_LOCK(dbenv); - LOCKER_LOCK(lt, region, locker, indx); - - if ((ret = __lock_getlocker(lt, - locker, indx, 0, &sh_locker)) != 0 || sh_locker == NULL) - goto err; - - if (SH_LIST_FIRST(&sh_locker->heldby, __db_lock) != NULL) { - ret = EINVAL; - __db_err(dbenv, "Freeing locker with locks"); - goto err; - } - - /* If this is part of a family, we must fix up its links. */ - if (sh_locker->master_locker != INVALID_ROFF) - SH_LIST_REMOVE(sh_locker, child_link, __db_locker); - - __lock_freelocker(lt, region, sh_locker, indx); - -err: LOCK_SYSTEM_UNLOCK(dbenv); - return (ret); -} - -/* - * __lock_freelocker - * Common code for deleting a locker; must be called with the - * locker bucket locked. - * - * PUBLIC: void __lock_freelocker - * PUBLIC: __P((DB_LOCKTAB *, DB_LOCKREGION *, DB_LOCKER *, u_int32_t)); - */ -void -__lock_freelocker(lt, region, sh_locker, indx) - DB_LOCKTAB *lt; - DB_LOCKREGION *region; - DB_LOCKER *sh_locker; - u_int32_t indx; - -{ - HASHREMOVE_EL( - lt->locker_tab, indx, __db_locker, links, sh_locker); - SH_TAILQ_INSERT_HEAD( - ®ion->free_lockers, sh_locker, links, __db_locker); - SH_TAILQ_REMOVE(®ion->lockers, sh_locker, ulinks, __db_locker); - region->stat.st_nlockers--; -} diff --git a/storage/bdb/lock/lock_list.c b/storage/bdb/lock/lock_list.c deleted file mode 100644 index c2bbd805ec7..00000000000 --- a/storage/bdb/lock/lock_list.c +++ /dev/null @@ -1,366 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: lock_list.c,v 12.5 2005/10/20 18:26:04 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#include <stdlib.h> -#endif - -#include "db_int.h" -#include "dbinc/db_shash.h" -#include "dbinc/lock.h" -#include "dbinc/log.h" - -static int __lock_sort_cmp __P((const void *, const void *)); - -/* - * Lock list routines. - * The list is composed of a 32-bit count of locks followed by - * each lock. A lock is represented by a 16-bit page-count, a lock - * object and a page list. A lock object consists of a 16-bit size - * and the object itself. In a pseudo BNF notation, you get: - * - * LIST = COUNT32 LOCK* - * LOCK = COUNT16 LOCKOBJ PAGELIST - * LOCKOBJ = COUNT16 OBJ - * PAGELIST = COUNT32* - * - * (Recall that X* means "0 or more X's") - * - * In most cases, the OBJ is a struct __db_ilock and the page list is - * a series of (32-bit) page numbers that should get written into the - * pgno field of the __db_ilock. So, the actual number of pages locked - * is the number of items in the PAGELIST plus 1. If this is an application- - * specific lock, then we cannot interpret obj and the pagelist must - * be empty. - * - * Consider a lock list for: File A, pages 1&2, File B pages 3-5, Applock - * This would be represented as: - * 5 1 [fid=A;page=1] 2 2 [fid=B;page=3] 4 5 0 APPLOCK - * ------------------ -------------------- --------- - * LOCK for file A LOCK for file B application-specific lock - */ - -#define MAX_PGNOS 0xffff - -/* - * These macros are bigger than one might expect because some compilers say a - * cast does not return an lvalue, so constructs like *(u_int32_t*)dp = count; - * generate warnings. - */ -#define RET_SIZE(size, count) ((size) + \ - sizeof(u_int32_t) + (count) * 2 * sizeof(u_int16_t)) - -#define PUT_COUNT(dp, count) do { u_int32_t *ip = (u_int32_t *)dp;\ - *ip = count; \ - dp = (u_int8_t *)dp + \ - sizeof(u_int32_t); \ - } while (0) -#define PUT_PCOUNT(dp, count) do { u_int16_t *ip = (u_int16_t *)dp;\ - *ip = count; \ - dp = (u_int8_t *)dp + \ - sizeof(u_int16_t); \ - } while (0) -#define PUT_SIZE(dp, size) do { u_int16_t *ip = (u_int16_t *)dp;\ - *ip = size; \ - dp = (u_int8_t *)dp + \ - sizeof(u_int16_t); \ - } while (0) -#define PUT_PGNO(dp, pgno) do { db_pgno_t *ip = (db_pgno_t *)dp;\ - *ip = pgno; \ - dp = (u_int8_t *)dp + \ - sizeof(db_pgno_t); \ - } while (0) -#define COPY_OBJ(dp, obj) do { \ - memcpy(dp, \ - (obj)->data, (obj)->size); \ - dp = (u_int8_t *)dp + \ - DB_ALIGN((obj)->size, \ - sizeof(u_int32_t)); \ - } while (0) -#define GET_COUNT(dp, count) do { \ - (count) = *(u_int32_t *)dp; \ - dp = (u_int8_t *)dp + \ - sizeof(u_int32_t); \ - } while (0) -#define GET_PCOUNT(dp, count) do { \ - (count) = *(u_int16_t *)dp; \ - dp = (u_int8_t *)dp + \ - sizeof(u_int16_t); \ - } while (0) -#define GET_SIZE(dp, size) do { \ - (size) = *(u_int16_t *)dp; \ - dp = (u_int8_t *)dp + \ - sizeof(u_int16_t); \ - } while (0) -#define GET_PGNO(dp, pgno) do { \ - (pgno) = *(db_pgno_t *)dp; \ - dp = (u_int8_t *)dp + \ - sizeof(db_pgno_t); \ - } while (0) - -/* - * __lock_fix_list -- - * - * PUBLIC: int __lock_fix_list __P((DB_ENV *, DBT *, u_int32_t)); - */ -int -__lock_fix_list(dbenv, list_dbt, nlocks) - DB_ENV *dbenv; - DBT *list_dbt; - u_int32_t nlocks; -{ - DBT *obj; - DB_LOCK_ILOCK *lock, *plock; - u_int32_t i, j, nfid, npgno, size; - u_int8_t *data, *dp; - int ret; - - if ((size = list_dbt->size) == 0) - return (0); - - obj = (DBT *)list_dbt->data; - - /* - * If necessary sort the list of locks so that locks on the same fileid - * are together. We do not sort 1 or 2 locks because by definition if - * there are locks on the same fileid they will be together. The sort - * will also move any locks that do not look like page locks to the end - * of the list so we can stop looking for locks we can combine when we - * hit one. - */ - switch (nlocks) { - case 1: - size = RET_SIZE(obj->size, 1); - if ((ret = __os_malloc(dbenv, size, &data)) != 0) - return (ret); - - dp = data; - PUT_COUNT(dp, 1); - PUT_PCOUNT(dp, 0); - PUT_SIZE(dp, obj->size); - COPY_OBJ(dp, obj); - break; - default: - /* Sort so that all locks with same fileid are together. */ - qsort(list_dbt->data, nlocks, sizeof(DBT), __lock_sort_cmp); - /* FALLTHROUGH */ - case 2: - nfid = npgno = 0; - i = 0; - if (obj->size != sizeof(DB_LOCK_ILOCK)) - goto not_ilock; - - nfid = 1; - plock = (DB_LOCK_ILOCK *)obj->data; - - /* We use ulen to keep track of the number of pages. */ - j = 0; - obj[0].ulen = 0; - for (i = 1; i < nlocks; i++) { - if (obj[i].size != sizeof(DB_LOCK_ILOCK)) - break; - lock = (DB_LOCK_ILOCK *)obj[i].data; - if (obj[j].ulen < MAX_PGNOS && - lock->type == plock->type && - memcmp(lock->fileid, - plock->fileid, DB_FILE_ID_LEN) == 0) { - obj[j].ulen++; - npgno++; - } else { - nfid++; - plock = lock; - j = i; - obj[j].ulen = 0; - } - } - -not_ilock: size = nfid * sizeof(DB_LOCK_ILOCK); - size += npgno * sizeof(db_pgno_t); - /* Add the number of nonstandard locks and get their size. */ - nfid += nlocks - i; - for (; i < nlocks; i++) { - size += obj[i].size; - obj[i].ulen = 0; - } - - size = RET_SIZE(size, nfid); - if ((ret = __os_malloc(dbenv, size, &data)) != 0) - return (ret); - - dp = data; - PUT_COUNT(dp, nfid); - - for (i = 0; i < nlocks; i = j) { - PUT_PCOUNT(dp, obj[i].ulen); - PUT_SIZE(dp, obj[i].size); - COPY_OBJ(dp, &obj[i]); - lock = (DB_LOCK_ILOCK *)obj[i].data; - for (j = i + 1; j <= i + obj[i].ulen; j++) { - lock = (DB_LOCK_ILOCK *)obj[j].data; - PUT_PGNO(dp, lock->pgno); - } - } - } - - __os_free(dbenv, list_dbt->data); - - list_dbt->data = data; - list_dbt->size = size; - - return (0); -} - -/* - * PUBLIC: int __lock_get_list __P((DB_ENV *, u_int32_t, u_int32_t, - * PUBLIC: db_lockmode_t, DBT *)); - */ -int -__lock_get_list(dbenv, locker, flags, lock_mode, list) - DB_ENV *dbenv; - u_int32_t locker, flags; - db_lockmode_t lock_mode; - DBT *list; -{ - DBT obj_dbt; - DB_LOCK ret_lock; - DB_LOCK_ILOCK *lock; - DB_LOCKTAB *lt; - db_pgno_t save_pgno; - u_int16_t npgno, size; - u_int32_t i, nlocks; - int ret; - void *data, *dp; - - if (list->size == 0) - return (0); - ret = 0; - data = NULL; - - lt = dbenv->lk_handle; - dp = list->data; - - /* - * There is no assurance log records will be aligned. If not, then - * copy the data to an aligned region so the rest of the code does - * not have to worry about it. - */ - if ((uintptr_t)dp != DB_ALIGN((uintptr_t)dp, sizeof(u_int32_t))) { - if ((ret = __os_malloc(dbenv, list->size, &data)) != 0) - return (ret); - memcpy(data, list->data, list->size); - dp = data; - } - - GET_COUNT(dp, nlocks); - LOCK_SYSTEM_LOCK(dbenv); - - for (i = 0; i < nlocks; i++) { - GET_PCOUNT(dp, npgno); - GET_SIZE(dp, size); - lock = (DB_LOCK_ILOCK *) dp; - save_pgno = lock->pgno; - obj_dbt.data = dp; - obj_dbt.size = size; - dp = ((u_int8_t *)dp) + DB_ALIGN(size, sizeof(u_int32_t)); - do { - if ((ret = __lock_get_internal(lt, locker, - flags, &obj_dbt, lock_mode, 0, &ret_lock)) != 0) { - lock->pgno = save_pgno; - goto err; - } - if (npgno != 0) - GET_PGNO(dp, lock->pgno); - } while (npgno-- != 0); - lock->pgno = save_pgno; - } - -err: LOCK_SYSTEM_UNLOCK(dbenv); - if (data != NULL) - __os_free(dbenv, data); - return (ret); -} - -#define UINT32_CMP(A, B) ((A) == (B) ? 0 : ((A) > (B) ? 1 : -1)) -static int -__lock_sort_cmp(a, b) - const void *a, *b; -{ - const DBT *d1, *d2; - DB_LOCK_ILOCK *l1, *l2; - - d1 = a; - d2 = b; - - /* Force all non-standard locks to sort at end. */ - if (d1->size != sizeof(DB_LOCK_ILOCK)) { - if (d2->size != sizeof(DB_LOCK_ILOCK)) - return (UINT32_CMP(d1->size, d2->size)); - else - return (1); - } else if (d2->size != sizeof(DB_LOCK_ILOCK)) - return (-1); - - l1 = d1->data; - l2 = d2->data; - if (l1->type != l2->type) - return (UINT32_CMP(l1->type, l2->type)); - return (memcmp(l1->fileid, l2->fileid, DB_FILE_ID_LEN)); -} - -/* - * PUBLIC: void __lock_list_print __P((DB_ENV *, DBT *)); - */ -void -__lock_list_print(dbenv, list) - DB_ENV *dbenv; - DBT *list; -{ - DB_LOCK_ILOCK *lock; - db_pgno_t pgno; - u_int16_t npgno, size; - u_int32_t i, nlocks; - u_int8_t *fidp; - char *namep; - void *dp; - - if (list->size == 0) - return; - dp = list->data; - - GET_COUNT(dp, nlocks); - - for (i = 0; i < nlocks; i++) { - GET_PCOUNT(dp, npgno); - GET_SIZE(dp, size); - lock = (DB_LOCK_ILOCK *) dp; - fidp = lock->fileid; - if (__dbreg_get_name(dbenv, fidp, &namep) != 0) - namep = NULL; - printf("\t"); - if (namep == NULL) - printf("(%lx %lx %lx %lx %lx)", - (u_long)fidp[0], (u_long)fidp[1], (u_long)fidp[2], - (u_long)fidp[3], (u_long)fidp[4]); - else - printf("%-25s", namep); - dp = ((u_int8_t *)dp) + DB_ALIGN(size, sizeof(u_int32_t)); - pgno = lock->pgno; - do { - printf(" %d", pgno); - if (npgno != 0) - GET_PGNO(dp, pgno); - } while (npgno-- != 0); - printf("\n"); - } -} diff --git a/storage/bdb/lock/lock_method.c b/storage/bdb/lock/lock_method.c deleted file mode 100644 index 0548f50ca15..00000000000 --- a/storage/bdb/lock/lock_method.c +++ /dev/null @@ -1,451 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: lock_method.c,v 12.6 2005/08/08 14:56:49 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_shash.h" -#include "dbinc/lock.h" - -/* - * __lock_dbenv_create -- - * Lock specific creation of the DB_ENV structure. - * - * PUBLIC: void __lock_dbenv_create __P((DB_ENV *)); - */ -void -__lock_dbenv_create(dbenv) - DB_ENV *dbenv; -{ - /* - * !!! - * Our caller has not yet had the opportunity to reset the panic - * state or turn off mutex locking, and so we can neither check - * the panic state or acquire a mutex in the DB_ENV create path. - */ - dbenv->lk_max = DB_LOCK_DEFAULT_N; - dbenv->lk_max_lockers = DB_LOCK_DEFAULT_N; - dbenv->lk_max_objects = DB_LOCK_DEFAULT_N; -} - -/* - * __lock_dbenv_close -- - * Lock specific destruction of the DB_ENV structure. - * - * PUBLIC: int __lock_dbenv_close __P((DB_ENV *)); - */ -int -__lock_dbenv_close(dbenv) - DB_ENV *dbenv; -{ - if (dbenv->lk_conflicts != NULL) { - __os_free(dbenv, dbenv->lk_conflicts); - dbenv->lk_conflicts = NULL; - } - - return (0); -} - -/* - * __lock_get_lk_conflicts - * Get the conflicts matrix. - * - * PUBLIC: int __lock_get_lk_conflicts - * PUBLIC: __P((DB_ENV *, const u_int8_t **, int *)); - */ -int -__lock_get_lk_conflicts(dbenv, lk_conflictsp, lk_modesp) - DB_ENV *dbenv; - const u_int8_t **lk_conflictsp; - int *lk_modesp; -{ - DB_LOCKTAB *lt; - - ENV_NOT_CONFIGURED(dbenv, - dbenv->lk_handle, "DB_ENV->get_lk_conflicts", DB_INIT_LOCK); - - lt = dbenv->lk_handle; - - if (LOCKING_ON(dbenv)) { - /* Cannot be set after open, no lock required to read. */ - if (lk_conflictsp != NULL) - *lk_conflictsp = lt->conflicts; - if (lk_modesp != NULL) - *lk_modesp = ((DB_LOCKREGION *) - (lt->reginfo.primary))->stat.st_nmodes; - } else { - if (lk_conflictsp != NULL) - *lk_conflictsp = dbenv->lk_conflicts; - if (lk_modesp != NULL) - *lk_modesp = dbenv->lk_modes; - } - return (0); -} - -/* - * __lock_set_lk_conflicts - * Set the conflicts matrix. - * - * PUBLIC: int __lock_set_lk_conflicts __P((DB_ENV *, u_int8_t *, int)); - */ -int -__lock_set_lk_conflicts(dbenv, lk_conflicts, lk_modes) - DB_ENV *dbenv; - u_int8_t *lk_conflicts; - int lk_modes; -{ - int ret; - - ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_lk_conflicts"); - - if (dbenv->lk_conflicts != NULL) { - __os_free(dbenv, dbenv->lk_conflicts); - dbenv->lk_conflicts = NULL; - } - if ((ret = __os_malloc(dbenv, - (size_t)(lk_modes * lk_modes), &dbenv->lk_conflicts)) != 0) - return (ret); - memcpy( - dbenv->lk_conflicts, lk_conflicts, (size_t)(lk_modes * lk_modes)); - dbenv->lk_modes = lk_modes; - - return (0); -} - -/* - * PUBLIC: int __lock_get_lk_detect __P((DB_ENV *, u_int32_t *)); - */ -int -__lock_get_lk_detect(dbenv, lk_detectp) - DB_ENV *dbenv; - u_int32_t *lk_detectp; -{ - DB_LOCKTAB *lt; - - ENV_NOT_CONFIGURED(dbenv, - dbenv->lk_handle, "DB_ENV->get_lk_detect", DB_INIT_LOCK); - - if (LOCKING_ON(dbenv)) { - lt = dbenv->lk_handle; - LOCK_SYSTEM_LOCK(dbenv); - *lk_detectp = ((DB_LOCKREGION *)lt->reginfo.primary)->detect; - LOCK_SYSTEM_UNLOCK(dbenv); - } else - *lk_detectp = dbenv->lk_detect; - return (0); -} - -/* - * __lock_set_lk_detect - * DB_ENV->set_lk_detect. - * - * PUBLIC: int __lock_set_lk_detect __P((DB_ENV *, u_int32_t)); - */ -int -__lock_set_lk_detect(dbenv, lk_detect) - DB_ENV *dbenv; - u_int32_t lk_detect; -{ - DB_LOCKTAB *lt; - DB_LOCKREGION *region; - int ret; - - ENV_NOT_CONFIGURED(dbenv, - dbenv->lk_handle, "DB_ENV->set_lk_detect", DB_INIT_LOCK); - - switch (lk_detect) { - case DB_LOCK_DEFAULT: - case DB_LOCK_EXPIRE: - case DB_LOCK_MAXLOCKS: - case DB_LOCK_MAXWRITE: - case DB_LOCK_MINLOCKS: - case DB_LOCK_MINWRITE: - case DB_LOCK_OLDEST: - case DB_LOCK_RANDOM: - case DB_LOCK_YOUNGEST: - break; - default: - __db_err(dbenv, - "DB_ENV->set_lk_detect: unknown deadlock detection mode specified"); - return (EINVAL); - } - - ret = 0; - if (LOCKING_ON(dbenv)) { - lt = dbenv->lk_handle; - region = lt->reginfo.primary; - LOCK_SYSTEM_LOCK(dbenv); - /* - * Check for incompatible automatic deadlock detection requests. - * There are scenarios where changing the detector configuration - * is reasonable, but we disallow them guessing it is likely to - * be an application error. - * - * We allow applications to turn on the lock detector, and we - * ignore attempts to set it to the default or current value. - */ - if (region->detect != DB_LOCK_NORUN && - lk_detect != DB_LOCK_DEFAULT && - region->detect != lk_detect) { - __db_err(dbenv, - "DB_ENV->set_lk_detect: incompatible deadlock detector mode"); - ret = EINVAL; - } else - if (region->detect == DB_LOCK_NORUN) - region->detect = lk_detect; - LOCK_SYSTEM_UNLOCK(dbenv); - } else - dbenv->lk_detect = lk_detect; - - return (ret); -} - -/* - * __lock_set_lk_max - * DB_ENV->set_lk_max. - * - * PUBLIC: int __lock_set_lk_max __P((DB_ENV *, u_int32_t)); - */ -int -__lock_set_lk_max(dbenv, lk_max) - DB_ENV *dbenv; - u_int32_t lk_max; -{ - ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_lk_max"); - - dbenv->lk_max = lk_max; - dbenv->lk_max_objects = lk_max; - dbenv->lk_max_lockers = lk_max; - return (0); -} - -/* - * PUBLIC: int __lock_get_lk_max_locks __P((DB_ENV *, u_int32_t *)); - */ -int -__lock_get_lk_max_locks(dbenv, lk_maxp) - DB_ENV *dbenv; - u_int32_t *lk_maxp; -{ - ENV_NOT_CONFIGURED(dbenv, - dbenv->lk_handle, "DB_ENV->get_lk_maxlocks", DB_INIT_LOCK); - - if (LOCKING_ON(dbenv)) { - /* Cannot be set after open, no lock required to read. */ - *lk_maxp = ((DB_LOCKREGION *)((DB_LOCKTAB *) - dbenv->lk_handle)->reginfo.primary)->stat.st_maxlocks; - } else - *lk_maxp = dbenv->lk_max; - return (0); -} - -/* - * __lock_set_lk_max_locks - * DB_ENV->set_lk_max_locks. - * - * PUBLIC: int __lock_set_lk_max_locks __P((DB_ENV *, u_int32_t)); - */ -int -__lock_set_lk_max_locks(dbenv, lk_max) - DB_ENV *dbenv; - u_int32_t lk_max; -{ - ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_lk_max_locks"); - - dbenv->lk_max = lk_max; - return (0); -} - -/* - * PUBLIC: int __lock_get_lk_max_lockers __P((DB_ENV *, u_int32_t *)); - */ -int -__lock_get_lk_max_lockers(dbenv, lk_maxp) - DB_ENV *dbenv; - u_int32_t *lk_maxp; -{ - ENV_NOT_CONFIGURED(dbenv, - dbenv->lk_handle, "DB_ENV->get_lk_max_lockers", DB_INIT_LOCK); - - if (LOCKING_ON(dbenv)) { - /* Cannot be set after open, no lock required to read. */ - *lk_maxp = ((DB_LOCKREGION *)((DB_LOCKTAB *) - dbenv->lk_handle)->reginfo.primary)->stat.st_maxlockers; - } else - *lk_maxp = dbenv->lk_max_lockers; - return (0); -} - -/* - * __lock_set_lk_max_lockers - * DB_ENV->set_lk_max_lockers. - * - * PUBLIC: int __lock_set_lk_max_lockers __P((DB_ENV *, u_int32_t)); - */ -int -__lock_set_lk_max_lockers(dbenv, lk_max) - DB_ENV *dbenv; - u_int32_t lk_max; -{ - ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_lk_max_lockers"); - - dbenv->lk_max_lockers = lk_max; - return (0); -} - -/* - * PUBLIC: int __lock_get_lk_max_objects __P((DB_ENV *, u_int32_t *)); - */ -int -__lock_get_lk_max_objects(dbenv, lk_maxp) - DB_ENV *dbenv; - u_int32_t *lk_maxp; -{ - ENV_NOT_CONFIGURED(dbenv, - dbenv->lk_handle, "DB_ENV->get_lk_max_objects", DB_INIT_LOCK); - - if (LOCKING_ON(dbenv)) { - /* Cannot be set after open, no lock required to read. */ - *lk_maxp = ((DB_LOCKREGION *)((DB_LOCKTAB *) - dbenv->lk_handle)->reginfo.primary)->stat.st_maxobjects; - } else - *lk_maxp = dbenv->lk_max_objects; - return (0); -} - -/* - * __lock_set_lk_max_objects - * DB_ENV->set_lk_max_objects. - * - * PUBLIC: int __lock_set_lk_max_objects __P((DB_ENV *, u_int32_t)); - */ -int -__lock_set_lk_max_objects(dbenv, lk_max) - DB_ENV *dbenv; - u_int32_t lk_max; -{ - ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_lk_max_objects"); - - dbenv->lk_max_objects = lk_max; - return (0); -} - -/* - * PUBLIC: int __lock_get_env_timeout - * PUBLIC: __P((DB_ENV *, db_timeout_t *, u_int32_t)); - */ -int -__lock_get_env_timeout(dbenv, timeoutp, flag) - DB_ENV *dbenv; - db_timeout_t *timeoutp; - u_int32_t flag; -{ - DB_LOCKTAB *lt; - DB_LOCKREGION *region; - int ret; - - ENV_NOT_CONFIGURED(dbenv, - dbenv->lk_handle, "DB_ENV->get_env_timeout", DB_INIT_LOCK); - - ret = 0; - if (LOCKING_ON(dbenv)) { - lt = dbenv->lk_handle; - region = lt->reginfo.primary; - LOCK_SYSTEM_LOCK(dbenv); - switch (flag) { - case DB_SET_LOCK_TIMEOUT: - *timeoutp = region->lk_timeout; - break; - case DB_SET_TXN_TIMEOUT: - *timeoutp = region->tx_timeout; - break; - default: - ret = 1; - break; - } - LOCK_SYSTEM_UNLOCK(dbenv); - } else - switch (flag) { - case DB_SET_LOCK_TIMEOUT: - *timeoutp = dbenv->lk_timeout; - break; - case DB_SET_TXN_TIMEOUT: - *timeoutp = dbenv->tx_timeout; - break; - default: - ret = 1; - break; - } - - if (ret) - ret = __db_ferr(dbenv, "DB_ENV->get_timeout", 0); - - return (ret); -} - -/* - * __lock_set_env_timeout - * DB_ENV->set_lock_timeout. - * - * PUBLIC: int __lock_set_env_timeout __P((DB_ENV *, db_timeout_t, u_int32_t)); - */ -int -__lock_set_env_timeout(dbenv, timeout, flags) - DB_ENV *dbenv; - db_timeout_t timeout; - u_int32_t flags; -{ - DB_LOCKTAB *lt; - DB_LOCKREGION *region; - int ret; - - ENV_NOT_CONFIGURED(dbenv, - dbenv->lk_handle, "DB_ENV->set_env_timeout", DB_INIT_LOCK); - - ret = 0; - if (LOCKING_ON(dbenv)) { - lt = dbenv->lk_handle; - region = lt->reginfo.primary; - LOCK_SYSTEM_LOCK(dbenv); - switch (flags) { - case DB_SET_LOCK_TIMEOUT: - region->lk_timeout = timeout; - break; - case DB_SET_TXN_TIMEOUT: - region->tx_timeout = timeout; - break; - default: - ret = 1; - break; - } - LOCK_SYSTEM_UNLOCK(dbenv); - } else - switch (flags) { - case DB_SET_LOCK_TIMEOUT: - dbenv->lk_timeout = timeout; - break; - case DB_SET_TXN_TIMEOUT: - dbenv->tx_timeout = timeout; - break; - default: - ret = 1; - break; - } - - if (ret) - ret = __db_ferr(dbenv, "DB_ENV->set_timeout", 0); - - return (ret); -} diff --git a/storage/bdb/lock/lock_region.c b/storage/bdb/lock/lock_region.c deleted file mode 100644 index f616f40699a..00000000000 --- a/storage/bdb/lock/lock_region.c +++ /dev/null @@ -1,400 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: lock_region.c,v 12.6 2005/10/07 20:21:31 ubell Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_shash.h" -#include "dbinc/lock.h" - -static int __lock_region_init __P((DB_ENV *, DB_LOCKTAB *)); -static size_t - __lock_region_size __P((DB_ENV *)); - -/* - * The conflict arrays are set up such that the row is the lock you are - * holding and the column is the lock that is desired. - */ -#define DB_LOCK_RIW_N 9 -static const u_int8_t db_riw_conflicts[] = { -/* N R W WT IW IR RIW DR WW */ -/* N */ 0, 0, 0, 0, 0, 0, 0, 0, 0, -/* R */ 0, 0, 1, 0, 1, 0, 1, 0, 1, -/* W */ 0, 1, 1, 1, 1, 1, 1, 1, 1, -/* WT */ 0, 0, 0, 0, 0, 0, 0, 0, 0, -/* IW */ 0, 1, 1, 0, 0, 0, 0, 1, 1, -/* IR */ 0, 0, 1, 0, 0, 0, 0, 0, 1, -/* RIW */ 0, 1, 1, 0, 0, 0, 0, 1, 1, -/* DR */ 0, 0, 1, 0, 1, 0, 1, 0, 0, -/* WW */ 0, 1, 1, 0, 1, 1, 1, 0, 1 -}; - -/* - * This conflict array is used for concurrent db access (CDB). It uses - * the same locks as the db_riw_conflicts array, but adds an IW mode to - * be used for write cursors. - */ -#define DB_LOCK_CDB_N 5 -static const u_int8_t db_cdb_conflicts[] = { - /* N R W WT IW */ - /* N */ 0, 0, 0, 0, 0, - /* R */ 0, 0, 1, 0, 0, - /* W */ 0, 1, 1, 1, 1, - /* WT */ 0, 0, 0, 0, 0, - /* IW */ 0, 0, 1, 0, 1 -}; - -/* - * __lock_open -- - * Internal version of lock_open: only called from DB_ENV->open. - * - * PUBLIC: int __lock_open __P((DB_ENV *)); - */ -int -__lock_open(dbenv) - DB_ENV *dbenv; -{ - DB_LOCKREGION *region; - DB_LOCKTAB *lt; - size_t size; - int region_locked, ret; - - region_locked = 0; - - /* Create the lock table structure. */ - if ((ret = __os_calloc(dbenv, 1, sizeof(DB_LOCKTAB), <)) != 0) - return (ret); - lt->dbenv = dbenv; - - /* Join/create the lock region. */ - lt->reginfo.dbenv = dbenv; - lt->reginfo.type = REGION_TYPE_LOCK; - lt->reginfo.id = INVALID_REGION_ID; - lt->reginfo.flags = REGION_JOIN_OK; - if (F_ISSET(dbenv, DB_ENV_CREATE)) - F_SET(<->reginfo, REGION_CREATE_OK); - size = __lock_region_size(dbenv); - if ((ret = __db_r_attach(dbenv, <->reginfo, size)) != 0) - goto err; - - /* If we created the region, initialize it. */ - if (F_ISSET(<->reginfo, REGION_CREATE)) - if ((ret = __lock_region_init(dbenv, lt)) != 0) - goto err; - - /* Set the local addresses. */ - region = lt->reginfo.primary = - R_ADDR(<->reginfo, lt->reginfo.rp->primary); - - /* Set remaining pointers into region. */ - lt->conflicts = R_ADDR(<->reginfo, region->conf_off); - lt->obj_tab = R_ADDR(<->reginfo, region->obj_off); - lt->locker_tab = R_ADDR(<->reginfo, region->locker_off); - - dbenv->lk_handle = lt; - - LOCK_SYSTEM_LOCK(dbenv); - region_locked = 1; - - if (dbenv->lk_detect != DB_LOCK_NORUN) { - /* - * Check for incompatible automatic deadlock detection requests. - * There are scenarios where changing the detector configuration - * is reasonable, but we disallow them guessing it is likely to - * be an application error. - * - * We allow applications to turn on the lock detector, and we - * ignore attempts to set it to the default or current value. - */ - if (region->detect != DB_LOCK_NORUN && - dbenv->lk_detect != DB_LOCK_DEFAULT && - region->detect != dbenv->lk_detect) { - __db_err(dbenv, - "lock_open: incompatible deadlock detector mode"); - ret = EINVAL; - goto err; - } - if (region->detect == DB_LOCK_NORUN) - region->detect = dbenv->lk_detect; - } - - /* - * A process joining the region may have reset the lock and transaction - * timeouts. - */ - if (dbenv->lk_timeout != 0) - region->lk_timeout = dbenv->lk_timeout; - if (dbenv->tx_timeout != 0) - region->tx_timeout = dbenv->tx_timeout; - - LOCK_SYSTEM_UNLOCK(dbenv); - region_locked = 0; - - return (0); - -err: dbenv->lk_handle = NULL; - if (lt->reginfo.addr != NULL) { - if (region_locked) - LOCK_SYSTEM_UNLOCK(dbenv); - (void)__db_r_detach(dbenv, <->reginfo, 0); - } - - __os_free(dbenv, lt); - return (ret); -} - -/* - * __lock_region_init -- - * Initialize the lock region. - */ -static int -__lock_region_init(dbenv, lt) - DB_ENV *dbenv; - DB_LOCKTAB *lt; -{ - const u_int8_t *lk_conflicts; - struct __db_lock *lp; - DB_LOCKER *lidp; - DB_LOCKOBJ *op; - DB_LOCKREGION *region; - u_int32_t i; - u_int8_t *addr; - int lk_modes, ret; - - if ((ret = __db_shalloc(<->reginfo, - sizeof(DB_LOCKREGION), 0, <->reginfo.primary)) != 0) - goto mem_err; - lt->reginfo.rp->primary = R_OFFSET(<->reginfo, lt->reginfo.primary); - region = lt->reginfo.primary; - memset(region, 0, sizeof(*region)); - - if ((ret = __mutex_alloc( - dbenv, MTX_LOCK_REGION, 0, ®ion->mtx_region)) != 0) - return (ret); - - /* Select a conflict matrix if none specified. */ - if (dbenv->lk_modes == 0) - if (CDB_LOCKING(dbenv)) { - lk_modes = DB_LOCK_CDB_N; - lk_conflicts = db_cdb_conflicts; - } else { - lk_modes = DB_LOCK_RIW_N; - lk_conflicts = db_riw_conflicts; - } - else { - lk_modes = dbenv->lk_modes; - lk_conflicts = dbenv->lk_conflicts; - } - - region->need_dd = 0; - LOCK_SET_TIME_INVALID(®ion->next_timeout); - region->detect = DB_LOCK_NORUN; - region->lk_timeout = dbenv->lk_timeout; - region->tx_timeout = dbenv->tx_timeout; - region->locker_t_size = __db_tablesize(dbenv->lk_max_lockers); - region->object_t_size = __db_tablesize(dbenv->lk_max_objects); - memset(®ion->stat, 0, sizeof(region->stat)); - region->stat.st_id = 0; - region->stat.st_cur_maxid = DB_LOCK_MAXID; - region->stat.st_maxlocks = dbenv->lk_max; - region->stat.st_maxlockers = dbenv->lk_max_lockers; - region->stat.st_maxobjects = dbenv->lk_max_objects; - region->stat.st_nmodes = lk_modes; - - /* Allocate room for the conflict matrix and initialize it. */ - if ((ret = __db_shalloc( - <->reginfo, (size_t)(lk_modes * lk_modes), 0, &addr)) != 0) - goto mem_err; - memcpy(addr, lk_conflicts, (size_t)(lk_modes * lk_modes)); - region->conf_off = R_OFFSET(<->reginfo, addr); - - /* Allocate room for the object hash table and initialize it. */ - if ((ret = __db_shalloc(<->reginfo, - region->object_t_size * sizeof(DB_HASHTAB), 0, &addr)) != 0) - goto mem_err; - __db_hashinit(addr, region->object_t_size); - region->obj_off = R_OFFSET(<->reginfo, addr); - - /* Allocate room for the locker hash table and initialize it. */ - if ((ret = __db_shalloc(<->reginfo, - region->locker_t_size * sizeof(DB_HASHTAB), 0, &addr)) != 0) - goto mem_err; - __db_hashinit(addr, region->locker_t_size); - region->locker_off = R_OFFSET(<->reginfo, addr); - - /* Initialize locks onto a free list. */ - SH_TAILQ_INIT(®ion->free_locks); - for (i = 0; i < region->stat.st_maxlocks; ++i) { - if ((ret = __db_shalloc(<->reginfo, - sizeof(struct __db_lock), 0, &lp)) != 0) - goto mem_err; - lp->mtx_lock = MUTEX_INVALID; - lp->gen = 0; - lp->status = DB_LSTAT_FREE; - SH_TAILQ_INSERT_HEAD(®ion->free_locks, lp, links, __db_lock); - } - - /* Initialize objects onto a free list. */ - SH_TAILQ_INIT(®ion->dd_objs); - SH_TAILQ_INIT(®ion->free_objs); - for (i = 0; i < region->stat.st_maxobjects; ++i) { - if ((ret = __db_shalloc(<->reginfo, - sizeof(DB_LOCKOBJ), 0, &op)) != 0) - goto mem_err; - SH_TAILQ_INSERT_HEAD( - ®ion->free_objs, op, links, __db_lockobj); - } - - /* Initialize lockers onto a free list. */ - SH_TAILQ_INIT(®ion->lockers); - SH_TAILQ_INIT(®ion->free_lockers); - for (i = 0; i < region->stat.st_maxlockers; ++i) { - if ((ret = __db_shalloc(<->reginfo, - sizeof(DB_LOCKER), 0, &lidp)) != 0) { -mem_err: __db_err(dbenv, - "Unable to allocate memory for the lock table"); - return (ret); - } - SH_TAILQ_INSERT_HEAD( - ®ion->free_lockers, lidp, links, __db_locker); - } - - return (0); -} - -/* - * __lock_dbenv_refresh -- - * Clean up after the lock system on a close or failed open. - * - * PUBLIC: int __lock_dbenv_refresh __P((DB_ENV *)); - */ -int -__lock_dbenv_refresh(dbenv) - DB_ENV *dbenv; -{ - struct __db_lock *lp; - DB_LOCKER *locker; - DB_LOCKOBJ *lockobj; - DB_LOCKREGION *lr; - DB_LOCKTAB *lt; - REGINFO *reginfo; - int ret; - - lt = dbenv->lk_handle; - reginfo = <->reginfo; - lr = reginfo->primary; - - /* - * If a private region, return the memory to the heap. Not needed for - * filesystem-backed or system shared memory regions, that memory isn't - * owned by any particular process. - */ - if (F_ISSET(dbenv, DB_ENV_PRIVATE)) { - /* Discard the conflict matrix. */ - __db_shalloc_free(reginfo, R_ADDR(reginfo, lr->conf_off)); - - /* Discard the object hash table. */ - __db_shalloc_free(reginfo, R_ADDR(reginfo, lr->obj_off)); - - /* Discard the locker hash table. */ - __db_shalloc_free(reginfo, R_ADDR(reginfo, lr->locker_off)); - - /* Discard locks. */ - while ((lp = - SH_TAILQ_FIRST(&lr->free_locks, __db_lock)) != NULL) { - SH_TAILQ_REMOVE(&lr->free_locks, lp, links, __db_lock); - __db_shalloc_free(reginfo, lp); - } - - /* Discard objects. */ - while ((lockobj = - SH_TAILQ_FIRST(&lr->free_objs, __db_lockobj)) != NULL) { - SH_TAILQ_REMOVE( - &lr->free_objs, lockobj, links, __db_lockobj); - __db_shalloc_free(reginfo, lockobj); - } - - /* Discard lockers. */ - while ((locker = - SH_TAILQ_FIRST(&lr->free_lockers, __db_locker)) != NULL) { - SH_TAILQ_REMOVE( - &lr->free_lockers, locker, links, __db_locker); - __db_shalloc_free(reginfo, locker); - } - } - - /* Detach from the region. */ - ret = __db_r_detach(dbenv, reginfo, 0); - - /* Discard DB_LOCKTAB. */ - __os_free(dbenv, lt); - dbenv->lk_handle = NULL; - - return (ret); -} - -/* - * __lock_region_mutex_count -- - * Return the number of mutexes the lock region will need. - * - * PUBLIC: u_int32_t __lock_region_mutex_count __P((DB_ENV *)); - */ -u_int32_t -__lock_region_mutex_count(dbenv) - DB_ENV *dbenv; -{ - return (dbenv->lk_max); -} - -/* - * __lock_region_size -- - * Return the region size. - */ -static size_t -__lock_region_size(dbenv) - DB_ENV *dbenv; -{ - size_t retval; - - /* - * Figure out how much space we're going to need. This list should - * map one-to-one with the __db_shalloc calls in __lock_region_init. - */ - retval = 0; - retval += __db_shalloc_size(sizeof(DB_LOCKREGION), 0); - retval += __db_shalloc_size( - (size_t)(dbenv->lk_modes * dbenv->lk_modes), 0); - retval += __db_shalloc_size( - __db_tablesize(dbenv->lk_max_objects) * (sizeof(DB_HASHTAB)), 0); - retval += __db_shalloc_size( - __db_tablesize(dbenv->lk_max_lockers) * (sizeof(DB_HASHTAB)), 0); - retval += - __db_shalloc_size(sizeof(struct __db_lock), 0) * dbenv->lk_max; - retval += - __db_shalloc_size(sizeof(DB_LOCKOBJ), 0) * dbenv->lk_max_objects; - retval += - __db_shalloc_size(sizeof(DB_LOCKER), 0) * dbenv->lk_max_lockers; - - /* - * Include 16 bytes of string space per lock. DB doesn't use it - * because we pre-allocate lock space for DBTs in the structure. - */ - retval += __db_shalloc_size(dbenv->lk_max * 16, sizeof(size_t)); - - /* And we keep getting this wrong, let's be generous. */ - retval += retval / 4; - - return (retval); -} diff --git a/storage/bdb/lock/lock_stat.c b/storage/bdb/lock/lock_stat.c deleted file mode 100644 index 0b40c6a528f..00000000000 --- a/storage/bdb/lock/lock_stat.c +++ /dev/null @@ -1,558 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: lock_stat.c,v 12.11 2005/10/07 20:21:31 ubell Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#include <string.h> -#if TIME_WITH_SYS_TIME -#include <sys/time.h> -#include <time.h> -#else -#if HAVE_SYS_TIME_H -#include <sys/time.h> -#else -#include <time.h> -#endif -#endif - -#include <ctype.h> -#endif - -#include "db_int.h" -#include "dbinc/db_shash.h" -#include "dbinc/db_page.h" -#include "dbinc/lock.h" -#include "dbinc/log.h" -#include "dbinc/db_am.h" - -#ifdef HAVE_STATISTICS -static void __lock_dump_locker - __P((DB_ENV *, DB_MSGBUF *, DB_LOCKTAB *, DB_LOCKER *)); -static void __lock_dump_object __P((DB_LOCKTAB *, DB_MSGBUF *, DB_LOCKOBJ *)); -static int __lock_print_all __P((DB_ENV *, u_int32_t)); -static int __lock_print_stats __P((DB_ENV *, u_int32_t)); -static void __lock_print_header __P((DB_ENV *)); -static int __lock_stat __P((DB_ENV *, DB_LOCK_STAT **, u_int32_t)); - -/* - * __lock_stat_pp -- - * DB_ENV->lock_stat pre/post processing. - * - * PUBLIC: int __lock_stat_pp __P((DB_ENV *, DB_LOCK_STAT **, u_int32_t)); - */ -int -__lock_stat_pp(dbenv, statp, flags) - DB_ENV *dbenv; - DB_LOCK_STAT **statp; - u_int32_t flags; -{ - DB_THREAD_INFO *ip; - int ret; - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, - dbenv->lk_handle, "DB_ENV->lock_stat", DB_INIT_LOCK); - - if ((ret = __db_fchk(dbenv, - "DB_ENV->lock_stat", flags, DB_STAT_CLEAR)) != 0) - return (ret); - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, (__lock_stat(dbenv, statp, flags)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __lock_stat -- - * DB_ENV->lock_stat. - */ -static int -__lock_stat(dbenv, statp, flags) - DB_ENV *dbenv; - DB_LOCK_STAT **statp; - u_int32_t flags; -{ - DB_LOCKREGION *region; - DB_LOCKTAB *lt; - DB_LOCK_STAT *stats, tmp; - int ret; - - *statp = NULL; - lt = dbenv->lk_handle; - - if ((ret = __os_umalloc(dbenv, sizeof(*stats), &stats)) != 0) - return (ret); - - /* Copy out the global statistics. */ - LOCK_SYSTEM_LOCK(dbenv); - - region = lt->reginfo.primary; - memcpy(stats, ®ion->stat, sizeof(*stats)); - stats->st_locktimeout = region->lk_timeout; - stats->st_txntimeout = region->tx_timeout; - - __mutex_set_wait_info(dbenv, region->mtx_region, - &stats->st_region_wait, &stats->st_region_nowait); - stats->st_regsize = lt->reginfo.rp->size; - if (LF_ISSET(DB_STAT_CLEAR)) { - tmp = region->stat; - memset(®ion->stat, 0, sizeof(region->stat)); - __mutex_clear(dbenv, region->mtx_region); - - region->stat.st_id = tmp.st_id; - region->stat.st_cur_maxid = tmp.st_cur_maxid; - region->stat.st_maxlocks = tmp.st_maxlocks; - region->stat.st_maxlockers = tmp.st_maxlockers; - region->stat.st_maxobjects = tmp.st_maxobjects; - region->stat.st_nlocks = - region->stat.st_maxnlocks = tmp.st_nlocks; - region->stat.st_nlockers = - region->stat.st_maxnlockers = tmp.st_nlockers; - region->stat.st_nobjects = - region->stat.st_maxnobjects = tmp.st_nobjects; - region->stat.st_nmodes = tmp.st_nmodes; - } - - LOCK_SYSTEM_UNLOCK(dbenv); - - *statp = stats; - return (0); -} - -/* - * __lock_stat_print_pp -- - * DB_ENV->lock_stat_print pre/post processing. - * - * PUBLIC: int __lock_stat_print_pp __P((DB_ENV *, u_int32_t)); - */ -int -__lock_stat_print_pp(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - DB_THREAD_INFO *ip; - int ret; - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, - dbenv->lk_handle, "DB_ENV->lock_stat_print", DB_INIT_LOCK); - -#define DB_STAT_LOCK_FLAGS \ - (DB_STAT_ALL | DB_STAT_CLEAR | DB_STAT_LOCK_CONF | \ - DB_STAT_LOCK_LOCKERS | DB_STAT_LOCK_OBJECTS | DB_STAT_LOCK_PARAMS) - if ((ret = __db_fchk(dbenv, "DB_ENV->lock_stat_print", - flags, DB_STAT_CLEAR | DB_STAT_LOCK_FLAGS)) != 0) - return (ret); - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, (__lock_stat_print(dbenv, flags)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __lock_stat_print -- - * DB_ENV->lock_stat_print method. - * - * PUBLIC: int __lock_stat_print __P((DB_ENV *, u_int32_t)); - */ -int -__lock_stat_print(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - u_int32_t orig_flags; - int ret; - - orig_flags = flags; - LF_CLR(DB_STAT_CLEAR); - if (flags == 0 || LF_ISSET(DB_STAT_ALL)) { - ret = __lock_print_stats(dbenv, orig_flags); - if (flags == 0 || ret != 0) - return (ret); - } - - if (LF_ISSET(DB_STAT_ALL | DB_STAT_LOCK_CONF | DB_STAT_LOCK_LOCKERS | - DB_STAT_LOCK_OBJECTS | DB_STAT_LOCK_PARAMS) && - (ret = __lock_print_all(dbenv, orig_flags)) != 0) - return (ret); - - return (0); -} - -/* - * __lock_print_stats -- - * Display default lock region statistics. - */ -static int -__lock_print_stats(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - DB_LOCK_STAT *sp; - int ret; - - if ((ret = __lock_stat(dbenv, &sp, flags)) != 0) - return (ret); - - if (LF_ISSET(DB_STAT_ALL)) - __db_msg(dbenv, "Default locking region information:"); - __db_dl(dbenv, "Last allocated locker ID", (u_long)sp->st_id); - __db_msg(dbenv, "%#lx\tCurrent maximum unused locker ID", - (u_long)sp->st_cur_maxid); - __db_dl(dbenv, "Number of lock modes", (u_long)sp->st_nmodes); - __db_dl(dbenv, - "Maximum number of locks possible", (u_long)sp->st_maxlocks); - __db_dl(dbenv, - "Maximum number of lockers possible", (u_long)sp->st_maxlockers); - __db_dl(dbenv, "Maximum number of lock objects possible", - (u_long)sp->st_maxobjects); - __db_dl(dbenv, "Number of current locks", (u_long)sp->st_nlocks); - __db_dl(dbenv, "Maximum number of locks at any one time", - (u_long)sp->st_maxnlocks); - __db_dl(dbenv, "Number of current lockers", (u_long)sp->st_nlockers); - __db_dl(dbenv, "Maximum number of lockers at any one time", - (u_long)sp->st_maxnlockers); - __db_dl(dbenv, - "Number of current lock objects", (u_long)sp->st_nobjects); - __db_dl(dbenv, "Maximum number of lock objects at any one time", - (u_long)sp->st_maxnobjects); - __db_dl(dbenv, - "Total number of locks requested", (u_long)sp->st_nrequests); - __db_dl(dbenv, - "Total number of locks released", (u_long)sp->st_nreleases); - __db_dl(dbenv, - "Total number of locks upgraded", (u_long)sp->st_nupgrade); - __db_dl(dbenv, - "Total number of locks downgraded", (u_long)sp->st_ndowngrade); - __db_dl(dbenv, - "Lock requests not available due to conflicts, for which we waited", - (u_long)sp->st_lock_wait); - __db_dl(dbenv, - "Lock requests not available due to conflicts, for which we did not wait", - (u_long)sp->st_lock_nowait); - __db_dl(dbenv, "Number of deadlocks", (u_long)sp->st_ndeadlocks); - __db_dl(dbenv, "Lock timeout value", (u_long)sp->st_locktimeout); - __db_dl(dbenv, "Number of locks that have timed out", - (u_long)sp->st_nlocktimeouts); - __db_dl(dbenv, - "Transaction timeout value", (u_long)sp->st_txntimeout); - __db_dl(dbenv, "Number of transactions that have timed out", - (u_long)sp->st_ntxntimeouts); - - __db_dlbytes(dbenv, "The size of the lock region", - (u_long)0, (u_long)0, (u_long)sp->st_regsize); - __db_dl_pct(dbenv, - "The number of region locks that required waiting", - (u_long)sp->st_region_wait, DB_PCT(sp->st_region_wait, - sp->st_region_wait + sp->st_region_nowait), NULL); - - __os_ufree(dbenv, sp); - - return (0); -} - -/* - * __lock_print_all -- - * Display debugging lock region statistics. - */ -static int -__lock_print_all(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - DB_LOCKER *lip; - DB_LOCKOBJ *op; - DB_LOCKREGION *lrp; - DB_LOCKTAB *lt; - DB_MSGBUF mb; - int i, j; - u_int32_t k; - char buf[64]; - - lt = dbenv->lk_handle; - lrp = lt->reginfo.primary; - DB_MSGBUF_INIT(&mb); - - LOCK_SYSTEM_LOCK(dbenv); - - __db_print_reginfo(dbenv, <->reginfo, "Lock"); - - if (LF_ISSET(DB_STAT_ALL | DB_STAT_LOCK_PARAMS)) { - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_msg(dbenv, "Lock region parameters:"); - __mutex_print_debug_single(dbenv, - "Lock region region mutex", lrp->mtx_region, flags); - STAT_ULONG("locker table size", lrp->locker_t_size); - STAT_ULONG("object table size", lrp->object_t_size); - STAT_ULONG("obj_off", lrp->obj_off); - STAT_ULONG("locker_off", lrp->locker_off); - STAT_ULONG("need_dd", lrp->need_dd); - if (LOCK_TIME_ISVALID(&lrp->next_timeout) && - strftime(buf, sizeof(buf), "%m-%d-%H:%M:%S", - localtime((time_t*)&lrp->next_timeout.tv_sec)) != 0) - __db_msg(dbenv, "next_timeout: %s.%lu", - buf, (u_long)lrp->next_timeout.tv_usec); - } - - if (LF_ISSET(DB_STAT_ALL | DB_STAT_LOCK_CONF)) { - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_msg(dbenv, "Lock conflict matrix:"); - for (i = 0; i < lrp->stat.st_nmodes; i++) { - for (j = 0; j < lrp->stat.st_nmodes; j++) - __db_msgadd(dbenv, &mb, "%lu\t", (u_long) - lt->conflicts[i * lrp->stat.st_nmodes + j]); - DB_MSGBUF_FLUSH(dbenv, &mb); - } - } - - if (LF_ISSET(DB_STAT_ALL | DB_STAT_LOCK_LOCKERS)) { - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_msg(dbenv, "Locks grouped by lockers:"); - __lock_print_header(dbenv); - for (k = 0; k < lrp->locker_t_size; k++) - for (lip = - SH_TAILQ_FIRST(<->locker_tab[k], __db_locker); - lip != NULL; - lip = SH_TAILQ_NEXT(lip, links, __db_locker)) { - __lock_dump_locker(dbenv, &mb, lt, lip); - } - } - - if (LF_ISSET(DB_STAT_ALL | DB_STAT_LOCK_OBJECTS)) { - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_msg(dbenv, "Locks grouped by object:"); - __lock_print_header(dbenv); - for (k = 0; k < lrp->object_t_size; k++) { - for (op = SH_TAILQ_FIRST(<->obj_tab[k], __db_lockobj); - op != NULL; - op = SH_TAILQ_NEXT(op, links, __db_lockobj)) { - __lock_dump_object(lt, &mb, op); - __db_msg(dbenv, "%s", ""); - } - } - } - LOCK_SYSTEM_UNLOCK(dbenv); - - return (0); -} - -static void -__lock_dump_locker(dbenv, mbp, lt, lip) - DB_ENV *dbenv; - DB_MSGBUF *mbp; - DB_LOCKTAB *lt; - DB_LOCKER *lip; -{ - struct __db_lock *lp; - time_t s; - char buf[DB_THREADID_STRLEN]; - - __db_msgadd(dbenv, - mbp, "%8lx dd=%2ld locks held %-4d write locks %-4d pid/thread %s", - (u_long)lip->id, (long)lip->dd_id, lip->nlocks, lip->nwrites, - dbenv->thread_id_string(dbenv, lip->pid, lip->tid, buf)); - __db_msgadd( - dbenv, mbp, "%s", F_ISSET(lip, DB_LOCKER_DELETED) ? "(D)" : " "); - if (LOCK_TIME_ISVALID(&lip->tx_expire)) { - s = (time_t)lip->tx_expire.tv_sec; - if (strftime(buf, - sizeof(buf), "%m-%d-%H:%M:%S", localtime(&s)) != 0) - __db_msgadd(dbenv, mbp, "expires %s.%lu", - buf, (u_long)lip->tx_expire.tv_usec); - } - if (F_ISSET(lip, DB_LOCKER_TIMEOUT)) - __db_msgadd(dbenv, mbp, " lk timeout %u", lip->lk_timeout); - if (LOCK_TIME_ISVALID(&lip->lk_expire)) { - s = (time_t)lip->lk_expire.tv_sec; - if (strftime(buf, - sizeof(buf), "%m-%d-%H:%M:%S", localtime(&s)) != 0) - __db_msgadd(dbenv, mbp, " lk expires %s.%lu", - buf, (u_long)lip->lk_expire.tv_usec); - } - DB_MSGBUF_FLUSH(dbenv, mbp); - - for (lp = SH_LIST_FIRST(&lip->heldby, __db_lock); - lp != NULL; lp = SH_LIST_NEXT(lp, locker_links, __db_lock)) - __lock_printlock(lt, mbp, lp, 1); -} - -static void -__lock_dump_object(lt, mbp, op) - DB_LOCKTAB *lt; - DB_MSGBUF *mbp; - DB_LOCKOBJ *op; -{ - struct __db_lock *lp; - - for (lp = - SH_TAILQ_FIRST(&op->holders, __db_lock); - lp != NULL; - lp = SH_TAILQ_NEXT(lp, links, __db_lock)) - __lock_printlock(lt, mbp, lp, 1); - for (lp = - SH_TAILQ_FIRST(&op->waiters, __db_lock); - lp != NULL; - lp = SH_TAILQ_NEXT(lp, links, __db_lock)) - __lock_printlock(lt, mbp, lp, 1); -} - -/* - * __lock_print_header -- - */ -static void -__lock_print_header(dbenv) - DB_ENV *dbenv; -{ - __db_msg(dbenv, "%-8s %-10s%-4s %-7s %s", - "Locker", "Mode", - "Count", "Status", "----------------- Object ---------------"); -} - -/* - * __lock_printlock -- - * - * PUBLIC: void __lock_printlock - * PUBLIC: __P((DB_LOCKTAB *, DB_MSGBUF *mbp, struct __db_lock *, int)); - */ -void -__lock_printlock(lt, mbp, lp, ispgno) - DB_LOCKTAB *lt; - DB_MSGBUF *mbp; - struct __db_lock *lp; - int ispgno; -{ - DB_ENV *dbenv; - DB_LOCKOBJ *lockobj; - DB_MSGBUF mb; - db_pgno_t pgno; - u_int32_t *fidp, type; - u_int8_t *ptr; - char *namep; - const char *mode, *status; - - dbenv = lt->dbenv; - - if (mbp == NULL) { - DB_MSGBUF_INIT(&mb); - mbp = &mb; - } - - switch (lp->mode) { - case DB_LOCK_IREAD: - mode = "IREAD"; - break; - case DB_LOCK_IWR: - mode = "IWR"; - break; - case DB_LOCK_IWRITE: - mode = "IWRITE"; - break; - case DB_LOCK_NG: - mode = "NG"; - break; - case DB_LOCK_READ: - mode = "READ"; - break; - case DB_LOCK_READ_UNCOMMITTED: - mode = "READ_UNCOMMITTED"; - break; - case DB_LOCK_WRITE: - mode = "WRITE"; - break; - case DB_LOCK_WWRITE: - mode = "WAS_WRITE"; - break; - case DB_LOCK_WAIT: - mode = "WAIT"; - break; - default: - mode = "UNKNOWN"; - break; - } - switch (lp->status) { - case DB_LSTAT_ABORTED: - status = "ABORT"; - break; - case DB_LSTAT_EXPIRED: - status = "EXPIRED"; - break; - case DB_LSTAT_FREE: - status = "FREE"; - break; - case DB_LSTAT_HELD: - status = "HELD"; - break; - case DB_LSTAT_PENDING: - status = "PENDING"; - break; - case DB_LSTAT_WAITING: - status = "WAIT"; - break; - default: - status = "UNKNOWN"; - break; - } - __db_msgadd(dbenv, mbp, "%8lx %-10s %4lu %-7s ", - (u_long)lp->holder, mode, (u_long)lp->refcount, status); - - lockobj = (DB_LOCKOBJ *)((u_int8_t *)lp + lp->obj); - ptr = SH_DBT_PTR(&lockobj->lockobj); - if (ispgno && lockobj->lockobj.size == sizeof(struct __db_ilock)) { - /* Assume this is a DBT lock. */ - memcpy(&pgno, ptr, sizeof(db_pgno_t)); - fidp = (u_int32_t *)(ptr + sizeof(db_pgno_t)); - type = *(u_int32_t *)(ptr + sizeof(db_pgno_t) + DB_FILE_ID_LEN); - if (__dbreg_get_name(lt->dbenv, (u_int8_t *)fidp, &namep) != 0) - namep = NULL; - if (namep == NULL) - __db_msgadd(dbenv, mbp, "(%lx %lx %lx %lx %lx) ", - (u_long)fidp[0], (u_long)fidp[1], (u_long)fidp[2], - (u_long)fidp[3], (u_long)fidp[4]); - else - __db_msgadd(dbenv, mbp, "%-25s ", namep); - __db_msgadd(dbenv, mbp, "%-7s %7lu", - type == DB_PAGE_LOCK ? "page" : - type == DB_RECORD_LOCK ? "record" : "handle", - (u_long)pgno); - } else { - __db_msgadd(dbenv, mbp, "0x%lx ", - (u_long)R_OFFSET(<->reginfo, lockobj)); - __db_pr(dbenv, mbp, ptr, lockobj->lockobj.size); - } - DB_MSGBUF_FLUSH(dbenv, mbp); -} - -#else /* !HAVE_STATISTICS */ - -int -__lock_stat_pp(dbenv, statp, flags) - DB_ENV *dbenv; - DB_LOCK_STAT **statp; - u_int32_t flags; -{ - COMPQUIET(statp, NULL); - COMPQUIET(flags, 0); - - return (__db_stat_not_built(dbenv)); -} - -int -__lock_stat_print_pp(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - COMPQUIET(flags, 0); - - return (__db_stat_not_built(dbenv)); -} -#endif diff --git a/storage/bdb/lock/lock_timer.c b/storage/bdb/lock/lock_timer.c deleted file mode 100644 index f05eac860c0..00000000000 --- a/storage/bdb/lock/lock_timer.c +++ /dev/null @@ -1,212 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: lock_timer.c,v 12.2 2005/07/20 16:51:44 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#include <stdlib.h> -#endif - -#include "db_int.h" -#include "dbinc/db_shash.h" -#include "dbinc/lock.h" - -/* - * __lock_set_timeout - * -- set timeout values in shared memory. - * - * This is called from the transaction system. We either set the time that - * this transaction expires or the amount of time a lock for this transaction - * is permitted to wait. - * - * PUBLIC: int __lock_set_timeout __P(( DB_ENV *, - * PUBLIC: u_int32_t, db_timeout_t, u_int32_t)); - */ -int -__lock_set_timeout(dbenv, locker, timeout, op) - DB_ENV *dbenv; - u_int32_t locker; - db_timeout_t timeout; - u_int32_t op; -{ - int ret; - - LOCK_SYSTEM_LOCK(dbenv); - ret = __lock_set_timeout_internal(dbenv, locker, timeout, op); - LOCK_SYSTEM_UNLOCK(dbenv); - return (ret); -} - -/* - * __lock_set_timeout_internal - * -- set timeout values in shared memory. - * - * This is the internal version called from the lock system. We either set - * the time that this transaction expires or the amount of time that a lock - * for this transaction is permitted to wait. - * - * PUBLIC: int __lock_set_timeout_internal - * PUBLIC: __P((DB_ENV *, u_int32_t, db_timeout_t, u_int32_t)); - */ -int -__lock_set_timeout_internal(dbenv, locker, timeout, op) - DB_ENV *dbenv; - u_int32_t locker; - db_timeout_t timeout; - u_int32_t op; -{ - DB_LOCKER *sh_locker; - DB_LOCKREGION *region; - DB_LOCKTAB *lt; - u_int32_t locker_ndx; - int ret; - - lt = dbenv->lk_handle; - region = lt->reginfo.primary; - - LOCKER_LOCK(lt, region, locker, locker_ndx); - ret = __lock_getlocker(lt, locker, locker_ndx, 1, &sh_locker); - - if (ret != 0) - return (ret); - - if (op == DB_SET_TXN_TIMEOUT) { - if (timeout == 0) - LOCK_SET_TIME_INVALID(&sh_locker->tx_expire); - else - __lock_expires(dbenv, &sh_locker->tx_expire, timeout); - } else if (op == DB_SET_LOCK_TIMEOUT) { - sh_locker->lk_timeout = timeout; - F_SET(sh_locker, DB_LOCKER_TIMEOUT); - } else if (op == DB_SET_TXN_NOW) { - LOCK_SET_TIME_INVALID(&sh_locker->tx_expire); - __lock_expires(dbenv, &sh_locker->tx_expire, 0); - sh_locker->lk_expire = sh_locker->tx_expire; - if (!LOCK_TIME_ISVALID(®ion->next_timeout) || - LOCK_TIME_GREATER( - ®ion->next_timeout, &sh_locker->lk_expire)) - region->next_timeout = sh_locker->lk_expire; - } else - return (EINVAL); - - return (0); -} - -/* - * __lock_inherit_timeout - * -- inherit timeout values from parent locker. - * This is called from the transaction system. This will - * return EINVAL if the parent does not exist or did not - * have a current txn timeout set. - * - * PUBLIC: int __lock_inherit_timeout __P(( DB_ENV *, u_int32_t, u_int32_t)); - */ -int -__lock_inherit_timeout(dbenv, parent, locker) - DB_ENV *dbenv; - u_int32_t parent, locker; -{ - DB_LOCKER *parent_locker, *sh_locker; - DB_LOCKREGION *region; - DB_LOCKTAB *lt; - u_int32_t locker_ndx; - int ret; - - lt = dbenv->lk_handle; - region = lt->reginfo.primary; - ret = 0; - LOCK_SYSTEM_LOCK(dbenv); - - /* If the parent does not exist, we are done. */ - LOCKER_LOCK(lt, region, parent, locker_ndx); - if ((ret = __lock_getlocker(lt, - parent, locker_ndx, 0, &parent_locker)) != 0) - goto err; - - /* - * If the parent is not there yet, thats ok. If it - * does not have any timouts set, then avoid creating - * the child locker at this point. - */ - if (parent_locker == NULL || - (LOCK_TIME_ISVALID(&parent_locker->tx_expire) && - !F_ISSET(parent_locker, DB_LOCKER_TIMEOUT))) { - ret = EINVAL; - goto done; - } - - LOCKER_LOCK(lt, region, locker, locker_ndx); - if ((ret = __lock_getlocker(lt, - locker, locker_ndx, 1, &sh_locker)) != 0) - goto err; - - sh_locker->tx_expire = parent_locker->tx_expire; - - if (F_ISSET(parent_locker, DB_LOCKER_TIMEOUT)) { - sh_locker->lk_timeout = parent_locker->lk_timeout; - F_SET(sh_locker, DB_LOCKER_TIMEOUT); - if (!LOCK_TIME_ISVALID(&parent_locker->tx_expire)) - ret = EINVAL; - } - -done: -err: LOCK_SYSTEM_UNLOCK(dbenv); - return (ret); -} - -/* - * __lock_expires -- - * Set the expire time given the time to live. If timevalp is set then - * it contains "now". This avoids repeated system calls to get the time. - * - * PUBLIC: void __lock_expires __P((DB_ENV *, db_timeval_t *, db_timeout_t)); - */ -void -__lock_expires(dbenv, timevalp, timeout) - DB_ENV *dbenv; - db_timeval_t *timevalp; - db_timeout_t timeout; -{ - if (!LOCK_TIME_ISVALID(timevalp)) - __os_clock(dbenv, &timevalp->tv_sec, &timevalp->tv_usec); - if (timeout > 1000000) { - timevalp->tv_sec += timeout / 1000000; - timevalp->tv_usec += timeout % 1000000; - } else - timevalp->tv_usec += timeout; - - if (timevalp->tv_usec > 1000000) { - timevalp->tv_sec++; - timevalp->tv_usec -= 1000000; - } -} - -/* - * __lock_expired -- determine if a lock has expired. - * - * PUBLIC: int __lock_expired __P((DB_ENV *, db_timeval_t *, db_timeval_t *)); - */ -int -__lock_expired(dbenv, now, timevalp) - DB_ENV *dbenv; - db_timeval_t *now, *timevalp; -{ - if (!LOCK_TIME_ISVALID(timevalp)) - return (0); - - if (!LOCK_TIME_ISVALID(now)) - __os_clock(dbenv, &now->tv_sec, &now->tv_usec); - - return (now->tv_sec > timevalp->tv_sec || - (now->tv_sec == timevalp->tv_sec && - now->tv_usec >= timevalp->tv_usec)); -} diff --git a/storage/bdb/lock/lock_util.c b/storage/bdb/lock/lock_util.c deleted file mode 100644 index a8f7b123cd4..00000000000 --- a/storage/bdb/lock/lock_util.c +++ /dev/null @@ -1,136 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: lock_util.c,v 12.2 2005/06/16 20:23:11 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/hash.h" -#include "dbinc/lock.h" - -/* - * __lock_cmp -- - * This function is used to compare a DBT that is about to be entered - * into a hash table with an object already in the hash table. Note - * that it just returns true on equal and 0 on not-equal. Therefore - * this function cannot be used as a sort function; its purpose is to - * be used as a hash comparison function. - * - * PUBLIC: int __lock_cmp __P((const DBT *, DB_LOCKOBJ *)); - */ -int -__lock_cmp(dbt, lock_obj) - const DBT *dbt; - DB_LOCKOBJ *lock_obj; -{ - void *obj_data; - - obj_data = SH_DBT_PTR(&lock_obj->lockobj); - return (dbt->size == lock_obj->lockobj.size && - memcmp(dbt->data, obj_data, dbt->size) == 0); -} - -/* - * PUBLIC: int __lock_locker_cmp __P((u_int32_t, DB_LOCKER *)); - */ -int -__lock_locker_cmp(locker, sh_locker) - u_int32_t locker; - DB_LOCKER *sh_locker; -{ - return (locker == sh_locker->id); -} - -/* - * The next two functions are the hash functions used to store objects in the - * lock hash tables. They are hashing the same items, but one (__lock_ohash) - * takes a DBT (used for hashing a parameter passed from the user) and the - * other (__lock_lhash) takes a DB_LOCKOBJ (used for hashing something that is - * already in the lock manager). In both cases, we have a special check to - * fast path the case where we think we are doing a hash on a DB page/fileid - * pair. If the size is right, then we do the fast hash. - * - * We know that DB uses DB_LOCK_ILOCK types for its lock objects. The first - * four bytes are the 4-byte page number and the next DB_FILE_ID_LEN bytes - * are a unique file id, where the first 4 bytes on UNIX systems are the file - * inode number, and the first 4 bytes on Windows systems are the FileIndexLow - * bytes. So, we use the XOR of the page number and the first four bytes of - * the file id to produce a 32-bit hash value. - * - * We have no particular reason to believe that this algorithm will produce - * a good hash, but we want a fast hash more than we want a good one, when - * we're coming through this code path. - */ -#define FAST_HASH(P) { \ - u_int32_t __h; \ - u_int8_t *__cp, *__hp; \ - __hp = (u_int8_t *)&__h; \ - __cp = (u_int8_t *)(P); \ - __hp[0] = __cp[0] ^ __cp[4]; \ - __hp[1] = __cp[1] ^ __cp[5]; \ - __hp[2] = __cp[2] ^ __cp[6]; \ - __hp[3] = __cp[3] ^ __cp[7]; \ - return (__h); \ -} - -/* - * __lock_ohash -- - * - * PUBLIC: u_int32_t __lock_ohash __P((const DBT *)); - */ -u_int32_t -__lock_ohash(dbt) - const DBT *dbt; -{ - if (dbt->size == sizeof(DB_LOCK_ILOCK)) - FAST_HASH(dbt->data); - - return (__ham_func5(NULL, dbt->data, dbt->size)); -} - -/* - * __lock_lhash -- - * - * PUBLIC: u_int32_t __lock_lhash __P((DB_LOCKOBJ *)); - */ -u_int32_t -__lock_lhash(lock_obj) - DB_LOCKOBJ *lock_obj; -{ - void *obj_data; - - obj_data = SH_DBT_PTR(&lock_obj->lockobj); - - if (lock_obj->lockobj.size == sizeof(DB_LOCK_ILOCK)) - FAST_HASH(obj_data); - - return (__ham_func5(NULL, obj_data, lock_obj->lockobj.size)); -} - -/* - * __lock_nomem -- - * Report a lack of some resource. - * - * PUBLIC: int __lock_nomem __P((DB_ENV *, const char *)); - */ -int -__lock_nomem(dbenv, res) - DB_ENV *dbenv; - const char *res; -{ - __db_err(dbenv, "Lock table is out of available %s", res); - return (ENOMEM); -} diff --git a/storage/bdb/log/log.c b/storage/bdb/log/log.c deleted file mode 100644 index 6e82eea3757..00000000000 --- a/storage/bdb/log/log.c +++ /dev/null @@ -1,1395 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: log.c,v 12.15 2005/10/14 15:20:24 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <ctype.h> -#include <stdlib.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/crypto.h" -#include "dbinc/hmac.h" -#include "dbinc/log.h" -#include "dbinc/txn.h" - -static int __log_init __P((DB_ENV *, DB_LOG *)); -static int __log_recover __P((DB_LOG *)); -static size_t __log_region_size __P((DB_ENV *)); -static int __log_zero __P((DB_ENV *, DB_LSN *, DB_LSN *)); - -/* - * __log_open -- - * Internal version of log_open: only called from DB_ENV->open. - * - * PUBLIC: int __log_open __P((DB_ENV *)); - */ -int -__log_open(dbenv) - DB_ENV *dbenv; -{ - DB_LOG *dblp; - LOG *lp; - u_int8_t *bulk; - int region_locked, ret; - - region_locked = 0; - - /* Create/initialize the DB_LOG structure. */ - if ((ret = __os_calloc(dbenv, 1, sizeof(DB_LOG), &dblp)) != 0) - return (ret); - dblp->dbenv = dbenv; - - /* Set the default buffer size, if not otherwise configured. */ - if (dbenv->lg_bsize == 0) - dbenv->lg_bsize = F_ISSET(dbenv, DB_ENV_LOG_INMEMORY) ? - LG_BSIZE_INMEM : LG_BSIZE_DEFAULT; - - /* Join/create the log region. */ - dblp->reginfo.dbenv = dbenv; - dblp->reginfo.type = REGION_TYPE_LOG; - dblp->reginfo.id = INVALID_REGION_ID; - dblp->reginfo.flags = REGION_JOIN_OK; - if (F_ISSET(dbenv, DB_ENV_CREATE)) - F_SET(&dblp->reginfo, REGION_CREATE_OK); - if ((ret = __db_r_attach( - dbenv, &dblp->reginfo, __log_region_size(dbenv))) != 0) - goto err; - - /* If we created the region, initialize it. */ - if (F_ISSET(&dblp->reginfo, REGION_CREATE)) - if ((ret = __log_init(dbenv, dblp)) != 0) - goto err; - - /* Set the local addresses. */ - lp = dblp->reginfo.primary = - R_ADDR(&dblp->reginfo, dblp->reginfo.rp->primary); - dblp->bufp = R_ADDR(&dblp->reginfo, lp->buffer_off); - - /* - * If the region is threaded, we have to lock the DBREG list, and we - * need to allocate a mutex for that purpose. - */ - if ((ret = __mutex_alloc(dbenv, - MTX_LOG_REGION, DB_MUTEX_THREAD, &dblp->mtx_dbreg)) != 0) - goto err; - - /* - * Set the handle -- we may be about to run recovery, which allocates - * log cursors. Log cursors require logging be already configured, - * and the handle being set is what demonstrates that. - * - * If we created the region, run recovery. If that fails, make sure - * we reset the log handle before cleaning up, otherwise we will try - * and clean up again in the mainline DB_ENV initialization code. - */ - dbenv->lg_handle = dblp; - - if (F_ISSET(&dblp->reginfo, REGION_CREATE)) { - /* - * We first take the log file size from the environment, if - * specified. If that wasn't set, default it. Regardless, - * recovery may set it from the persistent information in a - * log file header. - */ - if (lp->log_size == 0) - lp->log_size = F_ISSET(dbenv, DB_ENV_LOG_INMEMORY) ? - LG_MAX_INMEM : LG_MAX_DEFAULT; - - if ((ret = __log_recover(dblp)) != 0) - goto err; - - /* - * If the next log file size hasn't been set yet, default it - * to the current log file size. - */ - if (lp->log_nsize == 0) - lp->log_nsize = lp->log_size; - - /* - * If we haven't written any log files, write the first one - * so that checkpoint gets a valid ckp_lsn value. - */ - if (IS_INIT_LSN(lp->lsn) && - (ret = __log_newfile(dblp, NULL, 0)) != 0) - goto err; - - /* - * Initialize replication's next-expected LSN value - * and replication's bulk buffer. - */ - lp->ready_lsn = lp->lsn; - if (IS_ENV_REPLICATED(dbenv)) { - if ((ret = __db_shalloc(&dblp->reginfo, MEGABYTE, 0, - &bulk)) != 0) - goto err; - lp->bulk_buf = R_OFFSET(&dblp->reginfo, bulk); - lp->bulk_len = MEGABYTE; - lp->bulk_off = 0; - } else { - lp->bulk_buf = INVALID_ROFF; - lp->bulk_len = 0; - lp->bulk_off = 0; - } - } else { - /* - * A process joining the region may have reset the log file - * size, too. If so, it only affects the next log file we - * create. We need to check that the size is reasonable given - * the buffer size in the region. - */ - LOG_SYSTEM_LOCK(dbenv); - region_locked = 1; - - if (dbenv->lg_size != 0) { - if ((ret = - __log_check_sizes(dbenv, dbenv->lg_size, 0)) != 0) - goto err; - - lp->log_nsize = dbenv->lg_size; - } - - /* Migrate persistent flags from the region into the DB_ENV. */ - if (lp->db_log_autoremove) - F_SET(dbenv, DB_ENV_LOG_AUTOREMOVE); - if (lp->db_log_inmemory) - F_SET(dbenv, DB_ENV_LOG_INMEMORY); - - LOG_SYSTEM_UNLOCK(dbenv); - region_locked = 0; - } - - return (0); - -err: dbenv->lg_handle = NULL; - if (dblp->reginfo.addr != NULL) { - if (region_locked) - LOG_SYSTEM_UNLOCK(dbenv); - (void)__db_r_detach(dbenv, &dblp->reginfo, 0); - } - - (void)__mutex_free(dbenv, &dblp->mtx_dbreg); - __os_free(dbenv, dblp); - - return (ret); -} - -/* - * __log_init -- - * Initialize a log region in shared memory. - */ -static int -__log_init(dbenv, dblp) - DB_ENV *dbenv; - DB_LOG *dblp; -{ - LOG *lp; - int ret; - void *p; - - /* - * This is the first point where we can validate the buffer size, - * because we know all three settings have been configured (file size, - * buffer size and the in-memory flag). - */ - if ((ret = - __log_check_sizes(dbenv, dbenv->lg_size, dbenv->lg_bsize)) != 0) - return (ret); - - if ((ret = __db_shalloc(&dblp->reginfo, - sizeof(*lp), 0, &dblp->reginfo.primary)) != 0) - goto mem_err; - dblp->reginfo.rp->primary = - R_OFFSET(&dblp->reginfo, dblp->reginfo.primary); - lp = dblp->reginfo.primary; - memset(lp, 0, sizeof(*lp)); - - if ((ret = - __mutex_alloc(dbenv, MTX_LOG_REGION, 0, &lp->mtx_region)) != 0) - return (ret); - - lp->fid_max = 0; - SH_TAILQ_INIT(&lp->fq); - lp->free_fid_stack = INVALID_ROFF; - lp->free_fids = lp->free_fids_alloced = 0; - - /* Initialize LOG LSNs. */ - INIT_LSN(lp->lsn); - INIT_LSN(lp->t_lsn); - - /* - * It's possible to be waiting for an LSN of [1][0], if a replication - * client gets the first log record out of order. An LSN of [0][0] - * signifies that we're not waiting. - */ - ZERO_LSN(lp->waiting_lsn); - - /* - * Log makes note of the fact that it ran into a checkpoint on - * startup if it did so, as a recovery optimization. A zero - * LSN signifies that it hasn't found one [yet]. - */ - ZERO_LSN(lp->cached_ckp_lsn); - - if ((ret = - __mutex_alloc(dbenv, MTX_LOG_FILENAME, 0, &lp->mtx_filelist)) != 0) - return (ret); - if ((ret = __mutex_alloc(dbenv, MTX_LOG_FLUSH, 0, &lp->mtx_flush)) != 0) - return (ret); - - /* Initialize the buffer. */ - if ((ret = __db_shalloc(&dblp->reginfo, dbenv->lg_bsize, 0, &p)) != 0) { -mem_err: __db_err(dbenv, "Unable to allocate memory for the log buffer"); - return (ret); - } - lp->regionmax = dbenv->lg_regionmax; - lp->buffer_off = R_OFFSET(&dblp->reginfo, p); - lp->buffer_size = dbenv->lg_bsize; - lp->filemode = dbenv->lg_filemode; - lp->log_size = lp->log_nsize = dbenv->lg_size; - - /* Initialize the commit Queue. */ - SH_TAILQ_INIT(&lp->free_commits); - SH_TAILQ_INIT(&lp->commits); - lp->ncommit = 0; - - /* Initialize the logfiles list for in-memory logs. */ - SH_TAILQ_INIT(&lp->logfiles); - SH_TAILQ_INIT(&lp->free_logfiles); - - /* - * Fill in the log's persistent header. Don't fill in the log file - * sizes, as they may change at any time and so have to be filled in - * as each log file is created. - */ - lp->persist.magic = DB_LOGMAGIC; - lp->persist.version = DB_LOGVERSION; - lp->persist.notused = 0; - - /* Migrate persistent flags from the DB_ENV into the region. */ - if (F_ISSET(dbenv, DB_ENV_LOG_AUTOREMOVE)) - lp->db_log_autoremove = 1; - if (F_ISSET(dbenv, DB_ENV_LOG_INMEMORY)) - lp->db_log_inmemory = 1; - - return (0); -} - -/* - * __log_recover -- - * Recover a log. - */ -static int -__log_recover(dblp) - DB_LOG *dblp; -{ - DBT dbt; - DB_ENV *dbenv; - DB_LOGC *logc; - DB_LSN lsn; - LOG *lp; - u_int32_t cnt, rectype; - int ret; - logfile_validity status; - - logc = NULL; - dbenv = dblp->dbenv; - lp = dblp->reginfo.primary; - - /* - * Find a log file. If none exist, we simply return, leaving - * everything initialized to a new log. - */ - if ((ret = __log_find(dblp, 0, &cnt, &status)) != 0) - return (ret); - if (cnt == 0) - return (0); - - /* - * If the last file is an old version, readable or no, start a new - * file. Don't bother finding the end of the last log file; - * we assume that it's valid in its entirety, since the user - * should have shut down cleanly or run recovery before upgrading. - */ - if (status == DB_LV_OLD_READABLE || status == DB_LV_OLD_UNREADABLE) { - lp->lsn.file = lp->s_lsn.file = cnt + 1; - lp->lsn.offset = lp->s_lsn.offset = 0; - goto skipsearch; - } - DB_ASSERT(status == DB_LV_NORMAL); - - /* - * We have the last useful log file and we've loaded any persistent - * information. Set the end point of the log past the end of the last - * file. Read the last file, looking for the last checkpoint and - * the log's end. - */ - lp->lsn.file = cnt + 1; - lp->lsn.offset = 0; - lsn.file = cnt; - lsn.offset = 0; - - /* - * Allocate a cursor and set it to the first record. This shouldn't - * fail, leave error messages on. - */ - if ((ret = __log_cursor(dbenv, &logc)) != 0) - return (ret); - F_SET(logc, DB_LOG_LOCKED); - memset(&dbt, 0, sizeof(dbt)); - if ((ret = __log_c_get(logc, &lsn, &dbt, DB_SET)) != 0) - goto err; - - /* - * Read to the end of the file. This may fail at some point, so - * turn off error messages. - */ - F_SET(logc, DB_LOG_SILENT_ERR); - while (__log_c_get(logc, &lsn, &dbt, DB_NEXT) == 0) { - if (dbt.size < sizeof(u_int32_t)) - continue; - memcpy(&rectype, dbt.data, sizeof(u_int32_t)); - if (rectype == DB___txn_ckp) - /* - * If we happen to run into a checkpoint, cache its - * LSN so that the transaction system doesn't have - * to walk this log file again looking for it. - */ - lp->cached_ckp_lsn = lsn; - } - F_CLR(logc, DB_LOG_SILENT_ERR); - - /* - * We now know where the end of the log is. Set the first LSN that - * we want to return to an application and the LSN of the last known - * record on disk. - */ - lp->lsn = lsn; - lp->s_lsn = lsn; - lp->lsn.offset += logc->c_len; - lp->s_lsn.offset += logc->c_len; - - /* Set up the current buffer information, too. */ - lp->len = logc->c_len; - lp->a_off = 0; - lp->b_off = 0; - lp->w_off = lp->lsn.offset; - -skipsearch: - if (FLD_ISSET(dbenv->verbose, DB_VERB_RECOVERY)) - __db_msg(dbenv, - "Finding last valid log LSN: file: %lu offset %lu", - (u_long)lp->lsn.file, (u_long)lp->lsn.offset); - -err: if (logc != NULL) - (void)__log_c_close(logc); - - return (ret); -} - -/* - * __log_find -- - * Try to find a log file. If find_first is set, valp will contain - * the number of the first readable log file, else it will contain the number - * of the last log file (which may be too old to read). - * - * PUBLIC: int __log_find __P((DB_LOG *, int, u_int32_t *, logfile_validity *)); - */ -int -__log_find(dblp, find_first, valp, statusp) - DB_LOG *dblp; - int find_first; - u_int32_t *valp; - logfile_validity *statusp; -{ - DB_ENV *dbenv; - LOG *lp; - logfile_validity logval_status, status; - struct __db_filestart *filestart; - u_int32_t clv, logval; - int cnt, fcnt, ret; - const char *dir; - char *c, **names, *p, *q, savech; - - dbenv = dblp->dbenv; - lp = dblp->reginfo.primary; - logval_status = status = DB_LV_NONEXISTENT; - - /* Return a value of 0 as the log file number on failure. */ - *valp = 0; - - if (lp->db_log_inmemory) { - filestart = find_first ? - SH_TAILQ_FIRST(&lp->logfiles, __db_filestart) : - SH_TAILQ_LAST(&lp->logfiles, links, __db_filestart); - if (filestart != NULL) { - *valp = filestart->file; - logval_status = DB_LV_NORMAL; - } - *statusp = logval_status; - return (0); - } - - /* Find the directory name. */ - if ((ret = __log_name(dblp, 1, &p, NULL, 0)) != 0) - return (ret); - if ((q = __db_rpath(p)) == NULL) { - COMPQUIET(savech, 0); - dir = PATH_DOT; - } else { - savech = *q; - *q = '\0'; - dir = p; - } - - /* Get the list of file names. */ - ret = __os_dirlist(dbenv, dir, &names, &fcnt); - - /* - * !!! - * We overwrote a byte in the string with a nul. Restore the string - * so that the diagnostic checks in the memory allocation code work - * and any error messages display the right file name. - */ - if (q != NULL) - *q = savech; - - if (ret != 0) { - __db_err(dbenv, "%s: %s", dir, db_strerror(ret)); - __os_free(dbenv, p); - return (ret); - } - - /* Search for a valid log file name. */ - for (cnt = fcnt, clv = logval = 0; --cnt >= 0;) { - if (strncmp(names[cnt], LFPREFIX, sizeof(LFPREFIX) - 1) != 0) - continue; - - /* - * Names of the form log\.[0-9]* are reserved for DB. Other - * names sharing LFPREFIX, such as "log.db", are legal. - */ - for (c = names[cnt] + sizeof(LFPREFIX) - 1; *c != '\0'; c++) - if (!isdigit((int)*c)) - break; - if (*c != '\0') - continue; - - /* - * Use atol, not atoi; if an "int" is 16-bits, the largest - * log file name won't fit. - */ - clv = (u_int32_t)atol(names[cnt] + (sizeof(LFPREFIX) - 1)); - - /* - * If searching for the first log file, we want to return the - * oldest log file we can read, or, if no readable log files - * exist, the newest log file we can't read (the crossover - * point between the old and new versions of the log file). - * - * If we're searching for the last log file, we want to return - * the newest log file, period. - * - * Readable log files should never precede unreadable log - * files, that would mean the admin seriously screwed up. - */ - if (find_first) { - if (logval != 0 && - status != DB_LV_OLD_UNREADABLE && clv > logval) - continue; - } else - if (logval != 0 && clv < logval) - continue; - - if ((ret = __log_valid(dblp, clv, 1, NULL, 0, &status)) != 0) { - __db_err(dbenv, "Invalid log file: %s: %s", - names[cnt], db_strerror(ret)); - goto err; - } - switch (status) { - case DB_LV_NONEXISTENT: - /* __log_valid never returns DB_LV_NONEXISTENT. */ - DB_ASSERT(0); - break; - case DB_LV_INCOMPLETE: - /* - * The last log file may not have been initialized -- - * it's possible to create a log file but not write - * anything to it. If performing recovery (that is, - * if find_first isn't set), ignore the file, it's - * not interesting. If we're searching for the first - * log record, return the file (assuming we don't find - * something better), as the "real" first log record - * is likely to be in the log buffer, and we want to - * set the file LSN for our return. - */ - if (find_first) - goto found; - break; - case DB_LV_OLD_UNREADABLE: - /* - * If we're searching for the first log file, then we - * only want this file if we don't yet have a file or - * already have an unreadable file and this one is - * newer than that one. If we're searching for the - * last log file, we always want this file because we - * wouldn't be here if it wasn't newer than our current - * choice. - */ - if (!find_first || logval == 0 || - (status == DB_LV_OLD_UNREADABLE && clv > logval)) - goto found; - break; - case DB_LV_NORMAL: - case DB_LV_OLD_READABLE: -found: logval = clv; - logval_status = status; - break; - } - } - - *valp = logval; - -err: __os_dirfree(dbenv, names, fcnt); - __os_free(dbenv, p); - *statusp = logval_status; - - return (ret); -} - -/* - * log_valid -- - * Validate a log file. Returns an error code in the event of - * a fatal flaw in a the specified log file; returns success with - * a code indicating the currentness and completeness of the specified - * log file if it is not unexpectedly flawed (that is, if it's perfectly - * normal, if it's zero-length, or if it's an old version). - * - * PUBLIC: int __log_valid __P((DB_LOG *, u_int32_t, int, - * PUBLIC: DB_FH **, u_int32_t, logfile_validity *)); - */ -int -__log_valid(dblp, number, set_persist, fhpp, flags, statusp) - DB_LOG *dblp; - u_int32_t number; - int set_persist; - DB_FH **fhpp; - u_int32_t flags; - logfile_validity *statusp; -{ - DB_CIPHER *db_cipher; - DB_ENV *dbenv; - DB_FH *fhp; - HDR *hdr; - LOG *lp; - LOGP *persist; - logfile_validity status; - size_t hdrsize, nr, recsize; - int is_hmac, ret; - u_int8_t *tmp; - char *fname; - - dbenv = dblp->dbenv; - db_cipher = dbenv->crypto_handle; - fhp = NULL; - persist = NULL; - status = DB_LV_NORMAL; - tmp = NULL; - - /* Return the file handle to our caller, on request */ - if (fhpp != NULL) - *fhpp = NULL; - - if (flags == 0) - flags = DB_OSO_RDONLY | DB_OSO_SEQ; - /* Try to open the log file. */ - if ((ret = __log_name(dblp, number, &fname, &fhp, flags)) != 0) { - __os_free(dbenv, fname); - return (ret); - } - - hdrsize = HDR_NORMAL_SZ; - is_hmac = 0; - recsize = sizeof(LOGP); - if (CRYPTO_ON(dbenv)) { - hdrsize = HDR_CRYPTO_SZ; - recsize = sizeof(LOGP); - recsize += db_cipher->adj_size(recsize); - is_hmac = 1; - } - if ((ret = __os_calloc(dbenv, 1, recsize + hdrsize, &tmp)) != 0) - goto err; - - hdr = (HDR *)tmp; - persist = (LOGP *)(tmp + hdrsize); - /* - * Try to read the header. This can fail if the log is truncated, or - * if we find a preallocated log file where the header has not yet been - * written, so we need to check whether the header is zero-filled. - */ - if ((ret = __os_read(dbenv, fhp, tmp, recsize + hdrsize, &nr)) != 0 || - nr != recsize + hdrsize || - (hdr->len == 0 && persist->magic == 0 && persist->log_size == 0)) { - if (ret == 0) - status = DB_LV_INCOMPLETE; - else - /* - * The error was a fatal read error, not just an - * incompletely initialized log file. - */ - __db_err(dbenv, "Ignoring log file: %s: %s", - fname, db_strerror(ret)); - goto err; - } - - /* - * Now we have to validate the persistent record. We have - * several scenarios we have to deal with: - * - * 1. User has crypto turned on: - * - They're reading an old, unencrypted log file - * . We will fail the record size match check below. - * - They're reading a current, unencrypted log file - * . We will fail the record size match check below. - * - They're reading an old, encrypted log file [NOT YET] - * . After decryption we'll fail the version check. [NOT YET] - * - They're reading a current, encrypted log file - * . We should proceed as usual. - * 2. User has crypto turned off: - * - They're reading an old, unencrypted log file - * . We will fail the version check. - * - They're reading a current, unencrypted log file - * . We should proceed as usual. - * - They're reading an old, encrypted log file [NOT YET] - * . We'll fail the magic number check (it is encrypted). - * - They're reading a current, encrypted log file - * . We'll fail the magic number check (it is encrypted). - */ - if (CRYPTO_ON(dbenv)) { - /* - * If we are trying to decrypt an unencrypted log - * we can only detect that by having an unreasonable - * data length for our persistent data. - */ - if ((hdr->len - hdrsize) != sizeof(LOGP)) { - __db_err(dbenv, "log record size mismatch"); - goto err; - } - /* Check the checksum and decrypt. */ - if ((ret = __db_check_chksum(dbenv, db_cipher, &hdr->chksum[0], - (u_int8_t *)persist, hdr->len - hdrsize, is_hmac)) != 0) { - __db_err(dbenv, "log record checksum mismatch"); - goto err; - } - if ((ret = db_cipher->decrypt(dbenv, db_cipher->data, - &hdr->iv[0], (u_int8_t *)persist, hdr->len - hdrsize)) != 0) - goto err; - } - - /* Validate the header. */ - if (persist->magic != DB_LOGMAGIC) { - __db_err(dbenv, - "Ignoring log file: %s: magic number %lx, not %lx", - fname, (u_long)persist->magic, (u_long)DB_LOGMAGIC); - ret = EINVAL; - goto err; - } - - /* - * Set our status code to indicate whether the log file belongs to an - * unreadable or readable old version; leave it alone if and only if - * the log file version is the current one. - */ - if (persist->version > DB_LOGVERSION) { - /* This is a fatal error--the log file is newer than DB. */ - __db_err(dbenv, - "Unacceptable log file %s: unsupported log version %lu", - fname, (u_long)persist->version); - ret = EINVAL; - goto err; - } else if (persist->version < DB_LOGOLDVER) { - status = DB_LV_OLD_UNREADABLE; - /* This is a non-fatal error, but give some feedback. */ - __db_err(dbenv, - "Skipping log file %s: historic log version %lu", - fname, (u_long)persist->version); - /* - * We don't want to set persistent info based on an unreadable - * region, so jump to "err". - */ - goto err; - } else if (persist->version < DB_LOGVERSION) - status = DB_LV_OLD_READABLE; - - /* - * Only if we have a current log do we verify the checksum. We could - * not check the checksum before checking the magic and version because - * old log headers put the length and checksum in a different location. - */ - if (!CRYPTO_ON(dbenv) && ((ret = __db_check_chksum(dbenv, - db_cipher, &hdr->chksum[0], (u_int8_t *)persist, - hdr->len - hdrsize, is_hmac)) != 0)) { - __db_err(dbenv, "log record checksum mismatch"); - goto err; - } - - /* - * If the log is readable so far and we're doing system initialization, - * set the region's persistent information based on the headers. - * - * Override the current log file size. - */ - if (set_persist) { - lp = dblp->reginfo.primary; - lp->log_size = persist->log_size; - } - -err: if (fname != NULL) - __os_free(dbenv, fname); - if (ret == 0 && fhpp != NULL) - *fhpp = fhp; - else - /* Must close on error or if we only used it locally. */ - (void)__os_closehandle(dbenv, fhp); - if (tmp != NULL) - __os_free(dbenv, tmp); - - *statusp = status; - - return (ret); -} - -/* - * __log_dbenv_refresh -- - * Clean up after the log system on a close or failed open. - * - * PUBLIC: int __log_dbenv_refresh __P((DB_ENV *)); - */ -int -__log_dbenv_refresh(dbenv) - DB_ENV *dbenv; -{ - DB_LOG *dblp; - LOG *lp; - REGINFO *reginfo; - struct __fname *fnp; - int ret, t_ret; - - dblp = dbenv->lg_handle; - reginfo = &dblp->reginfo; - lp = reginfo->primary; - - /* We may have opened files as part of XA; if so, close them. */ - ret = __dbreg_close_files(dbenv); - - /* - * After we close the files, check for any unlogged closes left in - * the shared memory queue. If we find any, we need to panic the - * region. Note, just set "ret" -- a panic overrides any previously - * set error return. - */ - for (fnp = SH_TAILQ_FIRST(&lp->fq, __fname); fnp != NULL; - fnp = SH_TAILQ_NEXT(fnp, q, __fname)) - if (F_ISSET(fnp, DB_FNAME_NOTLOGGED)) - ret = __db_panic(dbenv, EINVAL); - - /* - * If a private region, return the memory to the heap. Not needed for - * filesystem-backed or system shared memory regions, that memory isn't - * owned by any particular process. - */ - if (F_ISSET(dbenv, DB_ENV_PRIVATE)) { - /* Discard the flush mutex. */ - if ((t_ret = - __mutex_free(dbenv, &lp->mtx_flush)) != 0 && ret == 0) - ret = t_ret; - - /* Discard the buffer. */ - __db_shalloc_free(reginfo, R_ADDR(reginfo, lp->buffer_off)); - - /* Discard stack of free file IDs. */ - if (lp->free_fid_stack != INVALID_ROFF) - __db_shalloc_free(reginfo, - R_ADDR(reginfo, lp->free_fid_stack)); - } - - /* Discard the per-thread DBREG mutex. */ - if ((t_ret = __mutex_free(dbenv, &dblp->mtx_dbreg)) != 0 && ret == 0) - ret = t_ret; - - /* Detach from the region. */ - if ((t_ret = __db_r_detach(dbenv, reginfo, 0)) != 0 && ret == 0) - ret = t_ret; - - /* Close open files, release allocated memory. */ - if (dblp->lfhp != NULL) { - if ((t_ret = - __os_closehandle(dbenv, dblp->lfhp)) != 0 && ret == 0) - ret = t_ret; - dblp->lfhp = NULL; - } - if (dblp->dbentry != NULL) - __os_free(dbenv, dblp->dbentry); - - __os_free(dbenv, dblp); - - dbenv->lg_handle = NULL; - return (ret); -} - -/* - * __log_get_cached_ckp_lsn -- - * Retrieve any last checkpoint LSN that we may have found on startup. - * - * PUBLIC: int __log_get_cached_ckp_lsn __P((DB_ENV *, DB_LSN *)); - */ -int -__log_get_cached_ckp_lsn(dbenv, ckp_lsnp) - DB_ENV *dbenv; - DB_LSN *ckp_lsnp; -{ - DB_LOG *dblp; - LOG *lp; - - dblp = (DB_LOG *)dbenv->lg_handle; - lp = (LOG *)dblp->reginfo.primary; - - LOG_SYSTEM_LOCK(dbenv); - *ckp_lsnp = lp->cached_ckp_lsn; - LOG_SYSTEM_UNLOCK(dbenv); - - return (0); -} - -/* - * __log_region_mutex_count -- - * Return the number of mutexes the log region will need. - * - * PUBLIC: u_int32_t __log_region_mutex_count __P((DB_ENV *)); - */ -u_int32_t -__log_region_mutex_count(dbenv) - DB_ENV *dbenv; -{ - /* - * We need a few assorted mutexes, and one per transaction waiting - * on the group commit list. We can't know how many that will be, - * but it should be bounded by the maximum active transactions. - */ - return (dbenv->tx_max + 5); -} - -/* - * __log_region_size -- - * Return the amount of space needed for the log region. - * Make the region large enough to hold txn_max transaction - * detail structures plus some space to hold thread handles - * and the beginning of the shalloc region and anything we - * need for mutex system resource recording. - */ -static size_t -__log_region_size(dbenv) - DB_ENV *dbenv; -{ - size_t s; - - s = dbenv->lg_regionmax + dbenv->lg_bsize; - - /* - * If running with replication, add in space for bulk buffer. - * Allocate a megabyte and a little bit more space. - */ - if (IS_ENV_REPLICATED(dbenv)) - s += MEGABYTE; - - return (s); -} - -/* - * __log_vtruncate - * This is a virtual truncate. We set up the log indicators to - * make everyone believe that the given record is the last one in the - * log. Returns with the next valid LSN (i.e., the LSN of the next - * record to be written). This is used in replication to discard records - * in the log file that do not agree with the master. - * - * PUBLIC: int __log_vtruncate __P((DB_ENV *, DB_LSN *, DB_LSN *, DB_LSN *)); - */ -int -__log_vtruncate(dbenv, lsn, ckplsn, trunclsn) - DB_ENV *dbenv; - DB_LSN *lsn, *ckplsn, *trunclsn; -{ - DBT log_dbt; - DB_LOG *dblp; - DB_LOGC *logc; - DB_LSN end_lsn; - LOG *lp; - u_int32_t bytes, c_len; - int ret, t_ret; - - /* Need to find out the length of this soon-to-be-last record. */ - if ((ret = __log_cursor(dbenv, &logc)) != 0) - return (ret); - memset(&log_dbt, 0, sizeof(log_dbt)); - ret = __log_c_get(logc, lsn, &log_dbt, DB_SET); - c_len = logc->c_len; - if ((t_ret = __log_c_close(logc)) != 0 && ret == 0) - ret = t_ret; - if (ret != 0) - return (ret); - - /* Now do the truncate. */ - dblp = (DB_LOG *)dbenv->lg_handle; - lp = (LOG *)dblp->reginfo.primary; - - LOG_SYSTEM_LOCK(dbenv); - - /* - * Flush the log so we can simply initialize the in-memory buffer - * after the truncate. - */ - if ((ret = __log_flush_int(dblp, NULL, 0)) != 0) - goto err; - - end_lsn = lp->lsn; - lp->lsn = *lsn; - lp->len = c_len; - lp->lsn.offset += lp->len; - - if (lp->db_log_inmemory && - (ret = __log_inmem_lsnoff(dblp, &lp->lsn, &lp->b_off)) != 0) - goto err; - - /* - * I am going to assume that the number of bytes written since - * the last checkpoint doesn't exceed a 32-bit number. - */ - DB_ASSERT(lp->lsn.file >= ckplsn->file); - bytes = 0; - if (ckplsn->file != lp->lsn.file) { - bytes = lp->log_size - ckplsn->offset; - if (lp->lsn.file > ckplsn->file + 1) - bytes += lp->log_size * - ((lp->lsn.file - ckplsn->file) - 1); - bytes += lp->lsn.offset; - } else - bytes = lp->lsn.offset - ckplsn->offset; - - lp->stat.st_wc_mbytes += bytes / MEGABYTE; - lp->stat.st_wc_bytes += bytes % MEGABYTE; - - /* - * If the saved lsn is greater than our new end of log, reset it - * to our current end of log. - */ - MUTEX_LOCK(dbenv, lp->mtx_flush); - if (log_compare(&lp->s_lsn, lsn) > 0) - lp->s_lsn = lp->lsn; - MUTEX_UNLOCK(dbenv, lp->mtx_flush); - - /* Initialize the in-region buffer to a pristine state. */ - ZERO_LSN(lp->f_lsn); - lp->w_off = lp->lsn.offset; - - if (trunclsn != NULL) - *trunclsn = lp->lsn; - - /* Truncate the log to the new point. */ - if ((ret = __log_zero(dbenv, &lp->lsn, &end_lsn)) != 0) - goto err; - -err: LOG_SYSTEM_UNLOCK(dbenv); - return (ret); -} - -/* - * __log_is_outdated -- - * Used by the replication system to identify if a client's logs are too - * old. - * - * PUBLIC: int __log_is_outdated __P((DB_ENV *, u_int32_t, int *)); - */ -int -__log_is_outdated(dbenv, fnum, outdatedp) - DB_ENV *dbenv; - u_int32_t fnum; - int *outdatedp; -{ - DB_LOG *dblp; - LOG *lp; - char *name; - int ret; - u_int32_t cfile; - struct __db_filestart *filestart; - - dblp = dbenv->lg_handle; - - /* - * The log represented by dbenv is compared to the file number passed - * in fnum. If the log file fnum does not exist and is lower-numbered - * than the current logs, return *outdatedp non-zero, else we return 0. - */ - if (F_ISSET(dbenv, DB_ENV_LOG_INMEMORY)) { - LOG_SYSTEM_LOCK(dbenv); - lp = (LOG *)dblp->reginfo.primary; - filestart = SH_TAILQ_FIRST(&lp->logfiles, __db_filestart); - *outdatedp = filestart == NULL ? 0 : (fnum < filestart->file); - LOG_SYSTEM_UNLOCK(dbenv); - return (0); - } - - *outdatedp = 0; - if ((ret = __log_name(dblp, fnum, &name, NULL, 0)) != 0) - return (ret); - - /* If the file exists, we're just fine. */ - if (__os_exists(name, NULL) == 0) - goto out; - - /* - * It didn't exist, decide if the file number is too big or - * too little. If it's too little, then we need to indicate - * that the LSN is outdated. - */ - LOG_SYSTEM_LOCK(dbenv); - lp = (LOG *)dblp->reginfo.primary; - cfile = lp->lsn.file; - LOG_SYSTEM_UNLOCK(dbenv); - - if (cfile > fnum) - *outdatedp = 1; -out: __os_free(dbenv, name); - return (ret); -} - -/* - * __log_zero -- - * Zero out the tail of a log after a truncate. - */ -static int -__log_zero(dbenv, from_lsn, to_lsn) - DB_ENV *dbenv; - DB_LSN *from_lsn, *to_lsn; -{ - DB_FH *fhp; - DB_LOG *dblp; - LOG *lp; - struct __db_filestart *filestart, *nextstart; - size_t nbytes, len, nw; - u_int32_t fn, mbytes, bytes; - u_int8_t buf[4096]; - int ret; - char *fname; - - dblp = dbenv->lg_handle; - DB_ASSERT(log_compare(from_lsn, to_lsn) <= 0); - if (log_compare(from_lsn, to_lsn) > 0) { - __db_err(dbenv, - "Warning: truncating to point beyond end of log"); - return (0); - } - - lp = (LOG *)dblp->reginfo.primary; - if (lp->db_log_inmemory) { - /* - * Remove the first file if it is invalidated by this write. - * Log records can't be bigger than a file, so we only need to - * check the first file. - */ - for (filestart = SH_TAILQ_FIRST(&lp->logfiles, __db_filestart); - filestart != NULL && from_lsn->file < filestart->file; - filestart = nextstart) { - nextstart = SH_TAILQ_NEXT(filestart, - links, __db_filestart); - SH_TAILQ_REMOVE(&lp->logfiles, filestart, - links, __db_filestart); - SH_TAILQ_INSERT_HEAD(&lp->free_logfiles, filestart, - links, __db_filestart); - } - - return (0); - } - - /* Close any open file handles so unlinks don't fail. */ - if (dblp->lfhp != NULL) { - (void)__os_closehandle(dbenv, dblp->lfhp); - dblp->lfhp = NULL; - } - - /* Throw away any extra log files that we have around. */ - for (fn = from_lsn->file + 1;; fn++) { - if (__log_name(dblp, fn, &fname, &fhp, DB_OSO_RDONLY) != 0) { - __os_free(dbenv, fname); - break; - } - (void)__os_closehandle(dbenv, fhp); - ret = __os_unlink(dbenv, fname); - __os_free(dbenv, fname); - if (ret != 0) - return (ret); - } - - /* We removed some log files; have to 0 to end of file. */ - if ((ret = - __log_name(dblp, from_lsn->file, &fname, &dblp->lfhp, 0)) != 0) - return (ret); - __os_free(dbenv, fname); - if ((ret = __os_ioinfo(dbenv, - NULL, dblp->lfhp, &mbytes, &bytes, NULL)) != 0) - goto err; - DB_ASSERT((mbytes * MEGABYTE + bytes) >= from_lsn->offset); - len = (mbytes * MEGABYTE + bytes) - from_lsn->offset; - - memset(buf, 0, sizeof(buf)); - - /* Initialize the write position. */ - if ((ret = __os_seek(dbenv, - dblp->lfhp, 0, 0, from_lsn->offset, 0, DB_OS_SEEK_SET)) != 0) - goto err; - - while (len > 0) { - nbytes = len > sizeof(buf) ? sizeof(buf) : len; - if ((ret = - __os_write(dbenv, dblp->lfhp, buf, nbytes, &nw)) != 0) - goto err; - len -= nbytes; - } - -err: (void)__os_closehandle(dbenv, dblp->lfhp); - dblp->lfhp = NULL; - - return (ret); -} - -/* - * __log_inmem_lsnoff -- - * Find the offset in the buffer of a given LSN. - * - * PUBLIC: int __log_inmem_lsnoff __P((DB_LOG *, DB_LSN *, size_t *)); - */ -int -__log_inmem_lsnoff(dblp, lsn, offsetp) - DB_LOG *dblp; - DB_LSN *lsn; - size_t *offsetp; -{ - LOG *lp; - struct __db_filestart *filestart; - - lp = (LOG *)dblp->reginfo.primary; - - SH_TAILQ_FOREACH(filestart, &lp->logfiles, links, __db_filestart) - if (filestart->file == lsn->file) { - *offsetp = - (filestart->b_off + lsn->offset) % lp->buffer_size; - return (0); - } - - return (DB_NOTFOUND); -} - -/* - * __log_inmem_newfile -- - * Records the offset of the beginning of a new file in the in-memory - * buffer. - * - * PUBLIC: int __log_inmem_newfile __P((DB_LOG *, u_int32_t)); - */ -int -__log_inmem_newfile(dblp, file) - DB_LOG *dblp; - u_int32_t file; -{ - HDR hdr; - LOG *lp; - struct __db_filestart *filestart; - int ret; -#ifdef DIAGNOSTIC - struct __db_filestart *first, *last; -#endif - - lp = (LOG *)dblp->reginfo.primary; - - /* - * We write an empty header at the end of every in-memory log file. - * This is used during cursor traversal to indicate when to switch the - * LSN to the next file. - */ - if (file > 1) { - memset(&hdr, 0, sizeof(HDR)); - __log_inmem_copyin(dblp, lp->b_off, &hdr, sizeof(HDR)); - lp->b_off = (lp->b_off + sizeof(HDR)) % lp->buffer_size; - } - - filestart = SH_TAILQ_FIRST(&lp->free_logfiles, __db_filestart); - if (filestart == NULL) { - if ((ret = __db_shalloc(&dblp->reginfo, - sizeof(struct __db_filestart), 0, &filestart)) != 0) - return (ret); - memset(filestart, 0, sizeof(*filestart)); - } else - SH_TAILQ_REMOVE(&lp->free_logfiles, filestart, - links, __db_filestart); - - filestart->file = file; - filestart->b_off = lp->b_off; - -#ifdef DIAGNOSTIC - first = SH_TAILQ_FIRST(&lp->logfiles, __db_filestart); - last = SH_TAILQ_LAST(&(lp)->logfiles, links, __db_filestart); - - /* Check that we don't wrap. */ - DB_ASSERT(!first || first == last || - RINGBUF_LEN(lp, first->b_off, lp->b_off) == - RINGBUF_LEN(lp, first->b_off, last->b_off) + - RINGBUF_LEN(lp, last->b_off, lp->b_off)); -#endif - - SH_TAILQ_INSERT_TAIL(&lp->logfiles, filestart, links); - return (0); -} - -/* - * __log_inmem_chkspace -- - * Ensure that the requested amount of space is available in the buffer, - * and invalidate the region. - * Note: assumes that the region lock is held on entry. - * - * PUBLIC: int __log_inmem_chkspace __P((DB_LOG *, size_t)); - */ -int -__log_inmem_chkspace(dblp, len) - DB_LOG *dblp; - size_t len; -{ - DB_ENV *dbenv; - LOG *lp; - DB_LSN active_lsn, old_active_lsn; - struct __db_filestart *filestart; - int ret; - - dbenv = dblp->dbenv; - lp = dblp->reginfo.primary; - - DB_ASSERT(lp->db_log_inmemory); - - /* - * Allow room for an extra header so that we don't need to check for - * space when switching files. - */ - len += sizeof(HDR); - - /* - * If transactions are enabled and we're about to fill available space, - * update the active LSN and recheck. If transactions aren't enabled, - * don't even bother checking: in that case we can always overwrite old - * log records, because we're never going to abort. - */ - while (TXN_ON(dbenv) && - RINGBUF_LEN(lp, lp->b_off, lp->a_off) <= len) { - old_active_lsn = lp->active_lsn; - active_lsn = lp->lsn; - - /* - * Drop the log region lock so we don't hold it while - * taking the transaction region lock. - */ - LOG_SYSTEM_UNLOCK(dbenv); - if ((ret = __txn_getactive(dbenv, &active_lsn)) != 0) - return (ret); - LOG_SYSTEM_LOCK(dbenv); - active_lsn.offset = 0; - - /* If we didn't make any progress, give up. */ - if (log_compare(&active_lsn, &old_active_lsn) == 0) { - __db_err(dbenv, - "In-memory log buffer is full (an active transaction spans the buffer)"); - return (DB_LOG_BUFFER_FULL); - } - - /* Make sure we're moving the region LSN forwards. */ - if (log_compare(&active_lsn, &lp->active_lsn) > 0) { - lp->active_lsn = active_lsn; - (void)__log_inmem_lsnoff(dblp, &active_lsn, - &lp->a_off); - } - } - - /* - * Remove the first file if it is invalidated by this write. - * Log records can't be bigger than a file, so we only need to - * check the first file. - */ - filestart = SH_TAILQ_FIRST(&lp->logfiles, __db_filestart); - if (filestart != NULL && - RINGBUF_LEN(lp, lp->b_off, filestart->b_off) <= len) { - SH_TAILQ_REMOVE(&lp->logfiles, filestart, - links, __db_filestart); - SH_TAILQ_INSERT_HEAD(&lp->free_logfiles, filestart, - links, __db_filestart); - lp->f_lsn.file = filestart->file + 1; - } - - return (0); -} - -/* - * __log_inmem_copyout -- - * Copies the given number of bytes from the buffer -- no checking. - * Note: assumes that the region lock is held on entry. - * - * PUBLIC: void __log_inmem_copyout __P((DB_LOG *, size_t, void *, size_t)); - */ -void -__log_inmem_copyout(dblp, offset, buf, size) - DB_LOG *dblp; - size_t offset; - void *buf; - size_t size; -{ - LOG *lp; - size_t nbytes; - - lp = (LOG *)dblp->reginfo.primary; - nbytes = (offset + size < lp->buffer_size) ? - size : lp->buffer_size - offset; - memcpy(buf, dblp->bufp + offset, nbytes); - if (nbytes < size) - memcpy((u_int8_t *)buf + nbytes, dblp->bufp, size - nbytes); -} - -/* - * __log_inmem_copyin -- - * Copies the given number of bytes into the buffer -- no checking. - * Note: assumes that the region lock is held on entry. - * - * PUBLIC: void __log_inmem_copyin __P((DB_LOG *, size_t, void *, size_t)); - */ -void -__log_inmem_copyin(dblp, offset, buf, size) - DB_LOG *dblp; - size_t offset; - void *buf; - size_t size; -{ - LOG *lp; - size_t nbytes; - - lp = (LOG *)dblp->reginfo.primary; - nbytes = (offset + size < lp->buffer_size) ? - size : lp->buffer_size - offset; - memcpy(dblp->bufp + offset, buf, nbytes); - if (nbytes < size) - memcpy(dblp->bufp, (u_int8_t *)buf + nbytes, size - nbytes); -} diff --git a/storage/bdb/log/log_archive.c b/storage/bdb/log/log_archive.c deleted file mode 100644 index 267997eadbf..00000000000 --- a/storage/bdb/log/log_archive.c +++ /dev/null @@ -1,591 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: log_archive.c,v 12.9 2005/11/04 17:27:58 ubell Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stdlib.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/log.h" -#include "dbinc/qam.h" -#include "dbinc/txn.h" - -static int __absname __P((DB_ENV *, char *, char *, char **)); -static int __build_data __P((DB_ENV *, char *, char ***)); -static int __cmpfunc __P((const void *, const void *)); -static int __log_archive __P((DB_ENV *, char **[], u_int32_t)); -static int __usermem __P((DB_ENV *, char ***)); - -/* - * __log_archive_pp -- - * DB_ENV->log_archive pre/post processing. - * - * PUBLIC: int __log_archive_pp __P((DB_ENV *, char **[], u_int32_t)); - */ -int -__log_archive_pp(dbenv, listp, flags) - DB_ENV *dbenv; - char ***listp; - u_int32_t flags; -{ - DB_THREAD_INFO *ip; - int ret; - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, - dbenv->lg_handle, "DB_ENV->log_archive", DB_INIT_LOG); - -#define OKFLAGS (DB_ARCH_ABS | DB_ARCH_DATA | DB_ARCH_LOG | DB_ARCH_REMOVE) - if (flags != 0) { - if ((ret = __db_fchk( - dbenv, "DB_ENV->log_archive", flags, OKFLAGS)) != 0) - return (ret); - if ((ret = __db_fcchk(dbenv, "DB_ENV->log_archive", - flags, DB_ARCH_DATA, DB_ARCH_LOG)) != 0) - return (ret); - if ((ret = __db_fcchk(dbenv, "DB_ENV->log_archive", - flags, DB_ARCH_REMOVE, - DB_ARCH_ABS | DB_ARCH_DATA | DB_ARCH_LOG)) != 0) - return (ret); - } - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, (__log_archive(dbenv, listp, flags)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __log_archive -- - * DB_ENV->log_archive. Internal. - */ -static int -__log_archive(dbenv, listp, flags) - DB_ENV *dbenv; - char ***listp; - u_int32_t flags; -{ - DBT rec; - DB_LOG *dblp; - LOG *lp; - DB_LOGC *logc; - DB_LSN stable_lsn; - u_int array_size, n; - u_int32_t fnum; - int ret, t_ret; - char **array, **arrayp, *name, *p, *pref; - - dblp = dbenv->lg_handle; - lp = (LOG *)dblp->reginfo.primary; - array = NULL; - name = NULL; - ret = 0; - COMPQUIET(fnum, 0); - - if (flags != DB_ARCH_REMOVE) - *listp = NULL; - - /* There are no log files if logs are in memory. */ - if (lp->db_log_inmemory) { - LF_CLR(~DB_ARCH_DATA); - if (flags == 0) - return (0); - } - - /* - * If the user wants the list of log files to remove and we're - * at a bad time in replication initialization, just return. - */ - if (!LF_ISSET(DB_ARCH_DATA) && - !LF_ISSET(DB_ARCH_LOG) && __rep_noarchive(dbenv)) - return (0); - - /* - * Prepend the original absolute pathname if the user wants an - * absolute path to the database environment directory. - */ - pref = LF_ISSET(DB_ARCH_ABS) ? dbenv->db_abshome : NULL; - - LF_CLR(DB_ARCH_ABS); - switch (flags) { - case DB_ARCH_DATA: - ret = __build_data(dbenv, pref, listp); - goto err; - case DB_ARCH_LOG: - memset(&rec, 0, sizeof(rec)); - if ((ret = __log_cursor(dbenv, &logc)) != 0) - goto err; -#ifdef UMRW - ZERO_LSN(stable_lsn); -#endif - ret = __log_c_get(logc, &stable_lsn, &rec, DB_LAST); - if ((t_ret = __log_c_close(logc)) != 0 && ret == 0) - ret = t_ret; - if (ret != 0) - goto err; - fnum = stable_lsn.file; - break; - case DB_ARCH_REMOVE: - __log_autoremove(dbenv); - goto err; - case 0: - - ret = __log_get_stable_lsn(dbenv, &stable_lsn); - /* - * A return of DB_NOTFOUND means the checkpoint LSN - * is before the beginning of the log files we have. - * This is not an error; it just means we're done. - */ - if (ret != 0) { - if (ret == DB_NOTFOUND) - ret = 0; - goto err; - } - /* Remove any log files before the last stable LSN. */ - fnum = stable_lsn.file - 1; - break; - default: - DB_ASSERT(0); - ret = EINVAL; - goto err; - } - -#define LIST_INCREMENT 64 - /* Get some initial space. */ - array_size = 64; - if ((ret = __os_malloc(dbenv, - sizeof(char *) * array_size, &array)) != 0) - goto err; - array[0] = NULL; - - /* Build an array of the file names. */ - for (n = 0; fnum > 0; --fnum) { - if ((ret = __log_name(dblp, fnum, &name, NULL, 0)) != 0) - goto err; - if (__os_exists(name, NULL) != 0) { - if (LF_ISSET(DB_ARCH_LOG) && fnum == stable_lsn.file) - continue; - __os_free(dbenv, name); - name = NULL; - break; - } - - if (n >= array_size - 2) { - array_size += LIST_INCREMENT; - if ((ret = __os_realloc(dbenv, - sizeof(char *) * array_size, &array)) != 0) - goto err; - } - - if (pref != NULL) { - if ((ret = - __absname(dbenv, pref, name, &array[n])) != 0) - goto err; - __os_free(dbenv, name); - } else if ((p = __db_rpath(name)) != NULL) { - if ((ret = __os_strdup(dbenv, p + 1, &array[n])) != 0) - goto err; - __os_free(dbenv, name); - } else - array[n] = name; - - name = NULL; - array[++n] = NULL; - } - - /* If there's nothing to return, we're done. */ - if (n == 0) - goto err; - - /* Sort the list. */ - qsort(array, (size_t)n, sizeof(char *), __cmpfunc); - - /* Rework the memory. */ - if ((ret = __usermem(dbenv, &array)) != 0) - goto err; - - if (listp != NULL) - *listp = array; - - if (0) { -err: if (array != NULL) { - for (arrayp = array; *arrayp != NULL; ++arrayp) - __os_free(dbenv, *arrayp); - __os_free(dbenv, array); - } - if (name != NULL) - __os_free(dbenv, name); - } - - return (ret); -} - -/* - * __log_get_stable_lsn -- - * Get the stable lsn based on where checkpoints are. - * - * PUBLIC: int __log_get_stable_lsn __P((DB_ENV *, DB_LSN *)); - */ -int -__log_get_stable_lsn(dbenv, stable_lsn) - DB_ENV *dbenv; - DB_LSN *stable_lsn; -{ - DB_LOGC *logc; - DBT rec; - __txn_ckp_args *ckp_args; - int ret, t_ret; - - ret = 0; - memset(&rec, 0, sizeof(rec)); - if (!TXN_ON(dbenv)) { - if ((ret = __log_get_cached_ckp_lsn(dbenv, stable_lsn)) != 0) - goto err; - /* - * No need to check for a return value of DB_NOTFOUND; - * __txn_findlastckp returns 0 if no checkpoint record - * is found. Instead of checking the return value, we - * check to see if the return LSN has been filled in. - */ - if (IS_ZERO_LSN(*stable_lsn) && (ret = - __txn_findlastckp(dbenv, stable_lsn, NULL)) != 0) - goto err; - /* - * If the LSN has not been filled in return DB_NOTFOUND - * so that the caller knows it may be done. - */ - if (IS_ZERO_LSN(*stable_lsn)) { - ret = DB_NOTFOUND; - goto err; - } - } else if ((ret = __txn_getckp(dbenv, stable_lsn)) != 0) - goto err; - if ((ret = __log_cursor(dbenv, &logc)) != 0) - goto err; - /* - * If we can read it, set the stable_lsn to the ckp_lsn in the - * checkpoint record. - */ - if ((ret = __log_c_get(logc, stable_lsn, &rec, DB_SET)) == 0 && - (ret = __txn_ckp_read(dbenv, rec.data, &ckp_args)) == 0) { - *stable_lsn = ckp_args->ckp_lsn; - __os_free(dbenv, ckp_args); - } - if ((t_ret = __log_c_close(logc)) != 0 && ret == 0) - ret = t_ret; -err: - return (ret); -} - -/* - * __log_autoremove -- - * Delete any non-essential log files. - * - * PUBLIC: void __log_autoremove __P((DB_ENV *)); - */ -void -__log_autoremove(dbenv) - DB_ENV *dbenv; -{ - int ret; - char **begin, **list; - - /* - * Complain if there's an error, but don't return the error to our - * caller. Auto-remove is done when writing a log record, and we - * don't want to fail a write, which could fail the corresponding - * committing transaction, for a permissions error. - */ - if ((ret = __log_archive(dbenv, &list, DB_ARCH_ABS)) != 0) { - if (ret != DB_NOTFOUND) - __db_err(dbenv, - "log file auto-remove: %s", db_strerror(ret)); - return; - } - - /* - * Remove the files. No error message needed for __os_unlink failure, - * the underlying OS layer has its own error handling. - */ - if (list != NULL) { - for (begin = list; *list != NULL; ++list) - (void)__os_unlink(dbenv, *list); - __os_ufree(dbenv, begin); - } -} - -/* - * __build_data -- - * Build a list of datafiles for return. - */ -static int -__build_data(dbenv, pref, listp) - DB_ENV *dbenv; - char *pref, ***listp; -{ - DBT rec; - DB_LOGC *logc; - DB_LSN lsn; - __dbreg_register_args *argp; - u_int array_size, last, n, nxt; - u_int32_t rectype; - int ret, t_ret; - char **array, **arrayp, **list, **lp, *p, *real_name; - - /* Get some initial space. */ - array_size = 64; - if ((ret = __os_malloc(dbenv, - sizeof(char *) * array_size, &array)) != 0) - return (ret); - array[0] = NULL; - - memset(&rec, 0, sizeof(rec)); - if ((ret = __log_cursor(dbenv, &logc)) != 0) - return (ret); - for (n = 0; (ret = __log_c_get(logc, &lsn, &rec, DB_PREV)) == 0;) { - if (rec.size < sizeof(rectype)) { - ret = EINVAL; - __db_err(dbenv, "DB_ENV->log_archive: bad log record"); - break; - } - - memcpy(&rectype, rec.data, sizeof(rectype)); - if (rectype != DB___dbreg_register) - continue; - if ((ret = - __dbreg_register_read(dbenv, rec.data, &argp)) != 0) { - ret = EINVAL; - __db_err(dbenv, - "DB_ENV->log_archive: unable to read log record"); - break; - } - - if (n >= array_size - 2) { - array_size += LIST_INCREMENT; - if ((ret = __os_realloc(dbenv, - sizeof(char *) * array_size, &array)) != 0) - goto free_continue; - } - - if ((ret = __os_strdup(dbenv, - argp->name.data, &array[n++])) != 0) - goto free_continue; - array[n] = NULL; - - if (argp->ftype == DB_QUEUE) { - if ((ret = __qam_extent_names(dbenv, - argp->name.data, &list)) != 0) - goto q_err; - for (lp = list; - lp != NULL && *lp != NULL; lp++) { - if (n >= array_size - 2) { - array_size += LIST_INCREMENT; - if ((ret = __os_realloc(dbenv, - sizeof(char *) * - array_size, &array)) != 0) - goto q_err; - } - if ((ret = - __os_strdup(dbenv, *lp, &array[n++])) != 0) - goto q_err; - array[n] = NULL; - } -q_err: if (list != NULL) - __os_free(dbenv, list); - } -free_continue: __os_free(dbenv, argp); - if (ret != 0) - break; - } - if (ret == DB_NOTFOUND) - ret = 0; - if ((t_ret = __log_c_close(logc)) != 0 && ret == 0) - ret = t_ret; - if (ret != 0) - goto err1; - - /* If there's nothing to return, we're done. */ - if (n == 0) { - ret = 0; - *listp = NULL; - goto err1; - } - - /* Sort the list. */ - qsort(array, (size_t)n, sizeof(char *), __cmpfunc); - - /* - * Build the real pathnames, discarding nonexistent files and - * duplicates. - */ - for (last = nxt = 0; nxt < n;) { - /* - * Discard duplicates. Last is the next slot we're going - * to return to the user, nxt is the next slot that we're - * going to consider. - */ - if (last != nxt) { - array[last] = array[nxt]; - array[nxt] = NULL; - } - for (++nxt; nxt < n && - strcmp(array[last], array[nxt]) == 0; ++nxt) { - __os_free(dbenv, array[nxt]); - array[nxt] = NULL; - } - - /* Get the real name. */ - if ((ret = __db_appname(dbenv, - DB_APP_DATA, array[last], 0, NULL, &real_name)) != 0) - goto err2; - - /* If the file doesn't exist, ignore it. */ - if (__os_exists(real_name, NULL) != 0) { - __os_free(dbenv, real_name); - __os_free(dbenv, array[last]); - array[last] = NULL; - continue; - } - - /* Rework the name as requested by the user. */ - __os_free(dbenv, array[last]); - array[last] = NULL; - if (pref != NULL) { - ret = __absname(dbenv, pref, real_name, &array[last]); - __os_free(dbenv, real_name); - if (ret != 0) - goto err2; - } else if ((p = __db_rpath(real_name)) != NULL) { - ret = __os_strdup(dbenv, p + 1, &array[last]); - __os_free(dbenv, real_name); - if (ret != 0) - goto err2; - } else - array[last] = real_name; - ++last; - } - - /* NULL-terminate the list. */ - array[last] = NULL; - - /* Rework the memory. */ - if ((ret = __usermem(dbenv, &array)) != 0) - goto err1; - - *listp = array; - return (0); - -err2: /* - * XXX - * We've possibly inserted NULLs into the array list, so clean up a - * bit so that the other error processing works. - */ - if (array != NULL) - for (; nxt < n; ++nxt) - __os_free(dbenv, array[nxt]); - /* FALLTHROUGH */ - -err1: if (array != NULL) { - for (arrayp = array; *arrayp != NULL; ++arrayp) - __os_free(dbenv, *arrayp); - __os_free(dbenv, array); - } - return (ret); -} - -/* - * __absname -- - * Return an absolute path name for the file. - */ -static int -__absname(dbenv, pref, name, newnamep) - DB_ENV *dbenv; - char *pref, *name, **newnamep; -{ - size_t l_pref, l_name; - int isabspath, ret; - char *newname; - - l_name = strlen(name); - isabspath = __os_abspath(name); - l_pref = isabspath ? 0 : strlen(pref); - - /* Malloc space for concatenating the two. */ - if ((ret = __os_malloc(dbenv, - l_pref + l_name + 2, &newname)) != 0) - return (ret); - *newnamep = newname; - - /* Build the name. If `name' is an absolute path, ignore any prefix. */ - if (!isabspath) { - memcpy(newname, pref, l_pref); - if (strchr(PATH_SEPARATOR, newname[l_pref - 1]) == NULL) - newname[l_pref++] = PATH_SEPARATOR[0]; - } - memcpy(newname + l_pref, name, l_name + 1); - - return (0); -} - -/* - * __usermem -- - * Create a single chunk of memory that holds the returned information. - * If the user has their own malloc routine, use it. - */ -static int -__usermem(dbenv, listp) - DB_ENV *dbenv; - char ***listp; -{ - size_t len; - int ret; - char **array, **arrayp, **orig, *strp; - - /* Find out how much space we need. */ - for (len = 0, orig = *listp; *orig != NULL; ++orig) - len += sizeof(char *) + strlen(*orig) + 1; - len += sizeof(char *); - - /* Allocate it and set up the pointers. */ - if ((ret = __os_umalloc(dbenv, len, &array)) != 0) - return (ret); - - strp = (char *)(array + (orig - *listp) + 1); - - /* Copy the original information into the new memory. */ - for (orig = *listp, arrayp = array; *orig != NULL; ++orig, ++arrayp) { - len = strlen(*orig); - memcpy(strp, *orig, len + 1); - *arrayp = strp; - strp += len + 1; - - __os_free(dbenv, *orig); - } - - /* NULL-terminate the list. */ - *arrayp = NULL; - - __os_free(dbenv, *listp); - *listp = array; - - return (0); -} - -static int -__cmpfunc(p1, p2) - const void *p1, *p2; -{ - return (strcmp(*((char * const *)p1), *((char * const *)p2))); -} diff --git a/storage/bdb/log/log_compare.c b/storage/bdb/log/log_compare.c deleted file mode 100644 index d4347b152aa..00000000000 --- a/storage/bdb/log/log_compare.c +++ /dev/null @@ -1,35 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: log_compare.c,v 12.1 2005/06/16 20:23:12 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - -#include "db_int.h" - -/* - * log_compare -- - * Compare two LSN's; return 1, 0, -1 if first is >, == or < second. - * - * EXTERN: int log_compare __P((const DB_LSN *, const DB_LSN *)); - */ -int -log_compare(lsn0, lsn1) - const DB_LSN *lsn0, *lsn1; -{ - if (lsn0->file != lsn1->file) - return (lsn0->file < lsn1->file ? -1 : 1); - - if (lsn0->offset != lsn1->offset) - return (lsn0->offset < lsn1->offset ? -1 : 1); - - return (0); -} diff --git a/storage/bdb/log/log_debug.c b/storage/bdb/log/log_debug.c deleted file mode 100644 index 0484cfef26d..00000000000 --- a/storage/bdb/log/log_debug.c +++ /dev/null @@ -1,160 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: log_debug.c,v 1.5 2005/10/14 01:17:09 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stdlib.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_am.h" -#include "dbinc/log.h" - -static int __log_printf_int __P((DB_ENV *, DB_TXN *, const char *, va_list)); - -/* - * __log_printf_capi -- - * Write a printf-style format string into the DB log. - * - * PUBLIC: int __log_printf_capi __P((DB_ENV *, DB_TXN *, const char *, ...)) - * PUBLIC: __attribute__ ((__format__ (__printf__, 3, 4))); - */ -int -#ifdef STDC_HEADERS -__log_printf_capi(DB_ENV *dbenv, DB_TXN *txnid, const char *fmt, ...) -#else -__log_printf_capi(dbenv, txnid, fmt, va_alist) - DB_ENV *dbenv; - DB_TXN *txnid; - const char *fmt; - va_dcl -#endif -{ - va_list ap; - int ret; - -#ifdef STDC_HEADERS - va_start(ap, fmt); -#else - va_start(ap); -#endif - ret = __log_printf_pp(dbenv, txnid, fmt, ap); - va_end(ap); - - return (ret); -} - -/* - * __log_printf_pp -- - * Handle the arguments and call an internal routine to do the work. - * - * The reason this routine isn't just folded into __log_printf_capi - * is because the C++ API has to call a C API routine, and you can - * only pass variadic arguments to a single routine. - * - * PUBLIC: int __log_printf_pp - * PUBLIC: __P((DB_ENV *, DB_TXN *, const char *, va_list)); - */ -int -__log_printf_pp(dbenv, txnid, fmt, ap) - DB_ENV *dbenv; - DB_TXN *txnid; - const char *fmt; - va_list ap; -{ - DB_THREAD_INFO *ip; - int rep_check, ret, t_ret; - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, - dbenv->lg_handle, "DB_ENV->log_printf", DB_INIT_LOG); - - ENV_ENTER(dbenv, ip); - rep_check = IS_ENV_REPLICATED(dbenv) ? 1 : 0; - if (rep_check && (ret = __env_rep_enter(dbenv, 0)) != 0) - return (ret); - - ret = __log_printf_int(dbenv, txnid, fmt, ap); - - if (rep_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && (ret) == 0) - ret = t_ret; - va_end(ap); - ENV_LEAVE(dbenv, ip); - - return (ret); -} - -/* - * __log_printf -- - * Write a printf-style format string into the DB log. - * - * PUBLIC: int __log_printf __P((DB_ENV *, DB_TXN *, const char *, ...)) - * PUBLIC: __attribute__ ((__format__ (__printf__, 3, 4))); - */ -int -#ifdef STDC_HEADERS -__log_printf(DB_ENV *dbenv, DB_TXN *txnid, const char *fmt, ...) -#else -__log_printf(dbenv, txnid, fmt, va_alist) - DB_ENV *dbenv; - DB_TXN *txnid; - const char *fmt; - va_dcl -#endif -{ - va_list ap; - int ret; - -#ifdef STDC_HEADERS - va_start(ap, fmt); -#else - va_start(ap); -#endif - ret = __log_printf_int(dbenv, txnid, fmt, ap); - va_end(ap); - - return (ret); -} - -/* - * __log_printf_int -- - * Write a printf-style format string into the DB log (internal). - */ -static int -__log_printf_int(dbenv, txnid, fmt, ap) - DB_ENV *dbenv; - DB_TXN *txnid; - const char *fmt; - va_list ap; -{ - DBT opdbt, msgdbt; - DB_LSN lsn; - char __logbuf[2048]; /* !!!: END OF THE STACK DON'T TRUST SPRINTF. */ - - if (!DBENV_LOGGING(dbenv)) { - __db_err(dbenv, "Logging not currently permitted"); - return (EAGAIN); - } - - memset(&opdbt, 0, sizeof(opdbt)); - opdbt.data = "DIAGNOSTIC"; - opdbt.size = sizeof("DIAGNOSTIC") - 1; - - memset(&msgdbt, 0, sizeof(msgdbt)); - msgdbt.data = __logbuf; - msgdbt.size = (u_int32_t)vsnprintf(__logbuf, sizeof(__logbuf), fmt, ap); - - return (__db_debug_log( - dbenv, txnid, &lsn, 0, &opdbt, -1, &msgdbt, NULL, 0)); -} diff --git a/storage/bdb/log/log_get.c b/storage/bdb/log/log_get.c deleted file mode 100644 index ccd1f3c3860..00000000000 --- a/storage/bdb/log/log_get.c +++ /dev/null @@ -1,1337 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: log_get.c,v 12.16 2005/10/21 17:13:42 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/crypto.h" -#include "dbinc/db_page.h" -#include "dbinc/hmac.h" -#include "dbinc/log.h" -#include "dbinc/hash.h" - -typedef enum { L_ALREADY, L_ACQUIRED, L_NONE } RLOCK; - -static int __log_c_close_pp __P((DB_LOGC *, u_int32_t)); -static int __log_c_get_pp __P((DB_LOGC *, DB_LSN *, DBT *, u_int32_t)); -static int __log_c_get_int __P((DB_LOGC *, DB_LSN *, DBT *, u_int32_t)); -static int __log_c_hdrchk __P((DB_LOGC *, DB_LSN *, HDR *, int *)); -static int __log_c_incursor __P((DB_LOGC *, DB_LSN *, HDR *, u_int8_t **)); -static int __log_c_inregion __P((DB_LOGC *, - DB_LSN *, RLOCK *, DB_LSN *, HDR *, u_int8_t **, int *)); -static int __log_c_io __P((DB_LOGC *, - u_int32_t, u_int32_t, void *, size_t *, int *)); -static int __log_c_ondisk __P((DB_LOGC *, - DB_LSN *, DB_LSN *, u_int32_t, HDR *, u_int8_t **, int *)); -static int __log_c_set_maxrec __P((DB_LOGC *, char *)); -static int __log_c_shortread __P((DB_LOGC *, DB_LSN *, int)); - -/* - * __log_cursor_pp -- - * DB_ENV->log_cursor - * - * PUBLIC: int __log_cursor_pp __P((DB_ENV *, DB_LOGC **, u_int32_t)); - */ -int -__log_cursor_pp(dbenv, logcp, flags) - DB_ENV *dbenv; - DB_LOGC **logcp; - u_int32_t flags; -{ - DB_THREAD_INFO *ip; - int ret; - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, - dbenv->lg_handle, "DB_ENV->log_cursor", DB_INIT_LOG); - - /* Validate arguments. */ - if ((ret = __db_fchk(dbenv, "DB_ENV->log_cursor", flags, 0)) != 0) - return (ret); - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, (__log_cursor(dbenv, logcp)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __log_cursor -- - * Create a log cursor. - * - * PUBLIC: int __log_cursor __P((DB_ENV *, DB_LOGC **)); - */ -int -__log_cursor(dbenv, logcp) - DB_ENV *dbenv; - DB_LOGC **logcp; -{ - DB_LOGC *logc; - int ret; - - *logcp = NULL; - - /* Allocate memory for the cursor. */ - if ((ret = __os_calloc(dbenv, 1, sizeof(DB_LOGC), &logc)) != 0) - return (ret); - - logc->bp_size = DB_LOGC_BUF_SIZE; - /* - * Set this to something positive. - */ - logc->bp_maxrec = MEGABYTE; - if ((ret = __os_malloc(dbenv, logc->bp_size, &logc->bp)) != 0) { - __os_free(dbenv, logc); - return (ret); - } - - logc->dbenv = dbenv; - logc->close = __log_c_close_pp; - logc->get = __log_c_get_pp; - - *logcp = logc; - return (0); -} - -/* - * __log_c_close_pp -- - * DB_LOGC->close pre/post processing. - */ -static int -__log_c_close_pp(logc, flags) - DB_LOGC *logc; - u_int32_t flags; -{ - DB_THREAD_INFO *ip; - DB_ENV *dbenv; - int ret; - - dbenv = logc->dbenv; - - PANIC_CHECK(dbenv); - if ((ret = __db_fchk(dbenv, "DB_LOGC->close", flags, 0)) != 0) - return (ret); - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, (__log_c_close(logc)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __log_c_close -- - * DB_LOGC->close. - * - * PUBLIC: int __log_c_close __P((DB_LOGC *)); - */ -int -__log_c_close(logc) - DB_LOGC *logc; -{ - DB_ENV *dbenv; - - dbenv = logc->dbenv; - - if (logc->c_fhp != NULL) { - (void)__os_closehandle(dbenv, logc->c_fhp); - logc->c_fhp = NULL; - } - - if (logc->c_dbt.data != NULL) - __os_free(dbenv, logc->c_dbt.data); - - __os_free(dbenv, logc->bp); - __os_free(dbenv, logc); - - return (0); -} - -/* - * __log_c_get_pp -- - * DB_LOGC->get pre/post processing. - */ -static int -__log_c_get_pp(logc, alsn, dbt, flags) - DB_LOGC *logc; - DB_LSN *alsn; - DBT *dbt; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int ret; - - dbenv = logc->dbenv; - - PANIC_CHECK(dbenv); - - /* Validate arguments. */ - switch (flags) { - case DB_CURRENT: - case DB_FIRST: - case DB_LAST: - case DB_NEXT: - case DB_PREV: - break; - case DB_SET: - if (IS_ZERO_LSN(*alsn)) { - __db_err(dbenv, "DB_LOGC->get: invalid LSN: %lu/%lu", - (u_long)alsn->file, (u_long)alsn->offset); - return (EINVAL); - } - break; - default: - return (__db_ferr(dbenv, "DB_LOGC->get", 1)); - } - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, (__log_c_get(logc, alsn, dbt, flags)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __log_c_get -- - * DB_LOGC->get. - * - * PUBLIC: int __log_c_get __P((DB_LOGC *, DB_LSN *, DBT *, u_int32_t)); - */ -int -__log_c_get(logc, alsn, dbt, flags) - DB_LOGC *logc; - DB_LSN *alsn; - DBT *dbt; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_LSN saved_lsn; - int ret; - - dbenv = logc->dbenv; - - /* - * On error, we take care not to overwrite the caller's LSN. This - * is because callers looking for the end of the log loop using the - * DB_NEXT flag, and expect to take the last successful lsn out of - * the passed-in structure after DB_LOGC->get fails with DB_NOTFOUND. - * - * !!! - * This line is often flagged an uninitialized memory read during a - * Purify or similar tool run, as the application didn't initialize - * *alsn. If the application isn't setting the DB_SET flag, there is - * no reason it should have initialized *alsn, but we can't know that - * and we want to make sure we never overwrite whatever the application - * put in there. - */ - saved_lsn = *alsn; - - /* - * If we get one of the log's header records as a result of doing a - * DB_FIRST, DB_NEXT, DB_LAST or DB_PREV, repeat the operation, log - * file header records aren't useful to applications. - */ - if ((ret = __log_c_get_int(logc, alsn, dbt, flags)) != 0) { - *alsn = saved_lsn; - return (ret); - } - if (alsn->offset == 0 && (flags == DB_FIRST || - flags == DB_NEXT || flags == DB_LAST || flags == DB_PREV)) { - switch (flags) { - case DB_FIRST: - flags = DB_NEXT; - break; - case DB_LAST: - flags = DB_PREV; - break; - case DB_NEXT: - case DB_PREV: - default: - break; - } - if (F_ISSET(dbt, DB_DBT_MALLOC)) { - __os_free(dbenv, dbt->data); - dbt->data = NULL; - } - if ((ret = __log_c_get_int(logc, alsn, dbt, flags)) != 0) { - *alsn = saved_lsn; - return (ret); - } - } - - return (0); -} - -/* - * __log_c_get_int -- - * Get a log record; internal version. - */ -static int -__log_c_get_int(logc, alsn, dbt, flags) - DB_LOGC *logc; - DB_LSN *alsn; - DBT *dbt; - u_int32_t flags; -{ - DB_CIPHER *db_cipher; - DB_ENV *dbenv; - DB_LOG *dblp; - DB_LSN last_lsn, nlsn; - HDR hdr; - LOG *lp; - RLOCK rlock; - logfile_validity status; - u_int32_t cnt; - u_int8_t *rp; - int eof, is_hmac, need_cksum, ret; - - dbenv = logc->dbenv; - db_cipher = dbenv->crypto_handle; - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - is_hmac = 0; - - /* - * We don't acquire the log region lock until we need it, and we - * release it as soon as we're done. - */ - rlock = F_ISSET(logc, DB_LOG_LOCKED) ? L_ALREADY : L_NONE; - - nlsn = logc->c_lsn; - switch (flags) { - case DB_NEXT: /* Next log record. */ - if (!IS_ZERO_LSN(nlsn)) { - /* Increment the cursor by the cursor record size. */ - nlsn.offset += logc->c_len; - break; - } - flags = DB_FIRST; - /* FALLTHROUGH */ - case DB_FIRST: /* First log record. */ - /* Find the first log file. */ - if ((ret = __log_find(dblp, 1, &cnt, &status)) != 0) - goto err; - - /* - * DB_LV_INCOMPLETE: - * Theoretically, the log file we want could be created - * but not yet written, the "first" log record must be - * in the log buffer. - * DB_LV_NORMAL: - * DB_LV_OLD_READABLE: - * We found a log file we can read. - * DB_LV_NONEXISTENT: - * No log files exist, the "first" log record must be in - * the log buffer. - * DB_LV_OLD_UNREADABLE: - * No readable log files exist, we're at the cross-over - * point between two versions. The "first" log record - * must be in the log buffer. - */ - switch (status) { - case DB_LV_INCOMPLETE: - DB_ASSERT(lp->lsn.file == cnt); - /* FALLTHROUGH */ - case DB_LV_NORMAL: - case DB_LV_OLD_READABLE: - nlsn.file = cnt; - break; - case DB_LV_NONEXISTENT: - nlsn.file = 1; - DB_ASSERT(lp->lsn.file == nlsn.file); - break; - case DB_LV_OLD_UNREADABLE: - nlsn.file = cnt + 1; - DB_ASSERT(lp->lsn.file == nlsn.file); - break; - } - nlsn.offset = 0; - break; - case DB_CURRENT: /* Current log record. */ - break; - case DB_PREV: /* Previous log record. */ - if (!IS_ZERO_LSN(nlsn)) { - /* If at start-of-file, move to the previous file. */ - if (nlsn.offset == 0) { - if (nlsn.file == 1) { - ret = DB_NOTFOUND; - goto err; - } - if ((!lp->db_log_inmemory && - (__log_valid(dblp, nlsn.file - 1, 0, NULL, - 0, &status) != 0 || - (status != DB_LV_NORMAL && - status != DB_LV_OLD_READABLE)))) { - ret = DB_NOTFOUND; - goto err; - } - - --nlsn.file; - } - nlsn.offset = logc->c_prev; - break; - } - /* FALLTHROUGH */ - case DB_LAST: /* Last log record. */ - if (rlock == L_NONE) { - rlock = L_ACQUIRED; - LOG_SYSTEM_LOCK(dbenv); - } - nlsn.file = lp->lsn.file; - nlsn.offset = lp->lsn.offset - lp->len; - break; - case DB_SET: /* Set log record. */ - nlsn = *alsn; - break; - default: - DB_ASSERT(0); - ret = EINVAL; - goto err; - } - - if (0) { /* Move to the next file. */ -next_file: ++nlsn.file; - nlsn.offset = 0; - } - - /* - * The above switch statement should have set nlsn to the lsn of - * the requested record. - */ - - if (CRYPTO_ON(dbenv)) { - hdr.size = HDR_CRYPTO_SZ; - is_hmac = 1; - } else { - hdr.size = HDR_NORMAL_SZ; - is_hmac = 0; - } - - /* - * Check to see if the record is in the cursor's buffer -- if so, - * we'll need to checksum it. - */ - if ((ret = __log_c_incursor(logc, &nlsn, &hdr, &rp)) != 0) - goto err; - if (rp != NULL) - goto cksum; - - /* - * Look to see if we're moving backward in the log with the last record - * coming from the disk -- it means the record can't be in the region's - * buffer. Else, check the region's buffer. - * - * If the record isn't in the region's buffer, then either logs are - * in-memory, and we're done, or we're going to have to read the - * record from disk. We want to make a point of not reading past the - * end of the logical log (after recovery, there may be data after the - * end of the logical log, not to mention the log file may have been - * pre-allocated). So, zero out last_lsn, and initialize it inside - * __log_c_inregion -- if it's still zero when we check it in - * __log_c_ondisk, that's OK, it just means the logical end of the log - * isn't an issue for this request. - */ - ZERO_LSN(last_lsn); - if (!F_ISSET(logc, DB_LOG_DISK) || - log_compare(&nlsn, &logc->c_lsn) > 0) { - F_CLR(logc, DB_LOG_DISK); - - if ((ret = __log_c_inregion(logc, - &nlsn, &rlock, &last_lsn, &hdr, &rp, &need_cksum)) != 0) - goto err; - if (rp != NULL) { - /* - * If we read the entire record from the in-memory log - * buffer, we don't need to checksum it, nor do we need - * to worry about vtruncate issues. - */ - if (need_cksum) - goto cksum; - goto from_memory; - } - if (lp->db_log_inmemory) - goto nohdr; - } - - /* - * We have to read from an on-disk file to retrieve the record. - * If we ever can't retrieve the record at offset 0, we're done, - * return EOF/DB_NOTFOUND. - * - * Discard the region lock if we're still holding it, the on-disk - * reading routines don't need it. - */ - if (rlock == L_ACQUIRED) { - rlock = L_NONE; - LOG_SYSTEM_UNLOCK(dbenv); - } - if ((ret = __log_c_ondisk( - logc, &nlsn, &last_lsn, flags, &hdr, &rp, &eof)) != 0) - goto err; - if (eof) { - /* - * Only DB_NEXT automatically moves to the next file, and - * it only happens once. - */ - if (flags != DB_NEXT || nlsn.offset == 0) - return (DB_NOTFOUND); - goto next_file; - } - F_SET(logc, DB_LOG_DISK); - -cksum: /* - * Discard the region lock if we're still holding it. (The path to - * get here is we acquired the region lock because of the caller's - * flag argument, but we found the record in the in-memory or cursor - * buffers. Improbable, but it's easy to avoid.) - */ - if (rlock == L_ACQUIRED) { - rlock = L_NONE; - LOG_SYSTEM_UNLOCK(dbenv); - } - - /* - * Checksum: there are two types of errors -- a configuration error - * or a checksum mismatch. The former is always bad. The latter is - * OK if we're searching for the end of the log, and very, very bad - * if we're reading random log records. - */ - if ((ret = __db_check_chksum(dbenv, db_cipher, - hdr.chksum, rp + hdr.size, hdr.len - hdr.size, is_hmac)) != 0) { - if (F_ISSET(logc, DB_LOG_SILENT_ERR)) { - if (ret == 0 || ret == -1) - ret = EIO; - } else if (ret == -1) { - __db_err(dbenv, - "DB_LOGC->get: log record LSN %lu/%lu: checksum mismatch", - (u_long)nlsn.file, (u_long)nlsn.offset); - __db_err(dbenv, - "DB_LOGC->get: catastrophic recovery may be required"); - ret = __db_panic(dbenv, DB_RUNRECOVERY); - } - goto err; - } - - /* - * If we got a 0-length record, that means we're in the midst of - * some bytes that got 0'd as the result of a vtruncate. We're - * going to have to retry. - */ - if (hdr.len == 0) { -nohdr: switch (flags) { - case DB_FIRST: - case DB_NEXT: - /* Zero'd records always indicate the end of a file. */ - goto next_file; - case DB_LAST: - case DB_PREV: - /* - * We should never get here. If we recover a log - * file with 0's at the end, we'll treat the 0'd - * headers as the end of log and ignore them. If - * we're reading backwards from another file, then - * the first record in that new file should have its - * prev field set correctly. - */ - __db_err(dbenv, - "Encountered zero length records while traversing backwards"); - DB_ASSERT(0); - ret = __db_panic(dbenv, DB_RUNRECOVERY); - goto err; - case DB_SET: - default: - /* Return the 0-length record. */ - break; - } - } - -from_memory: - /* - * Discard the region lock if we're still holding it. (The path to - * get here is we acquired the region lock because of the caller's - * flag argument, but we found the record in the in-memory or cursor - * buffers. Improbable, but it's easy to avoid.) - */ - if (rlock == L_ACQUIRED) { - rlock = L_NONE; - LOG_SYSTEM_UNLOCK(dbenv); - } - - /* Copy the record into the user's DBT. */ - if ((ret = __db_retcopy(dbenv, dbt, rp + hdr.size, - (u_int32_t)(hdr.len - hdr.size), - &logc->c_dbt.data, &logc->c_dbt.ulen)) != 0) - goto err; - - if (CRYPTO_ON(dbenv)) { - if ((ret = db_cipher->decrypt(dbenv, db_cipher->data, - hdr.iv, dbt->data, hdr.len - hdr.size)) != 0) { - ret = EAGAIN; - goto err; - } - /* - * Return the original log record size to the user, - * even though we've allocated more than that, possibly. - * The log record is decrypted in the user dbt, not in - * the buffer, so we must do this here after decryption, - * not adjust the len passed to the __db_retcopy call. - */ - dbt->size = hdr.orig_size; - } - - /* Update the cursor and the returned LSN. */ - *alsn = nlsn; - logc->c_lsn = nlsn; - logc->c_len = hdr.len; - logc->c_prev = hdr.prev; - -err: if (rlock == L_ACQUIRED) - LOG_SYSTEM_UNLOCK(dbenv); - - return (ret); -} - -/* - * __log_c_incursor -- - * Check to see if the requested record is in the cursor's buffer. - */ -static int -__log_c_incursor(logc, lsn, hdr, pp) - DB_LOGC *logc; - DB_LSN *lsn; - HDR *hdr; - u_int8_t **pp; -{ - u_int8_t *p; - int eof; - - *pp = NULL; - - /* - * Test to see if the requested LSN could be part of the cursor's - * buffer. - * - * The record must be part of the same file as the cursor's buffer. - * The record must start at a byte offset equal to or greater than - * the cursor buffer. - * The record must not start at a byte offset after the cursor - * buffer's end. - */ - if (logc->bp_lsn.file != lsn->file) - return (0); - if (logc->bp_lsn.offset > lsn->offset) - return (0); - if (logc->bp_lsn.offset + logc->bp_rlen <= lsn->offset + hdr->size) - return (0); - - /* - * Read the record's header and check if the record is entirely held - * in the buffer. If the record is not entirely held, get it again. - * (The only advantage in having part of the record locally is that - * we might avoid a system call because we already have the HDR in - * memory.) - * - * If the header check fails for any reason, it must be because the - * LSN is bogus. Fail hard. - */ - p = logc->bp + (lsn->offset - logc->bp_lsn.offset); - memcpy(hdr, p, hdr->size); - if (__log_c_hdrchk(logc, lsn, hdr, &eof)) - return (DB_NOTFOUND); - if (eof || logc->bp_lsn.offset + logc->bp_rlen < lsn->offset + hdr->len) - return (0); - - *pp = p; /* Success. */ - - return (0); -} - -/* - * __log_c_inregion -- - * Check to see if the requested record is in the region's buffer. - */ -static int -__log_c_inregion(logc, lsn, rlockp, last_lsn, hdr, pp, need_cksump) - DB_LOGC *logc; - DB_LSN *lsn, *last_lsn; - RLOCK *rlockp; - HDR *hdr; - u_int8_t **pp; - int *need_cksump; -{ - DB_ENV *dbenv; - DB_LOG *dblp; - LOG *lp; - size_t b_region, len, nr; - u_int32_t b_disk; - int eof, ret; - u_int8_t *p; - - dbenv = logc->dbenv; - dblp = dbenv->lg_handle; - lp = ((DB_LOG *)logc->dbenv->lg_handle)->reginfo.primary; - - ret = 0; - b_region = 0; - *pp = NULL; - *need_cksump = 0; - - /* If we haven't yet acquired the log region lock, do so. */ - if (*rlockp == L_NONE) { - *rlockp = L_ACQUIRED; - LOG_SYSTEM_LOCK(dbenv); - } - - /* - * The routines to read from disk must avoid reading past the logical - * end of the log, so pass that information back to it. - * - * Since they're reading directly from the disk, they must also avoid - * reading past the offset we've written out. If the log was - * truncated, it's possible that there are zeroes or garbage on - * disk after this offset, and the logical end of the log can - * come later than this point if the log buffer isn't empty. - */ - *last_lsn = lp->lsn; - if (!lp->db_log_inmemory && last_lsn->offset > lp->w_off) - last_lsn->offset = lp->w_off; - - /* - * Test to see if the requested LSN could be part of the region's - * buffer. - * - * During recovery, we read the log files getting the information to - * initialize the region. In that case, the region's lsn field will - * not yet have been filled in, use only the disk. - * - * The record must not start at a byte offset after the region buffer's - * end, since that means the request is for a record after the end of - * the log. Do this test even if the region's buffer is empty -- after - * recovery, the log files may continue past the declared end-of-log, - * and the disk reading routine will incorrectly attempt to read the - * remainder of the log. - * - * Otherwise, test to see if the region's buffer actually has what we - * want: - * - * The buffer must have some useful content. - * The record must be in the same file as the region's buffer and must - * start at a byte offset equal to or greater than the region's buffer. - */ - if (IS_ZERO_LSN(lp->lsn)) - return (0); - if (log_compare(lsn, &lp->lsn) >= 0) - return (DB_NOTFOUND); - else if (lp->db_log_inmemory) { - if ((ret = __log_inmem_lsnoff(dblp, lsn, &b_region)) != 0) - return (ret); - } else if (lp->b_off == 0 || log_compare(lsn, &lp->f_lsn) < 0) - return (0); - - /* - * The current contents of the cursor's buffer will be useless for a - * future call, we're about to overwrite it -- trash it rather than - * try and make it look correct. - */ - logc->bp_rlen = 0; - - /* - * If the requested LSN is greater than the region buffer's first - * byte, we know the entire record is in the buffer on a good LSN. - * - * If we're given a bad LSN, the "entire" record might not be in - * our buffer in order to fail at the chksum. __log_c_hdrchk made - * sure our dest buffer fits, via bp_maxrec, but we also need to - * make sure we don't run off the end of this buffer, the src. - * - * There is one case where the header check can fail: on a scan through - * in-memory logs, when we reach the end of a file we can read an empty - * header. In that case, it's safe to return zero, here: it will be - * caught in our caller. Otherwise, the LSN is bogus. Fail hard. - */ - if (lp->db_log_inmemory || log_compare(lsn, &lp->f_lsn) > 0) { - if (!lp->db_log_inmemory) - b_region = lsn->offset - lp->w_off; - __log_inmem_copyout(dblp, b_region, hdr, hdr->size); - if (__log_c_hdrchk(logc, lsn, hdr, &eof) != 0) - return (DB_NOTFOUND); - if (eof) - return (0); - if (lp->db_log_inmemory) { - if (RINGBUF_LEN(lp, b_region, lp->b_off) < hdr->len) - return (DB_NOTFOUND); - } else if (lsn->offset + hdr->len > lp->w_off + lp->buffer_size) - return (DB_NOTFOUND); - if (logc->bp_size <= hdr->len) { - len = (size_t)DB_ALIGN((uintmax_t)hdr->len * 2, 128); - if ((ret = - __os_realloc(logc->dbenv, len, &logc->bp)) != 0) - return (ret); - logc->bp_size = (u_int32_t)len; - } - __log_inmem_copyout(dblp, b_region, logc->bp, hdr->len); - *pp = logc->bp; - return (0); - } - - DB_ASSERT(!lp->db_log_inmemory); - - /* - * There's a partial record, that is, the requested record starts - * in a log file and finishes in the region buffer. We have to - * find out how many bytes of the record are in the region buffer - * so we can copy them out into the cursor buffer. First, check - * to see if the requested record is the only record in the region - * buffer, in which case we should copy the entire region buffer. - * - * Else, walk back through the region's buffer to find the first LSN - * after the record that crosses the buffer boundary -- we can detect - * that LSN, because its "prev" field will reference the record we - * want. The bytes we need to copy from the region buffer are the - * bytes up to the record we find. The bytes we'll need to allocate - * to hold the log record are the bytes between the two offsets. - */ - b_disk = lp->w_off - lsn->offset; - if (lp->b_off <= lp->len) - b_region = (u_int32_t)lp->b_off; - else - for (p = dblp->bufp + (lp->b_off - lp->len);;) { - memcpy(hdr, p, hdr->size); - if (hdr->prev == lsn->offset) { - b_region = (u_int32_t)(p - dblp->bufp); - break; - } - p = dblp->bufp + (hdr->prev - lp->w_off); - } - - /* - * If we don't have enough room for the record, we have to allocate - * space. We have to do it while holding the region lock, which is - * truly annoying, but there's no way around it. This call is why - * we allocate cursor buffer space when allocating the cursor instead - * of waiting. - */ - if (logc->bp_size <= b_region + b_disk) { - len = (size_t)DB_ALIGN((uintmax_t)(b_region + b_disk) * 2, 128); - if ((ret = __os_realloc(logc->dbenv, len, &logc->bp)) != 0) - return (ret); - logc->bp_size = (u_int32_t)len; - } - - /* Copy the region's bytes to the end of the cursor's buffer. */ - p = (logc->bp + logc->bp_size) - b_region; - memcpy(p, dblp->bufp, b_region); - - /* Release the region lock. */ - if (*rlockp == L_ACQUIRED) { - *rlockp = L_NONE; - LOG_SYSTEM_UNLOCK(dbenv); - } - - /* - * Read the rest of the information from disk. Neither short reads - * or EOF are acceptable, the bytes we want had better be there. - */ - if (b_disk != 0) { - p -= b_disk; - nr = b_disk; - if ((ret = __log_c_io( - logc, lsn->file, lsn->offset, p, &nr, NULL)) != 0) - return (ret); - if (nr < b_disk) - return (__log_c_shortread(logc, lsn, 0)); - - /* We read bytes from the disk, we'll need to checksum them. */ - *need_cksump = 1; - } - - /* Copy the header information into the caller's structure. */ - memcpy(hdr, p, hdr->size); - - *pp = p; - return (0); -} - -/* - * __log_c_ondisk -- - * Read a record off disk. - */ -static int -__log_c_ondisk(logc, lsn, last_lsn, flags, hdr, pp, eofp) - DB_LOGC *logc; - DB_LSN *lsn, *last_lsn; - u_int32_t flags; - int *eofp; - HDR *hdr; - u_int8_t **pp; -{ - DB_ENV *dbenv; - size_t len, nr; - u_int32_t offset; - int ret; - - dbenv = logc->dbenv; - *eofp = 0; - - nr = hdr->size; - if ((ret = - __log_c_io(logc, lsn->file, lsn->offset, hdr, &nr, eofp)) != 0) - return (ret); - if (*eofp) - return (0); - - /* - * If the read was successful, but we can't read a full header, assume - * we've hit EOF. We can't check that the header has been partially - * zeroed out, but it's unlikely that this is caused by a write failure - * since the header is written as a single write call and it's less - * than sector. - */ - if (nr < hdr->size) { - *eofp = 1; - return (0); - } - - /* Check the HDR. */ - if ((ret = __log_c_hdrchk(logc, lsn, hdr, eofp)) != 0) - return (ret); - if (*eofp) - return (0); - - /* - * Regardless of how we return, the previous contents of the cursor's - * buffer are useless -- trash it. - */ - logc->bp_rlen = 0; - - /* - * Otherwise, we now (finally!) know how big the record is. (Maybe - * we should have just stuck the length of the record into the LSN!?) - * Make sure we have enough space. - */ - if (logc->bp_size <= hdr->len) { - len = (size_t)DB_ALIGN((uintmax_t)hdr->len * 2, 128); - if ((ret = __os_realloc(dbenv, len, &logc->bp)) != 0) - return (ret); - logc->bp_size = (u_int32_t)len; - } - - /* - * If we're moving forward in the log file, read this record in at the - * beginning of the buffer. Otherwise, read this record in at the end - * of the buffer, making sure we don't try and read before the start - * of the file. (We prefer positioning at the end because transaction - * aborts use DB_SET to move backward through the log and we might get - * lucky.) - * - * Read a buffer's worth, without reading past the logical EOF. The - * last_lsn may be a zero LSN, but that's OK, the test works anyway. - */ - if (flags == DB_FIRST || flags == DB_NEXT) - offset = lsn->offset; - else if (lsn->offset + hdr->len < logc->bp_size) - offset = 0; - else - offset = (lsn->offset + hdr->len) - logc->bp_size; - - nr = logc->bp_size; - if (lsn->file == last_lsn->file && offset + nr >= last_lsn->offset) - nr = last_lsn->offset - offset; - - if ((ret = - __log_c_io(logc, lsn->file, offset, logc->bp, &nr, eofp)) != 0) - return (ret); - - /* - * We should have at least gotten the bytes up-to-and-including the - * record we're reading. - */ - if (nr < (lsn->offset + hdr->len) - offset) - return (__log_c_shortread(logc, lsn, 1)); - - /* - * Set up the return information. - * - * !!! - * No need to set the bp_lsn.file field, __log_c_io set it for us. - */ - logc->bp_rlen = (u_int32_t)nr; - logc->bp_lsn.offset = offset; - - *pp = logc->bp + (lsn->offset - offset); - - return (0); -} - -/* - * __log_c_hdrchk -- - * - * Check for corrupted HDRs before we use them to allocate memory or find - * records. - * - * If the log files were pre-allocated, a zero-filled HDR structure is the - * logical file end. However, we can see buffers filled with 0's during - * recovery, too (because multiple log buffers were written asynchronously, - * and one made it to disk before a different one that logically precedes - * it in the log file. - * - * Check for impossibly large records. The malloc should fail later, but we - * have customers that run mallocs that treat all allocation failures as fatal - * errors. - * - * Note that none of this is necessarily something awful happening. We let - * the application hand us any LSN they want, and it could be a pointer into - * the middle of a log record, there's no way to tell. - */ -static int -__log_c_hdrchk(logc, lsn, hdr, eofp) - DB_LOGC *logc; - DB_LSN *lsn; - HDR *hdr; - int *eofp; -{ - DB_ENV *dbenv; - int ret; - - dbenv = logc->dbenv; - - /* - * Check EOF before we do any other processing. - */ - if (eofp != NULL) { - if (hdr->prev == 0 && hdr->chksum[0] == 0 && hdr->len == 0) { - *eofp = 1; - return (0); - } - *eofp = 0; - } - - /* - * Sanity check the log record's size. - * We must check it after "virtual" EOF above. - */ - if (hdr->len <= hdr->size) - goto err; - - /* - * If the cursor's max-record value isn't yet set, it means we aren't - * reading these records from a log file and no check is necessary. - */ - if (logc->bp_maxrec != 0 && hdr->len > logc->bp_maxrec) { - /* - * If we fail the check, there's the pathological case that - * we're reading the last file, it's growing, and our initial - * check information was wrong. Get it again, to be sure. - */ - if ((ret = __log_c_set_maxrec(logc, NULL)) != 0) { - __db_err(dbenv, "DB_LOGC->get: %s", db_strerror(ret)); - return (ret); - } - if (logc->bp_maxrec != 0 && hdr->len > logc->bp_maxrec) - goto err; - } - return (0); - -err: if (!F_ISSET(logc, DB_LOG_SILENT_ERR)) - __db_err(dbenv, - "DB_LOGC->get: LSN %lu/%lu: invalid log record header", - (u_long)lsn->file, (u_long)lsn->offset); - return (EIO); -} - -/* - * __log_c_io -- - * Read records from a log file. - */ -static int -__log_c_io(logc, fnum, offset, p, nrp, eofp) - DB_LOGC *logc; - u_int32_t fnum, offset; - void *p; - size_t *nrp; - int *eofp; -{ - DB_ENV *dbenv; - DB_LOG *dblp; - LOG *lp; - int ret; - char *np; - - dbenv = logc->dbenv; - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - - /* - * If we've switched files, discard the current file handle and acquire - * a new one. - */ - if (logc->c_fhp != NULL && logc->bp_lsn.file != fnum) { - ret = __os_closehandle(dbenv, logc->c_fhp); - logc->c_fhp = NULL; - logc->bp_lsn.file = 0; - - if (ret != 0) - return (ret); - } - if (logc->c_fhp == NULL) { - if ((ret = __log_name(dblp, fnum, - &np, &logc->c_fhp, DB_OSO_RDONLY | DB_OSO_SEQ)) != 0) { - /* - * If we're allowed to return EOF, assume that's the - * problem, set the EOF status flag and return 0. - */ - if (eofp != NULL) { - *eofp = 1; - ret = 0; - } else if (!F_ISSET(logc, DB_LOG_SILENT_ERR)) - __db_err(dbenv, "DB_LOGC->get: %s: %s", - np, db_strerror(ret)); - __os_free(dbenv, np); - return (ret); - } - - if ((ret = __log_c_set_maxrec(logc, np)) != 0) { - __db_err(dbenv, - "DB_LOGC->get: %s: %s", np, db_strerror(ret)); - __os_free(dbenv, np); - return (ret); - } - __os_free(dbenv, np); - - logc->bp_lsn.file = fnum; - } - - /* Seek to the record's offset. */ - if ((ret = __os_seek(dbenv, - logc->c_fhp, 0, 0, offset, 0, DB_OS_SEEK_SET)) != 0) { - if (!F_ISSET(logc, DB_LOG_SILENT_ERR)) - __db_err(dbenv, - "DB_LOGC->get: LSN: %lu/%lu: seek: %s", - (u_long)fnum, (u_long)offset, db_strerror(ret)); - return (ret); - } - - /* Read the data. */ - ++lp->stat.st_rcount; - if ((ret = __os_read(dbenv, logc->c_fhp, p, *nrp, nrp)) != 0) { - if (!F_ISSET(logc, DB_LOG_SILENT_ERR)) - __db_err(dbenv, - "DB_LOGC->get: LSN: %lu/%lu: read: %s", - (u_long)fnum, (u_long)offset, db_strerror(ret)); - return (ret); - } - - return (0); -} - -/* - * __log_c_shortread -- - * Read was short -- return a consistent error message and error. - */ -static int -__log_c_shortread(logc, lsn, check_silent) - DB_LOGC *logc; - DB_LSN *lsn; - int check_silent; -{ - if (!check_silent || !F_ISSET(logc, DB_LOG_SILENT_ERR)) - __db_err(logc->dbenv, "DB_LOGC->get: LSN: %lu/%lu: short read", - (u_long)lsn->file, (u_long)lsn->offset); - return (EIO); -} - -/* - * __log_c_set_maxrec -- - * Bound the maximum log record size in a log file. - */ -static int -__log_c_set_maxrec(logc, np) - DB_LOGC *logc; - char *np; -{ - DB_ENV *dbenv; - DB_LOG *dblp; - LOG *lp; - u_int32_t mbytes, bytes; - int ret; - - dbenv = logc->dbenv; - dblp = dbenv->lg_handle; - - /* - * We don't want to try and allocate huge chunks of memory because - * applications with error-checking malloc's often consider that a - * hard failure. If we're about to look at a corrupted record with - * a bizarre size, we need to know before trying to allocate space - * to hold it. We could read the persistent data at the beginning - * of the file but that's hard -- we may have to decrypt it, checksum - * it and so on. Stat the file instead. - */ - if (logc->c_fhp != NULL) { - if ((ret = __os_ioinfo(dbenv, np, logc->c_fhp, - &mbytes, &bytes, NULL)) != 0) - return (ret); - if (logc->bp_maxrec < (mbytes * MEGABYTE + bytes)) - logc->bp_maxrec = mbytes * MEGABYTE + bytes; - } - - /* - * If reading from the log file currently being written, we could get - * an incorrect size, that is, if the cursor was opened on the file - * when it had only a few hundred bytes, and then the cursor used to - * move forward in the file, after more log records were written, the - * original stat value would be wrong. Use the maximum of the current - * log file size and the size of the buffer -- that should represent - * the max of any log record currently in the file. - * - * The log buffer size is set when the environment is opened and never - * changed, we don't need a lock on it. - */ - lp = dblp->reginfo.primary; - if (logc->bp_maxrec < lp->buffer_size) - logc->bp_maxrec = lp->buffer_size; - - return (0); -} - -#ifdef HAVE_REPLICATION -/* - * __log_rep_split -- - * - Split a log buffer into individual records. - * - * This is used by a replication client to process a bulk log message from the - * master and convert it into individual __rep_apply requests. - * - * PUBLIC: int __log_rep_split __P((DB_ENV *, REP_CONTROL *, DBT *, DB_LSN *)); - */ -int -__log_rep_split(dbenv, rp, rec, ret_lsnp) - DB_ENV *dbenv; - REP_CONTROL *rp; - DBT *rec; - DB_LSN *ret_lsnp; -{ - DB_LSN save_lsn, tmp_lsn; - DB_REP *db_rep; - DBT logrec; - REP *rep; - REP_CONTROL tmprp; - u_int32_t len; - int is_dup, is_perm, ret, save_ret; - u_int8_t *p, *ep; -#ifdef DIAGNOSTIC - DB_MSGBUF mb; -#endif - - memset(&logrec, 0, sizeof(logrec)); - memset(&save_lsn, 0, sizeof(save_lsn)); - memset(&tmp_lsn, 0, sizeof(tmp_lsn)); - /* - * We're going to be modifying the rp LSN contents so make - * our own private copy to play with. - */ - memcpy(&tmprp, rp, sizeof(tmprp)); - /* - * We send the bulk buffer on a PERM record, so often we will have - * DB_LOG_PERM set. However, we only want to mark the last LSN - * we have as a PERM record. So clear it here, and when we're on - * the last record below, set it. - */ - is_perm = F_ISSET(rp, DB_LOG_PERM); - F_CLR(&tmprp, DB_LOG_PERM); - ret = save_ret = 0; - db_rep = dbenv->rep_handle; - rep = db_rep->region; - for (ep = (u_int8_t *)rec->data + rec->size, p = (u_int8_t *)rec->data; - p < ep; ) { - /* - * First thing in the buffer is the length. Then the LSN - * of this record, then the record itself. - */ - /* - * XXX - * If/when we add architecture neutral log files we may want - * to send/receive these lengths in network byte order. - */ - memcpy(&len, p, sizeof(len)); - p += sizeof(len); - memcpy(&tmprp.lsn, p, sizeof(DB_LSN)); - p += sizeof(DB_LSN); - logrec.data = p; - logrec.size = len; - RPRINT(dbenv, rep, (dbenv, &mb, - "log_rep_split: Processing LSN [%lu][%lu]", - (u_long)tmprp.lsn.file, (u_long)tmprp.lsn.offset)); - RPRINT(dbenv, rep, (dbenv, &mb, - "log_rep_split: p %#lx ep %#lx logrec data %#lx, size %lu (%#lx)", - P_TO_ULONG(p), P_TO_ULONG(ep), P_TO_ULONG(logrec.data), - (u_long)logrec.size, (u_long)logrec.size)); - is_dup = 0; - p += len; - if (p >= ep && is_perm) - F_SET(&tmprp, DB_LOG_PERM); - ret = __rep_apply(dbenv, &tmprp, &logrec, &tmp_lsn, &is_dup); - RPRINT(dbenv, rep, (dbenv, &mb, - "log_split: rep_apply ret %d, tmp_lsn [%lu][%lu]", - ret, (u_long)tmp_lsn.file, (u_long)tmp_lsn.offset)); -#if 0 - /* - * This buffer may be old and we've already gotten these - * records. Short-circuit processing this buffer. - */ - if (is_dup) - goto out; -#endif - switch (ret) { - /* - * If we received the pieces we need for running recovery, - * short-circuit because recovery will truncate the log to - * the LSN we want anyway. - */ - case DB_REP_LOGREADY: - goto out; - /* - * If we just handled a special record, retain that information. - */ - case DB_REP_ISPERM: - case DB_REP_NOTPERM: - case DB_REP_STARTUPDONE: - save_ret = ret; - save_lsn = tmp_lsn; - ret = 0; - break; - /* - * Normal processing, do nothing, just continue. - */ - case 0: - break; - /* - * If we get an error, then stop immediately. - */ - default: - goto out; - } - } -out: - /* - * If we finish processing successfully, set our return values - * based on what we saw. - */ - if (ret == 0) { - ret = save_ret; - *ret_lsnp = save_lsn; - } - return (ret); -} -#endif diff --git a/storage/bdb/log/log_method.c b/storage/bdb/log/log_method.c deleted file mode 100644 index bc37722655d..00000000000 --- a/storage/bdb/log/log_method.c +++ /dev/null @@ -1,354 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: log_method.c,v 12.4 2005/07/21 18:21:25 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stdlib.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/log.h" - -/* - * __log_dbenv_create -- - * Log specific initialization of the DB_ENV structure. - * - * PUBLIC: void __log_dbenv_create __P((DB_ENV *)); - */ -void -__log_dbenv_create(dbenv) - DB_ENV *dbenv; -{ - /* - * !!! - * Our caller has not yet had the opportunity to reset the panic - * state or turn off mutex locking, and so we can neither check - * the panic state or acquire a mutex in the DB_ENV create path. - */ - dbenv->lg_bsize = 0; - dbenv->lg_regionmax = LG_BASE_REGION_SIZE; -} - -/* - * PUBLIC: int __log_get_lg_bsize __P((DB_ENV *, u_int32_t *)); - */ -int -__log_get_lg_bsize(dbenv, lg_bsizep) - DB_ENV *dbenv; - u_int32_t *lg_bsizep; -{ - ENV_NOT_CONFIGURED(dbenv, - dbenv->lg_handle, "DB_ENV->get_lg_bsize", DB_INIT_LOG); - - if (LOGGING_ON(dbenv)) { - /* Cannot be set after open, no lock required to read. */ - *lg_bsizep = ((LOG *) - ((DB_LOG *)dbenv->lg_handle)->reginfo.primary)->buffer_size; - } else - *lg_bsizep = dbenv->lg_bsize; - return (0); -} - -/* - * __log_set_lg_bsize -- - * DB_ENV->set_lg_bsize. - * - * PUBLIC: int __log_set_lg_bsize __P((DB_ENV *, u_int32_t)); - */ -int -__log_set_lg_bsize(dbenv, lg_bsize) - DB_ENV *dbenv; - u_int32_t lg_bsize; -{ - ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_lg_bsize"); - - dbenv->lg_bsize = lg_bsize; - return (0); -} - -/* - * PUBLIC: int __log_get_lg_filemode __P((DB_ENV *, int *)); - */ -int -__log_get_lg_filemode(dbenv, lg_modep) - DB_ENV *dbenv; - int *lg_modep; -{ - DB_LOG *dblp; - - ENV_NOT_CONFIGURED(dbenv, - dbenv->lg_handle, "DB_ENV->get_lg_filemode", DB_INIT_LOG); - - if (LOGGING_ON(dbenv)) { - dblp = dbenv->lg_handle; - LOG_SYSTEM_LOCK(dbenv); - *lg_modep = ((LOG *)dblp->reginfo.primary)->filemode; - LOG_SYSTEM_UNLOCK(dbenv); - } else - *lg_modep = dbenv->lg_filemode; - - return (0); -} - -/* - * __log_set_lg_filemode -- - * DB_ENV->set_lg_filemode. - * - * PUBLIC: int __log_set_lg_filemode __P((DB_ENV *, int)); - */ -int -__log_set_lg_filemode(dbenv, lg_mode) - DB_ENV *dbenv; - int lg_mode; -{ - DB_LOG *dblp; - LOG *lp; - - ENV_NOT_CONFIGURED(dbenv, - dbenv->lg_handle, "DB_ENV->set_lg_filemode", DB_INIT_LOG); - - if (LOGGING_ON(dbenv)) { - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - LOG_SYSTEM_LOCK(dbenv); - lp->filemode = lg_mode; - LOG_SYSTEM_UNLOCK(dbenv); - } else - dbenv->lg_filemode = lg_mode; - - return (0); -} - -/* - * PUBLIC: int __log_get_lg_max __P((DB_ENV *, u_int32_t *)); - */ -int -__log_get_lg_max(dbenv, lg_maxp) - DB_ENV *dbenv; - u_int32_t *lg_maxp; -{ - DB_LOG *dblp; - - ENV_NOT_CONFIGURED(dbenv, - dbenv->lg_handle, "DB_ENV->get_lg_max", DB_INIT_LOG); - - if (LOGGING_ON(dbenv)) { - dblp = dbenv->lg_handle; - LOG_SYSTEM_LOCK(dbenv); - *lg_maxp = ((LOG *)dblp->reginfo.primary)->log_nsize; - LOG_SYSTEM_UNLOCK(dbenv); - } else - *lg_maxp = dbenv->lg_size; - - return (0); -} - -/* - * __log_set_lg_max -- - * DB_ENV->set_lg_max. - * - * PUBLIC: int __log_set_lg_max __P((DB_ENV *, u_int32_t)); - */ -int -__log_set_lg_max(dbenv, lg_max) - DB_ENV *dbenv; - u_int32_t lg_max; -{ - DB_LOG *dblp; - LOG *lp; - int ret; - - ENV_NOT_CONFIGURED(dbenv, - dbenv->lg_handle, "DB_ENV->set_lg_max", DB_INIT_LOG); - - if (LOGGING_ON(dbenv)) { - if ((ret = __log_check_sizes(dbenv, lg_max, 0)) != 0) - return (ret); - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - LOG_SYSTEM_LOCK(dbenv); - lp->log_nsize = lg_max; - LOG_SYSTEM_UNLOCK(dbenv); - } else - dbenv->lg_size = lg_max; - - return (0); -} - -/* - * PUBLIC: int __log_get_lg_regionmax __P((DB_ENV *, u_int32_t *)); - */ -int -__log_get_lg_regionmax(dbenv, lg_regionmaxp) - DB_ENV *dbenv; - u_int32_t *lg_regionmaxp; -{ - ENV_NOT_CONFIGURED(dbenv, - dbenv->lg_handle, "DB_ENV->get_lg_regionmax", DB_INIT_LOG); - - if (LOGGING_ON(dbenv)) { - /* Cannot be set after open, no lock required to read. */ - *lg_regionmaxp = ((LOG *) - ((DB_LOG *)dbenv->lg_handle)->reginfo.primary)->regionmax; - } else - *lg_regionmaxp = dbenv->lg_regionmax; - return (0); -} - -/* - * __log_set_lg_regionmax -- - * DB_ENV->set_lg_regionmax. - * - * PUBLIC: int __log_set_lg_regionmax __P((DB_ENV *, u_int32_t)); - */ -int -__log_set_lg_regionmax(dbenv, lg_regionmax) - DB_ENV *dbenv; - u_int32_t lg_regionmax; -{ - ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_lg_regionmax"); - - /* Let's not be silly. */ - if (lg_regionmax != 0 && lg_regionmax < LG_BASE_REGION_SIZE) { - __db_err(dbenv, - "log file size must be >= %d", LG_BASE_REGION_SIZE); - return (EINVAL); - } - - dbenv->lg_regionmax = lg_regionmax; - return (0); -} - -/* - * PUBLIC: int __log_get_lg_dir __P((DB_ENV *, const char **)); - */ -int -__log_get_lg_dir(dbenv, dirp) - DB_ENV *dbenv; - const char **dirp; -{ - *dirp = dbenv->db_log_dir; - return (0); -} - -/* - * __log_set_lg_dir -- - * DB_ENV->set_lg_dir. - * - * PUBLIC: int __log_set_lg_dir __P((DB_ENV *, const char *)); - */ -int -__log_set_lg_dir(dbenv, dir) - DB_ENV *dbenv; - const char *dir; -{ - if (dbenv->db_log_dir != NULL) - __os_free(dbenv, dbenv->db_log_dir); - return (__os_strdup(dbenv, dir, &dbenv->db_log_dir)); -} - -/* - * __log_get_flags -- - * DB_ENV->get_flags. - * - * PUBLIC: void __log_get_flags __P((DB_ENV *, u_int32_t *)); - */ -void -__log_get_flags(dbenv, flagsp) - DB_ENV *dbenv; - u_int32_t *flagsp; -{ - DB_LOG *dblp; - LOG *lp; - u_int32_t flags; - - if ((dblp = dbenv->lg_handle) == NULL) - return; - - lp = dblp->reginfo.primary; - - flags = *flagsp; - if (lp->db_log_autoremove) - LF_SET(DB_LOG_AUTOREMOVE); - else - LF_CLR(DB_LOG_AUTOREMOVE); - if (lp->db_log_inmemory) - LF_SET(DB_LOG_INMEMORY); - else - LF_CLR(DB_LOG_INMEMORY); - *flagsp = flags; -} - -/* - * __log_set_flags -- - * DB_ENV->set_flags. - * - * PUBLIC: void __log_set_flags __P((DB_ENV *, u_int32_t, int)); - */ -void -__log_set_flags(dbenv, flags, on) - DB_ENV *dbenv; - u_int32_t flags; - int on; -{ - DB_LOG *dblp; - LOG *lp; - - if ((dblp = dbenv->lg_handle) == NULL) - return; - - lp = dblp->reginfo.primary; - - if (LF_ISSET(DB_LOG_AUTOREMOVE)) - lp->db_log_autoremove = on ? 1 : 0; - if (LF_ISSET(DB_LOG_INMEMORY)) - lp->db_log_inmemory = on ? 1 : 0; -} - -/* - * __log_check_sizes -- - * Makes sure that the log file size and log buffer size are compatible. - * - * PUBLIC: int __log_check_sizes __P((DB_ENV *, u_int32_t, u_int32_t)); - */ -int -__log_check_sizes(dbenv, lg_max, lg_bsize) - DB_ENV *dbenv; - u_int32_t lg_max; - u_int32_t lg_bsize; -{ - LOG *lp; - int inmem; - - if (LOGGING_ON(dbenv)) { - lp = ((DB_LOG *)dbenv->lg_handle)->reginfo.primary; - inmem = lp->db_log_inmemory; - lg_bsize = lp->buffer_size; - } else - inmem = (F_ISSET(dbenv, DB_ENV_LOG_INMEMORY) != 0); - - if (inmem) { - if (lg_bsize == 0) - lg_bsize = LG_BSIZE_INMEM; - if (lg_max == 0) - lg_max = LG_MAX_INMEM; - - if (lg_bsize <= lg_max) { - __db_err(dbenv, - "in-memory log buffer must be larger than the log file size"); - return (EINVAL); - } - } - - return (0); -} diff --git a/storage/bdb/log/log_put.c b/storage/bdb/log/log_put.c deleted file mode 100644 index 2bd128d6190..00000000000 --- a/storage/bdb/log/log_put.c +++ /dev/null @@ -1,1457 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: log_put.c,v 12.22 2005/10/31 02:22:30 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#if TIME_WITH_SYS_TIME -#include <sys/time.h> -#include <time.h> -#else -#if HAVE_SYS_TIME_H -#include <sys/time.h> -#else -#include <time.h> -#endif -#endif - -#include <stdio.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/crypto.h" -#include "dbinc/hmac.h" -#include "dbinc/log.h" -#include "dbinc/txn.h" - -static int __log_encrypt_record __P((DB_ENV *, DBT *, HDR *, u_int32_t)); -static int __log_file __P((DB_ENV *, const DB_LSN *, char *, size_t)); -static int __log_fill __P((DB_LOG *, DB_LSN *, void *, u_int32_t)); -static int __log_flush_commit __P((DB_ENV *, const DB_LSN *, u_int32_t)); -static int __log_newfh __P((DB_LOG *, int)); -static int __log_put_next __P((DB_ENV *, - DB_LSN *, const DBT *, HDR *, DB_LSN *)); -static int __log_putr __P((DB_LOG *, - DB_LSN *, const DBT *, u_int32_t, HDR *)); -static int __log_write __P((DB_LOG *, void *, u_int32_t)); - -/* - * __log_put_pp -- - * DB_ENV->log_put pre/post processing. - * - * PUBLIC: int __log_put_pp __P((DB_ENV *, DB_LSN *, const DBT *, u_int32_t)); - */ -int -__log_put_pp(dbenv, lsnp, udbt, flags) - DB_ENV *dbenv; - DB_LSN *lsnp; - const DBT *udbt; - u_int32_t flags; -{ - DB_THREAD_INFO *ip; - int ret; - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, - dbenv->lg_handle, "DB_ENV->log_put", DB_INIT_LOG); - - /* Validate arguments: check for allowed flags. */ - if ((ret = __db_fchk(dbenv, "DB_ENV->log_put", flags, - DB_LOG_CHKPNT | DB_LOG_COMMIT | - DB_FLUSH | DB_LOG_NOCOPY | DB_LOG_PERM | DB_LOG_WRNOSYNC)) != 0) - return (ret); - - /* DB_LOG_WRNOSYNC and DB_FLUSH are mutually exclusive. */ - if (LF_ISSET(DB_LOG_WRNOSYNC) && LF_ISSET(DB_FLUSH)) - return (__db_ferr(dbenv, "DB_ENV->log_put", 1)); - - /* Replication clients should never write log records. */ - if (IS_REP_CLIENT(dbenv)) { - __db_err(dbenv, - "DB_ENV->log_put is illegal on replication clients"); - return (EINVAL); - } - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, (__log_put(dbenv, lsnp, udbt, flags)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __log_put -- - * DB_ENV->log_put. - * - * PUBLIC: int __log_put __P((DB_ENV *, DB_LSN *, const DBT *, u_int32_t)); - */ -int -__log_put(dbenv, lsnp, udbt, flags) - DB_ENV *dbenv; - DB_LSN *lsnp; - const DBT *udbt; - u_int32_t flags; -{ - DB_CIPHER *db_cipher; - DBT *dbt, t; - DB_LOG *dblp; - DB_LSN lsn, old_lsn; - DB_REP *db_rep; - HDR hdr; - LOG *lp; - REP *rep; - REP_BULK bulk; - int lock_held, need_free, ret; - u_int8_t *key; - - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - db_cipher = dbenv->crypto_handle; - db_rep = dbenv->rep_handle; - if (db_rep != NULL) - rep = db_rep->region; - else - rep = NULL; - - dbt = &t; - t = *udbt; - lock_held = need_free = 0; - ZERO_LSN(old_lsn); - - /* - * If we are not a rep application, but are sharing a master rep env, - * we should not be writing log records. - */ - if (IS_REP_MASTER(dbenv) && dbenv->rep_send == NULL) { - __db_err(dbenv, "%s %s", - "Non-replication DB_ENV handle attempting", - "to modify a replicated environment"); - return (EINVAL); - } - - /* - * If we are coming from the logging code, we use an internal flag, - * DB_LOG_NOCOPY, because we know we can overwrite/encrypt the log - * record in place. Otherwise, if a user called log_put then we - * must copy it to new memory so that we know we can write it. - * - * We also must copy it to new memory if we are a replication master - * so that we retain an unencrypted copy of the log record to send - * to clients. - */ - if (!LF_ISSET(DB_LOG_NOCOPY) || IS_REP_MASTER(dbenv)) { - if (CRYPTO_ON(dbenv)) - t.size += db_cipher->adj_size(udbt->size); - if ((ret = __os_calloc(dbenv, 1, t.size, &t.data)) != 0) - goto err; - need_free = 1; - memcpy(t.data, udbt->data, udbt->size); - } - if ((ret = __log_encrypt_record(dbenv, dbt, &hdr, udbt->size)) != 0) - goto err; - if (CRYPTO_ON(dbenv)) - key = db_cipher->mac_key; - else - key = NULL; - - /* Before we grab the region lock, calculate the record's checksum. */ - __db_chksum(dbt->data, dbt->size, key, hdr.chksum); - - LOG_SYSTEM_LOCK(dbenv); - lock_held = 1; - - if ((ret = __log_put_next(dbenv, &lsn, dbt, &hdr, &old_lsn)) != 0) - goto panic_check; - - /* - * Assign the return LSN before dropping the region lock. Necessary - * in case the lsn is a begin_lsn from a TXN_DETAIL structure passed - * in by the logging routines. - */ - *lsnp = lsn; - - if (IS_REP_MASTER(dbenv)) { - /* - * Replication masters need to drop the lock to send messages, - * but want to drop and reacquire it a minimal number of times. - */ - LOG_SYSTEM_UNLOCK(dbenv); - lock_held = 0; - - /* - * If we changed files and we're in a replicated environment, - * we need to inform our clients now that we've dropped the - * region lock. - * - * Note that a failed NEWFILE send is a dropped message that - * our client can handle, so we can ignore it. It's possible - * that the record we already put is a commit, so we don't just - * want to return failure. - */ - if (!IS_ZERO_LSN(old_lsn)) - (void)__rep_send_message(dbenv, DB_EID_BROADCAST, - REP_NEWFILE, &old_lsn, NULL, 0, 0); - - /* - * If we're doing bulk processing put it in the bulk buffer. - */ - ret = 0; - if (FLD_ISSET(rep->config, REP_C_BULK)) { - /* - * Bulk could have been turned on by another process. - * If so, set the address into the bulk region now. - */ - if (db_rep->bulk == NULL) - db_rep->bulk = R_ADDR(&dblp->reginfo, - lp->bulk_buf); - memset(&bulk, 0, sizeof(bulk)); - bulk.addr = db_rep->bulk; - bulk.offp = &lp->bulk_off; - bulk.len = lp->bulk_len; - bulk.type = REP_BULK_LOG; - bulk.eid = DB_EID_BROADCAST; - bulk.flagsp = &lp->bulk_flags; - ret = __rep_bulk_message(dbenv, &bulk, NULL, - &lsn, udbt, flags); - } - if (!FLD_ISSET(rep->config, REP_C_BULK) || - ret == DB_REP_BULKOVF) { - /* - * Then send the log record itself on to our clients. - */ - /* - * !!! - * In the crypto case, we MUST send the udbt, not the - * now-encrypted dbt. Clients have no way to decrypt - * without the header. - */ - ret = __rep_send_message(dbenv, DB_EID_BROADCAST, - REP_LOG, &lsn, udbt, flags, 0); - } - /* - * If the send fails and we're a commit or checkpoint, - * there's nothing we can do; the record's in the log. - * Flush it, even if we're running with TXN_NOSYNC, - * on the grounds that it should be in durable - * form somewhere. - */ - if (ret != 0 && LF_ISSET(DB_LOG_PERM)) - LF_SET(DB_FLUSH); - } - - /* - * If needed, do a flush. Note that failures at this point - * are only permissible if we know we haven't written a commit - * record; __log_flush_commit is responsible for enforcing this. - * - * If a flush is not needed, see if WRITE_NOSYNC was set and we - * need to write out the log buffer. - */ - if (LF_ISSET(DB_FLUSH | DB_LOG_WRNOSYNC)) { - if (!lock_held) { - LOG_SYSTEM_LOCK(dbenv); - lock_held = 1; - } - if ((ret = __log_flush_commit(dbenv, &lsn, flags)) != 0) - goto panic_check; - } - - /* - * If flushed a checkpoint record, reset the "bytes since the last - * checkpoint" counters. - */ - if (LF_ISSET(DB_LOG_CHKPNT)) - lp->stat.st_wc_bytes = lp->stat.st_wc_mbytes = 0; - - /* Increment count of records added to the log. */ - ++lp->stat.st_record; - - if (0) { -panic_check: /* - * Writing log records cannot fail if we're a replication - * master. The reason is that once we send the record to - * replication clients, the transaction can no longer - * abort, otherwise the master would be out of sync with - * the rest of the replication group. Panic the system. - */ - if (ret != 0 && IS_REP_MASTER(dbenv)) - ret = __db_panic(dbenv, ret); - } - -err: if (lock_held) - LOG_SYSTEM_UNLOCK(dbenv); - if (need_free) - __os_free(dbenv, dbt->data); - - /* - * If auto-remove is set and we switched files, remove unnecessary - * log files. - */ - if (ret == 0 && !IS_ZERO_LSN(old_lsn) && lp->db_log_autoremove) - __log_autoremove(dbenv); - - return (ret); -} - -/* - * __log_current_lsn -- - * Return the current LSN. - * - * PUBLIC: int __log_current_lsn - * PUBLIC: __P((DB_ENV *, DB_LSN *, u_int32_t *, u_int32_t *)); - */ -int -__log_current_lsn(dbenv, lsnp, mbytesp, bytesp) - DB_ENV *dbenv; - DB_LSN *lsnp; - u_int32_t *mbytesp, *bytesp; -{ - DB_LOG *dblp; - LOG *lp; - - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - - LOG_SYSTEM_LOCK(dbenv); - - /* - * We are trying to get the LSN of the last entry in the log. We use - * this in three places: 1) DB_ENV->txn_checkpoint uses it as a first - * value when trying to compute an LSN such that all transactions begun - * before it are complete. 2) DB_ENV->txn_begin uses it as the - * begin_lsn. 3) While opening a file to see if we've gotten rid of - * too many log files. - * - * Typically, it's easy to get the last written LSN, you simply look - * at the current log pointer and back up the number of bytes of the - * last log record. However, if the last thing we did was write the - * log header of a new log file, then, this doesn't work, so we return - * the first log record that will be written in this new file. - */ - *lsnp = lp->lsn; - if (lp->lsn.offset > lp->len) - lsnp->offset -= lp->len; - - /* - * Since we're holding the log region lock, return the bytes put into - * the log since the last checkpoint, transaction checkpoint needs it. - * - * We add the current buffer offset so as to count bytes that have not - * yet been written, but are sitting in the log buffer. - */ - if (mbytesp != NULL) { - *mbytesp = lp->stat.st_wc_mbytes; - *bytesp = (u_int32_t)(lp->stat.st_wc_bytes + lp->b_off); - } - - LOG_SYSTEM_UNLOCK(dbenv); - - return (0); -} - -/* - * __log_put_next -- - * Put the given record as the next in the log, wherever that may - * turn out to be. - */ -static int -__log_put_next(dbenv, lsn, dbt, hdr, old_lsnp) - DB_ENV *dbenv; - DB_LSN *lsn; - const DBT *dbt; - HDR *hdr; - DB_LSN *old_lsnp; -{ - DB_LOG *dblp; - DB_LSN old_lsn; - LOG *lp; - int newfile, ret; - - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - - /* - * Save a copy of lp->lsn before we might decide to switch log - * files and change it. If we do switch log files, and we're - * doing replication, we'll need to tell our clients about the - * switch, and they need to receive a NEWFILE message - * with this "would-be" LSN in order to know they're not - * missing any log records. - */ - old_lsn = lp->lsn; - newfile = 0; - - /* - * If this information won't fit in the file, or if we're a - * replication client environment and have been told to do so, - * swap files. - */ - if (lp->lsn.offset == 0 || - lp->lsn.offset + hdr->size + dbt->size > lp->log_size) { - if (hdr->size + sizeof(LOGP) + dbt->size > lp->log_size) { - __db_err(dbenv, - "DB_ENV->log_put: record larger than maximum file size (%lu > %lu)", - (u_long)hdr->size + sizeof(LOGP) + dbt->size, - (u_long)lp->log_size); - return (EINVAL); - } - - if ((ret = __log_newfile(dblp, NULL, 0)) != 0) - return (ret); - - /* - * Flag that we switched files, in case we're a master - * and need to send this information to our clients. - * We postpone doing the actual send until we can - * safely release the log region lock and are doing so - * anyway. - */ - newfile = 1; - } - - /* - * The offset into the log file at this point is the LSN where - * we're about to put this record, and is the LSN the caller wants. - */ - *lsn = lp->lsn; - - /* If we switched log files, let our caller know where. */ - if (newfile) - *old_lsnp = old_lsn; - - /* Actually put the record. */ - return (__log_putr(dblp, lsn, dbt, lp->lsn.offset - lp->len, hdr)); -} - -/* - * __log_flush_commit -- - * Flush a record. - */ -static int -__log_flush_commit(dbenv, lsnp, flags) - DB_ENV *dbenv; - const DB_LSN *lsnp; - u_int32_t flags; -{ - DB_LOG *dblp; - DB_LSN flush_lsn; - LOG *lp; - int ret; - - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - flush_lsn = *lsnp; - - ret = 0; - - /* - * DB_FLUSH: - * Flush a record for which the DB_FLUSH flag to log_put was set. - * - * DB_LOG_WRNOSYNC: - * If there's anything in the current log buffer, write it out. - */ - if (LF_ISSET(DB_FLUSH)) - ret = __log_flush_int(dblp, &flush_lsn, 1); - else if (!lp->db_log_inmemory && lp->b_off != 0) - if ((ret = __log_write(dblp, - dblp->bufp, (u_int32_t)lp->b_off)) == 0) - lp->b_off = 0; - - /* - * If a flush supporting a transaction commit fails, we must abort the - * transaction. (If we aren't doing a commit, return the failure; if - * if the commit we care about made it to disk successfully, we just - * ignore the failure, because there's no way to undo the commit.) - */ - if (ret == 0 || !LF_ISSET(DB_LOG_COMMIT)) - return (ret); - - if (flush_lsn.file != lp->lsn.file || flush_lsn.offset < lp->w_off) - return (0); - - /* - * Else, make sure that the commit record does not get out after we - * abort the transaction. Do this by overwriting the commit record - * in the buffer. (Note that other commits in this buffer will wait - * until a successful write happens, we do not wake them.) We point - * at the right part of the buffer and write an abort record over the - * commit. We must then try and flush the buffer again, since the - * interesting part of the buffer may have actually made it out to - * disk before there was a failure, we can't know for sure. - */ - if (__txn_force_abort(dbenv, - dblp->bufp + flush_lsn.offset - lp->w_off) == 0) - (void)__log_flush_int(dblp, &flush_lsn, 0); - - return (ret); -} - -/* - * __log_newfile -- - * Initialize and switch to a new log file. (Note that this is - * called both when no log yet exists and when we fill a log file.) - * - * PUBLIC: int __log_newfile __P((DB_LOG *, DB_LSN *, u_int32_t)); - */ -int -__log_newfile(dblp, lsnp, logfile) - DB_LOG *dblp; - DB_LSN *lsnp; - u_int32_t logfile; -{ - DB_CIPHER *db_cipher; - DB_ENV *dbenv; - DB_LSN lsn; - DBT t; - HDR hdr; - LOG *lp; - int need_free, ret; - u_int32_t lastoff; - size_t tsize; - u_int8_t *tmp; - - dbenv = dblp->dbenv; - lp = dblp->reginfo.primary; - - /* - * If we're not specifying a specific log file number and we're - * not at the beginning of a file already, start a new one. - */ - if (logfile == 0 && lp->lsn.offset != 0) { - /* - * Flush the log so this file is out and can be closed. We - * cannot release the region lock here because we need to - * protect the end of the file while we switch. In - * particular, a thread with a smaller record than ours - * could detect that there is space in the log. Even - * blocking that event by declaring the file full would - * require all threads to wait here so that the lsn.file - * can be moved ahead after the flush completes. This - * probably can be changed if we had an lsn for the - * previous file and one for the current, but it does not - * seem like this would get much more throughput, if any. - */ - if ((ret = __log_flush_int(dblp, NULL, 0)) != 0) - return (ret); - - /* - * Save the last known offset from the previous file, we'll - * need it to initialize the persistent header information. - */ - lastoff = lp->lsn.offset; - - /* Point the current LSN to the new file. */ - ++lp->lsn.file; - lp->lsn.offset = 0; - - /* Reset the file write offset. */ - lp->w_off = 0; - } else - lastoff = 0; - - /* - * Replication may require we reset the log file name space entirely. - * In that case we also force a file switch so that replication can - * clean up old files. - */ - if (logfile != 0) { - lp->lsn.file = logfile; - lp->lsn.offset = 0; - lp->w_off = 0; - if ((ret = __log_newfh(dblp, 1)) != 0) - return (ret); - } - - DB_ASSERT(lp->db_log_inmemory || lp->b_off == 0); - if (lp->db_log_inmemory && - (ret = __log_inmem_newfile(dblp, lp->lsn.file)) != 0) - return (ret); - - /* - * Insert persistent information as the first record in every file. - * Note that the previous length is wrong for the very first record - * of the log, but that's okay, we check for it during retrieval. - */ - memset(&t, 0, sizeof(t)); - memset(&hdr, 0, sizeof(HDR)); - - need_free = 0; - tsize = sizeof(LOGP); - db_cipher = dbenv->crypto_handle; - if (CRYPTO_ON(dbenv)) - tsize += db_cipher->adj_size(tsize); - if ((ret = __os_calloc(dbenv, 1, tsize, &tmp)) != 0) - return (ret); - lp->persist.log_size = lp->log_size = lp->log_nsize; - memcpy(tmp, &lp->persist, sizeof(LOGP)); - t.data = tmp; - t.size = (u_int32_t)tsize; - need_free = 1; - - if ((ret = - __log_encrypt_record(dbenv, &t, &hdr, (u_int32_t)tsize)) != 0) - goto err; - __db_chksum(t.data, t.size, - (CRYPTO_ON(dbenv)) ? db_cipher->mac_key : NULL, hdr.chksum); - lsn = lp->lsn; - if ((ret = __log_putr(dblp, &lsn, - &t, lastoff == 0 ? 0 : lastoff - lp->len, &hdr)) != 0) - goto err; - - /* Update the LSN information returned to the caller. */ - if (lsnp != NULL) - *lsnp = lp->lsn; - -err: if (need_free) - __os_free(dbenv, tmp); - return (ret); -} - -/* - * __log_putr -- - * Actually put a record into the log. - */ -static int -__log_putr(dblp, lsn, dbt, prev, h) - DB_LOG *dblp; - DB_LSN *lsn; - const DBT *dbt; - u_int32_t prev; - HDR *h; -{ - DB_CIPHER *db_cipher; - DB_ENV *dbenv; - DB_LSN f_lsn; - LOG *lp; - HDR tmp, *hdr; - int ret, t_ret; - size_t b_off, nr; - u_int32_t w_off; - - dbenv = dblp->dbenv; - lp = dblp->reginfo.primary; - - /* - * If we weren't given a header, use a local one. - */ - db_cipher = dbenv->crypto_handle; - if (h == NULL) { - hdr = &tmp; - memset(hdr, 0, sizeof(HDR)); - if (CRYPTO_ON(dbenv)) - hdr->size = HDR_CRYPTO_SZ; - else - hdr->size = HDR_NORMAL_SZ; - } else - hdr = h; - - /* Save our position in case we fail. */ - b_off = lp->b_off; - w_off = lp->w_off; - f_lsn = lp->f_lsn; - - /* - * Initialize the header. If we just switched files, lsn.offset will - * be 0, and what we really want is the offset of the previous record - * in the previous file. Fortunately, prev holds the value we want. - */ - hdr->prev = prev; - hdr->len = (u_int32_t)hdr->size + dbt->size; - - /* - * If we were passed in a nonzero checksum, our caller calculated - * the checksum before acquiring the log mutex, as an optimization. - * - * If our caller calculated a real checksum of 0, we'll needlessly - * recalculate it. C'est la vie; there's no out-of-bounds value - * here. - */ - if (hdr->chksum[0] == 0) - __db_chksum(dbt->data, dbt->size, - (CRYPTO_ON(dbenv)) ? db_cipher->mac_key : NULL, - hdr->chksum); - - if (lp->db_log_inmemory && (ret = __log_inmem_chkspace(dblp, - (u_int32_t)hdr->size + dbt->size)) != 0) - goto err; - - if ((ret = __log_fill(dblp, lsn, hdr, (u_int32_t)hdr->size)) != 0) - goto err; - - if ((ret = __log_fill(dblp, lsn, dbt->data, dbt->size)) != 0) - goto err; - - lp->len = (u_int32_t)(hdr->size + dbt->size); - lp->lsn.offset += (u_int32_t)(hdr->size + dbt->size); - return (0); -err: - /* - * If we wrote more than one buffer before failing, get the - * first one back. The extra buffers will fail the checksums - * and be ignored. - */ - if (w_off + lp->buffer_size < lp->w_off) { - DB_ASSERT(!lp->db_log_inmemory); - if ((t_ret = __os_seek(dbenv, - dblp->lfhp, 0, 0, w_off, 0, DB_OS_SEEK_SET)) != 0 || - (t_ret = __os_read(dbenv, dblp->lfhp, dblp->bufp, - b_off, &nr)) != 0) - return (__db_panic(dbenv, t_ret)); - if (nr != b_off) { - __db_err(dbenv, "Short read while restoring log"); - return (__db_panic(dbenv, EIO)); - } - } - - /* Reset to where we started. */ - lp->w_off = w_off; - lp->b_off = b_off; - lp->f_lsn = f_lsn; - - return (ret); -} - -/* - * __log_flush_pp -- - * DB_ENV->log_flush pre/post processing. - * - * PUBLIC: int __log_flush_pp __P((DB_ENV *, const DB_LSN *)); - */ -int -__log_flush_pp(dbenv, lsn) - DB_ENV *dbenv; - const DB_LSN *lsn; -{ - DB_THREAD_INFO *ip; - int ret; - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, - dbenv->lg_handle, "DB_ENV->log_flush", DB_INIT_LOG); - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, (__log_flush(dbenv, lsn)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * See if we need to wait. s_lsn is not locked so some care is needed. - * The sync point can only move forward. The lsnp->file cannot be - * greater than the s_lsn.file. If the file we want is in the past - * we are done. If the file numbers are the same check the offset. - * This all assumes we can read an 32-bit quantity in one state or - * the other, not in transition. - */ -#define ALREADY_FLUSHED(lp, lsnp) \ - (((lp)->s_lsn.file > (lsnp)->file) || \ - ((lp)->s_lsn.file == (lsnp)->file && \ - (lp)->s_lsn.offset > (lsnp)->offset)) - -/* - * __log_flush -- - * DB_ENV->log_flush - * - * PUBLIC: int __log_flush __P((DB_ENV *, const DB_LSN *)); - */ -int -__log_flush(dbenv, lsn) - DB_ENV *dbenv; - const DB_LSN *lsn; -{ - DB_LOG *dblp; - LOG *lp; - int ret; - - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - if (lsn != NULL && ALREADY_FLUSHED(lp, lsn)) - return (0); - LOG_SYSTEM_LOCK(dbenv); - ret = __log_flush_int(dblp, lsn, 1); - LOG_SYSTEM_UNLOCK(dbenv); - return (ret); -} - -/* - * __log_flush_int -- - * Write all records less than or equal to the specified LSN; internal - * version. - * - * PUBLIC: int __log_flush_int __P((DB_LOG *, const DB_LSN *, int)); - */ -int -__log_flush_int(dblp, lsnp, release) - DB_LOG *dblp; - const DB_LSN *lsnp; - int release; -{ - struct __db_commit *commit; - DB_ENV *dbenv; - DB_LSN flush_lsn, f_lsn; - LOG *lp; - size_t b_off; - u_int32_t ncommit, w_off; - int do_flush, first, ret; - - dbenv = dblp->dbenv; - lp = dblp->reginfo.primary; - ncommit = 0; - ret = 0; - - if (lp->db_log_inmemory) { - lp->s_lsn = lp->lsn; - ++lp->stat.st_scount; - return (0); - } - - /* - * If no LSN specified, flush the entire log by setting the flush LSN - * to the last LSN written in the log. Otherwise, check that the LSN - * isn't a non-existent record for the log. - */ - if (lsnp == NULL) { - flush_lsn.file = lp->lsn.file; - flush_lsn.offset = lp->lsn.offset - lp->len; - } else if (lsnp->file > lp->lsn.file || - (lsnp->file == lp->lsn.file && - lsnp->offset > lp->lsn.offset - lp->len)) { - __db_err(dbenv, - "DB_ENV->log_flush: LSN of %lu/%lu past current end-of-log of %lu/%lu", - (u_long)lsnp->file, (u_long)lsnp->offset, - (u_long)lp->lsn.file, (u_long)lp->lsn.offset); - __db_err(dbenv, "%s %s %s", - "Database environment corrupt; the wrong log files may", - "have been removed or incompatible database files imported", - "from another environment"); - return (__db_panic(dbenv, DB_RUNRECOVERY)); - } else { - if (ALREADY_FLUSHED(lp, lsnp)) - return (0); - flush_lsn = *lsnp; - } - - /* - * If a flush is in progress and we're allowed to do so, drop - * the region lock and block waiting for the next flush. - */ - if (release && lp->in_flush != 0) { - if ((commit = SH_TAILQ_FIRST( - &lp->free_commits, __db_commit)) == NULL) { - if ((ret = __db_shalloc(&dblp->reginfo, - sizeof(struct __db_commit), 0, &commit)) != 0) - goto flush; - memset(commit, 0, sizeof(*commit)); - if ((ret = __mutex_alloc(dbenv, MTX_TXN_COMMIT, - DB_MUTEX_SELF_BLOCK, &commit->mtx_txnwait)) != 0) { - __db_shalloc_free(&dblp->reginfo, commit); - return (ret); - } - MUTEX_LOCK(dbenv, commit->mtx_txnwait); - } else - SH_TAILQ_REMOVE( - &lp->free_commits, commit, links, __db_commit); - - lp->ncommit++; - - /* - * Flushes may be requested out of LSN order; be - * sure we only move lp->t_lsn forward. - */ - if (log_compare(&lp->t_lsn, &flush_lsn) < 0) - lp->t_lsn = flush_lsn; - - commit->lsn = flush_lsn; - SH_TAILQ_INSERT_HEAD( - &lp->commits, commit, links, __db_commit); - LOG_SYSTEM_UNLOCK(dbenv); - /* Wait here for the in-progress flush to finish. */ - MUTEX_LOCK(dbenv, commit->mtx_txnwait); - LOG_SYSTEM_LOCK(dbenv); - - lp->ncommit--; - /* - * Grab the flag before freeing the struct to see if - * we need to flush the log to commit. If so, - * use the maximal lsn for any committing thread. - */ - do_flush = F_ISSET(commit, DB_COMMIT_FLUSH); - F_CLR(commit, DB_COMMIT_FLUSH); - SH_TAILQ_INSERT_HEAD( - &lp->free_commits, commit, links, __db_commit); - if (do_flush) { - lp->in_flush--; - flush_lsn = lp->t_lsn; - } else - return (0); - } - - /* - * Protect flushing with its own mutex so we can release - * the region lock except during file switches. - */ -flush: MUTEX_LOCK(dbenv, lp->mtx_flush); - - /* - * If the LSN is less than or equal to the last-sync'd LSN, we're done. - * Note, the last-sync LSN saved in s_lsn is the LSN of the first byte - * after the byte we absolutely know was written to disk, so the test - * is <, not <=. - */ - if (flush_lsn.file < lp->s_lsn.file || - (flush_lsn.file == lp->s_lsn.file && - flush_lsn.offset < lp->s_lsn.offset)) { - MUTEX_UNLOCK(dbenv, lp->mtx_flush); - goto done; - } - - /* - * We may need to write the current buffer. We have to write the - * current buffer if the flush LSN is greater than or equal to the - * buffer's starting LSN. - * - * Otherwise, it's still possible that this thread may never have - * written to this log file. Acquire a file descriptor if we don't - * already have one. - */ - if (lp->b_off != 0 && log_compare(&flush_lsn, &lp->f_lsn) >= 0) { - if ((ret = __log_write(dblp, - dblp->bufp, (u_int32_t)lp->b_off)) != 0) { - MUTEX_UNLOCK(dbenv, lp->mtx_flush); - goto done; - } - - lp->b_off = 0; - } else if (dblp->lfhp == NULL || dblp->lfname != lp->lsn.file) - if ((ret = __log_newfh(dblp, 0)) != 0) { - MUTEX_UNLOCK(dbenv, lp->mtx_flush); - goto done; - } - - /* - * We are going to flush, release the region. - * First get the current state of the buffer since - * another write may come in, but we may not flush it. - */ - b_off = lp->b_off; - w_off = lp->w_off; - f_lsn = lp->f_lsn; - lp->in_flush++; - if (release) - LOG_SYSTEM_UNLOCK(dbenv); - - /* Sync all writes to disk. */ - if ((ret = __os_fsync(dbenv, dblp->lfhp)) != 0) { - MUTEX_UNLOCK(dbenv, lp->mtx_flush); - if (release) - LOG_SYSTEM_LOCK(dbenv); - ret = __db_panic(dbenv, ret); - return (ret); - } - - /* - * Set the last-synced LSN. - * This value must be set to the LSN past the last complete - * record that has been flushed. This is at least the first - * lsn, f_lsn. If the buffer is empty, b_off == 0, then - * we can move up to write point since the first lsn is not - * set for the new buffer. - */ - lp->s_lsn = f_lsn; - if (b_off == 0) - lp->s_lsn.offset = w_off; - - MUTEX_UNLOCK(dbenv, lp->mtx_flush); - if (release) - LOG_SYSTEM_LOCK(dbenv); - - lp->in_flush--; - ++lp->stat.st_scount; - - /* - * How many flush calls (usually commits) did this call actually sync? - * At least one, if it got here. - */ - ncommit = 1; -done: - if (lp->ncommit != 0) { - first = 1; - for (commit = SH_TAILQ_FIRST(&lp->commits, __db_commit); - commit != NULL; - commit = SH_TAILQ_NEXT(commit, links, __db_commit)) - if (log_compare(&lp->s_lsn, &commit->lsn) > 0) { - MUTEX_UNLOCK(dbenv, commit->mtx_txnwait); - SH_TAILQ_REMOVE( - &lp->commits, commit, links, __db_commit); - ncommit++; - } else if (first == 1) { - F_SET(commit, DB_COMMIT_FLUSH); - MUTEX_UNLOCK(dbenv, commit->mtx_txnwait); - SH_TAILQ_REMOVE( - &lp->commits, commit, links, __db_commit); - /* - * This thread will wake and flush. - * If another thread commits and flushes - * first we will waste a trip trough the - * mutex. - */ - lp->in_flush++; - first = 0; - } - } - if (lp->stat.st_maxcommitperflush < ncommit) - lp->stat.st_maxcommitperflush = ncommit; - if (lp->stat.st_mincommitperflush > ncommit || - lp->stat.st_mincommitperflush == 0) - lp->stat.st_mincommitperflush = ncommit; - - return (ret); -} - -/* - * __log_fill -- - * Write information into the log. - */ -static int -__log_fill(dblp, lsn, addr, len) - DB_LOG *dblp; - DB_LSN *lsn; - void *addr; - u_int32_t len; -{ - LOG *lp; - u_int32_t bsize, nrec; - size_t nw, remain; - int ret; - - lp = dblp->reginfo.primary; - bsize = lp->buffer_size; - - if (lp->db_log_inmemory) { - __log_inmem_copyin(dblp, lp->b_off, addr, len); - lp->b_off = (lp->b_off + len) % lp->buffer_size; - return (0); - } - - while (len > 0) { /* Copy out the data. */ - /* - * If we're beginning a new buffer, note the user LSN to which - * the first byte of the buffer belongs. We have to know this - * when flushing the buffer so that we know if the in-memory - * buffer needs to be flushed. - */ - if (lp->b_off == 0) - lp->f_lsn = *lsn; - - /* - * If we're on a buffer boundary and the data is big enough, - * copy as many records as we can directly from the data. - */ - if (lp->b_off == 0 && len >= bsize) { - nrec = len / bsize; - if ((ret = __log_write(dblp, addr, nrec * bsize)) != 0) - return (ret); - addr = (u_int8_t *)addr + nrec * bsize; - len -= nrec * bsize; - ++lp->stat.st_wcount_fill; - continue; - } - - /* Figure out how many bytes we can copy this time. */ - remain = bsize - lp->b_off; - nw = remain > len ? len : remain; - memcpy(dblp->bufp + lp->b_off, addr, nw); - addr = (u_int8_t *)addr + nw; - len -= (u_int32_t)nw; - lp->b_off += nw; - - /* If we fill the buffer, flush it. */ - if (lp->b_off == bsize) { - if ((ret = __log_write(dblp, dblp->bufp, bsize)) != 0) - return (ret); - lp->b_off = 0; - ++lp->stat.st_wcount_fill; - } - } - return (0); -} - -/* - * __log_write -- - * Write the log buffer to disk. - */ -static int -__log_write(dblp, addr, len) - DB_LOG *dblp; - void *addr; - u_int32_t len; -{ - DB_ENV *dbenv; - LOG *lp; - size_t nw; - int ret; - - dbenv = dblp->dbenv; - lp = dblp->reginfo.primary; - - DB_ASSERT(!lp->db_log_inmemory); - - /* - * If we haven't opened the log file yet or the current one has - * changed, acquire a new log file. We are creating the file if we're - * about to write to the start of it, in other words, if the write - * offset is zero. - */ - if (dblp->lfhp == NULL || dblp->lfname != lp->lsn.file) - if ((ret = __log_newfh(dblp, lp->w_off == 0)) != 0) - return (ret); - - /* - * If we're writing the first block in a log file on a filesystem that - * guarantees unwritten blocks are zero-filled, we set the size of the - * file in advance. This increases sync performance on some systems, - * because they don't need to update metadata on every sync. - * - * Ignore any error -- we may have run out of disk space, but that's no - * reason to quit. - */ -#ifdef HAVE_FILESYSTEM_NOTZERO - if (lp->w_off == 0 && !__os_fs_notzero()) -#else - if (lp->w_off == 0) -#endif - (void)__db_file_extend(dbenv, dblp->lfhp, lp->log_size); - - /* - * Seek to the offset in the file (someone may have written it - * since we last did). - */ - if ((ret = __os_seek(dbenv, - dblp->lfhp, 0, 0, lp->w_off, 0, DB_OS_SEEK_SET)) != 0 || - (ret = __os_write(dbenv, dblp->lfhp, addr, len, &nw)) != 0) - return (ret); - - /* Reset the buffer offset and update the seek offset. */ - lp->w_off += len; - - /* Update written statistics. */ - if ((lp->stat.st_w_bytes += len) >= MEGABYTE) { - lp->stat.st_w_bytes -= MEGABYTE; - ++lp->stat.st_w_mbytes; - } - if ((lp->stat.st_wc_bytes += len) >= MEGABYTE) { - lp->stat.st_wc_bytes -= MEGABYTE; - ++lp->stat.st_wc_mbytes; - } - ++lp->stat.st_wcount; - - return (0); -} - -/* - * __log_file_pp -- - * DB_ENV->log_file pre/post processing. - * - * PUBLIC: int __log_file_pp __P((DB_ENV *, const DB_LSN *, char *, size_t)); - */ -int -__log_file_pp(dbenv, lsn, namep, len) - DB_ENV *dbenv; - const DB_LSN *lsn; - char *namep; - size_t len; -{ - DB_THREAD_INFO *ip; - int ret; - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, - dbenv->lg_handle, "DB_ENV->log_file", DB_INIT_LOG); - - if (F_ISSET(dbenv, DB_ENV_LOG_INMEMORY)) { - __db_err(dbenv, - "DB_ENV->log_file is illegal with in-memory logs."); - return (EINVAL); - } - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, (__log_file(dbenv, lsn, namep, len)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __log_file -- - * DB_ENV->log_file. - */ -static int -__log_file(dbenv, lsn, namep, len) - DB_ENV *dbenv; - const DB_LSN *lsn; - char *namep; - size_t len; -{ - DB_LOG *dblp; - int ret; - char *name; - - dblp = dbenv->lg_handle; - LOG_SYSTEM_LOCK(dbenv); - ret = __log_name(dblp, lsn->file, &name, NULL, 0); - LOG_SYSTEM_UNLOCK(dbenv); - if (ret != 0) - return (ret); - - /* Check to make sure there's enough room and copy the name. */ - if (len < strlen(name) + 1) { - *namep = '\0'; - __db_err(dbenv, "DB_ENV->log_file: name buffer is too short"); - return (EINVAL); - } - (void)strcpy(namep, name); - __os_free(dbenv, name); - - return (0); -} - -/* - * __log_newfh -- - * Acquire a file handle for the current log file. - */ -static int -__log_newfh(dblp, create) - DB_LOG *dblp; - int create; -{ - DB_ENV *dbenv; - LOG *lp; - u_int32_t flags; - int ret; - logfile_validity status; - - dbenv = dblp->dbenv; - lp = dblp->reginfo.primary; - - /* Close any previous file descriptor. */ - if (dblp->lfhp != NULL) { - (void)__os_closehandle(dbenv, dblp->lfhp); - dblp->lfhp = NULL; - } - - flags = DB_OSO_SEQ | - (create ? DB_OSO_CREATE : 0) | - (F_ISSET(dbenv, DB_ENV_DIRECT_LOG) ? DB_OSO_DIRECT : 0) | - (F_ISSET(dbenv, DB_ENV_DSYNC_LOG) ? DB_OSO_DSYNC : 0); - - /* Get the path of the new file and open it. */ - dblp->lfname = lp->lsn.file; - if ((ret = __log_valid(dblp, dblp->lfname, 0, &dblp->lfhp, - flags, &status)) != 0) - __db_err(dbenv, - "DB_ENV->log_put: %d: %s", lp->lsn.file, db_strerror(ret)); - else if (status != DB_LV_NORMAL && status != DB_LV_INCOMPLETE) - ret = DB_NOTFOUND; - - return (ret); -} - -/* - * __log_name -- - * Return the log name for a particular file, and optionally open it. - * - * PUBLIC: int __log_name __P((DB_LOG *, - * PUBLIC: u_int32_t, char **, DB_FH **, u_int32_t)); - */ -int -__log_name(dblp, filenumber, namep, fhpp, flags) - DB_LOG *dblp; - u_int32_t filenumber, flags; - char **namep; - DB_FH **fhpp; -{ - DB_ENV *dbenv; - LOG *lp; - int mode, ret; - char *oname; - char old[sizeof(LFPREFIX) + 5 + 20], new[sizeof(LFPREFIX) + 10 + 20]; - - dbenv = dblp->dbenv; - lp = dblp->reginfo.primary; - - DB_ASSERT(!lp->db_log_inmemory); - - /* - * !!! - * The semantics of this routine are bizarre. - * - * The reason for all of this is that we need a place where we can - * intercept requests for log files, and, if appropriate, check for - * both the old-style and new-style log file names. The trick is - * that all callers of this routine that are opening the log file - * read-only want to use an old-style file name if they can't find - * a match using a new-style name. The only down-side is that some - * callers may check for the old-style when they really don't need - * to, but that shouldn't mess up anything, and we only check for - * the old-style name when we've already failed to find a new-style - * one. - * - * Create a new-style file name, and if we're not going to open the - * file, return regardless. - */ - (void)snprintf(new, sizeof(new), LFNAME, filenumber); - if ((ret = __db_appname(dbenv, - DB_APP_LOG, new, 0, NULL, namep)) != 0 || fhpp == NULL) - return (ret); - - /* The application may have specified an absolute file mode. */ - if (lp->filemode == 0) - mode = dbenv->db_mode; - else { - LF_SET(DB_OSO_ABSMODE); - mode = lp->filemode; - } - - /* Open the new-style file -- if we succeed, we're done. */ - if ((ret = __os_open_extend(dbenv, *namep, 0, flags, mode, fhpp)) == 0) - return (0); - - /* - * If the open failed for reason other than the file - * not being there, complain loudly, the wrong user - * probably started up the application. - */ - if (ret != ENOENT) { - __db_err(dbenv, - "%s: log file unreadable: %s", *namep, db_strerror(ret)); - return (__db_panic(dbenv, ret)); - } - - /* - * The open failed... if the DB_RDONLY flag isn't set, we're done, - * the caller isn't interested in old-style files. - */ - if (!LF_ISSET(DB_OSO_RDONLY)) { - __db_err(dbenv, - "%s: log file open failed: %s", *namep, db_strerror(ret)); - return (__db_panic(dbenv, ret)); - } - - /* Create an old-style file name. */ - (void)snprintf(old, sizeof(old), LFNAME_V1, filenumber); - if ((ret = __db_appname(dbenv, DB_APP_LOG, old, 0, NULL, &oname)) != 0) - goto err; - - /* - * Open the old-style file -- if we succeed, we're done. Free the - * space allocated for the new-style name and return the old-style - * name to the caller. - */ - if ((ret = __os_open(dbenv, oname, flags, mode, fhpp)) == 0) { - __os_free(dbenv, *namep); - *namep = oname; - return (0); - } - - /* - * Couldn't find either style of name -- return the new-style name - * for the caller's error message. If it's an old-style name that's - * actually missing we're going to confuse the user with the error - * message, but that implies that not only were we looking for an - * old-style name, but we expected it to exist and we weren't just - * looking for any log file. That's not a likely error. - */ -err: __os_free(dbenv, oname); - return (ret); -} - -/* - * __log_rep_put -- - * Short-circuit way for replication clients to put records into the - * log. Replication clients' logs need to be laid out exactly their masters' - * are, so we let replication take responsibility for when the log gets - * flushed, when log switches files, etc. This is just a thin PUBLIC wrapper - * for __log_putr with a slightly prettier interface. - * - * Note that the REP->mtx_clientdb should be held when this is called. - * Note that we acquire the log region mutex while holding mtx_clientdb. - * - * PUBLIC: int __log_rep_put __P((DB_ENV *, DB_LSN *, const DBT *)); - */ -int -__log_rep_put(dbenv, lsnp, rec) - DB_ENV *dbenv; - DB_LSN *lsnp; - const DBT *rec; -{ - DB_CIPHER *db_cipher; - DB_LOG *dblp; - HDR hdr; - DBT *dbt, t; - LOG *lp; - int need_free, ret; - - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - - LOG_SYSTEM_LOCK(dbenv); - memset(&hdr, 0, sizeof(HDR)); - t = *rec; - dbt = &t; - need_free = 0; - db_cipher = (DB_CIPHER *)dbenv->crypto_handle; - if (CRYPTO_ON(dbenv)) - t.size += db_cipher->adj_size(rec->size); - if ((ret = __os_calloc(dbenv, 1, t.size, &t.data)) != 0) - goto err; - need_free = 1; - memcpy(t.data, rec->data, rec->size); - - if ((ret = __log_encrypt_record(dbenv, dbt, &hdr, rec->size)) != 0) - goto err; - __db_chksum(t.data, t.size, - (CRYPTO_ON(dbenv)) ? db_cipher->mac_key : NULL, hdr.chksum); - - DB_ASSERT(log_compare(lsnp, &lp->lsn) == 0); - ret = __log_putr(dblp, lsnp, dbt, lp->lsn.offset - lp->len, &hdr); -err: - /* - * !!! Assume caller holds REP->mtx_clientdb to modify ready_lsn. - */ - lp->ready_lsn = lp->lsn; - LOG_SYSTEM_UNLOCK(dbenv); - if (need_free) - __os_free(dbenv, t.data); - return (ret); -} - -static int -__log_encrypt_record(dbenv, dbt, hdr, orig) - DB_ENV *dbenv; - DBT *dbt; - HDR *hdr; - u_int32_t orig; -{ - DB_CIPHER *db_cipher; - int ret; - - if (CRYPTO_ON(dbenv)) { - db_cipher = (DB_CIPHER *)dbenv->crypto_handle; - hdr->size = HDR_CRYPTO_SZ; - hdr->orig_size = orig; - if ((ret = db_cipher->encrypt(dbenv, db_cipher->data, - hdr->iv, dbt->data, dbt->size)) != 0) - return (ret); - } else { - hdr->size = HDR_NORMAL_SZ; - } - return (0); -} diff --git a/storage/bdb/log/log_stat.c b/storage/bdb/log/log_stat.c deleted file mode 100644 index 7c6c503a37d..00000000000 --- a/storage/bdb/log/log_stat.c +++ /dev/null @@ -1,329 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: log_stat.c,v 12.10 2005/10/10 19:06:22 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_am.h" -#include "dbinc/log.h" - -#ifdef HAVE_STATISTICS -static int __log_print_all __P((DB_ENV *, u_int32_t)); -static int __log_print_stats __P((DB_ENV *, u_int32_t)); -static int __log_stat __P((DB_ENV *, DB_LOG_STAT **, u_int32_t)); - -/* - * __log_stat_pp -- - * DB_ENV->log_stat pre/post processing. - * - * PUBLIC: int __log_stat_pp __P((DB_ENV *, DB_LOG_STAT **, u_int32_t)); - */ -int -__log_stat_pp(dbenv, statp, flags) - DB_ENV *dbenv; - DB_LOG_STAT **statp; - u_int32_t flags; -{ - DB_THREAD_INFO *ip; - int ret; - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, - dbenv->lg_handle, "DB_ENV->log_stat", DB_INIT_LOG); - - if ((ret = __db_fchk(dbenv, - "DB_ENV->log_stat", flags, DB_STAT_CLEAR)) != 0) - return (ret); - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, (__log_stat(dbenv, statp, flags)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __log_stat -- - * DB_ENV->log_stat. - */ -static int -__log_stat(dbenv, statp, flags) - DB_ENV *dbenv; - DB_LOG_STAT **statp; - u_int32_t flags; -{ - DB_LOG *dblp; - DB_LOG_STAT *stats; - LOG *lp; - int ret; - - *statp = NULL; - - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - - if ((ret = __os_umalloc(dbenv, sizeof(DB_LOG_STAT), &stats)) != 0) - return (ret); - - /* Copy out the global statistics. */ - LOG_SYSTEM_LOCK(dbenv); - *stats = lp->stat; - if (LF_ISSET(DB_STAT_CLEAR)) - memset(&lp->stat, 0, sizeof(lp->stat)); - - stats->st_magic = lp->persist.magic; - stats->st_version = lp->persist.version; - stats->st_mode = lp->filemode; - stats->st_lg_bsize = lp->buffer_size; - stats->st_lg_size = lp->log_nsize; - - __mutex_set_wait_info(dbenv, lp->mtx_region, - &stats->st_region_wait, &stats->st_region_nowait); - if (LF_ISSET(DB_STAT_CLEAR)) - __mutex_clear(dbenv, lp->mtx_region); - stats->st_regsize = dblp->reginfo.rp->size; - - stats->st_cur_file = lp->lsn.file; - stats->st_cur_offset = lp->lsn.offset; - stats->st_disk_file = lp->s_lsn.file; - stats->st_disk_offset = lp->s_lsn.offset; - - LOG_SYSTEM_UNLOCK(dbenv); - - *statp = stats; - return (0); -} - -/* - * __log_stat_print_pp -- - * DB_ENV->log_stat_print pre/post processing. - * - * PUBLIC: int __log_stat_print_pp __P((DB_ENV *, u_int32_t)); - */ -int -__log_stat_print_pp(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - DB_THREAD_INFO *ip; - int ret; - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, - dbenv->lg_handle, "DB_ENV->log_stat_print", DB_INIT_LOG); - - if ((ret = __db_fchk(dbenv, "DB_ENV->log_stat_print", - flags, DB_STAT_ALL | DB_STAT_CLEAR)) != 0) - return (ret); - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, (__log_stat_print(dbenv, flags)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __log_stat_print -- - * DB_ENV->log_stat_print method. - * - * PUBLIC: int __log_stat_print __P((DB_ENV *, u_int32_t)); - */ -int -__log_stat_print(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - u_int32_t orig_flags; - int ret; - - orig_flags = flags; - LF_CLR(DB_STAT_CLEAR); - if (flags == 0 || LF_ISSET(DB_STAT_ALL)) { - ret = __log_print_stats(dbenv, orig_flags); - if (flags == 0 || ret != 0) - return (ret); - } - - if (LF_ISSET(DB_STAT_ALL) && - (ret = __log_print_all(dbenv, orig_flags)) != 0) - return (ret); - - return (0); -} - -/* - * __log_print_stats -- - * Display default log region statistics. - */ -static int -__log_print_stats(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - DB_LOG_STAT *sp; - int ret; - - if ((ret = __log_stat(dbenv, &sp, flags)) != 0) - return (ret); - - if (LF_ISSET(DB_STAT_ALL)) - __db_msg(dbenv, "Default logging region information:"); - STAT_HEX("Log magic number", sp->st_magic); - STAT_ULONG("Log version number", sp->st_version); - __db_dlbytes(dbenv, "Log record cache size", - (u_long)0, (u_long)0, (u_long)sp->st_lg_bsize); - __db_msg(dbenv, "%#o\tLog file mode", sp->st_mode); - if (sp->st_lg_size % MEGABYTE == 0) - __db_msg(dbenv, "%luMb\tCurrent log file size", - (u_long)sp->st_lg_size / MEGABYTE); - else if (sp->st_lg_size % 1024 == 0) - __db_msg(dbenv, "%luKb\tCurrent log file size", - (u_long)sp->st_lg_size / 1024); - else - __db_msg(dbenv, "%lu\tCurrent log file size", - (u_long)sp->st_lg_size); - __db_dl(dbenv, "Records entered into the log", (u_long)sp->st_record); - __db_dlbytes(dbenv, "Log bytes written", - (u_long)0, (u_long)sp->st_w_mbytes, (u_long)sp->st_w_bytes); - __db_dlbytes(dbenv, "Log bytes written since last checkpoint", - (u_long)0, (u_long)sp->st_wc_mbytes, (u_long)sp->st_wc_bytes); - __db_dl(dbenv, "Total log file I/O writes", (u_long)sp->st_wcount); - __db_dl(dbenv, "Total log file I/O writes due to overflow", - (u_long)sp->st_wcount_fill); - __db_dl(dbenv, "Total log file flushes", (u_long)sp->st_scount); - __db_dl(dbenv, "Total log file I/O reads", (u_long)sp->st_rcount); - STAT_ULONG("Current log file number", sp->st_cur_file); - STAT_ULONG("Current log file offset", sp->st_cur_offset); - STAT_ULONG("On-disk log file number", sp->st_disk_file); - STAT_ULONG("On-disk log file offset", sp->st_disk_offset); - - __db_dl(dbenv, - "Maximum commits in a log flush", (u_long)sp->st_maxcommitperflush); - __db_dl(dbenv, - "Minimum commits in a log flush", (u_long)sp->st_mincommitperflush); - - __db_dlbytes(dbenv, "Log region size", - (u_long)0, (u_long)0, (u_long)sp->st_regsize); - __db_dl_pct(dbenv, - "The number of region locks that required waiting", - (u_long)sp->st_region_wait, DB_PCT(sp->st_region_wait, - sp->st_region_wait + sp->st_region_nowait), NULL); - - __os_ufree(dbenv, sp); - - return (0); -} - -/* - * __log_print_all -- - * Display debugging log region statistics. - */ -static int -__log_print_all(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - static const FN fn[] = { - { DBLOG_RECOVER, "DBLOG_RECOVER" }, - { DBLOG_FORCE_OPEN, "DBLOG_FORCE_OPEN" }, - { 0, NULL } - }; - DB_LOG *dblp; - LOG *lp; - - dblp = dbenv->lg_handle; - lp = (LOG *)dblp->reginfo.primary; - - LOG_SYSTEM_LOCK(dbenv); - - __db_print_reginfo(dbenv, &dblp->reginfo, "Log"); - - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_msg(dbenv, "DB_LOG handle information:"); - __mutex_print_debug_single( - dbenv, "DB_LOG handle mutex", dblp->mtx_dbreg, flags); - STAT_ULONG("Log file name", dblp->lfname); - __db_print_fh(dbenv, "Log file handle", dblp->lfhp, flags); - __db_prflags(dbenv, NULL, dblp->flags, fn, NULL, "\tFlags"); - - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_msg(dbenv, "LOG handle information:"); - __mutex_print_debug_single( - dbenv, "LOG region mutex", lp->mtx_region, flags); - __mutex_print_debug_single( - dbenv, "File name list mutex", lp->mtx_filelist, flags); - - STAT_HEX("persist.magic", lp->persist.magic); - STAT_ULONG("persist.version", lp->persist.version); - __db_dlbytes(dbenv, - "persist.log_size", (u_long)0, (u_long)0, lp->persist.log_size); - STAT_FMT("log file permissions mode", "%#lo", u_long, lp->filemode); - STAT_LSN("current file offset LSN", &lp->lsn); - STAT_LSN("first buffer byte LSN", &lp->lsn); - STAT_ULONG("current buffer offset", lp->b_off); - STAT_ULONG("current file write offset", lp->w_off); - STAT_ULONG("length of last record", lp->len); - STAT_LONG("log flush in progress", lp->in_flush); - __mutex_print_debug_single( - dbenv, "Log flush mutex", lp->mtx_flush, flags); - - STAT_LSN("last sync LSN", &lp->s_lsn); - - /* - * Don't display the replication fields here, they're displayed as part - * of the replication statistics. - */ - - STAT_LSN("cached checkpoint LSN", &lp->cached_ckp_lsn); - - __db_dlbytes(dbenv, - "log buffer size", (u_long)0, (u_long)0, lp->buffer_size); - __db_dlbytes(dbenv, - "log file size", (u_long)0, (u_long)0, lp->log_size); - __db_dlbytes(dbenv, - "next log file size", (u_long)0, (u_long)0, lp->log_nsize); - - STAT_ULONG("transactions waiting to commit", lp->ncommit); - STAT_LSN("LSN of first commit", &lp->t_lsn); - - LOG_SYSTEM_UNLOCK(dbenv); - - return (0); -} - -#else /* !HAVE_STATISTICS */ - -int -__log_stat_pp(dbenv, statp, flags) - DB_ENV *dbenv; - DB_LOG_STAT **statp; - u_int32_t flags; -{ - COMPQUIET(statp, NULL); - COMPQUIET(flags, 0); - - return (__db_stat_not_built(dbenv)); -} - -int -__log_stat_print_pp(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - COMPQUIET(flags, 0); - - return (__db_stat_not_built(dbenv)); -} -#endif diff --git a/storage/bdb/mp/mp_alloc.c b/storage/bdb/mp/mp_alloc.c deleted file mode 100644 index edbaac9ce89..00000000000 --- a/storage/bdb/mp/mp_alloc.c +++ /dev/null @@ -1,408 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: mp_alloc.c,v 12.6 2005/08/12 13:17:22 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_shash.h" -#include "dbinc/mp.h" - -static void __memp_bad_buffer __P((DB_MPOOL_HASH *)); - -/* - * __memp_alloc -- - * Allocate some space from a cache region. - * - * PUBLIC: int __memp_alloc __P((DB_MPOOL *, - * PUBLIC: REGINFO *, MPOOLFILE *, size_t, roff_t *, void *)); - */ -int -__memp_alloc(dbmp, infop, mfp, len, offsetp, retp) - DB_MPOOL *dbmp; - REGINFO *infop; - MPOOLFILE *mfp; - size_t len; - roff_t *offsetp; - void *retp; -{ - BH *bhp; - DB_ENV *dbenv; - DB_MPOOL_HASH *dbht, *hp, *hp_end, *hp_tmp; - MPOOL *c_mp; - MPOOLFILE *bh_mfp; - size_t freed_space; - db_mutex_t mutex; - u_int32_t buckets, buffers, high_priority, priority; - u_int32_t put_counter, total_buckets; - int aggressive, giveup, ret; - void *p; - - dbenv = dbmp->dbenv; - c_mp = infop->primary; - dbht = R_ADDR(infop, c_mp->htab); - hp_end = &dbht[c_mp->htab_buckets]; - - buckets = buffers = put_counter = total_buckets = 0; - aggressive = giveup = 0; - hp_tmp = NULL; - - c_mp->stat.st_alloc++; - - /* - * If we're allocating a buffer, and the one we're discarding is the - * same size, we don't want to waste the time to re-integrate it into - * the shared memory free list. If the DB_MPOOLFILE argument isn't - * NULL, we'll compare the underlying page sizes of the two buffers - * before free-ing and re-allocating buffers. - */ - if (mfp != NULL) - len = (sizeof(BH) - sizeof(u_int8_t)) + mfp->stat.st_pagesize; - - MPOOL_REGION_LOCK(dbenv, infop); - - /* - * Anything newer than 1/10th of the buffer pool is ignored during - * allocation (unless allocation starts failing). - */ - high_priority = c_mp->lru_count - c_mp->stat.st_pages / 10; - - /* - * First we try to allocate from free memory. If that fails, scan the - * buffer pool to find buffers with low priorities. We consider small - * sets of hash buckets each time to limit the amount of work needing - * to be done. This approximates LRU, but not very well. We either - * find a buffer of the same size to use, or we will free 3 times what - * we need in the hopes it will coalesce into a contiguous chunk of the - * right size. In the latter case we branch back here and try again. - */ -alloc: if ((ret = __db_shalloc(infop, len, 0, &p)) == 0) { - if (mfp != NULL) - c_mp->stat.st_pages++; - MPOOL_REGION_UNLOCK(dbenv, infop); - -found: if (offsetp != NULL) - *offsetp = R_OFFSET(infop, p); - *(void **)retp = p; - - /* - * Update the search statistics. - * - * We're not holding the region locked here, these statistics - * can't be trusted. - */ - total_buckets += buckets; - if (total_buckets != 0) { - if (total_buckets > c_mp->stat.st_alloc_max_buckets) - c_mp->stat.st_alloc_max_buckets = total_buckets; - c_mp->stat.st_alloc_buckets += total_buckets; - } - if (buffers != 0) { - if (buffers > c_mp->stat.st_alloc_max_pages) - c_mp->stat.st_alloc_max_pages = buffers; - c_mp->stat.st_alloc_pages += buffers; - } - return (0); - } else if (giveup || c_mp->stat.st_pages == 0) { - MPOOL_REGION_UNLOCK(dbenv, infop); - - __db_err(dbenv, - "unable to allocate space from the buffer cache"); - return (ret); - } - ret = 0; - - /* - * We re-attempt the allocation every time we've freed 3 times what - * we need. Reset our free-space counter. - */ - freed_space = 0; - total_buckets += buckets; - buckets = 0; - - /* - * Walk the hash buckets and find the next two with potentially useful - * buffers. Free the buffer with the lowest priority from the buckets' - * chains. - */ - for (;;) { - /* All pages have been freed, make one last try */ - if (c_mp->stat.st_pages == 0) - goto alloc; - - /* Check for wrap around. */ - hp = &dbht[c_mp->last_checked++]; - if (hp >= hp_end) { - c_mp->last_checked = 0; - hp = &dbht[c_mp->last_checked++]; - } - - /* - * Skip empty buckets. - * - * We can check for empty buckets before locking as we - * only care if the pointer is zero or non-zero. - */ - if (SH_TAILQ_FIRST(&hp->hash_bucket, __bh) == NULL) - continue; - - /* - * The failure mode is when there are too many buffers we can't - * write or there's not enough memory in the system. We don't - * have a way to know that allocation has no way to succeed. - * We fail if there were no pages returned to the cache after - * we've been trying for a relatively long time. - * - * Get aggressive if we've tried to flush the number of hash - * buckets as are in the system and have not found any more - * space. Aggressive means: - * - * a: set a flag to attempt to flush high priority buffers as - * well as other buffers. - * b: sync the mpool to force out queue extent pages. While we - * might not have enough space for what we want and flushing - * is expensive, why not? - * c: look at a buffer in every hash bucket rather than choose - * the more preferable of two. - * d: start to think about giving up. - * - * If we get here twice, sleep for a second, hopefully someone - * else will run and free up some memory. - * - * Always try to allocate memory too, in case some other thread - * returns its memory to the region. - * - * !!! - * This test ignores pathological cases like no buffers in the - * system -- that shouldn't be possible. - */ - if ((++buckets % c_mp->htab_buckets) == 0) { - if (freed_space > 0) - goto alloc; - MPOOL_REGION_UNLOCK(dbenv, infop); - - switch (++aggressive) { - case 1: - break; - case 2: - put_counter = c_mp->put_counter; - /* FALLTHROUGH */ - case 3: - case 4: - case 5: - case 6: - (void)__memp_sync_int( - dbenv, NULL, 0, DB_SYNC_ALLOC, NULL); - - __os_sleep(dbenv, 1, 0); - break; - default: - aggressive = 1; - if (put_counter == c_mp->put_counter) - giveup = 1; - break; - } - - MPOOL_REGION_LOCK(dbenv, infop); - goto alloc; - } - - if (!aggressive) { - /* Skip high priority buckets. */ - if (hp->hash_priority > high_priority) - continue; - - /* - * Find two buckets and select the one with the lowest - * priority. Performance testing shows that looking - * at two improves the LRUness and looking at more only - * does a little better. - */ - if (hp_tmp == NULL) { - hp_tmp = hp; - continue; - } - if (hp->hash_priority > hp_tmp->hash_priority) - hp = hp_tmp; - hp_tmp = NULL; - } - - /* Remember the priority of the buffer we're looking for. */ - priority = hp->hash_priority; - - /* Unlock the region and lock the hash bucket. */ - MPOOL_REGION_UNLOCK(dbenv, infop); - mutex = hp->mtx_hash; - MUTEX_LOCK(dbenv, mutex); - -#ifdef DIAGNOSTIC - __memp_check_order(hp); -#endif - /* - * The lowest priority page is first in the bucket, as they are - * maintained in sorted order. - * - * The buffer may have been freed or its priority changed while - * we switched from the region lock to the hash lock. If so, - * we have to restart. We will still take the first buffer on - * the bucket's list, though, if it has a low enough priority. - */ - if ((bhp = SH_TAILQ_FIRST(&hp->hash_bucket, __bh)) == NULL || - bhp->ref != 0 || bhp->priority > priority) - goto next_hb; - - buffers++; - - /* Find the associated MPOOLFILE. */ - bh_mfp = R_ADDR(dbmp->reginfo, bhp->mf_offset); - - /* If the page is dirty, pin it and write it. */ - ret = 0; - if (F_ISSET(bhp, BH_DIRTY)) { - ++bhp->ref; - ret = __memp_bhwrite(dbmp, hp, bh_mfp, bhp, 0); - --bhp->ref; - if (ret == 0) - ++c_mp->stat.st_rw_evict; - } else - ++c_mp->stat.st_ro_evict; - - /* - * If a write fails for any reason, we can't proceed. - * - * We released the hash bucket lock while doing I/O, so another - * thread may have acquired this buffer and incremented the ref - * count after we wrote it, in which case we can't have it. - * - * If there's a write error and we're having problems finding - * something to allocate, avoid selecting this buffer again - * by making it the bucket's least-desirable buffer. - */ - if (ret != 0 || bhp->ref != 0) { - if (ret != 0 && aggressive) - __memp_bad_buffer(hp); - goto next_hb; - } - - /* - * Check to see if the buffer is the size we're looking for. - * If so, we can simply reuse it. Else, free the buffer and - * its space and keep looking. - */ - if (mfp != NULL && - mfp->stat.st_pagesize == bh_mfp->stat.st_pagesize) { - if ((ret = __memp_bhfree(dbmp, hp, bhp, 0)) != 0) { - MUTEX_UNLOCK(dbenv, mutex); - return (ret); - } - p = bhp; - goto found; - } - - freed_space += __db_shalloc_sizeof(bhp); - if ((ret = - __memp_bhfree(dbmp, hp, bhp, BH_FREE_FREEMEM)) != 0) { - MUTEX_UNLOCK(dbenv, mutex); - return (ret); - } - if (aggressive > 1) - aggressive = 1; - - /* - * Unlock this hash bucket and re-acquire the region lock. If - * we're reaching here as a result of calling memp_bhfree, the - * hash bucket lock has already been discarded. - */ - if (0) { -next_hb: MUTEX_UNLOCK(dbenv, mutex); - } - MPOOL_REGION_LOCK(dbenv, infop); - - /* - * Retry the allocation as soon as we've freed up sufficient - * space. We're likely to have to coalesce of memory to - * satisfy the request, don't try until it's likely (possible?) - * we'll succeed. - */ - if (freed_space >= 3 * len) - goto alloc; - } - /* NOTREACHED */ -} - -/* - * __memp_bad_buffer -- - * Make the first buffer in a hash bucket the least desirable buffer. - */ -static void -__memp_bad_buffer(hp) - DB_MPOOL_HASH *hp; -{ - BH *bhp; - u_int32_t priority; - - /* Remove the first buffer from the bucket. */ - bhp = SH_TAILQ_FIRST(&hp->hash_bucket, __bh); - SH_TAILQ_REMOVE(&hp->hash_bucket, bhp, hq, __bh); - - /* - * Find the highest priority buffer in the bucket. Buffers are - * sorted by priority, so it's the last one in the bucket. - */ - priority = SH_TAILQ_EMPTY(&hp->hash_bucket) ? bhp->priority : - SH_TAILQ_LASTP(&hp->hash_bucket, hq, __bh)->priority; - - /* - * Set our buffer's priority to be just as bad, and append it to - * the bucket. - */ - bhp->priority = priority; - SH_TAILQ_INSERT_TAIL(&hp->hash_bucket, bhp, hq); - - /* Reset the hash bucket's priority. */ - hp->hash_priority = SH_TAILQ_FIRSTP(&hp->hash_bucket, __bh)->priority; -#ifdef DIAGNOSTIC - __memp_check_order(hp); -#endif -} - -#ifdef DIAGNOSTIC -/* - * __memp_check_order -- - * Verify the priority ordering of a hash bucket chain. - * - * PUBLIC: #ifdef DIAGNOSTIC - * PUBLIC: void __memp_check_order __P((DB_MPOOL_HASH *)); - * PUBLIC: #endif - */ -void -__memp_check_order(hp) - DB_MPOOL_HASH *hp; -{ - BH *bhp; - u_int32_t priority; - - /* - * Assumes the hash bucket is locked. - */ - if ((bhp = SH_TAILQ_FIRST(&hp->hash_bucket, __bh)) == NULL) - return; - - DB_ASSERT(bhp->priority == hp->hash_priority); - - for (priority = bhp->priority; - (bhp = SH_TAILQ_NEXT(bhp, hq, __bh)) != NULL; - priority = bhp->priority) - DB_ASSERT(priority <= bhp->priority); -} -#endif diff --git a/storage/bdb/mp/mp_bh.c b/storage/bdb/mp/mp_bh.c deleted file mode 100644 index b2721b801a6..00000000000 --- a/storage/bdb/mp/mp_bh.c +++ /dev/null @@ -1,589 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: mp_bh.c,v 12.11 2005/10/20 18:57:07 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_shash.h" -#include "dbinc/mp.h" -#include "dbinc/log.h" -#include "dbinc/db_page.h" - -static int __memp_pgwrite - __P((DB_ENV *, DB_MPOOLFILE *, DB_MPOOL_HASH *, BH *)); - -/* - * __memp_bhwrite -- - * Write the page associated with a given buffer header. - * - * PUBLIC: int __memp_bhwrite __P((DB_MPOOL *, - * PUBLIC: DB_MPOOL_HASH *, MPOOLFILE *, BH *, int)); - */ -int -__memp_bhwrite(dbmp, hp, mfp, bhp, open_extents) - DB_MPOOL *dbmp; - DB_MPOOL_HASH *hp; - MPOOLFILE *mfp; - BH *bhp; - int open_extents; -{ - DB_ENV *dbenv; - DB_MPOOLFILE *dbmfp; - DB_MPREG *mpreg; - int ret; - - dbenv = dbmp->dbenv; - - /* - * If the file has been removed or is a closed temporary file, we're - * done -- the page-write function knows how to handle the fact that - * we don't have (or need!) any real file descriptor information. - */ - if (mfp->deadfile) - return (__memp_pgwrite(dbenv, NULL, hp, bhp)); - - /* - * Walk the process' DB_MPOOLFILE list and find a file descriptor for - * the file. We also check that the descriptor is open for writing. - */ - MUTEX_LOCK(dbenv, dbmp->mutex); - for (dbmfp = TAILQ_FIRST(&dbmp->dbmfq); - dbmfp != NULL; dbmfp = TAILQ_NEXT(dbmfp, q)) - if (dbmfp->mfp == mfp && !F_ISSET(dbmfp, MP_READONLY)) { - ++dbmfp->ref; - break; - } - MUTEX_UNLOCK(dbenv, dbmp->mutex); - - if (dbmfp != NULL) { - /* - * Temporary files may not have been created. We only handle - * temporary files in this path, because only the process that - * created a temporary file will ever flush buffers to it. - */ - if (dbmfp->fhp == NULL) { - /* We may not be allowed to create backing files. */ - if (mfp->no_backing_file) - return (EPERM); - - MUTEX_LOCK(dbenv, dbmp->mutex); - if (dbmfp->fhp == NULL) - ret = __db_appname(dbenv, DB_APP_TMP, NULL, - F_ISSET(dbenv, DB_ENV_DIRECT_DB) ? - DB_OSO_DIRECT : 0, &dbmfp->fhp, NULL); - else - ret = 0; - MUTEX_UNLOCK(dbenv, dbmp->mutex); - if (ret != 0) { - __db_err(dbenv, - "unable to create temporary backing file"); - return (ret); - } - } - - goto pgwrite; - } - - /* - * There's no file handle for this file in our process. - * - * !!! - * It's the caller's choice if we're going to open extent files. - */ - if (!open_extents && F_ISSET(mfp, MP_EXTENT)) - return (EPERM); - - /* - * !!! - * Don't try to attach to temporary files. There are two problems in - * trying to do that. First, if we have different privileges than the - * process that "owns" the temporary file, we might create the backing - * disk file such that the owning process couldn't read/write its own - * buffers, e.g., memp_trickle running as root creating a file owned - * as root, mode 600. Second, if the temporary file has already been - * created, we don't have any way of finding out what its real name is, - * and, even if we did, it was already unlinked (so that it won't be - * left if the process dies horribly). This decision causes a problem, - * however: if the temporary file consumes the entire buffer cache, - * and the owner doesn't flush the buffers to disk, we could end up - * with resource starvation, and the memp_trickle thread couldn't do - * anything about it. That's a pretty unlikely scenario, though. - * - * Note we should never get here when the temporary file in question - * has already been closed in another process, in which case it should - * be marked dead. - */ - if (F_ISSET(mfp, MP_TEMP) || mfp->no_backing_file) - return (EPERM); - - /* - * It's not a page from a file we've opened. If the file requires - * application-specific input/output processing, see if this process - * has ever registered information as to how to write this type of - * file. If not, there's nothing we can do. - */ - if (mfp->ftype != 0 && mfp->ftype != DB_FTYPE_SET) { - MUTEX_LOCK(dbenv, dbmp->mutex); - for (mpreg = LIST_FIRST(&dbmp->dbregq); - mpreg != NULL; mpreg = LIST_NEXT(mpreg, q)) - if (mpreg->ftype == mfp->ftype) - break; - MUTEX_UNLOCK(dbenv, dbmp->mutex); - if (mpreg == NULL) - return (EPERM); - } - - /* - * Try and open the file, specifying the known underlying shared area. - * - * !!! - * There's no negative cache, so we may repeatedly try and open files - * that we have previously tried (and failed) to open. - */ - if ((ret = __memp_fcreate(dbenv, &dbmfp)) != 0) - return (ret); - if ((ret = __memp_fopen(dbmfp, - mfp, NULL, DB_DURABLE_UNKNOWN, 0, mfp->stat.st_pagesize)) != 0) { - (void)__memp_fclose(dbmfp, 0); - - /* - * Ignore any error if the file is marked dead, assume the file - * was removed from under us. - */ - if (!mfp->deadfile) - return (ret); - - dbmfp = NULL; - } - -pgwrite: - ret = __memp_pgwrite(dbenv, dbmfp, hp, bhp); - if (dbmfp == NULL) - return (ret); - - /* - * Discard our reference, and, if we're the last reference, make sure - * the file eventually gets closed. - */ - MUTEX_LOCK(dbenv, dbmp->mutex); - if (dbmfp->ref == 1) - F_SET(dbmfp, MP_FLUSH); - else - --dbmfp->ref; - MUTEX_UNLOCK(dbenv, dbmp->mutex); - - return (ret); -} - -/* - * __memp_pgread -- - * Read a page from a file. - * - * PUBLIC: int __memp_pgread __P((DB_MPOOLFILE *, db_mutex_t, BH *, int)); - */ -int -__memp_pgread(dbmfp, mutex, bhp, can_create) - DB_MPOOLFILE *dbmfp; - db_mutex_t mutex; - BH *bhp; - int can_create; -{ - DB_ENV *dbenv; - MPOOLFILE *mfp; - size_t len, nr; - u_int32_t pagesize; - int ret; - - dbenv = dbmfp->dbenv; - mfp = dbmfp->mfp; - pagesize = mfp->stat.st_pagesize; - - /* We should never be called with a dirty or a locked buffer. */ - DB_ASSERT(!F_ISSET(bhp, BH_DIRTY | BH_DIRTY_CREATE | BH_LOCKED)); - - /* Lock the buffer and swap the hash bucket lock for the buffer lock. */ - F_SET(bhp, BH_LOCKED | BH_TRASH); - MUTEX_LOCK(dbenv, bhp->mtx_bh); - MUTEX_UNLOCK(dbenv, mutex); - - /* - * Temporary files may not yet have been created. We don't create - * them now, we create them when the pages have to be flushed. - */ - nr = 0; - if (dbmfp->fhp != NULL) - if ((ret = __os_io(dbenv, DB_IO_READ, - dbmfp->fhp, bhp->pgno, pagesize, bhp->buf, &nr)) != 0) - goto err; - - /* - * The page may not exist; if it doesn't, nr may well be 0, but we - * expect the underlying OS calls not to return an error code in - * this case. - */ - if (nr < pagesize) { - /* - * Don't output error messages for short reads. In particular, - * DB recovery processing may request pages never written to - * disk or for which only some part have been written to disk, - * in which case we won't find the page. The caller must know - * how to handle the error. - */ - if (can_create == 0) { - ret = DB_PAGE_NOTFOUND; - goto err; - } - - /* Clear any bytes that need to be cleared. */ - len = mfp->clear_len == DB_CLEARLEN_NOTSET ? - pagesize : mfp->clear_len; - memset(bhp->buf, 0, len); - -#if defined(DIAGNOSTIC) || defined(UMRW) - /* - * If we're running in diagnostic mode, corrupt any bytes on - * the page that are unknown quantities for the caller. - */ - if (len < pagesize) - memset(bhp->buf + len, CLEAR_BYTE, pagesize - len); -#endif - ++mfp->stat.st_page_create; - } else - ++mfp->stat.st_page_in; - - /* Call any pgin function. */ - ret = mfp->ftype == 0 ? 0 : __memp_pg(dbmfp, bhp, 1); - - /* Unlock the buffer and reacquire the hash bucket lock. */ -err: MUTEX_UNLOCK(dbenv, bhp->mtx_bh); - MUTEX_LOCK(dbenv, mutex); - - /* - * If no errors occurred, the data is now valid, clear the BH_TRASH - * flag; regardless, clear the lock bit and let other threads proceed. - */ - F_CLR(bhp, BH_LOCKED); - if (ret == 0) - F_CLR(bhp, BH_TRASH); - - return (ret); -} - -/* - * __memp_pgwrite -- - * Write a page to a file. - */ -static int -__memp_pgwrite(dbenv, dbmfp, hp, bhp) - DB_ENV *dbenv; - DB_MPOOLFILE *dbmfp; - DB_MPOOL_HASH *hp; - BH *bhp; -{ - DB_LSN lsn; - MPOOLFILE *mfp; - size_t nw; - int callpgin, ret; - - mfp = dbmfp == NULL ? NULL : dbmfp->mfp; - callpgin = ret = 0; - - /* - * We should never be called with a clean or trash buffer. - * The sync code does call us with already locked buffers. - */ - DB_ASSERT(F_ISSET(bhp, BH_DIRTY)); - DB_ASSERT(!F_ISSET(bhp, BH_TRASH)); - - /* - * If we have not already traded the hash bucket lock for the buffer - * lock, do so now. - */ - if (!F_ISSET(bhp, BH_LOCKED)) { - F_SET(bhp, BH_LOCKED); - MUTEX_LOCK(dbenv, bhp->mtx_bh); - MUTEX_UNLOCK(dbenv, hp->mtx_hash); - } - - /* - * It's possible that the underlying file doesn't exist, either - * because of an outright removal or because it was a temporary - * file that's been closed. - * - * !!! - * Once we pass this point, we know that dbmfp and mfp aren't NULL, - * and that we have a valid file reference. - */ - if (mfp == NULL || mfp->deadfile) - goto file_dead; - - /* - * If the page is in a file for which we have LSN information, we have - * to ensure the appropriate log records are on disk. - */ - if (LOGGING_ON(dbenv) && mfp->lsn_off != -1 && - !IS_CLIENT_PGRECOVER(dbenv)) { - memcpy(&lsn, bhp->buf + mfp->lsn_off, sizeof(DB_LSN)); - if (!IS_NOT_LOGGED_LSN(lsn) && - (ret = __log_flush(dbenv, &lsn)) != 0) - goto err; - } - -#ifdef DIAGNOSTIC - /* - * Verify write-ahead logging semantics. - * - * !!! - * Two special cases. There is a single field on the meta-data page, - * the last-page-number-in-the-file field, for which we do not log - * changes. If the page was originally created in a database that - * didn't have logging turned on, we can see a page marked dirty but - * for which no corresponding log record has been written. However, - * the only way that a page can be created for which there isn't a - * previous log record and valid LSN is when the page was created - * without logging turned on, and so we check for that special-case - * LSN value. - * - * Second, when a client is reading database pages from a master - * during an internal backup, we may get pages modified after - * the current end-of-log. - */ - if (LOGGING_ON(dbenv) && !IS_NOT_LOGGED_LSN(LSN(bhp->buf)) && - !IS_CLIENT_PGRECOVER(dbenv)) { - /* - * There is a potential race here. If we are in the midst of - * switching log files, it's possible we could test against the - * old file and the new offset in the log region's LSN. If we - * fail the first test, acquire the log mutex and check again. - */ - DB_LOG *dblp; - LOG *lp; - - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - if (!lp->db_log_inmemory && - log_compare(&lp->s_lsn, &LSN(bhp->buf)) <= 0) { - MUTEX_LOCK(dbenv, lp->mtx_flush); - DB_ASSERT(log_compare(&lp->s_lsn, &LSN(bhp->buf)) > 0); - MUTEX_UNLOCK(dbenv, lp->mtx_flush); - } - } -#endif - - /* - * Call any pgout function. We set the callpgin flag so that we flag - * that the contents of the buffer will need to be passed through pgin - * before they are reused. - */ - if (mfp->ftype != 0 && !F_ISSET(bhp, BH_CALLPGIN)) { - callpgin = 1; - if ((ret = __memp_pg(dbmfp, bhp, 0)) != 0) - goto err; - } - - /* Write the page. */ - if ((ret = __os_io(dbenv, DB_IO_WRITE, dbmfp->fhp, - bhp->pgno, mfp->stat.st_pagesize, bhp->buf, &nw)) != 0) { - __db_err(dbenv, "%s: write failed for page %lu", - __memp_fn(dbmfp), (u_long)bhp->pgno); - goto err; - } - ++mfp->stat.st_page_out; - -err: -file_dead: - /* - * !!! - * Once we pass this point, dbmfp and mfp may be NULL, we may not have - * a valid file reference. - * - * Unlock the buffer and reacquire the hash lock. - */ - MUTEX_UNLOCK(dbenv, bhp->mtx_bh); - MUTEX_LOCK(dbenv, hp->mtx_hash); - - /* - * If we rewrote the page, it will need processing by the pgin - * routine before reuse. - */ - if (callpgin) - F_SET(bhp, BH_CALLPGIN); - - /* - * Update the hash bucket statistics, reset the flags. - * If we were successful, the page is no longer dirty. - */ - if (ret == 0) { - DB_ASSERT(hp->hash_page_dirty != 0); - --hp->hash_page_dirty; - - F_CLR(bhp, BH_DIRTY | BH_DIRTY_CREATE); - } - - /* Regardless, clear any sync wait-for count and remove our lock. */ - bhp->ref_sync = 0; - F_CLR(bhp, BH_LOCKED); - - return (ret); -} - -/* - * __memp_pg -- - * Call the pgin/pgout routine. - * - * PUBLIC: int __memp_pg __P((DB_MPOOLFILE *, BH *, int)); - */ -int -__memp_pg(dbmfp, bhp, is_pgin) - DB_MPOOLFILE *dbmfp; - BH *bhp; - int is_pgin; -{ - DBT dbt, *dbtp; - DB_ENV *dbenv; - DB_MPOOL *dbmp; - DB_MPREG *mpreg; - MPOOLFILE *mfp; - int ftype, ret; - - dbenv = dbmfp->dbenv; - dbmp = dbenv->mp_handle; - mfp = dbmfp->mfp; - - if ((ftype = mfp->ftype) == DB_FTYPE_SET) - mpreg = dbmp->pg_inout; - else { - MUTEX_LOCK(dbenv, dbmp->mutex); - for (mpreg = LIST_FIRST(&dbmp->dbregq); - mpreg != NULL; mpreg = LIST_NEXT(mpreg, q)) - if (ftype == mpreg->ftype) - break; - MUTEX_UNLOCK(dbenv, dbmp->mutex); - } - if (mpreg == NULL) - return (0); - - if (mfp->pgcookie_len == 0) - dbtp = NULL; - else { - dbt.size = (u_int32_t)mfp->pgcookie_len; - dbt.data = R_ADDR(dbmp->reginfo, mfp->pgcookie_off); - dbtp = &dbt; - } - - if (is_pgin) { - if (mpreg->pgin != NULL && - (ret = mpreg->pgin(dbenv, bhp->pgno, bhp->buf, dbtp)) != 0) - goto err; - } else - if (mpreg->pgout != NULL && - (ret = mpreg->pgout(dbenv, bhp->pgno, bhp->buf, dbtp)) != 0) - goto err; - - return (0); - -err: __db_err(dbenv, "%s: %s failed for page %lu", - __memp_fn(dbmfp), is_pgin ? "pgin" : "pgout", (u_long)bhp->pgno); - return (ret); -} - -/* - * __memp_bhfree -- - * Free a bucket header and its referenced data. - * - * PUBLIC: int __memp_bhfree - * PUBLIC: __P((DB_MPOOL *, DB_MPOOL_HASH *, BH *, u_int32_t)); - */ -int -__memp_bhfree(dbmp, hp, bhp, flags) - DB_MPOOL *dbmp; - DB_MPOOL_HASH *hp; - BH *bhp; - u_int32_t flags; -{ - DB_ENV *dbenv; - MPOOL *c_mp, *mp; - MPOOLFILE *mfp; - u_int32_t n_cache; - int ret, t_ret; - - /* - * Assumes the hash bucket is locked and the MPOOL is not. - */ - dbenv = dbmp->dbenv; - mp = dbmp->reginfo[0].primary; - n_cache = NCACHE(mp, bhp->mf_offset, bhp->pgno); - - /* - * Delete the buffer header from the hash bucket queue and reset - * the hash bucket's priority, if necessary. - */ - SH_TAILQ_REMOVE(&hp->hash_bucket, bhp, hq, __bh); - if (bhp->priority == hp->hash_priority) - hp->hash_priority = - SH_TAILQ_EMPTY(&hp->hash_bucket) ? - 0 : SH_TAILQ_FIRSTP(&hp->hash_bucket, __bh)->priority; -#ifdef DIAGNOSTIC - __memp_check_order(hp); -#endif - - /* - * Discard the hash bucket's mutex, it's no longer needed, and - * we don't want to be holding it when acquiring other locks. - */ - if (!LF_ISSET(BH_FREE_UNLOCKED)) - MUTEX_UNLOCK(dbenv, hp->mtx_hash); - - /* - * Find the underlying MPOOLFILE and decrement its reference count. - * If this is its last reference, remove it. - */ - mfp = R_ADDR(dbmp->reginfo, bhp->mf_offset); - MUTEX_LOCK(dbenv, mfp->mutex); - if (--mfp->block_cnt == 0 && mfp->mpf_cnt == 0) - ret = __memp_mf_discard(dbmp, mfp); - else { - ret = 0; - MUTEX_UNLOCK(dbenv, mfp->mutex); - } - - /* - * Free the associated mutex. - * - * XXX - * This is wrong. We fast-path the allocation of replacement buffers - * by checking the required size, we shouldn't reallocate the mutex in - * that case, either. (Note that we should probably reset the mutex - * statistics in case we re-use the mutex, though.) - */ - if ((t_ret = __mutex_free(dbenv, &bhp->mtx_bh)) != 0 && ret == 0) - ret = t_ret; - - /* - * If we're not reusing the buffer immediately, free the buffer for - * real. - */ - if (LF_ISSET(BH_FREE_FREEMEM)) { - MPOOL_REGION_LOCK(dbenv, &dbmp->reginfo[n_cache]); - - __db_shalloc_free(&dbmp->reginfo[n_cache], bhp); - c_mp = dbmp->reginfo[n_cache].primary; - c_mp->stat.st_pages--; - - MPOOL_REGION_UNLOCK(dbenv, &dbmp->reginfo[n_cache]); - } - - return (ret); -} diff --git a/storage/bdb/mp/mp_fget.c b/storage/bdb/mp/mp_fget.c deleted file mode 100644 index 9cecc2ad86d..00000000000 --- a/storage/bdb/mp/mp_fget.c +++ /dev/null @@ -1,670 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: mp_fget.c,v 12.8 2005/10/12 17:53:36 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_shash.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" - -/* - * __memp_fget_pp -- - * DB_MPOOLFILE->get pre/post processing. - * - * PUBLIC: int __memp_fget_pp - * PUBLIC: __P((DB_MPOOLFILE *, db_pgno_t *, u_int32_t, void *)); - */ -int -__memp_fget_pp(dbmfp, pgnoaddr, flags, addrp) - DB_MPOOLFILE *dbmfp; - db_pgno_t *pgnoaddr; - u_int32_t flags; - void *addrp; -{ - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int rep_check, ret; - - dbenv = dbmfp->dbenv; - - PANIC_CHECK(dbenv); - MPF_ILLEGAL_BEFORE_OPEN(dbmfp, "DB_MPOOLFILE->get"); - - /* - * Validate arguments. - * - * !!! - * Don't test for DB_MPOOL_CREATE and DB_MPOOL_NEW flags for readonly - * files here, and create non-existent pages in readonly files if the - * flags are set, later. The reason is that the hash access method - * wants to get empty pages that don't really exist in readonly files. - * The only alternative is for hash to write the last "bucket" all the - * time, which we don't want to do because one of our big goals in life - * is to keep database files small. It's sleazy as hell, but we catch - * any attempt to actually write the file in memp_fput(). - */ -#define OKFLAGS (DB_MPOOL_CREATE | DB_MPOOL_LAST | DB_MPOOL_NEW) - if (flags != 0) { - if ((ret = __db_fchk(dbenv, "memp_fget", flags, OKFLAGS)) != 0) - return (ret); - - switch (flags) { - case DB_MPOOL_CREATE: - case DB_MPOOL_LAST: - case DB_MPOOL_NEW: - break; - default: - return (__db_ferr(dbenv, "memp_fget", 1)); - } - } - - ENV_ENTER(dbenv, ip); - - rep_check = IS_ENV_REPLICATED(dbenv) ? 1 : 0; - if (rep_check && (ret = __op_rep_enter(dbenv)) != 0) - goto err; - ret = __memp_fget(dbmfp, pgnoaddr, flags, addrp); - /* - * We only decrement the count in op_rep_exit if the operation fails. - * Otherwise the count will be decremented when the page is no longer - * pinned in memp_fput. - */ - if (ret != 0 && rep_check) - (void)__op_rep_exit(dbenv); - - /* Similarly if an app has a page pinned it is ACTIVE. */ -err: if (ret != 0) - ENV_LEAVE(dbenv, ip); - - return (ret); -} - -/* - * __memp_fget -- - * Get a page from the file. - * - * PUBLIC: int __memp_fget - * PUBLIC: __P((DB_MPOOLFILE *, db_pgno_t *, u_int32_t, void *)); - */ -int -__memp_fget(dbmfp, pgnoaddr, flags, addrp) - DB_MPOOLFILE *dbmfp; - db_pgno_t *pgnoaddr; - u_int32_t flags; - void *addrp; -{ - enum { FIRST_FOUND, FIRST_MISS, SECOND_FOUND, SECOND_MISS } state; - BH *alloc_bhp, *bhp; - DB_ENV *dbenv; - DB_MPOOL *dbmp; - DB_MPOOL_HASH *hp; - MPOOL *c_mp, *mp; - MPOOLFILE *mfp; - roff_t mf_offset; - u_int32_t n_cache, st_hsearch; - int b_incr, extending, first, ret; - - *(void **)addrp = NULL; - - dbenv = dbmfp->dbenv; - dbmp = dbenv->mp_handle; - - c_mp = NULL; - mp = dbmp->reginfo[0].primary; - mfp = dbmfp->mfp; - mf_offset = R_OFFSET(dbmp->reginfo, mfp); - alloc_bhp = bhp = NULL; - hp = NULL; - b_incr = extending = ret = 0; - - switch (flags) { - case DB_MPOOL_LAST: - /* Get the last page number in the file. */ - MPOOL_SYSTEM_LOCK(dbenv); - *pgnoaddr = mfp->last_pgno; - MPOOL_SYSTEM_UNLOCK(dbenv); - break; - case DB_MPOOL_NEW: - /* - * If always creating a page, skip the first search - * of the hash bucket. - */ - goto alloc; - case DB_MPOOL_CREATE: - default: - break; - } - - /* - * If mmap'ing the file and the page is not past the end of the file, - * just return a pointer. We can't use R_ADDR here: this is an offset - * into an mmap'd file, not a shared region, and doesn't change for - * private environments. - * - * The page may be past the end of the file, so check the page number - * argument against the original length of the file. If we previously - * returned pages past the original end of the file, last_pgno will - * have been updated to match the "new" end of the file, and checking - * against it would return pointers past the end of the mmap'd region. - * - * If another process has opened the file for writing since we mmap'd - * it, we will start playing the game by their rules, i.e. everything - * goes through the cache. All pages previously returned will be safe, - * as long as the correct locking protocol was observed. - * - * We don't discard the map because we don't know when all of the - * pages will have been discarded from the process' address space. - * It would be possible to do so by reference counting the open - * pages from the mmap, but it's unclear to me that it's worth it. - */ - if (dbmfp->addr != NULL && - F_ISSET(mfp, MP_CAN_MMAP) && *pgnoaddr <= mfp->orig_last_pgno) { - *(void **)addrp = (u_int8_t *)dbmfp->addr + - (*pgnoaddr * mfp->stat.st_pagesize); - ++mfp->stat.st_map; - return (0); - } - -hb_search: - /* - * Determine the cache and hash bucket where this page lives and get - * local pointers to them. Reset on each pass through this code, the - * page number can change. - */ - n_cache = NCACHE(mp, mf_offset, *pgnoaddr); - c_mp = dbmp->reginfo[n_cache].primary; - hp = R_ADDR(&dbmp->reginfo[n_cache], c_mp->htab); - hp = &hp[NBUCKET(c_mp, mf_offset, *pgnoaddr)]; - - /* Search the hash chain for the page. */ -retry: st_hsearch = 0; - MUTEX_LOCK(dbenv, hp->mtx_hash); - for (bhp = SH_TAILQ_FIRST(&hp->hash_bucket, __bh); - bhp != NULL; bhp = SH_TAILQ_NEXT(bhp, hq, __bh)) { - ++st_hsearch; - if (bhp->pgno != *pgnoaddr || bhp->mf_offset != mf_offset) - continue; - - /* - * Increment the reference count. We may discard the hash - * bucket lock as we evaluate and/or read the buffer, so we - * need to ensure it doesn't move and its contents remain - * unchanged. - */ - if (bhp->ref == UINT16_MAX) { - MUTEX_UNLOCK(dbenv, hp->mtx_hash); - - __db_err(dbenv, - "%s: page %lu: reference count overflow", - __memp_fn(dbmfp), (u_long)bhp->pgno); - ret = __db_panic(dbenv, EINVAL); - goto err; - } - ++bhp->ref; - b_incr = 1; - - /* - * BH_LOCKED -- - * I/O is in progress or sync is waiting on the buffer to write - * it. Because we've incremented the buffer reference count, - * we know the buffer can't move. Unlock the bucket lock, wait - * for the buffer to become available, reacquire the bucket. - */ - for (first = 1; F_ISSET(bhp, BH_LOCKED) && - !F_ISSET(dbenv, DB_ENV_NOLOCKING); first = 0) { - /* - * If someone is trying to sync this buffer and the - * buffer is hot, they may never get in. Give up - * and try again. - */ - if (!first && bhp->ref_sync != 0) { - --bhp->ref; - b_incr = 0; - MUTEX_UNLOCK(dbenv, hp->mtx_hash); - __os_yield(dbenv, 1); - goto retry; - } - - MUTEX_UNLOCK(dbenv, hp->mtx_hash); - /* - * Explicitly yield the processor if not the first pass - * through this loop -- if we don't, we might run to the - * end of our CPU quantum as we will simply be swapping - * between the two locks. - */ - if (!first) - __os_yield(dbenv, 1); - - MUTEX_LOCK(dbenv, bhp->mtx_bh); - /* Wait for I/O to finish... */ - MUTEX_UNLOCK(dbenv, bhp->mtx_bh); - MUTEX_LOCK(dbenv, hp->mtx_hash); - } - - ++mfp->stat.st_cache_hit; - break; - } - - /* - * Update the hash bucket search statistics -- do now because our next - * search may be for a different bucket. - */ - ++c_mp->stat.st_hash_searches; - if (st_hsearch > c_mp->stat.st_hash_longest) - c_mp->stat.st_hash_longest = st_hsearch; - c_mp->stat.st_hash_examined += st_hsearch; - - /* - * There are 4 possible paths to this location: - * - * FIRST_MISS: - * Didn't find the page in the hash bucket on our first pass: - * bhp == NULL, alloc_bhp == NULL - * - * FIRST_FOUND: - * Found the page in the hash bucket on our first pass: - * bhp != NULL, alloc_bhp == NULL - * - * SECOND_FOUND: - * Didn't find the page in the hash bucket on the first pass, - * allocated space, and found the page in the hash bucket on - * our second pass: - * bhp != NULL, alloc_bhp != NULL - * - * SECOND_MISS: - * Didn't find the page in the hash bucket on the first pass, - * allocated space, and didn't find the page in the hash bucket - * on our second pass: - * bhp == NULL, alloc_bhp != NULL - */ - state = bhp == NULL ? - (alloc_bhp == NULL ? FIRST_MISS : SECOND_MISS) : - (alloc_bhp == NULL ? FIRST_FOUND : SECOND_FOUND); - switch (state) { - case FIRST_FOUND: - /* - * If we are to free the buffer, then this had better - * be the only reference. If so, just free the buffer. - * If not, complain and get out. - */ - if (flags == DB_MPOOL_FREE) { - if (bhp->ref == 1) - return (__memp_bhfree( - dbmp, hp, bhp, BH_FREE_FREEMEM)); - __db_err(dbenv, - "File %s: freeing pinned buffer for page %lu", - __memp_fns(dbmp, mfp), (u_long)*pgnoaddr); - ret = __db_panic(dbenv, EINVAL); - goto err; - } - - /* We found the buffer in our first check -- we're done. */ - break; - case FIRST_MISS: - /* - * We didn't find the buffer in our first check. Figure out - * if the page exists, and allocate structures so we can add - * the page to the buffer pool. - */ - MUTEX_UNLOCK(dbenv, hp->mtx_hash); - - /* - * The buffer is not in the pool, so we don't need to free it. - */ - if (flags == DB_MPOOL_FREE) - return (0); - -alloc: /* - * If DB_MPOOL_NEW is set, we have to allocate a page number. - * If neither DB_MPOOL_CREATE or DB_MPOOL_CREATE is set, then - * it's an error to try and get a page past the end of file. - */ - COMPQUIET(n_cache, 0); - - extending = ret = 0; - MPOOL_SYSTEM_LOCK(dbenv); - switch (flags) { - case DB_MPOOL_NEW: - extending = 1; - if (mfp->maxpgno != 0 && - mfp->last_pgno >= mfp->maxpgno) { - __db_err(dbenv, "%s: file limited to %lu pages", - __memp_fn(dbmfp), (u_long)mfp->maxpgno); - ret = ENOSPC; - } else - *pgnoaddr = mfp->last_pgno + 1; - break; - case DB_MPOOL_CREATE: - if (mfp->maxpgno != 0 && *pgnoaddr > mfp->maxpgno) { - __db_err(dbenv, "%s: file limited to %lu pages", - __memp_fn(dbmfp), (u_long)mfp->maxpgno); - ret = ENOSPC; - } else - extending = *pgnoaddr > mfp->last_pgno; - break; - default: - ret = *pgnoaddr > mfp->last_pgno ? DB_PAGE_NOTFOUND : 0; - break; - } - MPOOL_SYSTEM_UNLOCK(dbenv); - if (ret != 0) - goto err; - - /* - * !!! - * In the DB_MPOOL_NEW code path, mf_offset and n_cache have - * not yet been initialized. - */ - mf_offset = R_OFFSET(dbmp->reginfo, mfp); - n_cache = NCACHE(mp, mf_offset, *pgnoaddr); - c_mp = dbmp->reginfo[n_cache].primary; - - /* Allocate a new buffer header and data space. */ - if ((ret = __memp_alloc(dbmp, - &dbmp->reginfo[n_cache], mfp, 0, NULL, &alloc_bhp)) != 0) - goto err; -#ifdef DIAGNOSTIC - if ((uintptr_t)alloc_bhp->buf & (sizeof(size_t) - 1)) { - __db_err(dbenv, - "DB_MPOOLFILE->get: buffer data is NOT size_t aligned"); - ret = __db_panic(dbenv, EINVAL); - goto err; - } -#endif - /* - * If we are extending the file, we'll need the region lock - * again. - */ - if (extending) - MPOOL_SYSTEM_LOCK(dbenv); - - /* - * DB_MPOOL_NEW does not guarantee you a page unreferenced by - * any other thread of control. (That guarantee is interesting - * for DB_MPOOL_NEW, unlike DB_MPOOL_CREATE, because the caller - * did not specify the page number, and so, may reasonably not - * have any way to lock the page outside of mpool.) Regardless, - * if we allocate the page, and some other thread of control - * requests the page by number, we will not detect that and the - * thread of control that allocated using DB_MPOOL_NEW may not - * have a chance to initialize the page. (Note: we *could* - * detect this case if we set a flag in the buffer header which - * guaranteed that no gets of the page would succeed until the - * reference count went to 0, that is, until the creating page - * put the page.) What we do guarantee is that if two threads - * of control are both doing DB_MPOOL_NEW calls, they won't - * collide, that is, they won't both get the same page. - * - * There's a possibility that another thread allocated the page - * we were planning to allocate while we were off doing buffer - * allocation. We can do that by making sure the page number - * we were going to use is still available. If it's not, then - * we check to see if the next available page number hashes to - * the same mpool region as the old one -- if it does, we can - * continue, otherwise, we have to start over. - */ - if (flags == DB_MPOOL_NEW && *pgnoaddr != mfp->last_pgno + 1) { - *pgnoaddr = mfp->last_pgno + 1; - if (n_cache != NCACHE(mp, mf_offset, *pgnoaddr)) { - /* - * flags == DB_MPOOL_NEW, so extending is set - * and we're holding the region locked. - */ - MPOOL_SYSTEM_UNLOCK(dbenv); - - MPOOL_REGION_LOCK( - dbenv, &dbmp->reginfo[n_cache]); - __db_shalloc_free( - &dbmp->reginfo[n_cache], alloc_bhp); - c_mp->stat.st_pages--; - MPOOL_REGION_UNLOCK( - dbenv, &dbmp->reginfo[n_cache]); - - alloc_bhp = NULL; - goto alloc; - } - } - - /* - * We released the region lock, so another thread might have - * extended the file. Update the last_pgno and initialize - * the file, as necessary, if we extended the file. - */ - if (extending) { - if (*pgnoaddr > mfp->last_pgno) - mfp->last_pgno = *pgnoaddr; - - MPOOL_SYSTEM_UNLOCK(dbenv); - if (ret != 0) - goto err; - } - goto hb_search; - case SECOND_FOUND: - /* - * We allocated buffer space for the requested page, but then - * found the page in the buffer cache on our second check. - * That's OK -- we can use the page we found in the pool, - * unless DB_MPOOL_NEW is set. - * - * Free the allocated memory, we no longer need it. Since we - * can't acquire the region lock while holding the hash bucket - * lock, we have to release the hash bucket and re-acquire it. - * That's OK, because we have the buffer pinned down. - */ - MUTEX_UNLOCK(dbenv, hp->mtx_hash); - MPOOL_REGION_LOCK(dbenv, &dbmp->reginfo[n_cache]); - __db_shalloc_free(&dbmp->reginfo[n_cache], alloc_bhp); - c_mp->stat.st_pages--; - alloc_bhp = NULL; - MPOOL_REGION_UNLOCK(dbenv, &dbmp->reginfo[n_cache]); - - /* - * We can't use the page we found in the pool if DB_MPOOL_NEW - * was set. (For details, see the above comment beginning - * "DB_MPOOL_NEW does not guarantee you a page unreferenced by - * any other thread of control".) If DB_MPOOL_NEW is set, we - * release our pin on this particular buffer, and try to get - * another one. - */ - if (flags == DB_MPOOL_NEW) { - --bhp->ref; - b_incr = 0; - goto alloc; - } - - /* We can use the page -- get the bucket lock. */ - MUTEX_LOCK(dbenv, hp->mtx_hash); - break; - case SECOND_MISS: - /* - * We allocated buffer space for the requested page, and found - * the page still missing on our second pass through the buffer - * cache. Instantiate the page. - */ - bhp = alloc_bhp; - alloc_bhp = NULL; - - /* - * Initialize all the BH and hash bucket fields so we can call - * __memp_bhfree if an error occurs. - * - * Append the buffer to the tail of the bucket list and update - * the hash bucket's priority. - */ - b_incr = 1; - - /*lint --e{668} (flexelint: bhp cannot be NULL). */ - memset(bhp, 0, sizeof(BH)); - bhp->ref = 1; - bhp->priority = UINT32_MAX; - bhp->pgno = *pgnoaddr; - bhp->mf_offset = mf_offset; - SH_TAILQ_INSERT_TAIL(&hp->hash_bucket, bhp, hq); - - /* - * Allocate the mutex. This is the last BH initialization step, - * because it's the only one that can fail, and everything else - * must be set up or we can't jump to the err label because it - * will call __memp_bhfree. - */ - if ((ret = __mutex_alloc( - dbenv, MTX_MPOOL_BUFFER, 0, &bhp->mtx_bh)) != 0) - goto err; - - hp->hash_priority = - SH_TAILQ_FIRSTP(&hp->hash_bucket, __bh)->priority; - - /* If we extended the file, make sure the page is never lost. */ - if (extending) { - ++hp->hash_page_dirty; - F_SET(bhp, BH_DIRTY | BH_DIRTY_CREATE); - } - - /* - * If we created the page, zero it out. If we didn't create - * the page, read from the backing file. - * - * !!! - * DB_MPOOL_NEW doesn't call the pgin function. - * - * If DB_MPOOL_CREATE is used, then the application's pgin - * function has to be able to handle pages of 0's -- if it - * uses DB_MPOOL_NEW, it can detect all of its page creates, - * and not bother. - * - * If we're running in diagnostic mode, smash any bytes on the - * page that are unknown quantities for the caller. - * - * Otherwise, read the page into memory, optionally creating it - * if DB_MPOOL_CREATE is set. - */ - if (extending) { - if (mfp->clear_len == DB_CLEARLEN_NOTSET) - memset(bhp->buf, 0, mfp->stat.st_pagesize); - else { - memset(bhp->buf, 0, mfp->clear_len); -#if defined(DIAGNOSTIC) || defined(UMRW) - memset(bhp->buf + mfp->clear_len, CLEAR_BYTE, - mfp->stat.st_pagesize - mfp->clear_len); -#endif - } - - if (flags == DB_MPOOL_CREATE && mfp->ftype != 0) - F_SET(bhp, BH_CALLPGIN); - - ++mfp->stat.st_page_create; - } else { - F_SET(bhp, BH_TRASH); - ++mfp->stat.st_cache_miss; - } - - /* Increment buffer count referenced by MPOOLFILE. */ - MUTEX_LOCK(dbenv, mfp->mutex); - ++mfp->block_cnt; - MUTEX_UNLOCK(dbenv, mfp->mutex); - } - - DB_ASSERT(bhp->ref != 0); - - /* - * If we're the only reference, update buffer and bucket priorities. - * We may be about to release the hash bucket lock, and everything - * should be correct, first. (We've already done this if we created - * the buffer, so there is no need to do it again.) - */ - if (state != SECOND_MISS && bhp->ref == 1) { - bhp->priority = UINT32_MAX; - SH_TAILQ_REMOVE(&hp->hash_bucket, bhp, hq, __bh); - SH_TAILQ_INSERT_TAIL(&hp->hash_bucket, bhp, hq); - hp->hash_priority = - SH_TAILQ_FIRSTP(&hp->hash_bucket, __bh)->priority; - } - - /* - * BH_TRASH -- - * The buffer we found may need to be filled from the disk. - * - * It's possible for the read function to fail, which means we fail as - * well. Note, the __memp_pgread() function discards and reacquires - * the hash lock, so the buffer must be pinned down so that it cannot - * move and its contents are unchanged. Discard the buffer on failure - * unless another thread is waiting on our I/O to complete. It's OK to - * leave the buffer around, as the waiting thread will see the BH_TRASH - * flag set, and will also attempt to discard it. If there's a waiter, - * we need to decrement our reference count. - */ - if (F_ISSET(bhp, BH_TRASH) && - (ret = __memp_pgread(dbmfp, - hp->mtx_hash, bhp, LF_ISSET(DB_MPOOL_CREATE) ? 1 : 0)) != 0) - goto err; - - /* - * BH_CALLPGIN -- - * The buffer was processed for being written to disk, and now has - * to be re-converted for use. - */ - if (F_ISSET(bhp, BH_CALLPGIN)) { - if ((ret = __memp_pg(dbmfp, bhp, 1)) != 0) - goto err; - F_CLR(bhp, BH_CALLPGIN); - } -#ifdef DIAGNOSTIC - __memp_check_order(hp); -#endif - - MUTEX_UNLOCK(dbenv, hp->mtx_hash); - -#ifdef DIAGNOSTIC - /* Update the file's pinned reference count. */ - MPOOL_SYSTEM_LOCK(dbenv); - ++dbmfp->pinref; - MPOOL_SYSTEM_UNLOCK(dbenv); - - /* - * We want to switch threads as often as possible, and at awkward - * times. Yield every time we get a new page to ensure contention. - */ - if (F_ISSET(dbenv, DB_ENV_YIELDCPU)) - __os_yield(dbenv, 1); -#endif - - *(void **)addrp = bhp->buf; - return (0); - -err: /* - * Discard our reference. If we're the only reference, discard the - * the buffer entirely. If we held a reference to a buffer, we are - * also still holding the hash bucket mutex. - */ - if (b_incr) { - if (bhp->ref == 1) - (void)__memp_bhfree(dbmp, hp, bhp, BH_FREE_FREEMEM); - else { - --bhp->ref; - MUTEX_UNLOCK(dbenv, hp->mtx_hash); - } - } - - /* If alloc_bhp is set, free the memory. */ - if (alloc_bhp != NULL) { - MPOOL_REGION_LOCK(dbenv, &dbmp->reginfo[n_cache]); - __db_shalloc_free(&dbmp->reginfo[n_cache], alloc_bhp); - c_mp->stat.st_pages--; - MPOOL_REGION_UNLOCK(dbenv, &dbmp->reginfo[n_cache]); - } - - return (ret); -} diff --git a/storage/bdb/mp/mp_fmethod.c b/storage/bdb/mp/mp_fmethod.c deleted file mode 100644 index 6fc5d5719f2..00000000000 --- a/storage/bdb/mp/mp_fmethod.c +++ /dev/null @@ -1,552 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: mp_fmethod.c,v 12.7 2005/10/07 20:21:32 ubell Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_shash.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" - -static int __memp_get_clear_len __P((DB_MPOOLFILE *, u_int32_t *)); -static int __memp_get_lsn_offset __P((DB_MPOOLFILE *, int32_t *)); -static int __memp_get_maxsize __P((DB_MPOOLFILE *, u_int32_t *, u_int32_t *)); -static int __memp_set_maxsize __P((DB_MPOOLFILE *, u_int32_t, u_int32_t)); -static int __memp_get_pgcookie __P((DB_MPOOLFILE *, DBT *)); -static int __memp_get_priority __P((DB_MPOOLFILE *, DB_CACHE_PRIORITY *)); -static int __memp_set_priority __P((DB_MPOOLFILE *, DB_CACHE_PRIORITY)); - -/* - * __memp_fcreate_pp -- - * DB_ENV->memp_fcreate pre/post processing. - * - * PUBLIC: int __memp_fcreate_pp __P((DB_ENV *, DB_MPOOLFILE **, u_int32_t)); - */ -int -__memp_fcreate_pp(dbenv, retp, flags) - DB_ENV *dbenv; - DB_MPOOLFILE **retp; - u_int32_t flags; -{ - DB_THREAD_INFO *ip; - int ret; - - PANIC_CHECK(dbenv); - - /* Validate arguments. */ - if ((ret = __db_fchk(dbenv, "DB_ENV->memp_fcreate", flags, 0)) != 0) - return (ret); - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, (__memp_fcreate(dbenv, retp)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __memp_fcreate -- - * DB_ENV->memp_fcreate. - * - * PUBLIC: int __memp_fcreate __P((DB_ENV *, DB_MPOOLFILE **)); - */ -int -__memp_fcreate(dbenv, retp) - DB_ENV *dbenv; - DB_MPOOLFILE **retp; -{ - DB_MPOOLFILE *dbmfp; - int ret; - - /* Allocate and initialize the per-process structure. */ - if ((ret = __os_calloc(dbenv, 1, sizeof(DB_MPOOLFILE), &dbmfp)) != 0) - return (ret); - - dbmfp->ref = 1; - dbmfp->lsn_offset = -1; - dbmfp->dbenv = dbenv; - dbmfp->mfp = INVALID_ROFF; - - dbmfp->close = __memp_fclose_pp; - dbmfp->get = __memp_fget_pp; - dbmfp->get_clear_len = __memp_get_clear_len; - dbmfp->get_fileid = __memp_get_fileid; - dbmfp->get_flags = __memp_get_flags; - dbmfp->get_ftype = __memp_get_ftype; - dbmfp->get_lsn_offset = __memp_get_lsn_offset; - dbmfp->get_maxsize = __memp_get_maxsize; - dbmfp->get_pgcookie = __memp_get_pgcookie; - dbmfp->get_priority = __memp_get_priority; - dbmfp->open = __memp_fopen_pp; - dbmfp->put = __memp_fput_pp; - dbmfp->set = __memp_fset_pp; - dbmfp->set_clear_len = __memp_set_clear_len; - dbmfp->set_fileid = __memp_set_fileid; - dbmfp->set_flags = __memp_set_flags; - dbmfp->set_ftype = __memp_set_ftype; - dbmfp->set_lsn_offset = __memp_set_lsn_offset; - dbmfp->set_maxsize = __memp_set_maxsize; - dbmfp->set_pgcookie = __memp_set_pgcookie; - dbmfp->set_priority = __memp_set_priority; - dbmfp->sync = __memp_fsync_pp; - - *retp = dbmfp; - return (0); -} - -/* - * __memp_get_clear_len -- - * Get the clear length. - */ -static int -__memp_get_clear_len(dbmfp, clear_lenp) - DB_MPOOLFILE *dbmfp; - u_int32_t *clear_lenp; -{ - *clear_lenp = dbmfp->clear_len; - return (0); -} - -/* - * __memp_set_clear_len -- - * DB_MPOOLFILE->set_clear_len. - * - * PUBLIC: int __memp_set_clear_len __P((DB_MPOOLFILE *, u_int32_t)); - */ -int -__memp_set_clear_len(dbmfp, clear_len) - DB_MPOOLFILE *dbmfp; - u_int32_t clear_len; -{ - MPF_ILLEGAL_AFTER_OPEN(dbmfp, "DB_MPOOLFILE->set_clear_len"); - - dbmfp->clear_len = clear_len; - return (0); -} - -/* - * __memp_get_fileid -- - * DB_MPOOLFILE->get_fileid. - * - * PUBLIC: int __memp_get_fileid __P((DB_MPOOLFILE *, u_int8_t *)); - */ -int -__memp_get_fileid(dbmfp, fileid) - DB_MPOOLFILE *dbmfp; - u_int8_t *fileid; -{ - if (!F_ISSET(dbmfp, MP_FILEID_SET)) { - __db_err(dbmfp->dbenv, "get_fileid: file ID not set"); - return (EINVAL); - } - - memcpy(fileid, dbmfp->fileid, DB_FILE_ID_LEN); - return (0); -} - -/* - * __memp_set_fileid -- - * DB_MPOOLFILE->set_fileid. - * - * PUBLIC: int __memp_set_fileid __P((DB_MPOOLFILE *, u_int8_t *)); - */ -int -__memp_set_fileid(dbmfp, fileid) - DB_MPOOLFILE *dbmfp; - u_int8_t *fileid; -{ - MPF_ILLEGAL_AFTER_OPEN(dbmfp, "DB_MPOOLFILE->set_fileid"); - - memcpy(dbmfp->fileid, fileid, DB_FILE_ID_LEN); - F_SET(dbmfp, MP_FILEID_SET); - - return (0); -} - -/* - * __memp_get_flags -- - * Get the DB_MPOOLFILE flags; - * - * PUBLIC: int __memp_get_flags __P((DB_MPOOLFILE *, u_int32_t *)); - */ -int -__memp_get_flags(dbmfp, flagsp) - DB_MPOOLFILE *dbmfp; - u_int32_t *flagsp; -{ - MPOOLFILE *mfp; - - mfp = dbmfp->mfp; - - *flagsp = 0; - - if (mfp == NULL) - *flagsp = FLD_ISSET(dbmfp->config_flags, - DB_MPOOL_NOFILE | DB_MPOOL_UNLINK); - else { - if (mfp->no_backing_file) - FLD_SET(*flagsp, DB_MPOOL_NOFILE); - if (mfp->unlink_on_close) - FLD_SET(*flagsp, DB_MPOOL_UNLINK); - } - return (0); -} - -/* - * __memp_set_flags -- - * Set the DB_MPOOLFILE flags; - * - * PUBLIC: int __memp_set_flags __P((DB_MPOOLFILE *, u_int32_t, int)); - */ -int -__memp_set_flags(dbmfp, flags, onoff) - DB_MPOOLFILE *dbmfp; - u_int32_t flags; - int onoff; -{ - DB_ENV *dbenv; - MPOOLFILE *mfp; - int ret; - - dbenv = dbmfp->dbenv; - mfp = dbmfp->mfp; - - switch (flags) { - case DB_MPOOL_NOFILE: - if (mfp == NULL) - if (onoff) - FLD_SET(dbmfp->config_flags, DB_MPOOL_NOFILE); - else - FLD_CLR(dbmfp->config_flags, DB_MPOOL_NOFILE); - else - mfp->no_backing_file = onoff; - break; - case DB_MPOOL_UNLINK: - if (mfp == NULL) - if (onoff) - FLD_SET(dbmfp->config_flags, DB_MPOOL_UNLINK); - else - FLD_CLR(dbmfp->config_flags, DB_MPOOL_UNLINK); - else - mfp->unlink_on_close = onoff; - break; - default: - if ((ret = __db_fchk(dbenv, "DB_MPOOLFILE->set_flags", - flags, DB_MPOOL_NOFILE | DB_MPOOL_UNLINK)) != 0) - return (ret); - break; - } - return (0); -} - -/* - * __memp_get_ftype -- - * Get the file type (as registered). - * - * PUBLIC: int __memp_get_ftype __P((DB_MPOOLFILE *, int *)); - */ -int -__memp_get_ftype(dbmfp, ftypep) - DB_MPOOLFILE *dbmfp; - int *ftypep; -{ - *ftypep = dbmfp->ftype; - return (0); -} - -/* - * __memp_set_ftype -- - * DB_MPOOLFILE->set_ftype. - * - * PUBLIC: int __memp_set_ftype __P((DB_MPOOLFILE *, int)); - */ -int -__memp_set_ftype(dbmfp, ftype) - DB_MPOOLFILE *dbmfp; - int ftype; -{ - MPF_ILLEGAL_AFTER_OPEN(dbmfp, "DB_MPOOLFILE->set_ftype"); - - dbmfp->ftype = ftype; - return (0); -} - -/* - * __memp_get_lsn_offset -- - * Get the page's LSN offset. - */ -static int -__memp_get_lsn_offset(dbmfp, lsn_offsetp) - DB_MPOOLFILE *dbmfp; - int32_t *lsn_offsetp; -{ - *lsn_offsetp = dbmfp->lsn_offset; - return (0); -} - -/* - * __memp_set_lsn_offset -- - * Set the page's LSN offset. - * - * PUBLIC: int __memp_set_lsn_offset __P((DB_MPOOLFILE *, int32_t)); - */ -int -__memp_set_lsn_offset(dbmfp, lsn_offset) - DB_MPOOLFILE *dbmfp; - int32_t lsn_offset; -{ - MPF_ILLEGAL_AFTER_OPEN(dbmfp, "DB_MPOOLFILE->set_lsn_offset"); - - dbmfp->lsn_offset = lsn_offset; - return (0); -} - -/* - * __memp_get_maxsize -- - * Get the file's maximum size. - */ -static int -__memp_get_maxsize(dbmfp, gbytesp, bytesp) - DB_MPOOLFILE *dbmfp; - u_int32_t *gbytesp, *bytesp; -{ - DB_ENV *dbenv; - MPOOLFILE *mfp; - - if ((mfp = dbmfp->mfp) == NULL) { - *gbytesp = dbmfp->gbytes; - *bytesp = dbmfp->bytes; - } else { - dbenv = dbmfp->dbenv; - - MPOOL_SYSTEM_LOCK(dbenv); - *gbytesp = (u_int32_t) - (mfp->maxpgno / (GIGABYTE / mfp->stat.st_pagesize)); - *bytesp = (u_int32_t) - ((mfp->maxpgno % (GIGABYTE / mfp->stat.st_pagesize)) * - mfp->stat.st_pagesize); - MPOOL_SYSTEM_UNLOCK(dbenv); - } - - return (0); -} - -/* - * __memp_set_maxsize -- - * Set the file's maximum size. - */ -static int -__memp_set_maxsize(dbmfp, gbytes, bytes) - DB_MPOOLFILE *dbmfp; - u_int32_t gbytes, bytes; -{ - DB_ENV *dbenv; - MPOOLFILE *mfp; - - if ((mfp = dbmfp->mfp) == NULL) { - dbmfp->gbytes = gbytes; - dbmfp->bytes = bytes; - } else { - dbenv = dbmfp->dbenv; - - MPOOL_SYSTEM_LOCK(dbenv); - mfp->maxpgno = (db_pgno_t) - (gbytes * (GIGABYTE / mfp->stat.st_pagesize)); - mfp->maxpgno += (db_pgno_t) - ((bytes + mfp->stat.st_pagesize - 1) / - mfp->stat.st_pagesize); - MPOOL_SYSTEM_UNLOCK(dbenv); - } - - return (0); -} - -/* - * __memp_get_pgcookie -- - * Get the pgin/pgout cookie. - */ -static int -__memp_get_pgcookie(dbmfp, pgcookie) - DB_MPOOLFILE *dbmfp; - DBT *pgcookie; -{ - if (dbmfp->pgcookie == NULL) { - pgcookie->size = 0; - pgcookie->data = ""; - } else - memcpy(pgcookie, dbmfp->pgcookie, sizeof(DBT)); - return (0); -} - -/* - * __memp_set_pgcookie -- - * Set the pgin/pgout cookie. - * - * PUBLIC: int __memp_set_pgcookie __P((DB_MPOOLFILE *, DBT *)); - */ -int -__memp_set_pgcookie(dbmfp, pgcookie) - DB_MPOOLFILE *dbmfp; - DBT *pgcookie; -{ - DB_ENV *dbenv; - DBT *cookie; - int ret; - - MPF_ILLEGAL_AFTER_OPEN(dbmfp, "DB_MPOOLFILE->set_pgcookie"); - dbenv = dbmfp->dbenv; - - if ((ret = __os_calloc(dbenv, 1, sizeof(*cookie), &cookie)) != 0) - return (ret); - if ((ret = __os_malloc(dbenv, pgcookie->size, &cookie->data)) != 0) { - __os_free(dbenv, cookie); - return (ret); - } - - memcpy(cookie->data, pgcookie->data, pgcookie->size); - cookie->size = pgcookie->size; - - dbmfp->pgcookie = cookie; - return (0); -} - -/* - * __memp_get_priority -- - * Set the cache priority for pages from this file. - */ -static int -__memp_get_priority(dbmfp, priorityp) - DB_MPOOLFILE *dbmfp; - DB_CACHE_PRIORITY *priorityp; -{ - switch (dbmfp->priority) { - case MPOOL_PRI_VERY_LOW: - *priorityp = DB_PRIORITY_VERY_LOW; - break; - case MPOOL_PRI_LOW: - *priorityp = DB_PRIORITY_LOW; - break; - case MPOOL_PRI_DEFAULT: - *priorityp = DB_PRIORITY_DEFAULT; - break; - case MPOOL_PRI_HIGH: - *priorityp = DB_PRIORITY_HIGH; - break; - case MPOOL_PRI_VERY_HIGH: - *priorityp = DB_PRIORITY_VERY_HIGH; - break; - default: - __db_err(dbmfp->dbenv, - "DB_MPOOLFILE->get_priority: unknown priority value: %d", - dbmfp->priority); - return (EINVAL); - } - - return (0); -} - -/* - * __memp_set_priority -- - * Set the cache priority for pages from this file. - */ -static int -__memp_set_priority(dbmfp, priority) - DB_MPOOLFILE *dbmfp; - DB_CACHE_PRIORITY priority; -{ - switch (priority) { - case DB_PRIORITY_VERY_LOW: - dbmfp->priority = MPOOL_PRI_VERY_LOW; - break; - case DB_PRIORITY_LOW: - dbmfp->priority = MPOOL_PRI_LOW; - break; - case DB_PRIORITY_DEFAULT: - dbmfp->priority = MPOOL_PRI_DEFAULT; - break; - case DB_PRIORITY_HIGH: - dbmfp->priority = MPOOL_PRI_HIGH; - break; - case DB_PRIORITY_VERY_HIGH: - dbmfp->priority = MPOOL_PRI_VERY_HIGH; - break; - default: - __db_err(dbmfp->dbenv, - "DB_MPOOLFILE->set_priority: unknown priority value: %d", - priority); - return (EINVAL); - } - - /* Update the underlying file if we've already opened it. */ - if (dbmfp->mfp != NULL) - dbmfp->mfp->priority = dbmfp->priority; - - return (0); -} - -/* - * __memp_last_pgno -- - * Return the page number of the last page in the file. - * - * !!! - * Undocumented interface: DB private. - * - * PUBLIC: int __memp_last_pgno __P((DB_MPOOLFILE *, db_pgno_t *)); - */ -int -__memp_last_pgno(dbmfp, pgnoaddr) - DB_MPOOLFILE *dbmfp; - db_pgno_t *pgnoaddr; -{ - DB_ENV *dbenv; - - dbenv = dbmfp->dbenv; - - MPOOL_SYSTEM_LOCK(dbenv); - *pgnoaddr = dbmfp->mfp->last_pgno; - MPOOL_SYSTEM_UNLOCK(dbenv); - - return (0); -} - -/* - * __memp_fn -- - * On errors we print whatever is available as the file name. - * - * PUBLIC: char * __memp_fn __P((DB_MPOOLFILE *)); - */ -char * -__memp_fn(dbmfp) - DB_MPOOLFILE *dbmfp; -{ - return (__memp_fns(dbmfp->dbenv->mp_handle, dbmfp->mfp)); -} - -/* - * __memp_fns -- - * On errors we print whatever is available as the file name. - * - * PUBLIC: char * __memp_fns __P((DB_MPOOL *, MPOOLFILE *)); - * - */ -char * -__memp_fns(dbmp, mfp) - DB_MPOOL *dbmp; - MPOOLFILE *mfp; -{ - if (mfp->path_off == 0) - return ((char *)"temporary"); - - return ((char *)R_ADDR(dbmp->reginfo, mfp->path_off)); -} diff --git a/storage/bdb/mp/mp_fopen.c b/storage/bdb/mp/mp_fopen.c deleted file mode 100644 index 04103371ab9..00000000000 --- a/storage/bdb/mp/mp_fopen.c +++ /dev/null @@ -1,970 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: mp_fopen.c,v 12.16 2005/10/31 02:22:31 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_shash.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" - -/* - * __memp_fopen_pp -- - * DB_MPOOLFILE->open pre/post processing. - * - * PUBLIC: int __memp_fopen_pp - * PUBLIC: __P((DB_MPOOLFILE *, const char *, u_int32_t, int, size_t)); - */ -int -__memp_fopen_pp(dbmfp, path, flags, mode, pagesize) - DB_MPOOLFILE *dbmfp; - const char *path; - u_int32_t flags; - int mode; - size_t pagesize; -{ - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int ret; - - dbenv = dbmfp->dbenv; - - PANIC_CHECK(dbenv); - - /* Validate arguments. */ - if ((ret = __db_fchk(dbenv, "DB_MPOOLFILE->open", flags, - DB_CREATE | DB_DIRECT | DB_EXTENT | - DB_NOMMAP | DB_ODDFILESIZE | DB_RDONLY | DB_TRUNCATE)) != 0) - return (ret); - - /* - * Require a non-zero, power-of-two pagesize, smaller than the - * clear length. - */ - if (pagesize == 0 || !POWER_OF_TWO(pagesize)) { - __db_err(dbenv, - "DB_MPOOLFILE->open: page sizes must be a power-of-2"); - return (EINVAL); - } - if (dbmfp->clear_len > pagesize) { - __db_err(dbenv, - "DB_MPOOLFILE->open: clear length larger than page size"); - return (EINVAL); - } - - /* Read-only checks, and local flag. */ - if (LF_ISSET(DB_RDONLY) && path == NULL) { - __db_err(dbenv, - "DB_MPOOLFILE->open: temporary files can't be readonly"); - return (EINVAL); - } - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, - (__memp_fopen(dbmfp, NULL, path, flags, mode, pagesize)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __memp_fopen -- - * DB_MPOOLFILE->open. - * - * PUBLIC: int __memp_fopen __P((DB_MPOOLFILE *, - * PUBLIC: MPOOLFILE *, const char *, u_int32_t, int, size_t)); - */ -int -__memp_fopen(dbmfp, mfp, path, flags, mode, pgsize) - DB_MPOOLFILE *dbmfp; - MPOOLFILE *mfp; - const char *path; - u_int32_t flags; - int mode; - size_t pgsize; -{ - DB_ENV *dbenv; - DB_MPOOL *dbmp; - DB_MPOOLFILE *tmp_dbmfp; - MPOOL *mp; - db_pgno_t last_pgno; - size_t maxmap; - u_int32_t mbytes, bytes, oflags, pagesize; - int created_fileid, refinc, ret; - char *rpath; - void *p; - - dbenv = dbmfp->dbenv; - dbmp = dbenv->mp_handle; - mp = dbmp->reginfo[0].primary; - created_fileid = refinc = ret = 0; - rpath = NULL; - - /* - * We're keeping the page size as a size_t in the public API, but - * it's a u_int32_t everywhere internally. - */ - pagesize = (u_int32_t)pgsize; - - /* - * We're called internally with a specified mfp, in which case the - * path is NULL, but we'll get the path from the underlying region - * information. Otherwise, if the path is NULL, it's a temporary - * file -- we know we can't join any existing files, and we'll delay - * the open until we actually need to write the file. - */ - DB_ASSERT(mfp == NULL || path == NULL); - - /* If this handle is already open, return. */ - if (F_ISSET(dbmfp, MP_OPEN_CALLED)) - return (0); - - if (path == NULL && mfp == NULL) - goto alloc; - - /* - * If there's no backing file, we can join existing files in the cache, - * but there's nothing to read from disk. - */ - if (FLD_ISSET(dbmfp->config_flags, DB_MPOOL_NOFILE)) - goto check_mpoolfile; - - /* - * Our caller may be able to tell us which underlying MPOOLFILE we - * need a handle for. - */ - if (mfp != NULL) { - /* - * Deadfile can only be set if mpf_cnt goes to zero (or if we - * failed creating the file DB_AM_DISCARD). Increment the ref - * count so the file cannot become dead and be unlinked. - */ - MUTEX_LOCK(dbenv, mfp->mutex); - if (!mfp->deadfile) { - ++mfp->mpf_cnt; - refinc = 1; - } - MUTEX_UNLOCK(dbenv, mfp->mutex); - - /* - * Test one last time to see if the file is dead -- it may have - * been removed. This happens when a checkpoint trying to open - * the file to flush a buffer races with the Db::remove method. - * The error will be ignored, so don't output an error message. - */ - if (mfp->deadfile) - return (EINVAL); - } - - /* Convert MP open flags to DB OS-layer open flags. */ - oflags = 0; - if (LF_ISSET(DB_CREATE)) - oflags |= DB_OSO_CREATE; - if (LF_ISSET(DB_DIRECT)) - oflags |= DB_OSO_DIRECT; - if (LF_ISSET(DB_RDONLY)) { - F_SET(dbmfp, MP_READONLY); - oflags |= DB_OSO_RDONLY; - } - - /* - * XXX - * A grievous layering violation, the DB_DSYNC_DB flag was left in - * the DB_ENV structure and not driven through the cache API. This - * needs to be fixed when the general API configuration is fixed. - */ - if (F_ISSET(dbenv, DB_ENV_DSYNC_DB)) - oflags |= DB_OSO_DSYNC; - - /* - * Get the real name for this file and open it. - * - * Supply a page size so os_open can decide whether to turn buffering - * off if the DB_DIRECT_DB flag is set. - * - * Acquire the region lock if we're using a path from an underlying - * MPOOLFILE -- there's a race in accessing the path name stored in - * the region, __memp_nameop may be simultaneously renaming the file. - */ - if (mfp != NULL) { - MPOOL_SYSTEM_LOCK(dbenv); - path = R_ADDR(dbmp->reginfo, mfp->path_off); - } - if ((ret = - __db_appname(dbenv, DB_APP_DATA, path, 0, NULL, &rpath)) == 0) - ret = __os_open_extend(dbenv, - rpath, (u_int32_t)pagesize, oflags, mode, &dbmfp->fhp); - if (mfp != NULL) - MPOOL_SYSTEM_UNLOCK(dbenv); - - if (ret != 0) { - /* If it's a Queue extent file, it may not exist, that's OK. */ - if (!LF_ISSET(DB_EXTENT)) - __db_err(dbenv, "%s: %s", rpath, db_strerror(ret)); - goto err; - } - - /* - * Cache file handles are shared, and have mutexes to protect the - * underlying file handle across seek and read/write calls. - */ - dbmfp->fhp->ref = 1; - if ((ret = __mutex_alloc( - dbenv, MTX_MPOOL_FH, DB_MUTEX_THREAD, &dbmfp->fhp->mtx_fh)) != 0) - goto err; - - /* - * Figure out the file's size. - * - * !!! - * We can't use off_t's here, or in any code in the mainline library - * for that matter. (We have to use them in the os stubs, of course, - * as there are system calls that take them as arguments.) The reason - * is some customers build in environments where an off_t is 32-bits, - * but still run where offsets are 64-bits, and they pay us a lot of - * money. - */ - if ((ret = __os_ioinfo( - dbenv, rpath, dbmfp->fhp, &mbytes, &bytes, NULL)) != 0) { - __db_err(dbenv, "%s: %s", rpath, db_strerror(ret)); - goto err; - } - - /* - * Get the file id if we weren't given one. Generated file id's - * don't use timestamps, otherwise there'd be no chance of any - * other process joining the party. - */ - if (!F_ISSET(dbmfp, MP_FILEID_SET)) { - if ((ret = __os_fileid(dbenv, rpath, 0, dbmfp->fileid)) != 0) - goto err; - created_fileid = 1; - } - - if (mfp != NULL) - goto have_mfp; - -check_mpoolfile: - /* - * Walk the list of MPOOLFILE's, looking for a matching file. - * - * The fileID is a filesystem unique number (e.g., a UNIX dev/inode - * pair) plus a timestamp. If files are removed and created in less - * than a second, the fileID can be repeated. The problem with - * repetition happens when the file that previously had the fileID - * value still has pages in the pool, since we don't want to use them - * to satisfy requests for the new file. - * - * Because the DB_TRUNCATE flag reuses the dev/inode pair, repeated - * opens with that flag set guarantees matching fileIDs when the - * machine can open a file and then re-open with truncate within a - * second. For this reason, we pass that flag down, and, if we find - * a matching entry, we ensure that it's never found again, and we - * create a new entry for the current request. - */ - MPOOL_SYSTEM_LOCK(dbenv); - for (mfp = SH_TAILQ_FIRST(&mp->mpfq, __mpoolfile); - mfp != NULL; mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile)) { - /* Skip dead files and temporary files. */ - if (mfp->deadfile || F_ISSET(mfp, MP_TEMP)) - continue; - - /* - * Any remaining DB_MPOOL_NOFILE databases are in-memory - * named databases and need only match other in-memory - * databases with the same name. - */ - if (FLD_ISSET(dbmfp->config_flags, DB_MPOOL_NOFILE)) { - if (!mfp->no_backing_file) - continue; - - if (strcmp(path, R_ADDR(dbmp->reginfo, mfp->path_off))) - continue; - - /* - * We matched an in-memory file; grab the fileid if - * it is set in the region, but not in the dbmfp. - */ - if (!F_ISSET(dbmfp, MP_FILEID_SET)) - __memp_set_fileid(dbmfp, - R_ADDR(dbmp->reginfo, mfp->fileid_off)); - } else - if (memcmp(dbmfp->fileid, R_ADDR(dbmp->reginfo, - mfp->fileid_off), DB_FILE_ID_LEN) != 0) - continue; - - /* - * If the file is being truncated, remove it from the system - * and create a new entry. - * - * !!! - * We should be able to set mfp to NULL and break out of the - * loop, but I like the idea of checking all the entries. - */ - if (LF_ISSET(DB_TRUNCATE)) { - MUTEX_LOCK(dbenv, mfp->mutex); - mfp->deadfile = 1; - MUTEX_UNLOCK(dbenv, mfp->mutex); - continue; - } - - /* - * Some things about a file cannot be changed: the clear length, - * page size, or LSN location. However, if this is an attempt - * to open a named in-memory file, we may not yet have that - * information. so accept uninitialized entries. - * - * The file type can change if the application's pre- and post- - * processing needs change. For example, an application that - * created a hash subdatabase in a database that was previously - * all btree. - * - * !!! - * We do not check to see if the pgcookie information changed, - * or update it if it is. - */ - if ((dbmfp->clear_len != DB_CLEARLEN_NOTSET && - mfp->clear_len != DB_CLEARLEN_NOTSET && - dbmfp->clear_len != mfp->clear_len) || - (pagesize != 0 && pagesize != mfp->stat.st_pagesize) || - (dbmfp->lsn_offset != -1 && - mfp->lsn_off != DB_LSN_OFF_NOTSET && - dbmfp->lsn_offset != mfp->lsn_off)) { - __db_err(dbenv, - "%s: clear length, page size or LSN location changed", - path); - MPOOL_SYSTEM_UNLOCK(dbenv); - ret = EINVAL; - goto err; - } - - /* - * Check to see if this file has died while we waited. - * - * We normally don't lock the deadfile field when we read it as - * we only care if the field is zero or non-zero. We do lock - * on read when searching for a matching MPOOLFILE so that two - * threads of control don't race between setting the deadfile - * bit and incrementing the reference count, that is, a thread - * of control decrementing the reference count and then setting - * deadfile because the reference count is 0 blocks us finding - * the file without knowing it's about to be marked dead. - */ - MUTEX_LOCK(dbenv, mfp->mutex); - if (mfp->deadfile) { - MUTEX_UNLOCK(dbenv, mfp->mutex); - continue; - } - ++mfp->mpf_cnt; - refinc = 1; - MUTEX_UNLOCK(dbenv, mfp->mutex); - - /* Initialize any fields that are not yet set. */ - if (dbmfp->ftype != 0) - mfp->ftype = dbmfp->ftype; - if (dbmfp->clear_len != DB_CLEARLEN_NOTSET) - mfp->clear_len = dbmfp->clear_len; - if (dbmfp->lsn_offset != -1) - mfp->lsn_off = dbmfp->lsn_offset; - - break; - } - MPOOL_SYSTEM_UNLOCK(dbenv); - - if (mfp != NULL) - goto have_mfp; - -alloc: /* - * If we get here and we created a FILEID, then it's OK to set - * the dbmfp as having its FILEID_SET, because we aren't trying - * to match an existing file in the mpool. - */ - if (created_fileid) - F_SET(dbmfp, MP_FILEID_SET); - /* - * If we didn't find the file and this is an in-memory file, then - * the create flag should be set. - */ - if (FLD_ISSET(dbmfp->config_flags, DB_MPOOL_NOFILE) && - !LF_ISSET(DB_CREATE)) { - ret = ENOENT; - goto err; - } - - /* Allocate and initialize a new MPOOLFILE. */ - if ((ret = __memp_alloc( - dbmp, dbmp->reginfo, NULL, sizeof(MPOOLFILE), NULL, &mfp)) != 0) - goto err; - memset(mfp, 0, sizeof(MPOOLFILE)); - mfp->mpf_cnt = 1; - mfp->ftype = dbmfp->ftype; - mfp->stat.st_pagesize = pagesize; - mfp->lsn_off = dbmfp->lsn_offset; - mfp->clear_len = dbmfp->clear_len; - mfp->priority = dbmfp->priority; - if (dbmfp->gbytes != 0 || dbmfp->bytes != 0) { - mfp->maxpgno = (db_pgno_t) - (dbmfp->gbytes * (GIGABYTE / mfp->stat.st_pagesize)); - mfp->maxpgno += (db_pgno_t) - ((dbmfp->bytes + mfp->stat.st_pagesize - 1) / - mfp->stat.st_pagesize); - } - if (FLD_ISSET(dbmfp->config_flags, DB_MPOOL_NOFILE)) - mfp->no_backing_file = 1; - if (FLD_ISSET(dbmfp->config_flags, DB_MPOOL_UNLINK)) - mfp->unlink_on_close = 1; - - if (LF_ISSET(DB_DURABLE_UNKNOWN | DB_RDONLY)) - F_SET(mfp, MP_DURABLE_UNKNOWN); - if (LF_ISSET(DB_DIRECT)) - F_SET(mfp, MP_DIRECT); - if (LF_ISSET(DB_EXTENT)) - F_SET(mfp, MP_EXTENT); - if (LF_ISSET(DB_TXN_NOT_DURABLE)) - F_SET(mfp, MP_NOT_DURABLE); - F_SET(mfp, MP_CAN_MMAP); - - /* - * An in-memory database with no name is a temp file. Named - * in-memory databases get an artificially bumped reference - * count so they don't disappear on close; they need a remove - * to make them disappear. - */ - if (path == NULL) - F_SET(mfp, MP_TEMP); - else if (FLD_ISSET(dbmfp->config_flags, DB_MPOOL_NOFILE)) - mfp->mpf_cnt++; - - if (path != NULL && !FLD_ISSET(dbmfp->config_flags, DB_MPOOL_NOFILE)) { - /* - * Don't permit files that aren't a multiple of the pagesize, - * and find the number of the last page in the file, all the - * time being careful not to overflow 32 bits. - * - * During verify or recovery, we might have to cope with a - * truncated file; if the file size is not a multiple of the - * page size, round down to a page, we'll take care of the - * partial page outside the mpool system. - */ - if (bytes % pagesize != 0) { - if (LF_ISSET(DB_ODDFILESIZE)) - bytes -= (u_int32_t)(bytes % pagesize); - else { - __db_err(dbenv, - "%s: file size not a multiple of the pagesize", rpath); - ret = EINVAL; - goto err; - } - } - - /* - * If the user specifies DB_MPOOL_LAST or DB_MPOOL_NEW on a - * page get, we have to increment the last page in the file. - * Figure it out and save it away. - * - * Note correction: page numbers are zero-based, not 1-based. - */ - last_pgno = (db_pgno_t)(mbytes * (MEGABYTE / pagesize)); - last_pgno += (db_pgno_t)(bytes / pagesize); - if (last_pgno != 0) - --last_pgno; - mfp->orig_last_pgno = mfp->last_pgno = last_pgno; - - /* - * Get the file ID if we weren't given one. Generated file ID's - * don't use timestamps, otherwise there'd be no chance of any - * other process joining the party. - */ - if (!F_ISSET(dbmfp, MP_FILEID_SET) && - (ret = __os_fileid(dbenv, rpath, 0, dbmfp->fileid)) != 0) - goto err; - - } - - /* Copy the file identification string into shared memory. */ - if (F_ISSET(dbmfp, MP_FILEID_SET)) { - if ((ret = __memp_alloc(dbmp, dbmp->reginfo, - NULL, DB_FILE_ID_LEN, &mfp->fileid_off, &p)) != 0) - goto err; - memcpy(p, dbmfp->fileid, DB_FILE_ID_LEN); - } - - /* Copy the file path into shared memory. */ - if (path != NULL) { - if ((ret = __memp_alloc(dbmp, dbmp->reginfo, - NULL, strlen(path) + 1, &mfp->path_off, &p)) != 0) - goto err; - memcpy(p, path, strlen(path) + 1); - } - - /* Copy the page cookie into shared memory. */ - if (dbmfp->pgcookie == NULL || dbmfp->pgcookie->size == 0) { - mfp->pgcookie_len = 0; - mfp->pgcookie_off = 0; - } else { - if ((ret = __memp_alloc(dbmp, dbmp->reginfo, - NULL, dbmfp->pgcookie->size, &mfp->pgcookie_off, &p)) != 0) - goto err; - memcpy(p, dbmfp->pgcookie->data, dbmfp->pgcookie->size); - mfp->pgcookie_len = dbmfp->pgcookie->size; - } - - if ((ret = - __mutex_alloc(dbenv, MTX_MPOOLFILE_HANDLE, 0, &mfp->mutex)) != 0) - goto err; - - /* - * Prepend the MPOOLFILE to the list of MPOOLFILE's. - */ - MPOOL_SYSTEM_LOCK(dbenv); - SH_TAILQ_INSERT_HEAD(&mp->mpfq, mfp, q, __mpoolfile); - MPOOL_SYSTEM_UNLOCK(dbenv); - -have_mfp: - /* - * We need to verify that all handles open a file either durable or not - * durable. This needs to be cross process and cross sub-databases, so - * mpool is the place to do it. - */ - if (!LF_ISSET(DB_DURABLE_UNKNOWN | DB_RDONLY)) { - if (F_ISSET(mfp, MP_DURABLE_UNKNOWN)) { - if (LF_ISSET(MP_NOT_DURABLE)) - F_SET(mfp, MP_NOT_DURABLE); - F_CLR(mfp, MP_DURABLE_UNKNOWN); - } else if (!LF_ISSET(DB_TXN_NOT_DURABLE) != - !F_ISSET(mfp, MP_NOT_DURABLE)) { - __db_err(dbenv, - "Cannot open DURABLE and NOT DURABLE handles in the same file"); - ret = EINVAL; - goto err; - } - } - /* - * All paths to here have initialized the mfp variable to reference - * the selected (or allocated) MPOOLFILE. - */ - dbmfp->mfp = mfp; - - /* - * Check to see if we can mmap the file. If a file: - * + isn't temporary - * + is read-only - * + doesn't require any pgin/pgout support - * + the DB_NOMMAP flag wasn't set (in either the file open or - * the environment in which it was opened) - * + and is less than mp_mmapsize bytes in size - * - * we can mmap it instead of reading/writing buffers. Don't do error - * checking based on the mmap call failure. We want to do normal I/O - * on the file if the reason we failed was because the file was on an - * NFS mounted partition, and we can fail in buffer I/O just as easily - * as here. - * - * We'd like to test to see if the file is too big to mmap. Since we - * don't know what size or type off_t's or size_t's are, or the largest - * unsigned integral type is, or what random insanity the local C - * compiler will perpetrate, doing the comparison in a portable way is - * flatly impossible. Hope that mmap fails if the file is too large. - */ -#define DB_MAXMMAPSIZE (10 * 1024 * 1024) /* 10 MB. */ - if (F_ISSET(mfp, MP_CAN_MMAP)) { - maxmap = dbenv->mp_mmapsize == 0 ? - DB_MAXMMAPSIZE : dbenv->mp_mmapsize; - if (path == NULL || - FLD_ISSET(dbmfp->config_flags, DB_MPOOL_NOFILE)) - F_CLR(mfp, MP_CAN_MMAP); - else if (!F_ISSET(dbmfp, MP_READONLY)) - F_CLR(mfp, MP_CAN_MMAP); - else if (dbmfp->ftype != 0) - F_CLR(mfp, MP_CAN_MMAP); - else if (LF_ISSET(DB_NOMMAP) || F_ISSET(dbenv, DB_ENV_NOMMAP)) - F_CLR(mfp, MP_CAN_MMAP); - else { - MPOOL_SYSTEM_LOCK(dbenv); - maxmap = mp->mp_mmapsize == 0 ? - DB_MAXMMAPSIZE : mp->mp_mmapsize; - MPOOL_SYSTEM_UNLOCK(dbenv); - if (mbytes > maxmap / MEGABYTE || - (mbytes == maxmap / MEGABYTE && - bytes >= maxmap % MEGABYTE)) - F_CLR(mfp, MP_CAN_MMAP); - } - - dbmfp->addr = NULL; - if (F_ISSET(mfp, MP_CAN_MMAP)) { - dbmfp->len = (size_t)mbytes * MEGABYTE + bytes; - if (__os_mapfile(dbenv, rpath, - dbmfp->fhp, dbmfp->len, 1, &dbmfp->addr) != 0) { - dbmfp->addr = NULL; - F_CLR(mfp, MP_CAN_MMAP); - } - } - } - - F_SET(dbmfp, MP_OPEN_CALLED); - - /* - * Share the underlying file descriptor if that's possible. - * - * Add the file to the process' list of DB_MPOOLFILEs. - */ - MUTEX_LOCK(dbenv, dbmp->mutex); - - if (dbmfp->fhp != NULL) - for (tmp_dbmfp = TAILQ_FIRST(&dbmp->dbmfq); - tmp_dbmfp != NULL; tmp_dbmfp = TAILQ_NEXT(tmp_dbmfp, q)) - if (dbmfp->mfp == tmp_dbmfp->mfp && - (F_ISSET(dbmfp, MP_READONLY) || - !F_ISSET(tmp_dbmfp, MP_READONLY))) { - __mutex_free(dbenv, &dbmfp->fhp->mtx_fh); - (void)__os_closehandle(dbenv, dbmfp->fhp); - ++tmp_dbmfp->fhp->ref; - dbmfp->fhp = tmp_dbmfp->fhp; - break; - } - - TAILQ_INSERT_TAIL(&dbmp->dbmfq, dbmfp, q); - - MUTEX_UNLOCK(dbenv, dbmp->mutex); - - if (0) { -err: if (refinc) { - /* - * If mpf_cnt goes to zero here and unlink_on_close is - * set, then we missed the last close, but there was an - * error trying to open the file, so we probably cannot - * unlink it anyway. - */ - MUTEX_LOCK(dbenv, mfp->mutex); - --mfp->mpf_cnt; - MUTEX_UNLOCK(dbenv, mfp->mutex); - } - - } - if (rpath != NULL) - __os_free(dbenv, rpath); - return (ret); -} - -/* - * memp_fclose_pp -- - * DB_MPOOLFILE->close pre/post processing. - * - * PUBLIC: int __memp_fclose_pp __P((DB_MPOOLFILE *, u_int32_t)); - */ -int -__memp_fclose_pp(dbmfp, flags) - DB_MPOOLFILE *dbmfp; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int ret; - - dbenv = dbmfp->dbenv; - - /* - * Validate arguments, but as a handle destructor, we can't fail. - * - * !!! - * DB_MPOOL_DISCARD: Undocumented flag: DB private. - */ - (void)__db_fchk(dbenv, "DB_MPOOLFILE->close", flags, DB_MPOOL_DISCARD); - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, (__memp_fclose(dbmfp, flags)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __memp_fclose -- - * DB_MPOOLFILE->close. - * - * PUBLIC: int __memp_fclose __P((DB_MPOOLFILE *, u_int32_t)); - */ -int -__memp_fclose(dbmfp, flags) - DB_MPOOLFILE *dbmfp; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_MPOOL *dbmp; - MPOOLFILE *mfp; - char *rpath; - u_int32_t ref; - int deleted, ret, t_ret; - - dbenv = dbmfp->dbenv; - dbmp = dbenv->mp_handle; - ret = 0; - - /* - * Remove the DB_MPOOLFILE from the process' list. - * - * It's possible the underlying mpool cache may never have been created. - * In that case, all we have is a structure, discard it. - * - * It's possible the DB_MPOOLFILE was never added to the DB_MPOOLFILE - * file list, check the MP_OPEN_CALLED flag to be sure. - */ - if (dbmp == NULL) - goto done; - - MUTEX_LOCK(dbenv, dbmp->mutex); - - DB_ASSERT(dbmfp->ref >= 1); - if ((ref = --dbmfp->ref) == 0 && F_ISSET(dbmfp, MP_OPEN_CALLED)) - TAILQ_REMOVE(&dbmp->dbmfq, dbmfp, q); - - /* - * Decrement the file descriptor's ref count -- if we're the last ref, - * we'll discard the file descriptor. - */ - if (ref == 0 && dbmfp->fhp != NULL && --dbmfp->fhp->ref > 0) - dbmfp->fhp = NULL; - MUTEX_UNLOCK(dbenv, dbmp->mutex); - if (ref != 0) - return (0); - - /* Complain if pinned blocks never returned. */ - if (dbmfp->pinref != 0) { - __db_err(dbenv, "%s: close: %lu blocks left pinned", - __memp_fn(dbmfp), (u_long)dbmfp->pinref); - ret = __db_panic(dbenv, DB_RUNRECOVERY); - } - - /* Discard any mmap information. */ - if (dbmfp->addr != NULL && - (ret = __os_unmapfile(dbenv, dbmfp->addr, dbmfp->len)) != 0) - __db_err(dbenv, "%s: %s", __memp_fn(dbmfp), db_strerror(ret)); - - /* - * Close the file and discard the descriptor structure; temporary - * files may not yet have been created. - */ - if (dbmfp->fhp != NULL) { - if ((t_ret = - __mutex_free(dbenv, &dbmfp->fhp->mtx_fh)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = __os_closehandle(dbenv, dbmfp->fhp)) != 0) { - __db_err(dbenv, "%s: %s", - __memp_fn(dbmfp), db_strerror(t_ret)); - if (ret == 0) - ret = t_ret; - } - dbmfp->fhp = NULL; - } - - /* - * Discard our reference on the underlying MPOOLFILE, and close it - * if it's no longer useful to anyone. It possible the open of the - * file never happened or wasn't successful, in which case, mpf will - * be NULL and MP_OPEN_CALLED will not be set. - */ - mfp = dbmfp->mfp; - DB_ASSERT((F_ISSET(dbmfp, MP_OPEN_CALLED) && mfp != NULL) || - (!F_ISSET(dbmfp, MP_OPEN_CALLED) && mfp == NULL)); - if (!F_ISSET(dbmfp, MP_OPEN_CALLED)) - goto done; - - /* - * If it's a temp file, all outstanding references belong to unflushed - * buffers. (A temp file can only be referenced by one DB_MPOOLFILE). - * We don't care about preserving any of those buffers, so mark the - * MPOOLFILE as dead so that even the dirty ones just get discarded - * when we try to flush them. - */ - deleted = 0; - MUTEX_LOCK(dbenv, mfp->mutex); - if (--mfp->mpf_cnt == 0 || LF_ISSET(DB_MPOOL_DISCARD)) { - if (LF_ISSET(DB_MPOOL_DISCARD) || - F_ISSET(mfp, MP_TEMP) || mfp->unlink_on_close) { - mfp->deadfile = 1; - } - if (mfp->unlink_on_close) { - if ((t_ret = __db_appname(dbmp->dbenv, - DB_APP_DATA, R_ADDR(dbmp->reginfo, - mfp->path_off), 0, NULL, &rpath)) != 0 && ret == 0) - ret = t_ret; - if (t_ret == 0) { - if ((t_ret = __os_unlink( - dbmp->dbenv, rpath)) != 0 && ret == 0) - ret = t_ret; - __os_free(dbenv, rpath); - } - } - if (mfp->block_cnt == 0) { - if ((t_ret = - __memp_mf_discard(dbmp, mfp)) != 0 && ret == 0) - ret = t_ret; - deleted = 1; - } - } - if (deleted == 0) - MUTEX_UNLOCK(dbenv, mfp->mutex); - -done: /* Discard the DB_MPOOLFILE structure. */ - if (dbmfp->pgcookie != NULL) { - __os_free(dbenv, dbmfp->pgcookie->data); - __os_free(dbenv, dbmfp->pgcookie); - } - __os_free(dbenv, dbmfp); - - return (ret); -} - -/* - * __memp_mf_discard -- - * Discard an MPOOLFILE. - * - * PUBLIC: int __memp_mf_discard __P((DB_MPOOL *, MPOOLFILE *)); - */ -int -__memp_mf_discard(dbmp, mfp) - DB_MPOOL *dbmp; - MPOOLFILE *mfp; -{ - DB_ENV *dbenv; - DB_MPOOL_STAT *sp; - MPOOL *mp; - int need_sync, ret, t_ret; - - dbenv = dbmp->dbenv; - mp = dbmp->reginfo[0].primary; - ret = 0; - - /* - * Expects caller to be holding the MPOOLFILE mutex. - * - * When discarding a file, we have to flush writes from it to disk. - * The scenario is that dirty buffers from this file need to be - * flushed to satisfy a future checkpoint, but when the checkpoint - * calls mpool sync, the sync code won't know anything about them. - * Ignore files not written, discarded, or only temporary. - */ - need_sync = - mfp->file_written && !mfp->deadfile && !F_ISSET(mfp, MP_TEMP); - - /* - * We have to release the MPOOLFILE mutex before acquiring the region - * mutex so we don't deadlock. Make sure nobody ever looks at this - * structure again. - */ - mfp->deadfile = 1; - - /* Discard the mutex we're holding and return it too the pool. */ - MUTEX_UNLOCK(dbenv, mfp->mutex); - if ((t_ret = __mutex_free(dbenv, &mfp->mutex)) != 0 && ret == 0) - ret = t_ret; - - /* Lock the region and delete from the list of MPOOLFILEs. */ - MPOOL_SYSTEM_LOCK(dbenv); - SH_TAILQ_REMOVE(&mp->mpfq, mfp, q, __mpoolfile); - - if (need_sync && - (t_ret = __memp_mf_sync(dbmp, mfp, 1)) != 0 && ret == 0) - ret = t_ret; - - /* Copy the statistics into the region. */ - sp = &mp->stat; - sp->st_cache_hit += mfp->stat.st_cache_hit; - sp->st_cache_miss += mfp->stat.st_cache_miss; - sp->st_map += mfp->stat.st_map; - sp->st_page_create += mfp->stat.st_page_create; - sp->st_page_in += mfp->stat.st_page_in; - sp->st_page_out += mfp->stat.st_page_out; - - /* Free the space. */ - if (mfp->path_off != 0) - __db_shalloc_free(&dbmp->reginfo[0], - R_ADDR(dbmp->reginfo, mfp->path_off)); - if (mfp->fileid_off != 0) - __db_shalloc_free(&dbmp->reginfo[0], - R_ADDR(dbmp->reginfo, mfp->fileid_off)); - if (mfp->pgcookie_off != 0) - __db_shalloc_free(&dbmp->reginfo[0], - R_ADDR(dbmp->reginfo, mfp->pgcookie_off)); - __db_shalloc_free(&dbmp->reginfo[0], mfp); - - MPOOL_SYSTEM_UNLOCK(dbenv); - - return (ret); -} - -/* - * __memp_inmemlist -- - * Return a list of the named in-memory databases. - * - * PUBLIC: int __memp_inmemlist __P((DB_ENV *, char ***, int *)); - */ -int -__memp_inmemlist(dbenv, namesp, cntp) - DB_ENV *dbenv; - char ***namesp; - int *cntp; -{ - DB_MPOOL *dbmp; - MPOOL *mp; - MPOOLFILE *mfp; - - int arraysz, cnt, ret; - char **names; - - names = NULL; - dbmp = dbenv->mp_handle; - mp = dbmp->reginfo[0].primary; - - arraysz = cnt = 0; - MPOOL_SYSTEM_LOCK(dbenv); - for (mfp = SH_TAILQ_FIRST(&mp->mpfq, __mpoolfile); - mfp != NULL; mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile)) { - /* Skip dead files and temporary files. */ - if (mfp->deadfile || F_ISSET(mfp, MP_TEMP)) - continue; - - /* Skip entries that allow files. */ - if (!mfp->no_backing_file) - continue; - - /* We found one. */ - if (cnt >= arraysz) { - arraysz += 100; - if ((ret = __os_realloc(dbenv, - (u_int)arraysz * sizeof(names[0]), &names)) != 0) - goto nomem; - } - if ((ret = __os_strdup(dbenv, - R_ADDR(dbmp->reginfo, mfp->path_off), &names[cnt])) != 0) - goto nomem; - - cnt++; - } - MPOOL_SYSTEM_UNLOCK(dbenv); - *namesp = names; - *cntp = cnt; - return (0); - -nomem: MPOOL_SYSTEM_UNLOCK(dbenv); - if (names != NULL) { - while (--cnt >= 0) - __os_free(dbenv, names[cnt]); - __os_free(dbenv, names); - } - - /* Make sure we don't return any garbage. */ - *cntp = 0; - *namesp = NULL; - return (ret); -} diff --git a/storage/bdb/mp/mp_fput.c b/storage/bdb/mp/mp_fput.c deleted file mode 100644 index 6c3f9145a97..00000000000 --- a/storage/bdb/mp/mp_fput.c +++ /dev/null @@ -1,314 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: mp_fput.c,v 12.7 2005/10/07 20:21:33 ubell Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#endif - -#include "db_int.h" -#include "dbinc/db_shash.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" - -static int __memp_reset_lru __P((DB_ENV *, REGINFO *)); - -/* - * __memp_fput_pp -- - * DB_MPOOLFILE->put pre/post processing. - * - * PUBLIC: int __memp_fput_pp __P((DB_MPOOLFILE *, void *, u_int32_t)); - */ -int -__memp_fput_pp(dbmfp, pgaddr, flags) - DB_MPOOLFILE *dbmfp; - void *pgaddr; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int ret, t_ret; - - dbenv = dbmfp->dbenv; - PANIC_CHECK(dbenv); - - ENV_ENTER(dbenv, ip); - - ret = __memp_fput(dbmfp, pgaddr, flags); - if (IS_ENV_REPLICATED(dbenv) && - (t_ret = __op_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __memp_fput -- - * DB_MPOOLFILE->put. - * - * PUBLIC: int __memp_fput __P((DB_MPOOLFILE *, void *, u_int32_t)); - */ -int -__memp_fput(dbmfp, pgaddr, flags) - DB_MPOOLFILE *dbmfp; - void *pgaddr; - u_int32_t flags; -{ - BH *fbhp, *bhp, *prev; - DB_ENV *dbenv; - DB_MPOOL *dbmp; - DB_MPOOL_HASH *hp; - MPOOL *c_mp; - MPOOLFILE *mfp; - u_int32_t n_cache; - int adjust, ret, t_ret; - - dbenv = dbmfp->dbenv; - MPF_ILLEGAL_BEFORE_OPEN(dbmfp, "DB_MPOOLFILE->put"); - dbmp = dbenv->mp_handle; - ret = 0; - - /* - * Check arguments, but don't fail because we want to unpin the page - * regardless. The problem is when running with replication. There - * is a reference count we incremented when __memp_fget was called, - * and we need to unpin the page and decrement that reference count. - * If we see flag problems, mark the page dirty. - */ - if (flags) { - if (__db_fchk(dbenv, "memp_fput", flags, - DB_MPOOL_CLEAN | DB_MPOOL_DIRTY | DB_MPOOL_DISCARD) != 0 || - __db_fcchk(dbenv, "memp_fput", flags, - DB_MPOOL_CLEAN, DB_MPOOL_DIRTY) != 0) { - flags = DB_MPOOL_DIRTY; - ret = EINVAL; - DB_ASSERT(0); - } - - if (LF_ISSET(DB_MPOOL_DIRTY) && F_ISSET(dbmfp, MP_READONLY)) { - __db_err(dbenv, - "%s: dirty flag set for readonly file page", - __memp_fn(dbmfp)); - flags = 0; - ret = EINVAL; - DB_ASSERT(0); - } - } - - /* - * If we're mapping the file, there's nothing to do. Because we can - * stop mapping the file at any time, we have to check on each buffer - * to see if the address we gave the application was part of the map - * region. - */ - if (dbmfp->addr != NULL && pgaddr >= dbmfp->addr && - (u_int8_t *)pgaddr <= (u_int8_t *)dbmfp->addr + dbmfp->len) - return (0); - -#ifdef DIAGNOSTIC - /* - * Decrement the per-file pinned buffer count (mapped pages aren't - * counted). - */ - MPOOL_SYSTEM_LOCK(dbenv); - if (dbmfp->pinref == 0) { - MPOOL_SYSTEM_UNLOCK(dbenv); - __db_err(dbenv, - "%s: more pages returned than retrieved", __memp_fn(dbmfp)); - return (__db_panic(dbenv, EACCES)); - } - --dbmfp->pinref; - MPOOL_SYSTEM_UNLOCK(dbenv); -#endif - - /* Convert a page address to a buffer header and hash bucket. */ - bhp = (BH *)((u_int8_t *)pgaddr - SSZA(BH, buf)); - n_cache = NCACHE(dbmp->reginfo[0].primary, bhp->mf_offset, bhp->pgno); - c_mp = dbmp->reginfo[n_cache].primary; - hp = R_ADDR(&dbmp->reginfo[n_cache], c_mp->htab); - hp = &hp[NBUCKET(c_mp, bhp->mf_offset, bhp->pgno)]; - - MUTEX_LOCK(dbenv, hp->mtx_hash); - - /* Set/clear the page bits. */ - if (LF_ISSET(DB_MPOOL_CLEAN) && - F_ISSET(bhp, BH_DIRTY) && !F_ISSET(bhp, BH_DIRTY_CREATE)) { - DB_ASSERT(hp->hash_page_dirty != 0); - --hp->hash_page_dirty; - F_CLR(bhp, BH_DIRTY); - } - if (LF_ISSET(DB_MPOOL_DIRTY) && !F_ISSET(bhp, BH_DIRTY)) { - ++hp->hash_page_dirty; - F_SET(bhp, BH_DIRTY); - } - if (LF_ISSET(DB_MPOOL_DISCARD)) - F_SET(bhp, BH_DISCARD); - - /* - * Check for a reference count going to zero. This can happen if the - * application returns a page twice. - */ - if (bhp->ref == 0) { - MUTEX_UNLOCK(dbenv, hp->mtx_hash); - __db_err(dbenv, "%s: page %lu: unpinned page returned", - __memp_fn(dbmfp), (u_long)bhp->pgno); - return (__db_panic(dbenv, EACCES)); - } - - /* Note the activity so allocation won't decide to quit. */ - ++c_mp->put_counter; - - /* - * Mark the file dirty. Check for a dirty bit on the buffer as well - * as the dirty flag because the buffer might have been marked dirty - * in the DB_MPOOLFILE->set method. - */ - mfp = dbmfp->mfp; - if (LF_ISSET(DB_MPOOL_DIRTY) || F_ISSET(bhp, BH_DIRTY)) - mfp->file_written = 1; - - /* - * If more than one reference to the page or a reference other than a - * thread waiting to flush the buffer to disk, we're done. Ignore the - * discard flags (for now) and leave the buffer's priority alone. - */ - if (--bhp->ref > 1 || (bhp->ref == 1 && !F_ISSET(bhp, BH_LOCKED))) { - MUTEX_UNLOCK(dbenv, hp->mtx_hash); - return (0); - } - - /* Update priority values. */ - if (F_ISSET(bhp, BH_DISCARD) || mfp->priority == MPOOL_PRI_VERY_LOW) - bhp->priority = 0; - else { - /* - * We don't lock the LRU counter or the stat.st_pages field, if - * we get garbage (which won't happen on a 32-bit machine), it - * only means a buffer has the wrong priority. - */ - bhp->priority = c_mp->lru_count; - - adjust = 0; - if (mfp->priority != 0) - adjust = - (int)c_mp->stat.st_pages / mfp->priority; - if (F_ISSET(bhp, BH_DIRTY)) - adjust += c_mp->stat.st_pages / MPOOL_PRI_DIRTY; - - if (adjust > 0) { - if (UINT32_MAX - bhp->priority >= (u_int32_t)adjust) - bhp->priority += adjust; - } else if (adjust < 0) - if (bhp->priority > (u_int32_t)-adjust) - bhp->priority += adjust; - } - - /* - * Buffers on hash buckets are sorted by priority -- move the buffer - * to the correct position in the list. - */ - if ((fbhp = - SH_TAILQ_FIRST(&hp->hash_bucket, __bh)) == - SH_TAILQ_LAST(&hp->hash_bucket, hq, __bh)) - goto done; - - if (fbhp == bhp) - fbhp = SH_TAILQ_NEXT(fbhp, hq, __bh); - SH_TAILQ_REMOVE(&hp->hash_bucket, bhp, hq, __bh); - - for (prev = NULL; fbhp != NULL; - prev = fbhp, fbhp = SH_TAILQ_NEXT(fbhp, hq, __bh)) - if (fbhp->priority > bhp->priority) - break; - if (prev == NULL) - SH_TAILQ_INSERT_HEAD(&hp->hash_bucket, bhp, hq, __bh); - else - SH_TAILQ_INSERT_AFTER(&hp->hash_bucket, prev, bhp, hq, __bh); - -done: - /* Reset the hash bucket's priority. */ - hp->hash_priority = SH_TAILQ_FIRSTP(&hp->hash_bucket, __bh)->priority; - -#ifdef DIAGNOSTIC - __memp_check_order(hp); -#endif - - /* - * The sync code has a separate counter for buffers on which it waits. - * It reads that value without holding a lock so we update it as the - * last thing we do. Once that value goes to 0, we won't see another - * reference to that buffer being returned to the cache until the sync - * code has finished, so we're safe as long as we don't let the value - * go to 0 before we finish with the buffer. - */ - if (F_ISSET(bhp, BH_LOCKED) && bhp->ref_sync != 0) - --bhp->ref_sync; - - MUTEX_UNLOCK(dbenv, hp->mtx_hash); - - /* - * On every buffer put we update the buffer generation number and check - * for wraparound. - */ - if (++c_mp->lru_count == UINT32_MAX) - if ((t_ret = - __memp_reset_lru(dbenv, dbmp->reginfo)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __memp_reset_lru -- - * Reset the cache LRU counter. - */ -static int -__memp_reset_lru(dbenv, infop) - DB_ENV *dbenv; - REGINFO *infop; -{ - BH *bhp; - DB_MPOOL_HASH *hp; - MPOOL *c_mp; - u_int32_t bucket; - - c_mp = infop->primary; - - /* - * Update the counter so all future allocations will start at the - * bottom. - */ - c_mp->lru_count -= MPOOL_BASE_DECREMENT; - - /* Adjust the priority of every buffer in the system. */ - for (hp = R_ADDR(infop, c_mp->htab), - bucket = 0; bucket < c_mp->htab_buckets; ++hp, ++bucket) { - /* - * Skip empty buckets. - * - * We can check for empty buckets before locking as we - * only care if the pointer is zero or non-zero. - */ - if (SH_TAILQ_FIRST(&hp->hash_bucket, __bh) == NULL) - continue; - - MUTEX_LOCK(dbenv, hp->mtx_hash); - for (bhp = SH_TAILQ_FIRST(&hp->hash_bucket, __bh); - bhp != NULL; bhp = SH_TAILQ_NEXT(bhp, hq, __bh)) - if (bhp->priority != UINT32_MAX && - bhp->priority > MPOOL_BASE_DECREMENT) - bhp->priority -= MPOOL_BASE_DECREMENT; - MUTEX_UNLOCK(dbenv, hp->mtx_hash); - } - - return (0); -} diff --git a/storage/bdb/mp/mp_fset.c b/storage/bdb/mp/mp_fset.c deleted file mode 100644 index b3898e46554..00000000000 --- a/storage/bdb/mp/mp_fset.c +++ /dev/null @@ -1,113 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: mp_fset.c,v 12.5 2005/10/07 20:21:33 ubell Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#endif - -#include "db_int.h" -#include "dbinc/db_shash.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" - -/* - * __memp_fset_pp -- - * DB_MPOOLFILE->set pre/post processing. - * - * PUBLIC: int __memp_fset_pp __P((DB_MPOOLFILE *, void *, u_int32_t)); - */ -int -__memp_fset_pp(dbmfp, pgaddr, flags) - DB_MPOOLFILE *dbmfp; - void *pgaddr; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int ret; - - dbenv = dbmfp->dbenv; - - PANIC_CHECK(dbenv); - MPF_ILLEGAL_BEFORE_OPEN(dbmfp, "DB_MPOOLFILE->set"); - - /* Validate arguments. */ - if (flags == 0) - return (__db_ferr(dbenv, "memp_fset", 1)); - - if ((ret = __db_fchk(dbenv, "memp_fset", flags, - DB_MPOOL_CLEAN | DB_MPOOL_DIRTY | DB_MPOOL_DISCARD)) != 0) - return (ret); - if ((ret = __db_fcchk(dbenv, "memp_fset", - flags, DB_MPOOL_CLEAN, DB_MPOOL_DIRTY)) != 0) - return (ret); - - if (LF_ISSET(DB_MPOOL_DIRTY) && F_ISSET(dbmfp, MP_READONLY)) { - __db_err(dbenv, "%s: dirty flag set for readonly file page", - __memp_fn(dbmfp)); - return (EACCES); - } - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, (__memp_fset(dbmfp, pgaddr, flags)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __memp_fset -- - * DB_MPOOLFILE->set. - * - * PUBLIC: int __memp_fset __P((DB_MPOOLFILE *, void *, u_int32_t)); - */ -int -__memp_fset(dbmfp, pgaddr, flags) - DB_MPOOLFILE *dbmfp; - void *pgaddr; - u_int32_t flags; -{ - BH *bhp; - DB_ENV *dbenv; - DB_MPOOL *dbmp; - DB_MPOOL_HASH *hp; - MPOOL *c_mp; - u_int32_t n_cache; - - dbenv = dbmfp->dbenv; - dbmp = dbenv->mp_handle; - - /* Convert the page address to a buffer header and hash bucket. */ - bhp = (BH *)((u_int8_t *)pgaddr - SSZA(BH, buf)); - n_cache = NCACHE(dbmp->reginfo[0].primary, bhp->mf_offset, bhp->pgno); - c_mp = dbmp->reginfo[n_cache].primary; - hp = R_ADDR(&dbmp->reginfo[n_cache], c_mp->htab); - hp = &hp[NBUCKET(c_mp, bhp->mf_offset, bhp->pgno)]; - - MUTEX_LOCK(dbenv, hp->mtx_hash); - - /* Set/clear the page bits. */ - if (LF_ISSET(DB_MPOOL_CLEAN) && - F_ISSET(bhp, BH_DIRTY) && !F_ISSET(bhp, BH_DIRTY_CREATE)) { - DB_ASSERT(hp->hash_page_dirty != 0); - --hp->hash_page_dirty; - F_CLR(bhp, BH_DIRTY); - } - if (LF_ISSET(DB_MPOOL_DIRTY) && !F_ISSET(bhp, BH_DIRTY)) { - ++hp->hash_page_dirty; - F_SET(bhp, BH_DIRTY); - } - if (LF_ISSET(DB_MPOOL_DISCARD)) - F_SET(bhp, BH_DISCARD); - - MUTEX_UNLOCK(dbenv, hp->mtx_hash); - return (0); -} diff --git a/storage/bdb/mp/mp_method.c b/storage/bdb/mp/mp_method.c deleted file mode 100644 index 646524aea20..00000000000 --- a/storage/bdb/mp/mp_method.c +++ /dev/null @@ -1,753 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: mp_method.c,v 12.15 2005/10/12 12:45:10 margo Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_shash.h" -#include "dbinc/mp.h" - -/* - * __memp_dbenv_create -- - * Mpool specific creation of the DB_ENV structure. - * - * PUBLIC: void __memp_dbenv_create __P((DB_ENV *)); - */ -void -__memp_dbenv_create(dbenv) - DB_ENV *dbenv; -{ - /* - * !!! - * Our caller has not yet had the opportunity to reset the panic - * state or turn off mutex locking, and so we can neither check - * the panic state or acquire a mutex in the DB_ENV create path. - * - * We default to 32 8K pages. We don't default to a flat 256K, because - * some systems require significantly more memory to hold 32 pages than - * others. For example, HP-UX with POSIX pthreads needs 88 bytes for - * a POSIX pthread mutex and almost 200 bytes per buffer header, while - * Solaris needs 24 and 52 bytes for the same structures. The minimum - * number of hash buckets is 37. These contain a mutex also. - */ - dbenv->mp_bytes = - 32 * ((8 * 1024) + sizeof(BH)) + 37 * sizeof(DB_MPOOL_HASH); - dbenv->mp_ncache = 1; -} - -/* - * __memp_get_cachesize -- - * {DB_ENV,DB}->get_cachesize. - * - * PUBLIC: int __memp_get_cachesize - * PUBLIC: __P((DB_ENV *, u_int32_t *, u_int32_t *, int *)); - */ -int -__memp_get_cachesize(dbenv, gbytesp, bytesp, ncachep) - DB_ENV *dbenv; - u_int32_t *gbytesp, *bytesp; - int *ncachep; -{ - MPOOL *mp; - - ENV_NOT_CONFIGURED(dbenv, - dbenv->mp_handle, "DB_ENV->get_cachesize", DB_INIT_MPOOL); - - if (MPOOL_ON(dbenv)) { - /* Cannot be set after open, no lock required to read. */ - mp = ((DB_MPOOL *)dbenv->mp_handle)->reginfo[0].primary; - if (gbytesp != NULL) - *gbytesp = mp->stat.st_gbytes; - if (bytesp != NULL) - *bytesp = mp->stat.st_bytes; - if (ncachep != NULL) - *ncachep = (int)mp->nreg; - } else { - if (gbytesp != NULL) - *gbytesp = dbenv->mp_gbytes; - if (bytesp != NULL) - *bytesp = dbenv->mp_bytes; - if (ncachep != NULL) - *ncachep = (int)dbenv->mp_ncache; - } - return (0); -} - -/* - * __memp_set_cachesize -- - * {DB_ENV,DB}->set_cachesize. - * - * PUBLIC: int __memp_set_cachesize __P((DB_ENV *, u_int32_t, u_int32_t, int)); - */ -int -__memp_set_cachesize(dbenv, gbytes, bytes, arg_ncache) - DB_ENV *dbenv; - u_int32_t gbytes, bytes; - int arg_ncache; -{ - u_int ncache; - - ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_cachesize"); - - /* Normalize the cache count. */ - ncache = arg_ncache <= 0 ? 1 : (u_int)arg_ncache; - - /* - * You can only store 4GB-1 in an unsigned 32-bit value, so correct for - * applications that specify 4GB cache sizes -- we know what they meant. - */ - if (sizeof(roff_t) == 4 && gbytes / ncache == 4 && bytes == 0) { - --gbytes; - bytes = GIGABYTE - 1; - } else { - gbytes += bytes / GIGABYTE; - bytes %= GIGABYTE; - } - - /* - * !!! - * With 32-bit region offsets, individual cache regions must be smaller - * than 4GB. Also, cache sizes larger than 10TB would cause 32-bit - * wrapping in the calculation of the number of hash buckets. See - * __memp_open for details. - */ - if (sizeof(roff_t) <= 4) { - if (gbytes / ncache >= 4) { - __db_err(dbenv, - "individual cache size too large: maximum is 4GB"); - return (EINVAL); - } - } else - if (gbytes / ncache > 10000) { - __db_err(dbenv, - "individual cache size too large: maximum is 10TB"); - return (EINVAL); - } - - /* - * If the application requested less than 500Mb, increase the cachesize - * by 25% and factor in the size of the hash buckets to account for our - * overhead. (I'm guessing caches over 500Mb are specifically sized, - * that is, it's a large server and the application actually knows how - * much memory is available. We only document the 25% overhead number, - * not the hash buckets, but I don't see a reason to confuse the issue, - * it shouldn't matter to an application.) - * - * There is a minimum cache size, regardless. - */ - if (gbytes == 0) { - if (bytes < 500 * MEGABYTE) - bytes += (bytes / 4) + 37 * sizeof(DB_MPOOL_HASH); - if (bytes / ncache < DB_CACHESIZE_MIN) - bytes = ncache * DB_CACHESIZE_MIN; - } - - dbenv->mp_gbytes = gbytes; - dbenv->mp_bytes = bytes; - dbenv->mp_ncache = ncache; - - return (0); -} - -/* - * PUBLIC: int __memp_get_mp_max_openfd __P((DB_ENV *, int *)); - */ -int -__memp_get_mp_max_openfd(dbenv, maxopenfdp) - DB_ENV *dbenv; - int *maxopenfdp; -{ - DB_MPOOL *dbmp; - MPOOL *mp; - - ENV_NOT_CONFIGURED(dbenv, - dbenv->mp_handle, "DB_ENV->get_mp_max_openfd", DB_INIT_MPOOL); - - if (MPOOL_ON(dbenv)) { - dbmp = dbenv->mp_handle; - mp = dbmp->reginfo[0].primary; - MPOOL_SYSTEM_LOCK(dbenv); - *maxopenfdp = mp->mp_maxopenfd; - MPOOL_SYSTEM_UNLOCK(dbenv); - } else - *maxopenfdp = dbenv->mp_maxopenfd; - return (0); -} - -/* - * __memp_set_mp_max_openfd -- - * Set the maximum number of open fd's when flushing the cache. - * PUBLIC: int __memp_set_mp_max_openfd __P((DB_ENV *, int)); - */ -int -__memp_set_mp_max_openfd(dbenv, maxopenfd) - DB_ENV *dbenv; - int maxopenfd; -{ - DB_MPOOL *dbmp; - MPOOL *mp; - - ENV_NOT_CONFIGURED(dbenv, - dbenv->mp_handle, "DB_ENV->set_mp_max_openfd", DB_INIT_MPOOL); - - if (MPOOL_ON(dbenv)) { - dbmp = dbenv->mp_handle; - mp = dbmp->reginfo[0].primary; - MPOOL_SYSTEM_LOCK(dbenv); - mp->mp_maxopenfd = maxopenfd; - MPOOL_SYSTEM_UNLOCK(dbenv); - } else - dbenv->mp_maxopenfd = maxopenfd; - return (0); -} - -/* - * PUBLIC: int __memp_get_mp_max_write __P((DB_ENV *, int *, int *)); - */ -int -__memp_get_mp_max_write(dbenv, maxwritep, maxwrite_sleepp) - DB_ENV *dbenv; - int *maxwritep, *maxwrite_sleepp; -{ - DB_MPOOL *dbmp; - MPOOL *mp; - - ENV_NOT_CONFIGURED(dbenv, - dbenv->mp_handle, "DB_ENV->get_mp_max_write", DB_INIT_MPOOL); - - if (MPOOL_ON(dbenv)) { - dbmp = dbenv->mp_handle; - mp = dbmp->reginfo[0].primary; - MPOOL_SYSTEM_LOCK(dbenv); - *maxwritep = mp->mp_maxwrite; - *maxwrite_sleepp = mp->mp_maxwrite_sleep; - MPOOL_SYSTEM_UNLOCK(dbenv); - } else { - *maxwritep = dbenv->mp_maxwrite; - *maxwrite_sleepp = dbenv->mp_maxwrite_sleep; - } - return (0); -} - -/* - * __memp_set_mp_max_write -- - * Set the maximum continuous I/O count. - * - * PUBLIC: int __memp_set_mp_max_write __P((DB_ENV *, int, int)); - */ -int -__memp_set_mp_max_write(dbenv, maxwrite, maxwrite_sleep) - DB_ENV *dbenv; - int maxwrite, maxwrite_sleep; -{ - DB_MPOOL *dbmp; - MPOOL *mp; - - ENV_NOT_CONFIGURED(dbenv, - dbenv->mp_handle, "DB_ENV->get_mp_max_write", DB_INIT_MPOOL); - - if (MPOOL_ON(dbenv)) { - dbmp = dbenv->mp_handle; - mp = dbmp->reginfo[0].primary; - MPOOL_SYSTEM_LOCK(dbenv); - mp->mp_maxwrite = maxwrite; - mp->mp_maxwrite_sleep = maxwrite_sleep; - MPOOL_SYSTEM_UNLOCK(dbenv); - } else { - dbenv->mp_maxwrite = maxwrite; - dbenv->mp_maxwrite_sleep = maxwrite_sleep; - } - return (0); -} - -/* - * PUBLIC: int __memp_get_mp_mmapsize __P((DB_ENV *, size_t *)); - */ -int -__memp_get_mp_mmapsize(dbenv, mp_mmapsizep) - DB_ENV *dbenv; - size_t *mp_mmapsizep; -{ - DB_MPOOL *dbmp; - MPOOL *mp; - - ENV_NOT_CONFIGURED(dbenv, - dbenv->mp_handle, "DB_ENV->get_mp_max_mmapsize", DB_INIT_MPOOL); - - if (MPOOL_ON(dbenv)) { - dbmp = dbenv->mp_handle; - mp = dbmp->reginfo[0].primary; - MPOOL_SYSTEM_LOCK(dbenv); - *mp_mmapsizep = mp->mp_mmapsize; - MPOOL_SYSTEM_UNLOCK(dbenv); - } else - *mp_mmapsizep = dbenv->mp_mmapsize; - return (0); -} - -/* - * __memp_set_mp_mmapsize -- - * DB_ENV->set_mp_mmapsize. - * - * PUBLIC: int __memp_set_mp_mmapsize __P((DB_ENV *, size_t)); - */ -int -__memp_set_mp_mmapsize(dbenv, mp_mmapsize) - DB_ENV *dbenv; - size_t mp_mmapsize; -{ - DB_MPOOL *dbmp; - MPOOL *mp; - - ENV_NOT_CONFIGURED(dbenv, - dbenv->mp_handle, "DB_ENV->get_mp_max_mmapsize", DB_INIT_MPOOL); - - if (MPOOL_ON(dbenv)) { - dbmp = dbenv->mp_handle; - mp = dbmp->reginfo[0].primary; - MPOOL_SYSTEM_LOCK(dbenv); - mp->mp_mmapsize = mp_mmapsize; - MPOOL_SYSTEM_UNLOCK(dbenv); - } else - dbenv->mp_mmapsize = mp_mmapsize; - return (0); -} - -/* - * __memp_nameop - * Remove or rename a file in the pool. - * - * PUBLIC: int __memp_nameop __P((DB_ENV *, - * PUBLIC: u_int8_t *, const char *, const char *, const char *, int)); - * - * XXX - * Undocumented interface: DB private. - */ -int -__memp_nameop(dbenv, fileid, newname, fullold, fullnew, inmem) - DB_ENV *dbenv; - u_int8_t *fileid; - const char *newname, *fullold, *fullnew; - int inmem; -{ - DB_MPOOL *dbmp; - MPOOL *mp; - MPOOLFILE *save_mfp, *mfp; - roff_t newname_off; - int is_remove, locked, ret; - void *p; - - ret = locked = 0; - dbmp = NULL; - save_mfp = mfp = NULL; - is_remove = newname == NULL; - if (!MPOOL_ON(dbenv)) - goto fsop; - - dbmp = dbenv->mp_handle; - mp = dbmp->reginfo[0].primary; - - /* - * Remove or rename a file that the mpool might know about. We assume - * that the fop layer has the file locked for exclusive access, so we - * don't worry about locking except for the mpool mutexes. Checkpoint - * can happen at any time, independent of file locking, so we have to - * do the actual unlink or rename system call to avoid any race. - * - * If this is a rename, allocate first, because we can't recursively - * grab the region lock. - */ - if (is_remove) { - p = NULL; - COMPQUIET(newname_off, INVALID_ROFF); - } else { - if ((ret = __memp_alloc(dbmp, dbmp->reginfo, - NULL, strlen(newname) + 1, &newname_off, &p)) != 0) - return (ret); - memcpy(p, newname, strlen(newname) + 1); - } - - locked = 1; - MPOOL_SYSTEM_LOCK(dbenv); - - /* - * Find the file -- if mpool doesn't know about this file, that may - * not be an error -- if the file is not a memory-only file and it - * is not open, it won't show up here. If this is a memory file - * then on a rename, we need to make sure that the new name does - * not exist. - */ - for (mfp = SH_TAILQ_FIRST(&mp->mpfq, __mpoolfile); - mfp != NULL; mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile)) { - /* Ignore non-active files. */ - if (mfp->deadfile || F_ISSET(mfp, MP_TEMP)) - continue; - - if (!is_remove && inmem && mfp->no_backing_file && - strcmp(newname, R_ADDR(dbmp->reginfo, mfp->path_off)) - == 0) { - ret = EEXIST; - goto err; - } - - /* Try to match on fileid. */ - if (memcmp(fileid, R_ADDR( - dbmp->reginfo, mfp->fileid_off), DB_FILE_ID_LEN) != 0) - continue; - - if (is_remove) { - MUTEX_LOCK(dbenv, mfp->mutex); - /* - * In-memory dbs have an artificially incremented - * ref count so that they do not ever get reclaimed - * as long as they exist. Since we are now deleting - * the database, we need to dec that count. - */ - if (mfp->no_backing_file) - mfp->mpf_cnt--; - mfp->deadfile = 1; - MUTEX_UNLOCK(dbenv, mfp->mutex); - } else { - /* - * Else, it's a rename. We've allocated memory - * for the new name. Swap it with the old one. - */ - p = R_ADDR(dbmp->reginfo, mfp->path_off); - mfp->path_off = newname_off; - } - save_mfp = mfp; - if (!inmem || is_remove) - break; - } - - /* Delete the memory we no longer need. */ - if (p != NULL) - __db_shalloc_free(&dbmp->reginfo[0], p); - -fsop: if (save_mfp == NULL && inmem) { - ret = ENOENT; - goto err; - } - - /* - * If this is a real file, then save_mfp could be NULL, because - * mpool isn't turned on, and we still need to do the file ops. - */ - if (save_mfp == NULL || !save_mfp->no_backing_file) { - if (is_remove) { - /* - * !!! - * Replication may ask us to unlink a file that's been - * renamed. Don't complain if it doesn't exist. - */ - if ((ret = __os_unlink(dbenv, fullold)) == ENOENT) - ret = 0; - } else { - /* - * Defensive only, fullname should never be - * NULL. - */ - DB_ASSERT(fullnew != NULL); - if (fullnew == NULL) - return (EINVAL); - ret = __os_rename(dbenv, fullold, fullnew, 1); - } - } - -err: if (locked) - MPOOL_SYSTEM_UNLOCK(dbenv); - - return (ret); -} - -/* - * __memp_get_refcnt - * Return a reference count, given a fileid. - * - * PUBLIC: int __memp_get_refcnt __P((DB_ENV *, u_int8_t *, u_int32_t *)); - */ -int -__memp_get_refcnt(dbenv, fileid, refp) - DB_ENV *dbenv; - u_int8_t *fileid; - u_int32_t *refp; -{ - DB_MPOOL *dbmp; - MPOOL *mp; - MPOOLFILE *mfp; - - *refp = 0; - - if (!MPOOL_ON(dbenv)) - return (0); - - dbmp = dbenv->mp_handle; - mp = dbmp->reginfo[0].primary; - - MPOOL_SYSTEM_LOCK(dbenv); - /* - * Find the file -- if mpool doesn't know about this file, the - * reference count is 0. - */ - for (mfp = SH_TAILQ_FIRST(&mp->mpfq, __mpoolfile); - mfp != NULL; mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile)) { - - /* Ignore non-active files. */ - if (mfp->deadfile || F_ISSET(mfp, MP_TEMP)) - continue; - - /* Ignore non-matching files. */ - if (memcmp(fileid, R_ADDR( - dbmp->reginfo, mfp->fileid_off), DB_FILE_ID_LEN) != 0) - continue; - - MUTEX_LOCK(dbenv, mfp->mutex); - *refp = mfp->mpf_cnt; - MUTEX_UNLOCK(dbenv, mfp->mutex); - break; - } - MPOOL_SYSTEM_UNLOCK(dbenv); - - return (0); -} - -#ifdef HAVE_FTRUNCATE -/* - * __memp_ftruncate __ - * Truncate the file. - * - * PUBLIC: int __memp_ftruncate __P((DB_MPOOLFILE *, db_pgno_t, u_int32_t)); - */ -int -__memp_ftruncate(dbmfp, pgno, flags) - DB_MPOOLFILE *dbmfp; - db_pgno_t pgno; - u_int32_t flags; -{ - DB_ENV *dbenv; - void *pagep; - db_pgno_t last_pgno, pg; - u_int32_t mbytes, bytes, pgsize; - int ret; - - dbenv = dbmfp->dbenv; - - MPOOL_SYSTEM_LOCK(dbenv); - last_pgno = dbmfp->mfp->last_pgno; - MPOOL_SYSTEM_UNLOCK(dbenv); - - if (pgno > last_pgno) { - if (LF_ISSET(MP_TRUNC_RECOVER)) - return (0); - __db_err(dbenv, "Truncate beyond the end of file"); - return (EINVAL); - } - - pg = pgno; - do { - if ((ret = - __memp_fget(dbmfp, &pg, DB_MPOOL_FREE, &pagep)) != 0) - return (ret); - } while (pg++ < last_pgno); - - /* - * If we are aborting an extend of a file, the call to __os_truncate - * could extend the file if the new page(s) had not yet been written - * to disk. If we are out of disk space, avoid generating an error on - * the truncate if we are actually extending the file. [#12743] - */ - if (!F_ISSET(dbmfp->mfp, MP_TEMP) && !dbmfp->mfp->no_backing_file && - (ret = __os_truncate(dbenv, - dbmfp->fhp, pgno, dbmfp->mfp->stat.st_pagesize)) != 0) { - if ((__os_ioinfo(dbenv, - NULL, dbmfp->fhp, &mbytes, &bytes, NULL)) != 0) - return (ret); - pgsize = dbmfp->mfp->stat.st_pagesize; - if (pgno < (mbytes * (MEGABYTE / pgsize)) + (bytes / pgsize)) - return (ret); - ret = 0; - } - - /* - * This set could race with another thread of control that extending - * the file. It's not a problem because we should have the page - * locked at a higher level of the system. - */ - MPOOL_SYSTEM_LOCK(dbenv); - dbmfp->mfp->last_pgno = pgno - 1; - MPOOL_SYSTEM_UNLOCK(dbenv); - - return (ret); -} - -/* - * Support routines for maintaining a sorted freelist - * while we try to rearrange and truncate the file. - */ - -/* - * __memp_alloc_freelist -- allocate mpool space for the freelist. - * - * PUBLIC: int __memp_alloc_freelist __P((DB_MPOOLFILE *, - * PUBLIC: u_int32_t, db_pgno_t **)); - */ -int -__memp_alloc_freelist(dbmfp, nelems, listp) - DB_MPOOLFILE *dbmfp; - u_int32_t nelems; - db_pgno_t **listp; -{ - DB_ENV *dbenv; - DB_MPOOL *dbmp; - MPOOLFILE *mfp; - void *retp; - int ret; - - dbenv = dbmfp->dbenv; - dbmp = dbenv->mp_handle; - mfp = dbmfp->mfp; - - *listp = NULL; - - /* - * These fields are protected because the database layer - * has the metapage locked while manipulating them. - */ - mfp->free_ref++; - if (mfp->free_size != 0) - return (EBUSY); - - /* Allocate at least a few slots. */ - mfp->free_cnt = nelems; - if (nelems == 0) - nelems = 50; - - if ((ret = __memp_alloc(dbmp, dbmp->reginfo, - NULL, nelems * sizeof(db_pgno_t), &mfp->free_list, &retp)) != 0) - return (ret); - - mfp->free_size = nelems * sizeof(db_pgno_t); - - *listp = retp; - - return (0); -} - -/* - * __memp_free_freelist -- free the list. - * - * PUBLIC: void __memp_free_freelist __P((DB_MPOOLFILE *)); - */ -void -__memp_free_freelist(dbmfp) - DB_MPOOLFILE *dbmfp; -{ - DB_ENV *dbenv; - DB_MPOOL *dbmp; - MPOOLFILE *mfp; - - dbenv = dbmfp->dbenv; - dbmp = dbenv->mp_handle; - mfp = dbmfp->mfp; - - DB_ASSERT(mfp->free_ref > 0); - if (--mfp->free_ref > 0) - return; - - DB_ASSERT(mfp->free_size != 0); - - __db_shalloc_free(dbmp->reginfo, R_ADDR(dbmp->reginfo, mfp->free_list)); - - mfp->free_cnt = 0; - mfp->free_list = 0; - mfp->free_size = 0; -} - -/* - * __memp_get_freelst -- return current list. - * - * PUBLIC: int __memp_get_freelist __P(( - * PUBLIC: DB_MPOOLFILE *, u_int32_t *, db_pgno_t **)); - */ -int -__memp_get_freelist(dbmfp, nelemp, listp) - DB_MPOOLFILE *dbmfp; - u_int32_t *nelemp; - db_pgno_t **listp; -{ - MPOOLFILE *mfp; - DB_ENV *dbenv; - DB_MPOOL *dbmp; - - dbenv = dbmfp->dbenv; - dbmp = dbenv->mp_handle; - mfp = dbmfp->mfp; - - if (mfp->free_size == 0) { - *nelemp = 0; - *listp = NULL; - return (0); - } - - *nelemp = mfp->free_cnt; - *listp = R_ADDR(dbmp->reginfo, mfp->free_list); - - return (0); -} - -/* - * __memp_extend_freelist -- extend the list. - * - * PUBLIC: int __memp_extend_freelist __P(( - * PUBLIC: DB_MPOOLFILE *, u_int32_t , db_pgno_t **)); - */ -int -__memp_extend_freelist(dbmfp, count, listp) - DB_MPOOLFILE *dbmfp; - u_int32_t count; - db_pgno_t **listp; -{ - DB_ENV *dbenv; - DB_MPOOL *dbmp; - MPOOLFILE *mfp; - int ret; - void *retp; - - dbenv = dbmfp->dbenv; - dbmp = dbenv->mp_handle; - mfp = dbmfp->mfp; - - if (mfp->free_size == 0) - return (EINVAL); - - if (count * sizeof(db_pgno_t) > mfp->free_size) { - mfp->free_size = - (size_t)DB_ALIGN(count * sizeof(db_pgno_t), 512); - *listp = R_ADDR(dbmp->reginfo, mfp->free_list); - if ((ret = __memp_alloc(dbmp, dbmp->reginfo, - NULL, mfp->free_size, &mfp->free_list, &retp)) != 0) - return (ret); - - memcpy(retp, *listp, mfp->free_cnt * sizeof(db_pgno_t)); - - __db_shalloc_free(dbmp->reginfo, *listp); - } - - mfp->free_cnt = count; - *listp = R_ADDR(dbmp->reginfo, mfp->free_list); - - return (0); -} -#endif diff --git a/storage/bdb/mp/mp_region.c b/storage/bdb/mp/mp_region.c deleted file mode 100644 index d16e79b6edf..00000000000 --- a/storage/bdb/mp/mp_region.c +++ /dev/null @@ -1,412 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: mp_region.c,v 12.7 2005/08/08 14:30:03 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_shash.h" -#include "dbinc/mp.h" - -static int __memp_init __P((DB_ENV *, DB_MPOOL *, u_int, u_int32_t)); -static int __memp_init_config __P((DB_ENV *, MPOOL *)); -static void __memp_region_size __P((DB_ENV *, roff_t *, u_int32_t *)); - -/* - * __memp_open -- - * Internal version of memp_open: only called from DB_ENV->open. - * - * PUBLIC: int __memp_open __P((DB_ENV *)); - */ -int -__memp_open(dbenv) - DB_ENV *dbenv; -{ - DB_MPOOL *dbmp; - MPOOL *mp; - REGINFO reginfo; - roff_t reg_size; - u_int i; - u_int32_t htab_buckets, *regids; - int ret; - - /* Calculate the region size and hash bucket count. */ - __memp_region_size(dbenv, ®_size, &htab_buckets); - - /* Create and initialize the DB_MPOOL structure. */ - if ((ret = __os_calloc(dbenv, 1, sizeof(*dbmp), &dbmp)) != 0) - return (ret); - LIST_INIT(&dbmp->dbregq); - TAILQ_INIT(&dbmp->dbmfq); - dbmp->dbenv = dbenv; - - /* Join/create the first mpool region. */ - memset(®info, 0, sizeof(REGINFO)); - reginfo.dbenv = dbenv; - reginfo.type = REGION_TYPE_MPOOL; - reginfo.id = INVALID_REGION_ID; - reginfo.flags = REGION_JOIN_OK; - if (F_ISSET(dbenv, DB_ENV_CREATE)) - F_SET(®info, REGION_CREATE_OK); - if ((ret = __db_r_attach(dbenv, ®info, reg_size)) != 0) - goto err; - - /* - * If we created the region, initialize it. Create or join any - * additional regions. - */ - if (F_ISSET(®info, REGION_CREATE)) { - /* - * We define how many regions there are going to be, allocate - * the REGINFO structures and create them. Make sure we don't - * clear the wrong entries on error. - */ - dbmp->nreg = dbenv->mp_ncache; - if ((ret = __os_calloc(dbenv, - dbmp->nreg, sizeof(REGINFO), &dbmp->reginfo)) != 0) - goto err; - /* Make sure we don't clear the wrong entries on error. */ - for (i = 0; i < dbmp->nreg; ++i) - dbmp->reginfo[i].id = INVALID_REGION_ID; - dbmp->reginfo[0] = reginfo; - - /* Initialize the first region. */ - if ((ret = __memp_init(dbenv, dbmp, 0, htab_buckets)) != 0) - goto err; - - /* - * Create/initialize remaining regions and copy their IDs into - * the first region. - */ - mp = R_ADDR(dbmp->reginfo, dbmp->reginfo[0].rp->primary); - regids = R_ADDR(dbmp->reginfo, mp->regids); - for (i = 1; i < dbmp->nreg; ++i) { - dbmp->reginfo[i].dbenv = dbenv; - dbmp->reginfo[i].type = REGION_TYPE_MPOOL; - dbmp->reginfo[i].id = INVALID_REGION_ID; - dbmp->reginfo[i].flags = REGION_CREATE_OK; - if ((ret = __db_r_attach( - dbenv, &dbmp->reginfo[i], reg_size)) != 0) - goto err; - if ((ret = - __memp_init(dbenv, dbmp, i, htab_buckets)) != 0) - goto err; - - regids[i] = dbmp->reginfo[i].id; - } - } else { - /* - * Determine how many regions there are going to be, allocate - * the REGINFO structures and fill in local copies of that - * information. - */ - mp = R_ADDR(®info, reginfo.rp->primary); - dbmp->nreg = mp->nreg; - if ((ret = __os_calloc(dbenv, - dbmp->nreg, sizeof(REGINFO), &dbmp->reginfo)) != 0) - goto err; - /* Make sure we don't clear the wrong entries on error. */ - for (i = 0; i < dbmp->nreg; ++i) - dbmp->reginfo[i].id = INVALID_REGION_ID; - dbmp->reginfo[0] = reginfo; - - /* Join remaining regions. */ - regids = R_ADDR(dbmp->reginfo, mp->regids); - for (i = 1; i < dbmp->nreg; ++i) { - dbmp->reginfo[i].dbenv = dbenv; - dbmp->reginfo[i].type = REGION_TYPE_MPOOL; - dbmp->reginfo[i].id = regids[i]; - dbmp->reginfo[i].flags = REGION_JOIN_OK; - if ((ret = __db_r_attach( - dbenv, &dbmp->reginfo[i], 0)) != 0) - goto err; - } - } - - /* Set the local addresses for the regions. */ - for (i = 0; i < dbmp->nreg; ++i) - dbmp->reginfo[i].primary = - R_ADDR(&dbmp->reginfo[i], dbmp->reginfo[i].rp->primary); - - /* If the region is threaded, allocate a mutex to lock the handles. */ - if ((ret = __mutex_alloc( - dbenv, MTX_MPOOL_HANDLE, DB_MUTEX_THREAD, &dbmp->mutex)) != 0) - goto err; - - dbenv->mp_handle = dbmp; - - /* A process joining the region may reset the mpool configuration. */ - if ((ret = __memp_init_config(dbenv, mp)) != 0) - return (ret); - - return (0); - -err: dbenv->mp_handle = NULL; - if (dbmp->reginfo != NULL && dbmp->reginfo[0].addr != NULL) { - for (i = 0; i < dbmp->nreg; ++i) - if (dbmp->reginfo[i].id != INVALID_REGION_ID) - (void)__db_r_detach( - dbenv, &dbmp->reginfo[i], 0); - __os_free(dbenv, dbmp->reginfo); - } - - (void)__mutex_free(dbenv, &dbmp->mutex); - __os_free(dbenv, dbmp); - return (ret); -} - -/* - * __memp_init -- - * Initialize a MPOOL structure in shared memory. - */ -static int -__memp_init(dbenv, dbmp, reginfo_off, htab_buckets) - DB_ENV *dbenv; - DB_MPOOL *dbmp; - u_int reginfo_off; - u_int32_t htab_buckets; -{ - DB_MPOOL_HASH *htab; - MPOOL *mp; - REGINFO *reginfo; - u_int32_t i; - int ret; - void *p; - - reginfo = &dbmp->reginfo[reginfo_off]; - if ((ret = __db_shalloc( - reginfo, sizeof(MPOOL), 0, ®info->primary)) != 0) - goto mem_err; - reginfo->rp->primary = R_OFFSET(reginfo, reginfo->primary); - mp = reginfo->primary; - memset(mp, 0, sizeof(*mp)); - - if ((ret = - __mutex_alloc(dbenv, MTX_MPOOL_REGION, 0, &mp->mtx_region)) != 0) - return (ret); - - if (reginfo_off == 0) { - SH_TAILQ_INIT(&mp->mpfq); - - ZERO_LSN(mp->lsn); - - mp->nreg = dbmp->nreg; - if ((ret = __db_shalloc(&dbmp->reginfo[0], - dbmp->nreg * sizeof(u_int32_t), 0, &p)) != 0) - goto mem_err; - mp->regids = R_OFFSET(dbmp->reginfo, p); - } - - /* Allocate hash table space and initialize it. */ - if ((ret = __db_shalloc(reginfo, - htab_buckets * sizeof(DB_MPOOL_HASH), 0, &htab)) != 0) - goto mem_err; - mp->htab = R_OFFSET(reginfo, htab); - for (i = 0; i < htab_buckets; i++) { - if ((ret = __mutex_alloc( - dbenv, MTX_MPOOL_HASH_BUCKET, 0, &htab[i].mtx_hash)) != 0) - return (ret); - SH_TAILQ_INIT(&htab[i].hash_bucket); - htab[i].hash_page_dirty = htab[i].hash_priority = 0; - } - mp->htab_buckets = mp->stat.st_hash_buckets = htab_buckets; - - /* - * Only the environment creator knows the total cache size, fill in - * those statistics now. - */ - mp->stat.st_gbytes = dbenv->mp_gbytes; - mp->stat.st_bytes = dbenv->mp_bytes; - return (0); - -mem_err:__db_err(dbenv, "Unable to allocate memory for mpool region"); - return (ret); -} - -/* - * __memp_region_size -- - * Size the region and figure out how many hash buckets we'll have. - */ -static void -__memp_region_size(dbenv, reg_sizep, htab_bucketsp) - DB_ENV *dbenv; - roff_t *reg_sizep; - u_int32_t *htab_bucketsp; -{ - roff_t reg_size; - - /* Figure out how big each cache region is. */ - reg_size = (roff_t)(dbenv->mp_gbytes / dbenv->mp_ncache) * GIGABYTE; - reg_size += ((roff_t)(dbenv->mp_gbytes % - dbenv->mp_ncache) * GIGABYTE) / dbenv->mp_ncache; - reg_size += dbenv->mp_bytes / dbenv->mp_ncache; - *reg_sizep = reg_size; - - /* - * Figure out how many hash buckets each region will have. Assume we - * want to keep the hash chains with under 10 pages on each chain. We - * don't know the pagesize in advance, and it may differ for different - * files. Use a pagesize of 1K for the calculation -- we walk these - * chains a lot, they must be kept short. - * - * XXX - * Cache sizes larger than 10TB would cause 32-bit wrapping in the - * calculation of the number of hash buckets. This probably isn't - * something we need to worry about right now, but is checked when the - * cache size is set. - */ - *htab_bucketsp = __db_tablesize((u_int32_t)(reg_size / (10 * 1024))); -} - -/* - * __memp_region_mutex_count -- - * Return the number of mutexes the mpool region will need. - * - * PUBLIC: u_int32_t __memp_region_mutex_count __P((DB_ENV *)); - */ -u_int32_t -__memp_region_mutex_count(dbenv) - DB_ENV *dbenv; -{ - roff_t reg_size; - u_int32_t htab_buckets; - - __memp_region_size(dbenv, ®_size, &htab_buckets); - - /* - * We need a couple of mutexes for the region itself, and one for each - * file handle (MPOOLFILE). More importantly, each configured cache - * has one mutex per hash bucket and buffer header. Hash buckets are - * configured to have 10 pages or fewer on each chain, but we don't - * want to fail if we have a large number of 512 byte pages, so double - * the guess. - */ - return (dbenv->mp_ncache * htab_buckets * 21 + 50); -} - -/* - * __memp_init_config -- - * Initialize shared configuration information. - */ -static int -__memp_init_config(dbenv, mp) - DB_ENV *dbenv; - MPOOL *mp; -{ - MPOOL_SYSTEM_LOCK(dbenv); - - if (dbenv->mp_mmapsize != 0) - mp->mp_mmapsize = dbenv->mp_mmapsize; - if (dbenv->mp_maxopenfd != 0) - mp->mp_maxopenfd = dbenv->mp_maxopenfd; - if (dbenv->mp_maxwrite != 0) - mp->mp_maxwrite = dbenv->mp_maxwrite; - if (dbenv->mp_maxwrite_sleep != 0) - mp->mp_maxwrite_sleep = dbenv->mp_maxwrite_sleep; - - MPOOL_SYSTEM_UNLOCK(dbenv); - - return (0); -} - -/* - * __memp_dbenv_refresh -- - * Clean up after the mpool system on a close or failed open. - * - * PUBLIC: int __memp_dbenv_refresh __P((DB_ENV *)); - */ -int -__memp_dbenv_refresh(dbenv) - DB_ENV *dbenv; -{ - BH *bhp; - DB_MPOOL *dbmp; - DB_MPOOLFILE *dbmfp; - DB_MPOOL_HASH *hp; - DB_MPREG *mpreg; - MPOOL *mp; - REGINFO *reginfo; - u_int32_t bucket, i; - int ret, t_ret; - - ret = 0; - dbmp = dbenv->mp_handle; - - /* - * If a private region, return the memory to the heap. Not needed for - * filesystem-backed or system shared memory regions, that memory isn't - * owned by any particular process. - * - * Discard buffers. - */ - if (F_ISSET(dbenv, DB_ENV_PRIVATE)) - for (i = 0; i < dbmp->nreg; ++i) { - reginfo = &dbmp->reginfo[i]; - mp = reginfo->primary; - for (hp = R_ADDR(reginfo, mp->htab), bucket = 0; - bucket < mp->htab_buckets; ++hp, ++bucket) - while ((bhp = SH_TAILQ_FIRST( - &hp->hash_bucket, __bh)) != NULL) - if ((t_ret = __memp_bhfree( - dbmp, hp, bhp, - BH_FREE_FREEMEM | - BH_FREE_UNLOCKED)) != 0 && ret == 0) - ret = t_ret; - } - - /* Discard DB_MPOOLFILEs. */ - while ((dbmfp = TAILQ_FIRST(&dbmp->dbmfq)) != NULL) - if ((t_ret = __memp_fclose(dbmfp, 0)) != 0 && ret == 0) - ret = t_ret; - - /* Discard DB_MPREGs. */ - if (dbmp->pg_inout != NULL) - __os_free(dbenv, dbmp->pg_inout); - while ((mpreg = LIST_FIRST(&dbmp->dbregq)) != NULL) { - LIST_REMOVE(mpreg, q); - __os_free(dbenv, mpreg); - } - - /* Discard the DB_MPOOL thread mutex. */ - if ((t_ret = __mutex_free(dbenv, &dbmp->mutex)) != 0 && ret == 0) - ret = t_ret; - - if (F_ISSET(dbenv, DB_ENV_PRIVATE)) { - /* Discard REGION IDs. */ - reginfo = &dbmp->reginfo[0]; - mp = dbmp->reginfo[0].primary; - __db_shalloc_free(reginfo, R_ADDR(reginfo, mp->regids)); - - /* Discard Hash tables. */ - for (i = 0; i < dbmp->nreg; ++i) { - reginfo = &dbmp->reginfo[i]; - mp = reginfo->primary; - __db_shalloc_free(reginfo, R_ADDR(reginfo, mp->htab)); - } - } - - /* Detach from the region. */ - for (i = 0; i < dbmp->nreg; ++i) { - reginfo = &dbmp->reginfo[i]; - if ((t_ret = __db_r_detach(dbenv, reginfo, 0)) != 0 && ret == 0) - ret = t_ret; - } - - /* Discard DB_MPOOL. */ - __os_free(dbenv, dbmp->reginfo); - __os_free(dbenv, dbmp); - - dbenv->mp_handle = NULL; - return (ret); -} diff --git a/storage/bdb/mp/mp_register.c b/storage/bdb/mp/mp_register.c deleted file mode 100644 index b93a07cc3de..00000000000 --- a/storage/bdb/mp/mp_register.c +++ /dev/null @@ -1,115 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: mp_register.c,v 12.6 2005/10/07 20:21:33 ubell Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - -#include "db_int.h" -#include "dbinc/db_shash.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" - -/* - * memp_register_pp -- - * DB_ENV->memp_register pre/post processing. - * - * PUBLIC: int __memp_register_pp __P((DB_ENV *, int, - * PUBLIC: int (*)(DB_ENV *, db_pgno_t, void *, DBT *), - * PUBLIC: int (*)(DB_ENV *, db_pgno_t, void *, DBT *))); - */ -int -__memp_register_pp(dbenv, ftype, pgin, pgout) - DB_ENV *dbenv; - int ftype; - int (*pgin) __P((DB_ENV *, db_pgno_t, void *, DBT *)); - int (*pgout) __P((DB_ENV *, db_pgno_t, void *, DBT *)); -{ - DB_THREAD_INFO *ip; - int ret; - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, - dbenv->mp_handle, "DB_ENV->memp_register", DB_INIT_MPOOL); - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, - (__memp_register(dbenv, ftype, pgin, pgout)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * memp_register -- - * DB_ENV->memp_register. - * - * PUBLIC: int __memp_register __P((DB_ENV *, int, - * PUBLIC: int (*)(DB_ENV *, db_pgno_t, void *, DBT *), - * PUBLIC: int (*)(DB_ENV *, db_pgno_t, void *, DBT *))); - */ -int -__memp_register(dbenv, ftype, pgin, pgout) - DB_ENV *dbenv; - int ftype; - int (*pgin) __P((DB_ENV *, db_pgno_t, void *, DBT *)); - int (*pgout) __P((DB_ENV *, db_pgno_t, void *, DBT *)); -{ - DB_MPOOL *dbmp; - DB_MPREG *mpreg; - int ret; - - dbmp = dbenv->mp_handle; - - /* - * We keep the DB pgin/pgout functions outside of the linked list - * to avoid locking/unlocking the linked list on every page I/O. - * - * The Berkeley DB I/O conversion functions are registered when the - * environment is first created, so there's no need for locking here. - */ - if (ftype == DB_FTYPE_SET) { - if (dbmp->pg_inout != NULL) - return (0); - if ((ret = - __os_malloc(dbenv, sizeof(DB_MPREG), &dbmp->pg_inout)) != 0) - return (ret); - dbmp->pg_inout->ftype = ftype; - dbmp->pg_inout->pgin = pgin; - dbmp->pg_inout->pgout = pgout; - return (0); - } - - /* - * The item may already have been registered. If already registered, - * just update the entry, although it's probably unchanged. - */ - MUTEX_LOCK(dbenv, dbmp->mutex); - for (mpreg = LIST_FIRST(&dbmp->dbregq); - mpreg != NULL; mpreg = LIST_NEXT(mpreg, q)) - if (mpreg->ftype == ftype) { - mpreg->pgin = pgin; - mpreg->pgout = pgout; - break; - } - - if (mpreg == NULL) { /* New entry. */ - if ((ret = __os_malloc(dbenv, sizeof(DB_MPREG), &mpreg)) != 0) - return (ret); - mpreg->ftype = ftype; - mpreg->pgin = pgin; - mpreg->pgout = pgout; - - LIST_INSERT_HEAD(&dbmp->dbregq, mpreg, q); - } - MUTEX_UNLOCK(dbenv, dbmp->mutex); - - return (0); -} diff --git a/storage/bdb/mp/mp_stat.c b/storage/bdb/mp/mp_stat.c deleted file mode 100644 index 24a37adf308..00000000000 --- a/storage/bdb/mp/mp_stat.c +++ /dev/null @@ -1,755 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: mp_stat.c,v 12.10 2005/10/27 01:26:00 mjc Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stdio.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/db_am.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" - -#ifdef HAVE_STATISTICS -static void __memp_print_bh - __P((DB_ENV *, DB_MPOOL *, BH *, roff_t *, u_int32_t)); -static int __memp_print_all __P((DB_ENV *, u_int32_t)); -static int __memp_print_stats __P((DB_ENV *, u_int32_t)); -static int __memp_print_hash __P((DB_ENV *, - DB_MPOOL *, REGINFO *, roff_t *, u_int32_t)); -static int __memp_stat __P((DB_ENV *, - DB_MPOOL_STAT **, DB_MPOOL_FSTAT ***, u_int32_t)); -static void __memp_stat_wait __P(( - DB_ENV *, REGINFO *, MPOOL *, DB_MPOOL_STAT *, u_int32_t)); - -/* - * __memp_stat_pp -- - * DB_ENV->memp_stat pre/post processing. - * - * PUBLIC: int __memp_stat_pp - * PUBLIC: __P((DB_ENV *, DB_MPOOL_STAT **, DB_MPOOL_FSTAT ***, u_int32_t)); - */ -int -__memp_stat_pp(dbenv, gspp, fspp, flags) - DB_ENV *dbenv; - DB_MPOOL_STAT **gspp; - DB_MPOOL_FSTAT ***fspp; - u_int32_t flags; -{ - DB_THREAD_INFO *ip; - int ret; - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, - dbenv->mp_handle, "DB_ENV->memp_stat", DB_INIT_MPOOL); - - if ((ret = __db_fchk(dbenv, - "DB_ENV->memp_stat", flags, DB_STAT_CLEAR)) != 0) - return (ret); - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, (__memp_stat(dbenv, gspp, fspp, flags)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __memp_stat -- - * DB_ENV->memp_stat - */ -static int -__memp_stat(dbenv, gspp, fspp, flags) - DB_ENV *dbenv; - DB_MPOOL_STAT **gspp; - DB_MPOOL_FSTAT ***fspp; - u_int32_t flags; -{ - DB_MPOOL *dbmp; - DB_MPOOL_FSTAT **tfsp, *tstruct; - DB_MPOOL_STAT *sp; - MPOOL *c_mp, *mp; - MPOOLFILE *mfp; - size_t len, nlen; - u_int32_t i, pagesize, st_bytes, st_gbytes, st_hash_buckets, st_pages; - u_int32_t tmp_wait, tmp_nowait; - int ret; - char *name, *tname; - - dbmp = dbenv->mp_handle; - mp = dbmp->reginfo[0].primary; - - /* Global statistics. */ - if (gspp != NULL) { - *gspp = NULL; - - if ((ret = __os_umalloc(dbenv, sizeof(**gspp), gspp)) != 0) - return (ret); - memset(*gspp, 0, sizeof(**gspp)); - sp = *gspp; - - /* - * Initialization and information that is not maintained on - * a per-cache basis. Note that configuration information - * may be modified at any time, and so we have to lock. - */ - c_mp = dbmp->reginfo[0].primary; - sp->st_gbytes = c_mp->stat.st_gbytes; - sp->st_bytes = c_mp->stat.st_bytes; - sp->st_ncache = dbmp->nreg; - sp->st_regsize = dbmp->reginfo[0].rp->size; - - MPOOL_SYSTEM_LOCK(dbenv); - sp->st_mmapsize = mp->mp_mmapsize; - sp->st_maxopenfd = mp->mp_maxopenfd; - sp->st_maxwrite = mp->mp_maxwrite; - sp->st_maxwrite_sleep = mp->mp_maxwrite_sleep; - MPOOL_SYSTEM_UNLOCK(dbenv); - - /* Walk the cache list and accumulate the global information. */ - for (i = 0; i < mp->nreg; ++i) { - c_mp = dbmp->reginfo[i].primary; - - sp->st_map += c_mp->stat.st_map; - sp->st_cache_hit += c_mp->stat.st_cache_hit; - sp->st_cache_miss += c_mp->stat.st_cache_miss; - sp->st_page_create += c_mp->stat.st_page_create; - sp->st_page_in += c_mp->stat.st_page_in; - sp->st_page_out += c_mp->stat.st_page_out; - sp->st_ro_evict += c_mp->stat.st_ro_evict; - sp->st_rw_evict += c_mp->stat.st_rw_evict; - sp->st_page_trickle += c_mp->stat.st_page_trickle; - sp->st_pages += c_mp->stat.st_pages; - /* - * st_page_dirty calculated by __memp_stat_hash - * st_page_clean calculated here - */ - __memp_stat_hash( - &dbmp->reginfo[i], c_mp, &sp->st_page_dirty); - sp->st_page_clean = sp->st_pages - sp->st_page_dirty; - sp->st_hash_buckets += c_mp->stat.st_hash_buckets; - sp->st_hash_searches += c_mp->stat.st_hash_searches; - sp->st_hash_longest += c_mp->stat.st_hash_longest; - sp->st_hash_examined += c_mp->stat.st_hash_examined; - /* - * st_hash_nowait calculated by __memp_stat_wait - * st_hash_wait - */ - __memp_stat_wait( - dbenv, &dbmp->reginfo[i], c_mp, sp, flags); - __mutex_set_wait_info(dbenv, - c_mp->mtx_region, &tmp_wait, &tmp_nowait); - sp->st_region_nowait += tmp_nowait; - sp->st_region_wait += tmp_wait; - sp->st_alloc += c_mp->stat.st_alloc; - sp->st_alloc_buckets += c_mp->stat.st_alloc_buckets; - if (sp->st_alloc_max_buckets < - c_mp->stat.st_alloc_max_buckets) - sp->st_alloc_max_buckets = - c_mp->stat.st_alloc_max_buckets; - sp->st_alloc_pages += c_mp->stat.st_alloc_pages; - if (sp->st_alloc_max_pages < - c_mp->stat.st_alloc_max_pages) - sp->st_alloc_max_pages = - c_mp->stat.st_alloc_max_pages; - - if (LF_ISSET(DB_STAT_CLEAR)) { - __mutex_clear(dbenv, c_mp->mtx_region); - - MPOOL_SYSTEM_LOCK(dbenv); - st_bytes = c_mp->stat.st_bytes; - st_gbytes = c_mp->stat.st_gbytes; - st_hash_buckets = c_mp->stat.st_hash_buckets; - st_pages = c_mp->stat.st_pages; - memset(&c_mp->stat, 0, sizeof(c_mp->stat)); - c_mp->stat.st_bytes = st_bytes; - c_mp->stat.st_gbytes = st_gbytes; - c_mp->stat.st_hash_buckets = st_hash_buckets; - c_mp->stat.st_pages = st_pages; - MPOOL_SYSTEM_UNLOCK(dbenv); - } - } - - /* - * We have duplicate statistics fields in per-file structures - * and the cache. The counters are only incremented in the - * per-file structures, except if a file is flushed from the - * mpool, at which time we copy its information into the cache - * statistics. We added the cache information above, now we - * add the per-file information. - */ - MPOOL_SYSTEM_LOCK(dbenv); - for (mfp = SH_TAILQ_FIRST(&mp->mpfq, __mpoolfile); - mfp != NULL; mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile)) { - sp->st_map += mfp->stat.st_map; - sp->st_cache_hit += mfp->stat.st_cache_hit; - sp->st_cache_miss += mfp->stat.st_cache_miss; - sp->st_page_create += mfp->stat.st_page_create; - sp->st_page_in += mfp->stat.st_page_in; - sp->st_page_out += mfp->stat.st_page_out; - if (fspp == NULL && LF_ISSET(DB_STAT_CLEAR)) { - pagesize = mfp->stat.st_pagesize; - memset(&mfp->stat, 0, sizeof(mfp->stat)); - mfp->stat.st_pagesize = pagesize; - } - } - MPOOL_SYSTEM_UNLOCK(dbenv); - } - - /* Per-file statistics. */ - if (fspp != NULL) { - *fspp = NULL; - - /* Count the MPOOLFILE structures. */ - MPOOL_SYSTEM_LOCK(dbenv); - for (i = 0, len = 0, - mfp = SH_TAILQ_FIRST(&mp->mpfq, __mpoolfile); - mfp != NULL; - ++i, mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile)) - len += sizeof(DB_MPOOL_FSTAT *) + - sizeof(DB_MPOOL_FSTAT) + - strlen(__memp_fns(dbmp, mfp)) + 1; - len += sizeof(DB_MPOOL_FSTAT *); /* Trailing NULL */ - MPOOL_SYSTEM_UNLOCK(dbenv); - - if (i == 0) - return (0); - - /* Allocate space */ - if ((ret = __os_umalloc(dbenv, len, fspp)) != 0) - return (ret); - - /* - * Build each individual entry. We assume that an array of - * pointers are aligned correctly to be followed by an array - * of structures, which should be safe (in this particular - * case, the first element of the structure is a pointer, so - * we're doubly safe). The array is followed by space for - * the text file names. - * - * Add 1 to i because we need to skip over the NULL. - */ - tfsp = *fspp; - tstruct = (DB_MPOOL_FSTAT *)(tfsp + i + 1); - tname = (char *)(tstruct + i); - - /* - * Files may have been opened since we counted, don't walk - * off the end of the allocated space. - */ - MPOOL_SYSTEM_LOCK(dbenv); - for (mfp = SH_TAILQ_FIRST(&mp->mpfq, __mpoolfile); - mfp != NULL && i-- > 0; - ++tfsp, ++tstruct, tname += nlen, - mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile)) { - name = __memp_fns(dbmp, mfp); - nlen = strlen(name) + 1; - *tfsp = tstruct; - *tstruct = mfp->stat; - if (LF_ISSET(DB_STAT_CLEAR)) { - pagesize = mfp->stat.st_pagesize; - memset(&mfp->stat, 0, sizeof(mfp->stat)); - mfp->stat.st_pagesize = pagesize; - } - tstruct->file_name = tname; - memcpy(tname, name, nlen); - } - MPOOL_SYSTEM_UNLOCK(dbenv); - - *tfsp = NULL; - } - return (0); -} - -/* - * __memp_stat_print_pp -- - * DB_ENV->memp_stat_print pre/post processing. - * - * PUBLIC: int __memp_stat_print_pp __P((DB_ENV *, u_int32_t)); - */ -int -__memp_stat_print_pp(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - DB_THREAD_INFO *ip; - int ret; - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, - dbenv->mp_handle, "DB_ENV->memp_stat_print", DB_INIT_MPOOL); - -#define DB_STAT_MEMP_FLAGS \ - (DB_STAT_ALL | DB_STAT_CLEAR | DB_STAT_MEMP_HASH) - if ((ret = __db_fchk(dbenv, - "DB_ENV->memp_stat_print", flags, DB_STAT_MEMP_FLAGS)) != 0) - return (ret); - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, (__memp_stat_print(dbenv, flags)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -#define FMAP_ENTRIES 200 /* Files we map. */ - -/* - * __memp_stat_print -- - * DB_ENV->memp_stat_print method. - * - * PUBLIC: int __memp_stat_print __P((DB_ENV *, u_int32_t)); - */ -int -__memp_stat_print(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - u_int32_t orig_flags; - int ret; - - orig_flags = flags; - LF_CLR(DB_STAT_CLEAR); - if (flags == 0 || LF_ISSET(DB_STAT_ALL)) { - ret = __memp_print_stats(dbenv, orig_flags); - if (flags == 0 || ret != 0) - return (ret); - } - - if (LF_ISSET(DB_STAT_ALL | DB_STAT_MEMP_HASH) && - (ret = __memp_print_all(dbenv, orig_flags)) != 0) - return (ret); - - return (0); -} - -/* - * __memp_print_stats -- - * Display default mpool region statistics. - */ -static int -__memp_print_stats(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - DB_MPOOL_FSTAT **fsp, **tfsp; - DB_MPOOL_STAT *gsp; - int ret; - - if ((ret = __memp_stat(dbenv, &gsp, &fsp, flags)) != 0) - return (ret); - - if (LF_ISSET(DB_STAT_ALL)) - __db_msg(dbenv, "Default cache region information:"); - __db_dlbytes(dbenv, "Total cache size", - (u_long)gsp->st_gbytes, (u_long)0, (u_long)gsp->st_bytes); - __db_dl(dbenv, "Number of caches", (u_long)gsp->st_ncache); - __db_dlbytes(dbenv, "Pool individual cache size", - (u_long)0, (u_long)0, (u_long)gsp->st_regsize); - __db_dlbytes(dbenv, "Maximum memory-mapped file size", - (u_long)0, (u_long)0, (u_long)gsp->st_mmapsize); - STAT_LONG("Maximum open file descriptors", gsp->st_maxopenfd); - STAT_LONG("Maximum sequential buffer writes", gsp->st_maxwrite); - STAT_LONG("Sleep after writing maximum sequential buffers", - gsp->st_maxwrite_sleep); - __db_dl(dbenv, - "Requested pages mapped into the process' address space", - (u_long)gsp->st_map); - __db_dl_pct(dbenv, "Requested pages found in the cache", - (u_long)gsp->st_cache_hit, DB_PCT( - gsp->st_cache_hit, gsp->st_cache_hit + gsp->st_cache_miss), NULL); - __db_dl(dbenv, "Requested pages not found in the cache", - (u_long)gsp->st_cache_miss); - __db_dl(dbenv, - "Pages created in the cache", (u_long)gsp->st_page_create); - __db_dl(dbenv, "Pages read into the cache", (u_long)gsp->st_page_in); - __db_dl(dbenv, "Pages written from the cache to the backing file", - (u_long)gsp->st_page_out); - __db_dl(dbenv, "Clean pages forced from the cache", - (u_long)gsp->st_ro_evict); - __db_dl(dbenv, "Dirty pages forced from the cache", - (u_long)gsp->st_rw_evict); - __db_dl(dbenv, "Dirty pages written by trickle-sync thread", - (u_long)gsp->st_page_trickle); - __db_dl(dbenv, "Current total page count", - (u_long)gsp->st_pages); - __db_dl(dbenv, "Current clean page count", - (u_long)gsp->st_page_clean); - __db_dl(dbenv, "Current dirty page count", - (u_long)gsp->st_page_dirty); - __db_dl(dbenv, "Number of hash buckets used for page location", - (u_long)gsp->st_hash_buckets); - __db_dl(dbenv, - "Total number of times hash chains searched for a page", - (u_long)gsp->st_hash_searches); - __db_dl(dbenv, "The longest hash chain searched for a page", - (u_long)gsp->st_hash_longest); - __db_dl(dbenv, - "Total number of hash chain entries checked for page", - (u_long)gsp->st_hash_examined); - __db_dl_pct(dbenv, - "The number of hash bucket locks that required waiting", - (u_long)gsp->st_hash_wait, DB_PCT( - gsp->st_hash_wait, gsp->st_hash_wait + gsp->st_hash_nowait), NULL); - __db_dl(dbenv, - "The maximum number of times any hash bucket lock was waited for", - (u_long)gsp->st_hash_max_wait); - __db_dl_pct(dbenv, - "The number of region locks that required waiting", - (u_long)gsp->st_region_wait, DB_PCT(gsp->st_region_wait, - gsp->st_region_wait + gsp->st_region_nowait), NULL); - __db_dl(dbenv, "The number of page allocations", (u_long)gsp->st_alloc); - __db_dl(dbenv, - "The number of hash buckets examined during allocations", - (u_long)gsp->st_alloc_buckets); - __db_dl(dbenv, - "The maximum number of hash buckets examined for an allocation", - (u_long)gsp->st_alloc_max_buckets); - __db_dl(dbenv, "The number of pages examined during allocations", - (u_long)gsp->st_alloc_pages); - __db_dl(dbenv, "The max number of pages examined for an allocation", - (u_long)gsp->st_alloc_max_pages); - - for (tfsp = fsp; fsp != NULL && *tfsp != NULL; ++tfsp) { - if (LF_ISSET(DB_STAT_ALL)) - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_msg(dbenv, "Pool File: %s", (*tfsp)->file_name); - __db_dl(dbenv, "Page size", (u_long)(*tfsp)->st_pagesize); - __db_dl(dbenv, - "Requested pages mapped into the process' address space", - (u_long)(*tfsp)->st_map); - __db_dl_pct(dbenv, "Requested pages found in the cache", - (u_long)(*tfsp)->st_cache_hit, DB_PCT((*tfsp)->st_cache_hit, - (*tfsp)->st_cache_hit + (*tfsp)->st_cache_miss), NULL); - __db_dl(dbenv, "Requested pages not found in the cache", - (u_long)(*tfsp)->st_cache_miss); - __db_dl(dbenv, "Pages created in the cache", - (u_long)(*tfsp)->st_page_create); - __db_dl(dbenv, "Pages read into the cache", - (u_long)(*tfsp)->st_page_in); - __db_dl(dbenv, - "Pages written from the cache to the backing file", - (u_long)(*tfsp)->st_page_out); - } - - __os_ufree(dbenv, fsp); - __os_ufree(dbenv, gsp); - return (0); -} - -/* - * __memp_print_all -- - * Display debugging mpool region statistics. - */ -static int -__memp_print_all(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - static const FN fn[] = { - { MP_CAN_MMAP, "MP_CAN_MMAP" }, - { MP_DIRECT, "MP_DIRECT" }, - { MP_EXTENT, "MP_EXTENT" }, - { MP_FAKE_DEADFILE, "deadfile" }, - { MP_FAKE_FILEWRITTEN, "file written" }, - { MP_FAKE_NB, "no backing file" }, - { MP_FAKE_UOC, "unlink on close" }, - { MP_NOT_DURABLE, "not durable" }, - { MP_TEMP, "MP_TEMP" }, - { 0, NULL } - }; - static const FN cfn[] = { - { DB_MPOOL_NOFILE, "DB_MPOOL_NOFILE" }, - { DB_MPOOL_UNLINK, "DB_MPOOL_UNLINK" }, - { 0, NULL } - }; - DB_MPOOL *dbmp; - DB_MPOOLFILE *dbmfp; - MPOOL *mp; - MPOOLFILE *mfp; - roff_t fmap[FMAP_ENTRIES + 1]; - u_int32_t i, mfp_flags; - int cnt, ret; - - dbmp = dbenv->mp_handle; - mp = dbmp->reginfo[0].primary; - ret = 0; - - MPOOL_SYSTEM_LOCK(dbenv); - - __db_print_reginfo(dbenv, dbmp->reginfo, "Mpool"); - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - - __db_msg(dbenv, "MPOOL structure:"); - __mutex_print_debug_single( - dbenv, "MPOOL region mutex", mp->mtx_region, flags); - STAT_LSN("Maximum checkpoint LSN", &mp->lsn); - STAT_ULONG("Hash table entries", mp->htab_buckets); - STAT_ULONG("Hash table last-checked", mp->last_checked); - STAT_ULONG("Hash table LRU count", mp->lru_count); - STAT_ULONG("Put counter", mp->put_counter); - - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_msg(dbenv, "DB_MPOOL handle information:"); - __mutex_print_debug_single( - dbenv, "DB_MPOOL handle mutex", dbmp->mutex, flags); - STAT_ULONG("Underlying cache regions", dbmp->nreg); - - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_msg(dbenv, "DB_MPOOLFILE structures:"); - for (cnt = 0, dbmfp = TAILQ_FIRST(&dbmp->dbmfq); - dbmfp != NULL; dbmfp = TAILQ_NEXT(dbmfp, q), ++cnt) { - __db_msg(dbenv, "File #%d: %s: per-process, %s", - cnt + 1, __memp_fn(dbmfp), - F_ISSET(dbmfp, MP_READONLY) ? "readonly" : "read/write"); - STAT_ULONG("Reference count", dbmfp->ref); - STAT_ULONG("Pinned block reference count", dbmfp->ref); - STAT_ULONG("Clear length", dbmfp->clear_len); - __db_print_fileid(dbenv, dbmfp->fileid, "\tID"); - STAT_ULONG("File type", dbmfp->ftype); - STAT_ULONG("LSN offset", dbmfp->lsn_offset); - STAT_ULONG("Max gbytes", dbmfp->gbytes); - STAT_ULONG("Max bytes", dbmfp->bytes); - STAT_ULONG("Cache priority", dbmfp->priority); - STAT_POINTER("mmap address", dbmfp->addr); - STAT_ULONG("mmap length", dbmfp->len); - __db_prflags(dbenv, NULL, dbmfp->flags, cfn, NULL, "\tFlags"); - __db_print_fh(dbenv, "File handle", dbmfp->fhp, flags); - } - - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_msg(dbenv, "MPOOLFILE structures:"); - for (cnt = 0, mfp = SH_TAILQ_FIRST(&mp->mpfq, __mpoolfile); - mfp != NULL; mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile), ++cnt) { - __db_msg(dbenv, "File #%d: %s", cnt + 1, __memp_fns(dbmp, mfp)); - __mutex_print_debug_single(dbenv, "Mutex", mfp->mutex, flags); - - MUTEX_LOCK(dbenv, mfp->mutex); - STAT_ULONG("Reference count", mfp->mpf_cnt); - STAT_ULONG("Block count", mfp->block_cnt); - STAT_ULONG("Last page number", mfp->last_pgno); - STAT_ULONG("Original last page number", mfp->orig_last_pgno); - STAT_ULONG("Maximum page number", mfp->maxpgno); - STAT_LONG("Type", mfp->ftype); - STAT_LONG("Priority", mfp->priority); - STAT_LONG("Page's LSN offset", mfp->lsn_off); - STAT_LONG("Page's clear length", mfp->clear_len); - - __db_print_fileid(dbenv, - R_ADDR(dbmp->reginfo, mfp->fileid_off), "\tID"); - - mfp_flags = 0; - if (mfp->deadfile) - FLD_SET(mfp_flags, MP_FAKE_DEADFILE); - if (mfp->file_written) - FLD_SET(mfp_flags, MP_FAKE_FILEWRITTEN); - if (mfp->no_backing_file) - FLD_SET(mfp_flags, MP_FAKE_NB); - if (mfp->unlink_on_close) - FLD_SET(mfp_flags, MP_FAKE_UOC); - __db_prflags(dbenv, NULL, mfp_flags, fn, NULL, "\tFlags"); - - if (cnt < FMAP_ENTRIES) - fmap[cnt] = R_OFFSET(dbmp->reginfo, mfp); - MUTEX_UNLOCK(dbenv, mfp->mutex); - } - MPOOL_SYSTEM_UNLOCK(dbenv); - - if (cnt < FMAP_ENTRIES) - fmap[cnt] = INVALID_ROFF; - else - fmap[FMAP_ENTRIES] = INVALID_ROFF; - - /* Dump the individual caches. */ - for (i = 0; i < mp->nreg; ++i) { - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_msg(dbenv, "Cache #%d:", i + 1); - if ((ret = __memp_print_hash( - dbenv, dbmp, &dbmp->reginfo[i], fmap, flags)) != 0) - break; - } - - return (ret); -} - -/* - * __memp_print_hash -- - * Display hash bucket statistics for a cache. - */ -static int -__memp_print_hash(dbenv, dbmp, reginfo, fmap, flags) - DB_ENV *dbenv; - DB_MPOOL *dbmp; - REGINFO *reginfo; - roff_t *fmap; - u_int32_t flags; -{ - BH *bhp; - DB_MPOOL_HASH *hp; - DB_MSGBUF mb; - MPOOL *c_mp; - u_int32_t bucket; - - c_mp = reginfo->primary; - DB_MSGBUF_INIT(&mb); - - /* Display the hash table list of BH's. */ - __db_msg(dbenv, - "BH hash table (%lu hash slots)", (u_long)c_mp->htab_buckets); - __db_msg(dbenv, "bucket #: priority, [mutex]"); - __db_msg(dbenv, - "\tpageno, file, ref, LSN, [mutex], address, priority, flags"); - - for (hp = R_ADDR(reginfo, c_mp->htab), - bucket = 0; bucket < c_mp->htab_buckets; ++hp, ++bucket) { - MUTEX_LOCK(dbenv, hp->mtx_hash); - if ((bhp = SH_TAILQ_FIRST(&hp->hash_bucket, __bh)) != NULL) { - __db_msgadd(dbenv, &mb, "bucket %lu: %lu, ", - (u_long)bucket, (u_long)hp->hash_priority); - __mutex_print_debug_stats( - dbenv, &mb, hp->mtx_hash, flags); - DB_MSGBUF_FLUSH(dbenv, &mb); - } - for (; bhp != NULL; bhp = SH_TAILQ_NEXT(bhp, hq, __bh)) - __memp_print_bh(dbenv, dbmp, bhp, fmap, flags); - - MUTEX_UNLOCK(dbenv, hp->mtx_hash); - } - - return (0); -} - -/* - * __memp_print_bh -- - * Display a BH structure. - */ -static void -__memp_print_bh(dbenv, dbmp, bhp, fmap, flags) - DB_ENV *dbenv; - DB_MPOOL *dbmp; - BH *bhp; - roff_t *fmap; - u_int32_t flags; -{ - static const FN fn[] = { - { BH_CALLPGIN, "callpgin" }, - { BH_DIRTY, "dirty" }, - { BH_DIRTY_CREATE, "created" }, - { BH_DISCARD, "discard" }, - { BH_LOCKED, "locked" }, - { BH_TRASH, "trash" }, - { 0, NULL } - }; - DB_MSGBUF mb; - int i; - - DB_MSGBUF_INIT(&mb); - - for (i = 0; i < FMAP_ENTRIES; ++i) - if (fmap[i] == INVALID_ROFF || fmap[i] == bhp->mf_offset) - break; - - if (fmap[i] == INVALID_ROFF) - __db_msgadd(dbenv, &mb, "\t%5lu, %lu, ", - (u_long)bhp->pgno, (u_long)bhp->mf_offset); - else - __db_msgadd( - dbenv, &mb, "\t%5lu, #%d, ", (u_long)bhp->pgno, i + 1); - - __db_msgadd(dbenv, &mb, "%2lu, %lu/%lu, ", (u_long)bhp->ref, - (u_long)LSN(bhp->buf).file, (u_long)LSN(bhp->buf).offset); - __mutex_print_debug_stats(dbenv, &mb, bhp->mtx_bh, flags); - __db_msgadd(dbenv, &mb, ", %#08lx, %lu", - (u_long)R_OFFSET(dbmp->reginfo, bhp), (u_long)bhp->priority); - __db_prflags(dbenv, &mb, bhp->flags, fn, " (", ")"); - DB_MSGBUF_FLUSH(dbenv, &mb); -} - -/* - * __memp_stat_wait -- - * Total hash bucket wait stats into the region. - */ -static void -__memp_stat_wait(dbenv, reginfo, mp, mstat, flags) - DB_ENV *dbenv; - REGINFO *reginfo; - MPOOL *mp; - DB_MPOOL_STAT *mstat; - u_int32_t flags; -{ - DB_MPOOL_HASH *hp; - u_int32_t i, tmp_nowait, tmp_wait; - - mstat->st_hash_max_wait = 0; - hp = R_ADDR(reginfo, mp->htab); - for (i = 0; i < mp->htab_buckets; i++, hp++) { - __mutex_set_wait_info( - dbenv, hp->mtx_hash, &tmp_wait, &tmp_nowait); - mstat->st_hash_nowait += tmp_nowait; - mstat->st_hash_wait += tmp_wait; - if (tmp_wait > mstat->st_hash_max_wait) - mstat->st_hash_max_wait = tmp_wait; - - if (LF_ISSET(DB_STAT_CLEAR)) - __mutex_clear(dbenv, hp->mtx_hash); - } -} - -#else /* !HAVE_STATISTICS */ - -int -__memp_stat_pp(dbenv, gspp, fspp, flags) - DB_ENV *dbenv; - DB_MPOOL_STAT **gspp; - DB_MPOOL_FSTAT ***fspp; - u_int32_t flags; -{ - COMPQUIET(gspp, NULL); - COMPQUIET(fspp, NULL); - COMPQUIET(flags, 0); - - return (__db_stat_not_built(dbenv)); -} - -int -__memp_stat_print_pp(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - COMPQUIET(flags, 0); - - return (__db_stat_not_built(dbenv)); -} -#endif - -/* - * __memp_stat_hash -- - * Total hash bucket stats (other than mutex wait) into the region. - * - * PUBLIC: void __memp_stat_hash __P((REGINFO *, MPOOL *, u_int32_t *)); - */ -void -__memp_stat_hash(reginfo, mp, dirtyp) - REGINFO *reginfo; - MPOOL *mp; - u_int32_t *dirtyp; -{ - DB_MPOOL_HASH *hp; - u_int32_t dirty, i; - - hp = R_ADDR(reginfo, mp->htab); - for (i = 0, dirty = 0; i < mp->htab_buckets; i++, hp++) - dirty += hp->hash_page_dirty; - *dirtyp = dirty; -} diff --git a/storage/bdb/mp/mp_sync.c b/storage/bdb/mp/mp_sync.c deleted file mode 100644 index cfc7c4f52da..00000000000 --- a/storage/bdb/mp/mp_sync.c +++ /dev/null @@ -1,858 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: mp_sync.c,v 12.11 2005/10/07 20:21:33 ubell Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stdlib.h> -#endif - -#include "db_int.h" -#include "dbinc/db_shash.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" - -typedef struct { - DB_MPOOL_HASH *track_hp; /* Hash bucket. */ - - roff_t track_off; /* Page file offset. */ - db_pgno_t track_pgno; /* Page number. */ -} BH_TRACK; - -static int __bhcmp __P((const void *, const void *)); -static int __memp_close_flush_files __P((DB_ENV *, DB_MPOOL *, int)); -static int __memp_sync_files __P((DB_ENV *, DB_MPOOL *)); - -/* - * __memp_sync_pp -- - * DB_ENV->memp_sync pre/post processing. - * - * PUBLIC: int __memp_sync_pp __P((DB_ENV *, DB_LSN *)); - */ -int -__memp_sync_pp(dbenv, lsnp) - DB_ENV *dbenv; - DB_LSN *lsnp; -{ - DB_THREAD_INFO *ip; - int ret; - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, - dbenv->mp_handle, "memp_sync", DB_INIT_MPOOL); - - /* - * If no LSN is provided, flush the entire cache (reasonable usage - * even if there's no log subsystem configured). - */ - if (lsnp != NULL) - ENV_REQUIRES_CONFIG(dbenv, - dbenv->lg_handle, "memp_sync", DB_INIT_LOG); - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, (__memp_sync(dbenv, lsnp)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __memp_sync -- - * DB_ENV->memp_sync. - * - * PUBLIC: int __memp_sync __P((DB_ENV *, DB_LSN *)); - */ -int -__memp_sync(dbenv, lsnp) - DB_ENV *dbenv; - DB_LSN *lsnp; -{ - DB_MPOOL *dbmp; - MPOOL *mp; - int ret; - - dbmp = dbenv->mp_handle; - mp = dbmp->reginfo[0].primary; - - /* If we've flushed to the requested LSN, return that information. */ - if (lsnp != NULL) { - MPOOL_SYSTEM_LOCK(dbenv); - if (log_compare(lsnp, &mp->lsn) <= 0) { - *lsnp = mp->lsn; - - MPOOL_SYSTEM_UNLOCK(dbenv); - return (0); - } - MPOOL_SYSTEM_UNLOCK(dbenv); - } - - if ((ret = __memp_sync_int(dbenv, NULL, 0, DB_SYNC_CACHE, NULL)) != 0) - return (ret); - - if (lsnp != NULL) { - MPOOL_SYSTEM_LOCK(dbenv); - if (log_compare(lsnp, &mp->lsn) > 0) - mp->lsn = *lsnp; - MPOOL_SYSTEM_UNLOCK(dbenv); - } - - return (0); -} - -/* - * __memp_fsync_pp -- - * DB_MPOOLFILE->sync pre/post processing. - * - * PUBLIC: int __memp_fsync_pp __P((DB_MPOOLFILE *)); - */ -int -__memp_fsync_pp(dbmfp) - DB_MPOOLFILE *dbmfp; -{ - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int ret; - - dbenv = dbmfp->dbenv; - - PANIC_CHECK(dbenv); - MPF_ILLEGAL_BEFORE_OPEN(dbmfp, "DB_MPOOLFILE->sync"); - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, (__memp_fsync(dbmfp)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __memp_fsync -- - * DB_MPOOLFILE->sync. - * - * PUBLIC: int __memp_fsync __P((DB_MPOOLFILE *)); - */ -int -__memp_fsync(dbmfp) - DB_MPOOLFILE *dbmfp; -{ - MPOOLFILE *mfp; - - mfp = dbmfp->mfp; - - /* - * If this handle doesn't have a file descriptor that's open for - * writing, or if the file is a temporary, or if the file hasn't - * been written since it was flushed, there's no reason to proceed - * further. - */ - if (F_ISSET(dbmfp, MP_READONLY)) - return (0); - - if (F_ISSET(dbmfp->mfp, MP_TEMP) || dbmfp->mfp->no_backing_file) - return (0); - - if (mfp->file_written == 0) - return (0); - - return (__memp_sync_int(dbmfp->dbenv, dbmfp, 0, DB_SYNC_FILE, NULL)); -} - -/* - * __mp_xxx_fh -- - * Return a file descriptor for DB 1.85 compatibility locking. - * - * PUBLIC: int __mp_xxx_fh __P((DB_MPOOLFILE *, DB_FH **)); - */ -int -__mp_xxx_fh(dbmfp, fhp) - DB_MPOOLFILE *dbmfp; - DB_FH **fhp; -{ - /* - * This is a truly spectacular layering violation, intended ONLY to - * support compatibility for the DB 1.85 DB->fd call. - * - * Sync the database file to disk, creating the file as necessary. - * - * We skip the MP_READONLY and MP_TEMP tests done by memp_fsync(3). - * The MP_READONLY test isn't interesting because we will either - * already have a file descriptor (we opened the database file for - * reading) or we aren't readonly (we created the database which - * requires write privileges). The MP_TEMP test isn't interesting - * because we want to write to the backing file regardless so that - * we get a file descriptor to return. - */ - if ((*fhp = dbmfp->fhp) != NULL) - return (0); - - return (__memp_sync_int(dbmfp->dbenv, dbmfp, 0, DB_SYNC_FILE, NULL)); -} - -/* - * __memp_sync_int -- - * Mpool sync internal function. - * - * PUBLIC: int __memp_sync_int __P((DB_ENV *, - * PUBLIC: DB_MPOOLFILE *, u_int32_t, db_sync_op, u_int32_t *)); - */ -int -__memp_sync_int(dbenv, dbmfp, trickle_max, op, wrotep) - DB_ENV *dbenv; - DB_MPOOLFILE *dbmfp; - u_int32_t trickle_max, *wrotep; - db_sync_op op; -{ - BH *bhp; - BH_TRACK *bharray; - DB_MPOOL *dbmp; - DB_MPOOL_HASH *hp; - MPOOL *c_mp, *mp; - MPOOLFILE *mfp; - db_mutex_t mutex; - roff_t last_mf_offset; - u_int32_t ar_cnt, ar_max, i, n_cache, remaining, wrote; - int filecnt, hb_lock, maxopenfd, maxwrite, maxwrite_sleep; - int pass, ret, t_ret, wait_cnt, write_cnt; - - dbmp = dbenv->mp_handle; - mp = dbmp->reginfo[0].primary; - last_mf_offset = INVALID_ROFF; - filecnt = pass = wrote = 0; - - /* Get shared configuration information. */ - MPOOL_SYSTEM_LOCK(dbenv); - maxopenfd = mp->mp_maxopenfd; - maxwrite = mp->mp_maxwrite; - maxwrite_sleep = mp->mp_maxwrite_sleep; - MPOOL_SYSTEM_UNLOCK(dbenv); - - /* Assume one dirty page per bucket. */ - ar_max = mp->nreg * mp->htab_buckets; - if ((ret = - __os_malloc(dbenv, ar_max * sizeof(BH_TRACK), &bharray)) != 0) - return (ret); - - /* - * Walk each cache's list of buffers and mark all dirty buffers to be - * written and all pinned buffers to be potentially written, depending - * on our flags. - */ - for (ar_cnt = 0, n_cache = 0; n_cache < mp->nreg; ++n_cache) { - c_mp = dbmp->reginfo[n_cache].primary; - - hp = R_ADDR(&dbmp->reginfo[n_cache], c_mp->htab); - for (i = 0; i < c_mp->htab_buckets; i++, hp++) { - /* - * We can check for empty buckets before locking as we - * only care if the pointer is zero or non-zero. We - * can ignore empty buckets because we only need write - * buffers that were dirty before we started. - */ - if (SH_TAILQ_FIRST(&hp->hash_bucket, __bh) == NULL) - continue; - - MUTEX_LOCK(dbenv, hp->mtx_hash); - for (bhp = SH_TAILQ_FIRST(&hp->hash_bucket, __bh); - bhp != NULL; bhp = SH_TAILQ_NEXT(bhp, hq, __bh)) { - /* Always ignore unreferenced, clean pages. */ - if (bhp->ref == 0 && !F_ISSET(bhp, BH_DIRTY)) - continue; - - /* - * Checkpoints have to wait on all pinned pages, - * as pages may be marked dirty when returned to - * the cache. - * - * File syncs only wait on pages both pinned and - * dirty. (We don't care if pages are marked - * dirty when returned to the cache, that means - * there's another writing thread and flushing - * the cache for this handle is meaningless.) - */ - if (op == DB_SYNC_FILE && - !F_ISSET(bhp, BH_DIRTY)) - continue; - - mfp = R_ADDR(dbmp->reginfo, bhp->mf_offset); - - /* - * Ignore in-memory files, even if they are - * temp files to whom a backing file has been - * allocated. - */ - if (mfp->no_backing_file || - F_ISSET(mfp, MP_TEMP)) - continue; - - /* - * If we're flushing a specific file, see if - * this page is from that file. - */ - if (dbmfp != NULL && mfp != dbmfp->mfp) - continue; - - /* - * Ignore files that aren't involved in DB's - * transactional operations during checkpoints. - */ - if (dbmfp == NULL && mfp->lsn_off == -1) - continue; - - /* Track the buffer, we want it. */ - bharray[ar_cnt].track_hp = hp; - bharray[ar_cnt].track_pgno = bhp->pgno; - bharray[ar_cnt].track_off = bhp->mf_offset; - ar_cnt++; - - /* - * If we run out of space, double and continue. - * Don't stop at trickle_max, we want to sort - * as large a sample set as possible in order - * to minimize disk seeks. - */ - if (ar_cnt >= ar_max) { - if ((ret = __os_realloc(dbenv, - (ar_max * 2) * sizeof(BH_TRACK), - &bharray)) != 0) - break; - ar_max *= 2; - } - } - MUTEX_UNLOCK(dbenv, hp->mtx_hash); - - if (ret != 0) - goto err; - } - } - - /* If there no buffers to write, we're done. */ - if (ar_cnt == 0) - goto done; - - /* - * Write the buffers in file/page order, trying to reduce seeks by the - * filesystem and, when pages are smaller than filesystem block sizes, - * reduce the actual number of writes. - */ - if (ar_cnt > 1) - qsort(bharray, ar_cnt, sizeof(BH_TRACK), __bhcmp); - - /* - * If we're trickling buffers, only write enough to reach the correct - * percentage. - */ - if (op == DB_SYNC_TRICKLE && ar_cnt > trickle_max) - ar_cnt = trickle_max; - - /* - * Flush the log. We have to ensure the log records reflecting the - * changes on the database pages we're writing have already made it - * to disk. We still have to check the log each time we write a page - * (because pages we are about to write may be modified after we have - * flushed the log), but in general this will at least avoid any I/O - * on the log's part. - */ - if (LOGGING_ON(dbenv) && (ret = __log_flush(dbenv, NULL)) != 0) - goto err; - - /* - * Walk the array, writing buffers. When we write a buffer, we NULL - * out its hash bucket pointer so we don't process a slot more than - * once. - */ - for (i = pass = write_cnt = 0, remaining = ar_cnt; remaining > 0; ++i) { - if (i >= ar_cnt) { - i = 0; - ++pass; - __os_sleep(dbenv, 1, 0); - } - if ((hp = bharray[i].track_hp) == NULL) - continue; - - /* Lock the hash bucket and find the buffer. */ - mutex = hp->mtx_hash; - MUTEX_LOCK(dbenv, mutex); - for (bhp = SH_TAILQ_FIRST(&hp->hash_bucket, __bh); - bhp != NULL; bhp = SH_TAILQ_NEXT(bhp, hq, __bh)) - if (bhp->pgno == bharray[i].track_pgno && - bhp->mf_offset == bharray[i].track_off) - break; - - /* - * If we can't find the buffer we're done, somebody else had - * to have written it. - * - * If the buffer isn't pinned or dirty, we're done, there's - * no work needed. - */ - if (bhp == NULL || (bhp->ref == 0 && !F_ISSET(bhp, BH_DIRTY))) { - MUTEX_UNLOCK(dbenv, mutex); - --remaining; - bharray[i].track_hp = NULL; - continue; - } - - /* - * If the buffer is locked by another thread, ignore it, we'll - * come back to it. - * - * If the buffer is pinned and it's only the first or second - * time we have looked at it, ignore it, we'll come back to - * it. - * - * In either case, skip the buffer if we're not required to - * write it. - */ - if (F_ISSET(bhp, BH_LOCKED) || (bhp->ref != 0 && pass < 2)) { - MUTEX_UNLOCK(dbenv, mutex); - if (op != DB_SYNC_CACHE && op != DB_SYNC_FILE) { - --remaining; - bharray[i].track_hp = NULL; - } - continue; - } - - /* - * The buffer is either pinned or dirty. - * - * Set the sync wait-for count, used to count down outstanding - * references to this buffer as they are returned to the cache. - */ - bhp->ref_sync = bhp->ref; - - /* Pin the buffer into memory and lock it. */ - ++bhp->ref; - F_SET(bhp, BH_LOCKED); - MUTEX_LOCK(dbenv, bhp->mtx_bh); - - /* - * Unlock the hash bucket and wait for the wait-for count to - * go to 0. No new thread can acquire the buffer because we - * have it locked. - * - * If a thread attempts to re-pin a page, the wait-for count - * will never go to 0 (the thread spins on our buffer lock, - * while we spin on the thread's ref count). Give up if we - * don't get the buffer in 3 seconds, we can try again later. - * - * If, when the wait-for count goes to 0, the buffer is found - * to be dirty, write it. - */ - MUTEX_UNLOCK(dbenv, mutex); - for (wait_cnt = 1; - bhp->ref_sync != 0 && wait_cnt < 4; ++wait_cnt) - __os_sleep(dbenv, 1, 0); - MUTEX_LOCK(dbenv, mutex); - hb_lock = 1; - - /* - * If we've switched files, check to see if we're configured - * to close file descriptors. - */ - if (maxopenfd != 0 && bhp->mf_offset != last_mf_offset) { - if (++filecnt >= maxopenfd) { - filecnt = 0; - if ((ret = __memp_close_flush_files( - dbenv, dbmp, 1)) != 0) - break; - } - last_mf_offset = bhp->mf_offset; - } - - /* - * If the ref_sync count has gone to 0, we're going to be done - * with this buffer no matter what happens. - */ - if (bhp->ref_sync == 0) { - --remaining; - bharray[i].track_hp = NULL; - } - - /* - * If the ref_sync count has gone to 0 and the buffer is still - * dirty, we write it. We only try to write the buffer once. - */ - if (bhp->ref_sync == 0 && F_ISSET(bhp, BH_DIRTY)) { - hb_lock = 0; - MUTEX_UNLOCK(dbenv, mutex); - - mfp = R_ADDR(dbmp->reginfo, bhp->mf_offset); - if ((ret = __memp_bhwrite(dbmp, hp, mfp, bhp, 1)) == 0) - ++wrote; - else - __db_err(dbenv, "%s: unable to flush page: %lu", - __memp_fns(dbmp, mfp), (u_long)bhp->pgno); - - /* - * Avoid saturating the disk, sleep once we've done - * some number of writes. - */ - if (maxwrite != 0 && ++write_cnt >= maxwrite) { - write_cnt = 0; - __os_sleep(dbenv, 0, (u_long)maxwrite_sleep); - } - } - - /* - * If ref_sync count never went to 0, the buffer was written - * by another thread, or the write failed, we still have the - * buffer locked. - * - * We may or may not currently hold the hash bucket mutex. If - * the __memp_bhwrite -> __memp_pgwrite call was successful, - * then __memp_pgwrite will have swapped the buffer lock for - * the hash lock. All other call paths will leave us without - * the hash bucket lock. - * - * The order of mutexes above was to acquire the buffer lock - * while holding the hash bucket lock. Don't deadlock here, - * release the buffer lock and then acquire the hash bucket - * lock. - */ - if (F_ISSET(bhp, BH_LOCKED)) { - F_CLR(bhp, BH_LOCKED); - MUTEX_UNLOCK(dbenv, bhp->mtx_bh); - - if (!hb_lock) - MUTEX_LOCK(dbenv, mutex); - } - - /* - * Reset the ref_sync count regardless of our success, we're - * done with this buffer for now. - */ - bhp->ref_sync = 0; - - /* Discard our reference and unlock the bucket. */ - --bhp->ref; - MUTEX_UNLOCK(dbenv, mutex); - - if (ret != 0) - break; - } - -done: /* - * If doing a checkpoint or flushing a file for the application, we - * have to force the pages to disk. We don't do this as we go along - * because we want to give the OS as much time as possible to lazily - * flush, and because we have to flush files that might not even have - * had dirty buffers in the cache, so we have to walk the files list. - */ - if (ret == 0 && (op == DB_SYNC_CACHE || op == DB_SYNC_FILE)) { - if (dbmfp == NULL) - ret = __memp_sync_files(dbenv, dbmp); - else - ret = __os_fsync(dbenv, dbmfp->fhp); - } - - /* If we've opened files to flush pages, close them. */ - if ((t_ret = __memp_close_flush_files(dbenv, dbmp, 0)) != 0 && ret == 0) - ret = t_ret; - -err: __os_free(dbenv, bharray); - if (wrotep != NULL) - *wrotep = wrote; - - return (ret); -} - -/* - * __memp_sync_files -- - * Sync all the files in the environment, open or not. - */ -static -int __memp_sync_files(dbenv, dbmp) - DB_ENV *dbenv; - DB_MPOOL *dbmp; -{ - DB_MPOOLFILE *dbmfp; - MPOOL *mp; - MPOOLFILE *mfp, *next_mfp; - int need_discard_pass, ret, t_ret; - - need_discard_pass = ret = 0; - mp = dbmp->reginfo[0].primary; - - MPOOL_SYSTEM_LOCK(dbenv); - for (mfp = SH_TAILQ_FIRST(&mp->mpfq, __mpoolfile); - mfp != NULL; mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile)) { - if (!mfp->file_written || mfp->no_backing_file || - mfp->deadfile || F_ISSET(mfp, MP_TEMP)) - continue; - /* - * Pin the MPOOLFILE structure into memory, and release the - * region mutex allowing us to walk the linked list. We'll - * re-acquire that mutex to move to the next entry in the list. - * - * This works because we only need to flush current entries, - * we don't care about new entries being added, and the linked - * list is never re-ordered, a single pass is sufficient. It - * requires MPOOLFILE structures removed before we get to them - * be flushed to disk, but that's nothing new, they could have - * been removed while checkpoint was running, too. - * - * Once we have the MPOOLFILE lock, re-check the MPOOLFILE is - * not being discarded. (A thread removing the MPOOLFILE - * will: hold the MPOOLFILE mutex, set deadfile, drop the - * MPOOLFILE mutex and then acquire the region MUTEX to walk - * the linked list and remove the MPOOLFILE structure. Make - * sure the MPOOLFILE wasn't marked dead while we waited for - * the mutex. - */ - MUTEX_LOCK(dbenv, mfp->mutex); - if (!mfp->file_written || mfp->deadfile) { - MUTEX_UNLOCK(dbenv, mfp->mutex); - continue; - } - MPOOL_SYSTEM_UNLOCK(dbenv); - ++mfp->mpf_cnt; - MUTEX_UNLOCK(dbenv, mfp->mutex); - - /* - * Look for an already open, writeable handle (fsync doesn't - * work on read-only Windows handles). - */ - MUTEX_LOCK(dbenv, dbmp->mutex); - for (dbmfp = TAILQ_FIRST(&dbmp->dbmfq); - dbmfp != NULL; dbmfp = TAILQ_NEXT(dbmfp, q)) { - if (dbmfp->mfp != mfp || F_ISSET(dbmfp, MP_READONLY)) - continue; - /* - * We don't want to hold the mutex while calling sync. - * Increment the DB_MPOOLFILE handle ref count to pin - * it into memory. - */ - ++dbmfp->ref; - break; - } - MUTEX_UNLOCK(dbenv, dbmp->mutex); - - /* If we don't find a handle we can use, open one. */ - if (dbmfp == NULL) { - if ((t_ret = __memp_mf_sync(dbmp, mfp, 0)) != 0) { - __db_err(dbenv, - "%s: unable to flush: %s", (char *) - R_ADDR(dbmp->reginfo, mfp->path_off), - db_strerror(t_ret)); - if (ret == 0) - ret = t_ret; - } - } else { - if ((t_ret = - __os_fsync(dbenv, dbmfp->fhp)) != 0 && ret == 0) - ret = t_ret; - - if ((t_ret = __memp_fclose(dbmfp, 0)) != 0 && ret == 0) - ret = t_ret; - } - - /* - * Re-acquire the region lock, we need it to move to the next - * MPOOLFILE. - * - * Re-acquire the MPOOLFILE mutex, we need it to modify the - * reference count. - */ - MPOOL_SYSTEM_LOCK(dbenv); - MUTEX_LOCK(dbenv, mfp->mutex); - --mfp->mpf_cnt; - - /* - * If we wrote the file and there are no open handles (or there - * is a single open handle, and it's the one we opened to write - * buffers during checkpoint), clear the file_written flag. We - * do this so that applications opening thousands of files don't - * loop here opening and flushing those files during checkpoint. - * - * The danger here is if a buffer were to be written as part of - * a checkpoint, and then not be flushed to disk. This cannot - * happen because we only clear file_written when there are no - * other users of the MPOOLFILE in the system, and, as we hold - * the region lock, no possibility of another thread of control - * racing with us to open a MPOOLFILE. - */ - if (mfp->mpf_cnt == 0 || (mfp->mpf_cnt == 1 && - dbmfp != NULL && F_ISSET(dbmfp, MP_FLUSH))) { - mfp->file_written = 0; - - /* - * We may be the last reference for a MPOOLFILE, as we - * weren't holding the MPOOLFILE mutex when flushing - * it's buffers to disk. If we can discard it, set - * a flag to schedule a clean-out pass. (Not likely, - * I mean, what are the chances that there aren't any - * buffers in the pool? Regardless, it might happen.) - */ - if (mfp->mpf_cnt == 0 && mfp->block_cnt == 0) - need_discard_pass = 1; - } - - /* Unlock the MPOOLFILE, and move to the next entry. */ - MUTEX_UNLOCK(dbenv, mfp->mutex); - } - - /* - * We exit the loop holding the region lock. - * - * We may need to do a last pass through the MPOOLFILE list -- if we - * were the last reference to an MPOOLFILE, we need to clean it out. - */ - if (need_discard_pass) - for (mfp = SH_TAILQ_FIRST( - &mp->mpfq, __mpoolfile); mfp != NULL; mfp = next_mfp) { - next_mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile); - - /* - * Do a fast check -- we can check for zero/non-zero - * without a mutex on the MPOOLFILE. If likely to - * succeed, lock the MPOOLFILE down and look for real. - */ - if (mfp->block_cnt != 0 || mfp->mpf_cnt != 0) - continue; - - MUTEX_LOCK(dbenv, mfp->mutex); - if (mfp->block_cnt == 0 && mfp->mpf_cnt == 0) - (void)__memp_mf_discard(dbmp, mfp); - else - MUTEX_UNLOCK(dbenv, mfp->mutex); - } - MPOOL_SYSTEM_UNLOCK(dbenv); - - return (ret); -} - -/* - * __memp_mf_sync -- - * Flush an MPOOLFILE, when no currently open handle is available. - * - * PUBLIC: int __memp_mf_sync __P((DB_MPOOL *, MPOOLFILE *, int)); - */ -int -__memp_mf_sync(dbmp, mfp, region_locked) - DB_MPOOL *dbmp; - MPOOLFILE *mfp; - int region_locked; -{ - DB_ENV *dbenv; - DB_FH *fhp; - int ret, t_ret; - char *rpath; - - dbenv = dbmp->dbenv; - - /* - * We need to be holding the region lock: we're using the path name - * and __memp_nameop might try and rename the file. - */ - if (!region_locked) - MPOOL_SYSTEM_LOCK(dbenv); - - if ((ret = __db_appname(dbenv, DB_APP_DATA, - R_ADDR(dbmp->reginfo, mfp->path_off), 0, NULL, &rpath)) == 0) { - if ((ret = __os_open(dbenv, rpath, 0, 0, &fhp)) == 0) { - ret = __os_fsync(dbenv, fhp); - if ((t_ret = - __os_closehandle(dbenv, fhp)) != 0 && ret == 0) - ret = t_ret; - } - __os_free(dbenv, rpath); - } - - if (!region_locked) - MPOOL_SYSTEM_UNLOCK(dbenv); - - return (ret); -} - -/* - * __memp_close_flush_files -- - * Close files opened only to flush buffers. - */ -static int -__memp_close_flush_files(dbenv, dbmp, dosync) - DB_ENV *dbenv; - DB_MPOOL *dbmp; - int dosync; -{ - DB_MPOOLFILE *dbmfp; - MPOOLFILE *mfp; - int ret; - - /* - * The routine exists because we must close files opened by sync to - * flush buffers. There are two cases: first, extent files have to - * be closed so they may be removed when empty. Second, regular - * files have to be closed so we don't run out of descriptors (for - * example, an application partitioning its data into databases - * based on timestamps, so there's a continually increasing set of - * files). - * - * We mark files opened in the __memp_bhwrite() function with the - * MP_FLUSH flag. Here we walk through our file descriptor list, - * and, if a file was opened by __memp_bhwrite(), we close it. - */ -retry: MUTEX_LOCK(dbenv, dbmp->mutex); - for (dbmfp = TAILQ_FIRST(&dbmp->dbmfq); - dbmfp != NULL; dbmfp = TAILQ_NEXT(dbmfp, q)) - if (F_ISSET(dbmfp, MP_FLUSH)) { - F_CLR(dbmfp, MP_FLUSH); - MUTEX_UNLOCK(dbenv, dbmp->mutex); - if (dosync) { - /* - * If we have the only open handle on the file, - * clear the dirty flag so we don't re-open and - * sync it again when discarding the MPOOLFILE - * structure. Clear the flag before the sync - * so can't race with a thread writing the file. - */ - mfp = dbmfp->mfp; - if (mfp->mpf_cnt == 1) { - MUTEX_LOCK(dbenv, mfp->mutex); - if (mfp->mpf_cnt == 1) - mfp->file_written = 0; - MUTEX_UNLOCK(dbenv, mfp->mutex); - } - if ((ret = __os_fsync(dbenv, dbmfp->fhp)) != 0) - return (ret); - } - if ((ret = __memp_fclose(dbmfp, 0)) != 0) - return (ret); - goto retry; - } - MUTEX_UNLOCK(dbenv, dbmp->mutex); - - return (0); -} - -static int -__bhcmp(p1, p2) - const void *p1, *p2; -{ - BH_TRACK *bhp1, *bhp2; - - bhp1 = (BH_TRACK *)p1; - bhp2 = (BH_TRACK *)p2; - - /* Sort by file (shared memory pool offset). */ - if (bhp1->track_off < bhp2->track_off) - return (-1); - if (bhp1->track_off > bhp2->track_off) - return (1); - - /* - * !!! - * Defend against badly written quicksort code calling the comparison - * function with two identical pointers (e.g., WATCOM C++ (Power++)). - */ - if (bhp1->track_pgno < bhp2->track_pgno) - return (-1); - if (bhp1->track_pgno > bhp2->track_pgno) - return (1); - return (0); -} diff --git a/storage/bdb/mp/mp_trickle.c b/storage/bdb/mp/mp_trickle.c deleted file mode 100644 index 4c6a2d0c82e..00000000000 --- a/storage/bdb/mp/mp_trickle.c +++ /dev/null @@ -1,106 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: mp_trickle.c,v 12.4 2005/10/07 20:21:33 ubell Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stdlib.h> -#endif - -#include "db_int.h" -#include "dbinc/db_shash.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" - -static int __memp_trickle __P((DB_ENV *, int, int *)); - -/* - * __memp_trickle_pp -- - * DB_ENV->memp_trickle pre/post processing. - * - * PUBLIC: int __memp_trickle_pp __P((DB_ENV *, int, int *)); - */ -int -__memp_trickle_pp(dbenv, pct, nwrotep) - DB_ENV *dbenv; - int pct, *nwrotep; -{ - DB_THREAD_INFO *ip; - int ret; - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, - dbenv->mp_handle, "memp_trickle", DB_INIT_MPOOL); - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, (__memp_trickle(dbenv, pct, nwrotep)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __memp_trickle -- - * DB_ENV->memp_trickle. - */ -static int -__memp_trickle(dbenv, pct, nwrotep) - DB_ENV *dbenv; - int pct, *nwrotep; -{ - DB_MPOOL *dbmp; - MPOOL *c_mp, *mp; - u_int32_t dirty, i, total, dtmp, wrote; - int n, ret; - - dbmp = dbenv->mp_handle; - mp = dbmp->reginfo[0].primary; - - if (nwrotep != NULL) - *nwrotep = 0; - - if (pct < 1 || pct > 100) - return (EINVAL); - - /* - * If there are sufficient clean buffers, no buffers or no dirty - * buffers, we're done. - * - * XXX - * Using hash_page_dirty is our only choice at the moment, but it's not - * as correct as we might like in the presence of pools having more - * than one page size, as a free 512B buffer isn't the same as a free - * 8KB buffer. - * - * Loop through the caches counting total/dirty buffers. - */ - for (ret = 0, i = dirty = total = 0; i < mp->nreg; ++i) { - c_mp = dbmp->reginfo[i].primary; - total += c_mp->stat.st_pages; - __memp_stat_hash(&dbmp->reginfo[i], c_mp, &dtmp); - dirty += dtmp; - } - - /* - * !!! - * Be careful in modifying this calculation, total may be 0. - */ - n = ((total * (u_int)pct) / 100) - (total - dirty); - if (dirty == 0 || n <= 0) - return (0); - - ret = __memp_sync_int( - dbenv, NULL, (u_int32_t)n, DB_SYNC_TRICKLE, &wrote); - mp->stat.st_page_trickle += wrote; - if (nwrotep != NULL) - *nwrotep = (int)wrote; - - return (ret); -} diff --git a/storage/bdb/mutex/README b/storage/bdb/mutex/README deleted file mode 100644 index 23527586a72..00000000000 --- a/storage/bdb/mutex/README +++ /dev/null @@ -1,110 +0,0 @@ -# $Id: README,v 12.1 2005/07/20 16:51:55 bostic Exp $ - -Note: this only applies to locking using test-and-set and fcntl calls, -pthreads were added after this was written. - -Resource locking routines: lock based on a DB_MUTEX. All this gunk -(including trying to make assembly code portable), is necessary because -System V semaphores require system calls for uncontested locks and we -don't want to make two system calls per resource lock. - -First, this is how it works. The DB_MUTEX structure contains a resource -test-and-set lock (tsl), a file offset, a pid for debugging and statistics -information. - -If HAVE_MUTEX_FCNTL is NOT defined (that is, we know how to do -test-and-sets for this compiler/architecture combination), we try and -lock the resource tsl some number of times (based on the number of -processors). If we can't acquire the mutex that way, we use a system -call to sleep for 1ms, 2ms, 4ms, etc. (The time is bounded at 10ms for -mutexes backing logical locks and 25 ms for data structures, just in -case.) Using the timer backoff means that there are two assumptions: -that mutexes are held for brief periods (never over system calls or I/O) -and mutexes are not hotly contested. - -If HAVE_MUTEX_FCNTL is defined, we use a file descriptor to do byte -locking on a file at a specified offset. In this case, ALL of the -locking is done in the kernel. Because file descriptors are allocated -per process, we have to provide the file descriptor as part of the lock -call. We still have to do timer backoff because we need to be able to -block ourselves, that is, the lock manager causes processes to wait by -having the process acquire a mutex and then attempting to re-acquire the -mutex. There's no way to use kernel locking to block yourself, that is, -if you hold a lock and attempt to re-acquire it, the attempt will -succeed. - -Next, let's talk about why it doesn't work the way a reasonable person -would think it should work. - -Ideally, we'd have the ability to try to lock the resource tsl, and if -that fails, increment a counter of waiting processes, then block in the -kernel until the tsl is released. The process holding the resource tsl -would see the wait counter when it went to release the resource tsl, and -would wake any waiting processes up after releasing the lock. This would -actually require both another tsl (call it the mutex tsl) and -synchronization between the call that blocks in the kernel and the actual -resource tsl. The mutex tsl would be used to protect accesses to the -DB_MUTEX itself. Locking the mutex tsl would be done by a busy loop, -which is safe because processes would never block holding that tsl (all -they would do is try to obtain the resource tsl and set/check the wait -count). The problem in this model is that the blocking call into the -kernel requires a blocking semaphore, i.e. one whose normal state is -locked. - -The only portable forms of locking under UNIX are fcntl(2) on a file -descriptor/offset, and System V semaphores. Neither of these locking -methods are sufficient to solve the problem. - -The problem with fcntl locking is that only the process that obtained the -lock can release it. Remember, we want the normal state of the kernel -semaphore to be locked. So, if the creator of the DB_MUTEX were to -initialize the lock to "locked", then a second process locks the resource -tsl, and then a third process needs to block, waiting for the resource -tsl, when the second process wants to wake up the third process, it can't -because it's not the holder of the lock! For the second process to be -the holder of the lock, we would have to make a system call per -uncontested lock, which is what we were trying to get away from in the -first place. - -There are some hybrid schemes, such as signaling the holder of the lock, -or using a different blocking offset depending on which process is -holding the lock, but it gets complicated fairly quickly. I'm open to -suggestions, but I'm not holding my breath. - -Regardless, we use this form of locking when we don't have any other -choice, because it doesn't have the limitations found in System V -semaphores, and because the normal state of the kernel object in that -case is unlocked, so the process releasing the lock is also the holder -of the lock. - -The System V semaphore design has a number of other limitations that make -it inappropriate for this task. Namely: - -First, the semaphore key name space is separate from the file system name -space (although there exist methods for using file names to create -semaphore keys). If we use a well-known key, there's no reason to believe -that any particular key will not already be in use, either by another -instance of the DB application or some other application, in which case -the DB application will fail. If we create a key, then we have to use a -file system name to rendezvous and pass around the key. - -Second, System V semaphores traditionally have compile-time, system-wide -limits on the number of semaphore keys that you can have. Typically, that -number is far too low for any practical purpose. Since the semaphores -permit more than a single slot per semaphore key, we could try and get -around that limit by using multiple slots, but that means that the file -that we're using for rendezvous is going to have to contain slot -information as well as semaphore key information, and we're going to be -reading/writing it on every db_mutex_t init or destroy operation. Anyhow, -similar compile-time, system-wide limits on the numbers of slots per -semaphore key kick in, and you're right back where you started. - -My fantasy is that once POSIX.1 standard mutexes are in wide-spread use, -we can switch to them. My guess is that it won't happen, because the -POSIX semaphores are only required to work for threads within a process, -and not independent processes. - -Note: there are races in the statistics code, but since it's just that, -I didn't bother fixing them. (The fix requires a mutex tsl, so, when/if -this code is fixed to do rational locking (see above), then change the -statistics update code to acquire/release the mutex tsl. diff --git a/storage/bdb/mutex/mut_alloc.c b/storage/bdb/mutex/mut_alloc.c deleted file mode 100644 index ad91d3d66b3..00000000000 --- a/storage/bdb/mutex/mut_alloc.c +++ /dev/null @@ -1,229 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: mut_alloc.c,v 12.6 2005/08/08 14:57:54 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/mutex_int.h" - -static int __mutex_free_int __P((DB_ENV *, int, db_mutex_t *)); - -/* - * __mutex_alloc -- - * Allocate a mutex from the mutex region. - * - * PUBLIC: int __mutex_alloc __P((DB_ENV *, int, u_int32_t, db_mutex_t *)); - */ -int -__mutex_alloc(dbenv, alloc_id, flags, indxp) - DB_ENV *dbenv; - int alloc_id; - u_int32_t flags; - db_mutex_t *indxp; -{ - int ret; - - /* The caller may depend on us to initialize. */ - *indxp = MUTEX_INVALID; - - /* - * If this is not an application lock, and we've turned off locking, - * or the DB_ENV handle isn't thread-safe, and this is a thread lock - * or the environment isn't multi-process by definition, there's no - * need to mutex at all. - */ - if (alloc_id != MTX_APPLICATION && - (F_ISSET(dbenv, DB_ENV_NOLOCKING) || - (!F_ISSET(dbenv, DB_ENV_THREAD) && - (LF_ISSET(DB_MUTEX_THREAD) || F_ISSET(dbenv, DB_ENV_PRIVATE))))) - return (0); - - /* - * If we have a region in which to allocate the mutexes, lock it and - * do the allocation. - */ - if (MUTEX_ON(dbenv)) - return (__mutex_alloc_int(dbenv, 1, alloc_id, flags, indxp)); - - /* - * We have to allocate some number of mutexes before we have a region - * in which to allocate them. We handle this by saving up the list of - * flags and allocating them as soon as we have a handle. - * - * The list of mutexes to alloc is maintained in pairs: first the - * alloc_id argument, second the flags passed in by the caller. - */ - if (dbenv->mutex_iq == NULL) { - dbenv->mutex_iq_max = 50; - if ((ret = __os_calloc(dbenv, dbenv->mutex_iq_max, - sizeof(dbenv->mutex_iq[0]), &dbenv->mutex_iq)) != 0) - return (ret); - } else if (dbenv->mutex_iq_next == dbenv->mutex_iq_max - 1) { - dbenv->mutex_iq_max *= 2; - if ((ret = __os_realloc(dbenv, - dbenv->mutex_iq_max * sizeof(dbenv->mutex_iq[0]), - &dbenv->mutex_iq)) != 0) - return (ret); - } - *indxp = dbenv->mutex_iq_next + 1; /* Correct for MUTEX_INVALID. */ - dbenv->mutex_iq[dbenv->mutex_iq_next].alloc_id = alloc_id; - dbenv->mutex_iq[dbenv->mutex_iq_next].flags = flags; - ++dbenv->mutex_iq_next; - - return (0); -} - -/* - * __mutex_alloc_int -- - * Internal routine to allocate a mutex. - * - * PUBLIC: int __mutex_alloc_int - * PUBLIC: __P((DB_ENV *, int, int, u_int32_t, db_mutex_t *)); - */ -int -__mutex_alloc_int(dbenv, locksys, alloc_id, flags, indxp) - DB_ENV *dbenv; - int locksys, alloc_id; - u_int32_t flags; - db_mutex_t *indxp; -{ - DB_MUTEX *mutexp; - DB_MUTEXMGR *mtxmgr; - DB_MUTEXREGION *mtxregion; - int ret; - - mtxmgr = dbenv->mutex_handle; - mtxregion = mtxmgr->reginfo.primary; - ret = 0; - - /* - * If we're not initializing the mutex region, then lock the region to - * allocate new mutexes. Drop the lock before initializing the mutex, - * mutex initialization may require a system call. - */ - if (locksys) - MUTEX_SYSTEM_LOCK(dbenv); - - if (mtxregion->mutex_next == MUTEX_INVALID) { - __db_err(dbenv, - "unable to allocate memory for mutex; resize mutex region"); - if (locksys) - MUTEX_SYSTEM_UNLOCK(dbenv); - return (ENOMEM); - } - - *indxp = mtxregion->mutex_next; - mutexp = MUTEXP_SET(*indxp); - mtxregion->mutex_next = mutexp->mutex_next_link; - - --mtxregion->stat.st_mutex_free; - ++mtxregion->stat.st_mutex_inuse; - if (mtxregion->stat.st_mutex_inuse > mtxregion->stat.st_mutex_inuse_max) - mtxregion->stat.st_mutex_inuse_max = - mtxregion->stat.st_mutex_inuse; - if (locksys) - MUTEX_SYSTEM_UNLOCK(dbenv); - - /* Initialize the mutex. */ - memset(mutexp, 0, sizeof(*mutexp)); - - F_SET(mutexp, DB_MUTEX_ALLOCATED); - if (LF_ISSET(DB_MUTEX_LOGICAL_LOCK)) - F_SET(mutexp, DB_MUTEX_LOGICAL_LOCK); - -#ifdef DIAGNOSTIC - mutexp->alloc_id = alloc_id; -#else - COMPQUIET(alloc_id, 0); -#endif - - if ((ret = __mutex_init(dbenv, *indxp, flags)) != 0) - (void)__mutex_free_int(dbenv, locksys, indxp); - - return (ret); -} - -/* - * __mutex_free -- - * Free a mutex. - * - * PUBLIC: int __mutex_free __P((DB_ENV *, db_mutex_t *)); - */ -int -__mutex_free(dbenv, indxp) - DB_ENV *dbenv; - db_mutex_t *indxp; -{ - /* - * There is no explicit ordering in how the regions are cleaned up - * up and/or discarded when an environment is destroyed (either a - * private environment is closed or a public environment is removed). - * The way we deal with mutexes is to clean up all remaining mutexes - * when we close the mutex environment (because we have to be able to - * do that anyway, after a crash), which means we don't have to deal - * with region cleanup ordering on normal environment destruction. - * All that said, what it really means is we can get here without a - * mpool region. It's OK, the mutex has been, or will be, destroyed. - * - * If the mutex has never been configured, we're done. - */ - if (!MUTEX_ON(dbenv) || *indxp == MUTEX_INVALID) - return (0); - - return (__mutex_free_int(dbenv, 1, indxp)); -} - -/* - * __mutex_free_int -- - * Internal routine to free a mutex. - */ -static int -__mutex_free_int(dbenv, locksys, indxp) - DB_ENV *dbenv; - int locksys; - db_mutex_t *indxp; -{ - DB_MUTEX *mutexp; - DB_MUTEXMGR *mtxmgr; - DB_MUTEXREGION *mtxregion; - db_mutex_t mutex; - int ret; - - mutex = *indxp; - *indxp = MUTEX_INVALID; - - mtxmgr = dbenv->mutex_handle; - mtxregion = mtxmgr->reginfo.primary; - mutexp = MUTEXP_SET(mutex); - - DB_ASSERT(F_ISSET(mutexp, DB_MUTEX_ALLOCATED)); - F_CLR(mutexp, DB_MUTEX_ALLOCATED); - - ret = __mutex_destroy(dbenv, mutex); - - if (locksys) - MUTEX_SYSTEM_LOCK(dbenv); - - /* Link the mutex on the head of the free list. */ - mutexp->mutex_next_link = mtxregion->mutex_next; - mtxregion->mutex_next = mutex; - ++mtxregion->stat.st_mutex_free; - --mtxregion->stat.st_mutex_inuse; - - if (locksys) - MUTEX_SYSTEM_UNLOCK(dbenv); - - return (ret); -} diff --git a/storage/bdb/mutex/mut_fcntl.c b/storage/bdb/mutex/mut_fcntl.c deleted file mode 100644 index e3efe9269dc..00000000000 --- a/storage/bdb/mutex/mut_fcntl.c +++ /dev/null @@ -1,191 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: mut_fcntl.c,v 12.13 2005/11/01 14:42:17 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <fcntl.h> -#include <stdlib.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/mutex_int.h" - -/* - * __db_fcntl_mutex_init -- - * Initialize a fcntl mutex. - * - * PUBLIC: int __db_fcntl_mutex_init __P((DB_ENV *, db_mutex_t, u_int32_t)); - */ -int -__db_fcntl_mutex_init(dbenv, mutex, flags) - DB_ENV *dbenv; - db_mutex_t mutex; - u_int32_t flags; -{ - COMPQUIET(dbenv, NULL); - COMPQUIET(mutex, MUTEX_INVALID); - COMPQUIET(flags, 0); - - return (0); -} - -/* - * __db_fcntl_mutex_lock - * Lock on a mutex, blocking if necessary. - * - * PUBLIC: int __db_fcntl_mutex_lock __P((DB_ENV *, db_mutex_t)); - */ -int -__db_fcntl_mutex_lock(dbenv, mutex) - DB_ENV *dbenv; - db_mutex_t mutex; -{ - DB_MUTEX *mutexp; - DB_MUTEXMGR *mtxmgr; - DB_MUTEXREGION *mtxregion; - struct flock k_lock; - int locked, ms, ret; - - if (!MUTEX_ON(dbenv) || F_ISSET(dbenv, DB_ENV_NOLOCKING)) - return (0); - - mtxmgr = dbenv->mutex_handle; - mtxregion = mtxmgr->reginfo.primary; - mutexp = MUTEXP_SET(mutex); - -#ifdef HAVE_STATISTICS - if (F_ISSET(mutexp, DB_MUTEX_LOCKED)) - ++mutexp->mutex_set_wait; - else - ++mutexp->mutex_set_nowait; -#endif - - /* Initialize the lock. */ - k_lock.l_whence = SEEK_SET; - k_lock.l_start = mutex; - k_lock.l_len = 1; - - for (locked = 0;;) { - /* - * Wait for the lock to become available; wait 1ms initially, - * up to 1 second. - */ - for (ms = 1; F_ISSET(mutexp, DB_MUTEX_LOCKED);) { - __os_yield(NULL, ms * USEC_PER_MS); - if ((ms <<= 1) > MS_PER_SEC) - ms = MS_PER_SEC; - } - - /* Acquire an exclusive kernel lock. */ - k_lock.l_type = F_WRLCK; - if (fcntl(dbenv->lockfhp->fd, F_SETLKW, &k_lock)) - goto err; - - /* If the resource is still available, it's ours. */ - if (!F_ISSET(mutexp, DB_MUTEX_LOCKED)) { - locked = 1; - - F_SET(mutexp, DB_MUTEX_LOCKED); - dbenv->thread_id(dbenv, &mutexp->pid, &mutexp->tid); - CHECK_MTX_THREAD(dbenv, mutexp); - } - - /* Release the kernel lock. */ - k_lock.l_type = F_UNLCK; - if (fcntl(dbenv->lockfhp->fd, F_SETLK, &k_lock)) - goto err; - - /* - * If we got the resource lock we're done. - * - * !!! - * We can't check to see if the lock is ours, because we may - * be trying to block ourselves in the lock manager, and so - * the holder of the lock that's preventing us from getting - * the lock may be us! (Seriously.) - */ - if (locked) - break; - } - -#ifdef DIAGNOSTIC - /* - * We want to switch threads as often as possible. Yield every time - * we get a mutex to ensure contention. - */ - if (F_ISSET(dbenv, DB_ENV_YIELDCPU)) - __os_yield(NULL, 1); -#endif - return (0); - -err: ret = __os_get_errno(); - __db_err(dbenv, "fcntl lock failed: %s", db_strerror(ret)); - return (__db_panic(dbenv, ret)); -} - -/* - * __db_fcntl_mutex_unlock -- - * Release a mutex. - * - * PUBLIC: int __db_fcntl_mutex_unlock __P((DB_ENV *, db_mutex_t)); - */ -int -__db_fcntl_mutex_unlock(dbenv, mutex) - DB_ENV *dbenv; - db_mutex_t mutex; -{ - DB_MUTEX *mutexp; - DB_MUTEXMGR *mtxmgr; - DB_MUTEXREGION *mtxregion; - - if (!MUTEX_ON(dbenv) || F_ISSET(dbenv, DB_ENV_NOLOCKING)) - return (0); - - mtxmgr = dbenv->mutex_handle; - mtxregion = mtxmgr->reginfo.primary; - mutexp = MUTEXP_SET(mutex); - -#ifdef DIAGNOSTIC - if (!F_ISSET(mutexp, DB_MUTEX_LOCKED)) { - __db_err(dbenv, "fcntl unlock failed: lock already unlocked"); - return (__db_panic(dbenv, EACCES)); - } -#endif - - /* - * Release the resource. We don't have to acquire any locks because - * processes trying to acquire the lock are waiting for the flag to - * go to 0. Once that happens the waiters will serialize acquiring - * an exclusive kernel lock before locking the mutex. - */ - F_CLR(mutexp, DB_MUTEX_LOCKED); - - return (0); -} - -/* - * __db_fcntl_mutex_destroy -- - * Destroy a mutex. - * - * PUBLIC: int __db_fcntl_mutex_destroy __P((DB_ENV *, db_mutex_t)); - */ -int -__db_fcntl_mutex_destroy(dbenv, mutex) - DB_ENV *dbenv; - db_mutex_t mutex; -{ - COMPQUIET(dbenv, NULL); - COMPQUIET(mutex, MUTEX_INVALID); - - return (0); -} diff --git a/storage/bdb/mutex/mut_method.c b/storage/bdb/mutex/mut_method.c deleted file mode 100644 index a9db642a0df..00000000000 --- a/storage/bdb/mutex/mut_method.c +++ /dev/null @@ -1,277 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2004 - * Sleepycat Software. All rights reserved. - * - * $Id: mut_method.c,v 12.5 2005/10/07 20:21:34 ubell Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/mutex_int.h" - -/* - * __mutex_alloc_pp -- - * Allocate a mutex, application method. - * - * PUBLIC: int __mutex_alloc_pp __P((DB_ENV *, u_int32_t, db_mutex_t *)); - */ -int -__mutex_alloc_pp(dbenv, flags, indxp) - DB_ENV *dbenv; - u_int32_t flags; - db_mutex_t *indxp; -{ - DB_THREAD_INFO *ip; - int ret; - - PANIC_CHECK(dbenv); - - if (flags != 0 && flags != DB_MUTEX_SELF_BLOCK) - return (__db_ferr(dbenv, "DB_ENV->mutex_alloc", 0)); - - ENV_ENTER(dbenv, ip); - ret = __mutex_alloc(dbenv, MTX_APPLICATION, flags, indxp); - ENV_LEAVE(dbenv, ip); - - return (ret); -} - -/* - * __mutex_free_pp -- - * Destroy a mutex, application method. - * - * PUBLIC: int __mutex_free_pp __P((DB_ENV *, db_mutex_t)); - */ -int -__mutex_free_pp(dbenv, indx) - DB_ENV *dbenv; - db_mutex_t indx; -{ - DB_THREAD_INFO *ip; - int ret; - - PANIC_CHECK(dbenv); - - if (indx == MUTEX_INVALID) - return (EINVAL); - - /* - * Internally Berkeley DB passes around the db_mutex_t address on - * free, because we want to make absolutely sure the slot gets - * overwritten with MUTEX_INVALID. We don't export MUTEX_INVALID, - * so we don't export that part of the API, either. - */ - ENV_ENTER(dbenv, ip); - ret = __mutex_free(dbenv, &indx); - ENV_LEAVE(dbenv, ip); - - return (ret); -} - -/* - * __mutex_lock -- - * Lock a mutex, application method. - * - * PUBLIC: int __mutex_lock_pp __P((DB_ENV *, db_mutex_t)); - */ -int -__mutex_lock_pp(dbenv, indx) - DB_ENV *dbenv; - db_mutex_t indx; -{ - PANIC_CHECK(dbenv); - - if (indx == MUTEX_INVALID) - return (EINVAL); - - return (__mutex_lock(dbenv, indx)); -} - -/* - * __mutex_unlock -- - * Unlock a mutex, application method. - * - * PUBLIC: int __mutex_unlock_pp __P((DB_ENV *, db_mutex_t)); - */ -int -__mutex_unlock_pp(dbenv, indx) - DB_ENV *dbenv; - db_mutex_t indx; -{ - PANIC_CHECK(dbenv); - - if (indx == MUTEX_INVALID) - return (EINVAL); - - return (__mutex_unlock(dbenv, indx)); -} - -/* - * __mutex_get_align -- - * DB_ENV->mutex_get_align. - * - * PUBLIC: int __mutex_get_align __P((DB_ENV *, u_int32_t *)); - */ -int -__mutex_get_align(dbenv, alignp) - DB_ENV *dbenv; - u_int32_t *alignp; -{ - if (MUTEX_ON(dbenv)) - *alignp = ((DB_MUTEXREGION *)((DB_MUTEXMGR *) - dbenv->mutex_handle)->reginfo.primary)->stat.st_mutex_align; - else - *alignp = dbenv->mutex_align; - return (0); -} - -/* - * __mutex_set_align -- - * DB_ENV->mutex_set_align. - * - * PUBLIC: int __mutex_set_align __P((DB_ENV *, u_int32_t)); - */ -int -__mutex_set_align(dbenv, align) - DB_ENV *dbenv; - u_int32_t align; -{ - ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_mutex_align"); - - if (align == 0 || !POWER_OF_TWO(align)) { - __db_err(dbenv, - "DB_ENV->mutex_set_align: alignment value must be a non-zero power-of-two"); - return (EINVAL); - } - - dbenv->mutex_align = align; - return (0); -} - -/* - * __mutex_get_increment -- - * DB_ENV->mutex_get_increment. - * - * PUBLIC: int __mutex_get_increment __P((DB_ENV *, u_int32_t *)); - */ -int -__mutex_get_increment(dbenv, incrementp) - DB_ENV *dbenv; - u_int32_t *incrementp; -{ - /* - * We don't maintain the increment in the region (it just makes - * no sense). Return whatever we have configured on this handle, - * nobody is ever going to notice. - */ - *incrementp = dbenv->mutex_inc; - return (0); -} - -/* - * __mutex_set_increment -- - * DB_ENV->mutex_set_increment. - * - * PUBLIC: int __mutex_set_increment __P((DB_ENV *, u_int32_t)); - */ -int -__mutex_set_increment(dbenv, increment) - DB_ENV *dbenv; - u_int32_t increment; -{ - ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_mutex_increment"); - - dbenv->mutex_cnt = 0; - dbenv->mutex_inc = increment; - return (0); -} - -/* - * __mutex_get_max -- - * DB_ENV->mutex_get_max. - * - * PUBLIC: int __mutex_get_max __P((DB_ENV *, u_int32_t *)); - */ -int -__mutex_get_max(dbenv, maxp) - DB_ENV *dbenv; - u_int32_t *maxp; -{ - if (MUTEX_ON(dbenv)) - *maxp = ((DB_MUTEXREGION *)((DB_MUTEXMGR *) - dbenv->mutex_handle)->reginfo.primary)->stat.st_mutex_cnt; - else - *maxp = dbenv->mutex_cnt; - return (0); -} - -/* - * __mutex_set_max -- - * DB_ENV->mutex_set_max. - * - * PUBLIC: int __mutex_set_max __P((DB_ENV *, u_int32_t)); - */ -int -__mutex_set_max(dbenv, max) - DB_ENV *dbenv; - u_int32_t max; -{ - ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_mutex_max"); - - dbenv->mutex_cnt = max; - dbenv->mutex_inc = 0; - return (0); -} - -/* - * __mutex_get_tas_spins -- - * DB_ENV->mutex_get_tas_spins. - * - * PUBLIC: int __mutex_get_tas_spins __P((DB_ENV *, u_int32_t *)); - */ -int -__mutex_get_tas_spins(dbenv, tas_spinsp) - DB_ENV *dbenv; - u_int32_t *tas_spinsp; -{ - if (MUTEX_ON(dbenv)) - *tas_spinsp = ((DB_MUTEXREGION *)((DB_MUTEXMGR *)dbenv-> - mutex_handle)->reginfo.primary)->stat.st_mutex_tas_spins; - else - *tas_spinsp = dbenv->mutex_tas_spins; - return (0); -} - -/* - * __mutex_set_tas_spins -- - * DB_ENV->mutex_set_tas_spins. - * - * PUBLIC: int __mutex_set_tas_spins __P((DB_ENV *, u_int32_t)); - */ -int -__mutex_set_tas_spins(dbenv, tas_spins) - DB_ENV *dbenv; - u_int32_t tas_spins; -{ - /* - * There's a theoretical race here, but I'm not interested in locking - * the test-and-set spin count. The worst possibility is a thread - * reads out a bad spin count and spins until it gets the lock, but - * that's awfully unlikely. - */ - if (MUTEX_ON(dbenv)) - ((DB_MUTEXREGION *)((DB_MUTEXMGR *)dbenv->mutex_handle) - ->reginfo.primary)->stat.st_mutex_tas_spins = tas_spins; - else - dbenv->mutex_tas_spins = tas_spins; - return (0); -} diff --git a/storage/bdb/mutex/mut_pthread.c b/storage/bdb/mutex/mut_pthread.c deleted file mode 100644 index e32e4852412..00000000000 --- a/storage/bdb/mutex/mut_pthread.c +++ /dev/null @@ -1,376 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: mut_pthread.c,v 12.12 2005/11/01 00:44:27 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/mutex_int.h" - -#ifdef HAVE_MUTEX_SOLARIS_LWP -#define pthread_cond_destroy(x) 0 -#define pthread_cond_signal _lwp_cond_signal -#define pthread_cond_wait _lwp_cond_wait -#define pthread_mutex_destroy(x) 0 -#define pthread_mutex_lock _lwp_mutex_lock -#define pthread_mutex_trylock _lwp_mutex_trylock -#define pthread_mutex_unlock _lwp_mutex_unlock -#endif -#ifdef HAVE_MUTEX_UI_THREADS -#define pthread_cond_destroy(x) cond_destroy -#define pthread_cond_signal cond_signal -#define pthread_cond_wait cond_wait -#define pthread_mutex_destroy mutex_destroy -#define pthread_mutex_lock mutex_lock -#define pthread_mutex_trylock mutex_trylock -#define pthread_mutex_unlock mutex_unlock -#endif - -#define PTHREAD_UNLOCK_ATTEMPTS 5 - -/* - * IBM's MVS pthread mutex implementation returns -1 and sets errno rather than - * returning errno itself. As -1 is not a valid errno value, assume functions - * returning -1 have set errno. If they haven't, return a random error value. - */ -#define RET_SET(f, ret) do { \ - if (((ret) = (f)) == -1 && ((ret) = errno) == 0) \ - (ret) = EAGAIN; \ -} while (0) - -/* - * __db_pthread_mutex_init -- - * Initialize a pthread mutex. - * - * PUBLIC: int __db_pthread_mutex_init __P((DB_ENV *, db_mutex_t, u_int32_t)); - */ -int -__db_pthread_mutex_init(dbenv, mutex, flags) - DB_ENV *dbenv; - db_mutex_t mutex; - u_int32_t flags; -{ - DB_MUTEX *mutexp; - DB_MUTEXMGR *mtxmgr; - DB_MUTEXREGION *mtxregion; - int ret; - - mtxmgr = dbenv->mutex_handle; - mtxregion = mtxmgr->reginfo.primary; - mutexp = MUTEXP_SET(mutex); - ret = 0; - -#ifdef HAVE_MUTEX_PTHREADS - { - pthread_condattr_t condattr, *condattrp = NULL; - pthread_mutexattr_t mutexattr, *mutexattrp = NULL; - - if (!LF_ISSET(DB_MUTEX_THREAD)) { - RET_SET((pthread_mutexattr_init(&mutexattr)), ret); -#ifndef HAVE_MUTEX_THREAD_ONLY - if (ret == 0) - RET_SET((pthread_mutexattr_setpshared( - &mutexattr, PTHREAD_PROCESS_SHARED)), ret); -#endif - mutexattrp = &mutexattr; - } - - if (ret == 0) - RET_SET((pthread_mutex_init(&mutexp->mutex, mutexattrp)), ret); - if (mutexattrp != NULL) - (void)pthread_mutexattr_destroy(mutexattrp); - if (ret == 0 && LF_ISSET(DB_MUTEX_SELF_BLOCK)) { - if (!LF_ISSET(DB_MUTEX_THREAD)) { - RET_SET((pthread_condattr_init(&condattr)), ret); - if (ret == 0) { - condattrp = &condattr; -#ifndef HAVE_MUTEX_THREAD_ONLY - RET_SET((pthread_condattr_setpshared( - &condattr, PTHREAD_PROCESS_SHARED)), ret); -#endif - } - } - - if (ret == 0) - RET_SET( - (pthread_cond_init(&mutexp->cond, condattrp)), ret); - - F_SET(mutexp, DB_MUTEX_SELF_BLOCK); - if (condattrp != NULL) - (void)pthread_condattr_destroy(condattrp); - } - - } -#endif -#ifdef HAVE_MUTEX_SOLARIS_LWP - /* - * XXX - * Gcc complains about missing braces in the static initializations of - * lwp_cond_t and lwp_mutex_t structures because the structures contain - * sub-structures/unions and the Solaris include file that defines the - * initialization values doesn't have surrounding braces. There's not - * much we can do. - */ - if (LF_ISSET(DB_MUTEX_THREAD)) { - static lwp_mutex_t mi = DEFAULTMUTEX; - - mutexp->mutex = mi; - } else { - static lwp_mutex_t mi = SHAREDMUTEX; - - mutexp->mutex = mi; - } - if (LF_ISSET(DB_MUTEX_SELF_BLOCK)) { - if (LF_ISSET(DB_MUTEX_THREAD)) { - static lwp_cond_t ci = DEFAULTCV; - - mutexp->cond = ci; - } else { - static lwp_cond_t ci = SHAREDCV; - - mutexp->cond = ci; - } - F_SET(mutexp, DB_MUTEX_SELF_BLOCK); - } -#endif -#ifdef HAVE_MUTEX_UI_THREADS - { - int type; - - type = LF_ISSET(DB_MUTEX_THREAD) ? USYNC_THREAD : USYNC_PROCESS; - - ret = mutex_init(&mutexp->mutex, type, NULL); - if (ret == 0 && LF_ISSET(DB_MUTEX_SELF_BLOCK)) { - ret = cond_init(&mutexp->cond, type, NULL); - - F_SET(mutexp, DB_MUTEX_SELF_BLOCK); - }} -#endif - - if (ret != 0) { - __db_err(dbenv, - "unable to initialize mutex: %s", strerror(ret)); - } - return (ret); -} - -/* - * __db_pthread_mutex_lock - * Lock on a mutex, blocking if necessary. - * - * PUBLIC: int __db_pthread_mutex_lock __P((DB_ENV *, db_mutex_t)); - */ -int -__db_pthread_mutex_lock(dbenv, mutex) - DB_ENV *dbenv; - db_mutex_t mutex; -{ - DB_MUTEX *mutexp; - DB_MUTEXMGR *mtxmgr; - DB_MUTEXREGION *mtxregion; - int i, ret; - - if (!MUTEX_ON(dbenv) || F_ISSET(dbenv, DB_ENV_NOLOCKING)) - return (0); - - mtxmgr = dbenv->mutex_handle; - mtxregion = mtxmgr->reginfo.primary; - mutexp = MUTEXP_SET(mutex); - -#ifdef HAVE_STATISTICS - /* - * We want to know which mutexes are contentious, but don't want to - * do an interlocked test here -- that's slower when the underlying - * system has adaptive mutexes and can perform optimizations like - * spinning only if the thread holding the mutex is actually running - * on a CPU. Make a guess, using a normal load instruction. - */ - if (F_ISSET(mutexp, DB_MUTEX_LOCKED)) - ++mutexp->mutex_set_wait; - else - ++mutexp->mutex_set_nowait; -#endif - - RET_SET((pthread_mutex_lock(&mutexp->mutex)), ret); - if (ret != 0) - goto err; - - if (F_ISSET(mutexp, DB_MUTEX_SELF_BLOCK)) { - while (F_ISSET(mutexp, DB_MUTEX_LOCKED)) { - RET_SET((pthread_cond_wait( - &mutexp->cond, &mutexp->mutex)), ret); - /* - * !!! - * Solaris bug workaround: - * pthread_cond_wait() sometimes returns ETIME -- out - * of sheer paranoia, check both ETIME and ETIMEDOUT. - * We believe this happens when the application uses - * SIGALRM for some purpose, e.g., the C library sleep - * call, and Solaris delivers the signal to the wrong - * LWP. - */ - if (ret != 0 && ret != EINTR && -#ifdef ETIME - ret != ETIME && -#endif - ret != ETIMEDOUT) { - (void)pthread_mutex_unlock(&mutexp->mutex); - goto err; - } - } - - F_SET(mutexp, DB_MUTEX_LOCKED); - dbenv->thread_id(dbenv, &mutexp->pid, &mutexp->tid); - CHECK_MTX_THREAD(dbenv, mutexp); - - /* - * According to HP-UX engineers contacted by Netscape, - * pthread_mutex_unlock() will occasionally return EFAULT - * for no good reason on mutexes in shared memory regions, - * and the correct caller behavior is to try again. Do - * so, up to PTHREAD_UNLOCK_ATTEMPTS consecutive times. - * Note that we don't bother to restrict this to HP-UX; - * it should be harmless elsewhere. [#2471] - */ - i = PTHREAD_UNLOCK_ATTEMPTS; - do { - RET_SET((pthread_mutex_unlock(&mutexp->mutex)), ret); - } while (ret == EFAULT && --i > 0); - if (ret != 0) - goto err; - } else { -#ifdef DIAGNOSTIC - if (F_ISSET(mutexp, DB_MUTEX_LOCKED)) { - char buf[DB_THREADID_STRLEN]; - (void)dbenv->thread_id_string(dbenv, - mutexp->pid, mutexp->tid, buf); - __db_err(dbenv, - "pthread lock failed: lock currently in use: pid/tid: %s", - buf); - ret = EINVAL; - goto err; - } -#endif - F_SET(mutexp, DB_MUTEX_LOCKED); - dbenv->thread_id(dbenv, &mutexp->pid, &mutexp->tid); - CHECK_MTX_THREAD(dbenv, mutexp); - } - -#ifdef DIAGNOSTIC - /* - * We want to switch threads as often as possible. Yield every time - * we get a mutex to ensure contention. - */ - if (F_ISSET(dbenv, DB_ENV_YIELDCPU)) - __os_yield(NULL, 1); -#endif - return (0); - -err: __db_err(dbenv, "pthread lock failed: %s", db_strerror(ret)); - return (__db_panic(dbenv, ret)); -} - -/* - * __db_pthread_mutex_unlock -- - * Release a mutex. - * - * PUBLIC: int __db_pthread_mutex_unlock __P((DB_ENV *, db_mutex_t)); - */ -int -__db_pthread_mutex_unlock(dbenv, mutex) - DB_ENV *dbenv; - db_mutex_t mutex; -{ - DB_MUTEX *mutexp; - DB_MUTEXMGR *mtxmgr; - DB_MUTEXREGION *mtxregion; - int i, ret; - - if (!MUTEX_ON(dbenv) || F_ISSET(dbenv, DB_ENV_NOLOCKING)) - return (0); - - mtxmgr = dbenv->mutex_handle; - mtxregion = mtxmgr->reginfo.primary; - mutexp = MUTEXP_SET(mutex); - -#ifdef DIAGNOSTIC - if (!F_ISSET(mutexp, DB_MUTEX_LOCKED)) { - __db_err(dbenv, "pthread unlock failed: lock already unlocked"); - return (__db_panic(dbenv, EACCES)); - } -#endif - if (F_ISSET(mutexp, DB_MUTEX_SELF_BLOCK)) { - RET_SET((pthread_mutex_lock(&mutexp->mutex)), ret); - if (ret != 0) - goto err; - - F_CLR(mutexp, DB_MUTEX_LOCKED); - - RET_SET((pthread_cond_signal(&mutexp->cond)), ret); - if (ret != 0) - goto err; - } else - F_CLR(mutexp, DB_MUTEX_LOCKED); - - /* See comment above; workaround for [#2471]. */ - i = PTHREAD_UNLOCK_ATTEMPTS; - do { - RET_SET((pthread_mutex_unlock(&mutexp->mutex)), ret); - } while (ret == EFAULT && --i > 0); - -err: if (ret != 0) { - __db_err(dbenv, "pthread unlock failed: %s", db_strerror(ret)); - return (__db_panic(dbenv, ret)); - } - return (ret); -} - -/* - * __db_pthread_mutex_destroy -- - * Destroy a mutex. - * - * PUBLIC: int __db_pthread_mutex_destroy __P((DB_ENV *, db_mutex_t)); - */ -int -__db_pthread_mutex_destroy(dbenv, mutex) - DB_ENV *dbenv; - db_mutex_t mutex; -{ - DB_MUTEX *mutexp; - DB_MUTEXMGR *mtxmgr; - DB_MUTEXREGION *mtxregion; - int ret, t_ret; - - if (!MUTEX_ON(dbenv)) - return (0); - - mtxmgr = dbenv->mutex_handle; - mtxregion = mtxmgr->reginfo.primary; - mutexp = MUTEXP_SET(mutex); - - ret = 0; - if (F_ISSET(mutexp, DB_MUTEX_SELF_BLOCK)) { - RET_SET((pthread_cond_destroy(&mutexp->cond)), ret); - if (ret != 0) - __db_err(NULL, - "unable to destroy cond: %s", strerror(ret)); - } - RET_SET((pthread_mutex_destroy(&mutexp->mutex)), t_ret); - if (t_ret != 0) { - __db_err(NULL, "unable to destroy mutex: %s", strerror(t_ret)); - if (ret == 0) - ret = t_ret; - } - return (ret); -} diff --git a/storage/bdb/mutex/mut_region.c b/storage/bdb/mutex/mut_region.c deleted file mode 100644 index 5d7c7333118..00000000000 --- a/storage/bdb/mutex/mut_region.c +++ /dev/null @@ -1,362 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2004 - * Sleepycat Software. All rights reserved. - * - * $Id: mut_region.c,v 12.9 2005/10/27 15:16:13 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_shash.h" -#include "dbinc/log.h" -#include "dbinc/lock.h" -#include "dbinc/mp.h" -#include "dbinc/mutex_int.h" - -static int __mutex_region_init __P((DB_ENV *, DB_MUTEXMGR *)); -static size_t __mutex_region_size __P((DB_ENV *)); - -/* - * __mutex_open -- - * Open a mutex region. - * - * PUBLIC: int __mutex_open __P((DB_ENV *)); - */ -int -__mutex_open(dbenv) - DB_ENV *dbenv; -{ - DB_MUTEXMGR *mtxmgr; - DB_MUTEXREGION *mtxregion; - db_mutex_t mutex; - u_int i; - int ret; - - /* - * Initialize the DB_ENV handle information if not already initialized. - * - * Align mutexes on the byte boundaries specified by the application. - */ - if (dbenv->mutex_align == 0) - dbenv->mutex_align = MUTEX_ALIGN; - if (dbenv->mutex_tas_spins == 0) - dbenv->mutex_tas_spins = __os_spin(dbenv); - - /* - * If the user didn't set an absolute value on the number of mutexes - * we'll need, figure it out. We're conservative in our allocation, - * we need mutexes for DB handles, group-commit queues and other things - * applications allocate at run-time. The application may have kicked - * up our count to allocate its own mutexes, add that in. - */ - if (dbenv->mutex_cnt == 0) - dbenv->mutex_cnt = - __lock_region_mutex_count(dbenv) + - __log_region_mutex_count(dbenv) + - __memp_region_mutex_count(dbenv) + - dbenv->mutex_inc + 500; - - /* Create/initialize the mutex manager structure. */ - if ((ret = __os_calloc(dbenv, 1, sizeof(DB_MUTEXMGR), &mtxmgr)) != 0) - return (ret); - - /* Join/create the txn region. */ - mtxmgr->reginfo.dbenv = dbenv; - mtxmgr->reginfo.type = REGION_TYPE_MUTEX; - mtxmgr->reginfo.id = INVALID_REGION_ID; - mtxmgr->reginfo.flags = REGION_JOIN_OK; - if (F_ISSET(dbenv, DB_ENV_CREATE)) - F_SET(&mtxmgr->reginfo, REGION_CREATE_OK); - if ((ret = __db_r_attach(dbenv, - &mtxmgr->reginfo, __mutex_region_size(dbenv))) != 0) - goto err; - - /* If we created the region, initialize it. */ - if (F_ISSET(&mtxmgr->reginfo, REGION_CREATE)) - if ((ret = __mutex_region_init(dbenv, mtxmgr)) != 0) - goto err; - - /* Set the local addresses. */ - mtxregion = mtxmgr->reginfo.primary = - R_ADDR(&mtxmgr->reginfo, mtxmgr->reginfo.rp->primary); - mtxmgr->mutex_array = R_ADDR(&mtxmgr->reginfo, mtxregion->mutex_offset); - - dbenv->mutex_handle = mtxmgr; - - /* Allocate initial queue of mutexes. */ - if (dbenv->mutex_iq != NULL) { - DB_ASSERT(F_ISSET(&mtxmgr->reginfo, REGION_CREATE)); - for (i = 0; i < dbenv->mutex_iq_next; ++i) { - if ((ret = __mutex_alloc_int( - dbenv, 0, dbenv->mutex_iq[i].alloc_id, - dbenv->mutex_iq[i].flags, &mutex)) != 0) - goto err; - /* - * Confirm we allocated the right index, correcting - * for avoiding slot 0 (MUTEX_INVALID). - */ - DB_ASSERT(mutex == i + 1); - } - __os_free(dbenv, dbenv->mutex_iq); - dbenv->mutex_iq = NULL; - - /* - * This is the first place we can test mutexes and we need to - * know if they're working. (They CAN fail, for example on - * SunOS, when using fcntl(2) for locking and using an - * in-memory filesystem as the database environment directory. - * But you knew that, I'm sure -- it probably wasn't worth - * mentioning.) - */ - mutex = MUTEX_INVALID; - if ((ret = - __mutex_alloc(dbenv, MTX_MUTEX_TEST, 0, &mutex) != 0) || - (ret = __mutex_lock(dbenv, mutex)) != 0 || - (ret = __mutex_unlock(dbenv, mutex)) != 0 || - (ret = __mutex_free(dbenv, &mutex)) != 0) { - __db_err(dbenv, - "Unable to acquire/release a mutex; check configuration"); - goto err; - } - } - - /* - * Initialize thread tracking. We want to do this as early - * has possible in case we die. This sits in the mutex region - * so do it now. - */ - if ((ret = __env_thread_init(dbenv, - F_ISSET(&mtxmgr->reginfo, REGION_CREATE))) != 0) - goto err; - - return (0); - -err: dbenv->mutex_handle = NULL; - if (mtxmgr->reginfo.addr != NULL) - (void)__db_r_detach(dbenv, &mtxmgr->reginfo, 0); - - __os_free(dbenv, mtxmgr); - return (ret); -} - -/* - * __mutex_region_init -- - * Initialize a mutex region in shared memory. - */ -static int -__mutex_region_init(dbenv, mtxmgr) - DB_ENV *dbenv; - DB_MUTEXMGR *mtxmgr; -{ - DB_MUTEXREGION *mtxregion; - DB_MUTEX *mutexp; - db_mutex_t i; - int ret; - void *mutex_array; - - COMPQUIET(mutexp, NULL); - - if ((ret = __db_shalloc(&mtxmgr->reginfo, - sizeof(DB_MUTEXREGION), 0, &mtxmgr->reginfo.primary)) != 0) { - __db_err(dbenv, - "Unable to allocate memory for the mutex region"); - return (ret); - } - mtxmgr->reginfo.rp->primary = - R_OFFSET(&mtxmgr->reginfo, mtxmgr->reginfo.primary); - mtxregion = mtxmgr->reginfo.primary; - memset(mtxregion, 0, sizeof(*mtxregion)); - - if ((ret = __mutex_alloc( - dbenv, MTX_MUTEX_REGION, 0, &mtxregion->mtx_region)) != 0) - return (ret); - - mtxregion->mutex_size = - (size_t)DB_ALIGN(sizeof(DB_MUTEX), dbenv->mutex_align); - - mtxregion->stat.st_mutex_align = dbenv->mutex_align; - mtxregion->stat.st_mutex_cnt = dbenv->mutex_cnt; - mtxregion->stat.st_mutex_tas_spins = dbenv->mutex_tas_spins; - - /* - * Get a chunk of memory to be used for the mutexes themselves. Each - * piece of the memory must be properly aligned. - * - * The OOB mutex (MUTEX_INVALID) is 0. To make this work, we ignore - * the first allocated slot when we build the free list. We have to - * correct the count by 1 here, though, otherwise our counter will be - * off by 1. - */ - if ((ret = __db_shalloc(&mtxmgr->reginfo, - (mtxregion->stat.st_mutex_cnt + 1) * mtxregion->mutex_size, - mtxregion->stat.st_mutex_align, &mutex_array)) != 0) { - __db_err(dbenv, - "Unable to allocate memory for mutexes from the region"); - return (ret); - } - - mtxregion->mutex_offset = R_OFFSET(&mtxmgr->reginfo, mutex_array); - mtxmgr->mutex_array = mutex_array; - - /* - * Put the mutexes on a free list and clear the allocated flag. - * - * The OOB mutex (MUTEX_INVALID) is 0, skip it. - * - * The comparison is <, not <=, because we're looking ahead one - * in each link. - */ - for (i = 1; i < mtxregion->stat.st_mutex_cnt; ++i) { - mutexp = MUTEXP_SET(i); - mutexp->flags = 0; - mutexp->mutex_next_link = i + 1; - } - mutexp = MUTEXP_SET(i); - mutexp->flags = 0; - mutexp->mutex_next_link = MUTEX_INVALID; - mtxregion->mutex_next = 1; - mtxregion->stat.st_mutex_free = mtxregion->stat.st_mutex_cnt; - mtxregion->stat.st_mutex_inuse = mtxregion->stat.st_mutex_inuse_max = 0; - - return (0); -} - -/* - * __mutex_dbenv_refresh -- - * Clean up after the mutex region on a close or failed open. - * - * PUBLIC: int __mutex_dbenv_refresh __P((DB_ENV *)); - */ -int -__mutex_dbenv_refresh(dbenv) - DB_ENV *dbenv; -{ - DB_MUTEXMGR *mtxmgr; - DB_MUTEXREGION *mtxregion; - REGINFO *reginfo; - int ret; - - mtxmgr = dbenv->mutex_handle; - reginfo = &mtxmgr->reginfo; - mtxregion = mtxmgr->reginfo.primary; - - /* - * If a private region, return the memory to the heap. Not needed for - * filesystem-backed or system shared memory regions, that memory isn't - * owned by any particular process. - */ - if (F_ISSET(dbenv, DB_ENV_PRIVATE)) { -#ifdef HAVE_MUTEX_SYSTEM_RESOURCES - /* - * If destroying the mutex region, return any system resources - * to the system. - */ - __mutex_resource_return(dbenv, reginfo); -#endif - /* Discard the mutex array. */ - __db_shalloc_free( - reginfo, R_ADDR(reginfo, mtxregion->mutex_offset)); - } - - /* Detach from the region. */ - ret = __db_r_detach(dbenv, reginfo, 0); - - __os_free(dbenv, mtxmgr); - - dbenv->mutex_handle = NULL; - - return (ret); -} - -/* - * __mutex_region_size -- - * Return the amount of space needed for the mutex region. - */ -static size_t -__mutex_region_size(dbenv) - DB_ENV *dbenv; -{ - size_t s; - - s = sizeof(DB_MUTEXMGR) + 1024; - s += dbenv->mutex_cnt * - __db_shalloc_size(sizeof(DB_MUTEX), dbenv->mutex_align); - /* - * Allocate space for thread info blocks. Max is only advisory, - * so we allocate 25% more. - */ - s += (dbenv->thr_max + dbenv->thr_max/4) * - __db_shalloc_size(sizeof(DB_THREAD_INFO), sizeof(roff_t)); - s += dbenv->thr_nbucket * - __db_shalloc_size(sizeof(DB_HASHTAB), sizeof(roff_t)); - return (s); -} - -#ifdef HAVE_MUTEX_SYSTEM_RESOURCES -/* - * __mutex_resource_return - * Return any system-allocated mutex resources to the system. - * - * PUBLIC: void __mutex_resource_return __P((DB_ENV *, REGINFO *)); - */ -void -__mutex_resource_return(dbenv, infop) - DB_ENV *dbenv; - REGINFO *infop; -{ - DB_MUTEX *mutexp; - DB_MUTEXMGR *mtxmgr, mtxmgr_st; - DB_MUTEXREGION *mtxregion; - db_mutex_t i; - void *orig_handle; - - /* - * This routine is called in two cases: when discarding the regions - * from a previous Berkeley DB run, during recovery, and two, when - * discarding regions as we shut down the database environment. - * - * Walk the list of mutexes and destroy any live ones. - * - * This is just like joining a region -- the REGINFO we're handed - * is the same as the one returned by __db_r_attach(), all we have - * to do is fill in the links. - * - * !!! - * The region may be corrupted, of course. We're safe because the - * only things we look at are things that are initialized when the - * region is created, and never modified after that. - */ - memset(&mtxmgr_st, 0, sizeof(mtxmgr_st)); - mtxmgr = &mtxmgr_st; - mtxmgr->reginfo = *infop; - mtxregion = mtxmgr->reginfo.primary = - R_ADDR(&mtxmgr->reginfo, mtxmgr->reginfo.rp->primary); - mtxmgr->mutex_array = R_ADDR(&mtxmgr->reginfo, mtxregion->mutex_offset); - - /* - * This is a little strange, but the mutex_handle is what all of the - * underlying mutex routines will use to determine if they should do - * any work and to find their information. Save/restore the handle - * around the work loop. - * - * The OOB mutex (MUTEX_INVALID) is 0, skip it. - */ - orig_handle = dbenv->mutex_handle; - dbenv->mutex_handle = mtxmgr; - for (i = 1; i <= mtxregion->stat.st_mutex_cnt; ++i, ++mutexp) { - mutexp = MUTEXP_SET(i); - if (F_ISSET(mutexp, DB_MUTEX_ALLOCATED)) - (void)__mutex_destroy(dbenv, i); - } - dbenv->mutex_handle = orig_handle; -} -#endif diff --git a/storage/bdb/mutex/mut_stat.c b/storage/bdb/mutex/mut_stat.c deleted file mode 100644 index cffff239c76..00000000000 --- a/storage/bdb/mutex/mut_stat.c +++ /dev/null @@ -1,454 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2004 - * Sleepycat Software. All rights reserved. - * - * $Id: mut_stat.c,v 12.10 2005/11/01 00:44:28 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stdlib.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_am.h" -#include "dbinc/mutex_int.h" - -#ifdef HAVE_STATISTICS -static int __mutex_print_all __P((DB_ENV *, u_int32_t)); -static const char *__mutex_print_id __P((int)); -static int __mutex_print_stats __P((DB_ENV *, u_int32_t)); -static void __mutex_print_summary __P((DB_ENV *)); - -/* - * __mutex_stat -- - * DB_ENV->mutex_stat. - * - * PUBLIC: int __mutex_stat __P((DB_ENV *, DB_MUTEX_STAT **, u_int32_t)); - */ -int -__mutex_stat(dbenv, statp, flags) - DB_ENV *dbenv; - DB_MUTEX_STAT **statp; - u_int32_t flags; -{ - DB_MUTEXMGR *mtxmgr; - DB_MUTEXREGION *mtxregion; - DB_MUTEX_STAT *stats; - int ret; - - PANIC_CHECK(dbenv); - - if ((ret = __db_fchk(dbenv, - "DB_ENV->mutex_stat", flags, DB_STAT_CLEAR)) != 0) - return (ret); - - *statp = NULL; - mtxmgr = dbenv->mutex_handle; - mtxregion = mtxmgr->reginfo.primary; - - if ((ret = __os_umalloc(dbenv, sizeof(DB_MUTEX_STAT), &stats)) != 0) - return (ret); - - MUTEX_SYSTEM_LOCK(dbenv); - - /* - * Most fields are maintained in the underlying region structure. - * Region size and region mutex are not. - */ - *stats = mtxregion->stat; - stats->st_regsize = mtxmgr->reginfo.rp->size; - __mutex_set_wait_info(dbenv, mtxregion->mtx_region, - &stats->st_region_wait, &stats->st_region_nowait); - if (LF_ISSET(DB_STAT_CLEAR)) - __mutex_clear(dbenv, mtxregion->mtx_region); - - MUTEX_SYSTEM_UNLOCK(dbenv); - - *statp = stats; - return (0); -} - -/* - * __mutex_stat_print - * DB_ENV->mutex_stat_print method. - * - * PUBLIC: int __mutex_stat_print __P((DB_ENV *, u_int32_t)); - */ -int -__mutex_stat_print(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - u_int32_t orig_flags; - int ret; - - PANIC_CHECK(dbenv); - - if ((ret = __db_fchk(dbenv, "DB_ENV->mutex_stat_print", - flags, DB_STAT_ALL | DB_STAT_CLEAR)) != 0) - return (ret); - - orig_flags = flags; - LF_CLR(DB_STAT_CLEAR); - if (flags == 0 || LF_ISSET(DB_STAT_ALL)) { - ret = __mutex_print_stats(dbenv, orig_flags); - __mutex_print_summary(dbenv); - if (flags == 0 || ret != 0) - return (ret); - } - - if (LF_ISSET(DB_STAT_ALL)) - ret = __mutex_print_all(dbenv, orig_flags); - - return (0); -} - -static void -__mutex_print_summary(dbenv) - DB_ENV *dbenv; -{ - DB_MUTEX *mutexp; - DB_MUTEXMGR *mtxmgr; - DB_MUTEXREGION *mtxregion; - db_mutex_t i; - u_int32_t counts[MTX_MAX_ENTRY + 2]; - int alloc_id; - - mtxmgr = dbenv->mutex_handle; - mtxregion = mtxmgr->reginfo.primary; - memset(counts, 0, sizeof(counts)); - - for (i = 1; i <= mtxregion->stat.st_mutex_cnt; ++i, ++mutexp) { - mutexp = MUTEXP_SET(i); - - if (!F_ISSET(mutexp, DB_MUTEX_ALLOCATED)) - counts[0]++; - else if (mutexp->alloc_id > MTX_MAX_ENTRY) - counts[MTX_MAX_ENTRY + 1]++; - else - counts[mutexp->alloc_id]++; - } - __db_msg(dbenv, "Mutex counts"); - __db_msg(dbenv, "%d\tUnallocated", counts[0]); - for (alloc_id = 1; alloc_id <= MTX_TXN_REGION + 1; alloc_id++) - if (counts[alloc_id] != 0) - __db_msg(dbenv, "%lu\t%s", - (u_long)counts[alloc_id], - __mutex_print_id(alloc_id)); - -} - -/* - * __mutex_print_stats -- - * Display default mutex region statistics. - */ -static int -__mutex_print_stats(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - DB_MUTEX_STAT *sp; - DB_MUTEXMGR *mtxmgr; - DB_MUTEXREGION *mtxregion; - REGINFO *infop; - THREAD_INFO *thread; - int ret; - - if ((ret = __mutex_stat(dbenv, &sp, LF_ISSET(DB_STAT_CLEAR))) != 0) - return (ret); - - if (LF_ISSET(DB_STAT_ALL)) - __db_msg(dbenv, "Default mutex region information:"); - - __db_dlbytes(dbenv, "Mutex region size", - (u_long)0, (u_long)0, (u_long)sp->st_regsize); - __db_dl_pct(dbenv, - "The number of region locks that required waiting", - (u_long)sp->st_region_wait, DB_PCT(sp->st_region_wait, - sp->st_region_wait + sp->st_region_nowait), NULL); - STAT_ULONG("Mutex alignment", sp->st_mutex_align); - STAT_ULONG("Mutex test-and-set spins", sp->st_mutex_tas_spins); - STAT_ULONG("Mutex total count", sp->st_mutex_cnt); - STAT_ULONG("Mutex free count", sp->st_mutex_free); - STAT_ULONG("Mutex in-use count", sp->st_mutex_inuse); - STAT_ULONG("Mutex maximum in-use count", sp->st_mutex_inuse_max); - - __os_ufree(dbenv, sp); - - /* - * Dump out the info we have on thread tracking, we do it here only - * because we share the region. - */ - if (dbenv->thr_hashtab != NULL) { - mtxmgr = dbenv->mutex_handle; - mtxregion = mtxmgr->reginfo.primary; - infop = &mtxmgr->reginfo; - thread = R_ADDR(infop, mtxregion->thread_off); - STAT_ULONG("Thread blocks allocated", thread->thr_count); - STAT_ULONG("Thread allocation threshold", thread->thr_max); - STAT_ULONG("Thread hash buckets", thread->thr_nbucket); - } - - return (0); -} - -/* - * __mutex_print_all -- - * Display debugging mutex region statistics. - */ -static int -__mutex_print_all(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - static const FN fn[] = { - { DB_MUTEX_ALLOCATED, "alloc" }, - { DB_MUTEX_LOGICAL_LOCK, "logical" }, - { DB_MUTEX_SELF_BLOCK, "self-block" }, - { DB_MUTEX_THREAD, "thread" }, - { 0, NULL } - }; - DB_MSGBUF mb, *mbp; - DB_MUTEX *mutexp; - DB_MUTEXMGR *mtxmgr; - DB_MUTEXREGION *mtxregion; - db_mutex_t i; - - DB_MSGBUF_INIT(&mb); - mbp = &mb; - - mtxmgr = dbenv->mutex_handle; - mtxregion = mtxmgr->reginfo.primary; - - __db_print_reginfo(dbenv, &mtxmgr->reginfo, "Mutex"); - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - - __db_msg(dbenv, "DB_MUTEXREGION structure:"); - __mutex_print_debug_single(dbenv, - "DB_MUTEXREGION region mutex", mtxregion->mtx_region, flags); - STAT_ULONG("Size of the aligned mutex", mtxregion->mutex_size); - STAT_ULONG("Next free mutex", mtxregion->mutex_next); - - /* - * The OOB mutex (MUTEX_INVALID) is 0, skip it. - * - * We're not holding the mutex region lock, so we're racing threads of - * control allocating mutexes. That's OK, it just means we display or - * clear statistics while mutexes are moving. - */ - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_msg(dbenv, "mutex\twait/nowait, pct wait, holder, flags"); - for (i = 1; i <= mtxregion->stat.st_mutex_cnt; ++i, ++mutexp) { - mutexp = MUTEXP_SET(i); - - if (!F_ISSET(mutexp, DB_MUTEX_ALLOCATED)) - continue; - - __db_msgadd(dbenv, mbp, "%5lu\t", (u_long)i); - - __mutex_print_debug_stats(dbenv, mbp, i, flags); - - if (mutexp->alloc_id != 0) - __db_msgadd(dbenv, - mbp, ", %s", __mutex_print_id(mutexp->alloc_id)); - - __db_prflags(dbenv, mbp, mutexp->flags, fn, " (", ")"); - - DB_MSGBUF_FLUSH(dbenv, mbp); - } - - return (0); -} - -/* - * __mutex_print_debug_single -- - * Print mutex internal debugging statistics for a single mutex on a - * single output line. - * - * PUBLIC: void __mutex_print_debug_single - * PUBLIC: __P((DB_ENV *, const char *, db_mutex_t, u_int32_t)); - */ -void -__mutex_print_debug_single(dbenv, tag, mutex, flags) - DB_ENV *dbenv; - const char *tag; - db_mutex_t mutex; - u_int32_t flags; -{ - DB_MSGBUF mb, *mbp; - - DB_MSGBUF_INIT(&mb); - mbp = &mb; - - __db_msgadd(dbenv, mbp, "%lu\t%s ", (u_long)mutex, tag); - __mutex_print_debug_stats(dbenv, mbp, mutex, flags); - DB_MSGBUF_FLUSH(dbenv, mbp); -} - -/* - * __mutex_print_debug_stats -- - * Print mutex internal debugging statistics, that is, the statistics - * in the [] square brackets. - * - * PUBLIC: void __mutex_print_debug_stats - * PUBLIC: __P((DB_ENV *, DB_MSGBUF *, db_mutex_t, u_int32_t)); - */ -void -__mutex_print_debug_stats(dbenv, mbp, mutex, flags) - DB_ENV *dbenv; - DB_MSGBUF *mbp; - db_mutex_t mutex; - u_int32_t flags; -{ - DB_MUTEX *mutexp; - DB_MUTEXMGR *mtxmgr; - DB_MUTEXREGION *mtxregion; - u_long value; - char buf[DB_THREADID_STRLEN]; - - if (mutex == MUTEX_INVALID) { - __db_msgadd(dbenv, mbp, "[!Set]"); - return; - } - - mtxmgr = dbenv->mutex_handle; - mtxregion = mtxmgr->reginfo.primary; - mutexp = MUTEXP_SET(mutex); - - __db_msgadd(dbenv, mbp, "["); - if ((value = mutexp->mutex_set_wait) < 10000000) - __db_msgadd(dbenv, mbp, "%lu", value); - else - __db_msgadd(dbenv, mbp, "%luM", value / 1000000); - if ((value = mutexp->mutex_set_nowait) < 10000000) - __db_msgadd(dbenv, mbp, "/%lu", value); - else - __db_msgadd(dbenv, mbp, "/%luM", value / 1000000); - - __db_msgadd(dbenv, mbp, " %d%%", - DB_PCT(mutexp->mutex_set_wait, - mutexp->mutex_set_wait + mutexp->mutex_set_nowait)); - - if (F_ISSET(mutexp, DB_MUTEX_LOCKED)) - __db_msgadd(dbenv, mbp, " %s]", - dbenv->thread_id_string(dbenv, - mutexp->pid, mutexp->tid, buf)); - else - __db_msgadd(dbenv, mbp, " !Own]"); - - if (LF_ISSET(DB_STAT_CLEAR)) - __mutex_clear(dbenv, mutex); -} - -static const char * -__mutex_print_id(alloc_id) - int alloc_id; -{ - switch (alloc_id) { - case MTX_APPLICATION: return ("application allocated"); - case MTX_DB_HANDLE: return ("db handle"); - case MTX_ENV_DBLIST: return ("env dblist"); - case MTX_ENV_REGION: return ("env region"); - case MTX_LOCK_REGION: return ("lock region"); - case MTX_LOGICAL_LOCK: return ("logical lock"); - case MTX_LOG_FILENAME: return ("log filename"); - case MTX_LOG_FLUSH: return ("log flush"); - case MTX_LOG_HANDLE: return ("log handle"); - case MTX_LOG_REGION: return ("log region"); - case MTX_MPOOLFILE_HANDLE: return ("mpoolfile handle"); - case MTX_MPOOL_BUFFER: return ("mpool buffer"); - case MTX_MPOOL_FH: return ("mpool filehandle"); - case MTX_MPOOL_HANDLE: return ("mpool handle"); - case MTX_MPOOL_HASH_BUCKET: return ("mpool hash bucket"); - case MTX_MPOOL_REGION: return ("mpool region"); - case MTX_REP_DATABASE: return ("replication database"); - case MTX_REP_REGION: return ("replication region"); - case MTX_SEQUENCE: return ("sequence"); - case MTX_TWISTER: return ("twister"); - case MTX_TXN_ACTIVE: return ("txn active list"); - case MTX_TXN_COMMIT: return ("txn commit"); - case MTX_TXN_REGION: return ("txn region"); - default: return ("unknown mutex type"); - } - /* NOTREACHED */ -} - -/* - * __mutex_set_wait_info -- - * Return mutex statistics. - * - * PUBLIC: void __mutex_set_wait_info - * PUBLIC: __P((DB_ENV *, db_mutex_t, u_int32_t *, u_int32_t *)); - */ -void -__mutex_set_wait_info(dbenv, mutex, waitp, nowaitp) - DB_ENV *dbenv; - db_mutex_t mutex; - u_int32_t *waitp, *nowaitp; -{ - DB_MUTEX *mutexp; - DB_MUTEXMGR *mtxmgr; - DB_MUTEXREGION *mtxregion; - - mtxmgr = dbenv->mutex_handle; - mtxregion = mtxmgr->reginfo.primary; - mutexp = MUTEXP_SET(mutex); - - *waitp = mutexp->mutex_set_wait; - *nowaitp = mutexp->mutex_set_nowait; -} - -/* - * __mutex_clear -- - * Clear mutex statistics. - * - * PUBLIC: void __mutex_clear __P((DB_ENV *, db_mutex_t)); - */ -void -__mutex_clear(dbenv, mutex) - DB_ENV *dbenv; - db_mutex_t mutex; -{ - DB_MUTEX *mutexp; - DB_MUTEXMGR *mtxmgr; - DB_MUTEXREGION *mtxregion; - - mtxmgr = dbenv->mutex_handle; - mtxregion = mtxmgr->reginfo.primary; - mutexp = MUTEXP_SET(mutex); - - mutexp->mutex_set_wait = mutexp->mutex_set_nowait = 0; -} - -#else /* !HAVE_STATISTICS */ - -int -__mutex_stat(dbenv, statp, flags) - DB_ENV *dbenv; - DB_MUTEX_STAT **statp; - u_int32_t flags; -{ - COMPQUIET(statp, NULL); - COMPQUIET(flags, 0); - - return (__db_stat_not_built(dbenv)); -} - -int -__mutex_stat_print(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - COMPQUIET(flags, 0); - - return (__db_stat_not_built(dbenv)); -} -#endif diff --git a/storage/bdb/mutex/mut_tas.c b/storage/bdb/mutex/mut_tas.c deleted file mode 100644 index 205637c980d..00000000000 --- a/storage/bdb/mutex/mut_tas.c +++ /dev/null @@ -1,255 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: mut_tas.c,v 12.14 2005/11/01 14:42:17 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stdlib.h> -#include <string.h> -#endif - -#include "db_int.h" - -/* - * This is where we load in the actual test-and-set mutex code. - */ -#define LOAD_ACTUAL_MUTEX_CODE -#include "dbinc/mutex_int.h" - -/* - * __db_tas_mutex_init -- - * Initialize a test-and-set mutex. - * - * PUBLIC: int __db_tas_mutex_init __P((DB_ENV *, db_mutex_t, u_int32_t)); - */ -int -__db_tas_mutex_init(dbenv, mutex, flags) - DB_ENV *dbenv; - db_mutex_t mutex; - u_int32_t flags; -{ - DB_MUTEX *mutexp; - DB_MUTEXMGR *mtxmgr; - DB_MUTEXREGION *mtxregion; - int ret; - - COMPQUIET(flags, 0); - - mtxmgr = dbenv->mutex_handle; - mtxregion = mtxmgr->reginfo.primary; - mutexp = MUTEXP_SET(mutex); - - /* Check alignment. */ - if (((uintptr_t)mutexp & (dbenv->mutex_align - 1)) != 0) { - __db_err(dbenv, "TAS: mutex not appropriately aligned"); - return (EINVAL); - } - - if (MUTEX_INIT(&mutexp->tas)) { - ret = __os_get_errno(); - __db_err(dbenv, - "TAS: mutex initialize: %s", db_strerror(ret)); - return (ret); - } - return (0); -} - -/* - * __db_tas_mutex_lock - * Lock on a mutex, blocking if necessary. - * - * PUBLIC: int __db_tas_mutex_lock __P((DB_ENV *, db_mutex_t)); - */ -int -__db_tas_mutex_lock(dbenv, mutex) - DB_ENV *dbenv; - db_mutex_t mutex; -{ - DB_MUTEX *mutexp; - DB_MUTEXMGR *mtxmgr; - DB_MUTEXREGION *mtxregion; - u_int32_t nspins; - u_long ms, max_ms; - - if (!MUTEX_ON(dbenv) || F_ISSET(dbenv, DB_ENV_NOLOCKING)) - return (0); - - mtxmgr = dbenv->mutex_handle; - mtxregion = mtxmgr->reginfo.primary; - mutexp = MUTEXP_SET(mutex); - -#ifdef HAVE_STATISTICS - if (F_ISSET(mutexp, DB_MUTEX_LOCKED)) - ++mutexp->mutex_set_wait; - else - ++mutexp->mutex_set_nowait; -#endif - - /* - * Wait 1ms initially, up to 10ms for mutexes backing logical database - * locks, and up to 25 ms for mutual exclusion data structure mutexes. - * SR: #7675 - */ - ms = 1; - max_ms = F_ISSET(mutexp, DB_MUTEX_LOGICAL_LOCK) ? 10 : 25; - -loop: /* Attempt to acquire the resource for N spins. */ - for (nspins = - mtxregion->stat.st_mutex_tas_spins; nspins > 0; --nspins) { -#ifdef HAVE_MUTEX_HPPA_MSEM_INIT -relock: -#endif -#ifdef HAVE_MUTEX_S390_CC_ASSEMBLY - tsl_t zero = 0; -#endif - /* - * Avoid interlocked instructions until they're likely to - * succeed. - */ - if (F_ISSET(mutexp, DB_MUTEX_LOCKED) || - !MUTEX_SET(&mutexp->tas)) { - /* - * Some systems (notably those with newer Intel CPUs) - * need a small pause here. [#6975] - */ -#ifdef MUTEX_PAUSE - MUTEX_PAUSE -#endif - continue; - } - -#ifdef HAVE_MUTEX_HPPA_MSEM_INIT - /* - * HP semaphores are unlocked automatically when a holding - * process exits. If the mutex appears to be locked - * (F_ISSET(DB_MUTEX_LOCKED)) but we got here, assume this - * has happened. Set the pid and tid into the mutex and - * lock again. (The default state of the mutexes used to - * block in __lock_get_internal is locked, so exiting with - * a locked mutex is reasonable behavior for a process that - * happened to initialize or use one of them.) - */ - if (F_ISSET(mutexp, DB_MUTEX_LOCKED)) { - F_SET(mutexp, DB_MUTEX_LOCKED); - dbenv->thread_id(dbenv, &mutexp->pid, &mutexp->tid); - CHECK_MTX_THREAD(dbenv, mutexp); - goto relock; - } - /* - * If we make it here, the mutex isn't locked, the diagnostic - * won't fire, and we were really unlocked by someone calling - * the DB mutex unlock function. - */ -#endif -#ifdef DIAGNOSTIC - if (F_ISSET(mutexp, DB_MUTEX_LOCKED)) { - char buf[DB_THREADID_STRLEN]; - __db_err(dbenv, - "TAS lock failed: lock currently in use: ID: %s", - dbenv->thread_id_string(dbenv, - mutexp->pid, mutexp->tid, buf)); - return (__db_panic(dbenv, EACCES)); - } -#endif - F_SET(mutexp, DB_MUTEX_LOCKED); - dbenv->thread_id(dbenv, &mutexp->pid, &mutexp->tid); - CHECK_MTX_THREAD(dbenv, mutexp); - -#ifdef DIAGNOSTIC - /* - * We want to switch threads as often as possible. Yield - * every time we get a mutex to ensure contention. - */ - if (F_ISSET(dbenv, DB_ENV_YIELDCPU)) - __os_yield(NULL, 1); -#endif - return (0); - } - - /* - * Yield the processor. - */ - __os_yield(NULL, ms * USEC_PER_MS); - if ((ms <<= 1) > max_ms) - ms = max_ms; - - /* - * We're spinning. The environment might be hung, and somebody else - * has already recovered it. The first thing recovery does is panic - * the environment. Check to see if we're never going to get this - * mutex. - */ - PANIC_CHECK(dbenv); - - goto loop; -} - -/* - * __db_tas_mutex_unlock -- - * Release a mutex. - * - * PUBLIC: int __db_tas_mutex_unlock __P((DB_ENV *, db_mutex_t)); - */ -int -__db_tas_mutex_unlock(dbenv, mutex) - DB_ENV *dbenv; - db_mutex_t mutex; -{ - DB_MUTEX *mutexp; - DB_MUTEXMGR *mtxmgr; - DB_MUTEXREGION *mtxregion; - - if (!MUTEX_ON(dbenv) || F_ISSET(dbenv, DB_ENV_NOLOCKING)) - return (0); - - mtxmgr = dbenv->mutex_handle; - mtxregion = mtxmgr->reginfo.primary; - mutexp = MUTEXP_SET(mutex); - -#ifdef DIAGNOSTIC - if (!F_ISSET(mutexp, DB_MUTEX_LOCKED)) { - __db_err(dbenv, "TAS unlock failed: lock already unlocked"); - return (__db_panic(dbenv, EACCES)); - } -#endif - F_CLR(mutexp, DB_MUTEX_LOCKED); - - MUTEX_UNSET(&mutexp->tas); - - return (0); -} - -/* - * __db_tas_mutex_destroy -- - * Destroy a mutex. - * - * PUBLIC: int __db_tas_mutex_destroy __P((DB_ENV *, db_mutex_t)); - */ -int -__db_tas_mutex_destroy(dbenv, mutex) - DB_ENV *dbenv; - db_mutex_t mutex; -{ - DB_MUTEX *mutexp; - DB_MUTEXMGR *mtxmgr; - DB_MUTEXREGION *mtxregion; - - if (!MUTEX_ON(dbenv)) - return (0); - - mtxmgr = dbenv->mutex_handle; - mtxregion = mtxmgr->reginfo.primary; - mutexp = MUTEXP_SET(mutex); - - MUTEX_DESTROY(&mutexp->tas); - - return (0); -} diff --git a/storage/bdb/mutex/mut_win32.c b/storage/bdb/mutex/mut_win32.c deleted file mode 100644 index 5e291a550d5..00000000000 --- a/storage/bdb/mutex/mut_win32.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2002-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: mut_win32.c,v 12.15 2005/11/01 11:49:31 mjc Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" - -/* - * This is where we load in the actual test-and-set mutex code. - */ -#define LOAD_ACTUAL_MUTEX_CODE -#include "dbinc/mutex_int.h" - -/* We don't want to run this code even in "ordinary" diagnostic mode. */ -#undef MUTEX_DIAG - -/* - * Common code to get an event handle. This is executed whenever a mutex - * blocks, or when unlocking a mutex that a thread is waiting on. We can't - * keep these handles around, since the mutex structure is in shared memory, - * and each process gets its own handle value. - * - * We pass security attributes so that the created event is accessible by all - * users, in case a Windows service is sharing an environment with a local - * process run as a different user. - */ -static _TCHAR hex_digits[] = _T("0123456789abcdef"); -static SECURITY_DESCRIPTOR null_sd; -static SECURITY_ATTRIBUTES all_sa; -static int security_initialized = 0; - -static __inline int get_handle(dbenv, mutexp, eventp) - DB_ENV *dbenv; - DB_MUTEX *mutexp; - HANDLE *eventp; -{ - _TCHAR idbuf[] = _T("db.m00000000"); - _TCHAR *p = idbuf + 12; - int ret = 0; - u_int32_t id; - - for (id = (mutexp)->id; id != 0; id >>= 4) - *--p = hex_digits[id & 0xf]; - - if (!security_initialized) { - InitializeSecurityDescriptor(&null_sd, - SECURITY_DESCRIPTOR_REVISION); - SetSecurityDescriptorDacl(&null_sd, TRUE, 0, FALSE); - all_sa.nLength = sizeof(SECURITY_ATTRIBUTES); - all_sa.bInheritHandle = FALSE; - all_sa.lpSecurityDescriptor = &null_sd; - security_initialized = 1; - } - - if ((*eventp = CreateEvent(&all_sa, FALSE, FALSE, idbuf)) == NULL) { - ret = __os_get_errno(); - __db_err(dbenv, "Win32 create event failed: %s", - db_strerror(ret)); - } - - return (ret); -} - -/* - * __db_win32_mutex_init -- - * Initialize a Win32 mutex. - * - * PUBLIC: int __db_win32_mutex_init __P((DB_ENV *, db_mutex_t, u_int32_t)); - */ -int -__db_win32_mutex_init(dbenv, mutex, flags) - DB_ENV *dbenv; - db_mutex_t mutex; - u_int32_t flags; -{ - DB_MUTEX *mutexp; - DB_MUTEXMGR *mtxmgr; - DB_MUTEXREGION *mtxregion; - - mtxmgr = dbenv->mutex_handle; - mtxregion = mtxmgr->reginfo.primary; - mutexp = MUTEXP_SET(mutex); - - mutexp->id = ((getpid() & 0xffff) << 16) ^ P_TO_UINT32(mutexp); - - return (0); -} - -/* - * __db_win32_mutex_lock - * Lock on a mutex, blocking if necessary. - * - * PUBLIC: int __db_win32_mutex_lock __P((DB_ENV *, db_mutex_t)); - */ -int -__db_win32_mutex_lock(dbenv, mutex) - DB_ENV *dbenv; - db_mutex_t mutex; -{ - DB_MUTEX *mutexp; - DB_MUTEXMGR *mtxmgr; - DB_MUTEXREGION *mtxregion; - HANDLE event; - u_int32_t nspins; - int ms, ret; -#ifdef MUTEX_DIAG - LARGE_INTEGER now; -#endif - - if (!MUTEX_ON(dbenv) || F_ISSET(dbenv, DB_ENV_NOLOCKING)) - return (0); - - mtxmgr = dbenv->mutex_handle; - mtxregion = mtxmgr->reginfo.primary; - mutexp = MUTEXP_SET(mutex); - - event = NULL; - ms = 50; - ret = 0; - -loop: /* Attempt to acquire the resource for N spins. */ - for (nspins = - mtxregion->stat.st_mutex_tas_spins; nspins > 0; --nspins) { - /* - * We can avoid the (expensive) interlocked instructions if - * the mutex is already "set". - */ - if (mutexp->tas || !MUTEX_SET(&mutexp->tas)) { - /* - * Some systems (notably those with newer Intel CPUs) - * need a small pause here. [#6975] - */ -#ifdef MUTEX_PAUSE - MUTEX_PAUSE -#endif - continue; - } - -#ifdef DIAGNOSTIC - if (F_ISSET(mutexp, DB_MUTEX_LOCKED)) { - char buf[DB_THREADID_STRLEN]; - __db_err(dbenv, - "Win32 lock failed: mutex already locked by %s", - dbenv->thread_id_string(dbenv, - mutexp->pid, mutexp->tid, buf)); - return (__db_panic(dbenv, EACCES)); - } -#endif - F_SET(mutexp, DB_MUTEX_LOCKED); - dbenv->thread_id(dbenv, &mutexp->pid, &mutexp->tid); - CHECK_MTX_THREAD(dbenv, mutexp); - -#ifdef HAVE_STATISTICS - if (event == NULL) - ++mutexp->mutex_set_nowait; - else - ++mutexp->mutex_set_wait; -#endif - if (event != NULL) { - CloseHandle(event); - InterlockedDecrement(&mutexp->nwaiters); -#ifdef MUTEX_DIAG - if (ret != WAIT_OBJECT_0) { - QueryPerformanceCounter(&now); - printf("[%I64d]: Lost signal on mutex %p, " - "id %d, ms %d\n", - now.QuadPart, mutexp, mutexp->id, ms); - } -#endif - } - -#ifdef DIAGNOSTIC - /* - * We want to switch threads as often as possible. Yield - * every time we get a mutex to ensure contention. - */ - if (F_ISSET(dbenv, DB_ENV_YIELDCPU)) - __os_yield(NULL, 1); -#endif - - return (0); - } - - /* - * Yield the processor; wait 50 ms initially, up to 1 second. This - * loop is needed to work around a race where the signal from the - * unlocking thread gets lost. We start at 50 ms because it's unlikely - * to happen often and we want to avoid wasting CPU. - */ - if (event == NULL) { -#ifdef MUTEX_DIAG - QueryPerformanceCounter(&now); - printf("[%I64d]: Waiting on mutex %p, id %d\n", - now.QuadPart, mutexp, mutexp->id); -#endif - InterlockedIncrement(&mutexp->nwaiters); - if ((ret = get_handle(dbenv, mutexp, &event)) != 0) - goto err; - } - if ((ret = WaitForSingleObject(event, ms)) == WAIT_FAILED) { - ret = __os_get_errno(); - goto err; - } - if ((ms <<= 1) > MS_PER_SEC) - ms = MS_PER_SEC; - - PANIC_CHECK(dbenv); - goto loop; - -err: __db_err(dbenv, "Win32 lock failed: %s", db_strerror(ret)); - return (__db_panic(dbenv, ret)); -} - -/* - * __db_win32_mutex_unlock -- - * Release a mutex. - * - * PUBLIC: int __db_win32_mutex_unlock __P((DB_ENV *, db_mutex_t)); - */ -int -__db_win32_mutex_unlock(dbenv, mutex) - DB_ENV *dbenv; - db_mutex_t mutex; -{ - DB_MUTEX *mutexp; - DB_MUTEXMGR *mtxmgr; - DB_MUTEXREGION *mtxregion; - HANDLE event; - int ret; -#ifdef MUTEX_DIAG - LARGE_INTEGER now; -#endif - if (!MUTEX_ON(dbenv) || F_ISSET(dbenv, DB_ENV_NOLOCKING)) - return (0); - - mtxmgr = dbenv->mutex_handle; - mtxregion = mtxmgr->reginfo.primary; - mutexp = MUTEXP_SET(mutex); - -#ifdef DIAGNOSTIC - if (!mutexp->tas || !F_ISSET(mutexp, DB_MUTEX_LOCKED)) { - __db_err(dbenv, "Win32 unlock failed: lock already unlocked"); - return (__db_panic(dbenv, EACCES)); - } -#endif - F_CLR(mutexp, DB_MUTEX_LOCKED); - MUTEX_UNSET(&mutexp->tas); - - if (mutexp->nwaiters > 0) { - if ((ret = get_handle(dbenv, mutexp, &event)) != 0) - goto err; - -#ifdef MUTEX_DIAG - QueryPerformanceCounter(&now); - printf("[%I64d]: Signalling mutex %p, id %d\n", - now.QuadPart, mutexp, mutexp->id); -#endif - if (!PulseEvent(event)) { - ret = __os_get_errno(); - CloseHandle(event); - goto err; - } - - CloseHandle(event); - } - - return (0); - -err: __db_err(dbenv, "Win32 unlock failed: %s", db_strerror(ret)); - return (__db_panic(dbenv, ret)); -} - -/* - * __db_win32_mutex_destroy -- - * Destroy a mutex. - * - * PUBLIC: int __db_win32_mutex_destroy __P((DB_ENV *, db_mutex_t)); - */ -int -__db_win32_mutex_destroy(dbenv, mutex) - DB_ENV *dbenv; - db_mutex_t mutex; -{ - return (0); -} diff --git a/storage/bdb/mutex/tm.c b/storage/bdb/mutex/tm.c deleted file mode 100644 index ce685c8b7b7..00000000000 --- a/storage/bdb/mutex/tm.c +++ /dev/null @@ -1,1020 +0,0 @@ -/* - * Standalone mutex tester for Berkeley DB mutexes. - * - * $Id: tm.c,v 12.10 2005/10/21 17:53:04 bostic Exp $ - */ -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#include <sys/wait.h> - -#include <errno.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - -#if defined(MUTEX_THREAD_TEST) -#include <pthread.h> -#endif -#endif - -#include "db_int.h" - -#ifdef DB_WIN32 -extern int getopt(int, char * const *, const char *); - -typedef HANDLE os_pid_t; -typedef HANDLE os_thread_t; - -#define os_thread_create(thrp, attr, func, arg) \ - (((*(thrp) = CreateThread(NULL, 0, \ - (LPTHREAD_START_ROUTINE)(func), (arg), 0, NULL)) == NULL) ? -1 : 0) -#define os_thread_join(thr, statusp) \ - ((WaitForSingleObject((thr), INFINITE) == WAIT_OBJECT_0) && \ - GetExitCodeThread((thr), (LPDWORD)(statusp)) ? 0 : -1) -#define os_thread_self() GetCurrentThreadId() - -#else /* !DB_WIN32 */ - -typedef pid_t os_pid_t; - -#ifdef MUTEX_THREAD_TEST -typedef pthread_t os_thread_t; -#endif - -#define os_thread_create(thrp, attr, func, arg) \ - pthread_create((thrp), (attr), (func), (arg)) -#define os_thread_join(thr, statusp) pthread_join((thr), (statusp)) -#define os_thread_self() pthread_self() -#endif - -#define OS_BAD_PID (os_pid_t)-1 - -#define TESTDIR "TESTDIR" /* Working area */ -#define MT_FILE "TESTDIR/mutex.file" -#define MT_FILE_QUIT "TESTDIR/mutex.file.quit" - -/* - * The backing file layout: - * TM[1] per-thread mutex array lock - * TM[nthreads] per-thread mutex array - * TM[maxlocks] per-lock mutex array - */ -typedef struct { - db_mutex_t mutex; /* Mutex. */ - u_long id; /* Holder's ID. */ - u_int wakeme; /* Request to awake. */ -} TM; - -DB_ENV *dbenv; /* Backing environment */ -size_t len; /* Backing file size. */ - -u_int8_t *gm_addr; /* Global mutex */ -u_int8_t *lm_addr; /* Locker mutexes */ -u_int8_t *tm_addr; /* Thread mutexes */ - -#ifdef MUTEX_THREAD_TEST -os_thread_t *kidsp; /* Locker threads */ -os_thread_t wakep; /* Wakeup thread */ -#endif - -int maxlocks = 20; /* -l: Backing locks. */ -int nlocks = 10000; /* -n: Locks per processes. */ -int nprocs = 20; /* -p: Processes. */ -int nthreads = 1; /* -t: Threads. */ -int verbose; /* -v: Verbosity. */ - -int locker_start(u_long); -int locker_wait(void); -void map_file(u_int8_t **, u_int8_t **, u_int8_t **, DB_FH **); -os_pid_t os_spawn(const char *, char *const[]); -int os_wait(os_pid_t *, int); -void *run_lthread(void *); -void *run_wthread(void *); -os_pid_t spawn_proc(u_long, char *, char *); -void tm_env_close(void); -int tm_env_init(void); -void tm_file_init(void); -void tm_mutex_destroy(void); -void tm_mutex_init(void); -void tm_mutex_stats(void); -void unmap_file(u_int8_t *, DB_FH *); -int usage(void); -int wakeup_start(u_long); -int wakeup_wait(void); - -int -main(argc, argv) - int argc; - char *argv[]; -{ - enum {LOCKER, WAKEUP, PARENT} rtype; - extern int optind; - extern char *optarg; - os_pid_t wakeup_pid, *pids; - u_long id; - DB_FH *fhp, *map_fhp; - int ch, err, i; - char *p, *tmpath, cmd[1024]; - - rtype = PARENT; - id = 0; - tmpath = argv[0]; - while ((ch = getopt(argc, argv, "l:n:p:T:t:v")) != EOF) - switch (ch) { - case 'l': - maxlocks = atoi(optarg); - break; - case 'n': - nlocks = atoi(optarg); - break; - case 'p': - nprocs = atoi(optarg); - break; - case 't': - if ((nthreads = atoi(optarg)) == 0) - nthreads = 1; -#if !defined(MUTEX_THREAD_TEST) - if (nthreads != 1) { - (void)fprintf(stderr, - "tm: thread support not available or not compiled for this platform.\n"); - return (EXIT_FAILURE); - } -#endif - break; - case 'T': - if (!memcmp(optarg, "locker", sizeof("locker") - 1)) - rtype = LOCKER; - else if ( - !memcmp(optarg, "wakeup", sizeof("wakeup") - 1)) - rtype = WAKEUP; - else - return (usage()); - if ((p = strchr(optarg, '=')) == NULL) - return (usage()); - id = atoi(p + 1); - break; - case 'v': - verbose = 1; - break; - case '?': - default: - return (usage()); - } - argc -= optind; - argv += optind; - - /* - * If we're not running a multi-process test, we should be running - * a multi-thread test. - */ - if (nprocs == 1 && nthreads == 1) { - fprintf(stderr, - "tm: running in a single process requires multiple threads\n"); - return (EXIT_FAILURE); - } - - len = sizeof(TM) * (1 + nthreads * nprocs + maxlocks); - - /* - * In the multi-process test, the parent spawns processes that exec - * the original binary, ending up here. Each process joins the DB - * environment separately and then calls the supporting function. - */ - if (rtype == LOCKER || rtype == WAKEUP) { - __os_sleep(dbenv, 3, 0); /* Let everyone catch up. */ - /* Initialize random numbers. */ - srand((u_int)time(NULL) % getpid()); - - if (tm_env_init() != 0) /* Join the environment. */ - exit(EXIT_FAILURE); - /* Join the backing file. */ - map_file(&gm_addr, &tm_addr, &lm_addr, &map_fhp); - if (verbose) - printf( - "Backing file: global (%#lx), threads (%#lx), locks (%#lx)\n", - (u_long)gm_addr, (u_long)tm_addr, (u_long)lm_addr); - - if ((rtype == LOCKER ? - locker_start(id) : wakeup_start(id)) != 0) - exit(EXIT_FAILURE); - if ((rtype == LOCKER ? locker_wait() : wakeup_wait()) != 0) - exit(EXIT_FAILURE); - - unmap_file(gm_addr, map_fhp); /* Detach from backing file. */ - - tm_env_close(); /* Detach from environment. */ - - exit(EXIT_SUCCESS); - } - - /* - * The following code is only executed by the original parent process. - * - * Clean up from any previous runs. - */ - snprintf(cmd, sizeof(cmd), "rm -rf %s", TESTDIR); - (void)system(cmd); - snprintf(cmd, sizeof(cmd), "mkdir %s", TESTDIR); - (void)system(cmd); - - printf( - "tm: %d processes, %d threads/process, %d lock requests from %d locks\n", - nprocs, nthreads, nlocks, maxlocks); - printf("tm: backing file %lu bytes\n", (u_long)len); - - if (tm_env_init() != 0) /* Create the environment. */ - exit(EXIT_FAILURE); - - tm_file_init(); /* Initialize backing file. */ - - /* Map in the backing file. */ - map_file(&gm_addr, &tm_addr, &lm_addr, &map_fhp); - if (verbose) - printf( - "backing file: global (%#lx), threads (%#lx), locks (%#lx)\n", - (u_long)gm_addr, (u_long)tm_addr, (u_long)lm_addr); - - tm_mutex_init(); /* Initialize mutexes. */ - - if (nprocs > 1) { /* Run the multi-process test. */ - /* Allocate array of locker process IDs. */ - if ((pids = calloc(nprocs, sizeof(os_pid_t))) == NULL) { - fprintf(stderr, "tm: %s\n", strerror(errno)); - goto fail; - } - - /* Spawn locker processes and threads. */ - for (i = 0; i < nprocs; ++i) { - if ((pids[i] = - spawn_proc(id, tmpath, "locker")) == OS_BAD_PID) { - fprintf(stderr, - "tm: failed to spawn a locker\n"); - goto fail; - } - id += nthreads; - } - - /* Spawn wakeup process/thread. */ - if ((wakeup_pid = - spawn_proc(id, tmpath, "wakeup")) == OS_BAD_PID) { - fprintf(stderr, "tm: failed to spawn waker\n"); - goto fail; - } - ++id; - - /* Wait for all lockers to exit. */ - if ((err = os_wait(pids, nprocs)) != 0) { - fprintf(stderr, "locker wait failed with %d\n", err); - goto fail; - } - - /* Signal wakeup process to exit. */ - if ((err = __os_open( - dbenv, MT_FILE_QUIT, DB_OSO_CREATE, 0664, &fhp)) != 0) { - fprintf(stderr, "tm: open %s\n", db_strerror(err)); - goto fail; - } - (void)__os_closehandle(dbenv, fhp); - - /* Wait for wakeup process/thread. */ - if ((err = os_wait(&wakeup_pid, 1)) != 0) { - fprintf(stderr, - "%lu: exited %d\n", (u_long)wakeup_pid, err); - goto fail; - } - } else { /* Run the single-process test. */ - /* Spawn locker threads. */ - if (locker_start(0) != 0) - goto fail; - - /* Spawn wakeup thread. */ - if (wakeup_start(nthreads) != 0) - goto fail; - - /* Wait for all lockers to exit. */ - if (locker_wait() != 0) - goto fail; - - /* Signal wakeup process to exit. */ - if ((err = __os_open( - dbenv, MT_FILE_QUIT, DB_OSO_CREATE, 0664, &fhp)) != 0) { - fprintf(stderr, "tm: open %s\n", db_strerror(err)); - goto fail; - } - (void)__os_closehandle(dbenv, fhp); - - /* Wait for wakeup thread. */ - if (wakeup_wait() != 0) - goto fail; - } - - tm_mutex_stats(); /* Display run statistics. */ - tm_mutex_destroy(); /* Destroy mutexes. */ - - unmap_file(gm_addr, map_fhp); /* Detach from backing file. */ - - tm_env_close(); /* Detach from environment. */ - - printf("tm: test succeeded\n"); - return (EXIT_SUCCESS); - -fail: printf("tm: FAILED!\n"); - return (EXIT_FAILURE); -} - -int -locker_start(id) - u_long id; -{ -#if defined(MUTEX_THREAD_TEST) - int err, i; - - /* - * Spawn off threads. We have nthreads all locking and going to - * sleep, and one other thread cycling through and waking them up. - */ - if ((kidsp = - (os_thread_t *)calloc(sizeof(os_thread_t), nthreads)) == NULL) { - fprintf(stderr, "tm: %s\n", strerror(errno)); - return (1); - } - for (i = 0; i < nthreads; i++) - if ((err = os_thread_create( - &kidsp[i], NULL, run_lthread, (void *)(id + i))) != 0) { - fprintf(stderr, "tm: failed spawning thread: %s\n", - db_strerror(err)); - return (1); - } - return (0); -#else - return (run_lthread((void *)id) == NULL ? 0 : 1); -#endif -} - -int -locker_wait() -{ -#if defined(MUTEX_THREAD_TEST) - int i; - void *retp; - - /* Wait for the threads to exit. */ - for (i = 0; i < nthreads; i++) { - os_thread_join(kidsp[i], &retp); - if (retp != NULL) { - fprintf(stderr, "tm: thread exited with error\n"); - return (1); - } - } - free(kidsp); -#endif - return (0); -} - -void * -run_lthread(arg) - void *arg; -{ - TM *gp, *mp, *tp; - u_long id, tid; - int err, i, lock, nl; - - id = (uintptr_t)arg; -#if defined(MUTEX_THREAD_TEST) - tid = (u_long)os_thread_self(); -#else - tid = 0; -#endif - printf("Locker: ID %03lu (PID: %lu; TID: %lx)\n", - id, (u_long)getpid(), tid); - - gp = (TM *)gm_addr; - tp = (TM *)(tm_addr + id * sizeof(TM)); - - for (nl = nlocks; nl > 0;) { - /* Select and acquire a data lock. */ - lock = rand() % maxlocks; - mp = (TM *)(lm_addr + lock * sizeof(TM)); - if (verbose) - printf("%03lu: lock %d (mtx: %lu)\n", - id, lock, (u_long)mp->mutex); - - if ((err = dbenv->mutex_lock(dbenv, mp->mutex)) != 0) { - fprintf(stderr, "%03lu: never got lock %d: %s\n", - id, lock, db_strerror(err)); - return ((void *)1); - } - if (mp->id != 0) { - fprintf(stderr, - "RACE! (%03lu granted lock %d held by %03lu)\n", - id, lock, mp->id); - return ((void *)1); - } - mp->id = id; - - /* - * Pretend to do some work, periodically checking to see if - * we still hold the mutex. - */ - for (i = 0; i < 3; ++i) { - __os_sleep(dbenv, 0, rand() % 3); - if (mp->id != id) { - fprintf(stderr, - "RACE! (%03lu stole lock %d from %03lu)\n", - mp->id, lock, id); - return ((void *)1); - } - } - - /* - * Test self-blocking and unlocking by other threads/processes: - * - * acquire the global lock - * set our wakeup flag - * release the global lock - * acquire our per-thread lock - * - * The wakeup thread will wake us up. - */ - if ((err = dbenv->mutex_lock(dbenv, gp->mutex)) != 0) { - fprintf(stderr, - "%03lu: global lock: %s\n", id, db_strerror(err)); - return ((void *)1); - } - if (tp->id != 0 && tp->id != id) { - fprintf(stderr, - "%03lu: per-thread mutex isn't mine, owned by %03lu\n", - id, tp->id); - return ((void *)1); - } - tp->id = id; - if (verbose) - printf("%03lu: self-blocking (mtx: %lu)\n", - id, (u_long)tp->mutex); - if (tp->wakeme) { - fprintf(stderr, - "%03lu: wakeup flag incorrectly set\n", id); - return ((void *)1); - } - tp->wakeme = 1; - if ((err = dbenv->mutex_unlock(dbenv, gp->mutex)) != 0) { - fprintf(stderr, - "%03lu: global unlock: %s\n", id, db_strerror(err)); - return ((void *)1); - } - if ((err = dbenv->mutex_lock(dbenv, tp->mutex)) != 0) { - fprintf(stderr, "%03lu: per-thread lock: %s\n", - id, db_strerror(err)); - return ((void *)1); - } - /* Time passes... */ - if (tp->wakeme) { - fprintf(stderr, "%03lu: wakeup flag not cleared\n", id); - return ((void *)1); - } - - if (verbose) - printf("%03lu: release %d (mtx: %lu)\n", - id, lock, (u_long)mp->mutex); - - /* Release the data lock. */ - mp->id = 0; - if ((err = dbenv->mutex_unlock(dbenv, mp->mutex)) != 0) { - fprintf(stderr, - "%03lu: lock release: %s\n", id, db_strerror(err)); - return ((void *)1); - } - - if (--nl % 100 == 0) { - fprintf(stderr, "%03lu: %d\n", id, nl); - /* - * Windows buffers stderr and the output looks wrong - * without this. - */ - fflush(stderr); - } - } - - return (NULL); -} - -int -wakeup_start(id) - u_long id; -{ -#if defined(MUTEX_THREAD_TEST) - int err; - - /* - * Spawn off wakeup thread. - */ - if ((err = os_thread_create( - &wakep, NULL, run_wthread, (void *)id)) != 0) { - fprintf(stderr, "tm: failed spawning wakeup thread: %s\n", - db_strerror(err)); - return (1); - } - return (0); -#else - return (run_wthread((void *)id) == NULL ? 0 : 1); -#endif -} - -int -wakeup_wait() -{ -#if defined(MUTEX_THREAD_TEST) - void *retp; - - /* - * A file is created when the wakeup thread is no longer needed. - */ - os_thread_join(wakep, &retp); - if (retp != NULL) { - fprintf(stderr, "tm: wakeup thread exited with error\n"); - return (1); - } -#endif - return (0); -} - -/* - * run_wthread -- - * Thread to wake up other threads that are sleeping. - */ -void * -run_wthread(arg) - void *arg; -{ - TM *gp, *tp; - u_long id, tid; - int check_id, err; - - id = (uintptr_t)arg; -#if defined(MUTEX_THREAD_TEST) - tid = (u_long)os_thread_self(); -#else - tid = 0; -#endif - printf("Wakeup: ID %03lu (PID: %lu; TID: %lx)\n", - id, (u_long)getpid(), tid); - - gp = (TM *)gm_addr; - - /* Loop, waking up sleepers and periodically sleeping ourselves. */ - for (check_id = 0;; ++check_id) { - /* Check to see if the locking threads have finished. */ - if (__os_exists(MT_FILE_QUIT, NULL) == 0) - break; - - /* Check for ID wraparound. */ - if (check_id == nthreads * nprocs) - check_id = 0; - - /* Check for a thread that needs a wakeup. */ - tp = (TM *)(tm_addr + check_id * sizeof(TM)); - if (!tp->wakeme) - continue; - - if (verbose) { - printf("%03lu: wakeup thread %03lu (mtx: %lu)\n", - id, tp->id, (u_long)tp->mutex); - fflush(stdout); - } - - /* Acquire the global lock. */ - if ((err = dbenv->mutex_lock(dbenv, gp->mutex)) != 0) { - fprintf(stderr, - "wakeup: global lock: %s\n", db_strerror(err)); - return ((void *)1); - } - - tp->wakeme = 0; - if ((err = dbenv->mutex_unlock(dbenv, tp->mutex)) != 0) { - fprintf(stderr, - "wakeup: unlock: %s\n", db_strerror(err)); - return ((void *)1); - } - - if ((err = dbenv->mutex_unlock(dbenv, gp->mutex))) { - fprintf(stderr, - "wakeup: global unlock: %s\n", db_strerror(err)); - return ((void *)1); - } - - __os_sleep(dbenv, 0, rand() % 3); - } - return (NULL); -} - -/* - * tm_env_init -- - * Create the backing database environment. - */ -int -tm_env_init() -{ - u_int32_t flags; - int ret; - char *home; - - /* - * Create an environment object and initialize it for error - * reporting. - */ - if ((ret = db_env_create(&dbenv, 0)) != 0) { - fprintf(stderr, "tm: %s\n", db_strerror(ret)); - return (1); - } - dbenv->set_errfile(dbenv, stderr); - dbenv->set_errpfx(dbenv, "tm"); - - /* Allocate enough mutexes. */ - if ((ret = dbenv->mutex_set_increment(dbenv, - 1 + nthreads * nprocs + maxlocks)) != 0) { - dbenv->err(dbenv, ret, "dbenv->mutex_set_increment"); - return (1); - } - - flags = DB_CREATE; - if (nprocs == 1) { - home = NULL; - flags |= DB_PRIVATE; - } else - home = TESTDIR; - if (nthreads != 1) - flags |= DB_THREAD; - if ((ret = dbenv->open(dbenv, home, flags, 0)) != 0) { - dbenv->err(dbenv, ret, "environment open: %s", home); - return (1); - } - - return (0); -} - -/* - * tm_env_close -- - * Close the backing database environment. - */ -void -tm_env_close() -{ - (void)dbenv->close(dbenv, 0); -} - -/* - * tm_file_init -- - * Initialize the backing file. - */ -void -tm_file_init() -{ - DB_FH *fhp; - int err; - size_t nwrite; - - /* Initialize the backing file. */ - if (verbose) - printf("Create the backing file.\n"); - - (void)unlink(MT_FILE); - - if ((err = __os_open(dbenv, MT_FILE, - DB_OSO_CREATE | DB_OSO_TRUNC, 0666, &fhp)) == -1) { - (void)fprintf(stderr, - "%s: open: %s\n", MT_FILE, db_strerror(err)); - exit(EXIT_FAILURE); - } - - if ((err = __os_seek(dbenv, fhp, - 0, 0, len, 0, DB_OS_SEEK_SET)) != 0 || - (err = __os_write(dbenv, fhp, &err, 1, &nwrite)) != 0 || - nwrite != 1) { - (void)fprintf(stderr, - "%s: seek/write: %s\n", MT_FILE, db_strerror(err)); - exit(EXIT_FAILURE); - } - (void)__os_closehandle(dbenv, fhp); -} - -/* - * tm_mutex_init -- - * Initialize the mutexes. - */ -void -tm_mutex_init() -{ - TM *mp; - int err, i; - - if (verbose) - printf("Allocate the global mutex: "); - mp = (TM *)gm_addr; - if ((err = dbenv->mutex_alloc(dbenv, 0, &mp->mutex)) != 0) { - fprintf(stderr, - "DB_ENV->mutex_alloc (global): %s\n", db_strerror(err)); - exit(EXIT_FAILURE); - } - if (verbose) - printf("%lu\n", (u_long)mp->mutex); - - if (verbose) - printf( - "Allocate %d per-thread, self-blocking mutexes: ", - nthreads * nprocs); - for (i = 0; i < nthreads * nprocs; ++i) { - mp = (TM *)(tm_addr + i * sizeof(TM)); - if ((err = dbenv->mutex_alloc( - dbenv, DB_MUTEX_SELF_BLOCK, &mp->mutex)) != 0) { - fprintf(stderr, - "DB_ENV->mutex_alloc (per-thread %d): %s\n", - i, db_strerror(err)); - exit(EXIT_FAILURE); - } - if ((err = dbenv->mutex_lock(dbenv, mp->mutex)) != 0) { - fprintf(stderr, - "DB_ENV->mutex_lock (per-thread %d): %s\n", - i, db_strerror(err)); - exit(EXIT_FAILURE); - } - if (verbose) - printf("%lu ", (u_long)mp->mutex); - } - if (verbose) - printf("\n"); - - if (verbose) - printf("Allocate %d per-lock mutexes: ", maxlocks); - for (i = 0; i < maxlocks; ++i) { - mp = (TM *)(lm_addr + i * sizeof(TM)); - if ((err = dbenv->mutex_alloc(dbenv, 0, &mp->mutex)) != 0) { - fprintf(stderr, - "DB_ENV->mutex_alloc (per-lock: %d): %s\n", - i, db_strerror(err)); - exit(EXIT_FAILURE); - } - if (verbose) - printf("%lu ", (u_long)mp->mutex); - } - if (verbose) - printf("\n"); -} - -/* - * tm_mutex_destroy -- - * Destroy the mutexes. - */ -void -tm_mutex_destroy() -{ - TM *gp, *mp; - int err, i; - - if (verbose) - printf("Destroy the global mutex.\n"); - gp = (TM *)gm_addr; - if ((err = dbenv->mutex_free(dbenv, gp->mutex)) != 0) { - fprintf(stderr, - "DB_ENV->mutex_free (global): %s\n", db_strerror(err)); - exit(EXIT_FAILURE); - } - - if (verbose) - printf("Destroy the per-thread mutexes.\n"); - for (i = 0; i < nthreads * nprocs; ++i) { - mp = (TM *)(tm_addr + i * sizeof(TM)); - if ((err = dbenv->mutex_free(dbenv, mp->mutex)) != 0) { - fprintf(stderr, - "DB_ENV->mutex_free (per-thread %d): %s\n", - i, db_strerror(err)); - exit(EXIT_FAILURE); - } - } - - if (verbose) - printf("Destroy the per-lock mutexes.\n"); - for (i = 0; i < maxlocks; ++i) { - mp = (TM *)(lm_addr + i * sizeof(TM)); - if ((err = dbenv->mutex_free(dbenv, mp->mutex)) != 0) { - fprintf(stderr, - "DB_ENV->mutex_free (per-lock: %d): %s\n", - i, db_strerror(err)); - exit(EXIT_FAILURE); - } - } - - (void)unlink(MT_FILE); -} - -/* - * tm_mutex_stats -- - * Display mutex statistics. - */ -void -tm_mutex_stats() -{ -#ifdef HAVE_STATISTICS - TM *mp; - int i; - u_int32_t set_wait, set_nowait; - - printf("Per-lock mutex statistics.\n"); - for (i = 0; i < maxlocks; ++i) { - mp = (TM *)(lm_addr + i * sizeof(TM)); - __mutex_set_wait_info(dbenv, mp->mutex, &set_wait, &set_nowait); - printf("mutex %2d: wait: %lu; no wait %lu\n", i, - (u_long)set_wait, (u_long)set_nowait); - } -#endif -} - -/* - * map_file -- - * Map in the backing file. - */ -void -map_file(gm_addrp, tm_addrp, lm_addrp, fhpp) - u_int8_t **gm_addrp, **tm_addrp, **lm_addrp; - DB_FH **fhpp; -{ - void *addr; - DB_FH *fhp; - int err; - -#ifndef MAP_FAILED -#define MAP_FAILED (void *)-1 -#endif -#ifndef MAP_FILE -#define MAP_FILE 0 -#endif - if ((err = __os_open(dbenv, MT_FILE, 0, 0, &fhp)) != 0) { - fprintf(stderr, "%s: open %s\n", MT_FILE, db_strerror(err)); - exit(EXIT_FAILURE); - } - - if ((err = __os_mapfile(dbenv, MT_FILE, fhp, len, 0, &addr)) != 0) { - fprintf(stderr, "%s: mmap: %s\n", MT_FILE, db_strerror(err)); - exit(EXIT_FAILURE); - } - - *gm_addrp = (u_int8_t *)addr; - addr = (u_int8_t *)addr + sizeof(TM); - *tm_addrp = (u_int8_t *)addr; - addr = (u_int8_t *)addr + sizeof(TM) * (nthreads * nprocs); - *lm_addrp = (u_int8_t *)addr; - - if (fhpp != NULL) - *fhpp = fhp; -} - -/* - * unmap_file -- - * Discard backing file map. - */ -void -unmap_file(addr, fhp) - u_int8_t *addr; - DB_FH *fhp; -{ - int err; - - if ((err = __os_unmapfile(dbenv, addr, len)) != 0) { - fprintf(stderr, "munmap: %s\n", db_strerror(err)); - exit(EXIT_FAILURE); - } - if ((err = __os_closehandle(dbenv, fhp)) != 0) { - fprintf(stderr, "close: %s\n", db_strerror(err)); - exit(EXIT_FAILURE); - } -} - -/* - * usage -- - * - */ -int -usage() -{ - (void)fprintf(stderr, "%s\n\t%s\n", - "usage: tm [-v] [-l maxlocks]", - "[-n locks] [-p procs] [-T locker=ID|wakeup=ID] [-t threads]"); - return (EXIT_FAILURE); -} - -/* - * os_wait -- - * Wait for an array of N procs. - */ -int -os_wait(procs, nprocs) - os_pid_t *procs; - int nprocs; -{ - int i, status; -#if defined(DB_WIN32) - DWORD ret; -#endif - - status = 0; - -#if defined(DB_WIN32) - do { - ret = WaitForMultipleObjects(nprocs, procs, FALSE, INFINITE); - i = ret - WAIT_OBJECT_0; - if (i < 0 || i >= nprocs) - return (__os_get_errno()); - - if ((GetExitCodeProcess(procs[i], &ret) == 0) || (ret != 0)) - return (ret); - - /* remove the process handle from the list */ - while (++i < nprocs) - procs[i - 1] = procs[i]; - } while (--nprocs); -#elif !defined(HAVE_VXWORKS) - do { - if ((i = wait(&status)) == -1) - return (__os_get_errno()); - - if (WIFEXITED(status) == 0 || WEXITSTATUS(status) != 0) { - for (i = 0; i < nprocs; i++) - kill(procs[i], SIGKILL); - return (WEXITSTATUS(status)); - } - } while (--nprocs); -#endif - - return (0); -} - -os_pid_t -spawn_proc(id, tmpath, typearg) - u_long id; - char *tmpath, *typearg; -{ - char lbuf[16], nbuf[16], pbuf[16], tbuf[16], Tbuf[256]; - char *const vbuf = verbose ? "-v" : NULL; - char *args[] = { NULL /* tmpath */, - "-l", NULL /* lbuf */, "-n", NULL /* nbuf */, - "-p", NULL /* pbuf */, "-t", NULL /* tbuf */, - "-T", NULL /* Tbuf */, NULL /* vbuf */, - NULL - }; - - args[0] = tmpath; - snprintf(lbuf, sizeof(lbuf), "%d", maxlocks); - args[2] = lbuf; - snprintf(nbuf, sizeof(nbuf), "%d", nlocks); - args[4] = nbuf; - snprintf(pbuf, sizeof(pbuf), "%d", nprocs); - args[6] = pbuf; - snprintf(tbuf, sizeof(tbuf), "%d", nthreads); - args[8] = tbuf; - snprintf(Tbuf, sizeof(Tbuf), "%s=%lu", typearg, id); - args[10] = Tbuf; - args[11] = vbuf; - - return (os_spawn(tmpath, args)); -} - -os_pid_t -os_spawn(path, argv) - const char *path; - char *const argv[]; -{ - os_pid_t pid; - int status; - - COMPQUIET(pid, 0); - COMPQUIET(status, 0); - -#ifdef HAVE_VXWORKS - fprintf(stderr, "ERROR: os_spawn not supported for VxWorks.\n"); - return (OS_BAD_PID); -#elif defined(HAVE_QNX) - /* - * For QNX, we cannot fork if we've ever used threads. So - * we'll use their spawn function. We use 'spawnl' which - * is NOT a POSIX function. - * - * The return value of spawnl is just what we want depending - * on the value of the 'wait' arg. - */ - return (spawnv(P_NOWAIT, path, argv)); -#elif defined(DB_WIN32) - return (os_pid_t)(_spawnv(P_NOWAIT, path, argv)); -#else - if ((pid = fork()) != 0) { - if (pid == -1) - return (OS_BAD_PID); - return (pid); - } else { - execv(path, argv); - exit(EXIT_FAILURE); - } -#endif -} diff --git a/storage/bdb/mutex/uts4_cc.s b/storage/bdb/mutex/uts4_cc.s deleted file mode 100644 index 9fca580bbe4..00000000000 --- a/storage/bdb/mutex/uts4_cc.s +++ /dev/null @@ -1,27 +0,0 @@ - / See the file LICENSE for redistribution information. - / - / Copyright (c) 1997-2005 - / Sleepycat Software. All rights reserved. - / - / $Id: uts4_cc.s,v 12.1 2005/06/16 20:23:22 bostic Exp $ - / - / int uts_lock ( int *p, int i ); - / Update the lock word pointed to by p with the - / value i, using compare-and-swap. - / Returns 0 if update was successful. - / Returns 1 if update failed. - / - entry uts_lock - uts_lock: - using .,r15 - st r2,8(sp) / Save R2 - l r2,64+0(sp) / R2 -> word to update - slr r0, r0 / R0 = current lock value must be 0 - l r1,64+4(sp) / R1 = new lock value - cs r0,r1,0(r2) / Try the update ... - be x / ... Success. Return 0 - la r0,1 / ... Failure. Return 1 - x: / - l r2,8(sp) / Restore R2 - b 2(,r14) / Return to caller - drop r15 diff --git a/storage/bdb/os/os_abs.c b/storage/bdb/os/os_abs.c deleted file mode 100644 index 1dc4dd3943c..00000000000 --- a/storage/bdb/os/os_abs.c +++ /dev/null @@ -1,29 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_abs.c,v 12.1 2005/06/16 20:23:23 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - -#include "db_int.h" - -/* - * __os_abspath -- - * Return if a path is an absolute path. - * - * PUBLIC: int __os_abspath __P((const char *)); - */ -int -__os_abspath(path) - const char *path; -{ - return (path[0] == '/'); -} diff --git a/storage/bdb/os/os_alloc.c b/storage/bdb/os/os_alloc.c deleted file mode 100644 index 858ec7738b1..00000000000 --- a/storage/bdb/os/os_alloc.c +++ /dev/null @@ -1,449 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_alloc.c,v 12.2 2005/06/16 20:23:23 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stdlib.h> -#include <string.h> -#endif - -#include "db_int.h" - -#ifdef DIAGNOSTIC -static void __os_guard __P((DB_ENV *)); - -union __db_allocinfo { - size_t size; - double align; -}; -#endif - -/* - * !!! - * Correct for systems that return NULL when you allocate 0 bytes of memory. - * There are several places in DB where we allocate the number of bytes held - * by the key/data item, and it can be 0. Correct here so that malloc never - * returns a NULL for that reason (which behavior is permitted by ANSI). We - * could make these calls macros on non-Alpha architectures (that's where we - * saw the problem), but it's probably not worth the autoconf complexity. - * - * !!! - * Correct for systems that don't set errno when malloc and friends fail. - * - * Out of memory. - * We wish to hold the whole sky, - * But we never will. - */ - -/* - * __os_umalloc -- - * A malloc(3) function that will use, in order of preference, - * the allocation function specified to the DB handle, the DB_ENV - * handle, or __os_malloc. - * - * PUBLIC: int __os_umalloc __P((DB_ENV *, size_t, void *)); - */ -int -__os_umalloc(dbenv, size, storep) - DB_ENV *dbenv; - size_t size; - void *storep; -{ - int ret; - - /* Never allocate 0 bytes -- some C libraries don't like it. */ - if (size == 0) - ++size; - - if (dbenv == NULL || dbenv->db_malloc == NULL) { - if (DB_GLOBAL(j_malloc) != NULL) - *(void **)storep = DB_GLOBAL(j_malloc)(size); - else - *(void **)storep = malloc(size); - if (*(void **)storep == NULL) { - /* - * Correct error return, see __os_malloc. - */ - if ((ret = __os_get_errno_ret_zero()) == 0) { - ret = ENOMEM; - __os_set_errno(ENOMEM); - } - __db_err(dbenv, - "malloc: %s: %lu", strerror(ret), (u_long)size); - return (ret); - } - return (0); - } - - if ((*(void **)storep = dbenv->db_malloc(size)) == NULL) { - __db_err(dbenv, "User-specified malloc function returned NULL"); - return (ENOMEM); - } - - return (0); -} - -/* - * __os_urealloc -- - * realloc(3) counterpart to __os_umalloc. - * - * PUBLIC: int __os_urealloc __P((DB_ENV *, size_t, void *)); - */ -int -__os_urealloc(dbenv, size, storep) - DB_ENV *dbenv; - size_t size; - void *storep; -{ - int ret; - void *ptr; - - ptr = *(void **)storep; - - /* Never allocate 0 bytes -- some C libraries don't like it. */ - if (size == 0) - ++size; - - if (dbenv == NULL || dbenv->db_realloc == NULL) { - if (ptr == NULL) - return (__os_umalloc(dbenv, size, storep)); - - if (DB_GLOBAL(j_realloc) != NULL) - *(void **)storep = DB_GLOBAL(j_realloc)(ptr, size); - else - *(void **)storep = realloc(ptr, size); - if (*(void **)storep == NULL) { - /* - * Correct errno, see __os_realloc. - */ - if ((ret = __os_get_errno_ret_zero()) == 0) { - ret = ENOMEM; - __os_set_errno(ENOMEM); - } - __db_err(dbenv, - "realloc: %s: %lu", strerror(ret), (u_long)size); - return (ret); - } - return (0); - } - - if ((*(void **)storep = dbenv->db_realloc(ptr, size)) == NULL) { - __db_err(dbenv, - "User-specified realloc function returned NULL"); - return (ENOMEM); - } - - return (0); -} - -/* - * __os_ufree -- - * free(3) counterpart to __os_umalloc. - * - * PUBLIC: void __os_ufree __P((DB_ENV *, void *)); - */ -void -__os_ufree(dbenv, ptr) - DB_ENV *dbenv; - void *ptr; -{ - if (dbenv != NULL && dbenv->db_free != NULL) - dbenv->db_free(ptr); - else if (DB_GLOBAL(j_free) != NULL) - DB_GLOBAL(j_free)(ptr); - else - free(ptr); -} - -/* - * __os_strdup -- - * The strdup(3) function for DB. - * - * PUBLIC: int __os_strdup __P((DB_ENV *, const char *, void *)); - */ -int -__os_strdup(dbenv, str, storep) - DB_ENV *dbenv; - const char *str; - void *storep; -{ - size_t size; - int ret; - void *p; - - *(void **)storep = NULL; - - size = strlen(str) + 1; - if ((ret = __os_malloc(dbenv, size, &p)) != 0) - return (ret); - - memcpy(p, str, size); - - *(void **)storep = p; - return (0); -} - -/* - * __os_calloc -- - * The calloc(3) function for DB. - * - * PUBLIC: int __os_calloc __P((DB_ENV *, size_t, size_t, void *)); - */ -int -__os_calloc(dbenv, num, size, storep) - DB_ENV *dbenv; - size_t num, size; - void *storep; -{ - void *p; - int ret; - - size *= num; - if ((ret = __os_malloc(dbenv, size, &p)) != 0) - return (ret); - - memset(p, 0, size); - - *(void **)storep = p; - return (0); -} - -/* - * __os_malloc -- - * The malloc(3) function for DB. - * - * PUBLIC: int __os_malloc __P((DB_ENV *, size_t, void *)); - */ -int -__os_malloc(dbenv, size, storep) - DB_ENV *dbenv; - size_t size; - void *storep; -{ - int ret; - void *p; - - *(void **)storep = NULL; - - /* Never allocate 0 bytes -- some C libraries don't like it. */ - if (size == 0) - ++size; - -#ifdef DIAGNOSTIC - /* Add room for size and a guard byte. */ - size += sizeof(union __db_allocinfo) + 1; -#endif - - if (DB_GLOBAL(j_malloc) != NULL) - p = DB_GLOBAL(j_malloc)(size); - else - p = malloc(size); - if (p == NULL) { - /* - * Some C libraries don't correctly set errno when malloc(3) - * fails. We'd like to 0 out errno before calling malloc, - * but it turns out that setting errno is quite expensive on - * Windows/NT in an MT environment. - */ - if ((ret = __os_get_errno_ret_zero()) == 0) { - ret = ENOMEM; - __os_set_errno(ENOMEM); - } - __db_err(dbenv, - "malloc: %s: %lu", strerror(ret), (u_long)size); - return (ret); - } - -#ifdef DIAGNOSTIC - /* Overwrite memory. */ - memset(p, CLEAR_BYTE, size); - - /* - * Guard bytes: if #DIAGNOSTIC is defined, we allocate an additional - * byte after the memory and set it to a special value that we check - * for when the memory is free'd. - */ - ((u_int8_t *)p)[size - 1] = CLEAR_BYTE; - - ((union __db_allocinfo *)p)->size = size; - p = &((union __db_allocinfo *)p)[1]; -#endif - *(void **)storep = p; - - return (0); -} - -/* - * __os_realloc -- - * The realloc(3) function for DB. - * - * PUBLIC: int __os_realloc __P((DB_ENV *, size_t, void *)); - */ -int -__os_realloc(dbenv, size, storep) - DB_ENV *dbenv; - size_t size; - void *storep; -{ - int ret; - void *p, *ptr; - - ptr = *(void **)storep; - - /* Never allocate 0 bytes -- some C libraries don't like it. */ - if (size == 0) - ++size; - - /* If we haven't yet allocated anything yet, simply call malloc. */ - if (ptr == NULL) - return (__os_malloc(dbenv, size, storep)); - -#ifdef DIAGNOSTIC - /* Add room for size and a guard byte. */ - size += sizeof(union __db_allocinfo) + 1; - - /* Back up to the real beginning */ - ptr = &((union __db_allocinfo *)ptr)[-1]; - - { - size_t s; - - s = ((union __db_allocinfo *)ptr)->size; - if (((u_int8_t *)ptr)[s - 1] != CLEAR_BYTE) - __os_guard(dbenv); - } -#endif - - /* - * Don't overwrite the original pointer, there are places in DB we - * try to continue after realloc fails. - */ - if (DB_GLOBAL(j_realloc) != NULL) - p = DB_GLOBAL(j_realloc)(ptr, size); - else - p = realloc(ptr, size); - if (p == NULL) { - /* - * Some C libraries don't correctly set errno when malloc(3) - * fails. We'd like to 0 out errno before calling malloc, - * but it turns out that setting errno is quite expensive on - * Windows/NT in an MT environment. - */ - if ((ret = __os_get_errno_ret_zero()) == 0) { - ret = ENOMEM; - __os_set_errno(ENOMEM); - } - __db_err(dbenv, - "realloc: %s: %lu", strerror(ret), (u_long)size); - return (ret); - } -#ifdef DIAGNOSTIC - ((u_int8_t *)p)[size - 1] = CLEAR_BYTE; /* Initialize guard byte. */ - - ((union __db_allocinfo *)p)->size = size; - p = &((union __db_allocinfo *)p)[1]; -#endif - - *(void **)storep = p; - - return (0); -} - -/* - * __os_free -- - * The free(3) function for DB. - * - * PUBLIC: void __os_free __P((DB_ENV *, void *)); - */ -void -__os_free(dbenv, ptr) - DB_ENV *dbenv; - void *ptr; -{ -#ifdef DIAGNOSTIC - size_t size; - /* - * Check that the guard byte (one past the end of the memory) is - * still CLEAR_BYTE. - */ - if (ptr == NULL) - return; - - ptr = &((union __db_allocinfo *)ptr)[-1]; - size = ((union __db_allocinfo *)ptr)->size; - if (((u_int8_t *)ptr)[size - 1] != CLEAR_BYTE) - __os_guard(dbenv); - - /* Overwrite memory. */ - if (size != 0) - memset(ptr, CLEAR_BYTE, size); -#endif - COMPQUIET(dbenv, NULL); - - if (DB_GLOBAL(j_free) != NULL) - DB_GLOBAL(j_free)(ptr); - else - free(ptr); -} - -#ifdef DIAGNOSTIC -/* - * __os_guard -- - * Complain and abort. - */ -static void -__os_guard(dbenv) - DB_ENV *dbenv; -{ - __db_err(dbenv, "Guard byte incorrect during free"); - abort(); - /* NOTREACHED */ -} -#endif - -/* - * __ua_memcpy -- - * Copy memory to memory without relying on any kind of alignment. - * - * There are places in DB that we have unaligned data, for example, - * when we've stored a structure in a log record as a DBT, and now - * we want to look at it. Unfortunately, if you have code like: - * - * struct a { - * int x; - * } *p; - * - * void *func_argument; - * int local; - * - * p = (struct a *)func_argument; - * memcpy(&local, p->x, sizeof(local)); - * - * compilers optimize to use inline instructions requiring alignment, - * and records in the log don't have any particular alignment. (This - * isn't a compiler bug, because it's a structure they're allowed to - * assume alignment.) - * - * Casting the memcpy arguments to (u_int8_t *) appears to work most - * of the time, but we've seen examples where it wasn't sufficient - * and there's nothing in ANSI C that requires that work. - * - * PUBLIC: void *__ua_memcpy __P((void *, const void *, size_t)); - */ -void * -__ua_memcpy(dst, src, len) - void *dst; - const void *src; - size_t len; -{ - return ((void *)memcpy(dst, src, len)); -} diff --git a/storage/bdb/os/os_clock.c b/storage/bdb/os/os_clock.c deleted file mode 100644 index 9fbacddd6b8..00000000000 --- a/storage/bdb/os/os_clock.c +++ /dev/null @@ -1,91 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2001-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_clock.c,v 12.1 2005/06/16 20:23:23 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#if TIME_WITH_SYS_TIME -#include <sys/time.h> -#include <time.h> -#else -#if HAVE_SYS_TIME_H -#include <sys/time.h> -#else -#include <time.h> -#endif /* HAVE_SYS_TIME_H */ -#endif /* TIME_WITH SYS_TIME */ - -#include <string.h> -#endif - -#include "db_int.h" - -/* - * __os_clock -- - * Return the current time-of-day clock in seconds and microseconds. - * - * PUBLIC: void __os_clock __P((DB_ENV *, u_int32_t *, u_int32_t *)); - */ -void -__os_clock(dbenv, secsp, usecsp) - DB_ENV *dbenv; - u_int32_t *secsp, *usecsp; /* Seconds and microseconds. */ -{ - const char *sc; - int ret; - -#if defined(HAVE_GETTIMEOFDAY) - struct timeval tp; - - RETRY_CHK((gettimeofday(&tp, NULL)), ret); - if (ret != 0) { - sc = "gettimeofday"; - goto err; - } - - if (secsp != NULL) - *secsp = (u_int32_t)tp.tv_sec; - if (usecsp != NULL) - *usecsp = (u_int32_t)tp.tv_usec; -#endif -#if !defined(HAVE_GETTIMEOFDAY) && defined(HAVE_CLOCK_GETTIME) - struct timespec tp; - - RETRY_CHK((clock_gettime(CLOCK_REALTIME, &tp)), ret); - if (ret != 0) { - sc = "clock_gettime"; - goto err; - } - - if (secsp != NULL) - *secsp = tp.tv_sec; - if (usecsp != NULL) - *usecsp = tp.tv_nsec / 1000; -#endif -#if !defined(HAVE_GETTIMEOFDAY) && !defined(HAVE_CLOCK_GETTIME) - time_t now; - - RETRY_CHK((time(&now) == (time_t)-1 ? 1 : 0), ret); - if (ret != 0) { - sc = "time"; - goto err; - } - - if (secsp != NULL) - *secsp = now; - if (usecsp != NULL) - *usecsp = 0; -#endif - return; - -err: __db_err(dbenv, "%s: %s", sc, strerror(ret)); - (void)__db_panic(dbenv, ret); -} diff --git a/storage/bdb/os/os_config.c b/storage/bdb/os/os_config.c deleted file mode 100644 index cdcb1513543..00000000000 --- a/storage/bdb/os/os_config.c +++ /dev/null @@ -1,53 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1998-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_config.c,v 12.2 2005/06/16 20:23:23 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - -#include "db_int.h" - -/* - * __os_fs_notzero -- - * Return 1 if allocated filesystem blocks are not zeroed. - * - * PUBLIC: int __os_fs_notzero __P((void)); - */ -int -__os_fs_notzero() -{ - /* Most filesystems zero out implicitly created pages. */ - return (0); -} - -/* - * __os_support_db_register -- - * Return 1 if the system supports DB_REGISTER. - * - * PUBLIC: int __os_support_db_register __P((void)); - */ -int -__os_support_db_register() -{ - return (1); -} - -/* - * __os_support_replication -- - * Return 1 if the system supports replication. - * - * PUBLIC: int __os_support_replication __P((void)); - */ -int -__os_support_replication() -{ - return (1); -} diff --git a/storage/bdb/os/os_dir.c b/storage/bdb/os/os_dir.c deleted file mode 100644 index 59fe55ca190..00000000000 --- a/storage/bdb/os/os_dir.c +++ /dev/null @@ -1,106 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_dir.c,v 12.1 2005/06/16 20:23:23 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#if HAVE_DIRENT_H -# include <dirent.h> -# define NAMLEN(dirent) strlen((dirent)->d_name) -#else -# define dirent direct -# define NAMLEN(dirent) (dirent)->d_namlen -# if HAVE_SYS_NDIR_H -# include <sys/ndir.h> -# endif -# if HAVE_SYS_DIR_H -# include <sys/dir.h> -# endif -# if HAVE_NDIR_H -# include <ndir.h> -# endif -#endif - -#endif - -#include "db_int.h" - -/* - * __os_dirlist -- - * Return a list of the files in a directory. - * - * PUBLIC: int __os_dirlist __P((DB_ENV *, const char *, char ***, int *)); - */ -int -__os_dirlist(dbenv, dir, namesp, cntp) - DB_ENV *dbenv; - const char *dir; - char ***namesp; - int *cntp; -{ - struct dirent *dp; - DIR *dirp; - int arraysz, cnt, ret; - char **names; - - if (DB_GLOBAL(j_dirlist) != NULL) - return (DB_GLOBAL(j_dirlist)(dir, namesp, cntp)); - -#ifdef HAVE_VXWORKS - if ((dirp = opendir((char *)dir)) == NULL) -#else - if ((dirp = opendir(dir)) == NULL) -#endif - return (__os_get_errno()); - names = NULL; - for (arraysz = cnt = 0; (dp = readdir(dirp)) != NULL; ++cnt) { - if (cnt >= arraysz) { - arraysz += 100; - if ((ret = __os_realloc(dbenv, - (u_int)arraysz * sizeof(names[0]), &names)) != 0) - goto nomem; - } - if ((ret = __os_strdup(dbenv, dp->d_name, &names[cnt])) != 0) - goto nomem; - } - (void)closedir(dirp); - - *namesp = names; - *cntp = cnt; - return (0); - -nomem: if (names != NULL) - __os_dirfree(dbenv, names, cnt); - if (dirp != NULL) - (void)closedir(dirp); - return (ret); -} - -/* - * __os_dirfree -- - * Free the list of files. - * - * PUBLIC: void __os_dirfree __P((DB_ENV *, char **, int)); - */ -void -__os_dirfree(dbenv, names, cnt) - DB_ENV *dbenv; - char **names; - int cnt; -{ - if (DB_GLOBAL(j_dirfree) != NULL) - DB_GLOBAL(j_dirfree)(names, cnt); - else { - while (cnt > 0) - __os_free(dbenv, names[--cnt]); - __os_free(dbenv, names); - } -} diff --git a/storage/bdb/os/os_errno.c b/storage/bdb/os/os_errno.c deleted file mode 100644 index 508a15abe1e..00000000000 --- a/storage/bdb/os/os_errno.c +++ /dev/null @@ -1,71 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_errno.c,v 12.1 2005/06/16 20:23:23 bostic Exp $ - */ - -#include "db_config.h" - -#include "db_int.h" - -/* - * __os_get_errno_ret_zero -- - * Return the value of errno, even if it's zero. - * - * PUBLIC: int __os_get_errno_ret_zero __P((void)); - */ -int -__os_get_errno_ret_zero() -{ - /* This routine must be able to return the same value repeatedly. */ - return (errno); -} - -/* - * __os_get_errno -- - * Return the value of errno, or EAGAIN if errno is zero. - * - * PUBLIC: int __os_get_errno __P((void)); - */ -int -__os_get_errno() -{ - /* - * This routine must be able to return the same value repeatedly. - * - * We've seen cases where system calls failed but errno was never set. - * This version of __os_get_errno() sets errno to EAGAIN if it's not - * already set, to work around that problem. For obvious reasons, we - * can only call this function if we know an error has occurred, that - * is, we can't test errno for a non-zero value after this call. - */ - if (errno == 0) - __os_set_errno(EAGAIN); - - return (errno); -} - -/* - * __os_set_errno -- - * Set the value of errno. - * - * PUBLIC: void __os_set_errno __P((int)); - */ -void -__os_set_errno(evalue) - int evalue; -{ - /* - * This routine is called by the compatibility interfaces (DB 1.85, - * dbm and hsearch). Force values > 0, that is, not one of DB 2.X - * and later's public error returns. If something bad has happened, - * default to EFAULT -- a nasty return. Otherwise, default to EINVAL. - * As the compatibility APIs aren't included on Windows, the Windows - * version of this routine doesn't need this behavior. - */ - errno = - evalue >= 0 ? evalue : (evalue == DB_RUNRECOVERY ? EFAULT : EINVAL); -} diff --git a/storage/bdb/os/os_fid.c b/storage/bdb/os/os_fid.c deleted file mode 100644 index 9d5633a43d7..00000000000 --- a/storage/bdb/os/os_fid.c +++ /dev/null @@ -1,135 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_fid.c,v 12.4 2005/10/14 15:33:08 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#include <sys/stat.h> - -#include <stdlib.h> -#include <string.h> -#endif - -#include "db_int.h" - -/* - * __os_fileid -- - * Return a unique identifier for a file. The structure - * of a fileid is: ino(4) dev(4) time(4) pid(4) extra(4). - * For real files, which have a backing inode and device, the first - * 16 bytes are filled in and the extra bytes are left 0. For - * temporary files, the inode and device fields are left blank and - * the extra four bytes are filled in with a random value. - * - * PUBLIC: int __os_fileid __P((DB_ENV *, const char *, int, u_int8_t *)); - */ -int -__os_fileid(dbenv, fname, unique_okay, fidp) - DB_ENV *dbenv; - const char *fname; - int unique_okay; - u_int8_t *fidp; -{ - pid_t pid; - db_threadid_t tid; - struct stat sb; - size_t i; - int ret; - u_int32_t tmp; - u_int8_t *p; - - /* Clear the buffer. */ - memset(fidp, 0, DB_FILE_ID_LEN); - - /* On POSIX/UNIX, use a dev/inode pair. */ -#ifdef HAVE_VXWORKS - RETRY_CHK((stat((char *)fname, &sb)), ret); -#else - RETRY_CHK((stat(fname, &sb)), ret); -#endif - if (ret != 0) { - __db_err(dbenv, "%s: %s", fname, strerror(ret)); - return (ret); - } - - /* - * !!! - * Nothing is ever big enough -- on Sparc V9, st_ino, st_dev and the - * time_t types are all 8 bytes. As DB_FILE_ID_LEN is only 20 bytes, - * we convert to a (potentially) smaller fixed-size type and use it. - * - * We don't worry about byte sexing or the actual variable sizes. - * - * When this routine is called from the DB access methods, it's only - * called once -- whatever ID is generated when a database is created - * is stored in the database file's metadata, and that is what is - * saved in the mpool region's information to uniquely identify the - * file. - * - * When called from the mpool layer this routine will be called each - * time a new thread of control wants to share the file, which makes - * things tougher. As far as byte sexing goes, since the mpool region - * lives on a single host, there's no issue of that -- the entire - * region is byte sex dependent. As far as variable sizes go, we make - * the simplifying assumption that 32-bit and 64-bit processes will - * get the same 32-bit values if we truncate any returned 64-bit value - * to a 32-bit value. When we're called from the mpool layer, though, - * we need to be careful not to include anything that isn't - * reproducible for a given file, such as the timestamp or serial - * number. - */ - tmp = (u_int32_t)sb.st_ino; - for (p = (u_int8_t *)&tmp, i = sizeof(u_int32_t); i > 0; --i) - *fidp++ = *p++; - - tmp = (u_int32_t)sb.st_dev; - for (p = (u_int8_t *)&tmp, i = sizeof(u_int32_t); i > 0; --i) - *fidp++ = *p++; - - if (unique_okay) { - static u_int32_t fid_serial = 0; - - /* Add in 32-bits of (hopefully) unique number. */ - __os_unique_id(dbenv, &tmp); - for (p = (u_int8_t *)&tmp, i = sizeof(u_int32_t); i > 0; --i) - *fidp++ = *p++; - - /* - * Initialize/increment the serial number we use to help - * avoid fileid collisions. Note we don't bother with - * locking; it's unpleasant to do from down in here, and - * if we race on this no real harm will be done, since the - * finished fileid has so many other components. - * - * We use the bottom 32-bits of the process ID, hoping they - * are more random than the top 32-bits (should we be on a - * machine with 64-bit process IDs). - * - * We increment by 100000 on each call as a simple way of - * randomizing; simply incrementing seems potentially less - * useful if pids are also simply incremented, since this - * is process-local and we may be one of a set of processes - * starting up. 100000 pushes us out of pid space on most - * 32-bit platforms, and has few interesting properties in - * base 2. - */ - if (fid_serial == 0) { - dbenv->thread_id(dbenv, &pid, &tid); - fid_serial = (u_int32_t)pid; - } else - fid_serial += 100000; - - for (p = - (u_int8_t *)&fid_serial, i = sizeof(u_int32_t); i > 0; --i) - *fidp++ = *p++; - } - - return (0); -} diff --git a/storage/bdb/os/os_flock.c b/storage/bdb/os/os_flock.c deleted file mode 100644 index 419407a5b23..00000000000 --- a/storage/bdb/os/os_flock.c +++ /dev/null @@ -1,56 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_flock.c,v 12.4 2005/06/20 14:59:01 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <fcntl.h> -#include <string.h> -#endif - -#include "db_int.h" - -/* - * __os_fdlock -- - * Acquire/release a lock on a byte in a file. - * - * PUBLIC: int __os_fdlock __P((DB_ENV *, DB_FH *, off_t, int, int)); - */ -int -__os_fdlock(dbenv, fhp, offset, acquire, nowait) - DB_ENV *dbenv; - DB_FH *fhp; - int acquire, nowait; - off_t offset; -{ - struct flock fl; - int ret; - - DB_ASSERT(F_ISSET(fhp, DB_FH_OPENED) && fhp->fd != -1); - -#ifdef HAVE_FCNTL - fl.l_start = offset; - fl.l_len = 1; - fl.l_type = acquire ? F_WRLCK : F_UNLCK; - fl.l_whence = SEEK_SET; - - RETRY_CHK_EINTR_ONLY( - (fcntl(fhp->fd, nowait ? F_SETLK : F_SETLKW, &fl)), ret); - - if (ret != 0 && ret != EACCES && ret != EAGAIN) - __db_err(dbenv, "fcntl: %s", strerror(ret)); - return (ret); -#else - __db_err(dbenv, - "advisory file locking unavailable: %s", strerror(DB_OPNOTSUP)); - return (DB_OPNOTSUP); -#endif -} diff --git a/storage/bdb/os/os_fsync.c b/storage/bdb/os/os_fsync.c deleted file mode 100644 index 81d94ddc0e0..00000000000 --- a/storage/bdb/os/os_fsync.c +++ /dev/null @@ -1,95 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_fsync.c,v 12.3 2005/09/07 17:30:20 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <fcntl.h> /* Required on some platforms. */ -#include <string.h> -#endif - -#include "db_int.h" - -#ifdef HAVE_VXWORKS -#include "ioLib.h" - -#define fsync(fd) __vx_fsync(fd) - -int -__vx_fsync(fd) - int fd; -{ - int ret; - - /* - * The results of ioctl are driver dependent. Some will return the - * number of bytes sync'ed. Only if it returns 'ERROR' should we - * flag it. - */ - if ((ret = ioctl(fd, FIOSYNC, 0)) != ERROR) - return (0); - return (ret); -} -#endif - -#ifdef __hp3000s900 -#define fsync(fd) __mpe_fsync(fd) - -int -__mpe_fsync(fd) - int fd; -{ - extern FCONTROL(short, short, void *); - - FCONTROL(_MPE_FILENO(fd), 2, NULL); /* Flush the buffers */ - FCONTROL(_MPE_FILENO(fd), 6, NULL); /* Write the EOF */ - return (0); -} -#endif - -/* - * __os_fsync -- - * Flush a file descriptor. - * - * PUBLIC: int __os_fsync __P((DB_ENV *, DB_FH *)); - */ -int -__os_fsync(dbenv, fhp) - DB_ENV *dbenv; - DB_FH *fhp; -{ - int ret; - - /* Check for illegal usage. */ - DB_ASSERT(F_ISSET(fhp, DB_FH_OPENED) && fhp->fd != -1); - - /* - * Do nothing if the file descriptor has been marked as not requiring - * any sync to disk. - */ - if (F_ISSET(fhp, DB_FH_NOSYNC)) - return (0); - - if (DB_GLOBAL(j_fsync) != NULL) - ret = DB_GLOBAL(j_fsync)(fhp->fd); - else -#if defined(F_FULLFSYNC) - RETRY_CHK((fcntl(fhp->fd, F_FULLFSYNC, 0)), ret); -#elif defined(HAVE_FDATASYNC) - RETRY_CHK((fdatasync(fhp->fd)), ret); -#else - RETRY_CHK((fsync(fhp->fd)), ret); -#endif - - if (ret != 0) - __db_err(dbenv, "fsync %s", strerror(ret)); - return (ret); -} diff --git a/storage/bdb/os/os_handle.c b/storage/bdb/os/os_handle.c deleted file mode 100644 index 2a87094e1c6..00000000000 --- a/storage/bdb/os/os_handle.c +++ /dev/null @@ -1,208 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1998-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_handle.c,v 12.2 2005/08/10 15:47:25 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <fcntl.h> -#include <string.h> -#endif - -#include "db_int.h" - -/* - * __os_openhandle -- - * Open a file, using POSIX 1003.1 open flags. - * - * PUBLIC: int __os_openhandle - * PUBLIC: __P((DB_ENV *, const char *, int, int, DB_FH **)); - */ -int -__os_openhandle(dbenv, name, flags, mode, fhpp) - DB_ENV *dbenv; - const char *name; - int flags, mode; - DB_FH **fhpp; -{ - DB_FH *fhp; - u_int nrepeat, retries; - int ret; -#ifdef HAVE_VXWORKS - int newflags; -#endif - - if ((ret = __os_calloc(dbenv, 1, sizeof(DB_FH), fhpp)) != 0) - return (ret); - fhp = *fhpp; - - /* If the application specified an interface, use it. */ - if (DB_GLOBAL(j_open) != NULL) { - if ((fhp->fd = DB_GLOBAL(j_open)(name, flags, mode)) == -1) { - ret = __os_get_errno(); - goto err; - } - F_SET(fhp, DB_FH_OPENED); - return (0); - } - - retries = 0; - for (nrepeat = 1; nrepeat < 4; ++nrepeat) { - ret = 0; -#ifdef HAVE_VXWORKS - /* - * VxWorks does not support O_CREAT on open, you have to use - * creat() instead. (It does not support O_EXCL or O_TRUNC - * either, even though they are defined "for future support".) - * We really want the POSIX behavior that if O_CREAT is set, - * we open if it exists, or create it if it doesn't exist. - * If O_CREAT is specified, single thread and try to open the - * file. If successful, and O_EXCL return EEXIST. If - * unsuccessful call creat and then end single threading. - */ - if (LF_ISSET(O_CREAT)) { - DB_BEGIN_SINGLE_THREAD; - newflags = flags & ~(O_CREAT | O_EXCL); - if ((fhp->fd = open(name, newflags, mode)) != -1) { - /* - * We need to mark the file opened at this - * point so that if we get any error below - * we will properly close the fd we just - * opened on the error path. - */ - F_SET(fhp, DB_FH_OPENED); - if (LF_ISSET(O_EXCL)) { - /* - * If we get here, want O_EXCL create, - * and the file exists. Close and - * return EEXISTS. - */ - DB_END_SINGLE_THREAD; - ret = EEXIST; - goto err; - } - /* - * XXX - * Assume any error means non-existence. - * Unfortunately return values (even for - * non-existence) are driver specific so - * there is no single error we can use to - * verify we truly got the equivalent of - * ENOENT. - */ - } else - fhp->fd = creat(name, newflags); - DB_END_SINGLE_THREAD; - } else - /* FALLTHROUGH */ -#endif -#ifdef __VMS - /* - * !!! - * Open with full sharing on VMS. - * - * We use these flags because they are the ones set by the VMS - * CRTL mmap() call when it opens a file, and we have to be - * able to open files that mmap() has previously opened, e.g., - * when we're joining already existing DB regions. - */ - fhp->fd = open(name, flags, mode, "shr=get,put,upd,del,upi"); -#else - fhp->fd = open(name, flags, mode); -#endif - if (fhp->fd != -1) { - F_SET(fhp, DB_FH_OPENED); - -#if defined(HAVE_FCNTL_F_SETFD) - /* Deny file descriptor access to any child process. */ - if (fcntl(fhp->fd, F_SETFD, 1) == -1) { - ret = __os_get_errno(); - __db_err(dbenv, - "fcntl(F_SETFD): %s", strerror(ret)); - goto err; - } -#endif - break; - } - - switch (ret = __os_get_errno()) { - case EMFILE: - case ENFILE: - case ENOSPC: - /* - * If it's a "temporary" error, we retry up to 3 times, - * waiting up to 12 seconds. While it's not a problem - * if we can't open a database, an inability to open a - * log file is cause for serious dismay. - */ - __os_sleep(dbenv, nrepeat * 2, 0); - break; - case EAGAIN: - case EBUSY: - case EINTR: - /* - * If an EAGAIN, EBUSY or EINTR, retry immediately for - * DB_RETRY times. - */ - if (++retries < DB_RETRY) - --nrepeat; - break; - default: - break; - } - } - -err: if (ret != 0) { - (void)__os_closehandle(dbenv, fhp); - *fhpp = NULL; - } - - return (ret); -} - -/* - * __os_closehandle -- - * Close a file. - * - * PUBLIC: int __os_closehandle __P((DB_ENV *, DB_FH *)); - */ -int -__os_closehandle(dbenv, fhp) - DB_ENV *dbenv; - DB_FH *fhp; -{ - int ret; - - ret = 0; - - /* - * If we have a valid handle, close it and unlink any temporary - * file. - */ - if (F_ISSET(fhp, DB_FH_OPENED)) { - if (DB_GLOBAL(j_close) != NULL) - ret = DB_GLOBAL(j_close)(fhp->fd); - else - RETRY_CHK((close(fhp->fd)), ret); - - if (ret != 0) - __db_err(dbenv, "close: %s", strerror(ret)); - - /* Unlink the file if we haven't already done so. */ - if (F_ISSET(fhp, DB_FH_UNLINK)) { - (void)__os_unlink(dbenv, fhp->name); - __os_free(dbenv, fhp->name); - } - } - - __os_free(dbenv, fhp); - - return (ret); -} diff --git a/storage/bdb/os/os_id.c b/storage/bdb/os/os_id.c deleted file mode 100644 index d53b18806a2..00000000000 --- a/storage/bdb/os/os_id.c +++ /dev/null @@ -1,113 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2001-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_id.c,v 12.15 2005/11/10 18:44:02 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stdlib.h> -#endif - -#include "db_int.h" -#include "dbinc/mutex_int.h" /* Required to load appropriate - header files for thread functions. */ - -/* - * __os_id -- - * Return the current process ID. - * - * PUBLIC: void __os_id __P((DB_ENV *, pid_t *, db_threadid_t*)); - */ -void -__os_id(dbenv, pidp, tidp) - DB_ENV *dbenv; - pid_t *pidp; - db_threadid_t *tidp; -{ - /* - * We can't depend on dbenv not being NULL, this routine is called - * from places where there's no DB_ENV handle. It takes a DB_ENV - * handle as an arg because it's the default DB_ENV->thread_id function. - * - * We cache the pid in the DB_ENV handle, it's a fairly slow call on - * lots of systems. - */ - if (pidp != NULL) { - if (dbenv == NULL) { -#if defined(HAVE_VXWORKS) - *pidp = taskIdSelf(); -#else - *pidp = getpid(); -#endif - } else - *pidp = dbenv->pid_cache; - } - - if (tidp != NULL) { -#if defined(DB_WIN32) - *tidp = GetCurrentThreadId(); -#elif defined(HAVE_MUTEX_UI_THREADS) - *tidp = thr_self(); -#elif defined(HAVE_MUTEX_SOLARIS_LWP) || \ - defined(HAVE_MUTEX_PTHREADS) || defined(HAVE_PTHREAD_SELF) - *tidp = pthread_self(); -#else - /* - * Default to just getpid. - */ - *tidp = 0; -#endif - } -} - -/* - * __os_unique_id -- - * Return a unique 32-bit value. - * - * PUBLIC: void __os_unique_id __P((DB_ENV *, u_int32_t *)); - */ -void -__os_unique_id(dbenv, idp) - DB_ENV *dbenv; - u_int32_t *idp; -{ - static int first = 1; - pid_t pid; - db_threadid_t tid; - u_int32_t id, sec, usec; - - *idp = 0; - - /* - * Our randomized value is comprised of our process ID, the current - * time of day and a couple of a stack addresses, all XOR'd together. - */ - __os_id(dbenv, &pid, &tid); - __os_clock(dbenv, &sec, &usec); - - id = (u_int32_t)pid ^ sec ^ usec ^ P_TO_UINT32(&pid); - - /* - * We could try and find a reasonable random-number generator, but - * that's not all that easy to do. Seed and use srand()/rand(), if - * we can find them. - */ -#if HAVE_SRAND - if (first == 1) - srand((u_int)id); -#endif - first = 0; - -#if HAVE_RAND - id ^= (u_int)rand(); -#endif - - *idp = id; -} diff --git a/storage/bdb/os/os_map.c b/storage/bdb/os/os_map.c deleted file mode 100644 index d0db7073ec9..00000000000 --- a/storage/bdb/os/os_map.c +++ /dev/null @@ -1,463 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_map.c,v 12.3 2005/07/21 01:36:18 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#ifdef HAVE_MMAP -#include <sys/mman.h> -#endif - -#ifdef HAVE_SHMGET -#include <sys/ipc.h> -#include <sys/shm.h> -#endif - -#include <string.h> -#endif - -#include "db_int.h" - -#ifdef HAVE_MMAP -static int __os_map __P((DB_ENV *, char *, DB_FH *, size_t, int, int, void **)); -#endif -#ifndef HAVE_SHMGET -static int __db_nosystemmem __P((DB_ENV *)); -#endif - -/* - * __os_r_sysattach -- - * Create/join a shared memory region. - * - * PUBLIC: int __os_r_sysattach __P((DB_ENV *, REGINFO *, REGION *)); - */ -int -__os_r_sysattach(dbenv, infop, rp) - DB_ENV *dbenv; - REGINFO *infop; - REGION *rp; -{ - if (F_ISSET(dbenv, DB_ENV_SYSTEM_MEM)) { - /* - * If the region is in system memory on UNIX, we use shmget(2). - * - * !!! - * There exist spinlocks that don't work in shmget memory, e.g., - * the HP/UX msemaphore interface. If we don't have locks that - * will work in shmget memory, we better be private and not be - * threaded. If we reach this point, we know we're public, so - * it's an error. - */ -#if defined(HAVE_MUTEX_HPPA_MSEM_INIT) - __db_err(dbenv, - "architecture does not support locks inside system shared memory"); - return (EINVAL); -#endif -#if defined(HAVE_SHMGET) - { - key_t segid; - int id, mode, ret; - - /* - * We could potentially create based on REGION_CREATE_OK, but - * that's dangerous -- we might get crammed in sideways if - * some of the expected regions exist but others do not. Also, - * if the requested size differs from an existing region's - * actual size, then all sorts of nasty things can happen. - * Basing create solely on REGION_CREATE is much safer -- a - * recovery will get us straightened out. - */ - if (F_ISSET(infop, REGION_CREATE)) { - /* - * The application must give us a base System V IPC key - * value. Adjust that value based on the region's ID, - * and correct so the user's original value appears in - * the ipcs output. - */ - if (dbenv->shm_key == INVALID_REGION_SEGID) { - __db_err(dbenv, - "no base system shared memory ID specified"); - return (EINVAL); - } - segid = (key_t)(dbenv->shm_key + (infop->id - 1)); - - /* - * If map to an existing region, assume the application - * crashed and we're restarting. Delete the old region - * and re-try. If that fails, return an error, the - * application will have to select a different segment - * ID or clean up some other way. - */ - if ((id = shmget(segid, 0, 0)) != -1) { - (void)shmctl(id, IPC_RMID, NULL); - if ((id = shmget(segid, 0, 0)) != -1) { - __db_err(dbenv, - "shmget: key: %ld: shared system memory region already exists", - (long)segid); - return (EAGAIN); - } - } - - /* - * Map the DbEnv::open method file mode permissions to - * shmget call permissions. - */ - mode = IPC_CREAT | __db_shm_mode(dbenv); - if ((id = shmget(segid, rp->size, mode)) == -1) { - ret = __os_get_errno(); - __db_err(dbenv, - "shmget: key: %ld: unable to create shared system memory region: %s", - (long)segid, strerror(ret)); - return (ret); - } - rp->segid = id; - } else - id = rp->segid; - - if ((infop->addr = shmat(id, NULL, 0)) == (void *)-1) { - infop->addr = NULL; - ret = __os_get_errno(); - __db_err(dbenv, - "shmat: id %d: unable to attach to shared system memory region: %s", - id, strerror(ret)); - return (ret); - } - - return (0); - } -#else - return (__db_nosystemmem(dbenv)); -#endif - } - -#ifdef HAVE_MMAP - { - DB_FH *fhp; - int ret; - - fhp = NULL; - - /* - * Try to open/create the shared region file. We DO NOT need to ensure - * that multiple threads/processes attempting to simultaneously create - * the region are properly ordered, our caller has already taken care - * of that. - */ - if ((ret = __os_open(dbenv, infop->name, - DB_OSO_REGION | - (F_ISSET(infop, REGION_CREATE_OK) ? DB_OSO_CREATE : 0), - dbenv->db_mode, &fhp)) != 0) - __db_err(dbenv, "%s: %s", infop->name, db_strerror(ret)); - - /* - * If we created the file, grow it to its full size before mapping - * it in. We really want to avoid touching the buffer cache after - * mmap(2) is called, doing anything else confuses the hell out of - * systems without merged VM/buffer cache systems, or, more to the - * point, *badly* merged VM/buffer cache systems. - */ - if (ret == 0 && F_ISSET(infop, REGION_CREATE)) { - if (F_ISSET(dbenv, DB_ENV_REGION_INIT)) - ret = __db_file_write(dbenv, "region file", fhp, - rp->size / MEGABYTE, rp->size % MEGABYTE, 0x00); - else - ret = __db_file_extend(dbenv, fhp, rp->size); - } - - /* Map the file in. */ - if (ret == 0) - ret = __os_map(dbenv, - infop->name, fhp, rp->size, 1, 0, &infop->addr); - - if (fhp != NULL) - (void)__os_closehandle(dbenv, fhp); - - return (ret); - } -#else - COMPQUIET(infop, NULL); - COMPQUIET(rp, NULL); - __db_err(dbenv, - "architecture lacks mmap(2), shared environments not possible"); - return (DB_OPNOTSUP); -#endif -} - -/* - * __os_r_sysdetach -- - * Detach from a shared memory region. - * - * PUBLIC: int __os_r_sysdetach __P((DB_ENV *, REGINFO *, int)); - */ -int -__os_r_sysdetach(dbenv, infop, destroy) - DB_ENV *dbenv; - REGINFO *infop; - int destroy; -{ - REGION *rp; - - rp = infop->rp; - - if (F_ISSET(dbenv, DB_ENV_SYSTEM_MEM)) { -#ifdef HAVE_SHMGET - int ret, segid; - - /* - * We may be about to remove the memory referenced by rp, - * save the segment ID, and (optionally) wipe the original. - */ - segid = rp->segid; - if (destroy) - rp->segid = INVALID_REGION_SEGID; - - if (shmdt(infop->addr) != 0) { - ret = __os_get_errno(); - __db_err(dbenv, "shmdt: %s", strerror(ret)); - return (ret); - } - - if (destroy && shmctl(segid, IPC_RMID, - NULL) != 0 && (ret = __os_get_errno()) != EINVAL) { - __db_err(dbenv, - "shmctl: id %d: unable to delete system shared memory region: %s", - segid, strerror(ret)); - return (ret); - } - - return (0); -#else - return (__db_nosystemmem(dbenv)); -#endif - } - -#ifdef HAVE_MMAP -#ifdef HAVE_MUNLOCK - if (F_ISSET(dbenv, DB_ENV_LOCKDOWN)) - (void)munlock(infop->addr, rp->size); -#endif - if (munmap(infop->addr, rp->size) != 0) { - int ret; - - ret = __os_get_errno(); - __db_err(dbenv, "munmap: %s", strerror(ret)); - return (ret); - } - - if (destroy && __os_region_unlink(dbenv, infop->name) != 0) - return (__os_get_errno()); - - return (0); -#else - COMPQUIET(destroy, 0); - return (EINVAL); -#endif -} - -/* - * __os_mapfile -- - * Map in a shared memory file. - * - * PUBLIC: int __os_mapfile __P((DB_ENV *, - * PUBLIC: char *, DB_FH *, size_t, int, void **)); - */ -int -__os_mapfile(dbenv, path, fhp, len, is_rdonly, addrp) - DB_ENV *dbenv; - char *path; - DB_FH *fhp; - int is_rdonly; - size_t len; - void **addrp; -{ -#if defined(HAVE_MMAP) && !defined(HAVE_QNX) - return (__os_map(dbenv, path, fhp, len, 0, is_rdonly, addrp)); -#else - COMPQUIET(dbenv, NULL); - COMPQUIET(path, NULL); - COMPQUIET(fhp, NULL); - COMPQUIET(is_rdonly, 0); - COMPQUIET(len, 0); - COMPQUIET(addrp, NULL); - return (EINVAL); -#endif -} - -/* - * __os_unmapfile -- - * Unmap the shared memory file. - * - * PUBLIC: int __os_unmapfile __P((DB_ENV *, void *, size_t)); - */ -int -__os_unmapfile(dbenv, addr, len) - DB_ENV *dbenv; - void *addr; - size_t len; -{ - int ret; - - /* If the user replaced the map call, call through their interface. */ - if (DB_GLOBAL(j_unmap) != NULL) - return (DB_GLOBAL(j_unmap)(addr, len)); - -#ifdef HAVE_MMAP -#ifdef HAVE_MUNLOCK - if (F_ISSET(dbenv, DB_ENV_LOCKDOWN)) - RETRY_CHK((munlock(addr, len)), ret); -#else - COMPQUIET(dbenv, NULL); -#endif - RETRY_CHK((munmap(addr, len)), ret); - return (ret); -#else - COMPQUIET(dbenv, NULL); - - return (EINVAL); -#endif -} - -#ifdef HAVE_MMAP -/* - * __os_map -- - * Call the mmap(2) function. - */ -static int -__os_map(dbenv, path, fhp, len, is_region, is_rdonly, addrp) - DB_ENV *dbenv; - char *path; - DB_FH *fhp; - int is_region, is_rdonly; - size_t len; - void **addrp; -{ - void *p; - int flags, prot, ret; - - /* If the user replaced the map call, call through their interface. */ - if (DB_GLOBAL(j_map) != NULL) - return (DB_GLOBAL(j_map) - (path, len, is_region, is_rdonly, addrp)); - - /* Check for illegal usage. */ - DB_ASSERT(F_ISSET(fhp, DB_FH_OPENED) && fhp->fd != -1); - - /* - * If it's read-only, it's private, and if it's not, it's shared. - * Don't bother with an additional parameter. - */ - flags = is_rdonly ? MAP_PRIVATE : MAP_SHARED; - -#ifdef MAP_FILE - /* - * Historically, MAP_FILE was required for mapping regular files, - * even though it was the default. Some systems have it, some - * don't, some that have it set it to 0. - */ - flags |= MAP_FILE; -#endif - - /* - * I know of no systems that implement the flag to tell the system - * that the region contains semaphores, but it's not an unreasonable - * thing to do, and has been part of the design since forever. I - * don't think anyone will object, but don't set it for read-only - * files, it doesn't make sense. - */ -#ifdef MAP_HASSEMAPHORE - if (is_region && !is_rdonly) - flags |= MAP_HASSEMAPHORE; -#else - COMPQUIET(is_region, 0); -#endif - - /* - * FreeBSD: - * Causes data dirtied via this VM map to be flushed to physical media - * only when necessary (usually by the pager) rather then gratuitously. - * Typically this prevents the update daemons from flushing pages - * dirtied through such maps and thus allows efficient sharing of - * memory across unassociated processes using a file-backed shared - * memory map. - */ -#ifdef MAP_NOSYNC - flags |= MAP_NOSYNC; -#endif - - prot = PROT_READ | (is_rdonly ? 0 : PROT_WRITE); - - /* - * XXX - * Work around a bug in the VMS V7.1 mmap() implementation. To map - * a file into memory on VMS it needs to be opened in a certain way, - * originally. To get the file opened in that certain way, the VMS - * mmap() closes the file and re-opens it. When it does this, it - * doesn't flush any caches out to disk before closing. The problem - * this causes us is that when the memory cache doesn't get written - * out, the file isn't big enough to match the memory chunk and the - * mmap() call fails. This call to fsync() fixes the problem. DEC - * thinks this isn't a bug because of language in XPG5 discussing user - * responsibility for on-disk and in-memory synchronization. - */ -#ifdef VMS - if (__os_fsync(dbenv, fhp) == -1) - return (__os_get_errno()); -#endif - - /* MAP_FAILED was not defined in early mmap implementations. */ -#ifndef MAP_FAILED -#define MAP_FAILED -1 -#endif - if ((p = mmap(NULL, - len, prot, flags, fhp->fd, (off_t)0)) == (void *)MAP_FAILED) { - ret = __os_get_errno(); - __db_err(dbenv, "mmap: %s", strerror(ret)); - return (ret); - } - -#ifdef HAVE_MLOCK - /* - * If it's a region, we want to make sure that the memory isn't paged. - * For example, Solaris will page large mpools because it thinks that - * I/O buffer memory is more important than we are. The mlock system - * call may or may not succeed (mlock is restricted to the super-user - * on some systems). Currently, the only other use of mmap in DB is - * to map read-only databases -- we don't want them paged, either, so - * the call isn't conditional. - */ - if (F_ISSET(dbenv, DB_ENV_LOCKDOWN) && mlock(p, len) != 0) { - ret = __os_get_errno(); - (void)munmap(p, len); - __db_err(dbenv, "mlock: %s", strerror(ret)); - return (ret); - } -#else - COMPQUIET(dbenv, NULL); -#endif - - *addrp = p; - return (0); -} -#endif - -#ifndef HAVE_SHMGET -/* - * __db_nosystemmem -- - * No system memory environments error message. - */ -static int -__db_nosystemmem(dbenv) - DB_ENV *dbenv; -{ - __db_err(dbenv, - "architecture doesn't support environments in system memory"); - return (DB_OPNOTSUP); -} -#endif diff --git a/storage/bdb/os/os_method.c b/storage/bdb/os/os_method.c deleted file mode 100644 index c304f881547..00000000000 --- a/storage/bdb/os/os_method.c +++ /dev/null @@ -1,267 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_method.c,v 12.1 2005/06/16 20:23:26 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - -#include "db_int.h" - -/* - * EXTERN: int db_env_set_func_close __P((int (*)(int))); - */ -int -db_env_set_func_close(func_close) - int (*func_close) __P((int)); -{ - DB_GLOBAL(j_close) = func_close; - return (0); -} - -/* - * EXTERN: int db_env_set_func_dirfree __P((void (*)(char **, int))); - */ -int -db_env_set_func_dirfree(func_dirfree) - void (*func_dirfree) __P((char **, int)); -{ - DB_GLOBAL(j_dirfree) = func_dirfree; - return (0); -} - -/* - * EXTERN: int db_env_set_func_dirlist - * EXTERN: __P((int (*)(const char *, char ***, int *))); - */ -int -db_env_set_func_dirlist(func_dirlist) - int (*func_dirlist) __P((const char *, char ***, int *)); -{ - DB_GLOBAL(j_dirlist) = func_dirlist; - return (0); -} - -/* - * EXTERN: int db_env_set_func_exists __P((int (*)(const char *, int *))); - */ -int -db_env_set_func_exists(func_exists) - int (*func_exists) __P((const char *, int *)); -{ - DB_GLOBAL(j_exists) = func_exists; - return (0); -} - -/* - * EXTERN: int db_env_set_func_free __P((void (*)(void *))); - */ -int -db_env_set_func_free(func_free) - void (*func_free) __P((void *)); -{ - DB_GLOBAL(j_free) = func_free; - return (0); -} - -/* - * EXTERN: int db_env_set_func_fsync __P((int (*)(int))); - */ -int -db_env_set_func_fsync(func_fsync) - int (*func_fsync) __P((int)); -{ - DB_GLOBAL(j_fsync) = func_fsync; - return (0); -} - -/* - * EXTERN: int db_env_set_func_ftruncate __P((int (*)(int, off_t))); - */ -int -db_env_set_func_ftruncate(func_ftruncate) - int (*func_ftruncate) __P((int, off_t)); -{ - DB_GLOBAL(j_ftruncate) = func_ftruncate; - return (0); -} - -/* - * EXTERN: int db_env_set_func_ioinfo __P((int (*)(const char *, - * EXTERN: int, u_int32_t *, u_int32_t *, u_int32_t *))); - */ -int -db_env_set_func_ioinfo(func_ioinfo) - int (*func_ioinfo) - __P((const char *, int, u_int32_t *, u_int32_t *, u_int32_t *)); -{ - DB_GLOBAL(j_ioinfo) = func_ioinfo; - return (0); -} - -/* - * EXTERN: int db_env_set_func_malloc __P((void *(*)(size_t))); - */ -int -db_env_set_func_malloc(func_malloc) - void *(*func_malloc) __P((size_t)); -{ - DB_GLOBAL(j_malloc) = func_malloc; - return (0); -} - -/* - * EXTERN: int db_env_set_func_map - * EXTERN: __P((int (*)(char *, size_t, int, int, void **))); - */ -int -db_env_set_func_map(func_map) - int (*func_map) __P((char *, size_t, int, int, void **)); -{ - DB_GLOBAL(j_map) = func_map; - return (0); -} - -/* - * EXTERN: int db_env_set_func_pread - * EXTERN: __P((ssize_t (*)(int, void *, size_t, off_t))); - */ -int -db_env_set_func_pread(func_pread) - ssize_t (*func_pread) __P((int, void *, size_t, off_t)); -{ - DB_GLOBAL(j_pread) = func_pread; - return (0); -} - -/* - * EXTERN: int db_env_set_func_pwrite - * EXTERN: __P((ssize_t (*)(int, const void *, size_t, off_t))); - */ -int -db_env_set_func_pwrite(func_pwrite) - ssize_t (*func_pwrite) __P((int, const void *, size_t, off_t)); -{ - DB_GLOBAL(j_pwrite) = func_pwrite; - return (0); -} - -/* - * EXTERN: int db_env_set_func_open __P((int (*)(const char *, int, ...))); - */ -int -db_env_set_func_open(func_open) - int (*func_open) __P((const char *, int, ...)); -{ - DB_GLOBAL(j_open) = func_open; - return (0); -} - -/* - * EXTERN: int db_env_set_func_read __P((ssize_t (*)(int, void *, size_t))); - */ -int -db_env_set_func_read(func_read) - ssize_t (*func_read) __P((int, void *, size_t)); -{ - DB_GLOBAL(j_read) = func_read; - return (0); -} - -/* - * EXTERN: int db_env_set_func_realloc __P((void *(*)(void *, size_t))); - */ -int -db_env_set_func_realloc(func_realloc) - void *(*func_realloc) __P((void *, size_t)); -{ - DB_GLOBAL(j_realloc) = func_realloc; - return (0); -} - -/* - * EXTERN: int db_env_set_func_rename - * EXTERN: __P((int (*)(const char *, const char *))); - */ -int -db_env_set_func_rename(func_rename) - int (*func_rename) __P((const char *, const char *)); -{ - DB_GLOBAL(j_rename) = func_rename; - return (0); -} - -/* - * EXTERN: int db_env_set_func_seek - * EXTERN: __P((int (*)(int, off_t, int))); - */ -int -db_env_set_func_seek(func_seek) - int (*func_seek) __P((int, off_t, int)); -{ - DB_GLOBAL(j_seek) = func_seek; - return (0); -} - -/* - * EXTERN: int db_env_set_func_sleep __P((int (*)(u_long, u_long))); - */ -int -db_env_set_func_sleep(func_sleep) - int (*func_sleep) __P((u_long, u_long)); -{ - DB_GLOBAL(j_sleep) = func_sleep; - return (0); -} - -/* - * EXTERN: int db_env_set_func_unlink __P((int (*)(const char *))); - */ -int -db_env_set_func_unlink(func_unlink) - int (*func_unlink) __P((const char *)); -{ - DB_GLOBAL(j_unlink) = func_unlink; - return (0); -} - -/* - * EXTERN: int db_env_set_func_unmap __P((int (*)(void *, size_t))); - */ -int -db_env_set_func_unmap(func_unmap) - int (*func_unmap) __P((void *, size_t)); -{ - DB_GLOBAL(j_unmap) = func_unmap; - return (0); -} - -/* - * EXTERN: int db_env_set_func_write - * EXTERN: __P((ssize_t (*)(int, const void *, size_t))); - */ -int -db_env_set_func_write(func_write) - ssize_t (*func_write) __P((int, const void *, size_t)); -{ - DB_GLOBAL(j_write) = func_write; - return (0); -} - -/* - * EXTERN: int db_env_set_func_yield __P((int (*)(void))); - */ -int -db_env_set_func_yield(func_yield) - int (*func_yield) __P((void)); -{ - DB_GLOBAL(j_yield) = func_yield; - return (0); -} diff --git a/storage/bdb/os/os_mkdir.c b/storage/bdb/os/os_mkdir.c deleted file mode 100644 index 4c8c8e6380d..00000000000 --- a/storage/bdb/os/os_mkdir.c +++ /dev/null @@ -1,54 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_mkdir.c,v 12.8 2005/11/02 03:12:17 mjc Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#include <sys/stat.h> -#endif - -#include "db_int.h" - -/* - * __os_mkdir -- - * Create a directory. - * - * PUBLIC: int __os_mkdir __P((DB_ENV *, const char *, int)); - */ -int -__os_mkdir(dbenv, name, mode) - DB_ENV *dbenv; - const char *name; - int mode; -{ - int ret; - - COMPQUIET(dbenv, NULL); - - /* Make the directory, with paranoid permissions. */ -#ifdef HAVE_VXWORKS - RETRY_CHK((mkdir((char *)name)), ret); -#else -#ifdef DB_WIN32 - RETRY_CHK((_mkdir(name)), ret); -#else - RETRY_CHK((mkdir(name, 0600)), ret); -#endif - if (ret != 0) - return (ret); - - /* Set the absolute permissions, if specified. */ -#ifndef DB_WIN32 - if (mode != 0) - RETRY_CHK((chmod(name, mode)), ret); -#endif -#endif - return (ret); -} diff --git a/storage/bdb/os/os_oflags.c b/storage/bdb/os/os_oflags.c deleted file mode 100644 index 27f72c8b95b..00000000000 --- a/storage/bdb/os/os_oflags.c +++ /dev/null @@ -1,198 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_oflags.c,v 12.2 2005/06/16 20:23:26 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#include <sys/stat.h> - -#ifdef HAVE_SHMGET -#include <sys/ipc.h> -#include <sys/shm.h> -#endif - -#include <fcntl.h> -#endif - -#include "db_int.h" - -/* - * __db_oflags -- - * Convert open(2) flags to DB flags. - * - * PUBLIC: u_int32_t __db_oflags __P((int)); - */ -u_int32_t -__db_oflags(oflags) - int oflags; -{ - u_int32_t dbflags; - - dbflags = 0; - - if (oflags & O_CREAT) - dbflags |= DB_CREATE; - - if (oflags & O_TRUNC) - dbflags |= DB_TRUNCATE; - - /* - * !!! - * Convert POSIX 1003.1 open(2) mode flags to DB flags. This isn't - * an exact science as few POSIX implementations have a flag value - * for O_RDONLY, it's simply the lack of a write flag. - */ -#ifndef O_ACCMODE -#define O_ACCMODE (O_RDONLY | O_RDWR | O_WRONLY) -#endif - switch (oflags & O_ACCMODE) { - case O_RDWR: - case O_WRONLY: - break; - default: - dbflags |= DB_RDONLY; - break; - } - return (dbflags); -} - -#ifdef DB_WIN32 -#ifndef S_IRUSR -#define S_IRUSR S_IREAD /* R for owner */ -#endif -#ifndef S_IWUSR -#define S_IWUSR S_IWRITE /* W for owner */ -#endif -#ifndef S_IXUSR -#define S_IXUSR 0 /* X for owner */ -#endif -#ifndef S_IRGRP -#define S_IRGRP 0 /* R for group */ -#endif -#ifndef S_IWGRP -#define S_IWGRP 0 /* W for group */ -#endif -#ifndef S_IXGRP -#define S_IXGRP 0 /* X for group */ -#endif -#ifndef S_IROTH -#define S_IROTH 0 /* R for other */ -#endif -#ifndef S_IWOTH -#define S_IWOTH 0 /* W for other */ -#endif -#ifndef S_IXOTH -#define S_IXOTH 0 /* X for other */ -#endif -#else -#ifndef S_IRUSR -#define S_IRUSR 0000400 /* R for owner */ -#endif -#ifndef S_IWUSR -#define S_IWUSR 0000200 /* W for owner */ -#endif -#ifndef S_IXUSR -#define S_IXUSR 0000100 /* X for owner */ -#endif -#ifndef S_IRGRP -#define S_IRGRP 0000040 /* R for group */ -#endif -#ifndef S_IWGRP -#define S_IWGRP 0000020 /* W for group */ -#endif -#ifndef S_IXGRP -#define S_IXGRP 0000010 /* X for group */ -#endif -#ifndef S_IROTH -#define S_IROTH 0000004 /* R for other */ -#endif -#ifndef S_IWOTH -#define S_IWOTH 0000002 /* W for other */ -#endif -#ifndef S_IXOTH -#define S_IXOTH 0000001 /* X for other */ -#endif -#endif /* DB_WIN32 */ - -/* - * __db_omode -- - * Convert a permission string to the correct open(2) flags. - * - * PUBLIC: int __db_omode __P((const char *)); - */ -int -__db_omode(perm) - const char *perm; -{ - int mode; - mode = 0; - if (perm[0] == 'r') - mode |= S_IRUSR; - if (perm[1] == 'w') - mode |= S_IWUSR; - if (perm[2] == 'x') - mode |= S_IXUSR; - if (perm[3] == 'r') - mode |= S_IRGRP; - if (perm[4] == 'w') - mode |= S_IWGRP; - if (perm[5] == 'x') - mode |= S_IXGRP; - if (perm[6] == 'r') - mode |= S_IROTH; - if (perm[7] == 'w') - mode |= S_IWOTH; - if (perm[8] == 'x') - mode |= S_IXOTH; - return (mode); -} - -#ifdef HAVE_SHMGET - -#ifndef SHM_R -#define SHM_R 0400 -#endif -#ifndef SHM_W -#define SHM_W 0200 -#endif - -/* - * __db_shm_mode -- - * Map the DbEnv::open method file mode permissions to shmget call - * permissions. - * - * PUBLIC: int __db_shm_mode __P((DB_ENV *)); - */ -int -__db_shm_mode(dbenv) - DB_ENV *dbenv; -{ - int mode; - - /* Default to r/w owner, r/w group. */ - if (dbenv->db_mode == 0) - return (SHM_R | SHM_W | SHM_R >> 3 | SHM_W >> 3); - - mode = 0; - if (dbenv->db_mode & S_IRUSR) - mode |= SHM_R; - if (dbenv->db_mode & S_IWUSR) - mode |= SHM_W; - if (dbenv->db_mode & S_IRGRP) - mode |= SHM_R >> 3; - if (dbenv->db_mode & S_IWGRP) - mode |= SHM_W >> 3; - if (dbenv->db_mode & S_IROTH) - mode |= SHM_R >> 6; - if (dbenv->db_mode & S_IWOTH) - mode |= SHM_W >> 6; - return (mode); -} -#endif diff --git a/storage/bdb/os/os_open.c b/storage/bdb/os/os_open.c deleted file mode 100644 index 0ae48092a0e..00000000000 --- a/storage/bdb/os/os_open.c +++ /dev/null @@ -1,404 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_open.c,v 12.7 2005/10/31 02:22:32 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#include <sys/stat.h> - -#ifdef HAVE_SYS_FCNTL_H -#include <sys/fcntl.h> -#endif - -#include <fcntl.h> -#include <string.h> -#endif - -#include "db_int.h" - -static int __os_intermediate_dir __P((DB_ENV *, const char *)); -#ifdef HAVE_QNX -static int __os_region_open __P((DB_ENV *, const char *, int, int, DB_FH **)); -#endif - -/* - * __os_have_direct -- - * Check to see if we support direct I/O. - * - * PUBLIC: int __os_have_direct __P((void)); - */ -int -__os_have_direct() -{ - int ret; - - ret = 0; - -#ifdef HAVE_O_DIRECT - ret = 1; -#endif -#if defined(HAVE_DIRECTIO) && defined(DIRECTIO_ON) - ret = 1; -#endif - return (ret); -} - -/* - * __os_open -- - * Open a file. - * - * PUBLIC: int __os_open - * PUBLIC: __P((DB_ENV *, const char *, u_int32_t, int, DB_FH **)); - */ -int -__os_open(dbenv, name, flags, mode, fhpp) - DB_ENV *dbenv; - const char *name; - u_int32_t flags; - int mode; - DB_FH **fhpp; -{ - return (__os_open_extend(dbenv, name, 0, flags, mode, fhpp)); -} - -/* - * __os_open_extend -- - * Open a file descriptor (including page size and log size information). - * - * PUBLIC: int __os_open_extend __P((DB_ENV *, - * PUBLIC: const char *, u_int32_t, u_int32_t, int, DB_FH **)); - */ -int -__os_open_extend(dbenv, name, page_size, flags, mode, fhpp) - DB_ENV *dbenv; - const char *name; - u_int32_t page_size, flags; - int mode; - DB_FH **fhpp; -{ - DB_FH *fhp; - int oflags, ret; - - COMPQUIET(page_size, 0); - - *fhpp = NULL; - oflags = 0; - -#define OKFLAGS \ - (DB_OSO_ABSMODE | DB_OSO_CREATE | DB_OSO_DIRECT | DB_OSO_DSYNC |\ - DB_OSO_EXCL | DB_OSO_RDONLY | DB_OSO_REGION | DB_OSO_SEQ | \ - DB_OSO_TEMP | DB_OSO_TRUNC) - if ((ret = __db_fchk(dbenv, "__os_open", flags, OKFLAGS)) != 0) - return (ret); - -#if defined(O_BINARY) - /* - * If there's a binary-mode open flag, set it, we never want any - * kind of translation. Some systems do translations by default, - * e.g., with Cygwin, the default mode for an open() is set by the - * mode of the mount that underlies the file. - */ - oflags |= O_BINARY; -#endif - - /* - * DB requires the POSIX 1003.1 semantic that two files opened at the - * same time with DB_OSO_CREATE/O_CREAT and DB_OSO_EXCL/O_EXCL flags - * set return an EEXIST failure in at least one. - */ - if (LF_ISSET(DB_OSO_CREATE)) - oflags |= O_CREAT; - - if (LF_ISSET(DB_OSO_EXCL)) - oflags |= O_EXCL; - -#ifdef HAVE_O_DIRECT - if (LF_ISSET(DB_OSO_DIRECT)) - oflags |= O_DIRECT; -#endif -#ifdef O_DSYNC - if (LF_ISSET(DB_OSO_DSYNC)) - oflags |= O_DSYNC; -#endif - - if (LF_ISSET(DB_OSO_RDONLY)) - oflags |= O_RDONLY; - else - oflags |= O_RDWR; - - if (LF_ISSET(DB_OSO_TRUNC)) - oflags |= O_TRUNC; - - /* - * Undocumented feature: allow applications to create intermediate - * directories whenever a file is opened. - */ - if (dbenv != NULL && - dbenv->dir_mode != 0 && LF_ISSET(DB_OSO_CREATE) && - (ret = __os_intermediate_dir(dbenv, name)) != 0) - return (ret); - -#ifdef HAVE_QNX - if (LF_ISSET(DB_OSO_REGION)) - return (__os_qnx_region_open(dbenv, name, oflags, mode, fhpp)); -#endif - /* Open the file. */ - if ((ret = __os_openhandle(dbenv, name, oflags, mode, &fhp)) != 0) - return (ret); - -#ifdef HAVE_FCHMOD - /* - * If the code using Berkeley DB is a library, that code may not be able - * to control the application's umask value. Allow applications to set - * absolute file modes. We can't fix the race between file creation and - * the fchmod call -- we can't modify the process' umask here since the - * process may be multi-threaded and the umask value is per-process, not - * per-thread. - */ - if (LF_ISSET(DB_OSO_CREATE) && LF_ISSET(DB_OSO_ABSMODE)) - (void)fchmod(fhp->fd, mode); -#endif - -#ifdef O_DSYNC - /* - * If we can configure the file descriptor to flush on write, the - * file descriptor does not need to be explicitly sync'd. - */ - if (LF_ISSET(DB_OSO_DSYNC)) - F_SET(fhp, DB_FH_NOSYNC); -#endif - -#if defined(HAVE_DIRECTIO) && defined(DIRECTIO_ON) - /* - * The Solaris C library includes directio, but you have to set special - * compile flags to #define DIRECTIO_ON. Require both in order to call - * directio. - */ - if (LF_ISSET(DB_OSO_DIRECT)) - (void)directio(fhp->fd, DIRECTIO_ON); -#endif - - /* - * Delete any temporary file. - * - * !!! - * There's a race here, where we've created a file and we crash before - * we can unlink it. Temporary files aren't common in DB, regardless, - * it's not a security problem because the file is empty. There's no - * reasonable way to avoid the race (playing signal games isn't worth - * the portability nightmare), so we just live with it. - */ - if (LF_ISSET(DB_OSO_TEMP)) { -#if defined(HAVE_UNLINK_WITH_OPEN_FAILURE) || defined(CONFIG_TEST) - if ((ret = __os_strdup(dbenv, name, &fhp->name)) != 0) { - (void)__os_closehandle(dbenv, fhp); - (void)__os_unlink(dbenv, name); - return (ret); - } - F_SET(fhp, DB_FH_UNLINK); -#else - (void)__os_unlink(dbenv, name); -#endif - } - - *fhpp = fhp; - return (0); -} - -#ifdef HAVE_QNX -/* - * __os_qnx_region_open -- - * Open a shared memory region file using POSIX shm_open. - */ -static int -__os_qnx_region_open(dbenv, name, oflags, mode, fhpp) - DB_ENV *dbenv; - const char *name; - int oflags; - int mode; - DB_FH **fhpp; -{ - DB_FH *fhp; - int ret; - char *newname; - - if ((ret = __os_calloc(dbenv, 1, sizeof(DB_FH), fhpp)) != 0) - return (ret); - fhp = *fhpp; - - if ((ret = __os_shmname(dbenv, name, &newname)) != 0) - goto err; - - /* - * Once we have created the object, we don't need the name - * anymore. Other callers of this will convert themselves. - */ - fhp->fd = shm_open(newname, oflags, mode); - __os_free(dbenv, newname); - - if (fhp->fd == -1) { - ret = __os_get_errno(); - goto err; - } - - F_SET(fhp, DB_FH_OPENED); - -#ifdef HAVE_FCNTL_F_SETFD - /* Deny file descriptor access to any child process. */ - if (fcntl(fhp->fd, F_SETFD, 1) == -1) { - ret = __os_get_errno(); - __db_err(dbenv, "fcntl(F_SETFD): %s", strerror(ret)); - goto err; - } -#endif - -err: if (ret != 0) { - (void)__os_closehandle(dbenv, fhp); - *fhpp = NULL; - } - - return (ret); -} - -/* - * __os_shmname -- - * Translate a pathname into a shm_open memory object name. - * - * PUBLIC: #ifdef HAVE_QNX - * PUBLIC: int __os_shmname __P((DB_ENV *, const char *, char **)); - * PUBLIC: #endif - */ -int -__os_shmname(dbenv, name, newnamep) - DB_ENV *dbenv; - const char *name; - char **newnamep; -{ - int ret; - size_t size; - char *p, *q, *tmpname; - - *newnamep = NULL; - - /* - * POSIX states that the name for a shared memory object - * may begin with a slash '/' and support for subsequent - * slashes is implementation-dependent. The one implementation - * we know of right now, QNX, forbids subsequent slashes. - * We don't want to be parsing pathnames for '.' and '..' in - * the middle. In order to allow easy conversion, just take - * the last component as the shared memory name. This limits - * the namespace a bit, but makes our job a lot easier. - * - * We should not be modifying user memory, so we use our own. - * Caller is responsible for freeing the memory we give them. - */ - if ((ret = __os_strdup(dbenv, name, &tmpname)) != 0) - return (ret); - /* - * Skip over filename component. - * We set that separator to '\0' so that we can do another - * __db_rpath. However, we immediately set it then to ':' - * so that we end up with the tailing directory:filename. - * We require a home directory component. Return an error - * if there isn't one. - */ - p = __db_rpath(tmpname); - if (p == NULL) - return (EINVAL); - if (p != tmpname) { - *p = '\0'; - q = p; - p = __db_rpath(tmpname); - *q = ':'; - } - if (p != NULL) { - /* - * If we have a path component, copy and return it. - */ - ret = __os_strdup(dbenv, p, newnamep); - __os_free(dbenv, tmpname); - return (ret); - } - - /* - * We were given just a directory name with no path components. - * Add a leading slash, and copy the remainder. - */ - size = strlen(tmpname) + 2; - if ((ret = __os_malloc(dbenv, size, &p)) != 0) - return (ret); - p[0] = '/'; - memcpy(&p[1], tmpname, size-1); - __os_free(dbenv, tmpname); - *newnamep = p; - return (0); -} -#endif - -/* - * __os_intermediate_dir -- - * Create intermediate directories. - */ -static int -__os_intermediate_dir(dbenv, name) - DB_ENV *dbenv; - const char *name; -{ - size_t len; - int ret; - char savech, *p, *t, buf[128]; - - ret = 0; - - /* - * Get a copy so we can modify the string. - * - * Allocate memory if temporary space is too small. - */ - if ((len = strlen(name)) > sizeof(buf) - 1) { - if ((ret = __os_umalloc(dbenv, len + 1, &t)) != 0) - return (ret); - } else - t = buf; - (void)strcpy(t, name); - - /* - * Cycle through the path, creating intermediate directories. - * - * Skip the first byte if it's a path separator, it's the start of an - * absolute pathname. - */ - if (PATH_SEPARATOR[1] == '\0') { - for (p = t + 1; p[0] != '\0'; ++p) - if (p[0] == PATH_SEPARATOR[0]) { - savech = *p; - *p = '\0'; - if (__os_exists(t, NULL) && - (ret = __os_mkdir( - dbenv, t, dbenv->dir_mode)) != 0) - break; - *p = savech; - } - } else - for (p = t + 1; p[0] != '\0'; ++p) - if (strchr(PATH_SEPARATOR, p[0]) != NULL) { - savech = *p; - *p = '\0'; - if (__os_exists(t, NULL) && - (ret = __os_mkdir( - dbenv, t, dbenv->dir_mode)) != 0) - break; - *p = savech; - } - if (t != buf) - __os_free(dbenv, t); - return (ret); -} diff --git a/storage/bdb/os/os_region.c b/storage/bdb/os/os_region.c deleted file mode 100644 index 13083ed6598..00000000000 --- a/storage/bdb/os/os_region.c +++ /dev/null @@ -1,150 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_region.c,v 12.4 2005/07/21 01:36:18 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" - -/* - * __os_r_attach -- - * Attach to a shared memory region. - * - * PUBLIC: int __os_r_attach __P((DB_ENV *, REGINFO *, REGION *)); - */ -int -__os_r_attach(dbenv, infop, rp) - DB_ENV *dbenv; - REGINFO *infop; - REGION *rp; -{ - int ret; - - /* - * All regions are created on 8K boundaries out of sheer paranoia, - * so we don't make some underlying VM unhappy. Make sure we don't - * overflow or underflow. - */ -#define OS_VMPAGESIZE (8 * 1024) -#define OS_VMROUNDOFF(i) { \ - if ((i) < \ - (UINT32_MAX - OS_VMPAGESIZE) + 1 || (i) < OS_VMPAGESIZE) \ - (i) += OS_VMPAGESIZE - 1; \ - (i) -= (i) % OS_VMPAGESIZE; \ -} - OS_VMROUNDOFF(rp->size); - -#ifdef DB_REGIONSIZE_MAX - /* Some architectures have hard limits on the maximum region size. */ - if (rp->size > DB_REGIONSIZE_MAX) { - __db_err(dbenv, "region size %lu is too large; maximum is %lu", - (u_long)rp->size, (u_long)DB_REGIONSIZE_MAX); - return (EINVAL); - } -#endif - - /* - * If a region is private, malloc the memory. - * - * !!! - * If this fails because the region is too large to malloc, mmap(2) - * using the MAP_ANON or MAP_ANONYMOUS flags would be an alternative. - * I don't know of any architectures (yet!) where malloc is a problem. - */ - if (F_ISSET(dbenv, DB_ENV_PRIVATE)) { -#if defined(HAVE_MUTEX_HPPA_MSEM_INIT) - /* - * !!! - * There exist spinlocks that don't work in malloc memory, e.g., - * the HP/UX msemaphore interface. If we don't have locks that - * will work in malloc memory, we better not be private or not - * be threaded. - */ - if (F_ISSET(dbenv, DB_ENV_THREAD)) { - __db_err(dbenv, "%s", - "architecture does not support locks inside process-local (malloc) memory"); - __db_err(dbenv, "%s", - "application may not specify both DB_PRIVATE and DB_THREAD"); - return (EINVAL); - } -#endif - if ((ret = __os_malloc( - dbenv, sizeof(REGENV), &infop->addr)) != 0) - return (ret); - - infop->max_alloc = rp->size; - } else { - /* - * If the user replaced the map call, call through their - * interface. - */ - if (DB_GLOBAL(j_map) != NULL && (ret = DB_GLOBAL(j_map) - (infop->name, rp->size, 1, 0, &infop->addr)) != 0) - return (ret); - - /* Get some space from the underlying system. */ - if ((ret = __os_r_sysattach(dbenv, infop, rp)) != 0) - return (ret); - } - - /* - * We may require alignment the underlying system or heap allocation - * library doesn't supply. Align the address if necessary, saving - * the original values for restoration when the region is discarded. - */ - infop->addr_orig = infop->addr; - infop->addr = ALIGNP_INC(infop->addr_orig, sizeof(size_t)); - - rp->size_orig = rp->size; - if (infop->addr != infop->addr_orig) - rp->size -= - (u_int8_t *)infop->addr - (u_int8_t *)infop->addr_orig; - - return (0); -} - -/* - * __os_r_detach -- - * Detach from a shared memory region. - * - * PUBLIC: int __os_r_detach __P((DB_ENV *, REGINFO *, int)); - */ -int -__os_r_detach(dbenv, infop, destroy) - DB_ENV *dbenv; - REGINFO *infop; - int destroy; -{ - REGION *rp; - - rp = infop->rp; - - /* Restore any address/size altered for alignment reasons. */ - if (infop->addr != infop->addr_orig) { - infop->addr = infop->addr_orig; - rp->size = rp->size_orig; - } - - /* If a region is private, free the memory. */ - if (F_ISSET(dbenv, DB_ENV_PRIVATE)) { - __os_free(dbenv, infop->addr); - return (0); - } - - /* If the user replaced the map call, call through their interface. */ - if (DB_GLOBAL(j_unmap) != NULL) - return (DB_GLOBAL(j_unmap)(infop->addr, rp->size)); - - return (__os_r_sysdetach(dbenv, infop, destroy)); -} diff --git a/storage/bdb/os/os_rename.c b/storage/bdb/os/os_rename.c deleted file mode 100644 index 46d32b81abc..00000000000 --- a/storage/bdb/os/os_rename.c +++ /dev/null @@ -1,47 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_rename.c,v 12.2 2005/07/29 14:21:51 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" - -/* - * __os_rename -- - * Rename a file. - * - * PUBLIC: int __os_rename __P((DB_ENV *, - * PUBLIC: const char *, const char *, u_int32_t)); - */ -int -__os_rename(dbenv, old, new, silent) - DB_ENV *dbenv; - const char *old, *new; - u_int32_t silent; -{ - int ret; - - if (DB_GLOBAL(j_rename) != NULL) - ret = DB_GLOBAL(j_rename)(old, new); - else - RETRY_CHK((rename(old, new)), ret); - - /* - * If "silent" is not set, then errors are OK and we should not output - * an error message. - */ - if (!silent && ret != 0) - __db_err(dbenv, "rename %s %s: %s", old, new, strerror(ret)); - return (ret); -} diff --git a/storage/bdb/os/os_root.c b/storage/bdb/os/os_root.c deleted file mode 100644 index f0a0395b3c9..00000000000 --- a/storage/bdb/os/os_root.c +++ /dev/null @@ -1,32 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_root.c,v 12.2 2005/08/10 15:47:26 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - -#include "db_int.h" - -/* - * __os_isroot -- - * Return if user has special permissions. - * - * PUBLIC: int __os_isroot __P((void)); - */ -int -__os_isroot() -{ -#ifdef HAVE_GETUID - return (getuid() == 0); -#else - return (0); -#endif -} diff --git a/storage/bdb/os/os_rpath.c b/storage/bdb/os/os_rpath.c deleted file mode 100644 index 9b8b84977ec..00000000000 --- a/storage/bdb/os/os_rpath.c +++ /dev/null @@ -1,67 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_rpath.c,v 12.1 2005/06/16 20:23:26 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <string.h> -#endif - -#include "db_int.h" -#ifdef HAVE_VXWORKS -#include "iosLib.h" -#endif - -/* - * __db_rpath -- - * Return the last path separator in the path or NULL if none found. - * - * PUBLIC: char *__db_rpath __P((const char *)); - */ -char * -__db_rpath(path) - const char *path; -{ - const char *s, *last; -#ifdef HAVE_VXWORKS - DEV_HDR *dummy; - char *ptail; - - /* - * VxWorks devices can be rooted at any name. We want to - * skip over the device name and not take into account any - * PATH_SEPARATOR characters that might be in that name. - * - * XXX [#2393] - * VxWorks supports having a filename directly follow a device - * name with no separator. I.e. to access a file 'xxx' in - * the top level directory of a device mounted at "mydrive" - * you could say "mydrivexxx" or "mydrive/xxx" or "mydrive\xxx". - * We do not support the first usage here. - * XXX - */ - if ((dummy = iosDevFind((char *)path, &ptail)) == NULL) - s = path; - else - s = ptail; -#else - s = path; -#endif - - last = NULL; - if (PATH_SEPARATOR[1] != '\0') { - for (; s[0] != '\0'; ++s) - if (strchr(PATH_SEPARATOR, s[0]) != NULL) - last = s; - } else - for (; s[0] != '\0'; ++s) - if (s[0] == PATH_SEPARATOR[0]) - last = s; - return ((char *)last); -} diff --git a/storage/bdb/os/os_rw.c b/storage/bdb/os/os_rw.c deleted file mode 100644 index 9a9e5b3b665..00000000000 --- a/storage/bdb/os/os_rw.c +++ /dev/null @@ -1,331 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_rw.c,v 12.5 2005/08/10 15:47:26 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#include <sys/stat.h> - -#include <string.h> -#endif - -#include "db_int.h" - -#ifdef HAVE_FILESYSTEM_NOTZERO -static int __os_zerofill __P((DB_ENV *, DB_FH *)); -#endif -static int __os_physwrite __P((DB_ENV *, DB_FH *, void *, size_t, size_t *)); - -/* - * __os_io -- - * Do an I/O. - * - * PUBLIC: int __os_io __P((DB_ENV *, - * PUBLIC: int, DB_FH *, db_pgno_t, u_int32_t, u_int8_t *, size_t *)); - */ -int -__os_io(dbenv, op, fhp, pgno, pagesize, buf, niop) - DB_ENV *dbenv; - int op; - DB_FH *fhp; - db_pgno_t pgno; - u_int32_t pagesize; - u_int8_t *buf; - size_t *niop; -{ -#if defined(HAVE_PREAD) && defined(HAVE_PWRITE) - ssize_t nio; -#endif - int ret; - - /* Check for illegal usage. */ - DB_ASSERT(F_ISSET(fhp, DB_FH_OPENED) && fhp->fd != -1); - -#if defined(HAVE_PREAD) && defined(HAVE_PWRITE) - switch (op) { - case DB_IO_READ: - if (DB_GLOBAL(j_read) != NULL) - goto slow; - nio = DB_GLOBAL(j_pread) != NULL ? DB_GLOBAL(j_pread) - (fhp->fd, buf, pagesize, (off_t)pgno * pagesize) : - pread(fhp->fd, buf, pagesize, (off_t)pgno * pagesize); - break; - case DB_IO_WRITE: - if (DB_GLOBAL(j_write) != NULL) - goto slow; -#ifdef HAVE_FILESYSTEM_NOTZERO - if (__os_fs_notzero()) - goto slow; -#endif - nio = DB_GLOBAL(j_pwrite) != NULL ? DB_GLOBAL(j_pwrite) - (fhp->fd, buf, pagesize, (off_t)pgno * pagesize) : - pwrite(fhp->fd, buf, pagesize, (off_t)pgno * pagesize); - break; - default: - return (EINVAL); - } - if (nio == (ssize_t)pagesize) { - *niop = pagesize; - return (0); - } -slow: -#endif - MUTEX_LOCK(dbenv, fhp->mtx_fh); - - if ((ret = __os_seek(dbenv, fhp, - pagesize, pgno, 0, 0, DB_OS_SEEK_SET)) != 0) - goto err; - switch (op) { - case DB_IO_READ: - ret = __os_read(dbenv, fhp, buf, pagesize, niop); - break; - case DB_IO_WRITE: - ret = __os_write(dbenv, fhp, buf, pagesize, niop); - break; - default: - ret = EINVAL; - break; - } - -err: MUTEX_UNLOCK(dbenv, fhp->mtx_fh); - - return (ret); - -} - -/* - * __os_read -- - * Read from a file handle. - * - * PUBLIC: int __os_read __P((DB_ENV *, DB_FH *, void *, size_t, size_t *)); - */ -int -__os_read(dbenv, fhp, addr, len, nrp) - DB_ENV *dbenv; - DB_FH *fhp; - void *addr; - size_t len; - size_t *nrp; -{ - size_t offset; - ssize_t nr; - int ret; - u_int8_t *taddr; - - ret = 0; - - /* Check for illegal usage. */ - DB_ASSERT(F_ISSET(fhp, DB_FH_OPENED) && fhp->fd != -1); - - if (DB_GLOBAL(j_read) != NULL) { - *nrp = len; - if (DB_GLOBAL(j_read)(fhp->fd, addr, len) != (ssize_t)len) { - ret = __os_get_errno(); - __db_err(dbenv, "read: %#lx, %lu: %s", - P_TO_ULONG(addr), (u_long)len, strerror(ret)); - } - return (ret); - } - - for (taddr = addr, offset = 0; - offset < len; taddr += nr, offset += (u_int32_t)nr) { - RETRY_CHK(((nr = read( - fhp->fd, taddr, len - offset)) < 0 ? 1 : 0), ret); - if (nr == 0 || ret != 0) - break; - } - *nrp = (size_t)(taddr - (u_int8_t *)addr); - if (ret != 0) - __db_err(dbenv, "read: %#lx, %lu: %s", - P_TO_ULONG(taddr), (u_long)len - offset, strerror(ret)); - return (ret); -} - -/* - * __os_write -- - * Write to a file handle. - * - * PUBLIC: int __os_write __P((DB_ENV *, DB_FH *, void *, size_t, size_t *)); - */ -int -__os_write(dbenv, fhp, addr, len, nwp) - DB_ENV *dbenv; - DB_FH *fhp; - void *addr; - size_t len; - size_t *nwp; -{ - /* Check for illegal usage. */ - DB_ASSERT(F_ISSET(fhp, DB_FH_OPENED) && fhp->fd != -1); - -#ifdef HAVE_FILESYSTEM_NOTZERO - /* Zero-fill as necessary. */ - if (__os_fs_notzero()) { - int ret; - if ((ret = __os_zerofill(dbenv, fhp)) != 0) - return (ret); - } -#endif - return (__os_physwrite(dbenv, fhp, addr, len, nwp)); -} - -/* - * __os_physwrite -- - * Physical write to a file handle. - */ -static int -__os_physwrite(dbenv, fhp, addr, len, nwp) - DB_ENV *dbenv; - DB_FH *fhp; - void *addr; - size_t len; - size_t *nwp; -{ - size_t offset; - ssize_t nw; - int ret; - u_int8_t *taddr; - - ret = 0; - -#if defined(HAVE_FILESYSTEM_NOTZERO) && defined(DIAGNOSTIC) - if (__os_fs_notzero()) { - struct stat sb; - off_t cur_off; - - DB_ASSERT(fstat(fhp->fd, &sb) != -1 && - (cur_off = lseek(fhp->fd, (off_t)0, SEEK_CUR)) != -1 && - cur_off <= sb.st_size); - } -#endif - - /* - * Make a last "panic" check. Imagine a thread of control running in - * Berkeley DB, going to sleep. Another thread of control decides to - * run recovery because the environment is broken. The first thing - * recovery does is panic the existing environment, but we only check - * the panic flag when crossing the public API. If the sleeping thread - * wakes up and writes something, we could have two threads of control - * writing the log files at the same time. So, before writing, make a - * last panic check. Obviously, there's still a window, but it's very, - * very small. - */ - PANIC_CHECK(dbenv); - - if (DB_GLOBAL(j_write) != NULL) { - *nwp = len; - if (DB_GLOBAL(j_write)(fhp->fd, addr, len) != (ssize_t)len) { - ret = __os_get_errno(); - __db_err(dbenv, "write: %#lx, %lu: %s", - P_TO_ULONG(addr), (u_long)len, strerror(ret)); - } - return (ret); - } - - for (taddr = addr, offset = 0; - offset < len; taddr += nw, offset += (u_int32_t)nw) { - RETRY_CHK(((nw = write( - fhp->fd, taddr, len - offset)) < 0 ? 1 : 0), ret); - if (ret != 0) - break; - } - *nwp = len; - if (ret != 0) - __db_err(dbenv, "write: %#lx, %lu: %s", - P_TO_ULONG(taddr), (u_long)len - offset, strerror(ret)); - return (ret); -} - -#ifdef HAVE_FILESYSTEM_NOTZERO -/* - * __os_zerofill -- - * Zero out bytes in the file. - * - * Pages allocated by writing pages past end-of-file are not zeroed, - * on some systems. Recovery could theoretically be fooled by a page - * showing up that contained garbage. In order to avoid this, we - * have to write the pages out to disk, and flush them. The reason - * for the flush is because if we don't sync, the allocation of another - * page subsequent to this one might reach the disk first, and if we - * crashed at the right moment, leave us with this page as the one - * allocated by writing a page past it in the file. - */ -static int -__os_zerofill(dbenv, fhp) - DB_ENV *dbenv; - DB_FH *fhp; -{ - off_t stat_offset, write_offset; - size_t blen, nw; - u_int32_t bytes, mbytes; - int group_sync, need_free, ret; - u_int8_t buf[8 * 1024], *bp; - - /* Calculate the byte offset of the next write. */ - write_offset = (off_t)fhp->pgno * fhp->pgsize + fhp->offset; - - /* Stat the file. */ - if ((ret = __os_ioinfo(dbenv, NULL, fhp, &mbytes, &bytes, NULL)) != 0) - return (ret); - stat_offset = (off_t)mbytes * MEGABYTE + bytes; - - /* Check if the file is large enough. */ - if (stat_offset >= write_offset) - return (0); - - /* Get a large buffer if we're writing lots of data. */ -#undef ZF_LARGE_WRITE -#define ZF_LARGE_WRITE (64 * 1024) - if (write_offset - stat_offset > ZF_LARGE_WRITE) { - if ((ret = __os_calloc(dbenv, 1, ZF_LARGE_WRITE, &bp)) != 0) - return (ret); - blen = ZF_LARGE_WRITE; - need_free = 1; - } else { - bp = buf; - blen = sizeof(buf); - need_free = 0; - memset(buf, 0, sizeof(buf)); - } - - /* Seek to the current end of the file. */ - if ((ret = __os_seek( - dbenv, fhp, MEGABYTE, mbytes, bytes, 0, DB_OS_SEEK_SET)) != 0) - goto err; - - /* - * Hash is the only access method that allocates groups of pages. Hash - * uses the existence of the last page in a group to signify the entire - * group is OK; so, write all the pages but the last one in the group, - * flush them to disk, then write the last one to disk and flush it. - */ - for (group_sync = 0; stat_offset < write_offset; group_sync = 1) { - if (write_offset - stat_offset <= blen) { - blen = (size_t)(write_offset - stat_offset); - if (group_sync && (ret = __os_fsync(dbenv, fhp)) != 0) - goto err; - } - if ((ret = __os_physwrite(dbenv, fhp, bp, blen, &nw)) != 0) - goto err; - stat_offset += blen; - } - if ((ret = __os_fsync(dbenv, fhp)) != 0) - goto err; - - /* Seek back to where we started. */ - mbytes = (u_int32_t)(write_offset / MEGABYTE); - bytes = (u_int32_t)(write_offset % MEGABYTE); - ret = __os_seek(dbenv, fhp, MEGABYTE, mbytes, bytes, 0, DB_OS_SEEK_SET); - -err: if (need_free) - __os_free(dbenv, bp); - return (ret); -} -#endif diff --git a/storage/bdb/os/os_seek.c b/storage/bdb/os/os_seek.c deleted file mode 100644 index bade2a4355a..00000000000 --- a/storage/bdb/os/os_seek.c +++ /dev/null @@ -1,77 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_seek.c,v 12.2 2005/08/10 15:47:27 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stdlib.h> -#include <string.h> -#endif - -#include "db_int.h" - -/* - * __os_seek -- - * Seek to a page/byte offset in the file. - * - * PUBLIC: int __os_seek __P((DB_ENV *, - * PUBLIC: DB_FH *, u_int32_t, db_pgno_t, u_int32_t, int, DB_OS_SEEK)); - */ -int -__os_seek(dbenv, fhp, pgsize, pageno, relative, isrewind, db_whence) - DB_ENV *dbenv; - DB_FH *fhp; - u_int32_t pgsize; - db_pgno_t pageno; - u_int32_t relative; - int isrewind; - DB_OS_SEEK db_whence; -{ - off_t offset; - int ret, whence; - - /* Check for illegal usage. */ - DB_ASSERT(F_ISSET(fhp, DB_FH_OPENED) && fhp->fd != -1); - - switch (db_whence) { - case DB_OS_SEEK_CUR: - whence = SEEK_CUR; - break; - case DB_OS_SEEK_END: - whence = SEEK_END; - break; - case DB_OS_SEEK_SET: - whence = SEEK_SET; - break; - default: - return (EINVAL); - } - - offset = (off_t)pgsize * pageno + relative; - if (isrewind) - offset = -offset; - - if (DB_GLOBAL(j_seek) != NULL) - ret = DB_GLOBAL(j_seek)(fhp->fd, offset, whence); - else - RETRY_CHK((lseek(fhp->fd, offset, whence) == -1 ? 1 : 0), ret); - - if (ret == 0) { - fhp->pgsize = pgsize; - fhp->pgno = pageno; - fhp->offset = relative; - } else - __db_err(dbenv, "seek: %lu %d %d: %s", - (u_long)pgsize * pageno + relative, - isrewind, db_whence, strerror(ret)); - - return (ret); -} diff --git a/storage/bdb/os/os_sleep.c b/storage/bdb/os/os_sleep.c deleted file mode 100644 index ee20af67f0d..00000000000 --- a/storage/bdb/os/os_sleep.c +++ /dev/null @@ -1,86 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_sleep.c,v 12.2 2005/08/10 15:47:27 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#ifdef HAVE_SYS_SELECT_H -#include <sys/select.h> -#endif - -#ifdef HAVE_VXWORKS -#include <sys/times.h> -#include <time.h> -#include <selectLib.h> -#else -#if TIME_WITH_SYS_TIME -#include <sys/time.h> -#include <time.h> -#else -#if HAVE_SYS_TIME_H -#include <sys/time.h> -#else -#include <time.h> -#endif /* HAVE_SYS_TIME_H */ -#endif /* TIME_WITH SYS_TIME */ -#endif /* HAVE_VXWORKS */ - -#include <string.h> -#endif - -#include "db_int.h" - -/* - * __os_sleep -- - * Yield the processor for a period of time. - * - * PUBLIC: void __os_sleep __P((DB_ENV *, u_long, u_long)); - */ -void -__os_sleep(dbenv, secs, usecs) - DB_ENV *dbenv; - u_long secs, usecs; /* Seconds and microseconds. */ -{ - struct timeval t; - int ret; - - /* Don't require that the values be normalized. */ - for (; usecs >= 1000000; usecs -= 1000000) - ++secs; - - if (DB_GLOBAL(j_sleep) != NULL) { - (void)DB_GLOBAL(j_sleep)(secs, usecs); - return; - } - - /* - * It's important that we yield the processor here so that other - * processes or threads are permitted to run. - * - * Sheer raving paranoia -- don't select for 0 time. - */ - t.tv_sec = (long)secs; - if (secs == 0 && usecs == 0) - t.tv_usec = 1; - else - t.tv_usec = (long)usecs; - - /* - * We don't catch interrupts and restart the system call here, unlike - * other Berkeley DB system calls. This may be a user attempting to - * interrupt a sleeping DB utility (for example, db_checkpoint), and - * we want the utility to see the signal and quit. This assumes it's - * always OK for DB to sleep for less time than originally scheduled. - */ - if (select(0, NULL, NULL, NULL, &t) == -1) - if ((ret = __os_get_errno()) != EINTR) - __db_err(dbenv, "select: %s", strerror(ret)); -} diff --git a/storage/bdb/os/os_spin.c b/storage/bdb/os/os_spin.c deleted file mode 100644 index 8e01c03a474..00000000000 --- a/storage/bdb/os/os_spin.c +++ /dev/null @@ -1,106 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_spin.c,v 12.3 2005/08/10 15:47:27 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#if defined(HAVE_PSTAT_GETDYNAMIC) -#include <sys/pstat.h> -#endif - -#include <limits.h> /* Needed for sysconf on Solaris. */ -#endif - -#include "db_int.h" - -#if defined(HAVE_PSTAT_GETDYNAMIC) -static int __os_pstat_getdynamic __P((void)); - -/* - * __os_pstat_getdynamic -- - * HP/UX. - */ -static int -__os_pstat_getdynamic() -{ - struct pst_dynamic psd; - - return (pstat_getdynamic(&psd, - sizeof(psd), (size_t)1, 0) == -1 ? 1 : psd.psd_proc_cnt); -} -#endif - -#if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN) -static u_int32_t __os_sysconf __P((void)); - -/* - * __os_sysconf -- - * Solaris, Linux. - */ -static u_int32_t -__os_sysconf() -{ - long nproc; - - nproc = sysconf(_SC_NPROCESSORS_ONLN); - return ((u_int32_t)(nproc > 1 ? nproc : 1)); -} -#endif - -/* - * __os_spin -- - * Set the number of default spins before blocking. - * - * PUBLIC: u_int32_t __os_spin __P((DB_ENV *)); - */ -u_int32_t -__os_spin(dbenv) - DB_ENV *dbenv; -{ - u_int32_t tas_spins; - - COMPQUIET(dbenv, NULL); - - tas_spins = 1; -#if defined(HAVE_PSTAT_GETDYNAMIC) - tas_spins = __os_pstat_getdynamic(); -#endif -#if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN) - tas_spins = __os_sysconf(); -#endif - - /* - * Spin 50 times per processor, we have anecdotal evidence that this - * is a reasonable value. - */ - if (tas_spins != 1) - tas_spins *= 50; - - return (tas_spins); -} - -/* - * __os_yield -- - * Yield the processor. - * - * PUBLIC: void __os_yield __P((DB_ENV*, u_long)); - */ -void -__os_yield(dbenv, usecs) - DB_ENV *dbenv; - u_long usecs; -{ - if (DB_GLOBAL(j_yield) != NULL && DB_GLOBAL(j_yield)() == 0) - return; -#ifdef HAVE_VXWORKS - taskDelay(1); -#endif - __os_sleep(dbenv, 0, usecs); -} diff --git a/storage/bdb/os/os_stat.c b/storage/bdb/os/os_stat.c deleted file mode 100644 index 233685ab9ff..00000000000 --- a/storage/bdb/os/os_stat.c +++ /dev/null @@ -1,112 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_stat.c,v 12.1 2005/06/16 20:23:26 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#include <sys/stat.h> - -#include <string.h> -#endif - -#include "db_int.h" - -/* - * __os_exists -- - * Return if the file exists. - * - * PUBLIC: int __os_exists __P((const char *, int *)); - */ -int -__os_exists(path, isdirp) - const char *path; - int *isdirp; -{ - struct stat sb; - int ret; - - if (DB_GLOBAL(j_exists) != NULL) - return (DB_GLOBAL(j_exists)(path, isdirp)); - -#ifdef HAVE_VXWORKS - RETRY_CHK((stat((char *)path, &sb)), ret); -#else - RETRY_CHK((stat(path, &sb)), ret); -#endif - if (ret != 0) - return (ret); - -#if !defined(S_ISDIR) || defined(STAT_MACROS_BROKEN) -#undef S_ISDIR -#ifdef _S_IFDIR -#define S_ISDIR(m) (_S_IFDIR & (m)) -#else -#define S_ISDIR(m) (((m) & 0170000) == 0040000) -#endif -#endif - if (isdirp != NULL) - *isdirp = S_ISDIR(sb.st_mode); - - return (0); -} - -/* - * __os_ioinfo -- - * Return file size and I/O size; abstracted to make it easier - * to replace. - * - * PUBLIC: int __os_ioinfo __P((DB_ENV *, const char *, - * PUBLIC: DB_FH *, u_int32_t *, u_int32_t *, u_int32_t *)); - */ -int -__os_ioinfo(dbenv, path, fhp, mbytesp, bytesp, iosizep) - DB_ENV *dbenv; - const char *path; - DB_FH *fhp; - u_int32_t *mbytesp, *bytesp, *iosizep; -{ - struct stat sb; - int ret; - - if (DB_GLOBAL(j_ioinfo) != NULL) - return (DB_GLOBAL(j_ioinfo)(path, - fhp->fd, mbytesp, bytesp, iosizep)); - - /* Check for illegal usage. */ - DB_ASSERT(F_ISSET(fhp, DB_FH_OPENED) && fhp->fd != -1); - - RETRY_CHK((fstat(fhp->fd, &sb)), ret); - if (ret != 0) { - __db_err(dbenv, "fstat: %s", strerror(ret)); - return (ret); - } - - /* Return the size of the file. */ - if (mbytesp != NULL) - *mbytesp = (u_int32_t)(sb.st_size / MEGABYTE); - if (bytesp != NULL) - *bytesp = (u_int32_t)(sb.st_size % MEGABYTE); - - /* - * Return the underlying filesystem blocksize, if available. - * - * XXX - * Check for a 0 size -- the HP MPE/iX architecture has st_blksize, - * but it's always 0. - */ -#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE - if (iosizep != NULL && (*iosizep = sb.st_blksize) == 0) - *iosizep = DB_DEF_IOSIZE; -#else - if (iosizep != NULL) - *iosizep = DB_DEF_IOSIZE; -#endif - return (0); -} diff --git a/storage/bdb/os/os_tmpdir.c b/storage/bdb/os/os_tmpdir.c deleted file mode 100644 index ee80582329b..00000000000 --- a/storage/bdb/os/os_tmpdir.c +++ /dev/null @@ -1,127 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1998-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_tmpdir.c,v 12.1 2005/06/16 20:23:26 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stdlib.h> -#endif - -#include "db_int.h" - -#ifdef macintosh -#include <TFileSpec.h> -#endif - -/* - * __os_tmpdir -- - * Set the temporary directory path. - * - * The order of items in the list structure and the order of checks in - * the environment are documented. - * - * PUBLIC: int __os_tmpdir __P((DB_ENV *, u_int32_t)); - */ -int -__os_tmpdir(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - int isdir; - - /* - * !!! - * Don't change this to: - * - * static const char * const list[] - * - * because it creates a text relocation in position independent code. - */ - static const char * list[] = { - "/var/tmp", - "/usr/tmp", - "/temp", /* Windows. */ - "/tmp", - "C:/temp", /* Windows. */ - "C:/tmp", /* Windows. */ - NULL - }; - const char * const *lp, *p; - - /* Use the environment if it's permitted and initialized. */ - if (LF_ISSET(DB_USE_ENVIRON) || - (LF_ISSET(DB_USE_ENVIRON_ROOT) && __os_isroot())) { - if ((p = getenv("TMPDIR")) != NULL && p[0] == '\0') { - __db_err(dbenv, "illegal TMPDIR environment variable"); - return (EINVAL); - } - /* Windows */ - if (p == NULL && (p = getenv("TEMP")) != NULL && p[0] == '\0') { - __db_err(dbenv, "illegal TEMP environment variable"); - return (EINVAL); - } - /* Windows */ - if (p == NULL && (p = getenv("TMP")) != NULL && p[0] == '\0') { - __db_err(dbenv, "illegal TMP environment variable"); - return (EINVAL); - } - /* Macintosh */ - if (p == NULL && - (p = getenv("TempFolder")) != NULL && p[0] == '\0') { - __db_err(dbenv, - "illegal TempFolder environment variable"); - return (EINVAL); - } - if (p != NULL) - return (__os_strdup(dbenv, p, &dbenv->db_tmp_dir)); - } - -#ifdef macintosh - /* Get the path to the temporary folder. */ - {FSSpec spec; - - if (!Special2FSSpec(kTemporaryFolderType, - kOnSystemDisk, 0, &spec)) - return (__os_strdup(dbenv, - FSp2FullPath(&spec), &dbenv->db_tmp_dir)); - } -#endif -#ifdef DB_WIN32 - /* Get the path to the temporary directory. */ - { - int ret; - _TCHAR tpath[MAXPATHLEN + 1]; - char *path, *eos; - - if (GetTempPath(MAXPATHLEN, tpath) > 2) { - FROM_TSTRING(dbenv, tpath, path, ret); - if (ret != 0) - return (ret); - eos = path + strlen(path) - 1; - if (*eos == '\\' || *eos == '/') - *eos = '\0'; - if (__os_exists(path, &isdir) == 0 && isdir) { - ret = __os_strdup(dbenv, - path, &dbenv->db_tmp_dir); - FREE_STRING(dbenv, path); - return (ret); - } - FREE_STRING(dbenv, path); - } - } -#endif - - /* Step through the static list looking for a possibility. */ - for (lp = list; *lp != NULL; ++lp) - if (__os_exists(*lp, &isdir) == 0 && isdir != 0) - return (__os_strdup(dbenv, *lp, &dbenv->db_tmp_dir)); - return (0); -} diff --git a/storage/bdb/os/os_truncate.c b/storage/bdb/os/os_truncate.c deleted file mode 100644 index ecf2cc773c9..00000000000 --- a/storage/bdb/os/os_truncate.c +++ /dev/null @@ -1,57 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2004-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_truncate.c,v 12.2 2005/08/10 15:47:27 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" - -/* - * __os_truncate -- - * Truncate the file. - * - * PUBLIC: int __os_truncate __P((DB_ENV *, DB_FH *, db_pgno_t, u_int32_t)); - */ -int -__os_truncate(dbenv, fhp, pgno, pgsize) - DB_ENV *dbenv; - DB_FH *fhp; - db_pgno_t pgno; - u_int32_t pgsize; -{ - off_t offset; - int ret; - - /* - * Truncate a file so that "pgno" is discarded from the end of the - * file. - */ - offset = (off_t)pgsize * pgno; - - if (DB_GLOBAL(j_ftruncate) != NULL) - ret = DB_GLOBAL(j_ftruncate)(fhp->fd, offset); - else { -#ifdef HAVE_FTRUNCATE - RETRY_CHK((ftruncate(fhp->fd, offset)), ret); -#else - ret = DB_OPNOTSUP; -#endif - } - - if (ret != 0) - __db_err(dbenv, - "ftruncate: %lu: %s", (u_long)offset, strerror(ret)); - - return (ret); -} diff --git a/storage/bdb/os/os_unlink.c b/storage/bdb/os/os_unlink.c deleted file mode 100644 index da6fbcc3637..00000000000 --- a/storage/bdb/os/os_unlink.c +++ /dev/null @@ -1,96 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_unlink.c,v 12.3 2005/08/10 15:47:27 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" - -/* - * __os_region_unlink -- - * Remove a shared memory object file. - * - * PUBLIC: int __os_region_unlink __P((DB_ENV *, const char *)); - */ -int -__os_region_unlink(dbenv, path) - DB_ENV *dbenv; - const char *path; -{ -#ifdef HAVE_QNX - int ret; - char *newname; - - if ((ret = __os_shmname(dbenv, path, &newname)) != 0) - goto err; - - if ((ret = shm_unlink(newname)) != 0) { - ret = __os_get_errno(); - if (ret != ENOENT) - __db_err(dbenv, "shm_unlink: %s: %s", - newname, strerror(ret)); - } -err: - if (newname != NULL) - __os_free(dbenv, newname); - return (ret); -#else - if (F_ISSET(dbenv, DB_ENV_OVERWRITE)) - (void)__db_file_multi_write(dbenv, path); - - return (__os_unlink(dbenv, path)); -#endif -} - -/* - * __os_unlink -- - * Remove a file. - * - * PUBLIC: int __os_unlink __P((DB_ENV *, const char *)); - */ -int -__os_unlink(dbenv, path) - DB_ENV *dbenv; - const char *path; -{ - int ret; - - if (DB_GLOBAL(j_unlink) != NULL) - ret = DB_GLOBAL(j_unlink)(path); - else -#ifdef HAVE_VXWORKS - RETRY_CHK((unlink((char *)path)), ret); -#else - RETRY_CHK((unlink(path)), ret); -#endif - /* - * !!! - * The results of unlink are file system driver specific on VxWorks. - * In the case of removing a file that did not exist, some, at least, - * return an error, but with an errno of 0, not ENOENT. We do not - * have to test for the explicitly, the RETRY_CHK macro resets "ret" - * to be the errno, and so we'll just slide right on through. - * - * XXX - * We shouldn't be testing for an errno of ENOENT here, but ENOENT - * signals that a file is missing, and we attempt to unlink things - * (such as v. 2.x environment regions, in DB_ENV->remove) that we - * are expecting not to be there. Reporting errors in these cases - * is annoying. - */ - if (ret != 0 && ret != ENOENT) - __db_err(dbenv, "unlink: %s: %s", path, strerror(ret)); - - return (ret); -} diff --git a/storage/bdb/os_win32/os_abs.c b/storage/bdb/os_win32/os_abs.c deleted file mode 100644 index b22231f7f4d..00000000000 --- a/storage/bdb/os_win32/os_abs.c +++ /dev/null @@ -1,31 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_abs.c,v 12.1 2005/06/16 20:23:28 bostic Exp $ - */ - -#include "db_config.h" - -#include "db_int.h" - -/* - * __os_abspath -- - * Return if a path is an absolute path. - */ -int -__os_abspath(path) - const char *path; -{ - /* - * !!! - * Check for drive specifications, e.g., "C:". In addition, the path - * separator used by the win32 DB (PATH_SEPARATOR) is \; look for both - * / and \ since these are user-input paths. - */ - if (isalpha(path[0]) && path[1] == ':') - path += 2; - return (path[0] == '/' || path[0] == '\\'); -} diff --git a/storage/bdb/os_win32/os_clock.c b/storage/bdb/os_win32/os_clock.c deleted file mode 100644 index 8abd26eaa55..00000000000 --- a/storage/bdb/os_win32/os_clock.c +++ /dev/null @@ -1,34 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2001-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_clock.c,v 12.1 2005/06/16 20:23:28 bostic Exp $ - */ - -#include "db_config.h" - -#include <sys/types.h> -#include <sys/timeb.h> -#include <string.h> - -#include "db_int.h" - -/* - * __os_clock -- - * Return the current time-of-day clock in seconds and microseconds. - */ -void -__os_clock(dbenv, secsp, usecsp) - DB_ENV *dbenv; - u_int32_t *secsp, *usecsp; /* Seconds and microseconds. */ -{ - struct _timeb now; - - _ftime(&now); - if (secsp != NULL) - *secsp = (u_int32_t)now.time; - if (usecsp != NULL) - *usecsp = now.millitm * 1000; -} diff --git a/storage/bdb/os_win32/os_config.c b/storage/bdb/os_win32/os_config.c deleted file mode 100644 index 762445863e5..00000000000 --- a/storage/bdb/os_win32/os_config.c +++ /dev/null @@ -1,108 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_config.c,v 12.2 2005/06/16 20:23:28 bostic Exp $ - */ - -#include "db_config.h" - -#include "db_int.h" - -/* - * __os_is_winnt -- - * Return 1 if Windows/NT, otherwise 0. - * - * PUBLIC: int __os_is_winnt __P((void)); - */ -int -__os_is_winnt() -{ - static int __os_type = -1; - - /* - * The value of __os_type is computed only once, and cached to - * avoid the overhead of repeated calls to GetVersion(). - */ - if (__os_type == -1) { - if ((GetVersion() & 0x80000000) == 0) - __os_type = 1; - else - __os_type = 0; - } - return (__os_type); -} - -/* - * __os_fs_notzero -- - * Return 1 if allocated filesystem blocks are not zeroed. - */ -int -__os_fs_notzero() -{ - static int __os_notzero = -1; - OSVERSIONINFO osvi; - - /* - * Windows/NT zero-fills pages that were never explicitly written to - * the file. Note however that this is *NOT* documented. In fact, the - * Win32 documentation makes it clear that there are no guarantees that - * uninitialized bytes will be zeroed: - * - * If the file is extended, the contents of the file between the old - * EOF position and the new position are not defined. - * - * Experiments confirm that NT/2K/XP all zero fill for both NTFS and - * FAT32. Cygwin also relies on this behavior. This is the relevant - * comment from Cygwin: - * - * Oops, this is the bug case - Win95 uses whatever is on the disk - * instead of some known (safe) value, so we must seek back and fill - * in the gap with zeros. - DJ - * Note: this bug doesn't happen on NT4, even though the - * documentation for WriteFile() says that it *may* happen on any OS. - * - * We're making a bet, here, but we made it a long time ago and haven't - * yet seen any evidence that it was wrong. - * - * Windows 95/98 and On-Time give random garbage, and that breaks - * Berkeley DB. - * - * The value of __os_notzero is computed only once, and cached to - * avoid the overhead of repeated calls to GetVersion(). - */ - if (__os_notzero == -1) { - if (__os_is_winnt()) { - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx(&osvi); - if (_tcscmp(osvi.szCSDVersion, _T("RTTarget-32")) == 0) - __os_notzero = 1; /* On-Time */ - else - __os_notzero = 0; /* Windows/NT */ - } else - __os_notzero = 1; /* Not Windows/NT */ - } - return (__os_notzero); -} - -/* - * __os_support_db_register -- - * Return 1 if the system supports DB_REGISTER. - */ -int -__os_support_db_register() -{ - return (__os_is_winnt()); -} - -/* - * __os_support_replication -- - * Return 1 if the system supports replication. - */ -int -__os_support_replication() -{ - return (__os_is_winnt()); -} diff --git a/storage/bdb/os_win32/os_dir.c b/storage/bdb/os_win32/os_dir.c deleted file mode 100644 index f3d28fbb791..00000000000 --- a/storage/bdb/os_win32/os_dir.c +++ /dev/null @@ -1,109 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_dir.c,v 12.2 2005/07/06 23:52:43 dda Exp $ - */ - -#include "db_config.h" - -#include "db_int.h" - -/* - * __os_dirlist -- - * Return a list of the files in a directory. - */ -int -__os_dirlist(dbenv, dir, namesp, cntp) - DB_ENV *dbenv; - const char *dir; - char ***namesp; - int *cntp; -{ - HANDLE dirhandle; - WIN32_FIND_DATA fdata; - int arraysz, cnt, ret; - char **names, *onename; - _TCHAR tfilespec[MAXPATHLEN + 1]; - _TCHAR *tdir; - - if (DB_GLOBAL(j_dirlist) != NULL) - return (DB_GLOBAL(j_dirlist)(dir, namesp, cntp)); - - TO_TSTRING(dbenv, dir, tdir, ret); - if (ret != 0) - return (ret); - - (void)_sntprintf(tfilespec, MAXPATHLEN, - _T("%s%hc*"), tdir, PATH_SEPARATOR[0]); - if ((dirhandle = FindFirstFile(tfilespec, &fdata)) - == INVALID_HANDLE_VALUE) - return (__os_get_errno()); - - names = NULL; - arraysz = cnt = ret = 0; - for (;;) { - if (cnt >= arraysz) { - arraysz += 100; - if ((ret = __os_realloc(dbenv, - arraysz * sizeof(names[0]), &names)) != 0) - goto err; - } - /* - * FROM_TSTRING doesn't necessarily allocate new memory, so we - * must do that explicitly. Unfortunately, when compiled with - * UNICODE, we'll copy twice. - */ - FROM_TSTRING(dbenv, fdata.cFileName, onename, ret); - if (ret != 0) - goto err; - ret = __os_strdup(dbenv, onename, &names[cnt]); - FREE_STRING(dbenv, onename); - if (ret != 0) - goto err; - cnt++; - if (!FindNextFile(dirhandle, &fdata)) { - if (GetLastError() == ERROR_NO_MORE_FILES) - break; - else { - ret = __os_get_errno(); - goto err; - } - } - } - -err: if (!FindClose(dirhandle) && ret == 0) - ret = __os_get_errno(); - - if (ret == 0) { - *namesp = names; - *cntp = cnt; - } else if (names != NULL) - __os_dirfree(dbenv, names, cnt); - - FREE_STRING(dbenv, tdir); - - return (ret); -} - -/* - * __os_dirfree -- - * Free the list of files. - */ -void -__os_dirfree(dbenv, names, cnt) - DB_ENV *dbenv; - char **names; - int cnt; -{ - if (DB_GLOBAL(j_dirfree) != NULL) { - DB_GLOBAL(j_dirfree)(names, cnt); - return; - } - - while (cnt > 0) - __os_free(dbenv, names[--cnt]); - __os_free(dbenv, names); -} diff --git a/storage/bdb/os_win32/os_errno.c b/storage/bdb/os_win32/os_errno.c deleted file mode 100644 index 80869ec9cd3..00000000000 --- a/storage/bdb/os_win32/os_errno.c +++ /dev/null @@ -1,136 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_errno.c,v 12.2 2005/06/16 20:23:28 bostic Exp $ - */ - -#include "db_config.h" - -#include "db_int.h" - -/* - * __os_get_errno_ret_zero -- - * Return the value of errno, even if it's zero. - */ -int -__os_get_errno_ret_zero() -{ - /* This routine must be able to return the same value repeatedly. */ - return (errno); -} - -/* - * __os_get_errno -- - * Return the last Windows error as an errno. - * We give generic error returns: - * - * EFAULT means Win* call failed, - * and GetLastError provided no extra info. - * - * EIO means error on Win* call, - * and we were unable to provide a meaningful errno for this Windows - * error. More information is only available by setting a breakpoint - * here. - */ -int -__os_get_errno() -{ - DWORD last_error; - int ret; - - last_error = GetLastError(); - - /* - * Take our best guess at translating some of the Windows error - * codes. We really care about only a few of these. - */ - switch (last_error) { - case ERROR_FILE_NOT_FOUND: - case ERROR_INVALID_DRIVE: - case ERROR_PATH_NOT_FOUND: - ret = ENOENT; - break; - - case ERROR_NO_MORE_FILES: - case ERROR_TOO_MANY_OPEN_FILES: - ret = EMFILE; - break; - - case ERROR_ACCESS_DENIED: - ret = EPERM; - break; - - case ERROR_INVALID_HANDLE: - ret = EBADF; - break; - - case ERROR_NOT_ENOUGH_MEMORY: - ret = ENOMEM; - break; - - case ERROR_DISK_FULL: - ret = ENOSPC; - break; - - case ERROR_ARENA_TRASHED: - case ERROR_BAD_COMMAND: - case ERROR_BAD_ENVIRONMENT: - case ERROR_BAD_FORMAT: - case ERROR_GEN_FAILURE: - case ERROR_INVALID_ACCESS: - case ERROR_INVALID_BLOCK: - case ERROR_INVALID_DATA: - case ERROR_READ_FAULT: - case ERROR_WRITE_FAULT: - ret = EFAULT; - break; - - case ERROR_FILE_EXISTS: - case ERROR_ALREADY_EXISTS: - ret = EEXIST; - break; - - case ERROR_NOT_SAME_DEVICE: - ret = EXDEV; - break; - - case ERROR_WRITE_PROTECT: - ret = EACCES; - break; - - case ERROR_LOCK_FAILED: - case ERROR_NOT_READY: - case ERROR_LOCK_VIOLATION: - case ERROR_SHARING_VIOLATION: - ret = EBUSY; - break; - - case ERROR_RETRY: - ret = EINTR; - break; - - case 0: - ret = EFAULT; - break; - - default: - ret = EIO; /* Generic error. */ - break; - } - - return (ret); -} - -/* - * __os_set_errno -- - * Set the value of errno. - */ -void -__os_set_errno(evalue) - int evalue; -{ - errno = evalue; -} diff --git a/storage/bdb/os_win32/os_fid.c b/storage/bdb/os_win32/os_fid.c deleted file mode 100644 index b2e2340b67e..00000000000 --- a/storage/bdb/os_win32/os_fid.c +++ /dev/null @@ -1,148 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_fid.c,v 12.4 2005/10/11 18:17:00 bostic Exp $ - */ - -#include "db_config.h" - -#include "db_int.h" - -#define SERIAL_INIT 0 -static u_int32_t fid_serial = SERIAL_INIT; - -/* - * __os_fileid -- - * Return a unique identifier for a file. - */ -int -__os_fileid(dbenv, fname, unique_okay, fidp) - DB_ENV *dbenv; - const char *fname; - int unique_okay; - u_int8_t *fidp; -{ - db_threadid_t tid; - pid_t pid; - size_t i; - u_int32_t tmp; - u_int8_t *p; - int ret; - - /* - * The documentation for GetFileInformationByHandle() states that the - * inode-type numbers are not constant between processes. Actually, - * they are, they're the NTFS MFT indexes. So, this works on NTFS, - * but perhaps not on other platforms, and perhaps not over a network. - * Can't think of a better solution right now. - */ - DB_FH *fhp; - BY_HANDLE_FILE_INFORMATION fi; - BOOL retval = FALSE; - - DB_ASSERT(fname != NULL); - - /* Clear the buffer. */ - memset(fidp, 0, DB_FILE_ID_LEN); - - /* - * Initialize/increment the serial number we use to help avoid - * fileid collisions. Note that we don't bother with locking; - * it's unpleasant to do from down in here, and if we race on - * this no real harm will be done, since the finished fileid - * has so many other components. - * - * We use the bottom 32-bits of the process ID, hoping they - * are more random than the top 32-bits (should we be on a - * machine with 64-bit process IDs). - * - * We increment by 100000 on each call as a simple way of - * randomizing; simply incrementing seems potentially less useful - * if pids are also simply incremented, since this is process-local - * and we may be one of a set of processes starting up. 100000 - * pushes us out of pid space on most platforms, and has few - * interesting properties in base 2. - */ - if (fid_serial == SERIAL_INIT) { - __os_id(dbenv, &pid, &tid); - fid_serial = pid; - } else - fid_serial += 100000; - - /* - * First we open the file, because we're not given a handle to it. - * If we can't open it, we're in trouble. - */ - if ((ret = __os_open(dbenv, fname, DB_OSO_RDONLY, _S_IREAD, &fhp)) != 0) - return (ret); - - /* File open, get its info */ - if ((retval = GetFileInformationByHandle(fhp->handle, &fi)) == FALSE) - ret = __os_get_errno(); - (void)__os_closehandle(dbenv, fhp); - - if (retval == FALSE) - return (ret); - - /* - * We want the three 32-bit words which tell us the volume ID and - * the file ID. We make a crude attempt to copy the bytes over to - * the callers buffer. - * - * We don't worry about byte sexing or the actual variable sizes. - * - * When this routine is called from the DB access methods, it's only - * called once -- whatever ID is generated when a database is created - * is stored in the database file's metadata, and that is what is - * saved in the mpool region's information to uniquely identify the - * file. - * - * When called from the mpool layer this routine will be called each - * time a new thread of control wants to share the file, which makes - * things tougher. As far as byte sexing goes, since the mpool region - * lives on a single host, there's no issue of that -- the entire - * region is byte sex dependent. As far as variable sizes go, we make - * the simplifying assumption that 32-bit and 64-bit processes will - * get the same 32-bit values if we truncate any returned 64-bit value - * to a 32-bit value. - */ - tmp = (u_int32_t)fi.nFileIndexLow; - for (p = (u_int8_t *)&tmp, i = sizeof(u_int32_t); i > 0; --i) - *fidp++ = *p++; - tmp = (u_int32_t)fi.nFileIndexHigh; - for (p = (u_int8_t *)&tmp, i = sizeof(u_int32_t); i > 0; --i) - *fidp++ = *p++; - - if (unique_okay) { - /* - * Use the system time to try to get a unique value - * within this process. A millisecond counter - * overflows 32 bits in about 49 days. So we use 8 - * bytes, and don't bother with the volume ID, which - * is not very useful for our purposes. - */ - SYSTEMTIME st; - - GetSystemTime(&st); - tmp = (st.wYear - 1900) * 12 + (st.wMonth - 1); - for (p = (u_int8_t *)&tmp, i = sizeof(u_int32_t); i > 0; --i) - *fidp++ = *p++; - tmp = ((((st.wDay - 1) * 24 + st.wHour) * 60 + - st.wMinute) * 60 + st.wSecond) * 1000 + - st.wMilliseconds; - for (p = (u_int8_t *)&tmp, i = sizeof(u_int32_t); i > 0; --i) - *fidp++ = *p++; - for (p = (u_int8_t *)&fid_serial, i = sizeof(u_int32_t); - i > 0; --i) - *fidp++ = *p++; - } else { - tmp = (u_int32_t)fi.dwVolumeSerialNumber; - for (p = (u_int8_t *)&tmp, i = sizeof(u_int32_t); i > 0; --i) - *fidp++ = *p++; - } - - return (0); -} diff --git a/storage/bdb/os_win32/os_flock.c b/storage/bdb/os_win32/os_flock.c deleted file mode 100644 index 0e9c83163e2..00000000000 --- a/storage/bdb/os_win32/os_flock.c +++ /dev/null @@ -1,71 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_flock.c,v 1.6 2005/06/16 20:23:28 bostic Exp $ - */ - -#include "db_config.h" - -#include "db_int.h" - -/* - * __os_fdlock -- - * Acquire/release a lock on a byte in a file. - * - * PUBLIC: int __os_fdlock __P((DB_ENV *, DB_FH *, off_t, int, int)); - */ -int -__os_fdlock(dbenv, fhp, offset, acquire, nowait) - DB_ENV *dbenv; - DB_FH *fhp; - int acquire, nowait; - off_t offset; -{ - int ret; - DWORD low, high; - OVERLAPPED over; - - DB_ASSERT(F_ISSET(fhp, DB_FH_OPENED) && - fhp->handle != INVALID_HANDLE_VALUE); - - /* - * Windows file locking interferes with read/write operations, so we - * map the ranges to an area past the end of the file. - */ - DB_ASSERT(offset < (u_int64_t)INT64_MAX); - offset = UINT64_MAX - offset; - low = (DWORD)offset; - high = (DWORD)(offset >> 32); - - if (acquire) { - if (nowait) - RETRY_CHK_EINTR_ONLY( - !LockFile(fhp->handle, low, high, 1, 0), ret); - else if (__os_is_winnt()) { - memset(&over, 0, sizeof over); - over.Offset = low; - over.OffsetHigh = high; - RETRY_CHK_EINTR_ONLY( - !LockFileEx(fhp->handle, LOCKFILE_EXCLUSIVE_LOCK, - 0, 1, 0, &over), - ret); - } else { - /* Windows 9x/ME doesn't support a blocking call. */ - for (;;) { - RETRY_CHK_EINTR_ONLY( - !LockFile(fhp->handle, low, high, 1, 0), - ret); - if (ret != EAGAIN) - break; - __os_sleep(dbenv, 1, 0); - } - } - } else - RETRY_CHK_EINTR_ONLY( - !UnlockFile(fhp->handle, low, high, 1, 0), ret); - - return (ret); -} diff --git a/storage/bdb/os_win32/os_fsync.c b/storage/bdb/os_win32/os_fsync.c deleted file mode 100644 index c5da376ab1e..00000000000 --- a/storage/bdb/os_win32/os_fsync.c +++ /dev/null @@ -1,47 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_fsync.c,v 12.2 2005/08/10 15:47:27 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <fcntl.h> /* XXX: Required by __hp3000s900 */ -#include <string.h> -#endif - -#include "db_int.h" - -/* - * __os_fsync -- - * Flush a file descriptor. - */ -int -__os_fsync(dbenv, fhp) - DB_ENV *dbenv; - DB_FH *fhp; -{ - int ret; - - /* - * Do nothing if the file descriptor has been marked as not requiring - * any sync to disk. - */ - if (F_ISSET(fhp, DB_FH_NOSYNC)) - return (0); - - if (DB_GLOBAL(j_fsync) != NULL) - ret = DB_GLOBAL(j_fsync)(fhp->fd); - else - RETRY_CHK((!FlushFileBuffers(fhp->handle)), ret); - - if (ret != 0) - __db_err(dbenv, "fsync %s", strerror(ret)); - return (ret); -} diff --git a/storage/bdb/os_win32/os_handle.c b/storage/bdb/os_win32/os_handle.c deleted file mode 100644 index 338bfd1e2e7..00000000000 --- a/storage/bdb/os_win32/os_handle.c +++ /dev/null @@ -1,130 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1998-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_handle.c,v 12.3 2005/11/02 03:12:18 mjc Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <fcntl.h> -#include <string.h> -#endif - -#include "db_int.h" - -/* - * __os_openhandle -- - * Open a file, using POSIX 1003.1 open flags. - */ -int -__os_openhandle(dbenv, name, flags, mode, fhpp) - DB_ENV *dbenv; - const char *name; - int flags, mode; - DB_FH **fhpp; -{ - DB_FH *fhp; - int ret, nrepeat, retries; - - if ((ret = __os_calloc(dbenv, 1, sizeof(DB_FH), fhpp)) != 0) - return (ret); - fhp = *fhpp; - - /* If the application specified an interface, use it. */ - if (DB_GLOBAL(j_open) != NULL) { - if ((fhp->fd = DB_GLOBAL(j_open)(name, flags, mode)) == -1) { - ret = __os_get_errno(); - goto err; - } - F_SET(fhp, DB_FH_OPENED); - return (0); - } - - retries = 0; - for (nrepeat = 1; nrepeat < 4; ++nrepeat) { - ret = 0; - fhp->fd = _open(name, flags, mode); - - if (fhp->fd != -1) { - F_SET(fhp, DB_FH_OPENED); - break; - } - - switch (ret = __os_get_errno()) { - case EMFILE: - case ENFILE: - case ENOSPC: - /* - * If it's a "temporary" error, we retry up to 3 times, - * waiting up to 12 seconds. While it's not a problem - * if we can't open a database, an inability to open a - * log file is cause for serious dismay. - */ - __os_sleep(dbenv, nrepeat * 2, 0); - break; - case EAGAIN: - case EBUSY: - case EINTR: - /* - * If an EAGAIN, EBUSY or EINTR, retry immediately for - * DB_RETRY times. - */ - if (++retries < DB_RETRY) - --nrepeat; - break; - } - } - -err: if (ret != 0) { - (void)__os_closehandle(dbenv, fhp); - *fhpp = NULL; - } - - return (ret); -} - -/* - * __os_closehandle -- - * Close a file. - */ -int -__os_closehandle(dbenv, fhp) - DB_ENV *dbenv; - DB_FH *fhp; -{ - int ret; - - ret = 0; - - /* - * If we have a valid handle, close it and unlink any temporary - * file. - */ - if (F_ISSET(fhp, DB_FH_OPENED)) { - if (DB_GLOBAL(j_close) != NULL) - ret = DB_GLOBAL(j_close)(fhp->fd); - else if (fhp->handle != INVALID_HANDLE_VALUE) - RETRY_CHK((!CloseHandle(fhp->handle)), ret); - else - RETRY_CHK((_close(fhp->fd)), ret); - - if (ret != 0) - __db_err(dbenv, "CloseHandle: %s", strerror(ret)); - - /* Unlink the file if we haven't already done so. */ - if (F_ISSET(fhp, DB_FH_UNLINK)) { - (void)__os_unlink(dbenv, fhp->name); - __os_free(dbenv, fhp->name); - } - } - - __os_free(dbenv, fhp); - - return (ret); -} diff --git a/storage/bdb/os_win32/os_map.c b/storage/bdb/os_win32/os_map.c deleted file mode 100644 index 9e2b5a6db63..00000000000 --- a/storage/bdb/os_win32/os_map.c +++ /dev/null @@ -1,315 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_map.c,v 12.2 2005/06/16 20:23:29 bostic Exp $ - */ - -#include "db_config.h" - -#include "db_int.h" - -static int __os_map - __P((DB_ENV *, char *, REGINFO *, DB_FH *, size_t, int, int, int, void **)); -static int __os_unique_name __P((_TCHAR *, HANDLE, _TCHAR *, size_t)); - -/* - * __os_r_sysattach -- - * Create/join a shared memory region. - */ -int -__os_r_sysattach(dbenv, infop, rp) - DB_ENV *dbenv; - REGINFO *infop; - REGION *rp; -{ - DB_FH *fhp; - int is_system, ret; - - /* - * Try to open/create the file. We DO NOT need to ensure that multiple - * threads/processes attempting to simultaneously create the region are - * properly ordered, our caller has already taken care of that. - */ - if ((ret = __os_open(dbenv, infop->name, - F_ISSET(infop, REGION_CREATE_OK) ? DB_OSO_CREATE: 0, - dbenv->db_mode, &fhp)) != 0) { - __db_err(dbenv, "%s: %s", infop->name, db_strerror(ret)); - return (ret); - } - - /* - * On Windows/9X, files that are opened by multiple processes do not - * share data correctly. For this reason, the DB_SYSTEM_MEM flag is - * implied for any application that does not specify the DB_PRIVATE - * flag. - */ - is_system = F_ISSET(dbenv, DB_ENV_SYSTEM_MEM) || - (!F_ISSET(dbenv, DB_ENV_PRIVATE) && __os_is_winnt() == 0); - - /* - * Map the file in. If we're creating an in-system-memory region, - * specify a segment ID (which is never used again) so that the - * calling code writes out the REGENV_REF structure to the primary - * environment file. - */ - ret = __os_map(dbenv, infop->name, infop, fhp, rp->size, - 1, is_system, 0, &infop->addr); - if (ret == 0 && is_system == 1) - rp->segid = 1; - - (void)__os_closehandle(dbenv, fhp); - - return (ret); -} - -/* - * __os_r_sysdetach -- - * Detach from a shared memory region. - */ -int -__os_r_sysdetach(dbenv, infop, destroy) - DB_ENV *dbenv; - REGINFO *infop; - int destroy; -{ - int ret, t_ret; - - if (infop->wnt_handle != NULL) { - (void)CloseHandle(infop->wnt_handle); - infop->wnt_handle = NULL; - } - - ret = !UnmapViewOfFile(infop->addr) ? __os_get_errno() : 0; - if (ret != 0) - __db_err(dbenv, "UnmapViewOfFile: %s", strerror(ret)); - - if (!F_ISSET(dbenv, DB_ENV_SYSTEM_MEM) && destroy) { - if (F_ISSET(dbenv, DB_ENV_OVERWRITE)) - (void)__db_file_multi_write(dbenv, infop->name); - if ((t_ret = __os_unlink(dbenv, infop->name)) != 0 && ret == 0) - ret = t_ret; - } - - return (ret); -} - -/* - * __os_mapfile -- - * Map in a shared memory file. - */ -int -__os_mapfile(dbenv, path, fhp, len, is_rdonly, addr) - DB_ENV *dbenv; - char *path; - DB_FH *fhp; - int is_rdonly; - size_t len; - void **addr; -{ - /* If the user replaced the map call, call through their interface. */ - if (DB_GLOBAL(j_map) != NULL) - return (DB_GLOBAL(j_map)(path, len, 0, is_rdonly, addr)); - - return (__os_map(dbenv, path, NULL, fhp, len, 0, 0, is_rdonly, addr)); -} - -/* - * __os_unmapfile -- - * Unmap the shared memory file. - */ -int -__os_unmapfile(dbenv, addr, len) - DB_ENV *dbenv; - void *addr; - size_t len; -{ - /* If the user replaced the map call, call through their interface. */ - if (DB_GLOBAL(j_unmap) != NULL) - return (DB_GLOBAL(j_unmap)(addr, len)); - - return (!UnmapViewOfFile(addr) ? __os_get_errno() : 0); -} - -/* - * __os_unique_name -- - * Create a unique identifying name from a pathname (may be absolute or - * relative) and/or a file descriptor. - * - * The name returned must be unique (different files map to different - * names), and repeatable (same files, map to same names). It's not - * so easy to do by name. Should handle not only: - * - * foo.bar == ./foo.bar == c:/whatever_path/foo.bar - * - * but also understand that: - * - * foo.bar == Foo.Bar (FAT file system) - * foo.bar != Foo.Bar (NTFS) - * - * The best solution is to use the file index, found in the file - * information structure (similar to UNIX inode #). - * - * When a file is deleted, its file index may be reused, - * but if the unique name has not gone from its namespace, - * we may get a conflict. So to ensure some tie in to the - * original pathname, we also use the creation time and the - * file basename. This is not a perfect system, but it - * should work for all but anamolous test cases. - * - */ -static int -__os_unique_name(orig_path, hfile, result_path, result_path_len) - _TCHAR *orig_path, *result_path; - HANDLE hfile; - size_t result_path_len; -{ - BY_HANDLE_FILE_INFORMATION fileinfo; - _TCHAR *basename, *p; - - /* - * In Windows, pathname components are delimited by '/' or '\', and - * if neither is present, we need to strip off leading drive letter - * (e.g. c:foo.txt). - */ - basename = _tcsrchr(orig_path, '/'); - p = _tcsrchr(orig_path, '\\'); - if (basename == NULL || (p != NULL && p > basename)) - basename = p; - if (basename == NULL) - basename = _tcsrchr(orig_path, ':'); - - if (basename == NULL) - basename = orig_path; - else - basename++; - - if (!GetFileInformationByHandle(hfile, &fileinfo)) - return (__os_get_errno()); - - (void)_sntprintf(result_path, result_path_len, - _T("__db_shmem.%8.8lx.%8.8lx.%8.8lx.%8.8lx.%8.8lx.%s"), - fileinfo.dwVolumeSerialNumber, - fileinfo.nFileIndexHigh, - fileinfo.nFileIndexLow, - fileinfo.ftCreationTime.dwHighDateTime, - fileinfo.ftCreationTime.dwHighDateTime, - basename); - - return (0); -} - -/* - * __os_map -- - * The mmap(2) function for Windows. - */ -static int -__os_map(dbenv, path, infop, fhp, len, is_region, is_system, is_rdonly, addr) - DB_ENV *dbenv; - REGINFO *infop; - char *path; - DB_FH *fhp; - int is_region, is_system, is_rdonly; - size_t len; - void **addr; -{ - HANDLE hMemory; - int ret, use_pagefile; - _TCHAR *tpath, shmem_name[MAXPATHLEN]; - void *pMemory; - - ret = 0; - if (infop != NULL) - infop->wnt_handle = NULL; - - use_pagefile = is_region && is_system; - - /* - * If creating a region in system space, get a matching name in the - * paging file namespace. - */ - if (use_pagefile) { - TO_TSTRING(dbenv, path, tpath, ret); - if (ret != 0) - return (ret); - ret = __os_unique_name(tpath, fhp->handle, - shmem_name, sizeof(shmem_name)); - FREE_STRING(dbenv, tpath); - if (ret != 0) - return (ret); - } - - /* - * XXX - * DB: We have not implemented copy-on-write here. - * - * If this is an region in system memory, we try to open it using the - * OpenFileMapping() first, and only call CreateFileMapping() if we're - * really creating the section. There are two reasons: - * - * 1) We only create the mapping if we have newly created the region. - * This avoids a long-running problem caused by Windows reference - * counting, where regions that are closed by all processes are - * deleted. It turns out that just checking for a zeroed region - * is not good enough. See [#4882] and [#7127] for the details. - * - * 2) CreateFileMapping seems to mess up making the commit charge to - * the process. It thinks, incorrectly, that when we want to join a - * previously existing section, that it should make a commit charge - * for the whole section. In fact, there is no new committed memory - * whatever. The call can fail if there is insufficient memory free - * to handle the erroneous commit charge. So, we find that the - * bogus commit is not made if we call OpenFileMapping. - */ - hMemory = NULL; - if (use_pagefile) { - hMemory = OpenFileMapping( - is_rdonly ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS, - 0, shmem_name); - - if (hMemory == NULL && F_ISSET(infop, REGION_CREATE_OK)) - hMemory = CreateFileMapping((HANDLE)-1, 0, - is_rdonly ? PAGE_READONLY : PAGE_READWRITE, - 0, (DWORD)len, shmem_name); - } else - hMemory = CreateFileMapping(fhp->handle, 0, - is_rdonly ? PAGE_READONLY : PAGE_READWRITE, - 0, (DWORD)len, NULL); - - if (hMemory == NULL) { - ret = __os_get_errno(); - __db_err(dbenv, "OpenFileMapping: %s", strerror(ret)); - return (__db_panic(dbenv, ret)); - } - - pMemory = MapViewOfFile(hMemory, - (is_rdonly ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS), 0, 0, len); - if (pMemory == NULL) { - ret = __os_get_errno(); - __db_err(dbenv, "MapViewOfFile: %s", strerror(ret)); - return (__db_panic(dbenv, ret)); - } - - /* - * XXX - * It turns out that the kernel object underlying the named section - * is reference counted, but that the call to MapViewOfFile() above - * does NOT increment the reference count! So, if we close the handle - * here, the kernel deletes the object from the kernel namespace. - * When a second process comes along to join the region, the kernel - * happily creates a new object with the same name, but completely - * different identity. The two processes then have distinct isolated - * mapped sections, not at all what was wanted. Not closing the handle - * here fixes this problem. We carry the handle around in the region - * structure so we can close it when unmap is called. - */ - if (use_pagefile && infop != NULL) - infop->wnt_handle = hMemory; - else - CloseHandle(hMemory); - - *addr = pMemory; - return (ret); -} diff --git a/storage/bdb/os_win32/os_open.c b/storage/bdb/os_win32/os_open.c deleted file mode 100644 index dde33cb5d1e..00000000000 --- a/storage/bdb/os_win32/os_open.c +++ /dev/null @@ -1,229 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_open.c,v 12.6 2005/10/31 11:21:01 mjc Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <fcntl.h> -#include <signal.h> -#include <string.h> -#endif - -#include "db_int.h" - -/* - * __os_have_direct -- - * Check to see if we support direct I/O. - * - * PUBLIC: int __os_have_direct __P((void)); - */ -int -__os_have_direct() -{ - return (1); -} - -/* - * __os_open -- - * Open a file descriptor. - */ -__os_open(dbenv, name, flags, mode, fhpp) - DB_ENV *dbenv; - const char *name; - u_int32_t flags; - int mode; - DB_FH **fhpp; -{ - return (__os_open_extend(dbenv, name, 0, flags, mode, fhpp)); -} - -/* - * __os_open_extend -- - * Open a file descriptor (including page size and log size information). - */ -int -__os_open_extend(dbenv, name, page_size, flags, mode, fhpp) - DB_ENV *dbenv; - const char *name; - u_int32_t page_size, flags; - int mode; - DB_FH **fhpp; -{ - DB_FH *fhp; - DWORD cluster_size, sector_size, free_clusters, total_clusters; - int access, attr, createflag, nrepeat, oflags, ret, share; - _TCHAR *drive, *tname; - _TCHAR dbuf[4]; /* <letter><colon><slash><nul> */ - - fhp = NULL; - tname = NULL; - -#define OKFLAGS \ - (DB_OSO_ABSMODE | DB_OSO_CREATE | DB_OSO_DIRECT | DB_OSO_DSYNC |\ - DB_OSO_EXCL | DB_OSO_RDONLY | DB_OSO_REGION | DB_OSO_SEQ | \ - DB_OSO_TEMP | DB_OSO_TRUNC) - if ((ret = __db_fchk(dbenv, "__os_open", flags, OKFLAGS)) != 0) - return (ret); - - /* - * The "public" interface to the __os_open routine passes around POSIX - * 1003.1 flags, not DB flags. If the user has defined their own open - * interface, use the POSIX flags. - */ - if (DB_GLOBAL(j_open) != NULL) { - oflags = O_BINARY | O_NOINHERIT; - - if (LF_ISSET(DB_OSO_CREATE)) - oflags |= O_CREAT; -#ifdef O_DSYNC - if (LF_ISSET(DB_OSO_DSYNC)) - oflags |= O_DSYNC; -#endif - - if (LF_ISSET(DB_OSO_EXCL)) - oflags |= O_EXCL; - - if (LF_ISSET(DB_OSO_RDONLY)) - oflags |= O_RDONLY; - else - oflags |= O_RDWR; - - if (LF_ISSET(DB_OSO_SEQ)) - oflags |= _O_SEQUENTIAL; - else - oflags |= _O_RANDOM; - - if (LF_ISSET(DB_OSO_TEMP)) - oflags |= _O_TEMPORARY; - - if (LF_ISSET(DB_OSO_TRUNC)) - oflags |= O_TRUNC; - - return (__os_openhandle(dbenv, name, oflags, mode, fhpp)); - } - - TO_TSTRING(dbenv, name, tname, ret); - if (ret != 0) - goto err; - - if ((ret = __os_calloc(dbenv, 1, sizeof(DB_FH), &fhp)) != 0) - goto err; - - /* - * Otherwise, use the Windows/32 CreateFile interface so that we can - * play magic games with files to get data flush effects similar to - * the POSIX O_DSYNC flag. - * - * !!! - * We currently ignore the 'mode' argument. It would be possible - * to construct a set of security attributes that we could pass to - * CreateFile that would accurately represents the mode. In worst - * case, this would require looking up user and all group names and - * creating an entry for each. Alternatively, we could call the - * _chmod (partial emulation) function after file creation, although - * this leaves us with an obvious race. However, these efforts are - * largely meaningless on FAT, the most common file system, which - * only has a "readable" and "writeable" flag, applying to all users. - */ - access = GENERIC_READ; - if (!LF_ISSET(DB_OSO_RDONLY)) - access |= GENERIC_WRITE; - - share = FILE_SHARE_READ | FILE_SHARE_WRITE; - if (__os_is_winnt()) - share |= FILE_SHARE_DELETE; - attr = FILE_ATTRIBUTE_NORMAL; - - /* - * Reproduce POSIX 1003.1 semantics: if O_CREATE and O_EXCL are both - * specified, fail, returning EEXIST, unless we create the file. - */ - if (LF_ISSET(DB_OSO_CREATE) && LF_ISSET(DB_OSO_EXCL)) - createflag = CREATE_NEW; /* create only if !exist*/ - else if (!LF_ISSET(DB_OSO_CREATE) && LF_ISSET(DB_OSO_TRUNC)) - createflag = TRUNCATE_EXISTING; /* truncate, fail if !exist */ - else if (LF_ISSET(DB_OSO_TRUNC)) - createflag = CREATE_ALWAYS; /* create and truncate */ - else if (LF_ISSET(DB_OSO_CREATE)) - createflag = OPEN_ALWAYS; /* open or create */ - else - createflag = OPEN_EXISTING; /* open only if existing */ - - if (LF_ISSET(DB_OSO_DSYNC)) { - F_SET(fhp, DB_FH_NOSYNC); - attr |= FILE_FLAG_WRITE_THROUGH; - } - - if (LF_ISSET(DB_OSO_SEQ)) - attr |= FILE_FLAG_SEQUENTIAL_SCAN; - else - attr |= FILE_FLAG_RANDOM_ACCESS; - - if (LF_ISSET(DB_OSO_TEMP)) - attr |= FILE_FLAG_DELETE_ON_CLOSE; - - /* - * We can turn filesystem buffering off if the page size is a - * multiple of the disk's sector size. To find the sector size, - * we call GetDiskFreeSpace, which expects a drive name like "d:\\" - * or NULL for the current disk (i.e., a relative path) - */ - if (LF_ISSET(DB_OSO_DIRECT) && page_size != 0 && name[0] != '\0') { - if (name[1] == ':') { - drive = dbuf; - _sntprintf(dbuf, sizeof(dbuf), _T("%c:\\"), tname[0]); - } else - drive = NULL; - - /* - * We ignore all results except sectorsize, but some versions - * of Windows require that the parameters are non-NULL. - */ - if (GetDiskFreeSpace(drive, &cluster_size, - §or_size, &free_clusters, &total_clusters) && - page_size % sector_size == 0) - attr |= FILE_FLAG_NO_BUFFERING; - } - - for (nrepeat = 1;; ++nrepeat) { - fhp->handle = - CreateFile(tname, access, share, NULL, createflag, attr, 0); - if (fhp->handle == INVALID_HANDLE_VALUE) { - /* - * If it's a "temporary" error, we retry up to 3 times, - * waiting up to 12 seconds. While it's not a problem - * if we can't open a database, an inability to open a - * log file is cause for serious dismay. - */ - ret = __os_get_errno(); - if ((ret != ENFILE && ret != EMFILE && ret != ENOSPC) || - nrepeat > 3) - goto err; - - __os_sleep(dbenv, nrepeat * 2, 0); - } else - break; - } - - FREE_STRING(dbenv, tname); - - F_SET(fhp, DB_FH_OPENED); - *fhpp = fhp; - return (0); - -err: if (ret == 0) - ret = __os_get_errno(); - - FREE_STRING(dbenv, tname); - if (fhp != NULL) - (void)__os_closehandle(dbenv, fhp); - return (ret); -} diff --git a/storage/bdb/os_win32/os_rename.c b/storage/bdb/os_win32/os_rename.c deleted file mode 100644 index 0d6d1783588..00000000000 --- a/storage/bdb/os_win32/os_rename.c +++ /dev/null @@ -1,72 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_rename.c,v 12.1 2005/06/16 20:23:30 bostic Exp $ - */ - -#include "db_config.h" - -#include "db_int.h" - -/* - * __os_rename -- - * Rename a file. - */ -int -__os_rename(dbenv, oldname, newname, flags) - DB_ENV *dbenv; - const char *oldname, *newname; - u_int32_t flags; -{ - int ret; - _TCHAR *toldname, *tnewname; - - ret = 0; - if (DB_GLOBAL(j_rename) != NULL) { - if (DB_GLOBAL(j_rename)(oldname, newname) == -1) - ret = __os_get_errno(); - goto done; - } - - TO_TSTRING(dbenv, oldname, toldname, ret); - if (ret != 0) - goto done; - TO_TSTRING(dbenv, newname, tnewname, ret); - if (ret != 0) - goto err; - - if (!MoveFile(toldname, tnewname)) - ret = __os_get_errno(); - - if (ret == EEXIST) { - ret = 0; - if (__os_is_winnt()) { - if (!MoveFileEx( - toldname, tnewname, MOVEFILE_REPLACE_EXISTING)) - ret = __os_get_errno(); - } else { - /* - * There is no MoveFileEx for Win9x/Me, so we have to - * do the best we can. Note that the MoveFile call - * above would have succeeded if oldname and newname - * refer to the same file, so we don't need to check - * that here. - */ - (void)DeleteFile(tnewname); - if (!MoveFile(toldname, tnewname)) - ret = __os_get_errno(); - } - } - - FREE_STRING(dbenv, tnewname); -err: FREE_STRING(dbenv, toldname); - -done: if (ret != 0 && flags == 0) - __db_err(dbenv, - "Rename %s %s: %s", oldname, newname, strerror(ret)); - - return (ret); -} diff --git a/storage/bdb/os_win32/os_rw.c b/storage/bdb/os_win32/os_rw.c deleted file mode 100644 index 394ce029eb8..00000000000 --- a/storage/bdb/os_win32/os_rw.c +++ /dev/null @@ -1,303 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_rw.c,v 12.4 2005/08/10 15:47:28 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" - -#ifdef HAVE_FILESYSTEM_NOTZERO -static int __os_zerofill __P((DB_ENV *, DB_FH *)); -#endif -static int __os_physwrite __P((DB_ENV *, DB_FH *, void *, size_t, size_t *)); - -/* - * __os_io -- - * Do an I/O. - */ -int -__os_io(dbenv, op, fhp, pgno, pagesize, buf, niop) - DB_ENV *dbenv; - int op; - DB_FH *fhp; - db_pgno_t pgno; - u_int32_t pagesize; - u_int8_t *buf; - size_t *niop; -{ - int ret; - - if (__os_is_winnt()) { - ULONG64 off = (ULONG64)pagesize * pgno; - OVERLAPPED over; - DWORD nbytes; - over.Offset = (DWORD)(off & 0xffffffff); - over.OffsetHigh = (DWORD)(off >> 32); - over.hEvent = 0; /* we don't want asynchronous notifications */ - - switch (op) { - case DB_IO_READ: - if (DB_GLOBAL(j_read) != NULL) - goto slow; - if (!ReadFile(fhp->handle, - buf, (DWORD)pagesize, &nbytes, &over)) - goto slow; - break; - case DB_IO_WRITE: - if (DB_GLOBAL(j_write) != NULL) - goto slow; -#ifdef HAVE_FILESYSTEM_NOTZERO - if (__os_fs_notzero()) - goto slow; -#endif - if (!WriteFile(fhp->handle, - buf, (DWORD)pagesize, &nbytes, &over)) - goto slow; - break; - } - if (nbytes == pagesize) { - *niop = (size_t)nbytes; - return (0); - } - } - -slow: MUTEX_LOCK(dbenv, fhp->mtx_fh); - - if ((ret = __os_seek(dbenv, fhp, - pagesize, pgno, 0, 0, DB_OS_SEEK_SET)) != 0) - goto err; - - switch (op) { - case DB_IO_READ: - ret = __os_read(dbenv, fhp, buf, pagesize, niop); - break; - case DB_IO_WRITE: - ret = __os_write(dbenv, fhp, buf, pagesize, niop); - break; - } - -err: MUTEX_UNLOCK(dbenv, fhp->mtx_fh); - - return (ret); -} - -/* - * __os_read -- - * Read from a file handle. - */ -int -__os_read(dbenv, fhp, addr, len, nrp) - DB_ENV *dbenv; - DB_FH *fhp; - void *addr; - size_t len; - size_t *nrp; -{ - size_t offset, nr; - DWORD count; - int ret; - u_int8_t *taddr; - - ret = 0; - - if (DB_GLOBAL(j_read) != NULL) { - *nrp = len; - if (DB_GLOBAL(j_read)(fhp->fd, addr, len) != (ssize_t)len) { - ret = __os_get_errno(); - __db_err(dbenv, "read: %#lx, %lu: %s", - P_TO_ULONG(addr), (u_long)len, strerror(ret)); - } - return (ret); - } - - ret = 0; - for (taddr = addr, - offset = 0; offset < len; taddr += nr, offset += nr) { - RETRY_CHK((!ReadFile(fhp->handle, - taddr, (DWORD)(len - offset), &count, NULL)), ret); - if (count == 0 || ret != 0) - break; - nr = (size_t)count; - } - *nrp = taddr - (u_int8_t *)addr; - if (ret != 0) - __db_err(dbenv, "read: 0x%lx, %lu: %s", - P_TO_ULONG(taddr), (u_long)len - offset, strerror(ret)); - return (ret); -} - -/* - * __os_write -- - * Write to a file handle. - */ -int -__os_write(dbenv, fhp, addr, len, nwp) - DB_ENV *dbenv; - DB_FH *fhp; - void *addr; - size_t len; - size_t *nwp; -{ - int ret; - -#ifdef HAVE_FILESYSTEM_NOTZERO - /* Zero-fill as necessary. */ - if (__os_fs_notzero() && (ret = __os_zerofill(dbenv, fhp)) != 0) - return (ret); -#endif - return (__os_physwrite(dbenv, fhp, addr, len, nwp)); -} - -/* - * __os_physwrite -- - * Physical write to a file handle. - */ -static int -__os_physwrite(dbenv, fhp, addr, len, nwp) - DB_ENV *dbenv; - DB_FH *fhp; - void *addr; - size_t len; - size_t *nwp; -{ - size_t offset, nw; - DWORD count; - int ret; - u_int8_t *taddr; - - /* - * Make a last "panic" check. Imagine a thread of control running in - * Berkeley DB, going to sleep. Another thread of control decides to - * run recovery because the environment is broken. The first thing - * recovery does is panic the existing environment, but we only check - * the panic flag when crossing the public API. If the sleeping thread - * wakes up and writes something, we could have two threads of control - * writing the log files at the same time. So, before writing, make a - * last panic check. Obviously, there's still a window, but it's very, - * very small. - */ - PANIC_CHECK(dbenv); - - if (DB_GLOBAL(j_write) != NULL) { - *nwp = len; - if (DB_GLOBAL(j_write)(fhp->fd, addr, len) != (ssize_t)len) { - ret = __os_get_errno(); - __db_err(dbenv, "write: %#lx, %lu: %s", - P_TO_ULONG(addr), (u_long)len, strerror(ret)); - } - return (ret); - } - - ret = 0; - for (taddr = addr, - offset = 0; offset < len; taddr += nw, offset += nw) { - RETRY_CHK((!WriteFile(fhp->handle, - taddr, (DWORD)(len - offset), &count, NULL)), ret); - if (ret != 0) - break; - nw = (size_t)count; - } - *nwp = len; - if (ret != 0) - __db_err(dbenv, "write: %#lx, %lu: %s", - P_TO_ULONG(taddr), (u_long)len - offset, strerror(ret)); - return (ret); -} - -#ifdef HAVE_FILESYSTEM_NOTZERO -/* - * __os_zerofill -- - * Zero out bytes in the file. - * - * Pages allocated by writing pages past end-of-file are not zeroed, - * on some systems. Recovery could theoretically be fooled by a page - * showing up that contained garbage. In order to avoid this, we - * have to write the pages out to disk, and flush them. The reason - * for the flush is because if we don't sync, the allocation of another - * page subsequent to this one might reach the disk first, and if we - * crashed at the right moment, leave us with this page as the one - * allocated by writing a page past it in the file. - */ -static int -__os_zerofill(dbenv, fhp) - DB_ENV *dbenv; - DB_FH *fhp; -{ - unsigned __int64 stat_offset, write_offset; - size_t blen, nw; - u_int32_t bytes, mbytes; - int group_sync, need_free, ret; - u_int8_t buf[8 * 1024], *bp; - - /* Calculate the byte offset of the next write. */ - write_offset = (unsigned __int64)fhp->pgno * fhp->pgsize + fhp->offset; - - /* Stat the file. */ - if ((ret = __os_ioinfo(dbenv, NULL, fhp, &mbytes, &bytes, NULL)) != 0) - return (ret); - stat_offset = (unsigned __int64)mbytes * MEGABYTE + bytes; - - /* Check if the file is large enough. */ - if (stat_offset >= write_offset) - return (0); - - /* Get a large buffer if we're writing lots of data. */ -#undef ZF_LARGE_WRITE -#define ZF_LARGE_WRITE (64 * 1024) - if (write_offset - stat_offset > ZF_LARGE_WRITE) { - if ((ret = __os_calloc(dbenv, 1, ZF_LARGE_WRITE, &bp)) != 0) - return (ret); - blen = ZF_LARGE_WRITE; - need_free = 1; - } else { - bp = buf; - blen = sizeof(buf); - need_free = 0; - memset(buf, 0, sizeof(buf)); - } - - /* Seek to the current end of the file. */ - if ((ret = __os_seek( - dbenv, fhp, MEGABYTE, mbytes, bytes, 0, DB_OS_SEEK_SET)) != 0) - goto err; - - /* - * Hash is the only access method that allocates groups of pages. Hash - * uses the existence of the last page in a group to signify the entire - * group is OK; so, write all the pages but the last one in the group, - * flush them to disk, then write the last one to disk and flush it. - */ - for (group_sync = 0; stat_offset < write_offset; group_sync = 1) { - if (write_offset - stat_offset <= blen) { - blen = (size_t)(write_offset - stat_offset); - if (group_sync && (ret = __os_fsync(dbenv, fhp)) != 0) - goto err; - } - if ((ret = __os_physwrite(dbenv, fhp, bp, blen, &nw)) != 0) - goto err; - stat_offset += blen; - } - if ((ret = __os_fsync(dbenv, fhp)) != 0) - goto err; - - /* Seek back to where we started. */ - mbytes = (u_int32_t)(write_offset / MEGABYTE); - bytes = (u_int32_t)(write_offset % MEGABYTE); - ret = __os_seek(dbenv, fhp, MEGABYTE, mbytes, bytes, 0, DB_OS_SEEK_SET); - -err: if (need_free) - __os_free(dbenv, bp); - return (ret); -} -#endif diff --git a/storage/bdb/os_win32/os_seek.c b/storage/bdb/os_win32/os_seek.c deleted file mode 100644 index 38e86ba032d..00000000000 --- a/storage/bdb/os_win32/os_seek.c +++ /dev/null @@ -1,92 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_seek.c,v 12.1 2005/06/16 20:23:30 bostic Exp $ - */ - -#include "db_config.h" - -#include "db_int.h" - -/* - * __os_seek -- - * Seek to a page/byte offset in the file. - */ -int -__os_seek(dbenv, fhp, pgsize, pageno, relative, isrewind, db_whence) - DB_ENV *dbenv; - DB_FH *fhp; - u_int32_t pgsize; - db_pgno_t pageno; - u_int32_t relative; - int isrewind; - DB_OS_SEEK db_whence; -{ - /* Yes, this really is how Microsoft have designed their API */ - union { - __int64 bigint; - struct { - unsigned long low; - long high; - }; - } offbytes; - off_t offset; - int ret, whence; - DWORD from; - - offset = (off_t)pgsize * pageno + relative; - if (isrewind) - offset = -offset; - - if (DB_GLOBAL(j_seek) != NULL) { - switch (db_whence) { - case DB_OS_SEEK_CUR: - whence = SEEK_CUR; - break; - case DB_OS_SEEK_END: - whence = SEEK_END; - break; - case DB_OS_SEEK_SET: - whence = SEEK_SET; - break; - default: - return (EINVAL); - } - - ret = DB_GLOBAL(j_seek)(fhp->fd, offset, whence); - } else { - switch (db_whence) { - case DB_OS_SEEK_CUR: - from = FILE_CURRENT; - break; - case DB_OS_SEEK_END: - from = FILE_END; - break; - case DB_OS_SEEK_SET: - from = FILE_BEGIN; - break; - default: - return (EINVAL); - } - - offbytes.bigint = offset; - ret = (SetFilePointer(fhp->handle, - offbytes.low, &offbytes.high, from) == (DWORD) - 1) ? - __os_get_errno() : 0; - } - - if (ret == 0) { - fhp->pgsize = pgsize; - fhp->pgno = pageno; - fhp->offset = relative; - } else { - __db_err(dbenv, "seek: %lu %d %d: %s", - (u_long)pgsize * pageno + relative, - isrewind, db_whence, strerror(ret)); - } - - return (ret); -} diff --git a/storage/bdb/os_win32/os_sleep.c b/storage/bdb/os_win32/os_sleep.c deleted file mode 100644 index 4baffe44c11..00000000000 --- a/storage/bdb/os_win32/os_sleep.c +++ /dev/null @@ -1,39 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_sleep.c,v 12.1 2005/06/16 20:23:30 bostic Exp $ - */ - -#include "db_config.h" - -#include "db_int.h" - -/* - * __os_sleep -- - * Yield the processor for a period of time. - */ -void -__os_sleep(dbenv, secs, usecs) - DB_ENV *dbenv; - u_long secs, usecs; /* Seconds and microseconds. */ -{ - COMPQUIET(dbenv, NULL); - - /* Don't require that the values be normalized. */ - for (; usecs >= 1000000; ++secs, usecs -= 1000000) - ; - - if (DB_GLOBAL(j_sleep) != NULL) { - DB_GLOBAL(j_sleep)(secs, usecs); - return; - } - - /* - * It's important that we yield the processor here so that other - * processes or threads are permitted to run. - */ - Sleep(secs * 1000 + usecs / 1000); -} diff --git a/storage/bdb/os_win32/os_spin.c b/storage/bdb/os_win32/os_spin.c deleted file mode 100644 index 53657fc897d..00000000000 --- a/storage/bdb/os_win32/os_spin.c +++ /dev/null @@ -1,52 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_spin.c,v 12.2 2005/07/20 16:52:02 bostic Exp $ - */ - -#include "db_config.h" - -#include "db_int.h" - -/* - * __os_spin -- - * Return the number of default spins before blocking. - */ -u_int32_t -__os_spin(dbenv) - DB_ENV *dbenv; -{ - SYSTEM_INFO SystemInfo; - u_int32_t tas_spins; - - /* Get the number of processors */ - GetSystemInfo(&SystemInfo); - - /* - * Spin 50 times per processor -- we have anecdotal evidence that this - * is a reasonable value. - */ - if (SystemInfo.dwNumberOfProcessors > 1) - tas_spins = 50 * SystemInfo.dwNumberOfProcessors; - else - tas_spins = 1; - - return (tas_spins); -} - -/* - * __os_yield -- - * Yield the processor. - */ -void -__os_yield(dbenv, usecs) - DB_ENV *dbenv; - u_long usecs; -{ - if (DB_GLOBAL(j_yield) != NULL && DB_GLOBAL(j_yield)() == 0) - return; - __os_sleep(dbenv, 0, usecs); -} diff --git a/storage/bdb/os_win32/os_stat.c b/storage/bdb/os_win32/os_stat.c deleted file mode 100644 index e4209f7d87d..00000000000 --- a/storage/bdb/os_win32/os_stat.c +++ /dev/null @@ -1,96 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_stat.c,v 12.1 2005/06/16 20:23:31 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#include <sys/stat.h> - -#include <string.h> -#endif - -#include "db_int.h" - -/* - * __os_exists -- - * Return if the file exists. - */ -int -__os_exists(path, isdirp) - const char *path; - int *isdirp; -{ - int ret; - DWORD attrs; - _TCHAR *tpath; - - if (DB_GLOBAL(j_exists) != NULL) - return (DB_GLOBAL(j_exists)(path, isdirp)); - - TO_TSTRING(NULL, path, tpath, ret); - if (ret != 0) - return (ret); - - RETRY_CHK( - ((attrs = GetFileAttributes(tpath)) == (DWORD)-1 ? 1 : 0), ret); - - if (ret == 0 && isdirp != NULL) - *isdirp = (attrs & FILE_ATTRIBUTE_DIRECTORY); - - FREE_STRING(NULL, tpath); - return (ret); -} - -/* - * __os_ioinfo -- - * Return file size and I/O size; abstracted to make it easier - * to replace. - */ -int -__os_ioinfo(dbenv, path, fhp, mbytesp, bytesp, iosizep) - DB_ENV *dbenv; - const char *path; - DB_FH *fhp; - u_int32_t *mbytesp, *bytesp, *iosizep; -{ - int ret; - BY_HANDLE_FILE_INFORMATION bhfi; - unsigned __int64 filesize; - - if (DB_GLOBAL(j_ioinfo) != NULL) - return (DB_GLOBAL(j_ioinfo)(path, - fhp->fd, mbytesp, bytesp, iosizep)); - - RETRY_CHK((!GetFileInformationByHandle(fhp->handle, &bhfi)), ret); - if (ret != 0) { - __db_err(dbenv, - "GetFileInformationByHandle: %s", strerror(ret)); - return (ret); - } - - filesize = ((unsigned __int64)bhfi.nFileSizeHigh << 32) + - bhfi.nFileSizeLow; - - /* Return the size of the file. */ - if (mbytesp != NULL) - *mbytesp = (u_int32_t)(filesize / MEGABYTE); - if (bytesp != NULL) - *bytesp = (u_int32_t)(filesize % MEGABYTE); - - /* - * The filesystem blocksize is not easily available. In particular, - * the values returned by GetDiskFreeSpace() are not very helpful - * (NTFS volumes often report 512B clusters, which are too small to - * be a useful default). - */ - if (iosizep != NULL) - *iosizep = DB_DEF_IOSIZE; - return (0); -} diff --git a/storage/bdb/os_win32/os_truncate.c b/storage/bdb/os_win32/os_truncate.c deleted file mode 100644 index e36a393a328..00000000000 --- a/storage/bdb/os_win32/os_truncate.c +++ /dev/null @@ -1,93 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2004-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_truncate.c,v 12.4 2005/10/12 17:57:33 bostic Exp $ - */ - -#include "db_config.h" - -#include "db_int.h" - -/* - * __os_truncate -- - * Truncate the file. - */ -int -__os_truncate(dbenv, fhp, pgno, pgsize) - DB_ENV *dbenv; - DB_FH *fhp; - db_pgno_t pgno; - u_int32_t pgsize; -{ - /* Yes, this really is how Microsoft have designed their API */ - union { - __int64 bigint; - struct { - unsigned long low; - long high; - }; - } off; - off_t offset; - HANDLE dup_handle; - int ret; - - ret = 0; - offset = (off_t)pgsize * pgno; - - if (DB_GLOBAL(j_ftruncate) != NULL) { - ret = DB_GLOBAL(j_ftruncate)(fhp->fd, offset); - goto done; - } - -#ifdef HAVE_FILESYSTEM_NOTZERO - /* - * If the filesystem doesn't zero fill, it isn't safe to extend the - * file, or we end up with junk blocks. Just return in that case. - */ - if (__os_fs_notzero()) { - off_t stat_offset; - u_int32_t mbytes, bytes; - - /* Stat the file. */ - if ((ret = - __os_ioinfo(dbenv, NULL, fhp, &mbytes, &bytes, NULL)) != 0) - return (ret); - stat_offset = (off_t)mbytes * MEGABYTE + bytes; - - if (offset > stat_offset) - return (0); - } -#endif - - /* - * Windows doesn't provide truncate directly. Instead, it has - * SetEndOfFile, which truncates to the current position. To - * deal with that, we first duplicate the file handle, then - * seek and set the end of file. This is necessary to avoid - * races with {Read,Write}File in other threads. - */ - if (!DuplicateHandle(GetCurrentProcess(), fhp->handle, - GetCurrentProcess(), &dup_handle, 0, FALSE, - DUPLICATE_SAME_ACCESS)) { - ret = __os_get_errno(); - goto done; - } - - off.bigint = (__int64)pgsize * pgno; - RETRY_CHK((SetFilePointer(dup_handle, - off.low, &off.high, FILE_BEGIN) == INVALID_SET_FILE_POINTER && - GetLastError() != NO_ERROR) || - !SetEndOfFile(dup_handle), ret); - - if (!CloseHandle(dup_handle) && ret == 0) - ret = __os_get_errno(); - -done: if (ret != 0) - __db_err(dbenv, - "ftruncate: %lu: %s", pgno * pgsize, strerror(ret)); - - return (ret); -} diff --git a/storage/bdb/os_win32/os_type.c b/storage/bdb/os_win32/os_type.c deleted file mode 100644 index 583da0aaf1e..00000000000 --- a/storage/bdb/os_win32/os_type.c +++ /dev/null @@ -1,36 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1998-2002 - * Sleepycat Software. All rights reserved. - */ - -#include "db_config.h" - -#ifndef lint -static const char revid[] = "$Id: os_type.c,v 11.6 2002/01/11 15:53:08 bostic Exp $"; -#endif /* not lint */ - -/* - * __os_is_winnt -- - * Return 1 if Windows/NT, otherwise 0. - * - * PUBLIC: int __os_is_winnt __P((void)); - */ -int -__os_is_winnt() -{ - static int __os_type = -1; - - /* - * The value of __os_type is computed only once, and cached to - * avoid the overhead of repeated calls to GetVersion(). - */ - if (__os_type == -1) { - if ((GetVersion() & 0x80000000) == 0) - __os_type = 1; - else - __os_type = 0; - } - return (__os_type); -} diff --git a/storage/bdb/os_win32/os_unlink.c b/storage/bdb/os_win32/os_unlink.c deleted file mode 100644 index 81e72d744d9..00000000000 --- a/storage/bdb/os_win32/os_unlink.c +++ /dev/null @@ -1,115 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: os_unlink.c,v 12.7 2005/10/20 18:57:08 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" - -/* - * __os_region_unlink -- - * Remove a shared memory object file. - */ -int -__os_region_unlink(dbenv, path) - DB_ENV *dbenv; - const char *path; -{ - if (F_ISSET(dbenv, DB_ENV_OVERWRITE)) - (void)__db_file_multi_write(dbenv, path); - - return (__os_unlink(dbenv, path)); -} - -/* - * __os_unlink -- - * Remove a file. - * - * PUBLIC: int __os_unlink __P((DB_ENV *, const char *)); - */ -int -__os_unlink(dbenv, path) - DB_ENV *dbenv; - const char *path; -{ - HANDLE h; - _TCHAR *tpath, *orig_tpath, buf[MAXPATHLEN]; - u_int32_t id; - int ret; - - if (DB_GLOBAL(j_unlink) != NULL) { - ret = DB_GLOBAL(j_unlink)(path); - goto done; - } - - TO_TSTRING(dbenv, path, tpath, ret); - if (ret != 0) - return (ret); - orig_tpath = tpath; - - /* - * Windows NT and its descendents allow removal of open files, but the - * DeleteFile Win32 system call isn't equivalent to a POSIX unlink. - * Firstly, it only succeeds if FILE_SHARE_DELETE is set when the file - * is opened. Secondly, it leaves the file in a "zombie" state, where - * it can't be opened again, but a new file with the same name can't be - * created either. - * - * Since we depend on being able to recreate files (during recovery, - * say), we have to first rename the file, and then delete it. It - * still hangs around, but with a name we don't care about. The rename - * will fail if the file doesn't exist, which isn't a problem, but if - * it fails for some other reason, we need to know about it or a - * subsequent open may fail for no apparent reason. - */ - if (__os_is_winnt()) { - __os_unique_id(dbenv, &id); - _sntprintf(buf, MAXPATHLEN, _T("%s.del.%010u"), tpath, id); - if (MoveFile(tpath, buf)) - tpath = buf; - else if (__os_get_errno() != ENOENT) - __db_err(dbenv, - "unlink: rename %s to temporary file failed", path); - - /* - * Try removing the file using the delete-on-close flag. This - * plays nicer with files that are still open than DeleteFile. - */ - h = CreateFile(tpath, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, - FILE_FLAG_DELETE_ON_CLOSE, 0); - if (h != INVALID_HANDLE_VALUE) { - (void)CloseHandle (h); - if (GetFileAttributes(tpath) == INVALID_FILE_ATTRIBUTES) - goto skipdel; - } - } - - RETRY_CHK((!DeleteFile(tpath)), ret); - -skipdel: - FREE_STRING(dbenv, orig_tpath); - - /* - * XXX - * We shouldn't be testing for an errno of ENOENT here, but ENOENT - * signals that a file is missing, and we attempt to unlink things - * (such as v. 2.x environment regions, in DB_ENV->remove) that we - * are expecting not to be there. Reporting errors in these cases - * is annoying. - */ -done: if (ret != 0 && ret != ENOENT) - __db_err(dbenv, "unlink: %s: %s", path, strerror(ret)); - - return (ret); -} diff --git a/storage/bdb/qam/qam.c b/storage/bdb/qam/qam.c deleted file mode 100644 index 778e3e6e07a..00000000000 --- a/storage/bdb/qam/qam.c +++ /dev/null @@ -1,1716 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: qam.c,v 12.12 2005/10/05 17:16:46 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/btree.h" -#include "dbinc/lock.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" -#include "dbinc/qam.h" - -static int __qam_bulk __P((DBC *, DBT *, u_int32_t)); -static int __qam_c_close __P((DBC *, db_pgno_t, int *)); -static int __qam_c_del __P((DBC *)); -static int __qam_c_destroy __P((DBC *)); -static int __qam_c_get __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *)); -static int __qam_c_put __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *)); -static int __qam_consume __P((DBC *, QMETA *, db_recno_t)); -static int __qam_getno __P((DB *, const DBT *, db_recno_t *)); - -/* - * __qam_position -- - * Position a queued access method cursor at a record. This returns - * the page locked. *exactp will be set if the record is valid. - * PUBLIC: int __qam_position - * PUBLIC: __P((DBC *, db_recno_t *, qam_position_mode, int *)); - */ -int -__qam_position(dbc, recnop, mode, exactp) - DBC *dbc; /* open cursor */ - db_recno_t *recnop; /* pointer to recno to find */ - qam_position_mode mode;/* locking: read or write */ - int *exactp; /* indicate if it was found */ -{ - QUEUE_CURSOR *cp; - DB *dbp; - QAMDATA *qp; - db_pgno_t pg; - int ret, t_ret; - - dbp = dbc->dbp; - cp = (QUEUE_CURSOR *)dbc->internal; - - /* Fetch the page for this recno. */ - pg = QAM_RECNO_PAGE(dbp, *recnop); - - if ((ret = __db_lget(dbc, 0, pg, mode == QAM_READ ? - DB_LOCK_READ : DB_LOCK_WRITE, 0, &cp->lock)) != 0) - return (ret); - cp->page = NULL; - *exactp = 0; - if ((ret = __qam_fget(dbp, &pg, - mode == QAM_WRITE ? DB_MPOOL_CREATE : 0, &cp->page)) != 0) { - if (mode != QAM_WRITE && - (ret == DB_PAGE_NOTFOUND || ret == ENOENT)) - ret = 0; - - /* We did not fetch it, we can release the lock. */ - if ((t_ret = __LPUT(dbc, cp->lock)) != 0 && ret == 0) - ret = t_ret; - return (ret); - } - cp->pgno = pg; - cp->indx = QAM_RECNO_INDEX(dbp, pg, *recnop); - - if (PGNO(cp->page) == 0) { - if (F_ISSET(dbp, DB_AM_RDONLY)) { - *exactp = 0; - return (0); - } - PGNO(cp->page) = pg; - TYPE(cp->page) = P_QAMDATA; - } - - qp = QAM_GET_RECORD(dbp, cp->page, cp->indx); - *exactp = F_ISSET(qp, QAM_VALID) ? 1 : 0; - - return (ret); -} - -/* - * __qam_pitem -- - * Put an item on a queue page. Copy the data to the page and set the - * VALID and SET bits. If logging and the record was previously set, - * log that data, otherwise just log the new data. - * - * pagep must be write locked - * - * PUBLIC: int __qam_pitem - * PUBLIC: __P((DBC *, QPAGE *, u_int32_t, db_recno_t, DBT *)); - */ -int -__qam_pitem(dbc, pagep, indx, recno, data) - DBC *dbc; - QPAGE *pagep; - u_int32_t indx; - db_recno_t recno; - DBT *data; -{ - DB_ENV *dbenv; - DB *dbp; - DBT olddata, pdata, *datap; - QAMDATA *qp; - QUEUE *t; - u_int8_t *dest, *p; - int allocated, ret; - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - t = (QUEUE *)dbp->q_internal; - allocated = ret = 0; - - if (data->size > t->re_len) - return (__db_rec_toobig(dbenv, data->size, t->re_len)); - qp = QAM_GET_RECORD(dbp, pagep, indx); - - p = qp->data; - datap = data; - if (F_ISSET(data, DB_DBT_PARTIAL)) { - if (data->doff + data->dlen > t->re_len) { - __db_err(dbenv, - "%s: data offset plus length larger than record size of %lu", - "Record length error", (u_long)t->re_len); - return (EINVAL); - } - - if (data->size != data->dlen) - return (__db_rec_repl(dbenv, data->size, data->dlen)); - - if (data->size == t->re_len) - goto no_partial; - - /* - * If we are logging, then we have to build the record - * first, otherwise, we can simply drop the change - * directly on the page. After this clause, make - * sure that datap and p are set up correctly so that - * copying datap into p does the right thing. - * - * Note, I am changing this so that if the existing - * record is not valid, we create a complete record - * to log so that both this and the recovery code is simpler. - */ - - if (DBC_LOGGING(dbc) || !F_ISSET(qp, QAM_VALID)) { - datap = &pdata; - memset(datap, 0, sizeof(*datap)); - - if ((ret = __os_malloc(dbenv, - t->re_len, &datap->data)) != 0) - return (ret); - allocated = 1; - datap->size = t->re_len; - - /* - * Construct the record if it's valid, otherwise set it - * all to the pad character. - */ - dest = datap->data; - if (F_ISSET(qp, QAM_VALID)) - memcpy(dest, p, t->re_len); - else - memset(dest, (int)t->re_pad, t->re_len); - - dest += data->doff; - memcpy(dest, data->data, data->size); - } else { - datap = data; - p += data->doff; - } - } - -no_partial: - if (DBC_LOGGING(dbc)) { - olddata.size = 0; - if (F_ISSET(qp, QAM_SET)) { - olddata.data = qp->data; - olddata.size = t->re_len; - } - if ((ret = __qam_add_log(dbp, dbc->txn, &LSN(pagep), - 0, &LSN(pagep), pagep->pgno, - indx, recno, datap, qp->flags, - olddata.size == 0 ? NULL : &olddata)) != 0) - goto err; - } - - F_SET(qp, QAM_VALID | QAM_SET); - memcpy(p, datap->data, datap->size); - if (!F_ISSET(data, DB_DBT_PARTIAL)) - memset(p + datap->size, - (int)t->re_pad, t->re_len - datap->size); - -err: if (allocated) - __os_free(dbenv, datap->data); - - return (ret); -} -/* - * __qam_c_put - * Cursor put for queued access method. - * BEFORE and AFTER cannot be specified. - */ -static int -__qam_c_put(dbc, key, data, flags, pgnop) - DBC *dbc; - DBT *key, *data; - u_int32_t flags; - db_pgno_t *pgnop; -{ - DB *dbp; - DB_LOCK lock; - DB_MPOOLFILE *mpf; - QMETA *meta; - QUEUE_CURSOR *cp; - db_pgno_t pg; - db_recno_t new_cur, new_first; - u_int32_t opcode; - int exact, ret, t_ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - if (pgnop != NULL) - *pgnop = PGNO_INVALID; - - cp = (QUEUE_CURSOR *)dbc->internal; - - switch (flags) { - case DB_KEYFIRST: - case DB_KEYLAST: - if ((ret = __qam_getno(dbp, key, &cp->recno)) != 0) - return (ret); - /* FALLTHROUGH */ - case DB_CURRENT: - break; - default: - /* The interface shouldn't let anything else through. */ - DB_ASSERT(0); - return (__db_ferr(dbp->dbenv, "DBC->put", 0)); - } - - /* Write lock the record. */ - if ((ret = __db_lget(dbc, LCK_COUPLE, - cp->recno, DB_LOCK_WRITE, DB_LOCK_RECORD, &cp->lock)) != 0) - return (ret); - - lock = cp->lock; - - if ((ret = __qam_position(dbc, &cp->recno, QAM_WRITE, &exact)) != 0) { - /* We could not get the page, we can release the record lock. */ - (void)__LPUT(dbc, lock); - return (ret); - } - - /* Put the item on the page. */ - ret = __qam_pitem(dbc, (QPAGE *)cp->page, cp->indx, cp->recno, data); - - /* Doing record locking, release the page lock */ - if ((t_ret = __LPUT(dbc, cp->lock)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = __qam_fput( - dbp, cp->pgno, cp->page, DB_MPOOL_DIRTY)) != 0 && ret == 0) - ret = t_ret; - cp->page = NULL; - cp->lock = lock; - cp->lock_mode = DB_LOCK_WRITE; - if (ret != 0) - return (ret); - - /* We may need to reset the head or tail of the queue. */ - pg = ((QUEUE *)dbp->q_internal)->q_meta; - - /* - * Get the meta page first, we don't want to write lock it while - * trying to pin it. - */ - if ((ret = __memp_fget(mpf, &pg, 0, &meta)) != 0) - return (ret); - if ((ret = __db_lget(dbc, LCK_COUPLE, - pg, DB_LOCK_WRITE, 0, &cp->lock)) != 0) { - (void)__memp_fput(mpf, meta, 0); - return (ret); - } - - opcode = 0; - new_cur = new_first = 0; - - /* - * If the put address is outside the queue, adjust the head and - * tail of the queue. If the order is inverted we move - * the one which is closer. The first case is when the - * queue is empty, move first and current to where the new - * insert is. - */ - - if (meta->first_recno == meta->cur_recno) { - new_first = cp->recno; - new_cur = cp->recno + 1; - if (new_cur == RECNO_OOB) - new_cur++; - opcode |= QAM_SETFIRST; - opcode |= QAM_SETCUR; - } else { - if (QAM_BEFORE_FIRST(meta, cp->recno) && - (meta->first_recno <= meta->cur_recno || - meta->first_recno - cp->recno < - cp->recno - meta->cur_recno)) { - new_first = cp->recno; - opcode |= QAM_SETFIRST; - } - - if (meta->cur_recno == cp->recno || - (QAM_AFTER_CURRENT(meta, cp->recno) && - (meta->first_recno <= meta->cur_recno || - cp->recno - meta->cur_recno <= - meta->first_recno - cp->recno))) { - new_cur = cp->recno + 1; - if (new_cur == RECNO_OOB) - new_cur++; - opcode |= QAM_SETCUR; - } - } - - if (opcode != 0 && DBC_LOGGING(dbc)) { - ret = __qam_mvptr_log(dbp, dbc->txn, &meta->dbmeta.lsn, - 0, opcode, meta->first_recno, new_first, - meta->cur_recno, new_cur, &meta->dbmeta.lsn, PGNO_BASE_MD); - if (ret != 0) - opcode = 0; - } - - if (opcode & QAM_SETCUR) - meta->cur_recno = new_cur; - if (opcode & QAM_SETFIRST) - meta->first_recno = new_first; - - if ((t_ret = __memp_fput( - mpf, meta, opcode != 0 ? DB_MPOOL_DIRTY : 0)) != 0 && ret == 0) - ret = t_ret; - - /* Don't hold the meta page long term. */ - if ((t_ret = __LPUT(dbc, cp->lock)) != 0 && ret == 0) - ret = t_ret; - return (ret); -} - -/* - * __qam_append -- - * Perform a put(DB_APPEND) in queue. - * - * PUBLIC: int __qam_append __P((DBC *, DBT *, DBT *)); - */ -int -__qam_append(dbc, key, data) - DBC *dbc; - DBT *key, *data; -{ - DB *dbp; - DB_LOCK lock; - DB_MPOOLFILE *mpf; - QMETA *meta; - QPAGE *page; - QUEUE *qp; - QUEUE_CURSOR *cp; - db_pgno_t pg; - db_recno_t recno; - int ret, t_ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - cp = (QUEUE_CURSOR *)dbc->internal; - - pg = ((QUEUE *)dbp->q_internal)->q_meta; - /* - * Get the meta page first, we don't want to write lock it while - * trying to pin it. - */ - if ((ret = __memp_fget(mpf, &pg, 0, &meta)) != 0) - return (ret); - /* Write lock the meta page. */ - if ((ret = __db_lget(dbc, 0, pg, DB_LOCK_WRITE, 0, &lock)) != 0) { - (void)__memp_fput(mpf, meta, 0); - return (ret); - } - - /* Get the next record number. */ - recno = meta->cur_recno; - meta->cur_recno++; - if (meta->cur_recno == RECNO_OOB) - meta->cur_recno++; - if (meta->cur_recno == meta->first_recno) { - meta->cur_recno--; - if (meta->cur_recno == RECNO_OOB) - meta->cur_recno--; - ret = __LPUT(dbc, lock); - - if (ret == 0) - ret = EFBIG; - goto err; - } - - if (QAM_BEFORE_FIRST(meta, recno)) - meta->first_recno = recno; - - /* Lock the record and release meta page lock. */ - ret = __db_lget(dbc, LCK_COUPLE_ALWAYS, - recno, DB_LOCK_WRITE, DB_LOCK_RECORD, &lock); - - /* - * The application may modify the data based on the selected record - * number. We always want to call this even if we ultimately end - * up aborting, because we are allocating a record number, regardless. - */ - if (dbc->dbp->db_append_recno != NULL && - (t_ret = dbc->dbp->db_append_recno(dbc->dbp, data, recno)) != 0 && - ret == 0) - ret = t_ret; - - /* - * Capture errors from either the lock couple or the call to - * dbp->db_append_recno. - */ - if (ret != 0) { - (void)__LPUT(dbc, lock); - goto err; - } - - cp->lock = lock; - cp->lock_mode = DB_LOCK_WRITE; - - pg = QAM_RECNO_PAGE(dbp, recno); - - /* Fetch and write lock the data page. */ - if ((ret = __db_lget(dbc, 0, pg, DB_LOCK_WRITE, 0, &lock)) != 0) - goto err; - if ((ret = __qam_fget(dbp, &pg, DB_MPOOL_CREATE, &page)) != 0) { - /* We did not fetch it, we can release the lock. */ - (void)__LPUT(dbc, lock); - goto err; - } - - /* See if this is a new page. */ - if (page->pgno == 0) { - page->pgno = pg; - page->type = P_QAMDATA; - } - - /* Put the item on the page and log it. */ - ret = __qam_pitem(dbc, page, - QAM_RECNO_INDEX(dbp, pg, recno), recno, data); - - /* Doing record locking, release the page lock */ - if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0) - ret = t_ret; - - if ((t_ret = - __qam_fput(dbp, pg, page, DB_MPOOL_DIRTY)) != 0 && ret == 0) - ret = t_ret; - - /* Return the record number to the user. */ - if (ret == 0) - ret = __db_retcopy(dbp->dbenv, key, - &recno, sizeof(recno), &dbc->rkey->data, &dbc->rkey->ulen); - - /* Position the cursor on this record. */ - cp->recno = recno; - - /* See if we are leaving the extent. */ - qp = (QUEUE *) dbp->q_internal; - if (qp->page_ext != 0 && - (recno % (qp->page_ext * qp->rec_page) == 0 || - recno == UINT32_MAX)) { - if ((ret = __db_lget(dbc, - 0, ((QUEUE *)dbp->q_internal)->q_meta, - DB_LOCK_WRITE, 0, &lock)) != 0) - goto err; - if (!QAM_AFTER_CURRENT(meta, recno)) - ret = __qam_fclose(dbp, pg); - if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0) - ret = t_ret; - } - -err: /* Release the meta page. */ - if ((t_ret = __memp_fput(mpf, meta, DB_MPOOL_DIRTY)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __qam_c_del -- - * Qam cursor->am_del function - */ -static int -__qam_c_del(dbc) - DBC *dbc; -{ - DB *dbp; - DBT data; - DB_LOCK lock, metalock; - DB_MPOOLFILE *mpf; - PAGE *pagep; - QAMDATA *qp; - QMETA *meta; - QUEUE_CURSOR *cp; - db_pgno_t pg; - int exact, ret, t_ret; - - dbp = dbc->dbp; - mpf = dbp->mpf; - cp = (QUEUE_CURSOR *)dbc->internal; - LOCK_INIT(lock); - - pg = ((QUEUE *)dbp->q_internal)->q_meta; - /* - * Get the meta page first, we don't want to write lock it while - * trying to pin it. - */ - if ((ret = __memp_fget(mpf, &pg, 0, &meta)) != 0) - return (ret); - /* Write lock the meta page. */ - if ((ret = __db_lget(dbc, 0, pg, DB_LOCK_READ, 0, &metalock)) != 0) { - (void)__memp_fput(mpf, meta, 0); - return (ret); - } - - if (QAM_NOT_VALID(meta, cp->recno)) - ret = DB_NOTFOUND; - - /* Don't hold the meta page long term. */ - if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0) - ret = t_ret; - - if (ret != 0) - goto err; - - if ((ret = __db_lget(dbc, LCK_COUPLE, - cp->recno, DB_LOCK_WRITE, DB_LOCK_RECORD, &cp->lock)) != 0) - goto err; - cp->lock_mode = DB_LOCK_WRITE; - lock = cp->lock; - - /* Find the record ; delete only deletes exact matches. */ - if ((ret = __qam_position(dbc, &cp->recno, QAM_WRITE, &exact)) != 0) - goto err; - - if (!exact) { - ret = DB_NOTFOUND; - goto err; - } - - pagep = cp->page; - qp = QAM_GET_RECORD(dbp, pagep, cp->indx); - - if (DBC_LOGGING(dbc)) { - if (((QUEUE *)dbp->q_internal)->page_ext == 0 || - ((QUEUE *)dbp->q_internal)->re_len == 0) { - if ((ret = __qam_del_log(dbp, - dbc->txn, &LSN(pagep), 0, &LSN(pagep), - pagep->pgno, cp->indx, cp->recno)) != 0) - goto err; - } else { - data.size = ((QUEUE *)dbp->q_internal)->re_len; - data.data = qp->data; - if ((ret = __qam_delext_log(dbp, - dbc->txn, &LSN(pagep), 0, &LSN(pagep), - pagep->pgno, cp->indx, cp->recno, &data)) != 0) - goto err; - } - } - - F_CLR(qp, QAM_VALID); - - /* - * Peek at the first_recno before locking the meta page. - * Other threads cannot move first_recno past - * our position while we have the record locked. - * If it's pointing at the deleted record then lock - * the metapage and check again as lower numbered - * record may have been inserted. - */ - if (cp->recno == meta->first_recno) { - pg = ((QUEUE *)dbp->q_internal)->q_meta; - if ((ret = - __db_lget(dbc, 0, pg, DB_LOCK_WRITE, 0, &metalock)) != 0) - goto err; - if (cp->recno == meta->first_recno) - ret = __qam_consume(dbc, meta, meta->first_recno); - if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0) - ret = t_ret; - } - -err: if ((t_ret = __memp_fput(mpf, meta, 0)) != 0 && ret == 0) - ret = t_ret; - if (cp->page != NULL && (t_ret = __qam_fput(dbp, cp->pgno, - cp->page, ret == 0 ? DB_MPOOL_DIRTY : 0)) != 0 && ret == 0) - ret = t_ret; - cp->page = NULL; - - /* Doing record locking, release the page lock */ - if ((t_ret = __LPUT(dbc, cp->lock)) != 0 && ret == 0) - ret = t_ret; - cp->lock = lock; - - return (ret); -} - -#ifdef DEBUG_WOP -#define QDEBUG -#endif - -/* - * __qam_c_get -- - * Queue cursor->c_get function. - */ -static int -__qam_c_get(dbc, key, data, flags, pgnop) - DBC *dbc; - DBT *key, *data; - u_int32_t flags; - db_pgno_t *pgnop; -{ - DB *dbp; - DBC *dbcdup; - DBT tmp; - DB_ENV *dbenv; - DB_LOCK lock, pglock, metalock; - DB_MPOOLFILE *mpf; - PAGE *pg; - QAMDATA *qp; - QMETA *meta; - QUEUE *t; - QUEUE_CURSOR *cp; - db_lockmode_t lock_mode; - db_pgno_t metapno; - db_recno_t first; - qam_position_mode mode; - u_int32_t put_mode; - int exact, inorder, is_first, locked, ret, t_ret, wait, with_delete; - int retrying; - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - mpf = dbp->mpf; - cp = (QUEUE_CURSOR *)dbc->internal; - LOCK_INIT(lock); - - PANIC_CHECK(dbenv); - - wait = 0; - with_delete = 0; - retrying = 0; - lock_mode = DB_LOCK_READ; - meta = NULL; - inorder = F_ISSET(dbp, DB_AM_INORDER); - put_mode = 0; - t_ret = 0; - *pgnop = 0; - pg = NULL; - - mode = QAM_READ; - if (F_ISSET(dbc, DBC_RMW)) { - lock_mode = DB_LOCK_WRITE; - mode = QAM_WRITE; - } - - if (flags == DB_CONSUME_WAIT) { - wait = 1; - flags = DB_CONSUME; - } - if (flags == DB_CONSUME) { - with_delete = 1; - flags = DB_FIRST; - lock_mode = DB_LOCK_WRITE; - mode = QAM_CONSUME; - } - - DEBUG_LREAD(dbc, dbc->txn, "qam_c_get", - flags == DB_SET || flags == DB_SET_RANGE ? key : NULL, NULL, flags); - - /* Make lint and friends happy. */ - locked = 0; - - is_first = 0; - - t = (QUEUE *)dbp->q_internal; - metapno = t->q_meta; - - /* - * Get the meta page first, we don't want to write lock it while - * trying to pin it. This is because someone my have it pinned - * but not locked. - */ - if ((ret = __memp_fget(mpf, &metapno, 0, &meta)) != 0) - return (ret); - if ((ret = __db_lget(dbc, 0, metapno, lock_mode, 0, &metalock)) != 0) - goto err; - locked = 1; - - first = 0; - - /* Release any previous lock if not in a transaction. */ - if ((ret = __TLPUT(dbc, cp->lock)) != 0) - goto err; - -retry: /* Update the record number. */ - switch (flags) { - case DB_CURRENT: - break; - case DB_NEXT_DUP: - ret = DB_NOTFOUND; - goto err; - /* NOTREACHED */ - case DB_NEXT: - case DB_NEXT_NODUP: -get_next: if (cp->recno != RECNO_OOB) { - ++cp->recno; - /* Wrap around, skipping zero. */ - if (cp->recno == RECNO_OOB) - cp->recno++; - /* - * Check to see if we are out of data. - */ - if (cp->recno == meta->cur_recno || - QAM_AFTER_CURRENT(meta, cp->recno)) { - pg = NULL; - if (!wait) { - ret = DB_NOTFOUND; - goto err; - } - flags = DB_FIRST; - /* - * If first is not set, then we skipped - * a locked record, go back and find it. - * If we find a locked record again - * wait for it. - */ - if (first == 0) { - retrying = 1; - goto retry; - } - - if (CDB_LOCKING(dbenv)) { - /* Drop the metapage before we wait. */ - if ((ret = - __memp_fput(mpf, meta, 0)) != 0) - goto err; - meta = NULL; - if ((ret = __lock_get( - dbenv, dbc->locker, - DB_LOCK_SWITCH, &dbc->lock_dbt, - DB_LOCK_WAIT, &dbc->mylock)) != 0) - goto err; - - if ((ret = __memp_fget(mpf, - &metapno, 0, &meta)) != 0) - goto err; - if ((ret = __lock_get( - dbenv, dbc->locker, - DB_LOCK_UPGRADE, &dbc->lock_dbt, - DB_LOCK_WRITE, &dbc->mylock)) != 0) - goto err; - goto retry; - } - /* - * Wait for someone to update the meta page. - * This will probably mean there is something - * in the queue. We then go back up and - * try again. - */ - if (locked == 0) { - if ((ret = __db_lget(dbc, 0, metapno, - lock_mode, 0, &metalock)) != 0) - goto err; - locked = 1; - if (cp->recno != meta->cur_recno && - cp->recno != RECNO_OOB && - !QAM_AFTER_CURRENT(meta, cp->recno)) - goto retry; - } - /* Drop the metapage before we wait. */ - if ((ret = __memp_fput(mpf, meta, 0)) != 0) - goto err; - meta = NULL; - if ((ret = __db_lget(dbc, - 0, metapno, DB_LOCK_WAIT, - DB_LOCK_SWITCH, &metalock)) != 0) { - if (ret == DB_LOCK_DEADLOCK) - ret = DB_LOCK_NOTGRANTED; - goto err; - } - if ((ret = __memp_fget( - mpf, &metapno, 0, &meta)) != 0) - goto err; - if ((ret = __db_lget(dbc, 0, - PGNO_INVALID, DB_LOCK_WRITE, - DB_LOCK_UPGRADE, &metalock)) != 0) { - if (ret == DB_LOCK_DEADLOCK) - ret = DB_LOCK_NOTGRANTED; - goto err; - } - locked = 1; - goto retry; - } - break; - } - /* FALLTHROUGH */ - case DB_FIRST: - flags = DB_NEXT; - is_first = 1; - - /* get the first record number */ - cp->recno = first = meta->first_recno; - - break; - case DB_PREV: - case DB_PREV_NODUP: - if (cp->recno != RECNO_OOB) { - if (cp->recno == meta->first_recno || - QAM_BEFORE_FIRST(meta, cp->recno)) { - ret = DB_NOTFOUND; - goto err; - } - --cp->recno; - /* Wrap around, skipping zero. */ - if (cp->recno == RECNO_OOB) - --cp->recno; - break; - } - /* FALLTHROUGH */ - case DB_LAST: - if (meta->first_recno == meta->cur_recno) { - ret = DB_NOTFOUND; - goto err; - } - cp->recno = meta->cur_recno - 1; - if (cp->recno == RECNO_OOB) - cp->recno--; - break; - case DB_SET: - case DB_SET_RANGE: - case DB_GET_BOTH: - case DB_GET_BOTH_RANGE: - if ((ret = __qam_getno(dbp, key, &cp->recno)) != 0) - goto err; - if (QAM_NOT_VALID(meta, cp->recno)) { - ret = DB_NOTFOUND; - goto err; - } - break; - default: - ret = __db_unknown_flag(dbenv, "__qam_c_get", flags); - goto err; - } - - /* Don't hold the meta page long term. */ - if (locked) { - if ((ret = __LPUT(dbc, metalock)) != 0) - goto err; - locked = 0; - } - - /* Lock the record. */ - if (((ret = __db_lget(dbc, 0, cp->recno, lock_mode, - (with_delete && !retrying) ? - DB_LOCK_NOWAIT | DB_LOCK_RECORD : DB_LOCK_RECORD, - &lock)) == DB_LOCK_DEADLOCK || ret == DB_LOCK_NOTGRANTED) && - with_delete) { -#ifdef QDEBUG - if (DBC_LOGGING(dbc)) - (void)__log_printf(dbenv, - dbc->txn, "Queue S: %x %d %d %d", - dbc->locker, cp->recno, first, meta->first_recno); -#endif - first = 0; - if ((ret = - __db_lget(dbc, 0, metapno, lock_mode, 0, &metalock)) != 0) - goto err; - locked = 1; - goto retry; - } - - if (ret != 0) - goto err; - - /* - * In the DB_FIRST or DB_LAST cases we must wait and then start over - * since the first/last may have moved while we slept. - * We release our locks and try again. - */ - if (((inorder || !with_delete) && is_first) || flags == DB_LAST) { -get_first: - if ((ret = - __db_lget(dbc, 0, metapno, lock_mode, 0, &metalock)) != 0) - goto err; - if (cp->recno != - (is_first ? meta->first_recno : (meta->cur_recno - 1))) { - if ((ret = __LPUT(dbc, lock)) != 0) - goto err; - if (is_first) - flags = DB_FIRST; - locked = 1; - goto retry; - } - /* Don't hold the meta page long term. */ - if ((ret = __LPUT(dbc, metalock)) != 0) - goto err; - } - - /* Position the cursor on the record. */ - if ((ret = __qam_position(dbc, &cp->recno, mode, &exact)) != 0) { - /* We cannot get the page, release the record lock. */ - (void)__LPUT(dbc, lock); - goto err; - } - - pg = cp->page; - pglock = cp->lock; - cp->lock = lock; - cp->lock_mode = lock_mode; - - if (!exact) { -release_retry: /* Release locks and retry, if possible. */ - if (pg != NULL) - (void)__qam_fput(dbp, cp->pgno, pg, 0); - cp->page = pg = NULL; - if ((ret = __LPUT(dbc, pglock)) != 0) - goto err1; - - switch (flags) { - case DB_GET_BOTH_RANGE: - flags = DB_SET_RANGE; - /* FALLTHROUGH */ - case DB_NEXT: - case DB_NEXT_NODUP: - case DB_SET_RANGE: - if (!with_delete) - is_first = 0; - /* Peek at the meta page unlocked. */ - if (QAM_BEFORE_FIRST(meta, cp->recno)) - goto get_first; - /* FALLTHROUGH */ - case DB_PREV: - case DB_PREV_NODUP: - case DB_LAST: - if (flags == DB_LAST) - flags = DB_PREV; - retrying = 0; - if ((ret = __LPUT(dbc, cp->lock)) != 0) - goto err1; - if (flags == DB_SET_RANGE) - goto get_next; - else - goto retry; - - default: - /* this is for the SET and GET_BOTH cases */ - ret = DB_KEYEMPTY; - goto err1; - } - } - - qp = QAM_GET_RECORD(dbp, pg, cp->indx); - - /* Return the data item. */ - if (flags == DB_GET_BOTH || flags == DB_GET_BOTH_RANGE) { - /* - * Need to compare - */ - tmp.data = qp->data; - tmp.size = t->re_len; - if ((ret = __bam_defcmp(dbp, data, &tmp)) != 0) { - if (flags == DB_GET_BOTH_RANGE) - goto release_retry; - ret = DB_NOTFOUND; - goto err1; - } - } - - /* Return the key if the user didn't give us one. */ - if (key != NULL) { - if (flags != DB_GET_BOTH && flags != DB_SET && - (ret = __db_retcopy(dbp->dbenv, - key, &cp->recno, sizeof(cp->recno), - &dbc->rkey->data, &dbc->rkey->ulen)) != 0) - goto err1; - F_SET(key, DB_DBT_ISSET); - } - - if (data != NULL) { - if (!F_ISSET(dbc, DBC_MULTIPLE|DBC_MULTIPLE_KEY) && - (ret = __db_retcopy(dbp->dbenv, data, qp->data, t->re_len, - &dbc->rdata->data, &dbc->rdata->ulen)) != 0) - goto err1; - F_SET(data, DB_DBT_ISSET); - } - - /* Finally, if we are doing DB_CONSUME mark the record. */ - if (with_delete) { - /* - * Assert that we're not a secondary index. Doing a DB_CONSUME - * on a secondary makes very little sense, since one can't - * DB_APPEND there; attempting one should be forbidden by - * the interface. - */ - DB_ASSERT(!F_ISSET(dbp, DB_AM_SECONDARY)); - - /* - * Check and see if we *have* any secondary indices. - * If we do, we're a primary, so call __db_c_del_primary - * to delete the references to the item we're about to - * delete. - * - * Note that we work on a duplicated cursor, since the - * __db_ret work has already been done, so it's not safe - * to perform any additional ops on this cursor. - */ - if (LIST_FIRST(&dbp->s_secondaries) != NULL) { - if ((ret = __db_c_idup(dbc, - &dbcdup, DB_POSITION)) != 0) - goto err1; - - if ((ret = __db_c_del_primary(dbcdup)) != 0) { - /* - * The __db_c_del_primary return is more - * interesting. - */ - (void)__db_c_close(dbcdup); - goto err1; - } - - if ((ret = __db_c_close(dbcdup)) != 0) - goto err1; - } - - if (DBC_LOGGING(dbc)) { - if (t->page_ext == 0 || t->re_len == 0) { - if ((ret = __qam_del_log(dbp, dbc->txn, - &LSN(pg), 0, &LSN(pg), - pg->pgno, cp->indx, cp->recno)) != 0) - goto err1; - } else { - tmp.data = qp->data; - tmp.size = t->re_len; - if ((ret = __qam_delext_log(dbp, - dbc->txn, &LSN(pg), 0, &LSN(pg), - pg->pgno, cp->indx, cp->recno, &tmp)) != 0) - goto err1; - } - } - - F_CLR(qp, QAM_VALID); - put_mode = DB_MPOOL_DIRTY; - - if ((ret = __LPUT(dbc, pglock)) != 0) - goto err1; - - /* - * Now we need to update the metapage - * first pointer. If we have deleted - * the record that is pointed to by - * first_recno then we move it as far - * forward as we can without blocking. - * The metapage lock must be held for - * the whole scan otherwise someone could - * do a random insert behind where we are - * looking. - */ - - if (locked == 0 && (ret = __db_lget( - dbc, 0, metapno, lock_mode, 0, &metalock)) != 0) - goto err1; - locked = 1; - -#ifdef QDEBUG - if (DBC_LOGGING(dbc)) - (void)__log_printf(dbenv, - dbc->txn, "Queue D: %x %d %d %d", - dbc->locker, cp->recno, first, meta->first_recno); -#endif - /* - * See if we deleted the "first" record. If - * first is zero then we skipped something, - * see if first_recno has been move passed - * that to the record that we deleted. - */ - if (first == 0) - first = cp->recno; - if (first != meta->first_recno) - goto done; - - if ((ret = __qam_consume(dbc, meta, first)) != 0) - goto err1; - } - -done: -err1: if (cp->page != NULL) { - if ((t_ret = __qam_fput( - dbp, cp->pgno, cp->page, put_mode)) != 0 && ret == 0) - ret = t_ret; - - /* Doing record locking, release the page lock */ - if ((t_ret = __LPUT(dbc, pglock)) != 0 && ret == 0) - ret = t_ret; - cp->page = NULL; - } - -err: if (meta) { - /* Release the meta page. */ - if ((t_ret = __memp_fput(mpf, meta, 0)) != 0 && ret == 0) - ret = t_ret; - - /* Don't hold the meta page long term. */ - if (locked) - if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0) - ret = t_ret; - } - DB_ASSERT(!LOCK_ISSET(metalock)); - - return ((ret == DB_LOCK_NOTGRANTED && - !F_ISSET(dbenv, DB_ENV_TIME_NOTGRANTED)) ? - DB_LOCK_DEADLOCK : ret); -} - -/* - * __qam_consume -- try to reset the head of the queue. - * - */ -static int -__qam_consume(dbc, meta, first) - DBC *dbc; - QMETA *meta; - db_recno_t first; -{ - DB *dbp; - DB_LOCK lock, save_lock; - DB_MPOOLFILE *mpf; - QUEUE_CURSOR *cp; - db_indx_t save_indx; - db_pgno_t save_page; - db_recno_t current, save_recno; - u_int32_t put_mode, rec_extent; - int exact, ret, t_ret, wrapped; - - dbp = dbc->dbp; - mpf = dbp->mpf; - cp = (QUEUE_CURSOR *)dbc->internal; - put_mode = DB_MPOOL_DIRTY; - ret = 0; - - save_page = cp->pgno; - save_indx = cp->indx; - save_recno = cp->recno; - save_lock = cp->lock; - - /* - * If we skipped some deleted records, we need to - * reposition on the first one. Get a lock - * in case someone is trying to put it back. - */ - if (first != cp->recno) { - ret = __db_lget(dbc, 0, first, DB_LOCK_READ, - DB_LOCK_NOWAIT | DB_LOCK_RECORD, &lock); - if (ret == DB_LOCK_DEADLOCK) { - ret = 0; - goto done; - } - if (ret != 0) - goto done; - if ((ret = - __qam_fput(dbp, cp->pgno, cp->page, put_mode)) != 0) - goto done; - cp->page = NULL; - put_mode = 0; - if ((ret = __qam_position(dbc, - &first, QAM_READ, &exact)) != 0 || exact != 0) { - (void)__LPUT(dbc, lock); - goto done; - } - if ((ret =__LPUT(dbc, lock)) != 0) - goto done; - if ((ret = __LPUT(dbc, cp->lock)) != 0) - goto done; - } - - current = meta->cur_recno; - wrapped = 0; - if (first > current) - wrapped = 1; - rec_extent = meta->page_ext * meta->rec_page; - - /* Loop until we find a record or hit current */ - for (;;) { - /* - * Check to see if we are moving off the extent - * and remove the extent. - * If we are moving off a page we need to - * get rid of the buffer. - * Wait for the lagging readers to move off the - * page. - */ - if (cp->page != NULL && rec_extent != 0 && - ((exact = (first % rec_extent == 0)) || - (first % meta->rec_page == 0) || - first == UINT32_MAX)) { - if (exact == 1 && (ret = __db_lget(dbc, - 0, cp->pgno, DB_LOCK_WRITE, 0, &cp->lock)) != 0) - break; -#ifdef QDEBUG - if (DBC_LOGGING(dbc)) - (void)__log_printf(dbp->dbenv, dbc->txn, - "Queue R: %x %d %d %d", dbc->locker, - cp->pgno, first, meta->first_recno); -#endif - put_mode |= DB_MPOOL_DISCARD; - if ((ret = __qam_fput(dbp, - cp->pgno, cp->page, put_mode)) != 0) - break; - cp->page = NULL; - - if (exact == 1) { - ret = __qam_fremove(dbp, cp->pgno); - if ((t_ret = - __LPUT(dbc, cp->lock)) != 0 && ret == 0) - ret = t_ret; - } - if (ret != 0) - break; - } else if (cp->page != NULL && (ret = - __qam_fput(dbp, cp->pgno, cp->page, put_mode)) != 0) - break; - cp->page = NULL; - first++; - if (first == RECNO_OOB) { - wrapped = 0; - first++; - } - - /* - * LOOP EXIT when we come move to the current - * pointer. - */ - if (!wrapped && first >= current) - break; - - ret = __db_lget(dbc, 0, first, DB_LOCK_READ, - DB_LOCK_NOWAIT | DB_LOCK_RECORD, &lock); - if (ret == DB_LOCK_DEADLOCK) { - ret = 0; - break; - } - if (ret != 0) - break; - - if ((ret = __qam_position(dbc, - &first, QAM_READ, &exact)) != 0) { - (void)__LPUT(dbc, lock); - break; - } - put_mode = 0; - if ((ret =__LPUT(dbc, lock)) != 0 || - (ret = __LPUT(dbc, cp->lock)) != 0 || exact) { - if ((t_ret = __qam_fput(dbp, cp->pgno, - cp->page, put_mode)) != 0 && ret == 0) - ret = t_ret; - cp->page = NULL; - break; - } - } - - cp->pgno = save_page; - cp->indx = save_indx; - cp->recno = save_recno; - cp->lock = save_lock; - - /* - * We have advanced as far as we can. - * Advance first_recno to this point. - */ - if (ret == 0 && meta->first_recno != first) { -#ifdef QDEBUG - if (DBC_LOGGING(dbc)) - (void)__log_printf(dbp->dbenv, dbc->txn, - "Queue M: %x %d %d %d", dbc->locker, cp->recno, - first, meta->first_recno); -#endif - if (DBC_LOGGING(dbc)) - if ((ret = __qam_incfirst_log(dbp, - dbc->txn, &meta->dbmeta.lsn, 0, - cp->recno, PGNO_BASE_MD)) != 0) - goto done; - meta->first_recno = first; - (void)__memp_fset(mpf, meta, DB_MPOOL_DIRTY); - } - -done: - return (ret); -} - -static int -__qam_bulk(dbc, data, flags) - DBC *dbc; - DBT *data; - u_int32_t flags; -{ - DB *dbp; - DB_LOCK metalock, rlock; - DB_MPOOLFILE *mpf; - PAGE *pg; - QMETA *meta; - QAMDATA *qp; - QUEUE_CURSOR *cp; - db_indx_t indx; - db_lockmode_t lkmode; - db_pgno_t metapno; - qam_position_mode mode; - u_int32_t *endp, *offp; - u_int32_t pagesize, re_len, recs; - u_int8_t *dbuf, *dp, *np; - int exact, ret, t_ret, valid; - int is_key, need_pg, size, space; - - dbp = dbc->dbp; - mpf = dbp->mpf; - cp = (QUEUE_CURSOR *)dbc->internal; - - mode = QAM_READ; - lkmode = DB_LOCK_READ; - if (F_ISSET(dbc, DBC_RMW)) { - mode = QAM_WRITE; - lkmode = DB_LOCK_WRITE; - } - - pagesize = dbp->pgsize; - re_len = ((QUEUE *)dbp->q_internal)->re_len; - recs = ((QUEUE *)dbp->q_internal)->rec_page; - metapno = ((QUEUE *)dbp->q_internal)->q_meta; - - is_key = LF_ISSET(DB_MULTIPLE_KEY) ? 1 : 0; - size = 0; - - if ((ret = __db_lget(dbc, 0, metapno, DB_LOCK_READ, 0, &metalock)) != 0) - return (ret); - if ((ret = __memp_fget(mpf, &metapno, 0, &meta)) != 0) { - /* We did not fetch it, we can release the lock. */ - (void)__LPUT(dbc, metalock); - return (ret); - } - - dbuf = data->data; - np = dp = dbuf; - - /* Keep track of space that is left. There is an termination entry */ - space = (int)data->ulen; - space -= (int)sizeof(*offp); - - /* Build the offset/size table from the end up. */ - endp = (u_int32_t *)((u_int8_t *)dbuf + data->ulen); - endp--; - offp = endp; - /* Save the lock on the current position of the cursor. */ - rlock = cp->lock; - LOCK_INIT(cp->lock); - -next_pg: - /* Wrap around, skipping zero. */ - if (cp->recno == RECNO_OOB) - cp->recno++; - if ((ret = __qam_position(dbc, &cp->recno, mode, &exact)) != 0) - goto done; - - pg = cp->page; - indx = cp->indx; - need_pg = 1; - - do { - /* - * If this page is a nonexistent page at the end of an - * extent, pg may be NULL. A NULL page has no valid records, - * so just keep looping as though qp exists and isn't QAM_VALID; - * calling QAM_GET_RECORD is unsafe. - */ - valid = 0; - - if (pg != NULL) { - if ((ret = __db_lget(dbc, LCK_COUPLE, - cp->recno, lkmode, DB_LOCK_RECORD, &rlock)) != 0) - goto done; - qp = QAM_GET_RECORD(dbp, pg, indx); - if (F_ISSET(qp, QAM_VALID)) { - valid = 1; - space -= (int) - ((is_key ? 3 : 2) * sizeof(*offp)); - if (space < 0) - goto get_space; - if (need_pg) { - dp = np; - size = (int)pagesize - QPAGE_SZ(dbp); - if (space < size) { -get_space: - if (offp == endp) { - data->size = (u_int32_t) - DB_ALIGN((u_int32_t) - size + pagesize, - sizeof(u_int32_t)); - ret = DB_BUFFER_SMALL; - break; - } - if (indx != 0) - indx--; - cp->recno--; - space = 0; - break; - } - memcpy(dp, - (char *)pg + QPAGE_SZ(dbp), - (unsigned)size); - need_pg = 0; - space -= size; - np += size; - } - if (is_key) - *offp-- = cp->recno; - *offp-- = (u_int32_t)((((u_int8_t*)qp - - (u_int8_t*)pg) - QPAGE_SZ(dbp)) + - (dp - dbuf) + SSZA(QAMDATA, data)); - *offp-- = re_len; - } - } - if (!valid && is_key == 0) { - *offp-- = 0; - *offp-- = 0; - } - cp->recno++; - } while (++indx < recs && cp->recno != RECNO_OOB && - cp->recno != meta->cur_recno && - !QAM_AFTER_CURRENT(meta, cp->recno)); - - /* Drop the page lock. */ - if ((t_ret = __LPUT(dbc, cp->lock)) != 0 && ret == 0) - ret = t_ret; - - if (cp->page != NULL) { - if ((t_ret = - __qam_fput(dbp, cp->pgno, cp->page, 0)) != 0 && ret == 0) - ret = t_ret; - cp->page = NULL; - } - - if (ret == 0 && space > 0 && - (indx >= recs || cp->recno == RECNO_OOB) && - cp->recno != meta->cur_recno && - !QAM_AFTER_CURRENT(meta, cp->recno)) - goto next_pg; - - /* - * Correct recno in two cases: - * 1) If we just wrapped fetch must start at record 1 not a FIRST. - * 2) We ran out of space exactly at the end of a page. - */ - if (cp->recno == RECNO_OOB || (space == 0 && indx == recs)) - cp->recno--; - - if (is_key == 1) - *offp = RECNO_OOB; - else - *offp = (u_int32_t)-1; - -done: /* Release the meta page. */ - if ((t_ret = __memp_fput(mpf, meta, 0)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0) - ret = t_ret; - - cp->lock = rlock; - - return (ret); -} - -/* - * __qam_c_close -- - * Close down the cursor from a single use. - */ -static int -__qam_c_close(dbc, root_pgno, rmroot) - DBC *dbc; - db_pgno_t root_pgno; - int *rmroot; -{ - QUEUE_CURSOR *cp; - int ret; - - COMPQUIET(root_pgno, 0); - COMPQUIET(rmroot, NULL); - - cp = (QUEUE_CURSOR *)dbc->internal; - - /* Discard any locks not acquired inside of a transaction. */ - ret = __TLPUT(dbc, cp->lock); - - LOCK_INIT(cp->lock); - cp->page = NULL; - cp->pgno = PGNO_INVALID; - cp->indx = 0; - cp->lock_mode = DB_LOCK_NG; - cp->recno = RECNO_OOB; - cp->flags = 0; - - return (ret); -} - -/* - * __qam_c_dup -- - * Duplicate a queue cursor, such that the new one holds appropriate - * locks for the position of the original. - * - * PUBLIC: int __qam_c_dup __P((DBC *, DBC *)); - */ -int -__qam_c_dup(orig_dbc, new_dbc) - DBC *orig_dbc, *new_dbc; -{ - QUEUE_CURSOR *orig, *new; - int ret; - - orig = (QUEUE_CURSOR *)orig_dbc->internal; - new = (QUEUE_CURSOR *)new_dbc->internal; - - new->recno = orig->recno; - - /* Acquire the long term lock if we are not in a transaction. */ - if (orig_dbc->txn == NULL && LOCK_ISSET(orig->lock)) - if ((ret = __db_lget(new_dbc, 0, new->recno, - new->lock_mode, DB_LOCK_RECORD, &new->lock)) != 0) - return (ret); - - return (0); -} - -/* - * __qam_c_init - * - * PUBLIC: int __qam_c_init __P((DBC *)); - */ -int -__qam_c_init(dbc) - DBC *dbc; -{ - QUEUE_CURSOR *cp; - DB *dbp; - int ret; - - dbp = dbc->dbp; - - /* Allocate the internal structure. */ - cp = (QUEUE_CURSOR *)dbc->internal; - if (cp == NULL) { - if ((ret = - __os_calloc(dbp->dbenv, 1, sizeof(QUEUE_CURSOR), &cp)) != 0) - return (ret); - dbc->internal = (DBC_INTERNAL *)cp; - } - - /* Initialize methods. */ - dbc->c_close = __db_c_close_pp; - dbc->c_count = __db_c_count_pp; - dbc->c_del = __db_c_del_pp; - dbc->c_dup = __db_c_dup_pp; - dbc->c_get = __db_c_get_pp; - dbc->c_pget = __db_c_pget_pp; - dbc->c_put = __db_c_put_pp; - dbc->c_am_bulk = __qam_bulk; - dbc->c_am_close = __qam_c_close; - dbc->c_am_del = __qam_c_del; - dbc->c_am_destroy = __qam_c_destroy; - dbc->c_am_get = __qam_c_get; - dbc->c_am_put = __qam_c_put; - dbc->c_am_writelock = NULL; - - return (0); -} - -/* - * __qam_c_destroy -- - * Close a single cursor -- internal version. - */ -static int -__qam_c_destroy(dbc) - DBC *dbc; -{ - /* Discard the structures. */ - __os_free(dbc->dbp->dbenv, dbc->internal); - - return (0); -} - -/* - * __qam_getno -- - * Check the user's record number. - */ -static int -__qam_getno(dbp, key, rep) - DB *dbp; - const DBT *key; - db_recno_t *rep; -{ - if ((*rep = *(db_recno_t *)key->data) == 0) { - __db_err(dbp->dbenv, "illegal record number of 0"); - return (EINVAL); - } - return (0); -} - -/* - * __qam_truncate -- - * Truncate a queue database - * - * PUBLIC: int __qam_truncate __P((DBC *, u_int32_t *)); - */ -int -__qam_truncate(dbc, countp) - DBC *dbc; - u_int32_t *countp; -{ - DB *dbp; - DB_LOCK metalock; - DB_MPOOLFILE *mpf; - QMETA *meta; - db_pgno_t metapno; - u_int32_t count; - int ret, t_ret; - - dbp = dbc->dbp; - - /* Walk the queue, counting rows. */ - for (count = 0; - (ret = __qam_c_get(dbc, NULL, NULL, DB_CONSUME, &metapno)) == 0;) - count++; - if (ret != DB_NOTFOUND) - return (ret); - - /* Update the meta page. */ - metapno = ((QUEUE *)dbp->q_internal)->q_meta; - if ((ret = - __db_lget(dbc, 0, metapno, DB_LOCK_WRITE, 0, &metalock)) != 0) - return (ret); - - mpf = dbp->mpf; - if ((ret = __memp_fget(mpf, &metapno, 0, &meta)) != 0) { - /* We did not fetch it, we can release the lock. */ - (void)__LPUT(dbc, metalock); - return (ret); - } - /* Remove the last extent file. */ - if (meta->cur_recno > 1 && ((QUEUE *)dbp->q_internal)->page_ext != 0) { - if ((ret = __qam_fremove(dbp, - QAM_RECNO_PAGE(dbp, meta->cur_recno - 1))) != 0) - return (ret); - } - - if (DBC_LOGGING(dbc)) { - ret = __qam_mvptr_log(dbp, dbc->txn, &meta->dbmeta.lsn, 0, - QAM_SETCUR | QAM_SETFIRST | QAM_TRUNCATE, meta->first_recno, - 1, meta->cur_recno, 1, &meta->dbmeta.lsn, PGNO_BASE_MD); - } - if (ret == 0) - meta->first_recno = meta->cur_recno = 1; - - if ((t_ret = __memp_fput(mpf, - meta, ret == 0 ? DB_MPOOL_DIRTY: 0)) != 0 && ret == 0) - ret = t_ret; - if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0) - ret = t_ret; - - if (countp != NULL) - *countp = count; - - return (ret); -} - -/* - * __qam_delete -- - * Queue fast delete function. - * - * PUBLIC: int __qam_delete __P((DBC *, DBT *)); - */ -int -__qam_delete(dbc, key) - DBC *dbc; - DBT *key; -{ - QUEUE_CURSOR *cp; - int ret; - - cp = (QUEUE_CURSOR *)dbc->internal; - if ((ret = __qam_getno(dbc->dbp, key, &cp->recno)) != 0) - goto err; - - ret = __qam_c_del(dbc); - -err: return (ret); -} diff --git a/storage/bdb/qam/qam.src b/storage/bdb/qam/qam.src deleted file mode 100644 index e63c15e666c..00000000000 --- a/storage/bdb/qam/qam.src +++ /dev/null @@ -1,98 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: qam.src,v 12.1 2005/06/16 20:23:32 bostic Exp $ - */ - -PREFIX __qam -DBPRIVATE - -INCLUDE #ifndef NO_SYSTEM_INCLUDES -INCLUDE #include <sys/types.h> -INCLUDE -INCLUDE #include <ctype.h> -INCLUDE #include <string.h> -INCLUDE #endif -INCLUDE -INCLUDE #include "db_int.h" -INCLUDE #include "dbinc/crypto.h" -INCLUDE #include "dbinc/db_page.h" -INCLUDE #include "dbinc/db_dispatch.h" -INCLUDE #include "dbinc/db_am.h" -INCLUDE #include "dbinc/log.h" -INCLUDE #include "dbinc/qam.h" -INCLUDE #include "dbinc/txn.h" -INCLUDE - -/* - * incfirst - * Used when we increment first_recno. - */ -BEGIN incfirst 84 -DB fileid int32_t ld -ARG recno db_recno_t lu -ARG meta_pgno db_pgno_t lu -END - -/* - * mvptr - * Used when we change one or both of cur_recno and first_recno. - */ -BEGIN mvptr 85 -ARG opcode u_int32_t lu -DB fileid int32_t ld -ARG old_first db_recno_t lu -ARG new_first db_recno_t lu -ARG old_cur db_recno_t lu -ARG new_cur db_recno_t lu -POINTER metalsn DB_LSN * lu -ARG meta_pgno db_pgno_t lu -END - - -/* - * del - * Used when we delete a record. - * recno is the record that is being deleted. - */ -BEGIN del 79 -DB fileid int32_t ld -POINTER lsn DB_LSN * lu -ARG pgno db_pgno_t lu -ARG indx u_int32_t lu -ARG recno db_recno_t lu -END - -/* - * add - * Used when we put a record on a page. - * recno is the record being added. - * data is the record itself. - */ -BEGIN add 80 -DB fileid int32_t ld -POINTER lsn DB_LSN * lu -ARG pgno db_pgno_t lu -ARG indx u_int32_t lu -ARG recno db_recno_t lu -DBT data DBT s -ARG vflag u_int32_t lu -DBT olddata DBT s -END - -/* - * delext - * Used when we delete a record in extent based queue. - * recno is the record that is being deleted. - */ -BEGIN delext 83 -DB fileid int32_t ld -POINTER lsn DB_LSN * lu -ARG pgno db_pgno_t lu -ARG indx u_int32_t lu -ARG recno db_recno_t lu -DBT data DBT s -END diff --git a/storage/bdb/qam/qam_conv.c b/storage/bdb/qam/qam_conv.c deleted file mode 100644 index e3ff19c86e5..00000000000 --- a/storage/bdb/qam/qam_conv.c +++ /dev/null @@ -1,83 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: qam_conv.c,v 12.1 2005/06/16 20:23:32 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_swap.h" -#include "dbinc/db_am.h" -#include "dbinc/qam.h" - -/* - * __qam_mswap -- - * Swap the bytes on the queue metadata page. - * - * PUBLIC: int __qam_mswap __P((PAGE *)); - */ -int -__qam_mswap(pg) - PAGE *pg; -{ - u_int8_t *p; - - __db_metaswap(pg); - - p = (u_int8_t *)pg + sizeof(DBMETA); - - SWAP32(p); /* first_recno */ - SWAP32(p); /* cur_recno */ - SWAP32(p); /* re_len */ - SWAP32(p); /* re_pad */ - SWAP32(p); /* rec_page */ - SWAP32(p); /* page_ext */ - p += 91 * sizeof(u_int32_t); /* unused */ - SWAP32(p); /* crypto_magic */ - - return (0); -} - -/* - * __qam_pgin_out -- - * Convert host-specific page layout to/from the host-independent format - * stored on disk. - * We only need to fix up a few fields in the header - * - * PUBLIC: int __qam_pgin_out __P((DB_ENV *, db_pgno_t, void *, DBT *)); - */ -int -__qam_pgin_out(dbenv, pg, pp, cookie) - DB_ENV *dbenv; - db_pgno_t pg; - void *pp; - DBT *cookie; -{ - DB_PGINFO *pginfo; - QPAGE *h; - - COMPQUIET(pg, 0); - COMPQUIET(dbenv, NULL); - pginfo = (DB_PGINFO *)cookie->data; - if (!F_ISSET(pginfo, DB_AM_SWAP)) - return (0); - - h = pp; - if (h->type == P_QAMMETA) - return (__qam_mswap(pp)); - - M_32_SWAP(h->lsn.file); - M_32_SWAP(h->lsn.offset); - M_32_SWAP(h->pgno); - - return (0); -} diff --git a/storage/bdb/qam/qam_files.c b/storage/bdb/qam/qam_files.c deleted file mode 100644 index 3cf3bd5c55e..00000000000 --- a/storage/bdb/qam/qam_files.c +++ /dev/null @@ -1,852 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: qam_files.c,v 12.6 2005/10/20 18:57:12 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#include <stdlib.h> - -#include <string.h> -#include <ctype.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/db_am.h" -#include "dbinc/log.h" -#include "dbinc/fop.h" -#include "dbinc/mp.h" -#include "dbinc/qam.h" - -#define QAM_EXNAME(Q, I, B, L) \ - snprintf((B), (L), \ - QUEUE_EXTENT, (Q)->dir, PATH_SEPARATOR[0], (Q)->name, (I)) - -/* - * __qam_fprobe -- calculate and open extent - * - * Calculate which extent the page is in, open and create if necessary. - * - * PUBLIC: int __qam_fprobe - * PUBLIC: __P((DB *, db_pgno_t, void *, qam_probe_mode, u_int32_t)); - */ -int -__qam_fprobe(dbp, pgno, addrp, mode, flags) - DB *dbp; - db_pgno_t pgno; - void *addrp; - qam_probe_mode mode; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_MPOOLFILE *mpf; - MPFARRAY *array; - QUEUE *qp; - u_int8_t fid[DB_FILE_ID_LEN]; - u_int32_t i, extid, maxext, numext, lflags, offset, oldext, openflags; - char buf[MAXPATHLEN]; - int ftype, less, ret, t_ret; - - dbenv = dbp->dbenv; - qp = (QUEUE *)dbp->q_internal; - ret = 0; - - if (qp->page_ext == 0) { - mpf = dbp->mpf; - return (mode == QAM_PROBE_GET ? - __memp_fget(mpf, &pgno, flags, addrp) : - __memp_fput(mpf, addrp, flags)); - } - - mpf = NULL; - - /* - * Need to lock long enough to find the mpf or create the file. - * The file cannot go away because we must have a record locked - * in that file. - */ - MUTEX_LOCK(dbenv, dbp->mutex); - extid = QAM_PAGE_EXTENT(dbp, pgno); - - /* Array1 will always be in use if array2 is in use. */ - array = &qp->array1; - if (array->n_extent == 0) { - /* Start with 4 extents */ - array->n_extent = 4; - array->low_extent = extid; - numext = offset = oldext = 0; - less = 0; - goto alloc; - } - -retry: - if (extid < array->low_extent) { - less = 1; - offset = array->low_extent - extid; - } else { - less = 0; - offset = extid - array->low_extent; - } - if (qp->array2.n_extent != 0 && - (extid >= qp->array2.low_extent ? - offset > extid - qp->array2.low_extent : - offset > qp->array2.low_extent - extid)) { - array = &qp->array2; - if (extid < array->low_extent) { - less = 1; - offset = array->low_extent - extid; - } else { - less = 0; - offset = extid - array->low_extent; - } - } - - /* - * Check to see if the requested extent is outside the range of - * extents in the array. This is true by default if there are - * no extents here yet. - */ - if (less == 1 || offset >= array->n_extent) { - oldext = array->n_extent; - numext = (array->hi_extent - array->low_extent) + 1; - if (less == 1 && offset + numext <= array->n_extent) { - /* - * If we can fit this one into the existing array by - * shifting the existing entries then we do not have - * to allocate. - */ - memmove(&array->mpfarray[offset], - array->mpfarray, numext - * sizeof(array->mpfarray[0])); - memset(array->mpfarray, 0, offset - * sizeof(array->mpfarray[0])); - offset = 0; - } else if (less == 0 && offset == array->n_extent && - mode != QAM_PROBE_MPF && array->mpfarray[0].pinref == 0) { - /* - * If this is at the end of the array and the file at - * the beginning has a zero pin count we can close - * the bottom extent and put this one at the end. - */ - mpf = array->mpfarray[0].mpf; - if (mpf != NULL && (ret = __memp_fclose(mpf, 0)) != 0) - goto err; - memmove(&array->mpfarray[0], &array->mpfarray[1], - (array->n_extent - 1) * sizeof(array->mpfarray[0])); - array->low_extent++; - array->hi_extent++; - offset--; - array->mpfarray[offset].mpf = NULL; - array->mpfarray[offset].pinref = 0; - } else { - /* - * See if we have wrapped around the queue. - * If it has then allocate the second array. - * Otherwise just expand the one we are using. - */ - maxext = (u_int32_t) UINT32_MAX - / (qp->page_ext * qp->rec_page); - if (offset >= maxext/2) { - array = &qp->array2; - DB_ASSERT(array->n_extent == 0); - oldext = 0; - array->n_extent = 4; - array->low_extent = extid; - offset = 0; - numext = 0; - } else if (array->mpfarray[0].pinref == 0) { - /* - * Check to see if there are extents marked - * for deletion at the beginning of the cache. - * If so close them so they will go away. - */ - for (i = 0; i < array->n_extent; i++) { - if (array->mpfarray[i].pinref != 0) - break; - mpf = array->mpfarray[i].mpf; - if (mpf == NULL) - continue; - (void)__memp_get_flags(mpf, &lflags); - if (!FLD_ISSET(lflags, DB_MPOOL_UNLINK)) - break; - - array->mpfarray[i].mpf = NULL; - if ((ret = __memp_fclose(mpf, 0)) != 0) - goto err; - } - if (i == 0) - goto increase; - memmove(&array->mpfarray[0], - &array->mpfarray[i], - (array->n_extent - i) * - sizeof(array->mpfarray[0])); - memset(&array->mpfarray[array->n_extent - i], - '\0', i * sizeof(array->mpfarray[0])); - array->low_extent += i; - array->hi_extent += i; - goto retry; - } else { - /* - * Increase the size to at least include - * the new one and double it. - */ -increase: array->n_extent += offset; - array->n_extent <<= 2; - } -alloc: if ((ret = __os_realloc(dbenv, - array->n_extent * sizeof(struct __qmpf), - &array->mpfarray)) != 0) - goto err; - - if (less == 1) { - /* - * Move the array up and put the new one - * in the first slot. - */ - memmove(&array->mpfarray[offset], - array->mpfarray, - numext * sizeof(array->mpfarray[0])); - memset(array->mpfarray, 0, - offset * sizeof(array->mpfarray[0])); - memset(&array->mpfarray[numext + offset], 0, - (array->n_extent - (numext + offset)) - * sizeof(array->mpfarray[0])); - offset = 0; - } - else - /* Clear the new part of the array. */ - memset(&array->mpfarray[oldext], 0, - (array->n_extent - oldext) * - sizeof(array->mpfarray[0])); - } - } - - /* Update the low and hi range of saved extents. */ - if (extid < array->low_extent) - array->low_extent = extid; - if (extid > array->hi_extent) - array->hi_extent = extid; - - /* If the extent file is not yet open, open it. */ - if (array->mpfarray[offset].mpf == NULL) { - QAM_EXNAME(qp, extid, buf, sizeof(buf)); - if ((ret = __memp_fcreate( - dbenv, &array->mpfarray[offset].mpf)) != 0) - goto err; - mpf = array->mpfarray[offset].mpf; - (void)__memp_set_lsn_offset(mpf, 0); - (void)__memp_set_pgcookie(mpf, &qp->pgcookie); - (void)__memp_get_ftype(dbp->mpf, &ftype); - (void)__memp_set_ftype(mpf, ftype); - (void)__memp_set_clear_len(mpf, dbp->pgsize); - - /* Set up the fileid for this extent. */ - __qam_exid(dbp, fid, extid); - (void)__memp_set_fileid(mpf, fid); - openflags = DB_EXTENT; - if (LF_ISSET(DB_MPOOL_CREATE)) - openflags |= DB_CREATE; - if (F_ISSET(dbp, DB_AM_RDONLY)) - openflags |= DB_RDONLY; - if (F_ISSET(dbenv, DB_ENV_DIRECT_DB)) - openflags |= DB_DIRECT; - if ((ret = __memp_fopen( - mpf, NULL, buf, openflags, qp->mode, dbp->pgsize)) != 0) { - array->mpfarray[offset].mpf = NULL; - (void)__memp_fclose(mpf, 0); - goto err; - } - } - - /* - * We have found the right file. Update its ref count - * before dropping the dbp mutex so it does not go away. - */ - mpf = array->mpfarray[offset].mpf; - if (mode == QAM_PROBE_GET) - array->mpfarray[offset].pinref++; - - /* - * If we may create the page, then we are writing, - * the file may nolonger be empty after this operation - * so we clear the UNLINK flag. - */ - if (LF_ISSET(DB_MPOOL_CREATE)) - (void)__memp_set_flags(mpf, DB_MPOOL_UNLINK, 0); - -err: - MUTEX_UNLOCK(dbenv, dbp->mutex); - - if (ret == 0) { - if (mode == QAM_PROBE_MPF) { - *(DB_MPOOLFILE **)addrp = mpf; - return (0); - } - pgno--; - pgno %= qp->page_ext; - if (mode == QAM_PROBE_GET) { - if ((ret = __memp_fget(mpf, &pgno, flags, addrp)) == 0) - return (ret); - } else - ret = __memp_fput(mpf, addrp, flags); - - MUTEX_LOCK(dbenv, dbp->mutex); - /* Recalculate because we dropped the lock. */ - offset = extid - array->low_extent; - DB_ASSERT(array->mpfarray[offset].pinref > 0); - if (--array->mpfarray[offset].pinref == 0 && - (mode == QAM_PROBE_GET || ret == 0)) { - /* Check to see if this file will be unlinked. */ - (void)__memp_get_flags(mpf, &flags); - if (LF_ISSET(DB_MPOOL_UNLINK)) { - array->mpfarray[offset].mpf = NULL; - if ((t_ret = - __memp_fclose(mpf, 0)) != 0 && ret == 0) - ret = t_ret; - } - } - MUTEX_UNLOCK(dbenv, dbp->mutex); - } - return (ret); -} - -/* - * __qam_fclose -- close an extent. - * - * Calculate which extent the page is in and close it. - * We assume the mpf entry is present. - * - * PUBLIC: int __qam_fclose __P((DB *, db_pgno_t)); - */ -int -__qam_fclose(dbp, pgnoaddr) - DB *dbp; - db_pgno_t pgnoaddr; -{ - DB_ENV *dbenv; - DB_MPOOLFILE *mpf; - MPFARRAY *array; - QUEUE *qp; - u_int32_t extid, offset; - int ret; - - ret = 0; - dbenv = dbp->dbenv; - qp = (QUEUE *)dbp->q_internal; - - MUTEX_LOCK(dbenv, dbp->mutex); - - extid = QAM_PAGE_EXTENT(dbp, pgnoaddr); - array = &qp->array1; - if (array->low_extent > extid || array->hi_extent < extid) - array = &qp->array2; - offset = extid - array->low_extent; - - DB_ASSERT(extid >= array->low_extent && offset < array->n_extent); - - /* If other threads are still using this file, leave it. */ - if (array->mpfarray[offset].pinref != 0) - goto done; - - mpf = array->mpfarray[offset].mpf; - array->mpfarray[offset].mpf = NULL; - ret = __memp_fclose(mpf, 0); - -done: - MUTEX_UNLOCK(dbenv, dbp->mutex); - return (ret); -} - -/* - * __qam_fremove -- remove an extent. - * - * Calculate which extent the page is in and remove it. There is no way - * to remove an extent without probing it first and seeing that is is empty - * so we assume the mpf entry is present. - * - * PUBLIC: int __qam_fremove __P((DB *, db_pgno_t)); - */ -int -__qam_fremove(dbp, pgnoaddr) - DB *dbp; - db_pgno_t pgnoaddr; -{ - DB_ENV *dbenv; - DB_MPOOLFILE *mpf; - MPFARRAY *array; - QUEUE *qp; - u_int32_t extid, offset; -#ifdef CONFIG_TEST - char buf[MAXPATHLEN], *real_name; -#endif - int ret; - - qp = (QUEUE *)dbp->q_internal; - dbenv = dbp->dbenv; - ret = 0; - - MUTEX_LOCK(dbenv, dbp->mutex); - - extid = QAM_PAGE_EXTENT(dbp, pgnoaddr); - array = &qp->array1; - if (array->low_extent > extid || array->hi_extent < extid) - array = &qp->array2; - offset = extid - array->low_extent; - - DB_ASSERT(extid >= array->low_extent && offset < array->n_extent); - -#ifdef CONFIG_TEST - real_name = NULL; - /* Find the real name of the file. */ - QAM_EXNAME(qp, extid, buf, sizeof(buf)); - if ((ret = __db_appname(dbenv, - DB_APP_DATA, buf, 0, NULL, &real_name)) != 0) - goto err; -#endif - /* - * The log must be flushed before the file is deleted. We depend on - * the log record of the last delete to recreate the file if we crash. - */ - if (LOGGING_ON(dbenv) && (ret = __log_flush(dbenv, NULL)) != 0) - goto err; - - mpf = array->mpfarray[offset].mpf; - (void)__memp_set_flags(mpf, DB_MPOOL_UNLINK, 1); - /* Someone could be real slow, let them close it down. */ - if (array->mpfarray[offset].pinref != 0) - goto err; - array->mpfarray[offset].mpf = NULL; - if ((ret = __memp_fclose(mpf, 0)) != 0) - goto err; - - /* - * If the file is at the bottom of the array - * shift things down and adjust the end points. - */ - if (offset == 0) { - memmove(array->mpfarray, &array->mpfarray[1], - (array->hi_extent - array->low_extent) - * sizeof(array->mpfarray[0])); - array->mpfarray[ - array->hi_extent - array->low_extent].mpf = NULL; - if (array->low_extent != array->hi_extent) - array->low_extent++; - } else { - if (extid == array->hi_extent) - array->hi_extent--; - } - -err: MUTEX_UNLOCK(dbenv, dbp->mutex); - -#ifdef CONFIG_TEST - if (real_name != NULL) - __os_free(dbenv, real_name); -#endif - return (ret); -} - -/* - * __qam_sync -- - * Flush the database cache. - * - * PUBLIC: int __qam_sync __P((DB *)); - */ -int -__qam_sync(dbp) - DB *dbp; -{ - DB_ENV *dbenv; - DB_MPOOLFILE *mpf; - - dbenv = dbp->dbenv; - mpf = dbp->mpf; - - /* - * We need to flush all extent files. There is no easy way to find - * all the extents for this queue which are currently open. For now - * just flush the whole cache. An alternative would be to have a - * call into the cache layer that would flush all of the queue extent - * files it has open (there's a flag when we open a queue extent file, - * so the cache layer can identify them). - */ - - if (((QUEUE *)dbp->q_internal)->page_ext == 0) - return (__memp_fsync(mpf)); - else - return (__memp_sync(dbenv, NULL)); -} - -/* - * __qam_gen_filelist -- generate a list of extent files. - * Another thread may close the handle so this should only - * be used single threaded or with care. - * - * PUBLIC: int __qam_gen_filelist __P(( DB *, QUEUE_FILELIST **)); - */ -int -__qam_gen_filelist(dbp, filelistp) - DB *dbp; - QUEUE_FILELIST **filelistp; -{ - DB_ENV *dbenv; - DB_MPOOLFILE *mpf; - QUEUE *qp; - QMETA *meta; - size_t extent_cnt; - db_recno_t i, current, first, stop, rec_extent; - QUEUE_FILELIST *fp; - int ret; - - dbenv = dbp->dbenv; - mpf = dbp->mpf; - qp = (QUEUE *)dbp->q_internal; - *filelistp = NULL; - - if (qp->page_ext == 0) - return (0); - - /* This may happen during metapage recovery. */ - if (qp->name == NULL) - return (0); - - /* Find out the first and last record numbers in the database. */ - i = PGNO_BASE_MD; - if ((ret = __memp_fget(mpf, &i, 0, &meta)) != 0) - return (ret); - - current = meta->cur_recno; - first = meta->first_recno; - - if ((ret = __memp_fput(mpf, meta, 0)) != 0) - return (ret); - - /* - * Allocate the extent array. Calculate the worst case number of - * pages and convert that to a count of extents. The count of - * extents has 3 or 4 extra slots: - * roundoff at first (e.g., current record in extent); - * roundoff at current (e.g., first record in extent); - * NULL termination; and - * UINT32_MAX wraparound (the last extent can be small). - */ - rec_extent = qp->rec_page * qp->page_ext; - if (current >= first) - extent_cnt = (current - first) / rec_extent + 3; - else - extent_cnt = - (current + (UINT32_MAX - first)) / rec_extent + 4; - if ((ret = __os_calloc(dbenv, - extent_cnt, sizeof(QUEUE_FILELIST), filelistp)) != 0) - return (ret); - fp = *filelistp; - -again: - if (current >= first) - stop = current; - else - stop = UINT32_MAX; - - /* - * Make sure that first is at the same offset in the extent as stop. - * This guarantees that the stop will be reached in the loop below, - * even if it is the only record in its extent. This calculation is - * safe because first won't move out of its extent. - */ - first -= first % rec_extent; - first += stop % rec_extent; - - for (i = first; i >= first && i <= stop; i += rec_extent) { - if ((ret = __qam_fprobe(dbp, QAM_RECNO_PAGE(dbp, i), &fp->mpf, - QAM_PROBE_MPF, 0)) != 0) { - if (ret == ENOENT) - continue; - return (ret); - } - fp->id = QAM_RECNO_EXTENT(dbp, i); - fp++; - DB_ASSERT((size_t)(fp - *filelistp) < extent_cnt); - } - - if (current < first) { - first = 1; - goto again; - } - - return (0); -} - -/* - * __qam_extent_names -- generate a list of extent files names. - * - * PUBLIC: int __qam_extent_names __P((DB_ENV *, char *, char ***)); - */ -int -__qam_extent_names(dbenv, name, namelistp) - DB_ENV *dbenv; - char *name; - char ***namelistp; -{ - DB *dbp; - QUEUE *qp; - QUEUE_FILELIST *filelist, *fp; - size_t len; - int cnt, ret, t_ret; - char buf[MAXPATHLEN], **cp, *freep; - - *namelistp = NULL; - filelist = NULL; - if ((ret = db_create(&dbp, dbenv, 0)) != 0) - return (ret); - if ((ret = __db_open(dbp, - NULL, name, NULL, DB_QUEUE, DB_RDONLY, 0, PGNO_BASE_MD)) != 0) - return (ret); - qp = dbp->q_internal; - if (qp->page_ext == 0) - goto done; - - if ((ret = __qam_gen_filelist(dbp, &filelist)) != 0) - goto done; - - if (filelist == NULL) - goto done; - - cnt = 0; - for (fp = filelist; fp->mpf != NULL; fp++) - cnt++; - - /* QUEUE_EXTENT contains extra chars, but add 6 anyway for the int. */ - len = (size_t)cnt * (sizeof(**namelistp) + - strlen(QUEUE_EXTENT) + strlen(qp->dir) + strlen(qp->name) + 6); - - if ((ret = __os_malloc(dbp->dbenv, len, namelistp)) != 0) - goto done; - cp = *namelistp; - freep = (char *)(cp + cnt + 1); - for (fp = filelist; fp->mpf != NULL; fp++) { - QAM_EXNAME(qp, fp->id, buf, sizeof(buf)); - len = strlen(buf); - *cp++ = freep; - (void)strcpy(freep, buf); - freep += len + 1; - } - *cp = NULL; - -done: - if (filelist != NULL) - __os_free(dbp->dbenv, filelist); - if ((t_ret = __db_close(dbp, NULL, DB_NOSYNC)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __qam_exid -- - * Generate a fileid for an extent based on the fileid of the main - * file. Since we do not log schema creates/deletes explicitly, the log - * never captures the fileid of an extent file. In order that masters and - * replicas have the same fileids (so they can explicitly delete them), we - * use computed fileids for the extent files of Queue files. - * - * An extent file id retains the low order 12 bytes of the file id and - * overwrites the dev/inode fields, placing a 0 in the inode field, and - * the extent number in the dev field. - * - * PUBLIC: void __qam_exid __P((DB *, u_int8_t *, u_int32_t)); - */ -void -__qam_exid(dbp, fidp, exnum) - DB *dbp; - u_int8_t *fidp; - u_int32_t exnum; -{ - int i; - u_int8_t *p; - - /* Copy the fileid from the master. */ - memcpy(fidp, dbp->fileid, DB_FILE_ID_LEN); - - /* The first four bytes are the inode or the FileIndexLow; 0 it. */ - for (i = sizeof(u_int32_t); i > 0; --i) - *fidp++ = 0; - - /* The next four bytes are the dev/FileIndexHigh; insert the exnum . */ - for (p = (u_int8_t *)&exnum, i = sizeof(u_int32_t); i > 0; --i) - *fidp++ = *p++; -} - -/* - * __qam_nameop -- - * Remove or rename extent files associated with a particular file. - * This is to remove or rename (both in mpool and the file system) any - * extent files associated with the given dbp. - * This is either called from the QUEUE remove or rename methods or - * when undoing a transaction that created the database. - * - * PUBLIC: int __qam_nameop __P((DB *, DB_TXN *, const char *, qam_name_op)); - */ -int __qam_nameop(dbp, txn, newname, op) - DB *dbp; - DB_TXN *txn; - const char *newname; - qam_name_op op; -{ - DB_ENV *dbenv; - QUEUE *qp; - size_t exlen, fulllen, len; - u_int8_t fid[DB_FILE_ID_LEN]; - u_int32_t exid; - int cnt, i, ret, t_ret; - char buf[MAXPATHLEN], nbuf[MAXPATHLEN], sepsave; - char *endname, *endpath, *exname, *fullname, **names; - char *ndir, *namep, *new, *cp; - - dbenv = dbp->dbenv; - qp = (QUEUE *)dbp->q_internal; - cnt = ret = t_ret = 0; - namep = exname = fullname = NULL; - names = NULL; - - /* If this isn't a queue with extents, we're done. */ - if (qp->page_ext == 0) - return (0); - - /* - * Generate the list of all queue extents for this file (from the - * file system) and then cycle through removing them and evicting - * from mpool. We have two modes of operation here. If we are - * undoing log operations, then do not write log records and try - * to keep going even if we encounter failures in nameop. If we - * are in mainline code, then return as soon as we have a problem. - * Memory allocation errors (__db_appname, __os_malloc) are always - * considered failure. - * - * Set buf to : dir/__dbq.NAME.0 and fullname to HOME/dir/__dbq.NAME.0 - * or, in the case of an absolute path: /dir/__dbq.NAME.0 - */ - QAM_EXNAME(qp, 0, buf, sizeof(buf)); - if ((ret = - __db_appname(dbenv, DB_APP_DATA, buf, 0, NULL, &fullname)) != 0) - return (ret); - - /* We should always have a path separator here. */ - if ((endpath = __db_rpath(fullname)) == NULL) { - ret = EINVAL; - goto err; - } - sepsave = *endpath; - *endpath = '\0'; - - /* - * Get the list of all names in the directory and restore the - * path separator. - */ - if ((ret = __os_dirlist(dbenv, fullname, &names, &cnt)) != 0) - goto err; - *endpath = sepsave; - - /* If there aren't any names, don't allocate any space. */ - if (cnt == 0) - goto err; - - /* - * Now, make endpath reference the queue extent names upon which - * we can match. Then we set the end of the path to be the - * beginning of the extent number, and we can compare the bytes - * between endpath and endname (__dbq.NAME.). - */ - endpath++; - endname = strrchr(endpath, '.'); - if (endname == NULL) { - ret = EINVAL; - goto err; - } - ++endname; - *endname = '\0'; - len = strlen(endpath); - fulllen = strlen(fullname); - - /* Allocate space for a full extent name. */ - exlen = fulllen + 20; - if ((ret = __os_malloc(dbenv, exlen, &exname)) != 0) - goto err; - - ndir = new = NULL; - if (newname != NULL) { - if ((ret = __os_strdup(dbenv, newname, &namep)) != 0) - goto err; - ndir = namep; - if ((new = __db_rpath(namep)) != NULL) - *new++ = '\0'; - else { - new = namep; - ndir = PATH_DOT; - } - } - for (i = 0; i < cnt; i++) { - /* Check if this is a queue extent file. */ - if (strncmp(names[i], endpath, len) != 0) - continue; - /* Make sure we have all numbers. foo.db vs. foo.db.0. */ - for (cp = &names[i][len]; *cp != '\0'; cp++) - if (!isdigit(*cp)) - break; - if (*cp != '\0') - continue; - - /* - * We have a queue extent file. We need to generate its - * name and its fileid. - */ - exid = (u_int32_t)strtoul(names[i] + len, NULL, 10); - __qam_exid(dbp, fid, exid); - - switch (op) { - case QAM_NAME_DISCARD: - snprintf(exname, exlen, - "%s%s", fullname, names[i] + len); - if ((t_ret = __memp_nameop(dbenv, - fid, NULL, exname, NULL, - F_ISSET(dbp, DB_AM_INMEM))) != 0 && ret == 0) - ret = t_ret; - break; - - case QAM_NAME_RENAME: - snprintf(nbuf, sizeof(nbuf), QUEUE_EXTENT, - ndir, PATH_SEPARATOR[0], new, exid); - QAM_EXNAME(qp, exid, buf, sizeof(buf)); - if ((ret = __fop_rename(dbenv, - txn, buf, nbuf, fid, DB_APP_DATA, - F_ISSET(dbp, DB_AM_NOT_DURABLE) ? - DB_LOG_NOT_DURABLE : 0)) != 0) - goto err; - break; - - case QAM_NAME_REMOVE: - QAM_EXNAME(qp, exid, buf, sizeof(buf)); - if ((ret = __fop_remove(dbenv, txn, fid, buf, - DB_APP_DATA, F_ISSET(dbp, DB_AM_NOT_DURABLE) ? - DB_LOG_NOT_DURABLE : 0)) != 0) - goto err; - break; - } - } - -err: if (fullname != NULL) - __os_free(dbenv, fullname); - if (exname != NULL) - __os_free(dbenv, exname); - if (namep != NULL) - __os_free(dbenv, namep); - if (names != NULL) - __os_dirfree(dbenv, names, cnt); - return (ret); -} diff --git a/storage/bdb/qam/qam_method.c b/storage/bdb/qam/qam_method.c deleted file mode 100644 index 6be9ad75b22..00000000000 --- a/storage/bdb/qam/qam_method.c +++ /dev/null @@ -1,387 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: qam_method.c,v 12.2 2005/09/28 17:45:01 margo Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/db_am.h" -#include "dbinc/lock.h" -#include "dbinc/mp.h" -#include "dbinc/qam.h" -#include "dbinc/txn.h" - -static int __qam_rr __P((DB *, DB_TXN *, - const char *, const char *, const char *, qam_name_op)); -static int __qam_set_extentsize __P((DB *, u_int32_t)); - -/* - * __qam_db_create -- - * Queue specific initialization of the DB structure. - * - * PUBLIC: int __qam_db_create __P((DB *)); - */ -int -__qam_db_create(dbp) - DB *dbp; -{ - QUEUE *t; - int ret; - - /* Allocate and initialize the private queue structure. */ - if ((ret = __os_calloc(dbp->dbenv, 1, sizeof(QUEUE), &t)) != 0) - return (ret); - dbp->q_internal = t; - dbp->get_q_extentsize = __qam_get_extentsize; - dbp->set_q_extentsize = __qam_set_extentsize; - - t->re_pad = ' '; - - return (0); -} - -/* - * __qam_db_close -- - * Queue specific discard of the DB structure. - * - * PUBLIC: int __qam_db_close __P((DB *, u_int32_t)); - */ -int -__qam_db_close(dbp, flags) - DB *dbp; - u_int32_t flags; -{ - DB_MPOOLFILE *mpf; - MPFARRAY *array; - QUEUE *t; - struct __qmpf *mpfp; - u_int32_t i; - int ret, t_ret; - - ret = 0; - if ((t = dbp->q_internal) == NULL) - return (0); - - array = &t->array1; -again: - mpfp = array->mpfarray; - if (mpfp != NULL) { - for (i = array->low_extent; - i <= array->hi_extent; i++, mpfp++) { - mpf = mpfp->mpf; - mpfp->mpf = NULL; - if (mpf != NULL && (t_ret = __memp_fclose(mpf, - LF_ISSET(DB_AM_DISCARD) ? DB_MPOOL_DISCARD : 0)) - != 0 && ret == 0) - ret = t_ret; - } - __os_free(dbp->dbenv, array->mpfarray); - } - if (t->array2.n_extent != 0) { - array = &t->array2; - array->n_extent = 0; - goto again; - } - - if (LF_ISSET(DB_AM_DISCARD) && - (t_ret = __qam_nameop(dbp, NULL, - NULL, QAM_NAME_DISCARD)) != 0 && ret == 0) - ret = t_ret; - - if (t->path != NULL) - __os_free(dbp->dbenv, t->path); - __os_free(dbp->dbenv, t); - dbp->q_internal = NULL; - - return (ret); -} - -/* - * __qam_get_extentsize -- - * The DB->q_get_extentsize method. - * - * PUBLIC: int __qam_get_extentsize __P((DB *, u_int32_t *)); - */ -int -__qam_get_extentsize(dbp, q_extentsizep) - DB *dbp; - u_int32_t *q_extentsizep; -{ - *q_extentsizep = ((QUEUE*)dbp->q_internal)->page_ext; - return (0); -} - -static int -__qam_set_extentsize(dbp, extentsize) - DB *dbp; - u_int32_t extentsize; -{ - DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_extentsize"); - - if (extentsize < 1) { - __db_err(dbp->dbenv, "Extent size must be at least 1"); - return (EINVAL); - } - - ((QUEUE*)dbp->q_internal)->page_ext = extentsize; - - return (0); -} - -/* - * __queue_pageinfo - - * Given a dbp, get first/last page information about a queue. - * - * PUBLIC: int __queue_pageinfo __P((DB *, db_pgno_t *, db_pgno_t *, - * PUBLIC: int *, int, u_int32_t)); - */ -int -__queue_pageinfo(dbp, firstp, lastp, emptyp, prpage, flags) - DB *dbp; - db_pgno_t *firstp, *lastp; - int *emptyp; - int prpage; - u_int32_t flags; -{ - DB_MPOOLFILE *mpf; - QMETA *meta; - db_pgno_t first, i, last; - int empty, ret, t_ret; - - mpf = dbp->mpf; - - /* Find out the page number of the last page in the database. */ - i = PGNO_BASE_MD; - if ((ret = __memp_fget(mpf, &i, 0, &meta)) != 0) - return (ret); - - first = QAM_RECNO_PAGE(dbp, meta->first_recno); - last = QAM_RECNO_PAGE( - dbp, meta->cur_recno == 1 ? 1 : meta->cur_recno - 1); - - empty = meta->cur_recno == meta->first_recno; - if (firstp != NULL) - *firstp = first; - if (lastp != NULL) - *lastp = last; - if (emptyp != NULL) - *emptyp = empty; -#ifdef HAVE_STATISTICS - if (prpage) - ret = __db_prpage(dbp, (PAGE *)meta, flags); -#else - COMPQUIET(prpage, 0); - COMPQUIET(flags, 0); -#endif - - if ((t_ret = __memp_fput(mpf, meta, 0)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -#ifdef HAVE_STATISTICS -/* - * __db_prqueue -- - * Print out a queue - * - * PUBLIC: int __db_prqueue __P((DB *, u_int32_t)); - */ -int -__db_prqueue(dbp, flags) - DB *dbp; - u_int32_t flags; -{ - PAGE *h; - db_pgno_t first, i, last, pg_ext, stop; - int empty, ret; - - if ((ret = __queue_pageinfo(dbp, &first, &last, &empty, 1, flags)) != 0) - return (ret); - - if (empty || ret != 0) - return (ret); - - i = first; - if (first > last) - stop = QAM_RECNO_PAGE(dbp, UINT32_MAX); - else - stop = last; - - /* Dump each page. */ -begin: - for (; i <= stop; ++i) { - if ((ret = __qam_fget(dbp, &i, 0, &h)) != 0) { - pg_ext = ((QUEUE *)dbp->q_internal)->page_ext; - if (pg_ext == 0) { - if (ret == DB_PAGE_NOTFOUND && first == last) - return (0); - return (ret); - } - if (ret == ENOENT || ret == DB_PAGE_NOTFOUND) { - i += (pg_ext - ((i - 1) % pg_ext)) - 1; - continue; - } - return (ret); - } - (void)__db_prpage(dbp, h, flags); - if ((ret = __qam_fput(dbp, i, h, 0)) != 0) - return (ret); - } - - if (first > last) { - i = 1; - stop = last; - first = last; - goto begin; - } - return (0); -} -#endif - -/* - * __qam_remove -- - * Remove method for a Queue. - * - * PUBLIC: int __qam_remove __P((DB *, DB_TXN *, const char *, const char *)); - */ -int -__qam_remove(dbp, txn, name, subdb) - DB *dbp; - DB_TXN *txn; - const char *name, *subdb; -{ - return (__qam_rr(dbp, txn, name, subdb, NULL, QAM_NAME_REMOVE)); -} - -/* - * __qam_rename -- - * Rename method for a Queue. - * - * PUBLIC: int __qam_rename __P((DB *, - * PUBLIC: DB_TXN *, const char *, const char *, const char *)); - */ -int -__qam_rename(dbp, txn, name, subdb, newname) - DB *dbp; - DB_TXN *txn; - const char *name, *subdb, *newname; -{ - return (__qam_rr(dbp, txn, name, subdb, newname, QAM_NAME_RENAME)); -} - -/* - * __qam_rr -- - * Remove/Rename method for a Queue. - */ -static int -__qam_rr(dbp, txn, name, subdb, newname, op) - DB *dbp; - DB_TXN *txn; - const char *name, *subdb, *newname; - qam_name_op op; -{ - DB_ENV *dbenv; - DB *tmpdbp; - QUEUE *qp; - int ret, t_ret; - - dbenv = dbp->dbenv; - ret = 0; - - PANIC_CHECK(dbenv); - - if (subdb != NULL && name != NULL) { - __db_err(dbenv, - "Queue does not support multiple databases per file"); - return (EINVAL); - } - - /* - * Since regular rename no longer opens the database, we may have - * to do it here. - */ - if (F_ISSET(dbp, DB_AM_OPEN_CALLED)) - tmpdbp = dbp; - else { - if ((ret = db_create(&tmpdbp, dbenv, 0)) != 0) - return (ret); - - /* - * We need to make sure we don't self-deadlock, so give - * this dbp the same locker as the incoming one. - */ - tmpdbp->lid = dbp->lid; - if ((ret = __db_open(tmpdbp, txn, - name, NULL, DB_QUEUE, DB_RDONLY, 0, PGNO_BASE_MD)) != 0) - goto err; - } - - qp = (QUEUE *)tmpdbp->q_internal; - if (qp->page_ext != 0) - ret = __qam_nameop(tmpdbp, txn, newname, op); - - if (!F_ISSET(dbp, DB_AM_OPEN_CALLED)) { -err: /* - * Since we copied the locker ID from the dbp, we'd better not - * free it here. - */ - tmpdbp->lid = DB_LOCK_INVALIDID; - - /* We need to remove the lock event we associated with this. */ - if (txn != NULL) - __txn_remlock(dbenv, - txn, &tmpdbp->handle_lock, DB_LOCK_INVALIDID); - - if ((t_ret = - __db_close(tmpdbp, txn, DB_NOSYNC)) != 0 && ret == 0) - ret = t_ret; - } - return (ret); -} - -/* - * __qam_map_flags -- - * Map queue-specific flags from public to the internal values. - * - * PUBLIC: void __qam_map_flags __P((DB *, u_int32_t *, u_int32_t *)); - */ -void -__qam_map_flags(dbp, inflagsp, outflagsp) - DB *dbp; - u_int32_t *inflagsp, *outflagsp; -{ - COMPQUIET(dbp, NULL); - - if (FLD_ISSET(*inflagsp, DB_INORDER)) { - FLD_SET(*outflagsp, DB_AM_INORDER); - FLD_CLR(*inflagsp, DB_INORDER); - } -} - -/* - * __qam_set_flags -- - * Set queue-specific flags. - * - * PUBLIC: int __qam_set_flags __P((DB *, u_int32_t *flagsp)); - */ -int -__qam_set_flags(dbp, flagsp) - DB *dbp; - u_int32_t *flagsp; -{ - - __qam_map_flags(dbp, flagsp, &dbp->flags); - return (0); -} diff --git a/storage/bdb/qam/qam_open.c b/storage/bdb/qam/qam_open.c deleted file mode 100644 index 5f1dbecbdd8..00000000000 --- a/storage/bdb/qam/qam_open.c +++ /dev/null @@ -1,351 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: qam_open.c,v 12.4 2005/10/15 00:56:55 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/crypto.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/db_swap.h" -#include "dbinc/db_am.h" -#include "dbinc/lock.h" -#include "dbinc/mp.h" -#include "dbinc/qam.h" -#include "dbinc/fop.h" - -static int __qam_init_meta __P((DB *, QMETA *)); - -/* - * __qam_open - * - * PUBLIC: int __qam_open __P((DB *, - * PUBLIC: DB_TXN *, const char *, db_pgno_t, int, u_int32_t)); - */ -int -__qam_open(dbp, txn, name, base_pgno, mode, flags) - DB *dbp; - DB_TXN *txn; - const char *name; - db_pgno_t base_pgno; - int mode; - u_int32_t flags; -{ - DBC *dbc; - DB_ENV *dbenv; - DB_LOCK metalock; - DB_MPOOLFILE *mpf; - QMETA *qmeta; - QUEUE *t; - int ret, t_ret; - - dbenv = dbp->dbenv; - mpf = dbp->mpf; - t = dbp->q_internal; - ret = 0; - qmeta = NULL; - - if (name == NULL && t->page_ext != 0) { - __db_err(dbenv, - "Extent size may not be specified for in-memory queue database"); - return (EINVAL); - } - - /* Initialize the remaining fields/methods of the DB. */ - dbp->db_am_remove = __qam_remove; - dbp->db_am_rename = __qam_rename; - - /* - * Get a cursor. If DB_CREATE is specified, we may be creating - * pages, and to do that safely in CDB we need a write cursor. - * In STD_LOCKING mode, we'll synchronize using the meta page - * lock instead. - */ - if ((ret = __db_cursor(dbp, txn, &dbc, - LF_ISSET(DB_CREATE) && CDB_LOCKING(dbenv) ? - DB_WRITECURSOR : 0)) != 0) - return (ret); - - /* - * Get the meta data page. It must exist, because creates of - * files/databases come in through the __qam_new_file interface - * and queue doesn't support subdatabases. - */ - if ((ret = - __db_lget(dbc, 0, base_pgno, DB_LOCK_READ, 0, &metalock)) != 0) - goto err; - if ((ret = __memp_fget(mpf, &base_pgno, 0, &qmeta)) != 0) - goto err; - - /* If the magic number is incorrect, that's a fatal error. */ - if (qmeta->dbmeta.magic != DB_QAMMAGIC) { - __db_err(dbenv, "%s: unexpected file type or format", name); - ret = EINVAL; - goto err; - } - - /* Setup information needed to open extents. */ - t->page_ext = qmeta->page_ext; - - if (t->page_ext != 0 && (ret = __qam_set_ext_data(dbp, name)) != 0) - goto err; - - if (mode == 0) - mode = __db_omode("rw-rw----"); - t->mode = mode; - t->re_pad = qmeta->re_pad; - t->re_len = qmeta->re_len; - t->rec_page = qmeta->rec_page; - - t->q_meta = base_pgno; - t->q_root = base_pgno + 1; - -err: if (qmeta != NULL && - (t_ret = __memp_fput(mpf, qmeta, 0)) != 0 && ret == 0) - ret = t_ret; - - /* Don't hold the meta page long term. */ - if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0) - ret = t_ret; - - if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __qam_set_ext_data -- - * Setup DBP data for opening queue extents. - * - * PUBLIC: int __qam_set_ext_data __P((DB*, const char *)); - */ -int -__qam_set_ext_data(dbp, name) - DB *dbp; - const char *name; -{ - QUEUE *t; - int ret; - - t = dbp->q_internal; - t->pginfo.db_pagesize = dbp->pgsize; - t->pginfo.flags = - F_ISSET(dbp, (DB_AM_CHKSUM | DB_AM_ENCRYPT | DB_AM_SWAP)); - t->pginfo.type = dbp->type; - t->pgcookie.data = &t->pginfo; - t->pgcookie.size = sizeof(DB_PGINFO); - - if ((ret = __os_strdup(dbp->dbenv, name, &t->path)) != 0) - return (ret); - t->dir = t->path; - if ((t->name = __db_rpath(t->path)) == NULL) { - t->name = t->path; - t->dir = PATH_DOT; - } else - *t->name++ = '\0'; - - return (0); -} - -/* - * __qam_metachk -- - * - * PUBLIC: int __qam_metachk __P((DB *, const char *, QMETA *)); - */ -int -__qam_metachk(dbp, name, qmeta) - DB *dbp; - const char *name; - QMETA *qmeta; -{ - DB_ENV *dbenv; - u_int32_t vers; - int ret; - - dbenv = dbp->dbenv; - ret = 0; - - /* - * At this point, all we know is that the magic number is for a Queue. - * Check the version, the database may be out of date. - */ - vers = qmeta->dbmeta.version; - if (F_ISSET(dbp, DB_AM_SWAP)) - M_32_SWAP(vers); - switch (vers) { - case 1: - case 2: - __db_err(dbenv, - "%s: queue version %lu requires a version upgrade", - name, (u_long)vers); - return (DB_OLD_VERSION); - case 3: - case 4: - break; - default: - __db_err(dbenv, - "%s: unsupported qam version: %lu", name, (u_long)vers); - return (EINVAL); - } - - /* Swap the page if we need to. */ - if (F_ISSET(dbp, DB_AM_SWAP) && (ret = __qam_mswap((PAGE *)qmeta)) != 0) - return (ret); - - /* Check the type. */ - if (dbp->type != DB_QUEUE && dbp->type != DB_UNKNOWN) - return (EINVAL); - dbp->type = DB_QUEUE; - DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE); - - /* Set the page size. */ - dbp->pgsize = qmeta->dbmeta.pagesize; - - /* Copy the file's ID. */ - memcpy(dbp->fileid, qmeta->dbmeta.uid, DB_FILE_ID_LEN); - - /* Set up AM-specific methods that do not require an open. */ - dbp->db_am_rename = __qam_rename; - dbp->db_am_remove = __qam_remove; - - return (ret); -} - -/* - * __qam_init_meta -- - * Initialize the meta-data for a Queue database. - */ -static int -__qam_init_meta(dbp, meta) - DB *dbp; - QMETA *meta; -{ - QUEUE *t; - - t = dbp->q_internal; - - memset(meta, 0, sizeof(QMETA)); - LSN_NOT_LOGGED(meta->dbmeta.lsn); - meta->dbmeta.pgno = PGNO_BASE_MD; - meta->dbmeta.last_pgno = 0; - meta->dbmeta.magic = DB_QAMMAGIC; - meta->dbmeta.version = DB_QAMVERSION; - meta->dbmeta.pagesize = dbp->pgsize; - if (F_ISSET(dbp, DB_AM_CHKSUM)) - FLD_SET(meta->dbmeta.metaflags, DBMETA_CHKSUM); - if (F_ISSET(dbp, DB_AM_ENCRYPT)) { - meta->dbmeta.encrypt_alg = - ((DB_CIPHER *)dbp->dbenv->crypto_handle)->alg; - DB_ASSERT(meta->dbmeta.encrypt_alg != 0); - meta->crypto_magic = meta->dbmeta.magic; - } - meta->dbmeta.type = P_QAMMETA; - meta->re_pad = t->re_pad; - meta->re_len = t->re_len; - meta->rec_page = CALC_QAM_RECNO_PER_PAGE(dbp); - meta->cur_recno = 1; - meta->first_recno = 1; - meta->page_ext = t->page_ext; - t->rec_page = meta->rec_page; - memcpy(meta->dbmeta.uid, dbp->fileid, DB_FILE_ID_LEN); - - /* Verify that we can fit at least one record per page. */ - if (QAM_RECNO_PER_PAGE(dbp) < 1) { - __db_err(dbp->dbenv, - "Record size of %lu too large for page size of %lu", - (u_long)t->re_len, (u_long)dbp->pgsize); - return (EINVAL); - } - - return (0); -} - -/* - * __qam_new_file -- - * Create the necessary pages to begin a new queue database file. - * - * This code appears more complex than it is because of the two cases (named - * and unnamed). The way to read the code is that for each page being created, - * there are three parts: 1) a "get page" chunk (which either uses malloc'd - * memory or calls __memp_fget), 2) the initialization, and 3) the "put page" - * chunk which either does a fop write or an __memp_fput. - * - * PUBLIC: int __qam_new_file __P((DB *, DB_TXN *, DB_FH *, const char *)); - */ -int -__qam_new_file(dbp, txn, fhp, name) - DB *dbp; - DB_TXN *txn; - DB_FH *fhp; - const char *name; -{ - QMETA *meta; - DB_ENV *dbenv; - DB_MPOOLFILE *mpf; - DB_PGINFO pginfo; - DBT pdbt; - db_pgno_t pgno; - int ret; - void *buf; - - dbenv = dbp->dbenv; - mpf = dbp->mpf; - buf = NULL; - meta = NULL; - - /* Build meta-data page. */ - - if (F_ISSET(dbp, DB_AM_INMEM)) { - pgno = PGNO_BASE_MD; - ret = __memp_fget(mpf, &pgno, DB_MPOOL_CREATE, &meta); - } else { - ret = __os_calloc(dbenv, 1, dbp->pgsize, &buf); - meta = (QMETA *)buf; - } - if (ret != 0) - return (ret); - - if ((ret = __qam_init_meta(dbp, meta)) != 0) - goto err; - - if (F_ISSET(dbp, DB_AM_INMEM)) { - if ((ret = __db_log_page(dbp, - txn, &meta->dbmeta.lsn, pgno, (PAGE *)meta)) != 0) - goto err; - ret = __memp_fput(mpf, meta, DB_MPOOL_DIRTY); - } else { - pginfo.db_pagesize = dbp->pgsize; - pginfo.flags = - F_ISSET(dbp, (DB_AM_CHKSUM | DB_AM_ENCRYPT | DB_AM_SWAP)); - pginfo.type = DB_QUEUE; - pdbt.data = &pginfo; - pdbt.size = sizeof(pginfo); - if ((ret = __db_pgout(dbenv, PGNO_BASE_MD, meta, &pdbt)) != 0) - goto err; - ret = __fop_write(dbenv, txn, name, - DB_APP_DATA, fhp, dbp->pgsize, 0, 0, buf, dbp->pgsize, 1, - F_ISSET(dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0); - } - if (ret != 0) - goto err; - meta = NULL; - -err: if (name != NULL) - __os_free(dbenv, buf); - else if (meta != NULL) - (void)__memp_fput(mpf, meta, 0); - return (ret); -} diff --git a/storage/bdb/qam/qam_rec.c b/storage/bdb/qam/qam_rec.c deleted file mode 100644 index 6751f64a4c1..00000000000 --- a/storage/bdb/qam/qam_rec.c +++ /dev/null @@ -1,634 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: qam_rec.c,v 12.8 2005/10/20 18:57:13 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/db_am.h" -#include "dbinc/lock.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" -#include "dbinc/qam.h" -#include "dbinc/txn.h" - -/* Determine if we are restoring prepared transactions from __txn_recover. */ -#define IS_IN_RESTORE(dbenv) \ - (((DB_TXNREGION *)((DB_TXNMGR *) \ - (dbenv)->tx_handle)->reginfo.primary)->stat.st_nrestores != 0) - -/* - * __qam_incfirst_recover -- - * Recovery function for incfirst. - * - * PUBLIC: int __qam_incfirst_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__qam_incfirst_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __qam_incfirst_args *argp; - DB *file_dbp; - DBC *dbc; - DB_LOCK lock; - DB_LSN trunc_lsn; - DB_MPOOLFILE *mpf; - QMETA *meta; - QUEUE_CURSOR *cp; - db_pgno_t metapg; - u_int32_t rec_ext; - int exact, modified, ret, t_ret; - - LOCK_INIT(lock); - COMPQUIET(meta, NULL); - REC_PRINT(__qam_incfirst_print); - REC_INTRO(__qam_incfirst_read, 1, 1); - - metapg = ((QUEUE *)file_dbp->q_internal)->q_meta; - - if ((ret = __db_lget(dbc, - LCK_ROLLBACK, metapg, DB_LOCK_WRITE, 0, &lock)) != 0) - goto done; - if ((ret = __memp_fget(mpf, &metapg, 0, &meta)) != 0) { - if (DB_REDO(op)) { - if ((ret = __memp_fget(mpf, - &metapg, DB_MPOOL_CREATE, &meta)) != 0) { - (void)__LPUT(dbc, lock); - goto out; - } - meta->dbmeta.pgno = metapg; - meta->dbmeta.type = P_QAMMETA; - } else { - *lsnp = argp->prev_lsn; - ret = __LPUT(dbc, lock); - goto out; - } - } - - modified = 0; - - /* - * Only move first_recno backwards so we pick up the aborted delete. - * When going forward we need to be careful since - * we may have bumped over a locked record. - */ - if (DB_UNDO(op)) { - if (QAM_BEFORE_FIRST(meta, argp->recno)) { - meta->first_recno = argp->recno; - modified = 1; - } - - trunc_lsn = ((DB_TXNHEAD *)info)->trunc_lsn; - /* if we are truncating, update the LSN */ - if (!IS_ZERO_LSN(trunc_lsn) && - log_compare(&LSN(meta), &trunc_lsn) > 0) { - LSN(meta) = trunc_lsn; - modified = 1; - } - } else { - if (log_compare(&LSN(meta), lsnp) < 0) { - LSN(meta) = *lsnp; - modified = 1; - } - if (meta->page_ext == 0) - rec_ext = 0; - else - rec_ext = meta->page_ext * meta->rec_page; - cp = (QUEUE_CURSOR *)dbc->internal; - if (meta->first_recno == RECNO_OOB) - meta->first_recno++; - while (meta->first_recno != meta->cur_recno && - !QAM_BEFORE_FIRST(meta, argp->recno + 1)) { - if ((ret = __qam_position(dbc, - &meta->first_recno, QAM_READ, &exact)) != 0) - goto err; - if (cp->page != NULL && (ret = - __qam_fput(file_dbp, cp->pgno, cp->page, 0)) != 0) - goto err; - - if (exact == 1) - break; - if (cp->page != NULL && - rec_ext != 0 && meta->first_recno % rec_ext == 0) - if ((ret = - __qam_fremove(file_dbp, cp->pgno)) != 0) - goto err; - meta->first_recno++; - if (meta->first_recno == RECNO_OOB) - meta->first_recno++; - modified = 1; - } - } - - ret = __memp_fput(mpf, meta, modified ? DB_MPOOL_DIRTY : 0); - if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0) - ret = t_ret; - if (ret != 0) - goto out; - -done: *lsnp = argp->prev_lsn; - ret = 0; - - if (0) { -err: (void)__memp_fput(mpf, meta, 0); - (void)__LPUT(dbc, lock); - } - -out: REC_CLOSE; -} - -/* - * __qam_mvptr_recover -- - * Recovery function for mvptr. - * - * PUBLIC: int __qam_mvptr_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__qam_mvptr_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __qam_mvptr_args *argp; - DB *file_dbp; - DBC *dbc; - DB_LSN trunc_lsn; - DB_LOCK lock; - DB_MPOOLFILE *mpf; - QMETA *meta; - QUEUE_CURSOR *cp; - db_pgno_t metapg; - int cmp_n, cmp_p, exact, modified, ret; - - REC_PRINT(__qam_mvptr_print); - REC_INTRO(__qam_mvptr_read, 1, 1); - - metapg = ((QUEUE *)file_dbp->q_internal)->q_meta; - - if ((ret = __db_lget(dbc, - LCK_ROLLBACK, metapg, DB_LOCK_WRITE, 0, &lock)) != 0) - goto done; - if ((ret = __memp_fget(mpf, &metapg, 0, &meta)) != 0) { - if (DB_REDO(op)) { - if ((ret = __memp_fget(mpf, - &metapg, DB_MPOOL_CREATE, &meta)) != 0) { - (void)__LPUT(dbc, lock); - goto out; - } - meta->dbmeta.pgno = metapg; - meta->dbmeta.type = P_QAMMETA; - } else { - *lsnp = argp->prev_lsn; - ret = __LPUT(dbc, lock); - goto out; - } - } - - modified = 0; - cmp_n = log_compare(lsnp, &LSN(meta)); - cmp_p = log_compare(&LSN(meta), &argp->metalsn); - - /* - * Under normal circumstances, we never undo a movement of one of - * the pointers. Just move them along regardless of abort/commit. - * When going forward we need to verify that this is really where - * the pointer belongs. A transaction may roll back and reinsert - * a record that was missing at the time of this action. - * - * If we're undoing a truncate, we need to reset the pointers to - * their state before the truncate. - */ - if (DB_UNDO(op)) { - if ((argp->opcode & QAM_TRUNCATE) && cmp_n <= 0) { - meta->first_recno = argp->old_first; - meta->cur_recno = argp->old_cur; - LSN(meta) = argp->metalsn; - modified = 1; - } - /* If the page lsn is beyond the truncate point, move it back */ - trunc_lsn = ((DB_TXNHEAD *)info)->trunc_lsn; - if (!IS_ZERO_LSN(trunc_lsn) && - log_compare(&trunc_lsn, &LSN(meta)) < 0) { - LSN(meta) = argp->metalsn; - modified = 1; - } - } else if (op == DB_TXN_APPLY || cmp_p == 0) { - cp = (QUEUE_CURSOR *)dbc->internal; - if ((argp->opcode & QAM_SETFIRST) && - meta->first_recno == argp->old_first) { - if ((ret = __qam_position(dbc, - &meta->first_recno, QAM_READ, &exact)) != 0) - goto err; - if (!exact) - meta->first_recno = argp->new_first; - if (cp->page != NULL && (ret = - __qam_fput(file_dbp, cp->pgno, cp->page, 0)) != 0) - goto err; - } - - if ((argp->opcode & QAM_SETCUR) && - meta->cur_recno == argp->old_cur) { - if ((ret = __qam_position(dbc, - &meta->cur_recno, QAM_READ, &exact)) != 0) - goto err; - if (!exact) - meta->cur_recno = argp->new_cur; - if (cp->page != NULL && (ret = - __qam_fput(file_dbp, cp->pgno, cp->page, 0)) != 0) - goto err; - } - - modified = 1; - meta->dbmeta.lsn = *lsnp; - } - - if ((ret = __memp_fput(mpf, meta, modified ? DB_MPOOL_DIRTY : 0)) != 0) - goto out; - - if ((ret = __LPUT(dbc, lock)) != 0) - goto out; - -done: *lsnp = argp->prev_lsn; - ret = 0; - - if (0) { -err: (void)__memp_fput(mpf, meta, 0); - (void)__LPUT(dbc, lock); - } - -out: REC_CLOSE; -} - -/* - * __qam_del_recover -- - * Recovery function for del. - * Non-extent version or if there is no data (zero len). - * - * PUBLIC: int __qam_del_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__qam_del_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __qam_del_args *argp; - DB *file_dbp; - DBC *dbc; - DB_LOCK lock; - DB_MPOOLFILE *mpf; - QAMDATA *qp; - QMETA *meta; - QPAGE *pagep; - db_pgno_t metapg; - int cmp_n, modified, ret, t_ret; - - COMPQUIET(info, NULL); - COMPQUIET(pagep, NULL); - REC_PRINT(__qam_del_print); - REC_INTRO(__qam_del_read, 1, 1); - - if ((ret = __qam_fget(file_dbp, - &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) - goto out; - - modified = 0; - if (pagep->pgno == PGNO_INVALID) { - pagep->pgno = argp->pgno; - pagep->type = P_QAMDATA; - modified = 1; - } - - cmp_n = log_compare(lsnp, &LSN(pagep)); - - if (DB_UNDO(op)) { - /* make sure first is behind us */ - metapg = ((QUEUE *)file_dbp->q_internal)->q_meta; - if ((ret = __db_lget(dbc, - LCK_ROLLBACK, metapg, DB_LOCK_WRITE, 0, &lock)) != 0) - goto err; - if ((ret = __memp_fget(mpf, &metapg, 0, &meta)) != 0) { - (void)__LPUT(dbc, lock); - goto err; - } - if (meta->first_recno == RECNO_OOB || - (QAM_BEFORE_FIRST(meta, argp->recno) && - (meta->first_recno <= meta->cur_recno || - meta->first_recno - - argp->recno < argp->recno - meta->cur_recno))) { - meta->first_recno = argp->recno; - ret = __memp_fput(mpf, meta, DB_MPOOL_DIRTY); - } else - ret = __memp_fput(mpf, meta, 0); - if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0) - ret = t_ret; - if (ret != 0) - goto err; - - /* Need to undo delete - mark the record as present */ - qp = QAM_GET_RECORD(file_dbp, pagep, argp->indx); - F_SET(qp, QAM_VALID); - - /* - * Move the LSN back to this point; do not move it forward. - * Only move it back if we're in recovery. If we're in - * an abort, because we don't hold a page lock, we could - * foul up a concurrent put. Having too late an LSN - * is harmless in queue except when we're determining - * what we need to roll forward during recovery. [#2588] - * If we are aborting a restored transaction then it - * might get rolled forward later so the LSN needs to - * be correct in that case too. [#12181] - */ - if (cmp_n <= 0 && - (op == DB_TXN_BACKWARD_ROLL || IS_IN_RESTORE(dbenv))) - LSN(pagep) = argp->lsn; - modified = 1; - } else if (op == DB_TXN_APPLY || (cmp_n > 0 && DB_REDO(op))) { - /* Need to redo delete - clear the valid bit */ - qp = QAM_GET_RECORD(file_dbp, pagep, argp->indx); - F_CLR(qp, QAM_VALID); - LSN(pagep) = *lsnp; - modified = 1; - } - if ((ret = __qam_fput(file_dbp, - argp->pgno, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0) - goto out; - -done: *lsnp = argp->prev_lsn; - ret = 0; - - if (0) { -err: (void)__qam_fput(file_dbp, argp->pgno, pagep, 0); - } -out: REC_CLOSE; -} - -/* - * __qam_delext_recover -- - * Recovery function for del in an extent based queue. - * - * PUBLIC: int __qam_delext_recover __P((DB_ENV *, - * PUBLIC: DBT *, DB_LSN *, db_recops, void *)); - */ -int -__qam_delext_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __qam_delext_args *argp; - DB *file_dbp; - DBC *dbc; - DB_LOCK lock; - DB_MPOOLFILE *mpf; - QAMDATA *qp; - QMETA *meta; - QPAGE *pagep; - db_pgno_t metapg; - int cmp_n, modified, ret, t_ret; - - COMPQUIET(info, NULL); - COMPQUIET(pagep, NULL); - REC_PRINT(__qam_delext_print); - REC_INTRO(__qam_delext_read, 1, 1); - - if ((ret = __qam_fget(file_dbp, &argp->pgno, 0, &pagep)) != 0) { - if (ret != DB_PAGE_NOTFOUND && ret != ENOENT) - goto out; - /* - * If we are redoing a delete and the page is not there - * we are done. - */ - if (DB_REDO(op)) - goto done; - if ((ret = __qam_fget(file_dbp, - &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) - goto out; - } - - modified = 0; - if (pagep->pgno == PGNO_INVALID) { - pagep->pgno = argp->pgno; - pagep->type = P_QAMDATA; - modified = 1; - } - - cmp_n = log_compare(lsnp, &LSN(pagep)); - - if (DB_UNDO(op)) { - /* make sure first is behind us */ - metapg = ((QUEUE *)file_dbp->q_internal)->q_meta; - if ((ret = __db_lget(dbc, - LCK_ROLLBACK, metapg, DB_LOCK_WRITE, 0, &lock)) != 0) - goto err; - if ((ret = __memp_fget(mpf, &metapg, 0, &meta)) != 0) { - (void)__LPUT(dbc, lock); - goto err; - } - if (meta->first_recno == RECNO_OOB || - (QAM_BEFORE_FIRST(meta, argp->recno) && - (meta->first_recno <= meta->cur_recno || - meta->first_recno - - argp->recno < argp->recno - meta->cur_recno))) { - meta->first_recno = argp->recno; - ret = __memp_fput(mpf, meta, DB_MPOOL_DIRTY); - } else - ret = __memp_fput(mpf, meta, 0); - if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0) - ret = t_ret; - if (ret != 0) - goto err; - - if ((ret = __qam_pitem(dbc, pagep, - argp->indx, argp->recno, &argp->data)) != 0) - goto err; - - /* - * Move the LSN back to this point; do not move it forward. - * Only move it back if we're in recovery. If we're in - * an abort, because we don't hold a page lock, we could - * foul up a concurrent put. Having too late an LSN - * is harmless in queue except when we're determining - * what we need to roll forward during recovery. [#2588] - */ - if (cmp_n <= 0 && - (op == DB_TXN_BACKWARD_ROLL || IS_IN_RESTORE(dbenv))) - LSN(pagep) = argp->lsn; - modified = 1; - } else if (op == DB_TXN_APPLY || (cmp_n > 0 && DB_REDO(op))) { - /* Need to redo delete - clear the valid bit */ - qp = QAM_GET_RECORD(file_dbp, pagep, argp->indx); - F_CLR(qp, QAM_VALID); - LSN(pagep) = *lsnp; - modified = 1; - } - if ((ret = __qam_fput(file_dbp, - argp->pgno, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0) - goto out; - -done: *lsnp = argp->prev_lsn; - ret = 0; - - if (0) { -err: (void)__qam_fput(file_dbp, argp->pgno, pagep, 0); - } -out: REC_CLOSE; -} - -/* - * __qam_add_recover -- - * Recovery function for add. - * - * PUBLIC: int __qam_add_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__qam_add_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __qam_add_args *argp; - DB *file_dbp; - DBC *dbc; - DB_MPOOLFILE *mpf; - QAMDATA *qp; - QMETA *meta; - QPAGE *pagep; - db_pgno_t metapg; - int cmp_n, meta_dirty, modified, ret; - - COMPQUIET(info, NULL); - COMPQUIET(pagep, NULL); - REC_PRINT(__qam_add_print); - REC_INTRO(__qam_add_read, 1, 1); - - modified = 0; - if ((ret = __qam_fget(file_dbp, &argp->pgno, 0, &pagep)) != 0) { - if (ret != DB_PAGE_NOTFOUND && ret != ENOENT) - goto out; - /* - * If we are undoing an append and the page is not there - * we are done. - */ - if (DB_UNDO(op)) - goto done; - if ((ret = __qam_fget(file_dbp, - &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) - goto out; - } - - if (pagep->pgno == PGNO_INVALID) { - pagep->pgno = argp->pgno; - pagep->type = P_QAMDATA; - modified = 1; - } - - cmp_n = log_compare(lsnp, &LSN(pagep)); - - if (DB_REDO(op)) { - /* Fix meta-data page. */ - metapg = ((QUEUE *)file_dbp->q_internal)->q_meta; - if ((ret = __memp_fget(mpf, &metapg, 0, &meta)) != 0) - goto err; - meta_dirty = 0; - if (QAM_BEFORE_FIRST(meta, argp->recno)) { - meta->first_recno = argp->recno; - meta_dirty = 1; - } - if (argp->recno == meta->cur_recno || - QAM_AFTER_CURRENT(meta, argp->recno)) { - meta->cur_recno = argp->recno + 1; - meta_dirty = 1; - } - if ((ret = __memp_fput(mpf, - meta, meta_dirty? DB_MPOOL_DIRTY : 0)) != 0) - goto err; - - /* Now update the actual page if necessary. */ - if (op == DB_TXN_APPLY || cmp_n > 0) { - /* Need to redo add - put the record on page */ - if ((ret = __qam_pitem(dbc, - pagep, argp->indx, argp->recno, &argp->data)) != 0) - goto err; - LSN(pagep) = *lsnp; - modified = 1; - } - } else if (DB_UNDO(op)) { - /* - * Need to undo add - * If this was an overwrite, put old record back. - * Otherwise just clear the valid bit - */ - if (argp->olddata.size != 0) { - if ((ret = __qam_pitem(dbc, pagep, - argp->indx, argp->recno, &argp->olddata)) != 0) - goto err; - - if (!(argp->vflag & QAM_VALID)) { - qp = QAM_GET_RECORD( - file_dbp, pagep, argp->indx); - F_CLR(qp, QAM_VALID); - } - modified = 1; - } else { - qp = QAM_GET_RECORD(file_dbp, pagep, argp->indx); - qp->flags = 0; - modified = 1; - } - - /* - * Move the LSN back to this point; do not move it forward. - * Only move it back if we're in recovery. If we're in - * an abort, because we don't hold a page lock, we could - * foul up a concurrent put. Having too late an LSN - * is harmless in queue except when we're determining - * what we need to roll forward during recovery. [#2588] - */ - if (cmp_n <= 0 && - (op == DB_TXN_BACKWARD_ROLL || IS_IN_RESTORE(dbenv))) - LSN(pagep) = argp->lsn; - } - - if ((ret = __qam_fput(file_dbp, - argp->pgno, pagep, modified ? DB_MPOOL_DIRTY : 0)) != 0) - goto out; - -done: *lsnp = argp->prev_lsn; - ret = 0; - - if (0) { -err: (void)__qam_fput(file_dbp, argp->pgno, pagep, 0); - } - -out: REC_CLOSE; -} diff --git a/storage/bdb/qam/qam_stat.c b/storage/bdb/qam/qam_stat.c deleted file mode 100644 index d6d28b5cc81..00000000000 --- a/storage/bdb/qam/qam_stat.c +++ /dev/null @@ -1,261 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: qam_stat.c,v 12.1 2005/06/16 20:23:33 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <ctype.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/db_am.h" -#include "dbinc/lock.h" -#include "dbinc/mp.h" -#include "dbinc/qam.h" - -#ifdef HAVE_STATISTICS -/* - * __qam_stat -- - * Gather/print the qam statistics - * - * PUBLIC: int __qam_stat __P((DBC *, void *, u_int32_t)); - */ -int -__qam_stat(dbc, spp, flags) - DBC *dbc; - void *spp; - u_int32_t flags; -{ - DB *dbp; - DB_LOCK lock; - DB_MPOOLFILE *mpf; - DB_QUEUE_STAT *sp; - PAGE *h; - QAMDATA *qp, *ep; - QMETA *meta; - QUEUE *t; - db_indx_t indx; - db_pgno_t first, last, pgno, pg_ext, stop; - u_int32_t re_len; - int ret, t_ret; - - dbp = dbc->dbp; - - LOCK_INIT(lock); - mpf = dbp->mpf; - sp = NULL; - t = dbp->q_internal; - - if (spp == NULL) - return (0); - - /* Allocate and clear the structure. */ - if ((ret = __os_umalloc(dbp->dbenv, sizeof(*sp), &sp)) != 0) - goto err; - memset(sp, 0, sizeof(*sp)); - - re_len = ((QUEUE *)dbp->q_internal)->re_len; - - /* Determine the last page of the database. */ - if ((ret = __db_lget(dbc, 0, t->q_meta, DB_LOCK_READ, 0, &lock)) != 0) - goto err; - if ((ret = __memp_fget(mpf, &t->q_meta, 0, &meta)) != 0) - goto err; - - if (flags == DB_FAST_STAT || flags == DB_CACHED_COUNTS) { - sp->qs_nkeys = meta->dbmeta.key_count; - sp->qs_ndata = meta->dbmeta.record_count; - goto meta_only; - } - - first = QAM_RECNO_PAGE(dbp, meta->first_recno); - last = QAM_RECNO_PAGE(dbp, meta->cur_recno); - - ret = __memp_fput(mpf, meta, 0); - if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0) - ret = t_ret; - if (ret != 0) - goto err; - - pgno = first; - if (first > last) - stop = QAM_RECNO_PAGE(dbp, UINT32_MAX); - else - stop = last; - - /* Dump each page. */ - pg_ext = ((QUEUE *)dbp->q_internal)->page_ext; -begin: - /* Walk through the pages and count. */ - for (; pgno <= stop; ++pgno) { - if ((ret = - __db_lget(dbc, 0, pgno, DB_LOCK_READ, 0, &lock)) != 0) - goto err; - ret = __qam_fget(dbp, &pgno, 0, &h); - if (ret == ENOENT) { - pgno += pg_ext - 1; - continue; - } - if (ret == DB_PAGE_NOTFOUND) { - if (pg_ext == 0) { - if (pgno != stop && first != last) - goto err; - ret = 0; - break; - } - pgno += (pg_ext - ((pgno - 1) % pg_ext)) - 1; - continue; - } - if (ret != 0) - goto err; - - ++sp->qs_pages; - - ep = (QAMDATA *)((u_int8_t *)h + dbp->pgsize - re_len); - for (indx = 0, qp = QAM_GET_RECORD(dbp, h, indx); - qp <= ep; - ++indx, qp = QAM_GET_RECORD(dbp, h, indx)) { - if (F_ISSET(qp, QAM_VALID)) - sp->qs_ndata++; - else - sp->qs_pgfree += re_len; - } - - ret = __qam_fput(dbp, pgno, h, 0); - if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0) - ret = t_ret; - if (ret != 0) - goto err; - } - - if ((ret = __LPUT(dbc, lock)) != 0) - goto err; - if (first > last) { - pgno = 1; - stop = last; - first = last; - goto begin; - } - - /* Get the meta-data page. */ - if ((ret = __db_lget(dbc, - 0, t->q_meta, F_ISSET(dbp, DB_AM_RDONLY) ? - DB_LOCK_READ : DB_LOCK_WRITE, 0, &lock)) != 0) - goto err; - if ((ret = __memp_fget(mpf, &t->q_meta, 0, &meta)) != 0) - goto err; - - if (!F_ISSET(dbp, DB_AM_RDONLY)) - meta->dbmeta.key_count = - meta->dbmeta.record_count = sp->qs_ndata; - sp->qs_nkeys = sp->qs_ndata; - -meta_only: - /* Get the metadata fields. */ - sp->qs_magic = meta->dbmeta.magic; - sp->qs_version = meta->dbmeta.version; - sp->qs_metaflags = meta->dbmeta.flags; - sp->qs_pagesize = meta->dbmeta.pagesize; - sp->qs_extentsize = meta->page_ext; - sp->qs_re_len = meta->re_len; - sp->qs_re_pad = meta->re_pad; - sp->qs_first_recno = meta->first_recno; - sp->qs_cur_recno = meta->cur_recno; - - /* Discard the meta-data page. */ - ret = __memp_fput(mpf, - meta, F_ISSET(dbp, DB_AM_RDONLY) ? 0 : DB_MPOOL_DIRTY); - if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0) - ret = t_ret; - if (ret != 0) - goto err; - - *(DB_QUEUE_STAT **)spp = sp; - - if (0) { -err: if (sp != NULL) - __os_ufree(dbp->dbenv, sp); - } - - if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __qam_stat_print -- - * Display queue statistics. - * - * PUBLIC: int __qam_stat_print __P((DBC *, u_int32_t)); - */ -int -__qam_stat_print(dbc, flags) - DBC *dbc; - u_int32_t flags; -{ - DB *dbp; - DB_ENV *dbenv; - DB_QUEUE_STAT *sp; - int ret; - - dbp = dbc->dbp; - dbenv = dbp->dbenv; - - if ((ret = __qam_stat(dbc, &sp, 0)) != 0) - return (ret); - - if (LF_ISSET(DB_STAT_ALL)) { - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_msg(dbenv, "Default Queue database information:"); - } - __db_msg(dbenv, "%lx\tQueue magic number", (u_long)sp->qs_magic); - __db_msg(dbenv, "%lu\tQueue version number", (u_long)sp->qs_version); - __db_dl(dbenv, "Fixed-length record size", (u_long)sp->qs_re_len); - __db_msg(dbenv, "%#x\tFixed-length record pad", (int)sp->qs_re_pad); - __db_dl(dbenv, - "Underlying database page size", (u_long)sp->qs_pagesize); - __db_dl(dbenv, - "Underlying database extent size", (u_long)sp->qs_extentsize); - __db_dl(dbenv, - "Number of records in the database", (u_long)sp->qs_nkeys); - __db_dl(dbenv, "Number of database pages", (u_long)sp->qs_pages); - __db_dl_pct(dbenv, - "Number of bytes free in database pages", - (u_long)sp->qs_pgfree, - DB_PCT_PG(sp->qs_pgfree, sp->qs_pages, sp->qs_pagesize), "ff"); - __db_msg(dbenv, - "%lu\tFirst undeleted record", (u_long)sp->qs_first_recno); - __db_msg(dbenv, - "%lu\tNext available record number", (u_long)sp->qs_cur_recno); - - __os_ufree(dbenv, sp); - - return (0); -} - -#else /* !HAVE_STATISTICS */ - -int -__qam_stat(dbc, spp, flags) - DBC *dbc; - void *spp; - u_int32_t flags; -{ - COMPQUIET(spp, NULL); - COMPQUIET(flags, 0); - - return (__db_stat_not_built(dbc->dbp->dbenv)); -} -#endif diff --git a/storage/bdb/qam/qam_stub.c b/storage/bdb/qam/qam_stub.c deleted file mode 100644 index f8149881324..00000000000 --- a/storage/bdb/qam/qam_stub.c +++ /dev/null @@ -1,334 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: qam_stub.c,v 12.1 2005/06/16 20:23:33 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef HAVE_QUEUE -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/qam.h" - -/* - * If the library wasn't compiled with the Queue access method, various - * routines aren't available. Stub them here, returning an appropriate - * error. - */ - -/* - * __db_no_queue_am -- - * Error when a Berkeley DB build doesn't include the access method. - * - * PUBLIC: int __db_no_queue_am __P((DB_ENV *)); - */ -int -__db_no_queue_am(dbenv) - DB_ENV *dbenv; -{ - __db_err(dbenv, - "library build did not include support for the Queue access method"); - return (DB_OPNOTSUP); -} - -int -__db_prqueue(dbp, flags) - DB *dbp; - u_int32_t flags; -{ - COMPQUIET(flags, 0); - return (__db_no_queue_am(dbp->dbenv)); -} - -int -__qam_31_qammeta(dbp, real_name, buf) - DB *dbp; - char *real_name; - u_int8_t *buf; -{ - COMPQUIET(real_name, NULL); - COMPQUIET(buf, NULL); - return (__db_no_queue_am(dbp->dbenv)); -} - -int -__qam_32_qammeta(dbp, real_name, buf) - DB *dbp; - char *real_name; - u_int8_t *buf; -{ - COMPQUIET(real_name, NULL); - COMPQUIET(buf, NULL); - return (__db_no_queue_am(dbp->dbenv)); -} - -int -__qam_append(dbc, key, data) - DBC *dbc; - DBT *key, *data; -{ - COMPQUIET(key, NULL); - COMPQUIET(data, NULL); - return (__db_no_queue_am(dbc->dbp->dbenv)); -} - -int -__qam_c_dup(orig_dbc, new_dbc) - DBC *orig_dbc, *new_dbc; -{ - COMPQUIET(new_dbc, NULL); - return (__db_no_queue_am(orig_dbc->dbp->dbenv)); -} - -int -__qam_c_init(dbc) - DBC *dbc; -{ - return (__db_no_queue_am(dbc->dbp->dbenv)); -} - -int -__qam_db_close(dbp, flags) - DB *dbp; - u_int32_t flags; -{ - COMPQUIET(dbp, NULL); - COMPQUIET(flags, 0); - return (0); -} - -int -__qam_db_create(dbp) - DB *dbp; -{ - COMPQUIET(dbp, NULL); - return (0); -} - -int -__qam_extent_names(dbenv, name, namelistp) - DB_ENV *dbenv; - char *name; - char ***namelistp; -{ - COMPQUIET(name, NULL); - COMPQUIET(namelistp, NULL); - return (__db_no_queue_am(dbenv)); -} - -int -__qam_gen_filelist(dbp, filelistp) - DB *dbp; - QUEUE_FILELIST **filelistp; -{ - COMPQUIET(filelistp, NULL); - return (__db_no_queue_am(dbp->dbenv)); -} - -int -__qam_init_print(dbenv, dtabp, dtabsizep) - DB_ENV *dbenv; - int (***dtabp)__P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - size_t *dtabsizep; -{ - COMPQUIET(dbenv, NULL); - COMPQUIET(dtabp, NULL); - COMPQUIET(dtabsizep, NULL); - return (0); -} - -int -__qam_init_recover(dbenv, dtabp, dtabsizep) - DB_ENV *dbenv; - int (***dtabp)__P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - size_t *dtabsizep; -{ - COMPQUIET(dbenv, NULL); - COMPQUIET(dtabp, NULL); - COMPQUIET(dtabsizep, NULL); - return (0); -} - -int -__qam_metachk(dbp, name, qmeta) - DB *dbp; - const char *name; - QMETA *qmeta; -{ - COMPQUIET(name, NULL); - COMPQUIET(qmeta, NULL); - return (__db_no_queue_am(dbp->dbenv)); -} - -int -__qam_new_file(dbp, txn, fhp, name) - DB *dbp; - DB_TXN *txn; - DB_FH *fhp; - const char *name; -{ - COMPQUIET(txn, NULL); - COMPQUIET(fhp, NULL); - COMPQUIET(name, NULL); - return (__db_no_queue_am(dbp->dbenv)); -} - -int -__qam_open(dbp, txn, name, base_pgno, mode, flags) - DB *dbp; - DB_TXN *txn; - const char *name; - db_pgno_t base_pgno; - int mode; - u_int32_t flags; -{ - COMPQUIET(txn, NULL); - COMPQUIET(name, NULL); - COMPQUIET(base_pgno, 0); - COMPQUIET(mode, 0); - COMPQUIET(flags, 0); - return (__db_no_queue_am(dbp->dbenv)); -} - -int -__qam_pgin_out(dbenv, pg, pp, cookie) - DB_ENV *dbenv; - db_pgno_t pg; - void *pp; - DBT *cookie; -{ - COMPQUIET(pg, 0); - COMPQUIET(pp, NULL); - COMPQUIET(cookie, NULL); - return (__db_no_queue_am(dbenv)); -} - -int -__qam_salvage(dbp, vdp, pgno, h, handle, callback, flags) - DB *dbp; - VRFY_DBINFO *vdp; - db_pgno_t pgno; - PAGE *h; - void *handle; - int (*callback) __P((void *, const void *)); - u_int32_t flags; -{ - COMPQUIET(vdp, NULL); - COMPQUIET(pgno, 0); - COMPQUIET(h, NULL); - COMPQUIET(handle, NULL); - COMPQUIET(callback, NULL); - COMPQUIET(flags, 0); - return (__db_no_queue_am(dbp->dbenv)); -} - -int -__qam_set_ext_data(dbp, name) - DB *dbp; - const char *name; -{ - COMPQUIET(name, NULL); - return (__db_no_queue_am(dbp->dbenv)); -} - -int -__qam_stat(dbc, spp, flags) - DBC *dbc; - void *spp; - u_int32_t flags; -{ - COMPQUIET(spp, NULL); - COMPQUIET(flags, 0); - return (__db_no_queue_am(dbc->dbp->dbenv)); -} - -int -__qam_stat_print(dbc, flags) - DBC *dbc; - u_int32_t flags; -{ - COMPQUIET(flags, 0); - return (__db_no_queue_am(dbc->dbp->dbenv)); -} - -int -__qam_sync(dbp) - DB *dbp; -{ - return (__db_no_queue_am(dbp->dbenv)); -} - -int -__qam_truncate(dbc, countp) - DBC *dbc; - u_int32_t *countp; -{ - COMPQUIET(dbc, NULL); - COMPQUIET(countp, NULL); - return (__db_no_queue_am(dbc->dbp->dbenv)); -} - -int -__qam_vrfy_data(dbp, vdp, h, pgno, flags) - DB *dbp; - VRFY_DBINFO *vdp; - QPAGE *h; - db_pgno_t pgno; - u_int32_t flags; -{ - COMPQUIET(vdp, NULL); - COMPQUIET(h, NULL); - COMPQUIET(pgno, 0); - COMPQUIET(flags, 0); - return (__db_no_queue_am(dbp->dbenv)); -} - -int -__qam_vrfy_meta(dbp, vdp, meta, pgno, flags) - DB *dbp; - VRFY_DBINFO *vdp; - QMETA *meta; - db_pgno_t pgno; - u_int32_t flags; -{ - COMPQUIET(vdp, NULL); - COMPQUIET(meta, NULL); - COMPQUIET(pgno, 0); - COMPQUIET(flags, 0); - return (__db_no_queue_am(dbp->dbenv)); -} - -int -__qam_vrfy_structure(dbp, vdp, flags) - DB *dbp; - VRFY_DBINFO *vdp; - u_int32_t flags; -{ - COMPQUIET(vdp, NULL); - COMPQUIET(flags, 0); - return (__db_no_queue_am(dbp->dbenv)); -} - -int -__qam_vrfy_walkqueue(dbp, vdp, handle, callback, flags) - DB *dbp; - VRFY_DBINFO *vdp; - void *handle; - int (*callback) __P((void *, const void *)); - u_int32_t flags; -{ - COMPQUIET(vdp, NULL); - COMPQUIET(handle, NULL); - COMPQUIET(callback, NULL); - COMPQUIET(flags, 0); - return (__db_no_queue_am(dbp->dbenv)); -} -#endif /* !HAVE_QUEUE */ diff --git a/storage/bdb/qam/qam_upgrade.c b/storage/bdb/qam/qam_upgrade.c deleted file mode 100644 index 383b0c0a416..00000000000 --- a/storage/bdb/qam/qam_upgrade.c +++ /dev/null @@ -1,108 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: qam_upgrade.c,v 12.1 2005/06/16 20:23:33 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_upgrade.h" -#include "dbinc/db_page.h" -#include "dbinc/qam.h" - -/* - * __qam_31_qammeta -- - * Upgrade the database from version 1 to version 2. - * - * PUBLIC: int __qam_31_qammeta __P((DB *, char *, u_int8_t *)); - */ -int -__qam_31_qammeta(dbp, real_name, buf) - DB *dbp; - char *real_name; - u_int8_t *buf; -{ - QMETA31 *newmeta; - QMETA30 *oldmeta; - - COMPQUIET(dbp, NULL); - COMPQUIET(real_name, NULL); - - newmeta = (QMETA31 *)buf; - oldmeta = (QMETA30 *)buf; - - /* - * Copy the fields to their new locations. - * They may overlap so start at the bottom and use memmove(). - */ - newmeta->rec_page = oldmeta->rec_page; - newmeta->re_pad = oldmeta->re_pad; - newmeta->re_len = oldmeta->re_len; - newmeta->cur_recno = oldmeta->cur_recno; - newmeta->first_recno = oldmeta->first_recno; - newmeta->start = oldmeta->start; - memmove(newmeta->dbmeta.uid, - oldmeta->dbmeta.uid, sizeof(oldmeta->dbmeta.uid)); - newmeta->dbmeta.flags = oldmeta->dbmeta.flags; - newmeta->dbmeta.record_count = 0; - newmeta->dbmeta.key_count = 0; - ZERO_LSN(newmeta->dbmeta.unused3); - - /* Update the version. */ - newmeta->dbmeta.version = 2; - - return (0); -} - -/* - * __qam_32_qammeta -- - * Upgrade the database from version 2 to version 3. - * - * PUBLIC: int __qam_32_qammeta __P((DB *, char *, u_int8_t *)); - */ -int -__qam_32_qammeta(dbp, real_name, buf) - DB *dbp; - char *real_name; - u_int8_t *buf; -{ - QMETA32 *newmeta; - QMETA31 *oldmeta; - - COMPQUIET(dbp, NULL); - COMPQUIET(real_name, NULL); - - newmeta = (QMETA32 *)buf; - oldmeta = (QMETA31 *)buf; - - /* - * Copy the fields to their new locations. - * We are dropping the first field so move - * from the top. - */ - newmeta->first_recno = oldmeta->first_recno; - newmeta->cur_recno = oldmeta->cur_recno; - newmeta->re_len = oldmeta->re_len; - newmeta->re_pad = oldmeta->re_pad; - newmeta->rec_page = oldmeta->rec_page; - newmeta->page_ext = 0; - /* cur_recno now points to the first free slot. */ - newmeta->cur_recno++; - if (newmeta->first_recno == 0) - newmeta->first_recno = 1; - - /* Update the version. */ - newmeta->dbmeta.version = 3; - - return (0); -} diff --git a/storage/bdb/qam/qam_verify.c b/storage/bdb/qam/qam_verify.c deleted file mode 100644 index 535cbe28a4c..00000000000 --- a/storage/bdb/qam/qam_verify.c +++ /dev/null @@ -1,518 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1999-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: qam_verify.c,v 12.3 2005/06/16 20:23:34 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#include <stdlib.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_verify.h" -#include "dbinc/db_am.h" -#include "dbinc/db_shash.h" -#include "dbinc/mp.h" -#include "dbinc/qam.h" -/* - * __qam_vrfy_meta -- - * Verify the queue-specific part of a metadata page. - * - * PUBLIC: int __qam_vrfy_meta __P((DB *, VRFY_DBINFO *, QMETA *, - * PUBLIC: db_pgno_t, u_int32_t)); - */ -int -__qam_vrfy_meta(dbp, vdp, meta, pgno, flags) - DB *dbp; - VRFY_DBINFO *vdp; - QMETA *meta; - db_pgno_t pgno; - u_int32_t flags; -{ - DB_ENV *dbenv; - QUEUE *qp; - VRFY_PAGEINFO *pip; - db_pgno_t *extents, extid, first, last; - size_t len; - int count, i, isbad, nextents, ret, t_ret; - char *buf, **names; - - COMPQUIET(count, 0); - - dbenv = dbp->dbenv; - qp = (QUEUE *)dbp->q_internal; - extents = NULL; - first = last = 0; - buf = NULL; - names = NULL; - - if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) - return (ret); - isbad = 0; - - /* - * Queue can't be used in subdatabases, so if this isn't set - * something very odd is going on. - */ - if (!F_ISSET(pip, VRFY_INCOMPLETE)) - EPRINT((dbenv, "Page %lu: queue databases must be one-per-file", - (u_long)pgno)); - - /* - * Because the metapage pointers are rolled forward by - * aborting transactions, the extent of the queue may - * extend beyond the allocated pages, so we do - * not check that meta_current is within the allocated - * pages. - */ - - /* - * re_len: If this is bad, we can't safely verify queue data pages, so - * return DB_VERIFY_FATAL - */ - if (DB_ALIGN(meta->re_len + sizeof(QAMDATA) - 1, sizeof(u_int32_t)) * - meta->rec_page + QPAGE_SZ(dbp) > dbp->pgsize) { - EPRINT((dbenv, - "Page %lu: queue record length %lu too high for page size and recs/page", - (u_long)pgno, (u_long)meta->re_len)); - ret = DB_VERIFY_FATAL; - goto err; - } else { - /* - * We initialize the Queue internal pointer; we may need - * it when handling extents. It would get set up in open, - * if we called open normally, but we don't. - */ - vdp->re_pad = meta->re_pad; - qp->re_pad = (int)meta->re_pad; - qp->re_len = vdp->re_len = meta->re_len; - qp->rec_page = vdp->rec_page = meta->rec_page; - qp->page_ext = vdp->page_ext = meta->page_ext; - } - - /* - * There's no formal maximum extentsize, and a 0 value represents - * no extents, so there's nothing to verify. - * - * Note that since QUEUE databases can't have subdatabases, it's an - * error to see more than one QUEUE metadata page in a single - * verifier run. Theoretically, this should really be a structure - * rather than a per-page check, but since we're setting qp fields - * here (and have only one qp to set) we raise the alarm now if - * this assumption fails. (We need the qp info to be reasonable - * before we do per-page verification of queue extents.) - */ - if (F_ISSET(vdp, VRFY_QMETA_SET)) { - isbad = 1; - EPRINT((dbenv, - "Page %lu: database contains multiple Queue metadata pages", - (u_long)pgno)); - goto err; - } - F_SET(vdp, VRFY_QMETA_SET); - qp->page_ext = meta->page_ext; - dbp->pgsize = meta->dbmeta.pagesize; - qp->q_meta = pgno; - qp->q_root = pgno + 1; - vdp->first_recno = meta->first_recno; - vdp->last_recno = meta->cur_recno; - if (qp->page_ext != 0) { - first = QAM_RECNO_EXTENT(dbp, vdp->first_recno); - last = QAM_RECNO_EXTENT(dbp, vdp->last_recno); - } - - /* - * Look in the data directory to see if there are any extents - * around that are not in the range of the queue. If so, - * then report that and look there if we are salvaging. - */ - - if ((ret = __db_appname(dbenv, - DB_APP_DATA, qp->dir, 0, NULL, &buf)) != 0) - goto err; - if ((ret = __os_dirlist(dbenv, buf, &names, &count)) != 0) - goto err; - __os_free(dbenv, buf); - buf = NULL; - - len = strlen(QUEUE_EXTENT_HEAD) + strlen(qp->name) + 1; - if ((ret = __os_malloc(dbenv, len, &buf)) != 0) - goto err; - len = (size_t)snprintf(buf, len, QUEUE_EXTENT_HEAD, qp->name); - for (i = nextents = 0; i < count; i++) { - if (strncmp(names[i], buf, len) == 0) { - /* Only save extents out of bounds. */ - extid = (db_pgno_t)strtoul(&names[i][len], NULL, 10); - if (qp->page_ext != 0 && - (last > first ? - (extid >= first && extid <= last) : - (extid >= first || extid <= last))) - continue; - if (extents == NULL && (ret = __os_malloc( - dbenv, (size_t)(count - i) * sizeof(extid), - &extents)) != 0) - goto err; - extents[nextents] = extid; - nextents++; - } - } - if (nextents > 0) - __db_err(dbenv, - "Warning: %d extra extent files found", nextents); - vdp->nextents = nextents; - vdp->extents = extents; - -err: if ((t_ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0 && ret == 0) - ret = t_ret; - if (names != NULL) - __os_dirfree(dbenv, names, count); - if (buf != NULL) - __os_free(dbenv, buf); - if (ret != 0 && extents != NULL) - __os_free(dbenv, extents); - if (LF_ISSET(DB_SALVAGE) && - (t_ret = __db_salvage_markdone(vdp, pgno)) != 0 && ret == 0) - ret = t_ret; - return (ret == 0 && isbad == 1 ? DB_VERIFY_BAD : ret); -} - -/* - * __qam_vrfy_data -- - * Verify a queue data page. - * - * PUBLIC: int __qam_vrfy_data __P((DB *, VRFY_DBINFO *, QPAGE *, - * PUBLIC: db_pgno_t, u_int32_t)); - */ -int -__qam_vrfy_data(dbp, vdp, h, pgno, flags) - DB *dbp; - VRFY_DBINFO *vdp; - QPAGE *h; - db_pgno_t pgno; - u_int32_t flags; -{ - DB fakedb; - struct __queue fakeq; - QAMDATA *qp; - db_recno_t i; - - /* - * Not much to do here, except make sure that flags are reasonable. - * - * QAM_GET_RECORD assumes a properly initialized q_internal - * structure, however, and we don't have one, so we play - * some gross games to fake it out. - */ - fakedb.q_internal = &fakeq; - fakedb.flags = dbp->flags; - fakeq.re_len = vdp->re_len; - - for (i = 0; i < vdp->rec_page; i++) { - qp = QAM_GET_RECORD(&fakedb, h, i); - if ((u_int8_t *)qp >= (u_int8_t *)h + dbp->pgsize) { - EPRINT((dbp->dbenv, - "Page %lu: queue record %lu extends past end of page", - (u_long)pgno, (u_long)i)); - return (DB_VERIFY_BAD); - } - - if (qp->flags & ~(QAM_VALID | QAM_SET)) { - EPRINT((dbp->dbenv, - "Page %lu: queue record %lu has bad flags (%#lx)", - (u_long)pgno, (u_long)i, (u_long)qp->flags)); - return (DB_VERIFY_BAD); - } - } - - return (0); -} - -/* - * __qam_vrfy_structure -- - * Verify a queue database structure, such as it is. - * - * PUBLIC: int __qam_vrfy_structure __P((DB *, VRFY_DBINFO *, u_int32_t)); - */ -int -__qam_vrfy_structure(dbp, vdp, flags) - DB *dbp; - VRFY_DBINFO *vdp; - u_int32_t flags; -{ - VRFY_PAGEINFO *pip; - db_pgno_t i; - int ret, isbad; - - isbad = 0; - - if ((ret = __db_vrfy_getpageinfo(vdp, PGNO_BASE_MD, &pip)) != 0) - return (ret); - - if (pip->type != P_QAMMETA) { - EPRINT((dbp->dbenv, - "Page %lu: queue database has no meta page", - (u_long)PGNO_BASE_MD)); - isbad = 1; - goto err; - } - - if ((ret = __db_vrfy_pgset_inc(vdp->pgset, 0)) != 0) - goto err; - - for (i = 1; i <= vdp->last_pgno; i++) { - /* Send feedback to the application about our progress. */ - if (!LF_ISSET(DB_SALVAGE)) - __db_vrfy_struct_feedback(dbp, vdp); - - if ((ret = __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0 || - (ret = __db_vrfy_getpageinfo(vdp, i, &pip)) != 0) - return (ret); - if (!F_ISSET(pip, VRFY_IS_ALLZEROES) && - pip->type != P_QAMDATA) { - EPRINT((dbp->dbenv, - "Page %lu: queue database page of incorrect type %lu", - (u_long)i, (u_long)pip->type)); - isbad = 1; - goto err; - } else if ((ret = __db_vrfy_pgset_inc(vdp->pgset, i)) != 0) - goto err; - } - -err: if ((ret = __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0) - return (ret); - return (isbad == 1 ? DB_VERIFY_BAD : 0); -} - -/* - * __qam_vrfy_walkqueue -- - * Do a "walkpages" per-page verification pass over the set of Queue - * extent pages. - * - * PUBLIC: int __qam_vrfy_walkqueue __P((DB *, VRFY_DBINFO *, void *, - * PUBLIC: int (*)(void *, const void *), u_int32_t)); - */ -int -__qam_vrfy_walkqueue(dbp, vdp, handle, callback, flags) - DB *dbp; - VRFY_DBINFO *vdp; - void *handle; - int (*callback) __P((void *, const void *)); - u_int32_t flags; -{ - DB_ENV *dbenv; - PAGE *h; - QUEUE *qp; - VRFY_PAGEINFO *pip; - db_pgno_t first, i, last, pg_ext, stop; - int isbad, nextents, ret, t_ret; - - COMPQUIET(h, NULL); - - dbenv = dbp->dbenv; - qp = dbp->q_internal; - pip = NULL; - pg_ext = qp->page_ext; - isbad = ret = t_ret = 0; - - /* If this database has no extents, we've seen all the pages already. */ - if (pg_ext == 0) - return (0); - - first = QAM_RECNO_PAGE(dbp, vdp->first_recno); - last = QAM_RECNO_PAGE(dbp, vdp->last_recno); - - i = first; - if (first > last) - stop = QAM_RECNO_PAGE(dbp, UINT32_MAX); - else - stop = last; - nextents = vdp->nextents; - - /* Verify/salvage each page. */ -begin: for (; i <= stop; i++) { - /* - * If DB_SALVAGE is set, we inspect our database of completed - * pages, and skip any we've already printed in the subdb pass. - */ - if (LF_ISSET(DB_SALVAGE) && (__db_salvage_isdone(vdp, i) != 0)) - continue; - if ((t_ret = __qam_fget(dbp, &i, 0, &h)) != 0) { - if (t_ret == ENOENT || t_ret == DB_PAGE_NOTFOUND) { - i += (pg_ext - ((i - 1) % pg_ext)) - 1; - continue; - } - - /* - * If an individual page get fails, keep going iff - * we're salvaging. - */ - if (LF_ISSET(DB_SALVAGE)) { - if (ret == 0) - ret = t_ret; - continue; - } else - return (t_ret); - } - - if (LF_ISSET(DB_SALVAGE)) { - /* - * We pretty much don't want to quit unless a - * bomb hits. May as well return that something - * was screwy, however. - */ - if ((t_ret = __db_salvage(dbp, - vdp, i, h, handle, callback, flags)) != 0) { - if (ret == 0) - ret = t_ret; - isbad = 1; - } - } else { - /* - * If we are not salvaging, and we get any error - * other than DB_VERIFY_BAD, return immediately; - * it may not be safe to proceed. If we get - * DB_VERIFY_BAD, keep going; listing more errors - * may make it easier to diagnose problems and - * determine the magnitude of the corruption. - */ - if ((ret = __db_vrfy_common(dbp, - vdp, h, i, flags)) == DB_VERIFY_BAD) - isbad = 1; - else if (ret != 0) - goto err; - - __db_vrfy_struct_feedback(dbp, vdp); - - if ((ret = __db_vrfy_getpageinfo(vdp, i, &pip)) != 0) - return (ret); - if (F_ISSET(pip, VRFY_IS_ALLZEROES)) - goto put; - if (pip->type != P_QAMDATA) { - EPRINT((dbenv, - "Page %lu: queue database page of incorrect type %lu", - (u_long)i, (u_long)pip->type)); - isbad = 1; - goto err; - } - if ((ret = __db_vrfy_pgset_inc(vdp->pgset, i)) != 0) - goto err; - if ((ret = __qam_vrfy_data(dbp, vdp, - (QPAGE *)h, i, flags)) == DB_VERIFY_BAD) - isbad = 1; - else if (ret != 0) - goto err; - -put: if ((ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0) - goto err; - pip = NULL; - } - - /* Again, keep going iff we're salvaging. */ - if ((t_ret = __qam_fput(dbp, i, h, 0)) != 0) { - if (LF_ISSET(DB_SALVAGE)) { - if (ret == 0) - ret = t_ret; - continue; - } else - return (t_ret); - } - } - - if (first > last) { - i = 1; - stop = last; - first = last; - goto begin; - } - - /* - * Now check to see if there were any lingering - * extents and dump their data. - */ - if (LF_ISSET(DB_SALVAGE) && nextents != 0) { - nextents--; - i = 1 + - vdp->extents[nextents] * vdp->page_ext; - stop = i + vdp->page_ext; - goto begin; - } - - if (0) { -err: if ((t_ret = __qam_fput(dbp, i, h, 0)) != 0) - return (ret == 0 ? t_ret : ret); - if (pip != NULL && - (t_ret = __db_vrfy_putpageinfo(dbenv, vdp, pip)) != 0) - return (ret == 0 ? t_ret : ret); - } - return ((isbad == 1 && ret == 0) ? DB_VERIFY_BAD : ret); -} - -/* - * __qam_salvage -- - * Safely dump out all recnos and data on a queue page. - * - * PUBLIC: int __qam_salvage __P((DB *, VRFY_DBINFO *, db_pgno_t, PAGE *, - * PUBLIC: void *, int (*)(void *, const void *), u_int32_t)); - */ -int -__qam_salvage(dbp, vdp, pgno, h, handle, callback, flags) - DB *dbp; - VRFY_DBINFO *vdp; - db_pgno_t pgno; - PAGE *h; - void *handle; - int (*callback) __P((void *, const void *)); - u_int32_t flags; -{ - DBT dbt, key; - QAMDATA *qp, *qep; - db_recno_t recno; - int ret, err_ret, t_ret; - u_int32_t pagesize, qlen; - u_int32_t i; - - memset(&dbt, 0, sizeof(DBT)); - memset(&key, 0, sizeof(DBT)); - - err_ret = ret = 0; - - pagesize = (u_int32_t)dbp->mpf->mfp->stat.st_pagesize; - qlen = ((QUEUE *)dbp->q_internal)->re_len; - dbt.size = qlen; - key.data = &recno; - key.size = sizeof(recno); - recno = (pgno - 1) * QAM_RECNO_PER_PAGE(dbp) + 1; - i = 0; - qep = (QAMDATA *)((u_int8_t *)h + pagesize - qlen); - for (qp = QAM_GET_RECORD(dbp, h, i); qp < qep; - recno++, i++, qp = QAM_GET_RECORD(dbp, h, i)) { - if (F_ISSET(qp, ~(QAM_VALID|QAM_SET))) - continue; - if (!F_ISSET(qp, QAM_SET)) - continue; - - if (!LF_ISSET(DB_AGGRESSIVE) && !F_ISSET(qp, QAM_VALID)) - continue; - - dbt.data = qp->data; - if ((ret = __db_vrfy_prdbt(&key, - 0, " ", handle, callback, 1, vdp)) != 0) - err_ret = ret; - - if ((ret = __db_vrfy_prdbt(&dbt, - 0, " ", handle, callback, 0, vdp)) != 0) - err_ret = ret; - } - - if ((t_ret = __db_salvage_markdone(vdp, pgno)) != 0) - return (t_ret); - return ((ret == 0 && err_ret != 0) ? err_ret : ret); -} diff --git a/storage/bdb/rep/rep.src b/storage/bdb/rep/rep.src deleted file mode 100644 index d1b207f5b3b..00000000000 --- a/storage/bdb/rep/rep.src +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2001-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: rep.src,v 12.3 2005/10/27 13:27:03 bostic Exp $ - */ - -PREFIX __rep -DBPRIVATE - -INCLUDE #ifndef NO_SYSTEM_INCLUDES -INCLUDE #include <stdlib.h> -INCLUDE #include <string.h> -INCLUDE #endif -INCLUDE -INCLUDE #include "db_int.h" -INCLUDE #include "dbinc/db_page.h" -INCLUDE #include "dbinc/db_shash.h" -INCLUDE #include "dbinc/db_am.h" -INCLUDE #include "dbinc/log.h" -INCLUDE #include "dbinc/mp.h" -INCLUDE #include "dbinc/txn.h" -INCLUDE - -/* - * update - send update information - */ -BEGIN_BUF update -POINTER first_lsn DB_LSN * lu -ARG num_files u_int32_t lu -END - -/* - * file info - */ -BEGIN_BUF fileinfo -ARG pgsize u_int32_t lu -ARG pgno db_pgno_t lu -ARG max_pgno db_pgno_t lu -ARG filenum u_int32_t lu -ARG id int32_t d -ARG type u_int32_t lu -ARG flags u_int32_t lu -DBT uid DBT s -DBT info DBT s -END diff --git a/storage/bdb/rep/rep_backup.c b/storage/bdb/rep/rep_backup.c deleted file mode 100644 index b19e387d382..00000000000 --- a/storage/bdb/rep/rep_backup.c +++ /dev/null @@ -1,1962 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2004-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: rep_backup.c,v 12.38 2005/11/09 14:17:30 margo Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#if TIME_WITH_SYS_TIME -#include <sys/time.h> -#include <time.h> -#else -#if HAVE_SYS_TIME_H -#include <sys/time.h> -#else -#include <time.h> -#endif -#endif - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/db_am.h" -#include "dbinc/lock.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" -#include "dbinc/qam.h" -#include "dbinc/txn.h" - -static int __rep_filedone __P((DB_ENV *, int, REP *, __rep_fileinfo_args *, - u_int32_t)); -static int __rep_find_dbs __P((DB_ENV *, u_int8_t *, size_t *, - size_t *, u_int32_t *)); -static int __rep_get_fileinfo __P((DB_ENV *, const char *, - const char *, __rep_fileinfo_args *, u_int8_t *, u_int32_t *)); -static int __rep_log_setup __P((DB_ENV *, REP *)); -static int __rep_mpf_open __P((DB_ENV *, DB_MPOOLFILE **, - __rep_fileinfo_args *, u_int32_t)); -static int __rep_page_gap __P((DB_ENV *, REP *, __rep_fileinfo_args *, - u_int32_t)); -static int __rep_page_sendpages __P((DB_ENV *, int, - __rep_fileinfo_args *, DB_MPOOLFILE *, DB *)); -static int __rep_queue_filedone __P((DB_ENV *, REP *, __rep_fileinfo_args *)); -static int __rep_walk_dir __P((DB_ENV *, const char *, u_int8_t *, - size_t *, size_t *, u_int32_t *)); -static int __rep_write_page __P((DB_ENV *, REP *, __rep_fileinfo_args *)); - -/* - * __rep_update_req - - * Process an update_req and send the file information to the client. - * - * PUBLIC: int __rep_update_req __P((DB_ENV *, int)); - */ -int -__rep_update_req(dbenv, eid) - DB_ENV *dbenv; - int eid; -{ - DBT updbt; - DB_LOG *dblp; - DB_LSN lsn; - size_t filelen, filesz, updlen; - u_int32_t filecnt; - u_int8_t *buf, *fp; - int ret; - - /* - * Allocate enough for all currently open files and then some. - * Optimize for the common use of having most databases open. - * Allocate dbentry_cnt * 2 plus an estimated 60 bytes per - * file for the filename/path (or multiplied by 120). - * - * The data we send looks like this: - * __rep_update_args - * __rep_fileinfo_args - * __rep_fileinfo_args - * ... - */ - dblp = dbenv->lg_handle; - filecnt = 0; - filelen = 0; - updlen = 0; - filesz = MEGABYTE; - if ((ret = __os_calloc(dbenv, 1, filesz, &buf)) != 0) - return (ret); - - /* - * First get our file information. Get in-memory files first - * then get on-disk files. - */ - fp = buf + sizeof(__rep_update_args); - if ((ret = __rep_find_dbs(dbenv, fp, &filesz, &filelen, &filecnt)) != 0) - goto err; - - /* - * Now get our first LSN. We send the lsn of the first - * non-archivable log file. - */ - if ((ret = __log_get_stable_lsn(dbenv, &lsn)) != 0) - goto err; - - /* - * Package up the update information. - */ - if ((ret = __rep_update_buf(buf, filesz, &updlen, &lsn, filecnt)) != 0) - goto err; - /* - * We have all the file information now. Send it to the client. - */ - memset(&updbt, 0, sizeof(updbt)); - updbt.data = buf; - updbt.size = (u_int32_t)(filelen + updlen); - LOG_SYSTEM_LOCK(dbenv); - lsn = ((LOG *)dblp->reginfo.primary)->lsn; - LOG_SYSTEM_UNLOCK(dbenv); - (void)__rep_send_message(dbenv, eid, REP_UPDATE, &lsn, &updbt, 0, - DB_REP_ANYWHERE); - -err: - __os_free(dbenv, buf); - return (ret); -} - -/* - * __rep_find_dbs - - * Walk through all the named files/databases including those in the - * environment or data_dirs and those that in named and in-memory. We - * need to open them, gather the necessary information and then close - * them. Then we need to figure out if they're already in the dbentry - * array. - */ -static int -__rep_find_dbs(dbenv, fp, fileszp, filelenp, filecntp) - DB_ENV *dbenv; - u_int8_t *fp; - size_t *fileszp, *filelenp; - u_int32_t *filecntp; -{ - int ret; - char **ddir; - - ret = 0; - if (dbenv->db_data_dir == NULL) { - /* - * If we don't have a data dir, we have just the - * env home dir. - */ - ret = __rep_walk_dir(dbenv, dbenv->db_home, fp, - fileszp, filelenp, filecntp); - } else { - for (ddir = dbenv->db_data_dir; *ddir != NULL; ++ddir) - if ((ret = __rep_walk_dir(dbenv, *ddir, fp, - fileszp, filelenp, filecntp)) != 0) - break; - } - - /* Now, collect any in-memory named databases. */ - if (ret == 0) - ret = __rep_walk_dir(dbenv, - NULL, fp, fileszp, filelenp, filecntp); - - return (ret); -} - -/* - * __rep_walk_dir -- - * - * This is the routine that walks a directory and fills in the structures - * that we use to generate messages to the client telling it what files - * files are available. If the directory name is NULL, then we should - * walk the list of in-memory named files. - */ -int -__rep_walk_dir(dbenv, dir, fp, fileszp, filelenp, filecntp) - DB_ENV *dbenv; - const char *dir; - u_int8_t *fp; - size_t *fileszp, *filelenp; - u_int32_t *filecntp; -{ - DBT namedbt, uiddbt; - __rep_fileinfo_args tmpfp; - size_t len, offset; - int cnt, i, ret; - u_int8_t *rfp, uid[DB_FILE_ID_LEN]; - char *file, **names, *subdb; -#ifdef DIAGNOSTIC - REP *rep; - DB_MSGBUF mb; - DB_REP *db_rep; - - db_rep = dbenv->rep_handle; - rep = db_rep->region; -#endif - memset(&namedbt, 0, sizeof(namedbt)); - memset(&uiddbt, 0, sizeof(uiddbt)); - if (dir == NULL) { - RPRINT(dbenv, rep, (dbenv, &mb, - "Walk_dir: Getting info for in-memory named files")); - if ((ret = __memp_inmemlist(dbenv, &names, &cnt)) != 0) - return (ret); - } else { - RPRINT(dbenv, rep, (dbenv, &mb, - "Walk_dir: Getting info for dir: %s", dir)); - if ((ret = __os_dirlist(dbenv, dir, &names, &cnt)) != 0) - return (ret); - } - rfp = fp; - RPRINT(dbenv, rep, (dbenv, &mb, - "Walk_dir: Dir %s has %d files", dir, cnt)); - for (i = 0; i < cnt; i++) { - RPRINT(dbenv, rep, (dbenv, &mb, - "Walk_dir: File %d name: %s", i, names[i])); - /* - * Skip DB-owned files: ., .., __db*, DB_CONFIG, log* - */ - if (strcmp(names[i], ".") == 0) - continue; - if (strcmp(names[i], "..") == 0) - continue; - if (strncmp(names[i], "__db", 4) == 0) - continue; - if (strncmp(names[i], "DB_CONFIG", 9) == 0) - continue; - if (strncmp(names[i], "log", 3) == 0) - continue; - /* - * We found a file to process. Check if we need - * to allocate more space. - */ - if (dir == NULL) { - file = NULL; - subdb = names[i]; - } else { - file = names[i]; - subdb = NULL; - } - if ((ret = __rep_get_fileinfo(dbenv, - file, subdb, &tmpfp, uid, filecntp)) != 0) { - /* - * If we find a file that isn't a database, skip it. - */ - RPRINT(dbenv, rep, (dbenv, &mb, - "Walk_dir: File %d %s: returned error %s", - i, names[i], db_strerror(ret))); - ret = 0; - continue; - } - RPRINT(dbenv, rep, (dbenv, &mb, - "Walk_dir: File %d (of %d) %s: pgsize %lu, max_pgno %lu", - tmpfp.filenum, i, names[i], - (u_long)tmpfp.pgsize, (u_long)tmpfp.max_pgno)); - namedbt.data = names[i]; - namedbt.size = (u_int32_t)strlen(names[i]) + 1; - uiddbt.data = uid; - uiddbt.size = DB_FILE_ID_LEN; -retry: - ret = __rep_fileinfo_buf(rfp, *fileszp, &len, - tmpfp.pgsize, tmpfp.pgno, tmpfp.max_pgno, - tmpfp.filenum, tmpfp.id, tmpfp.type, - tmpfp.flags, &uiddbt, &namedbt); - if (ret == ENOMEM) { - offset = (size_t)(rfp - fp); - *fileszp *= 2; - /* - * Need to account for update info on both sides - * of the allocation. - */ - fp -= sizeof(__rep_update_args); - if ((ret = __os_realloc(dbenv, *fileszp, fp)) != 0) - break; - fp += sizeof(__rep_update_args); - rfp = fp + offset; - /* - * Now that we've reallocated the space, try to - * store it again. - */ - goto retry; - } - rfp += len; - *filelenp += len; - } - __os_dirfree(dbenv, names, cnt); - return (ret); -} - -static int -__rep_get_fileinfo(dbenv, file, subdb, rfp, uid, filecntp) - DB_ENV *dbenv; - const char *file, *subdb; - __rep_fileinfo_args *rfp; - u_int8_t *uid; - u_int32_t *filecntp; -{ - - DB *dbp, *entdbp; - DB_LOCK lk; - DB_LOG *dblp; - DB_MPOOLFILE *mpf; - DBC *dbc; - DBMETA *dbmeta; - PAGE *pagep; - int i, ret, t_ret; - - dbp = NULL; - dbc = NULL; - pagep = NULL; - mpf = NULL; - LOCK_INIT(lk); - - if ((ret = db_create(&dbp, dbenv, 0)) != 0) - goto err; - if ((ret = __db_open(dbp, NULL, file, subdb, DB_UNKNOWN, - DB_RDONLY | (F_ISSET(dbenv, DB_ENV_THREAD) ? DB_THREAD : 0), - 0, PGNO_BASE_MD)) != 0) - goto err; - - if ((ret = __db_cursor(dbp, NULL, &dbc, 0)) != 0) - goto err; - if ((ret = __db_lget( - dbc, 0, dbp->meta_pgno, DB_LOCK_READ, 0, &lk)) != 0) - goto err; - if ((ret = __memp_fget(dbp->mpf, &dbp->meta_pgno, 0, &pagep)) != 0) - goto err; - /* - * We have the meta page. Set up our information. - */ - dbmeta = (DBMETA *)pagep; - rfp->pgno = 0; - /* - * Queue is a special-case. We need to set max_pgno to 0 so that - * the client can compute the pages from the meta-data. - */ - if (dbp->type == DB_QUEUE) - rfp->max_pgno = 0; - else - rfp->max_pgno = dbmeta->last_pgno; - rfp->pgsize = dbp->pgsize; - memcpy(uid, dbp->fileid, DB_FILE_ID_LEN); - rfp->filenum = (*filecntp)++; - rfp->type = (u_int32_t)dbp->type; - rfp->flags = dbp->flags; - rfp->id = DB_LOGFILEID_INVALID; - ret = __memp_fput(dbp->mpf, pagep, 0); - pagep = NULL; - if ((t_ret = __LPUT(dbc, lk)) != 0 && ret == 0) - ret = t_ret; - if (ret != 0) - goto err; -err: - if ((t_ret = __LPUT(dbc, lk)) != 0 && ret == 0) - ret = t_ret; - if (dbc != NULL && (t_ret = __db_c_close(dbc)) != 0 && ret == 0) - ret = t_ret; - if (pagep != NULL && - (t_ret = __memp_fput(mpf, pagep, 0)) != 0 && ret == 0) - ret = t_ret; - if (dbp != NULL && (t_ret = __db_close(dbp, NULL, 0)) != 0 && ret == 0) - ret = t_ret; - /* - * We walk the entry table now, after closing the dbp because - * otherwise we find the open from this function and the id - * is useless in that case. - */ - if (ret == 0) { - LOG_SYSTEM_LOCK(dbenv); - /* - * Walk entry table looking for this uid. - * If we find it, save the id. - */ - for (dblp = dbenv->lg_handle, - i = 0; i < dblp->dbentry_cnt; i++) { - entdbp = dblp->dbentry[i].dbp; - if (entdbp == NULL) - break; - DB_ASSERT(entdbp->log_filename != NULL); - if (memcmp(uid, - entdbp->log_filename->ufid, - DB_FILE_ID_LEN) == 0) - rfp->id = i; - } - LOG_SYSTEM_UNLOCK(dbenv); - } - return (ret); -} - -/* - * __rep_page_req - * Process a page_req and send the page information to the client. - * - * PUBLIC: int __rep_page_req __P((DB_ENV *, int, DBT *)); - */ -int -__rep_page_req(dbenv, eid, rec) - DB_ENV *dbenv; - int eid; - DBT *rec; -{ - __rep_fileinfo_args *msgfp; - DB *dbp; - DBT msgdbt; - DB_LOG *dblp; - DB_MPOOLFILE *mpf; - DB_REP *db_rep; - REP *rep; - int ret, t_ret; - void *next; -#ifdef DIAGNOSTIC - DB_MSGBUF mb; -#endif - - db_rep = dbenv->rep_handle; - rep = db_rep->region; - dblp = dbenv->lg_handle; - - if ((ret = __rep_fileinfo_read(dbenv, rec->data, &next, &msgfp)) != 0) - return (ret); - - /* - * See if we can find it already. If so we can quickly access its - * mpool and process. Otherwise we have to open the file ourselves. - */ - RPRINT(dbenv, rep, (dbenv, &mb, "page_req: file %d page %lu to %lu", - msgfp->filenum, (u_long)msgfp->pgno, (u_long)msgfp->max_pgno)); - LOG_SYSTEM_LOCK(dbenv); - if (msgfp->id >= 0 && dblp->dbentry_cnt > msgfp->id) { - dbp = dblp->dbentry[msgfp->id].dbp; - if (dbp != NULL) { - DB_ASSERT(dbp->log_filename != NULL); - if (memcmp(msgfp->uid.data, dbp->log_filename->ufid, - DB_FILE_ID_LEN) == 0) { - LOG_SYSTEM_UNLOCK(dbenv); - RPRINT(dbenv, rep, (dbenv, &mb, - "page_req: found %d in dbreg", - msgfp->filenum)); - ret = __rep_page_sendpages(dbenv, eid, - msgfp, dbp->mpf, dbp); - goto err; - } - } - } - LOG_SYSTEM_UNLOCK(dbenv); - - /* - * If we get here, we do not have the file open via dbreg. - * We need to open the file and then send its pages. - * If we cannot open the file, we send REP_FILE_FAIL. - */ - RPRINT(dbenv, rep, (dbenv, &mb, "page_req: Open %d via mpf_open", - msgfp->filenum)); - if ((ret = __rep_mpf_open(dbenv, &mpf, msgfp, 0)) != 0) { - memset(&msgdbt, 0, sizeof(msgdbt)); - msgdbt.data = msgfp; - msgdbt.size = sizeof(*msgfp); - RPRINT(dbenv, rep, (dbenv, &mb, "page_req: Open %d failed", - msgfp->filenum)); - if (F_ISSET(rep, REP_F_MASTER)) - (void)__rep_send_message(dbenv, eid, REP_FILE_FAIL, - NULL, &msgdbt, 0, 0); - else - ret = DB_NOTFOUND; - goto err; - } - - ret = __rep_page_sendpages(dbenv, eid, msgfp, mpf, NULL); - t_ret = __memp_fclose(mpf, 0); - if (ret == 0 && t_ret != 0) - ret = t_ret; -err: - __os_free(dbenv, msgfp); - return (ret); -} - -static int -__rep_page_sendpages(dbenv, eid, msgfp, mpf, dbp) - DB_ENV *dbenv; - int eid; - __rep_fileinfo_args *msgfp; - DB_MPOOLFILE *mpf; - DB *dbp; -{ - DB *qdbp; - DBT lockdbt, msgdbt, pgdbt; - DB_LOCK lock; - DB_LOCK_ILOCK lock_obj; - DB_LOG *dblp; - DB_LSN lsn; - DB_MSGBUF mb; - DB_REP *db_rep; - PAGE *pagep; - REP *rep; - REP_BULK bulk; - REP_THROTTLE repth; - db_pgno_t p; - uintptr_t bulkoff; - size_t len, msgsz; - u_int32_t bulkflags, lockid, use_bulk; - int opened, ret, t_ret; - u_int8_t *buf; - -#ifndef DIAGNOSTIC - DB_MSGBUF_INIT(&mb); -#endif - db_rep = dbenv->rep_handle; - rep = db_rep->region; - lockid = DB_LOCK_INVALIDID; - opened = 0; - qdbp = NULL; - buf = NULL; - bulk.addr = NULL; - use_bulk = FLD_ISSET(rep->config, REP_C_BULK); - if (msgfp->type == (u_int32_t)DB_QUEUE) { - if (dbp == NULL) { - if ((ret = db_create(&qdbp, dbenv, 0)) != 0) - goto err; - /* - * We need to check whether this is in-memory so that - * we pass the name correctly as either the file or - * the database name. - */ - if ((ret = __db_open(qdbp, NULL, - FLD_ISSET(msgfp->flags, DB_AM_INMEM) ? - NULL : msgfp->info.data, - FLD_ISSET(msgfp->flags, DB_AM_INMEM) ? - msgfp->info.data : NULL, - DB_UNKNOWN, - DB_RDONLY | (F_ISSET(dbenv, DB_ENV_THREAD) ? - DB_THREAD : 0), 0, PGNO_BASE_MD)) != 0) - goto err; - opened = 1; - } else - qdbp = dbp; - } - msgsz = sizeof(__rep_fileinfo_args) + DB_FILE_ID_LEN + msgfp->pgsize; - if ((ret = __os_calloc(dbenv, 1, msgsz, &buf)) != 0) - goto err; - memset(&msgdbt, 0, sizeof(msgdbt)); - memset(&pgdbt, 0, sizeof(pgdbt)); - RPRINT(dbenv, rep, (dbenv, &mb, "sendpages: file %d page %lu to %lu", - msgfp->filenum, (u_long)msgfp->pgno, (u_long)msgfp->max_pgno)); - memset(&repth, 0, sizeof(repth)); - /* - * If we're doing bulk transfer, allocate a bulk buffer to put our - * pages in. We still need to initialize the throttle info - * because if we encounter a page larger than our entire bulk - * buffer, we need to send it as a singleton. - * - * Use a local var so that we don't need to worry if someone else - * turns on/off bulk in the middle of our call here. - */ - if (use_bulk && (ret = __rep_bulk_alloc(dbenv, &bulk, eid, - &bulkoff, &bulkflags, REP_BULK_PAGE)) != 0) - goto err; - REP_SYSTEM_LOCK(dbenv); - repth.gbytes = rep->gbytes; - repth.bytes = rep->bytes; - repth.type = REP_PAGE; - repth.data_dbt = &msgdbt; - REP_SYSTEM_UNLOCK(dbenv); - - /* - * Set up locking. - */ - LOCK_INIT(lock); - memset(&lock_obj, 0, sizeof(lock_obj)); - if ((ret = __lock_id(dbenv, &lockid, NULL)) != 0) - goto err; - memcpy(lock_obj.fileid, mpf->fileid, DB_FILE_ID_LEN); - lock_obj.type = DB_PAGE_LOCK; - - memset(&lockdbt, 0, sizeof(lockdbt)); - lockdbt.data = &lock_obj; - lockdbt.size = sizeof(lock_obj); - - for (p = msgfp->pgno; p <= msgfp->max_pgno; p++) { - /* - * We're not waiting for the lock, if we cannot get - * the lock for this page, skip it. The gap - * code will rerequest it. - */ - lock_obj.pgno = p; - if ((ret = __lock_get(dbenv, lockid, DB_LOCK_NOWAIT, &lockdbt, - DB_LOCK_READ, &lock)) != 0) { - /* - * Continue if we couldn't get the lock. - */ - if (ret == DB_LOCK_NOTGRANTED) - continue; - /* - * Otherwise we have an error. - */ - goto err; - } - if (msgfp->type == (u_int32_t)DB_QUEUE && p != 0) -#ifdef HAVE_QUEUE - ret = __qam_fget(qdbp, &p, DB_MPOOL_CREATE, &pagep); -#else - ret = DB_PAGE_NOTFOUND; -#endif - else - ret = __memp_fget(mpf, &p, DB_MPOOL_CREATE, &pagep); - if (ret == DB_PAGE_NOTFOUND) { - memset(&pgdbt, 0, sizeof(pgdbt)); - ZERO_LSN(lsn); - msgfp->pgno = p; - if (F_ISSET(rep, REP_F_MASTER)) { - ret = 0; - RPRINT(dbenv, rep, (dbenv, &mb, - "sendpages: PAGE_FAIL on page %lu", - (u_long)p)); - (void)__rep_send_message(dbenv, eid, - REP_PAGE_FAIL, &lsn, &msgdbt, 0, 0); - } else - ret = DB_NOTFOUND; - goto lockerr; - } else if (ret != 0) - goto lockerr; - else { - pgdbt.data = pagep; - pgdbt.size = (u_int32_t)msgfp->pgsize; - } - len = 0; - ret = __rep_fileinfo_buf(buf, msgsz, &len, - msgfp->pgsize, p, msgfp->max_pgno, - msgfp->filenum, msgfp->id, msgfp->type, - msgfp->flags, &msgfp->uid, &pgdbt); - if (msgfp->type != (u_int32_t)DB_QUEUE || p == 0) - t_ret = __memp_fput(mpf, pagep, 0); -#ifdef HAVE_QUEUE - else - /* - * We don't need an #else for HAVE_QUEUE here because if - * we're not compiled with queue, then we're guaranteed - * to have set REP_PAGE_FAIL above. - */ - t_ret = __qam_fput(qdbp, p, pagep, 0); -#endif - if ((t_ret = __ENV_LPUT(dbenv, lock)) != 0 && ret == 0) - ret = t_ret; - if (ret != 0) - goto err; - - DB_ASSERT(len <= msgsz); - msgdbt.data = buf; - msgdbt.size = (u_int32_t)len; - - dblp = dbenv->lg_handle; - LOG_SYSTEM_LOCK(dbenv); - repth.lsn = ((LOG *)dblp->reginfo.primary)->lsn; - LOG_SYSTEM_UNLOCK(dbenv); - /* - * If we are configured for bulk, try to send this as a bulk - * request. If not configured, or it is too big for bulk - * then just send normally. - */ - if (use_bulk) - ret = __rep_bulk_message(dbenv, &bulk, &repth, - &repth.lsn, &msgdbt, 0); - if (!use_bulk || ret == DB_REP_BULKOVF) - ret = __rep_send_throttle(dbenv, eid, &repth, 0); - RPRINT(dbenv, rep, (dbenv, &mb, - "sendpages: %lu, lsn [%lu][%lu]", (u_long)p, - (u_long)repth.lsn.file, (u_long)repth.lsn.offset)); - /* - * If we have REP_PAGE_MORE - * we need to break this loop after giving the page back - * to mpool. Otherwise, with REP_PAGE, we keep going. - */ - if (ret == 0) - ret = t_ret; - if (repth.type == REP_PAGE_MORE || ret != 0) - break; - } - - if (0) { -lockerr: if ((t_ret = __ENV_LPUT(dbenv, lock)) != 0 && ret == 0) - ret = t_ret; - } -err: - /* - * We're done, force out whatever remains in the bulk buffer and - * free it. - */ - if (use_bulk && bulk.addr != NULL && - (t_ret = __rep_bulk_free(dbenv, &bulk, 0)) != 0 && ret == 0) - ret = t_ret; - if (opened && (t_ret = __db_close(qdbp, NULL, DB_NOSYNC)) != 0 && - ret == 0) - ret = t_ret; - if (buf != NULL) - __os_free(dbenv, buf); - if (lockid != DB_LOCK_INVALIDID && (t_ret = __lock_id_free(dbenv, - lockid)) != 0 && ret == 0) - ret = t_ret; - return (ret); -} - -/* - * __rep_update_setup - * Process and setup with this file information. - * - * PUBLIC: int __rep_update_setup __P((DB_ENV *, int, REP_CONTROL *, DBT *)); - */ -int -__rep_update_setup(dbenv, eid, rp, rec) - DB_ENV *dbenv; - int eid; - REP_CONTROL *rp; - DBT *rec; -{ - DB_LOG *dblp; - DB_REP *db_rep; - DBT pagereq_dbt; - LOG *lp; - REGENV *renv; - REGINFO *infop; - REP *rep; - __rep_update_args *rup; - int ret; - u_int32_t count, infolen; - void *next; -#ifdef DIAGNOSTIC - __rep_fileinfo_args *msgfp; - DB_MSGBUF mb; -#endif - - db_rep = dbenv->rep_handle; - rep = db_rep->region; - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - ret = 0; - - REP_SYSTEM_LOCK(dbenv); - if (!F_ISSET(rep, REP_F_RECOVER_UPDATE)) { - REP_SYSTEM_UNLOCK(dbenv); - return (0); - } - F_CLR(rep, REP_F_RECOVER_UPDATE); - /* - * We know we're the first to come in here due to the - * REP_F_RECOVER_UPDATE flag. - */ - F_SET(rep, REP_F_RECOVER_PAGE); - /* - * We do not clear REP_F_READY or rep->in_recovery in this code. - * We'll eventually call the normal __rep_verify_match recovery - * code and that will clear all the flags and allow others to - * proceed. - */ - if ((ret = __rep_lockout(dbenv, rep, 1)) != 0) - goto err; - /* - * We need to update the timestamp and kill any open handles - * on this client. The files are changing completely. - */ - infop = dbenv->reginfo; - renv = infop->primary; - (void)time(&renv->rep_timestamp); - - REP_SYSTEM_UNLOCK(dbenv); - MUTEX_LOCK(dbenv, rep->mtx_clientdb); - lp->wait_recs = rep->request_gap; - lp->rcvd_recs = 0; - ZERO_LSN(lp->ready_lsn); - ZERO_LSN(lp->waiting_lsn); - ZERO_LSN(lp->max_wait_lsn); - ZERO_LSN(lp->max_perm_lsn); - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - if ((ret = __rep_update_read(dbenv, rec->data, &next, &rup)) != 0) - goto err_nolock; - - /* - * We need to empty out any old log records that might be in the - * temp database. - */ - if ((ret = __db_truncate(db_rep->rep_db, NULL, &count)) != 0) - goto err_nolock; - - /* - * We will remove all logs we have so we need to request - * from the master's beginning. - */ - REP_SYSTEM_LOCK(dbenv); - rep->first_lsn = rup->first_lsn; - rep->last_lsn = rp->lsn; - rep->nfiles = rup->num_files; - rep->curfile = 0; - rep->ready_pg = 0; - rep->npages = 0; - rep->waiting_pg = PGNO_INVALID; - rep->max_wait_pg = PGNO_INVALID; - - __os_free(dbenv, rup); - - RPRINT(dbenv, rep, (dbenv, &mb, - "Update setup for %d files.", rep->nfiles)); - RPRINT(dbenv, rep, (dbenv, &mb, "Update setup: First LSN [%lu][%lu].", - (u_long)rep->first_lsn.file, (u_long)rep->first_lsn.offset)); - RPRINT(dbenv, rep, (dbenv, &mb, "Update setup: Last LSN [%lu][%lu]", - (u_long)rep->last_lsn.file, (u_long)rep->last_lsn.offset)); - - infolen = rec->size - sizeof(__rep_update_args); - if ((ret = __os_calloc(dbenv, 1, infolen, &rep->originfo)) != 0) - goto err; - memcpy(rep->originfo, next, infolen); - rep->finfo = rep->originfo; - if ((ret = __rep_fileinfo_read(dbenv, - rep->finfo, &next, &rep->curinfo)) != 0) { - RPRINT(dbenv, rep, (dbenv, &mb, - "Update setup: Fileinfo read: %s", db_strerror(ret))); - goto errmem1; - } - rep->nextinfo = next; - -#ifdef DIAGNOSTIC - msgfp = rep->curinfo; - DB_ASSERT(msgfp->pgno == 0); -#endif - - /* - * We want to create/open our dbp to the database - * where we'll keep our page information. - */ - if ((ret = __rep_client_dbinit(dbenv, 1, REP_PG)) != 0) { - RPRINT(dbenv, rep, (dbenv, &mb, - "Update setup: Client_dbinit %s", db_strerror(ret))); - goto errmem; - } - - /* - * We should get file info 'ready to go' to avoid data copies. - */ - memset(&pagereq_dbt, 0, sizeof(pagereq_dbt)); - pagereq_dbt.data = rep->finfo; - pagereq_dbt.size = (u_int32_t)((u_int8_t *)rep->nextinfo - - (u_int8_t *)rep->finfo); - - RPRINT(dbenv, rep, (dbenv, &mb, - "Update PAGE_REQ file 0: pgsize %lu, maxpg %lu", - (u_long)rep->curinfo->pgsize, - (u_long)rep->curinfo->max_pgno)); - /* - * We set up pagereq_dbt as we went along. Send it now. - */ - (void)__rep_send_message(dbenv, eid, REP_PAGE_REQ, - NULL, &pagereq_dbt, 0, DB_REP_ANYWHERE); - if (0) { -errmem: __os_free(dbenv, rep->curinfo); -errmem1: __os_free(dbenv, rep->originfo); - rep->finfo = NULL; - rep->curinfo = NULL; - rep->originfo = NULL; - } - - if (0) { -err_nolock: REP_SYSTEM_LOCK(dbenv); - } - -err: /* - * If we get an error, we cannot leave ourselves in the RECOVER_PAGE - * state because we have no file information. That also means undo'ing - * the rep_lockout. We need to move back to the RECOVER_UPDATE stage. - */ - if (ret != 0) { - RPRINT(dbenv, rep, (dbenv, &mb, - "Update_setup: Error: Clear PAGE, set UPDATE again. %s", - db_strerror(ret))); - F_CLR(rep, REP_F_RECOVER_PAGE | REP_F_READY); - rep->in_recovery = 0; - F_SET(rep, REP_F_RECOVER_UPDATE); - } - REP_SYSTEM_UNLOCK(dbenv); - return (ret); -} - -/* - * __rep_bulk_page - * Process a bulk page message. - * - * PUBLIC: int __rep_bulk_page __P((DB_ENV *, int, REP_CONTROL *, DBT *)); - */ -int -__rep_bulk_page(dbenv, eid, rp, rec) - DB_ENV *dbenv; - int eid; - REP_CONTROL *rp; - DBT *rec; -{ - DB_REP *db_rep; - DBT pgrec; - REP *rep; - REP_CONTROL tmprp; - u_int32_t len; - int ret; - u_int8_t *p, *ep; -#ifdef DIAGNOSTIC - DB_MSGBUF mb; -#endif - - memset(&pgrec, 0, sizeof(pgrec)); - /* - * We're going to be modifying the rp LSN contents so make - * our own private copy to play with. We need to set the - * rectype to REP_PAGE because we're calling through __rep_page - * to process each page, and lower functions make decisions - * based on the rectypes (for throttling/gap processing) - */ - memcpy(&tmprp, rp, sizeof(tmprp)); - tmprp.rectype = REP_PAGE; - ret = 0; - db_rep = dbenv->rep_handle; - rep = db_rep->region; - for (ep = (u_int8_t *)rec->data + rec->size, p = (u_int8_t *)rec->data; - p < ep; p += len) { - /* - * First thing in the buffer is the length. Then the LSN - * of this page, then the page info itself. - */ - memcpy(&len, p, sizeof(len)); - p += sizeof(len); - memcpy(&tmprp.lsn, p, sizeof(DB_LSN)); - p += sizeof(DB_LSN); - pgrec.data = p; - pgrec.size = len; - RPRINT(dbenv, rep, (dbenv, &mb, - "rep_bulk_page: Processing LSN [%lu][%lu]", - (u_long)tmprp.lsn.file, (u_long)tmprp.lsn.offset)); - RPRINT(dbenv, rep, (dbenv, &mb, - "rep_bulk_page: p %#lx ep %#lx pgrec data %#lx, size %lu (%#lx)", - P_TO_ULONG(p), P_TO_ULONG(ep), P_TO_ULONG(pgrec.data), - (u_long)pgrec.size, (u_long)pgrec.size)); - /* - * Now send the page info DBT to the page processing function. - */ - ret = __rep_page(dbenv, eid, &tmprp, &pgrec); - RPRINT(dbenv, rep, (dbenv, &mb, - "rep_bulk_page: rep_page ret %d", ret)); - - if (ret != 0) - break; - } - return (ret); -} - -/* - * __rep_page - * Process a page message. - * - * PUBLIC: int __rep_page __P((DB_ENV *, int, REP_CONTROL *, DBT *)); - */ -int -__rep_page(dbenv, eid, rp, rec) - DB_ENV *dbenv; - int eid; - REP_CONTROL *rp; - DBT *rec; -{ - - DB_REP *db_rep; - DBT key, data; - REP *rep; - __rep_fileinfo_args *msgfp; - db_recno_t recno; - int ret; - void *next; -#ifdef DIAGNOSTIC - DB_MSGBUF mb; -#endif - - ret = 0; - db_rep = dbenv->rep_handle; - rep = db_rep->region; - - REP_SYSTEM_LOCK(dbenv); - if (!F_ISSET(rep, REP_F_RECOVER_PAGE)) { - REP_SYSTEM_UNLOCK(dbenv); - return (0); - } - if ((ret = __rep_fileinfo_read(dbenv, rec->data, &next, &msgfp)) != 0) { - REP_SYSTEM_UNLOCK(dbenv); - return (ret); - } - RPRINT(dbenv, rep, (dbenv, &mb, - "PAGE: Received page %lu from file %d", - (u_long)msgfp->pgno, msgfp->filenum)); - /* - * Check if this page is from the file we're expecting. - * This may be an old or delayed page message. - */ - /* - * !!! - * If we allow dbrename/dbremove on the master while a client - * is updating, then we'd have to verify the file's uid here too. - */ - if (msgfp->filenum != rep->curfile) { - RPRINT(dbenv, rep, - (dbenv, &mb, "Msg file %d != curfile %d", - msgfp->filenum, rep->curfile)); - goto err; - } - /* - * We want to create/open our dbp to the database - * where we'll keep our page information. - */ - if ((ret = __rep_client_dbinit(dbenv, 1, REP_PG)) != 0) - goto err; - - REP_SYSTEM_UNLOCK(dbenv); - memset(&key, 0, sizeof(key)); - memset(&data, 0, sizeof(data)); - recno = (db_recno_t)(msgfp->pgno + 1); - key.data = &recno; - key.ulen = key.size = sizeof(db_recno_t); - key.flags = DB_DBT_USERMEM; - - /* - * If we already have this page, then we don't want to bother - * rewriting it into the file. Otherwise, any other error - * we want to return. - */ - ret = __db_put(rep->file_dbp, NULL, &key, &data, DB_NOOVERWRITE); - if (ret == DB_KEYEXIST) { - RPRINT(dbenv, rep, (dbenv, &mb, - "PAGE: Received duplicate page %lu from file %d", - (u_long)msgfp->pgno, msgfp->filenum)); - rep->stat.st_pg_duplicated++; - ret = 0; - goto err_nolock; - } - if (ret != 0) - goto err_nolock; - - RPRINT(dbenv, rep, (dbenv, &mb, - "PAGE: Write page %lu into mpool", (u_long)msgfp->pgno)); - REP_SYSTEM_LOCK(dbenv); - /* - * We put the page in the database file itself. - */ - ret = __rep_write_page(dbenv, rep, msgfp); - if (ret != 0) { - /* - * We got an error storing the page, therefore, we need - * remove this page marker from the page database too. - * !!! - * I'm ignoring errors from the delete because we want to - * return the original error. If we cannot write the page - * and we cannot delete the item we just put, what should - * we do? Panic the env and return DB_RUNRECOVERY? - */ - (void)__db_del(rep->file_dbp, NULL, &key, 0); - goto err; - } - rep->stat.st_pg_records++; - rep->npages++; - - /* - * Now check the LSN on the page and save it if it is later - * than the one we have. - */ - if (log_compare(&rp->lsn, &rep->last_lsn) > 0) - rep->last_lsn = rp->lsn; - - /* - * We've successfully written the page. Now we need to see if - * we're done with this file. __rep_filedone will check if we - * have all the pages expected and if so, set up for the next - * file and send out a page request for the next file's pages. - */ - ret = __rep_filedone(dbenv, eid, rep, msgfp, rp->rectype); - -err: REP_SYSTEM_UNLOCK(dbenv); - -err_nolock: - __os_free(dbenv, msgfp); - return (ret); -} - -/* - * __rep_page_fail - * Process a page fail message. - * - * PUBLIC: int __rep_page_fail __P((DB_ENV *, int, DBT *)); - */ -int -__rep_page_fail(dbenv, eid, rec) - DB_ENV *dbenv; - int eid; - DBT *rec; -{ - - DB_REP *db_rep; - REP *rep; - __rep_fileinfo_args *msgfp, *rfp; - int ret; - void *next; -#ifdef DIAGNOSTIC - DB_MSGBUF mb; -#endif - - ret = 0; - db_rep = dbenv->rep_handle; - rep = db_rep->region; - - REP_SYSTEM_LOCK(dbenv); - if (!F_ISSET(rep, REP_F_RECOVER_PAGE)) { - REP_SYSTEM_UNLOCK(dbenv); - return (0); - } - if ((ret = __rep_fileinfo_read(dbenv, rec->data, &next, &msgfp)) != 0) { - REP_SYSTEM_UNLOCK(dbenv); - return (ret); - } - /* - * Check if this page is from the file we're expecting. - * This may be an old or delayed page message. - */ - /* - * !!! - * If we allow dbrename/dbremove on the master while a client - * is updating, then we'd have to verify the file's uid here too. - */ - if (msgfp->filenum != rep->curfile) { - RPRINT(dbenv, rep, (dbenv, &mb, "Msg file %d != curfile %d", - msgfp->filenum, rep->curfile)); - REP_SYSTEM_UNLOCK(dbenv); - return (0); - } - rfp = rep->curinfo; - if (rfp->type != (u_int32_t)DB_QUEUE) - --rfp->max_pgno; - else { - /* - * Queue is special. Pages at the beginning of the queue - * may disappear, as well as at the end. Use msgfp->pgno - * to adjust accordingly. - */ - RPRINT(dbenv, rep, (dbenv, &mb, - "page_fail: BEFORE page %lu failed. ready %lu, max %lu, npages %d", - (u_long)msgfp->pgno, (u_long)rep->ready_pg, - (u_long)rfp->max_pgno, rep->npages)); - if (msgfp->pgno == rfp->max_pgno) - --rfp->max_pgno; - if (msgfp->pgno >= rep->ready_pg) { - rep->ready_pg = msgfp->pgno + 1; - rep->npages = rep->ready_pg; - } - RPRINT(dbenv, rep, (dbenv, &mb, - "page_fail: AFTER page %lu failed. ready %lu, max %lu, npages %d", - (u_long)msgfp->pgno, (u_long)rep->ready_pg, - (u_long)rfp->max_pgno, rep->npages)); - } - /* - * We've lowered the number of pages expected. It is possible that - * this was the last page we were expecting. Now we need to see if - * we're done with this file. __rep_filedone will check if we have - * all the pages expected and if so, set up for the next file and - * send out a page request for the next file's pages. - */ - ret = __rep_filedone(dbenv, eid, rep, msgfp, REP_PAGE_FAIL); - REP_SYSTEM_UNLOCK(dbenv); - return (ret); -} - -/* - * __rep_write_page - - * Write this page into a database. - */ -static int -__rep_write_page(dbenv, rep, msgfp) - DB_ENV *dbenv; - REP *rep; - __rep_fileinfo_args *msgfp; -{ - __rep_fileinfo_args *rfp; - DB_FH *rfh; - int ret; - void *dst; - char *real_name; - - real_name = NULL; - rfp = NULL; - - /* - * If this is the first page we're putting in this database, we need - * to create the mpool file. Otherwise call memp_fget to create the - * page in mpool. Then copy the data to the page, and memp_fput the - * page to give it back to mpool. - * - * We need to create the file, removing any existing file and associate - * the correct file ID with the new one. - */ - rfp = rep->curinfo; - if (rep->file_mpf == NULL) { - if (!F_ISSET(rfp, DB_AM_INMEM)) { - if ((ret = __db_appname(dbenv, DB_APP_DATA, - rfp->info.data, 0, NULL, &real_name)) != 0) - goto err; - /* - * Calling memp_nameop will both purge any matching - * fileid from mpool and unlink it on disk. - */ - if ((ret = __memp_nameop(dbenv, - rfp->uid.data, NULL, real_name, NULL, 0)) != 0) - goto err; - /* - * Create the file on disk. We'll be putting the data - * into the file via mpool. - */ - if ((ret = __os_open(dbenv, real_name, - DB_OSO_CREATE, dbenv->db_mode, &rfh)) == 0) - ret = __os_closehandle(dbenv, rfh); - if (ret != 0) - goto err; - } - - if ((ret = - __rep_mpf_open(dbenv, &rep->file_mpf, rep->curinfo, - F_ISSET(rfp, DB_AM_INMEM) ? DB_CREATE : 0)) != 0) - goto err; - } - /* - * Handle queue specially. If we're a QUEUE database, we need to - * use the __qam_fget/put calls. We need to use rep->queue_dbp for - * that. That dbp is opened after getting the metapage for the - * queue database. Since the meta-page is always in the queue file, - * we'll use the normal path for that first page. After that we - * can assume the dbp is opened. - */ - if (msgfp->type == (u_int32_t)DB_QUEUE && msgfp->pgno != 0) { -#ifdef HAVE_QUEUE - if ((ret = __qam_fget( - rep->queue_dbp, &msgfp->pgno, DB_MPOOL_CREATE, &dst)) != 0) - goto err; -#else - /* - * This always returns an error. - */ - ret = __db_no_queue_am(dbenv); - goto err; -#endif - } else if ((ret = __memp_fget( - rep->file_mpf, &msgfp->pgno, DB_MPOOL_CREATE, &dst)) != 0) - goto err; - - memcpy(dst, msgfp->info.data, msgfp->pgsize); - if (msgfp->type != (u_int32_t)DB_QUEUE || msgfp->pgno == 0) - ret = __memp_fput(rep->file_mpf, dst, DB_MPOOL_DIRTY); -#ifdef HAVE_QUEUE - else - ret = __qam_fput(rep->queue_dbp, msgfp->pgno, dst, - DB_MPOOL_DIRTY); -#endif - -err: if (real_name != NULL) - __os_free(dbenv, real_name); - return (ret); -} - -/* - * __rep_page_gap - - * After we've put the page into the database, we need to check if - * we have a page gap and whether we need to request pages. - */ -static int -__rep_page_gap(dbenv, rep, msgfp, type) - DB_ENV *dbenv; - REP *rep; - __rep_fileinfo_args *msgfp; - u_int32_t type; -{ - DB_LOG *dblp; - DBT data, key; - LOG *lp; - __rep_fileinfo_args *rfp; - db_recno_t recno; - int ret; -#ifdef DIAGNOSTIC - DB_MSGBUF mb; -#endif - - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - ret = 0; - - /* - * We've successfully put this page into our file. - * Now we need to account for it and re-request new pages - * if necessary. - */ - /* - * We already hold the rep mutex, but we also need the db mutex. - * So we need to drop it, acquire both in the right order and - * then recheck the state of the world. - */ - REP_SYSTEM_UNLOCK(dbenv); - MUTEX_LOCK(dbenv, rep->mtx_clientdb); - REP_SYSTEM_LOCK(dbenv); - rfp = rep->curinfo; - - /* - * Make sure we're still talking about the same file. - * If not, we're done here. - */ - if (rfp->filenum != msgfp->filenum) { - ret = DB_REP_PAGEDONE; - goto err; - } - - /* - * We have 3 possible states: - * 1. We receive a page we already have. - * msg pgno < ready pgno - * 2. We receive a page that is beyond a gap. - * msg pgno > ready pgno - * 3. We receive the page we're expecting. - * msg pgno == ready pgno - */ - /* - * State 1. This should not happen because this function - * should only be called once per page received because we - * check for DB_KEY_EXIST when we save the page information. - */ - DB_ASSERT(msgfp->pgno >= rep->ready_pg); - - /* - * State 2. This page is beyond the page we're expecting. - * We need to update waiting_pg if this page is less than - * (earlier) the current waiting_pg. There is nothing - * to do but see if we need to request. - */ - RPRINT(dbenv, rep, (dbenv, &mb, - "PAGE_GAP: pgno %lu, max_pg %lu ready %lu, waiting %lu max_wait %lu", - (u_long)msgfp->pgno, (u_long)rfp->max_pgno, (u_long)rep->ready_pg, - (u_long)rep->waiting_pg, (u_long)rep->max_wait_pg)); - if (msgfp->pgno > rep->ready_pg) { - if (rep->waiting_pg == PGNO_INVALID || - msgfp->pgno < rep->waiting_pg) - rep->waiting_pg = msgfp->pgno; - } else { - /* - * We received the page we're expecting. - */ - rep->ready_pg++; - lp->rcvd_recs = 0; - while (ret == 0 && rep->ready_pg == rep->waiting_pg) { - /* - * If we get here we know we just filled a gap. - */ - lp->wait_recs = 0; - lp->rcvd_recs = 0; - rep->max_wait_pg = PGNO_INVALID; - /* - * We need to walk the recno database looking for the - * next page we need or expect. - */ - memset(&key, 0, sizeof(key)); - memset(&data, 0, sizeof(data)); - recno = (db_recno_t)rep->ready_pg; - key.data = &recno; - key.ulen = key.size = sizeof(db_recno_t); - key.flags = DB_DBT_USERMEM; - ret = __db_get(rep->file_dbp, NULL, &key, &data, 0); - if (ret == DB_NOTFOUND || ret == DB_KEYEMPTY) - break; - else if (ret != 0) - goto err; - rep->ready_pg++; - } - } - - /* - * If we filled a gap and now have the entire file, there's - * nothing to do. We're done when ready_pg is > max_pgno - * because ready_pg is larger than the last page we received. - */ - if (rep->ready_pg > rfp->max_pgno) - goto err; - - /* - * Check if we need to ask for more pages. - */ - if ((rep->waiting_pg != PGNO_INVALID && - rep->ready_pg != rep->waiting_pg) || type == REP_PAGE_MORE) { - /* - * We got a page but we may still be waiting for more. - */ - if (lp->wait_recs == 0) { - /* - * This is a new gap. Initialize the number of - * records that we should wait before requesting - * that it be resent. We grab the limits out of - * the rep without the mutex. - */ - lp->wait_recs = rep->request_gap; - lp->rcvd_recs = 0; - rep->max_wait_pg = PGNO_INVALID; - } - /* - * If we got REP_PAGE_MORE we always want to ask for more. - */ - if ((__rep_check_doreq(dbenv, rep) || type == REP_PAGE_MORE) && - ((ret = __rep_pggap_req(dbenv, rep, rfp, - (type == REP_PAGE_MORE) ? REP_GAP_FORCE : 0)) != 0)) - goto err; - } else { - lp->wait_recs = 0; - rep->max_wait_pg = PGNO_INVALID; - } - -err: - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - return (ret); -} - -/* - * __rep_init_cleanup - - * Clean up internal initialization pieces. - * - * PUBLIC: int __rep_init_cleanup __P((DB_ENV *, REP *, int)); - */ -int -__rep_init_cleanup(dbenv, rep, force) - DB_ENV *dbenv; - REP *rep; - int force; -{ - int ret, t_ret; - - ret = 0; - /* - * 1. Close up the file data pointer we used. - * 2. Close/reset the page database. - * 3. Close/reset the queue database if we're forcing a cleanup. - * 4. Free current file info. - * 5. If we have all files or need to force, free original file info. - */ - if (rep->file_mpf != NULL) { - ret = __memp_fclose(rep->file_mpf, 0); - rep->file_mpf = NULL; - } - if (rep->file_dbp != NULL) { - t_ret = __db_close(rep->file_dbp, NULL, DB_NOSYNC); - rep->file_dbp = NULL; - if (t_ret != 0 && ret == 0) - ret = t_ret; - } - if (force && rep->queue_dbp != NULL) { - t_ret = __db_close(rep->queue_dbp, NULL, DB_NOSYNC); - rep->queue_dbp = NULL; - if (t_ret != 0 && ret == 0) - ret = t_ret; - } - if (rep->curinfo != NULL) { - __os_free(dbenv, rep->curinfo); - rep->curinfo = NULL; - } - if (rep->originfo != NULL && - (force || ++rep->curfile == rep->nfiles)) { - __os_free(dbenv, rep->originfo); - rep->originfo = NULL; - } - return (ret); -} - -/* - * __rep_filedone - - * We need to check if we're done with the current file after - * processing the current page. Stat the database to see if - * we have all the pages. If so, we need to clean up/close - * this one, set up for the next one, and ask for its pages, - * or if this is the last file, request the log records and - * move to the REP_RECOVER_LOG state. - */ -static int -__rep_filedone(dbenv, eid, rep, msgfp, type) - DB_ENV *dbenv; - int eid; - REP *rep; - __rep_fileinfo_args *msgfp; - u_int32_t type; -{ - DBT dbt; - __rep_fileinfo_args *rfp; - int ret; -#ifdef DIAGNOSTIC - DB_MSGBUF mb; -#endif - - /* - * We've put our page, now we need to do any gap processing - * that might be needed to re-request pages. - */ - ret = __rep_page_gap(dbenv, rep, msgfp, type); - /* - * The world changed while we were doing gap processing. - * We're done here. - */ - if (ret == DB_REP_PAGEDONE) - return (0); - - rfp = rep->curinfo; - /* - * max_pgno is 0-based and npages is 1-based, so we don't have - * all the pages until npages is > max_pgno. - */ - RPRINT(dbenv, rep, (dbenv, &mb, "FILEDONE: have %lu pages. Need %lu.", - (u_long)rep->npages, (u_long)rfp->max_pgno + 1)); - if (rep->npages <= rfp->max_pgno) - return (0); - - /* - * If we're queue and we think we have all the pages for this file, - * we need to do special queue processing. Queue is handled in - * several stages. - */ - if (rfp->type == (u_int32_t)DB_QUEUE && - ((ret = __rep_queue_filedone(dbenv, rep, rfp)) != - DB_REP_PAGEDONE)) - return (ret); - /* - * We have all the pages for this file. Clean up. - */ - if ((ret = __rep_init_cleanup(dbenv, rep, 0)) != 0) - goto err; - if (rep->curfile == rep->nfiles) { - RPRINT(dbenv, rep, (dbenv, &mb, - "FILEDONE: have %d files. RECOVER_LOG now", rep->nfiles)); - /* - * Move to REP_RECOVER_LOG state. - * Request logs. - */ - /* - * We need to do a sync here so that any later opens - * can find the file and file id. We need to do it - * before we clear REP_F_RECOVER_PAGE so that we do not - * try to flush the log. - */ - if ((ret = __memp_sync(dbenv, NULL)) != 0) - goto err; - F_CLR(rep, REP_F_RECOVER_PAGE); - F_SET(rep, REP_F_RECOVER_LOG); - memset(&dbt, 0, sizeof(dbt)); - dbt.data = &rep->last_lsn; - dbt.size = sizeof(rep->last_lsn); - REP_SYSTEM_UNLOCK(dbenv); - if ((ret = __rep_log_setup(dbenv, rep)) != 0) - goto err; - RPRINT(dbenv, rep, (dbenv, &mb, - "FILEDONE: LOG_REQ from LSN [%lu][%lu] to [%lu][%lu]", - (u_long)rep->first_lsn.file, (u_long)rep->first_lsn.offset, - (u_long)rep->last_lsn.file, (u_long)rep->last_lsn.offset)); - (void)__rep_send_message(dbenv, eid, - REP_LOG_REQ, &rep->first_lsn, &dbt, 0, DB_REP_ANYWHERE); - REP_SYSTEM_LOCK(dbenv); - return (0); - } - - /* - * 4. If not, set curinfo to next file and request its pages. - */ - rep->finfo = rep->nextinfo; - if ((ret = __rep_fileinfo_read(dbenv, rep->finfo, &rep->nextinfo, - &rep->curinfo)) != 0) - goto err; - DB_ASSERT(rep->curinfo->pgno == 0); - rep->ready_pg = 0; - rep->npages = 0; - rep->waiting_pg = PGNO_INVALID; - rep->max_wait_pg = PGNO_INVALID; - memset(&dbt, 0, sizeof(dbt)); - RPRINT(dbenv, rep, (dbenv, &mb, - "FILEDONE: Next file %d. Request pages 0 to %lu", - rep->curinfo->filenum, (u_long)rep->curinfo->max_pgno)); - dbt.data = rep->finfo; - dbt.size = (u_int32_t)((u_int8_t *)rep->nextinfo - - (u_int8_t *)rep->finfo); - (void)__rep_send_message(dbenv, eid, REP_PAGE_REQ, - NULL, &dbt, 0, DB_REP_ANYWHERE); -err: - return (ret); -} - -/* - * __rep_mpf_open - - * Create and open the mpool file for a database. - * Used by both master and client to bring files into mpool. - */ -static int -__rep_mpf_open(dbenv, mpfp, rfp, flags) - DB_ENV *dbenv; - DB_MPOOLFILE **mpfp; - __rep_fileinfo_args *rfp; - u_int32_t flags; -{ - DB db; - int ret; - - if ((ret = __memp_fcreate(dbenv, mpfp)) != 0) - return (ret); - - /* - * We need a dbp to pass into to __db_dbenv_mpool. Set up - * only the parts that it needs. - */ - db.dbenv = dbenv; - db.type = (DBTYPE)rfp->type; - db.pgsize = rfp->pgsize; - memcpy(db.fileid, rfp->uid.data, DB_FILE_ID_LEN); - db.flags = rfp->flags; - /* We need to make sure the dbp isn't marked open. */ - F_CLR(&db, DB_AM_OPEN_CALLED); - db.mpf = *mpfp; - if (F_ISSET(&db, DB_AM_INMEM)) - (void)__memp_set_flags(db.mpf, DB_MPOOL_NOFILE, 1); - if ((ret = __db_dbenv_mpool(&db, rfp->info.data, flags)) != 0) { - (void)__memp_fclose(*mpfp, 0); - *mpfp = NULL; - } - return (ret); -} - -/* - * __rep_pggap_req - - * Request a page gap. Assumes the caller holds the rep_mutex. - * - * PUBLIC: int __rep_pggap_req __P((DB_ENV *, REP *, __rep_fileinfo_args *, - * PUBLIC: u_int32_t)); - */ -int -__rep_pggap_req(dbenv, rep, reqfp, gapflags) - DB_ENV *dbenv; - REP *rep; - __rep_fileinfo_args *reqfp; - u_int32_t gapflags; -{ - DBT max_pg_dbt; - __rep_fileinfo_args *tmpfp; - size_t len; - u_int32_t flags; - int alloc, ret; - - ret = 0; - alloc = 0; - /* - * There is a window where we have to set REP_RECOVER_PAGE when - * we receive the update information to transition from getting - * file information to getting page information. However, that - * thread does release and then reacquire mutexes. So, we might - * try re-requesting before the original thread can get curinfo - * setup. If curinfo isn't set up there is nothing to do. - */ - if (rep->curinfo == NULL) - return (0); - if (reqfp == NULL) { - if ((ret = __rep_finfo_alloc(dbenv, rep->curinfo, &tmpfp)) != 0) - return (ret); - alloc = 1; - } else - tmpfp = reqfp; - - /* - * If we've never requested this page, then - * request everything between it and the first - * page we have. If we have requested this page - * then only request this record, not the entire gap. - */ - flags = 0; - memset(&max_pg_dbt, 0, sizeof(max_pg_dbt)); - tmpfp->pgno = rep->ready_pg; - max_pg_dbt.data = rep->finfo; - max_pg_dbt.size = (u_int32_t)((u_int8_t *)rep->nextinfo - - (u_int8_t *)rep->finfo); - if (rep->max_wait_pg == PGNO_INVALID || - FLD_ISSET(gapflags, REP_GAP_FORCE | REP_GAP_REREQUEST)) { - /* - * Request the gap - set max to waiting_pg - 1 or if - * there is no waiting_pg, just ask for one. - */ - if (rep->waiting_pg == PGNO_INVALID) { - if (FLD_ISSET(gapflags, - REP_GAP_FORCE | REP_GAP_REREQUEST)) - rep->max_wait_pg = rep->curinfo->max_pgno; - else - rep->max_wait_pg = rep->ready_pg; - } else - rep->max_wait_pg = rep->waiting_pg - 1; - tmpfp->max_pgno = rep->max_wait_pg; - /* - * Gap requests are "new" and can go anywhere. - */ - if (FLD_ISSET(gapflags, REP_GAP_REREQUEST)) - flags = DB_REP_REREQUEST; - else - flags = DB_REP_ANYWHERE; - } else { - /* - * Request 1 page - set max to ready_pg. - */ - rep->max_wait_pg = rep->ready_pg; - tmpfp->max_pgno = rep->ready_pg; - /* - * If we're dropping to singletons, this is a rerequest. - */ - flags = DB_REP_REREQUEST; - } - if (rep->master_id != DB_EID_INVALID) { - rep->stat.st_pg_requested++; - /* - * We need to request the pages, but we need to get the - * new info into rep->finfo. Assert that the sizes never - * change. The only thing this should do is change - * the pgno field. Everything else remains the same. - */ - ret = __rep_fileinfo_buf(rep->finfo, max_pg_dbt.size, &len, - tmpfp->pgsize, tmpfp->pgno, tmpfp->max_pgno, - tmpfp->filenum, tmpfp->id, tmpfp->type, - tmpfp->flags, &tmpfp->uid, &tmpfp->info); - DB_ASSERT(len == max_pg_dbt.size); - (void)__rep_send_message(dbenv, rep->master_id, - REP_PAGE_REQ, NULL, &max_pg_dbt, 0, flags); - } else - (void)__rep_send_message(dbenv, DB_EID_BROADCAST, - REP_MASTER_REQ, NULL, NULL, 0, 0); - - if (alloc) - __os_free(dbenv, tmpfp); - return (ret); -} - -/* - * __rep_finfo_alloc - - * Allocate and initialize a fileinfo structure. - * - * PUBLIC: int __rep_finfo_alloc __P((DB_ENV *, __rep_fileinfo_args *, - * PUBLIC: __rep_fileinfo_args **)); - */ -int -__rep_finfo_alloc(dbenv, rfpsrc, rfpp) - DB_ENV *dbenv; - __rep_fileinfo_args *rfpsrc, **rfpp; -{ - __rep_fileinfo_args *rfp; - size_t size; - int ret; - void *uidp, *infop; - - /* - * Allocate enough for the structure and the two DBT data areas. - */ - size = sizeof(__rep_fileinfo_args) + rfpsrc->uid.size + - rfpsrc->info.size; - if ((ret = __os_malloc(dbenv, size, &rfp)) != 0) - return (ret); - - /* - * Copy the structure itself, and then set the DBT data pointers - * to their space and copy the data itself as well. - */ - memcpy(rfp, rfpsrc, sizeof(__rep_fileinfo_args)); - uidp = (u_int8_t *)rfp + sizeof(__rep_fileinfo_args); - rfp->uid.data = uidp; - memcpy(uidp, rfpsrc->uid.data, rfpsrc->uid.size); - - infop = (u_int8_t *)uidp + rfpsrc->uid.size; - rfp->info.data = infop; - memcpy(infop, rfpsrc->info.data, rfpsrc->info.size); - *rfpp = rfp; - return (ret); -} - -/* - * __rep_log_setup - - * We know our first LSN and need to reset the log subsystem - * to get our logs set up for the proper file. - */ -static int -__rep_log_setup(dbenv, rep) - DB_ENV *dbenv; - REP *rep; -{ - DB_LOG *dblp; - DB_LSN lsn; - DB_TXNMGR *mgr; - DB_TXNREGION *region; - LOG *lp; - u_int32_t fnum, lastfile; - int ret; - char *name; - - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - mgr = dbenv->tx_handle; - region = mgr->reginfo.primary; - - /* - * Forcibly remove *all* existing log files. - */ - lastfile = lp->lsn.file; - for (fnum = 1; fnum <= lastfile; fnum++) { - if ((ret = __log_name(dblp, fnum, &name, NULL, 0)) != 0) - goto err; - (void)__os_unlink(dbenv, name); - __os_free(dbenv, name); - } - /* - * Set up the log starting at the file number of the first LSN we - * need to get from the master. - */ - ret = __log_newfile(dblp, &lsn, rep->first_lsn.file); - - /* - * We reset first_lsn to the lp->lsn. We were given the LSN of - * the checkpoint and we now need the LSN for the beginning of - * the file, which __log_newfile conveniently set up for us - * in lp->lsn. - */ - rep->first_lsn = lp->lsn; - TXN_SYSTEM_LOCK(dbenv); - ZERO_LSN(region->last_ckp); - TXN_SYSTEM_UNLOCK(dbenv); -err: - return (ret); -} - -/* - * __rep_queue_filedone - - * Determine if we're really done getting the pages for a queue file. - * Queue is handled in several steps. - * 1. First we get the meta page only. - * 2. We use the meta-page information to figure out first and last - * page numbers (and if queue wraps, first can be > last. - * 3. If first < last, we do a REP_PAGE_REQ for all pages. - * 4. If first > last, we REP_PAGE_REQ from first -> max page number. - * Then we'll ask for page 1 -> last. - * - * This function can return several things: - * DB_REP_PAGEDONE - if we're done with this file. - * 0 - if we're not doen with this file. - * error - if we get an error doing some operations. - * - * This function will open a dbp handle to the queue file. This is needed - * by most of the QAM macros. We'll open it on the first pass through - * here and we'll close it whenever we decide we're done. - */ -static int -__rep_queue_filedone(dbenv, rep, rfp) - DB_ENV *dbenv; - REP *rep; - __rep_fileinfo_args *rfp; -{ -#ifndef HAVE_QUEUE - COMPQUIET(rep, NULL); - COMPQUIET(rfp, NULL); - return (__db_no_queue_am(dbenv)); -#else - db_pgno_t first, last; - u_int32_t flags; - int empty, ret, t_ret; -#ifdef DIAGNOSTIC - DB_MSGBUF mb; -#endif - - ret = 0; - if (rep->queue_dbp == NULL) { - /* - * We need to do a sync here so that the open - * can find the file and file id. - */ - if ((ret = __memp_sync(dbenv, NULL)) != 0) - goto out; - if ((ret = db_create(&rep->queue_dbp, dbenv, 0)) != 0) - goto out; - flags = DB_NO_AUTO_COMMIT | - (F_ISSET(dbenv, DB_ENV_THREAD) ? DB_THREAD : 0); - /* - * We need to check whether this is in-memory so that we pass - * the name correctly as either the file or the database name. - */ - if ((ret = __db_open(rep->queue_dbp, NULL, - FLD_ISSET(rfp->flags, DB_AM_INMEM) ? NULL : rfp->info.data, - FLD_ISSET(rfp->flags, DB_AM_INMEM) ? rfp->info.data : NULL, - DB_QUEUE, flags, 0, PGNO_BASE_MD)) != 0) - goto out; - } - if ((ret = __queue_pageinfo(rep->queue_dbp, - &first, &last, &empty, 0, 0)) != 0) - goto out; - RPRINT(dbenv, rep, (dbenv, &mb, - "Queue fileinfo: first %lu, last %lu, empty %d", - (u_long)first, (u_long)last, empty)); - /* - * We can be at the end of 3 possible states. - * 1. We have received the meta-page and now need to get the - * rest of the pages in the database. - * 2. We have received from first -> max_pgno. We might be done, - * or we might need to ask for wrapped pages. - * 3. We have received all pages in the file. We're done. - */ - if (rfp->max_pgno == 0) { - /* - * We have just received the meta page. Set up the next - * pages to ask for and check if the file is empty. - */ - if (empty) - goto out; - if (first > last) { - rfp->max_pgno = - QAM_RECNO_PAGE(rep->queue_dbp, UINT32_MAX); - } else - rfp->max_pgno = last; - RPRINT(dbenv, rep, (dbenv, &mb, - "Queue fileinfo: First req: first %lu, last %lu", - (u_long)first, (u_long)rfp->max_pgno)); - goto req; - } else if (rfp->max_pgno != last) { - /* - * If max_pgno != last that means we're dealing with a - * wrapped situation. Request next batch of pages. - * Set npages to 1 because we already have page 0, the - * meta-page, now we need pages 1-max_pgno. - */ - first = 1; - rfp->max_pgno = last; - RPRINT(dbenv, rep, (dbenv, &mb, - "Queue fileinfo: Wrap req: first %lu, last %lu", - (u_long)first, (u_long)last)); -req: - /* - * Since we're simulating a "gap" to resend new PAGE_REQ - * for this file, we need to set waiting page to last + 1 - * so that we'll ask for all from ready_pg -> last. - */ - rep->npages = first; - rep->ready_pg = first; - rep->waiting_pg = rfp->max_pgno + 1; - rep->max_wait_pg = PGNO_INVALID; - ret = __rep_pggap_req(dbenv, rep, rfp, 0); - return (ret); - } - /* - * max_pgno == last - * If we get here, we have all the pages we need. - * Close the dbp and return. - */ -out: - if (rep->queue_dbp != NULL && - (t_ret = __db_close(rep->queue_dbp, NULL, DB_NOSYNC)) != 0 && - ret == 0) - ret = t_ret; - rep->queue_dbp = NULL; - if (ret == 0) - ret = DB_REP_PAGEDONE; - return (ret); -#endif -} diff --git a/storage/bdb/rep/rep_elect.c b/storage/bdb/rep/rep_elect.c deleted file mode 100644 index 71813532fa1..00000000000 --- a/storage/bdb/rep/rep_elect.c +++ /dev/null @@ -1,939 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2004-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: rep_elect.c,v 12.10 2005/08/23 14:18:19 sue Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <stdlib.h> -#include <string.h> -#if TIME_WITH_SYS_TIME -#include <sys/time.h> -#include <time.h> -#else -#if HAVE_SYS_TIME_H -#include <sys/time.h> -#else -#include <time.h> -#endif -#endif -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_am.h" -#include "dbinc/log.h" - -static void __rep_cmp_vote __P((DB_ENV *, REP *, int, DB_LSN *, - int, u_int32_t, u_int32_t)); -static int __rep_cmp_vote2 __P((DB_ENV *, REP *, int, u_int32_t)); -static int __rep_elect_init - __P((DB_ENV *, DB_LSN *, int, int, int, int *, u_int32_t *)); -static int __rep_tally __P((DB_ENV *, REP *, int, int *, u_int32_t, roff_t)); -static int __rep_wait __P((DB_ENV *, u_int32_t, int *, u_int32_t)); - -/* - * __rep_elect -- - * Called after master failure to hold/participate in an election for - * a new master. - * - * PUBLIC: int __rep_elect __P((DB_ENV *, int, int, int, - * PUBLIC: u_int32_t, int *, u_int32_t)); - */ -int -__rep_elect(dbenv, nsites, nvotes, priority, timeout, eidp, flags) - DB_ENV *dbenv; - int nsites, nvotes, priority; - u_int32_t timeout; - int *eidp; - u_int32_t flags; -{ - DB_LOG *dblp; - DB_LSN lsn; - DB_REP *db_rep; - REP *rep; - int ack, done, in_progress, ret, send_vote; - u_int32_t egen, orig_tally, tiebreaker, to; -#ifdef DIAGNOSTIC - DB_MSGBUF mb; -#endif - - PANIC_CHECK(dbenv); - COMPQUIET(flags, 0); - ENV_REQUIRES_CONFIG(dbenv, dbenv->rep_handle, "rep_elect", DB_INIT_REP); - - /* Error checking. */ - if (nsites <= 0) { - __db_err(dbenv, - "DB_ENV->rep_elect: nsites must be greater than 0"); - return (EINVAL); - } - if (nvotes < 0) { - __db_err(dbenv, - "DB_ENV->rep_elect: nvotes may not be negative"); - return (EINVAL); - } - if (priority < 0) { - __db_err(dbenv, - "DB_ENV->rep_elect: priority may not be negative"); - return (EINVAL); - } - if (nsites < nvotes) { - __db_err(dbenv, - "DB_ENV->rep_elect: nvotes (%d) is larger than nsites (%d)", - nvotes, nsites); - return (EINVAL); - } - - ack = nvotes; - /* If they give us a 0 for nvotes, default to simple majority. */ - if (nvotes == 0) - ack = (nsites / 2) + 1; - - /* - * XXX - * If users give us less than a majority, they run the risk of - * having a network partition. However, this also allows the - * scenario of master/1 client to elect the client. Allow - * sub-majority values, but give a warning. - */ - if (nvotes <= (nsites / 2)) { - __db_err(dbenv, - "DB_ENV->rep_elect:WARNING: nvotes (%d) is sub-majority with nsites (%d)", - nvotes, nsites); - } - - db_rep = dbenv->rep_handle; - rep = db_rep->region; - dblp = dbenv->lg_handle; - - RPRINT(dbenv, rep, - (dbenv, &mb, "Start election nsites %d, ack %d, priority %d", - nsites, ack, priority)); - - LOG_SYSTEM_LOCK(dbenv); - lsn = ((LOG *)dblp->reginfo.primary)->lsn; - LOG_SYSTEM_UNLOCK(dbenv); - - orig_tally = 0; - to = timeout; - if ((ret = __rep_elect_init(dbenv, - &lsn, nsites, ack, priority, &in_progress, &orig_tally)) != 0) { - if (ret == DB_REP_NEWMASTER) { - ret = 0; - *eidp = dbenv->rep_eid; - } - goto err; - } - /* - * If another thread is in the middle of an election we - * just quietly return and not interfere. - */ - if (in_progress) { - *eidp = rep->master_id; - return (0); - } - __os_clock(dbenv, &rep->esec, &rep->eusec); -restart: - /* Generate a randomized tiebreaker value. */ - __os_unique_id(dbenv, &tiebreaker); - - REP_SYSTEM_LOCK(dbenv); - F_SET(rep, REP_F_EPHASE1 | REP_F_NOARCHIVE); - F_CLR(rep, REP_F_TALLY); - - /* - * We are about to participate at this egen. We must - * write out the next egen before participating in this one - * so that if we crash we can never participate in this egen - * again. - */ - if ((ret = __rep_write_egen(dbenv, rep->egen + 1)) != 0) - goto lockdone; - - /* Tally our own vote */ - if (__rep_tally(dbenv, rep, rep->eid, &rep->sites, rep->egen, - rep->tally_off) != 0) { - ret = EINVAL; - goto lockdone; - } - __rep_cmp_vote(dbenv, rep, rep->eid, &lsn, priority, rep->gen, - tiebreaker); - - RPRINT(dbenv, rep, (dbenv, &mb, "Beginning an election")); - - /* Now send vote */ - send_vote = DB_EID_INVALID; - egen = rep->egen; - REP_SYSTEM_UNLOCK(dbenv); - __rep_send_vote(dbenv, &lsn, nsites, ack, priority, tiebreaker, egen, - DB_EID_BROADCAST, REP_VOTE1); - DB_ENV_TEST_RECOVERY(dbenv, DB_TEST_ELECTVOTE1, ret, NULL); - ret = __rep_wait(dbenv, to, eidp, REP_F_EPHASE1); - switch (ret) { - case 0: - /* Check if election complete or phase complete. */ - if (*eidp != DB_EID_INVALID) { - RPRINT(dbenv, rep, (dbenv, &mb, - "Ended election phase 1 %d", ret)); - goto edone; - } - goto phase2; - case DB_REP_EGENCHG: - if (to > timeout) - to = timeout; - to = (to * 8) / 10; - RPRINT(dbenv, rep, (dbenv, &mb, -"Egen changed while waiting. Now %lu. New timeout %lu, orig timeout %lu", - (u_long)rep->egen, (u_long)to, (u_long)timeout)); - /* - * If the egen changed while we were sleeping, that - * means we're probably late to the next election, - * so we'll backoff our timeout so that we don't get - * into an out-of-phase election scenario. - * - * Backoff to 80% of the current timeout. - */ - goto restart; - case DB_TIMEOUT: - break; - default: - goto err; - } - /* - * If we got here, we haven't heard from everyone, but we've - * run out of time, so it's time to decide if we have enough - * votes to pick a winner and if so, to send out a vote to - * the winner. - */ - REP_SYSTEM_LOCK(dbenv); - /* - * If our egen changed while we were waiting. We need to - * essentially reinitialize our election. - */ - if (egen != rep->egen) { - REP_SYSTEM_UNLOCK(dbenv); - RPRINT(dbenv, rep, (dbenv, &mb, "Egen changed from %lu to %lu", - (u_long)egen, (u_long)rep->egen)); - goto restart; - } - if (rep->sites >= rep->nvotes) { - - /* We think we've seen enough to cast a vote. */ - send_vote = rep->winner; - /* - * See if we won. This will make sure we - * don't count ourselves twice if we're racing - * with incoming votes. - */ - if (rep->winner == rep->eid) { - (void)__rep_tally(dbenv, rep, rep->eid, &rep->votes, - egen, rep->v2tally_off); - RPRINT(dbenv, rep, (dbenv, &mb, - "Counted my vote %d", rep->votes)); - } - F_SET(rep, REP_F_EPHASE2); - F_CLR(rep, REP_F_EPHASE1); - } - REP_SYSTEM_UNLOCK(dbenv); - if (send_vote == DB_EID_INVALID) { - /* We do not have enough votes to elect. */ - RPRINT(dbenv, rep, (dbenv, &mb, - "Not enough votes to elect: recvd %d of %d from %d sites", - rep->sites, rep->nvotes, rep->nsites)); - ret = DB_REP_UNAVAIL; - goto err; - - } else { - /* - * We have seen enough vote1's. Now we need to wait - * for all the vote2's. - */ - if (send_vote != rep->eid) { - RPRINT(dbenv, rep, (dbenv, &mb, "Sending vote")); - __rep_send_vote(dbenv, NULL, 0, 0, 0, 0, egen, - send_vote, REP_VOTE2); - /* - * If we are NOT the new master we want to send - * our vote to the winner, and wait longer. The - * reason is that the winner may be "behind" us - * in the election waiting and if the master is - * down, the winner will wait the full timeout - * and we want to give the winner enough time to - * process all the votes. Otherwise we could - * incorrectly return DB_REP_UNAVAIL and start a - * new election before the winner can declare - * itself. - */ - to = to * 2; - - } - -phase2: ret = __rep_wait(dbenv, to, eidp, REP_F_EPHASE2); - RPRINT(dbenv, rep, (dbenv, &mb, - "Ended election phase 2 %d", ret)); - switch (ret) { - case 0: - goto edone; - case DB_REP_EGENCHG: - if (to > timeout) - to = timeout; - to = (to * 8) / 10; - RPRINT(dbenv, rep, (dbenv, &mb, -"While waiting egen changed to %lu. Phase 2 New timeout %lu, orig timeout %lu", - (u_long)rep->egen, - (u_long)to, (u_long)timeout)); - goto restart; - case DB_TIMEOUT: - ret = DB_REP_UNAVAIL; - break; - default: - goto err; - } - REP_SYSTEM_LOCK(dbenv); - if (egen != rep->egen) { - REP_SYSTEM_UNLOCK(dbenv); - RPRINT(dbenv, rep, (dbenv, &mb, - "Egen ph2 changed from %lu to %lu", - (u_long)egen, (u_long)rep->egen)); - goto restart; - } - done = rep->votes >= rep->nvotes; - RPRINT(dbenv, rep, (dbenv, &mb, - "After phase 2: done %d, votes %d, nsites %d", - done, rep->votes, rep->nsites)); - if (send_vote == rep->eid && done) { - __rep_elect_master(dbenv, rep, eidp); - ret = 0; - goto lockdone; - } - REP_SYSTEM_UNLOCK(dbenv); - } - -err: REP_SYSTEM_LOCK(dbenv); -lockdone: - /* - * If we get here because of a non-election error, then we - * did not tally our vote. The only non-election error is - * from elect_init where we were unable to grow_sites. In - * that case we do not want to discard all known election info. - */ - if (ret == 0 || ret == DB_REP_UNAVAIL) - __rep_elect_done(dbenv, rep); - else if (orig_tally) - F_SET(rep, orig_tally); - - /* - * If the election finished elsewhere, we need to decrement - * the elect_th anyway. - */ - if (0) { -edone: REP_SYSTEM_LOCK(dbenv); - } - rep->elect_th = 0; - - RPRINT(dbenv, rep, (dbenv, &mb, - "Ended election with %d, sites %d, egen %lu, flags 0x%lx", - ret, rep->sites, (u_long)rep->egen, (u_long)rep->flags)); - REP_SYSTEM_UNLOCK(dbenv); - -DB_TEST_RECOVERY_LABEL - return (ret); -} - -/* - * __rep_vote1 -- - * Handle incoming vote1 message on a client. - * - * PUBLIC: int __rep_vote1 __P((DB_ENV *, REP_CONTROL *, DBT *, int)); - */ -int -__rep_vote1(dbenv, rp, rec, eid) - DB_ENV *dbenv; - REP_CONTROL *rp; - DBT *rec; - int eid; -{ - DB_LOG *dblp; - DB_LSN lsn; - DB_REP *db_rep; - DBT data_dbt; - LOG *lp; - REP *rep; - REP_VOTE_INFO *vi; - u_int32_t egen; - int done, master, ret; -#ifdef DIAGNOSTIC - DB_MSGBUF mb; -#endif - - ret = 0; - db_rep = dbenv->rep_handle; - rep = db_rep->region; - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - - if (F_ISSET(rep, REP_F_MASTER)) { - RPRINT(dbenv, rep, - (dbenv, &mb, "Master received vote")); - LOG_SYSTEM_LOCK(dbenv); - lsn = lp->lsn; - LOG_SYSTEM_UNLOCK(dbenv); - (void)__rep_send_message(dbenv, - DB_EID_BROADCAST, REP_NEWMASTER, &lsn, NULL, 0, 0); - return (ret); - } - - vi = (REP_VOTE_INFO *)rec->data; - REP_SYSTEM_LOCK(dbenv); - - /* - * If we get a vote from a later election gen, we - * clear everything from the current one, and we'll - * start over by tallying it. If we get an old vote, - * send an ALIVE to the old participant. - */ - RPRINT(dbenv, rep, (dbenv, &mb, - "Received vote1 egen %lu, egen %lu", - (u_long)vi->egen, (u_long)rep->egen)); - if (vi->egen < rep->egen) { - RPRINT(dbenv, rep, (dbenv, &mb, - "Received old vote %lu, egen %lu, ignoring vote1", - (u_long)vi->egen, (u_long)rep->egen)); - egen = rep->egen; - REP_SYSTEM_UNLOCK(dbenv); - data_dbt.data = &egen; - data_dbt.size = sizeof(egen); - (void)__rep_send_message(dbenv, - eid, REP_ALIVE, &rp->lsn, &data_dbt, 0, 0); - return (ret); - } - if (vi->egen > rep->egen) { - RPRINT(dbenv, rep, (dbenv, &mb, - "Received VOTE1 from egen %lu, my egen %lu; reset", - (u_long)vi->egen, (u_long)rep->egen)); - __rep_elect_done(dbenv, rep); - rep->egen = vi->egen; - } - if (!IN_ELECTION(rep)) - F_SET(rep, REP_F_TALLY); - - /* Check if this site knows about more sites than we do. */ - if (vi->nsites > rep->nsites) - rep->nsites = vi->nsites; - - /* Check if this site requires more votes than we do. */ - if (vi->nvotes > rep->nvotes) - rep->nvotes = vi->nvotes; - - /* - * We are keeping the vote, let's see if that changes our - * count of the number of sites. - */ - if (rep->sites + 1 > rep->nsites) - rep->nsites = rep->sites + 1; - if (rep->nsites > rep->asites && - (ret = __rep_grow_sites(dbenv, rep->nsites)) != 0) { - RPRINT(dbenv, rep, (dbenv, &mb, - "Grow sites returned error %d", ret)); - goto err; - } - - /* - * Ignore vote1's if we're in phase 2. - */ - if (F_ISSET(rep, REP_F_EPHASE2)) { - RPRINT(dbenv, rep, (dbenv, &mb, - "In phase 2, ignoring vote1")); - goto err; - } - - /* - * Record this vote. If we get back non-zero, we - * ignore the vote. - */ - if ((ret = __rep_tally(dbenv, rep, eid, &rep->sites, - vi->egen, rep->tally_off)) != 0) { - RPRINT(dbenv, rep, (dbenv, &mb, - "Tally returned %d, sites %d", - ret, rep->sites)); - ret = 0; - goto err; - } - RPRINT(dbenv, rep, (dbenv, &mb, - "Incoming vote: (eid)%d (pri)%d (gen)%lu (egen)%lu [%lu,%lu]", - eid, vi->priority, - (u_long)rp->gen, (u_long)vi->egen, - (u_long)rp->lsn.file, (u_long)rp->lsn.offset)); -#ifdef DIAGNOSTIC - if (rep->sites > 1) - RPRINT(dbenv, rep, (dbenv, &mb, - "Existing vote: (eid)%d (pri)%d (gen)%lu (sites)%d [%lu,%lu]", - rep->winner, rep->w_priority, - (u_long)rep->w_gen, rep->sites, - (u_long)rep->w_lsn.file, - (u_long)rep->w_lsn.offset)); -#endif - __rep_cmp_vote(dbenv, rep, eid, &rp->lsn, vi->priority, - rp->gen, vi->tiebreaker); - /* - * If you get a vote and you're not in an election, we've - * already recorded this vote. But that is all we need - * to do. - */ - if (!IN_ELECTION(rep)) { - RPRINT(dbenv, rep, (dbenv, &mb, - "Not in election, but received vote1 0x%x", - rep->flags)); - ret = DB_REP_HOLDELECTION; - goto err; - } - - master = rep->winner; - lsn = rep->w_lsn; - /* - * We need to check sites == nsites, not more than half - * like we do in __rep_elect and the VOTE2 code below. The - * reason is that we want to process all the incoming votes - * and not short-circuit once we reach more than half. The - * real winner's vote may be in the last half. - */ - done = rep->sites >= rep->nsites && rep->w_priority != 0; - if (done) { - RPRINT(dbenv, rep, - (dbenv, &mb, "Phase1 election done")); - RPRINT(dbenv, rep, (dbenv, &mb, "Voting for %d%s", - master, master == rep->eid ? "(self)" : "")); - egen = rep->egen; - F_SET(rep, REP_F_EPHASE2); - F_CLR(rep, REP_F_EPHASE1); - if (master == rep->eid) { - (void)__rep_tally(dbenv, rep, rep->eid, - &rep->votes, egen, rep->v2tally_off); - goto err; - } - REP_SYSTEM_UNLOCK(dbenv); - - /* Vote for someone else. */ - __rep_send_vote(dbenv, NULL, 0, 0, 0, 0, egen, - master, REP_VOTE2); - } else -err: REP_SYSTEM_UNLOCK(dbenv); - return (ret); -} - -/* - * __rep_vote2 -- - * Handle incoming vote1 message on a client. - * - * PUBLIC: int __rep_vote2 __P((DB_ENV *, DBT *, int *)); - */ -int -__rep_vote2(dbenv, rec, eidp) - DB_ENV *dbenv; - DBT *rec; - int *eidp; -{ - DB_LOG *dblp; - DB_LSN lsn; - DB_REP *db_rep; - LOG *lp; - REP *rep; - REP_VOTE_INFO *vi; - int done, ret; -#ifdef DIAGNOSTIC - DB_MSGBUF mb; -#endif - - ret = 0; - db_rep = dbenv->rep_handle; - rep = db_rep->region; - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - - RPRINT(dbenv, rep, (dbenv, &mb, "We received a vote%s", - F_ISSET(rep, REP_F_MASTER) ? " (master)" : "")); - if (F_ISSET(rep, REP_F_MASTER)) { - LOG_SYSTEM_LOCK(dbenv); - lsn = lp->lsn; - LOG_SYSTEM_UNLOCK(dbenv); - rep->stat.st_elections_won++; - (void)__rep_send_message(dbenv, - DB_EID_BROADCAST, REP_NEWMASTER, &lsn, NULL, 0, 0); - return (ret); - } - - REP_SYSTEM_LOCK(dbenv); - - /* If we have priority 0, we should never get a vote. */ - DB_ASSERT(rep->priority != 0); - - /* - * We might be the last to the party and we haven't had - * time to tally all the vote1's, but others have and - * decided we're the winner. So, if we're in the process - * of tallying sites, keep the vote so that when our - * election thread catches up we'll have the votes we - * already received. - */ - vi = (REP_VOTE_INFO *)rec->data; - if (!IN_ELECTION_TALLY(rep) && vi->egen >= rep->egen) { - RPRINT(dbenv, rep, (dbenv, &mb, - "Not in election gen %lu, at %lu, got vote", - (u_long)vi->egen, (u_long)rep->egen)); - ret = DB_REP_HOLDELECTION; - goto err; - } - - /* - * Record this vote. In a VOTE2, the only valid entry - * in the REP_VOTE_INFO is the election generation. - * - * There are several things which can go wrong that we - * need to account for: - * 1. If we receive a latent VOTE2 from an earlier election, - * we want to ignore it. - * 2. If we receive a VOTE2 from a site from which we never - * received a VOTE1, we want to ignore it. - * 3. If we have received a duplicate VOTE2 from this election - * from the same site we want to ignore it. - * 4. If this is from the current election and someone is - * really voting for us, then we finally get to record it. - */ - /* - * __rep_cmp_vote2 checks for cases 1 and 2. - */ - if ((ret = __rep_cmp_vote2(dbenv, rep, *eidp, vi->egen)) != 0) { - ret = 0; - goto err; - } - /* - * __rep_tally takes care of cases 3 and 4. - */ - if ((ret = __rep_tally(dbenv, rep, *eidp, &rep->votes, - vi->egen, rep->v2tally_off)) != 0) { - ret = 0; - goto err; - } - done = rep->votes >= rep->nvotes; - RPRINT(dbenv, rep, (dbenv, &mb, "Counted vote %d of %d", - rep->votes, rep->nvotes)); - if (done) { - __rep_elect_master(dbenv, rep, eidp); - ret = DB_REP_NEWMASTER; - } - -err: REP_SYSTEM_UNLOCK(dbenv); - return (ret); -} - -/* - * __rep_tally -- - * Handle incoming vote1 message on a client. Called with the db_rep - * mutex held. This function will return 0 if we successfully tally - * the vote and non-zero if the vote is ignored. This will record - * both VOTE1 and VOTE2 records, depending on which region offset the - * caller passed in. - */ -static int -__rep_tally(dbenv, rep, eid, countp, egen, vtoff) - DB_ENV *dbenv; - REP *rep; - int eid, *countp; - u_int32_t egen; - roff_t vtoff; -{ - REP_VTALLY *tally, *vtp; - int i; -#ifdef DIAGNOSTIC - DB_MSGBUF mb; -#else - COMPQUIET(rep, NULL); -#endif - - tally = R_ADDR((REGINFO *)dbenv->reginfo, vtoff); - i = 0; - vtp = &tally[i]; - while (i < *countp) { - /* - * Ignore votes from earlier elections (i.e. we've heard - * from this site in this election, but its vote from an - * earlier election got delayed and we received it now). - * However, if we happened to hear from an earlier vote - * and we recorded it and we're now hearing from a later - * election we want to keep the updated one. Note that - * updating the entry will not increase the count. - * Also ignore votes that are duplicates. - */ - if (vtp->eid == eid) { - RPRINT(dbenv, rep, (dbenv, &mb, - "Tally found[%d] (%d, %lu), this vote (%d, %lu)", - i, vtp->eid, (u_long)vtp->egen, - eid, (u_long)egen)); - if (vtp->egen >= egen) - return (1); - else { - vtp->egen = egen; - return (0); - } - } - i++; - vtp = &tally[i]; - } - /* - * If we get here, we have a new voter we haven't - * seen before. Tally this vote. - */ -#ifdef DIAGNOSTIC - if (vtoff == rep->tally_off) - RPRINT(dbenv, rep, (dbenv, &mb, "Tallying VOTE1[%d] (%d, %lu)", - i, eid, (u_long)egen)); - else - RPRINT(dbenv, rep, (dbenv, &mb, "Tallying VOTE2[%d] (%d, %lu)", - i, eid, (u_long)egen)); -#endif - vtp->eid = eid; - vtp->egen = egen; - (*countp)++; - return (0); -} - -/* - * __rep_cmp_vote -- - * Compare incoming vote1 message on a client. Called with the db_rep - * mutex held. - * - */ -static void -__rep_cmp_vote(dbenv, rep, eid, lsnp, priority, gen, tiebreaker) - DB_ENV *dbenv; - REP *rep; - int eid; - DB_LSN *lsnp; - int priority; - u_int32_t gen, tiebreaker; -{ - int cmp; - -#ifdef DIAGNOSTIC - DB_MSGBUF mb; -#else - COMPQUIET(dbenv, NULL); -#endif - cmp = log_compare(lsnp, &rep->w_lsn); - /* - * If we've seen more than one, compare us to the best so far. - * If we're the first, make ourselves the winner to start. - */ - if (rep->sites > 1 && priority != 0) { - /* - * LSN is primary determinant. Then priority if LSNs - * are equal, then tiebreaker if both are equal. - */ - if (cmp > 0 || - (cmp == 0 && (priority > rep->w_priority || - (priority == rep->w_priority && - (tiebreaker > rep->w_tiebreaker))))) { - RPRINT(dbenv, rep, (dbenv, &mb, "Accepting new vote")); - rep->winner = eid; - rep->w_priority = priority; - rep->w_lsn = *lsnp; - rep->w_gen = gen; - rep->w_tiebreaker = tiebreaker; - } - } else if (rep->sites == 1) { - if (priority != 0) { - /* Make ourselves the winner to start. */ - rep->winner = eid; - rep->w_priority = priority; - rep->w_gen = gen; - rep->w_lsn = *lsnp; - rep->w_tiebreaker = tiebreaker; - } else { - rep->winner = DB_EID_INVALID; - rep->w_priority = 0; - rep->w_gen = 0; - ZERO_LSN(rep->w_lsn); - rep->w_tiebreaker = 0; - } - } - return; -} - -/* - * __rep_cmp_vote2 -- - * Compare incoming vote2 message with vote1's we've recorded. Called - * with the db_rep mutex held. We return 0 if the VOTE2 is from a - * site we've heard from and it is from this election. Otherwise return 1. - * - */ -static int -__rep_cmp_vote2(dbenv, rep, eid, egen) - DB_ENV *dbenv; - REP *rep; - int eid; - u_int32_t egen; -{ - int i; - REP_VTALLY *tally, *vtp; -#ifdef DIAGNOSTIC - DB_MSGBUF mb; -#endif - - tally = R_ADDR((REGINFO *)dbenv->reginfo, rep->tally_off); - i = 0; - vtp = &tally[i]; - for (i = 0; i < rep->sites; i++) { - vtp = &tally[i]; - if (vtp->eid == eid && vtp->egen == egen) { - RPRINT(dbenv, rep, (dbenv, &mb, - "Found matching vote1 (%d, %lu), at %d of %d", - eid, (u_long)egen, i, rep->sites)); - return (0); - } - } - RPRINT(dbenv, rep, - (dbenv, &mb, "Didn't find vote1 for eid %d, egen %lu", - eid, (u_long)egen)); - return (1); -} - -/* - * __rep_elect_init - * Initialize an election. Sets beginp non-zero if the election is - * already in progress; makes it 0 otherwise. - */ -static int -__rep_elect_init(dbenv, lsnp, nsites, nvotes, priority, beginp, otally) - DB_ENV *dbenv; - DB_LSN *lsnp; - int nsites, nvotes, priority; - int *beginp; - u_int32_t *otally; -{ - DB_REP *db_rep; - REP *rep; - int ret; - - db_rep = dbenv->rep_handle; - rep = db_rep->region; - - ret = 0; - - /* We may miscount, as we don't hold the replication mutex here. */ - rep->stat.st_elections++; - - /* If we are already a master; simply broadcast that fact and return. */ - if (F_ISSET(rep, REP_F_MASTER)) { - (void)__rep_send_message(dbenv, - DB_EID_BROADCAST, REP_NEWMASTER, lsnp, NULL, 0, 0); - rep->stat.st_elections_won++; - return (DB_REP_NEWMASTER); - } - - REP_SYSTEM_LOCK(dbenv); - if (otally != NULL) - *otally = F_ISSET(rep, REP_F_TALLY); - *beginp = IN_ELECTION(rep) || rep->elect_th; - if (!*beginp) { - /* - * Make sure that we always initialize all the election fields - * before putting ourselves in an election state. That means - * issuing calls that can fail (allocation) before setting all - * the variables. - */ - if (nsites > rep->asites && - (ret = __rep_grow_sites(dbenv, nsites)) != 0) - goto err; - DB_ENV_TEST_RECOVERY(dbenv, DB_TEST_ELECTINIT, ret, NULL); - rep->elect_th = 1; - rep->nsites = nsites; - rep->nvotes = nvotes; - rep->priority = priority; - rep->master_id = DB_EID_INVALID; - } -DB_TEST_RECOVERY_LABEL -err: REP_SYSTEM_UNLOCK(dbenv); - return (ret); -} - -/* - * __rep_elect_master - * Set up for new master from election. Must be called with - * the replication region mutex held. - * - * PUBLIC: void __rep_elect_master __P((DB_ENV *, REP *, int *)); - */ -void -__rep_elect_master(dbenv, rep, eidp) - DB_ENV *dbenv; - REP *rep; - int *eidp; -{ -#ifdef DIAGNOSTIC - DB_MSGBUF mb; -#else - COMPQUIET(dbenv, NULL); -#endif - rep->master_id = rep->eid; - F_SET(rep, REP_F_MASTERELECT); - if (eidp != NULL) - *eidp = rep->master_id; - rep->stat.st_elections_won++; - RPRINT(dbenv, rep, (dbenv, &mb, - "Got enough votes to win; election done; winner is %d, gen %lu", - rep->master_id, (u_long)rep->gen)); -} - -static int -__rep_wait(dbenv, timeout, eidp, flags) - DB_ENV *dbenv; - u_int32_t timeout; - int *eidp; - u_int32_t flags; -{ - DB_REP *db_rep; - REP *rep; - int done, echg; - u_int32_t egen, sleeptime; - - done = echg = 0; - db_rep = dbenv->rep_handle; - rep = db_rep->region; - egen = rep->egen; - - /* - * The user specifies an overall timeout function, but checking - * is cheap and the timeout may be a generous upper bound. - * Sleep repeatedly for the smaller of .5s and timeout/10. - */ - sleeptime = (timeout > 5000000) ? 500000 : timeout / 10; - if (sleeptime == 0) - sleeptime++; - while (timeout > 0) { - __os_sleep(dbenv, 0, sleeptime); - REP_SYSTEM_LOCK(dbenv); - echg = egen != rep->egen; - done = !F_ISSET(rep, flags) && rep->master_id != DB_EID_INVALID; - - *eidp = rep->master_id; - REP_SYSTEM_UNLOCK(dbenv); - - if (done) - return (0); - - if (echg) - return (DB_REP_EGENCHG); - - if (timeout > sleeptime) - timeout -= sleeptime; - else - timeout = 0; - } - return (DB_TIMEOUT); -} diff --git a/storage/bdb/rep/rep_log.c b/storage/bdb/rep/rep_log.c deleted file mode 100644 index 83c04a54254..00000000000 --- a/storage/bdb/rep/rep_log.c +++ /dev/null @@ -1,616 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2004-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: rep_log.c,v 12.26 2005/10/12 17:58:39 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#if TIME_WITH_SYS_TIME -#include <sys/time.h> -#include <time.h> -#else -#if HAVE_SYS_TIME_H -#include <sys/time.h> -#else -#include <time.h> -#endif -#endif - -#include <stdlib.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_am.h" -#include "dbinc/log.h" - -/* - * __rep_allreq -- - * Handle a REP_ALL_REQ message. - * - * PUBLIC: int __rep_allreq __P((DB_ENV *, REP_CONTROL *, int)); - */ -int -__rep_allreq(dbenv, rp, eid) - DB_ENV *dbenv; - REP_CONTROL *rp; - int eid; -{ - DB_LOGC *logc; - DB_LSN oldfilelsn; - DB_REP *db_rep; - DBT data_dbt; - REP *rep; - REP_BULK bulk; - REP_THROTTLE repth; - uintptr_t bulkoff; - u_int32_t bulkflags, flags, use_bulk; - int ret, t_ret; - - ret = 0; - db_rep = dbenv->rep_handle; - rep = db_rep->region; - - if ((ret = __log_cursor(dbenv, &logc)) != 0) - return (ret); - memset(&data_dbt, 0, sizeof(data_dbt)); - /* - * If we're doing bulk transfer, allocate a bulk buffer to put our - * log records in. We still need to initialize the throttle info - * because if we encounter a log record larger than our entire bulk - * buffer, we need to send it as a singleton and also we want to - * support throttling with bulk. - * - * Use a local var so we don't need to worry if someone else turns - * on/off bulk in the middle of our call. - */ - use_bulk = FLD_ISSET(rep->config, REP_C_BULK); - if (use_bulk && (ret = __rep_bulk_alloc(dbenv, &bulk, eid, - &bulkoff, &bulkflags, REP_BULK_LOG)) != 0) - goto err; - memset(&repth, 0, sizeof(repth)); - REP_SYSTEM_LOCK(dbenv); - repth.gbytes = rep->gbytes; - repth.bytes = rep->bytes; - oldfilelsn = repth.lsn = rp->lsn; - repth.type = REP_LOG; - repth.data_dbt = &data_dbt; - REP_SYSTEM_UNLOCK(dbenv); - flags = IS_ZERO_LSN(rp->lsn) || - IS_INIT_LSN(rp->lsn) ? DB_FIRST : DB_SET; - /* - * We get the first item so that a client servicing requests - * can distinguish between not having the records and reaching - * the end of its log. Return the DB_NOTFOUND if the client - * cannot get the record. Return 0 if we finish the loop and - * sent all that we have. - */ - ret = __log_c_get(logc, &repth.lsn, &data_dbt, flags); - if (ret == DB_NOTFOUND) { - if (F_ISSET(rep, REP_F_MASTER)) - ret = 0; - goto err; - } - /* - * For singleton log records, we break when we get a REP_LOG_MORE. - * Or if we're not using throttling, or we are using bulk, we stop - * when we reach the end (i.e. ret != 0). - */ - for (; - ret == 0 && repth.type != REP_LOG_MORE; - ret = __log_c_get(logc, &repth.lsn, &data_dbt, DB_NEXT)) { - /* - * If the client is asking for all records because it doesn't - * have any, and our first record is not in the first log - * file, then the client is outdated and needs to get a - * VERIFY_FAIL. - */ - if (repth.lsn.file != 1 && flags == DB_FIRST) { - (void)__rep_send_message(dbenv, eid, - REP_VERIFY_FAIL, &repth.lsn, NULL, 0, 0); - break; - } - if (repth.lsn.file != oldfilelsn.file) - (void)__rep_send_message(dbenv, - eid, REP_NEWFILE, &oldfilelsn, NULL, 0, 0); - /* - * If we are configured for bulk, try to send this as a bulk - * request. If not configured, or it is too big for bulk - * then just send normally. - */ - if (use_bulk) - ret = __rep_bulk_message(dbenv, &bulk, &repth, - &repth.lsn, &data_dbt, DB_LOG_RESEND); - if (!use_bulk || ret == DB_REP_BULKOVF) - ret = __rep_send_throttle(dbenv, eid, &repth, 0); - if (ret != 0) - break; - /* - * If we are about to change files, then we'll need the - * last LSN in the previous file. Save it here. - */ - oldfilelsn = repth.lsn; - oldfilelsn.offset += logc->c_len; - } - - if (ret == DB_NOTFOUND) - ret = 0; - /* - * We're done, force out whatever remains in the bulk buffer and - * free it. - */ - if (use_bulk && (t_ret = __rep_bulk_free(dbenv, &bulk, - DB_LOG_RESEND)) != 0 && ret == 0) - ret = t_ret; -err: - if ((t_ret = __log_c_close(logc)) != 0 && ret == 0) - ret = t_ret; - return (ret); -} - -/* - * __rep_log -- - * Handle a REP_LOG/REP_LOG_MORE message. - * - * PUBLIC: int __rep_log __P((DB_ENV *, REP_CONTROL *, DBT *, - * PUBLIC: time_t, DB_LSN *)); - */ -int -__rep_log(dbenv, rp, rec, savetime, ret_lsnp) - DB_ENV *dbenv; - REP_CONTROL *rp; - DBT *rec; - time_t savetime; - DB_LSN *ret_lsnp; -{ - DB_LOG *dblp; - DB_LSN lsn; - DB_REP *db_rep; - LOG *lp; - REP *rep; - int is_dup, master, ret; - - is_dup = ret = 0; - db_rep = dbenv->rep_handle; - rep = db_rep->region; - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - - ret = __rep_apply(dbenv, rp, rec, ret_lsnp, &is_dup); - switch (ret) { - /* - * We're in an internal backup and we've gotten - * all the log we need to run recovery. Do so now. - */ - case DB_REP_LOGREADY: - if ((ret = __log_flush(dbenv, NULL)) != 0) - goto out; - if ((ret = __rep_verify_match(dbenv, &rep->last_lsn, - savetime)) == 0) { - REP_SYSTEM_LOCK(dbenv); - ZERO_LSN(rep->first_lsn); - ZERO_LSN(rep->last_lsn); - F_CLR(rep, REP_F_RECOVER_LOG); - REP_SYSTEM_UNLOCK(dbenv); - } - break; - /* - * If we get any of the "normal" returns, we only process - * LOG_MORE if this is not a duplicate record. If the - * record is a duplicate we don't want to handle LOG_MORE - * and request a multiple data stream (or trigger internal - * initialization) since this could be a very old record - * that no longer exists on the master. - */ - case DB_REP_ISPERM: - case DB_REP_NOTPERM: - case 0: - if (is_dup) - goto out; - else - break; - /* - * Any other return (errors), we're done. - */ - default: - goto out; - } - if (rp->rectype == REP_LOG_MORE) { - REP_SYSTEM_LOCK(dbenv); - master = rep->master_id; - REP_SYSTEM_UNLOCK(dbenv); - LOG_SYSTEM_LOCK(dbenv); - lsn = lp->lsn; - LOG_SYSTEM_UNLOCK(dbenv); - /* - * If the master_id is invalid, this means that since - * the last record was sent, somebody declared an - * election and we may not have a master to request - * things of. - * - * This is not an error; when we find a new master, - * we'll re-negotiate where the end of the log is and - * try to bring ourselves up to date again anyway. - * - * If we've asked for a bunch of records, it could - * either be from a LOG_REQ or ALL_REQ. If we're - * waiting for a gap to be filled, call loggap_req, - * otherwise use ALL_REQ again. - */ - MUTEX_LOCK(dbenv, rep->mtx_clientdb); - if (master == DB_EID_INVALID) { - ret = 0; - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - } else if (IS_ZERO_LSN(lp->waiting_lsn)) { - /* - * We're making an ALL_REQ. However, since we're - * in a LOG_MORE, this is in reply to a request and - * it is likely we may receive new records, even if - * we don't have any at this moment. So, to avoid - * multiple data streams, set the wait_recs high - * now to give the master a chance to start sending - * us these records before the gap code re-requests - * the same gap. Wait_recs will get reset once we - * start receiving these records. - */ - lp->wait_recs = rep->max_gap; - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - if (__rep_send_message(dbenv, master, REP_ALL_REQ, - &lsn, NULL, 0, DB_REP_ANYWHERE) != 0) - goto out; - } else { - ret = __rep_loggap_req(dbenv, rep, &lsn, REP_GAP_FORCE); - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - } - } -out: - return (ret); -} - -/* - * __rep_bulk_log -- - * Handle a REP_BULK_LOG message. - * - * PUBLIC: int __rep_bulk_log __P((DB_ENV *, REP_CONTROL *, DBT *, - * PUBLIC: time_t, DB_LSN *)); - */ -int -__rep_bulk_log(dbenv, rp, rec, savetime, ret_lsnp) - DB_ENV *dbenv; - REP_CONTROL *rp; - DBT *rec; - time_t savetime; - DB_LSN *ret_lsnp; -{ - DB_REP *db_rep; - REP *rep; - int ret; - - db_rep = dbenv->rep_handle; - rep = db_rep->region; - - ret = __log_rep_split(dbenv, rp, rec, ret_lsnp); - switch (ret) { - /* - * We're in an internal backup and we've gotten - * all the log we need to run recovery. Do so now. - */ - case DB_REP_LOGREADY: - if ((ret = __log_flush(dbenv, NULL)) != 0) - goto out; - if ((ret = __rep_verify_match(dbenv, &rep->last_lsn, - savetime)) == 0) { - REP_SYSTEM_LOCK(dbenv); - ZERO_LSN(rep->first_lsn); - ZERO_LSN(rep->last_lsn); - F_CLR(rep, REP_F_RECOVER_LOG); - REP_SYSTEM_UNLOCK(dbenv); - } - break; - /* - * Any other return (errors), we're done. - */ - default: - break; - } -out: - return (ret); -} - -/* - * __rep_log_req -- - * Handle a REP_LOG_REQ message. - * - * PUBLIC: int __rep_logreq __P((DB_ENV *, REP_CONTROL *, DBT *, int)); - */ -int -__rep_logreq(dbenv, rp, rec, eid) - DB_ENV *dbenv; - REP_CONTROL *rp; - DBT *rec; - int eid; -{ - DB_LOG *dblp; - DB_LOGC *logc; - DB_LSN endlsn, lsn, oldfilelsn; - DB_REP *db_rep; - DBT data_dbt; - LOG *lp; - REP *rep; - REP_BULK bulk; - REP_THROTTLE repth; - uintptr_t bulkoff; - u_int32_t bulkflags, use_bulk; - int ret, t_ret; -#ifdef DIAGNOSTIC - DB_MSGBUF mb; -#endif - - ret = 0; - db_rep = dbenv->rep_handle; - rep = db_rep->region; - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - - if (rec != NULL && rec->size != 0) { - RPRINT(dbenv, rep, (dbenv, &mb, - "[%lu][%lu]: LOG_REQ max lsn: [%lu][%lu]", - (u_long) rp->lsn.file, (u_long)rp->lsn.offset, - (u_long)((DB_LSN *)rec->data)->file, - (u_long)((DB_LSN *)rec->data)->offset)); - } - /* - * There are three different cases here. - * 1. We asked log_c_get for a particular LSN and got it. - * 2. We asked log_c_get for an LSN and it's not found because it is - * beyond the end of a log file and we need a NEWFILE msg. - * and then the record that was requested. - * 3. We asked log_c_get for an LSN and it simply doesn't exist, but - * doesn't meet any of those other criteria, in which case - * it's an error (that should never happen on a master). - * - * If we have a valid LSN and the request has a data_dbt with - * it, the sender is asking for a chunk of log records. - * Then we need to send all records up to the LSN in the data dbt. - */ - memset(&data_dbt, 0, sizeof(data_dbt)); - oldfilelsn = lsn = rp->lsn; - if ((ret = __log_cursor(dbenv, &logc)) != 0) - return (ret); - ret = __log_c_get(logc, &lsn, &data_dbt, DB_SET); - - if (ret == 0) /* Case 1 */ - (void)__rep_send_message(dbenv, - eid, REP_LOG, &lsn, &data_dbt, DB_LOG_RESEND, 0); - else if (ret == DB_NOTFOUND) { - LOG_SYSTEM_LOCK(dbenv); - endlsn = lp->lsn; - LOG_SYSTEM_UNLOCK(dbenv); - if (endlsn.file > lsn.file) { - /* - * Case 2: - * Need to find the LSN of the last record in - * file lsn.file so that we can send it with - * the NEWFILE call. In order to do that, we - * need to try to get {lsn.file + 1, 0} and - * then backup. - */ - endlsn.file = lsn.file + 1; - endlsn.offset = 0; - if ((ret = __log_c_get(logc, - &endlsn, &data_dbt, DB_SET)) != 0 || - (ret = __log_c_get(logc, - &endlsn, &data_dbt, DB_PREV)) != 0) { - RPRINT(dbenv, rep, (dbenv, &mb, - "Unable to get prev of [%lu][%lu]", - (u_long)lsn.file, - (u_long)lsn.offset)); - /* - * We want to push the error back - * to the client so that the client - * does an internal backup. The - * client asked for a log record - * we no longer have and it is - * outdated. - * XXX - This could be optimized by - * having the master perform and - * send a REP_UPDATE message. We - * currently want the client to set - * up its 'update' state prior to - * requesting REP_UPDATE_REQ. - * - * If we're a client servicing a request - * just return DB_NOTFOUND. - */ - if (F_ISSET(rep, REP_F_MASTER)) { - ret = 0; - (void)__rep_send_message(dbenv, eid, - REP_VERIFY_FAIL, &rp->lsn, - NULL, 0, 0); - } else - ret = DB_NOTFOUND; - } else { - endlsn.offset += logc->c_len; - (void)__rep_send_message(dbenv, eid, - REP_NEWFILE, &endlsn, NULL, 0, 0); - } - } else { - /* Case 3 */ - /* - * If we're a master, this is a problem. - * If we're a client servicing a request - * just return the DB_NOTFOUND. - */ - if (F_ISSET(rep, REP_F_MASTER)) { - __db_err(dbenv, - "Request for LSN [%lu][%lu] fails", - (u_long)lsn.file, (u_long)lsn.offset); - DB_ASSERT(0); - ret = EINVAL; - } - } - } - if (ret != 0) - goto err; - - /* - * If the user requested a gap, send the whole thing, - * while observing the limits from set_rep_limit. - */ - /* - * If we're doing bulk transfer, allocate a bulk buffer to put our - * log records in. We still need to initialize the throttle info - * because if we encounter a log record larger than our entire bulk - * buffer, we need to send it as a singleton. - * - * Use a local var so we don't need to worry if someone else turns - * on/off bulk in the middle of our call. - */ - use_bulk = FLD_ISSET(rep->config, REP_C_BULK); - if (use_bulk && (ret = __rep_bulk_alloc(dbenv, &bulk, eid, - &bulkoff, &bulkflags, REP_BULK_LOG)) != 0) - goto err; - memset(&repth, 0, sizeof(repth)); - REP_SYSTEM_LOCK(dbenv); - repth.gbytes = rep->gbytes; - repth.bytes = rep->bytes; - repth.type = REP_LOG; - repth.data_dbt = &data_dbt; - REP_SYSTEM_UNLOCK(dbenv); - while (ret == 0 && rec != NULL && rec->size != 0 && - repth.type == REP_LOG) { - if ((ret = - __log_c_get(logc, &repth.lsn, &data_dbt, DB_NEXT)) != 0) { - /* - * If we're a client and we only have part of the gap, - * return DB_NOTFOUND so that we send a REREQUEST - * back to the requester and it can ask for more. - */ - if (ret == DB_NOTFOUND && F_ISSET(rep, REP_F_MASTER)) - ret = 0; - break; - } - if (log_compare(&repth.lsn, (DB_LSN *)rec->data) >= 0) - break; - if (repth.lsn.file != oldfilelsn.file) - (void)__rep_send_message(dbenv, - eid, REP_NEWFILE, &oldfilelsn, NULL, 0, 0); - /* - * If we are configured for bulk, try to send this as a bulk - * request. If not configured, or it is too big for bulk - * then just send normally. - */ - if (use_bulk) - ret = __rep_bulk_message(dbenv, &bulk, &repth, - &repth.lsn, &data_dbt, DB_LOG_RESEND); - if (!use_bulk || ret == DB_REP_BULKOVF) - ret = __rep_send_throttle(dbenv, eid, &repth, 0); - if (ret != 0) - break; - /* - * If we are about to change files, then we'll need the - * last LSN in the previous file. Save it here. - */ - oldfilelsn = repth.lsn; - oldfilelsn.offset += logc->c_len; - } - - /* - * We're done, force out whatever remains in the bulk buffer and - * free it. - */ - if (use_bulk && (t_ret = __rep_bulk_free(dbenv, &bulk, - DB_LOG_RESEND)) != 0 && ret == 0) - ret = t_ret; -err: - if ((t_ret = __log_c_close(logc)) != 0 && ret == 0) - ret = t_ret; - return (ret); -} - -/* - * __rep_loggap_req - - * Request a log gap. Assumes the caller holds the REP->mtx_clientdb. - * - * lsnp is the current LSN we're handling. It is used to help decide - * if we ask for a gap or singleton. - * gapflags are flags that may override the algorithm or control the - * processing in some way. - * - * PUBLIC: int __rep_loggap_req __P((DB_ENV *, REP *, DB_LSN *, u_int32_t)); - */ -int -__rep_loggap_req(dbenv, rep, lsnp, gapflags) - DB_ENV *dbenv; - REP *rep; - DB_LSN *lsnp; - u_int32_t gapflags; -{ - DB_LOG *dblp; - DBT max_lsn_dbt, *max_lsn_dbtp; - DB_LSN next_lsn; - LOG *lp; - u_int32_t flags, type; - - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - LOG_SYSTEM_LOCK(dbenv); - next_lsn = lp->lsn; - LOG_SYSTEM_UNLOCK(dbenv); - flags = 0; - type = REP_LOG_REQ; - - /* - * Check if we need to ask for the gap. - * We ask for the gap if: - * We are forced to with gapflags. - * If max_wait_lsn is ZERO_LSN - we've never asked for - * records before. - * If we asked for a single record and received it. - * - * If we want a gap, but don't have an ending LSN (waiting_lsn) - * send an ALL_REQ. This is primarily used by REP_REREQUEST when - * an ALL_REQ was not able to be fulfilled by another client. - */ - if (FLD_ISSET(gapflags, (REP_GAP_FORCE | REP_GAP_REREQUEST)) || - IS_ZERO_LSN(lp->max_wait_lsn) || - (lsnp != NULL && log_compare(lsnp, &lp->max_wait_lsn) == 0)) { - lp->max_wait_lsn = lp->waiting_lsn; - if (IS_ZERO_LSN(lp->max_wait_lsn)) - type = REP_ALL_REQ; - memset(&max_lsn_dbt, 0, sizeof(max_lsn_dbt)); - max_lsn_dbt.data = &lp->waiting_lsn; - max_lsn_dbt.size = sizeof(lp->waiting_lsn); - max_lsn_dbtp = &max_lsn_dbt; - /* - * Gap requests are "new" and can go anywhere, unless - * this is already a rerequest. - */ - if (FLD_ISSET(gapflags, REP_GAP_REREQUEST)) - flags = DB_REP_REREQUEST; - else - flags = DB_REP_ANYWHERE; - } else { - max_lsn_dbtp = NULL; - lp->max_wait_lsn = next_lsn; - /* - * If we're dropping to singletons, this is a rerequest. - */ - flags = DB_REP_REREQUEST; - } - if (rep->master_id != DB_EID_INVALID) { - rep->stat.st_log_requested++; - (void)__rep_send_message(dbenv, rep->master_id, - type, &next_lsn, max_lsn_dbtp, 0, flags); - } else - (void)__rep_send_message(dbenv, DB_EID_BROADCAST, - REP_MASTER_REQ, NULL, NULL, 0, 0); - - return (0); -} diff --git a/storage/bdb/rep/rep_method.c b/storage/bdb/rep/rep_method.c deleted file mode 100644 index aaa1d70b5a1..00000000000 --- a/storage/bdb/rep/rep_method.c +++ /dev/null @@ -1,1120 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2001-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: rep_method.c,v 12.18 2005/11/08 03:25:13 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stdlib.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/btree.h" -#include "dbinc/log.h" -#include "dbinc/txn.h" - -static int __rep_abort_prepared __P((DB_ENV *)); -static int __rep_bt_cmp __P((DB *, const DBT *, const DBT *)); -static void __rep_config_map __P((DB_ENV *, u_int32_t *, u_int32_t *)); -static int __rep_restore_prepared __P((DB_ENV *)); - -/* - * __rep_open -- - * Replication-specific initialization of the DB_ENV structure. - * - * PUBLIC: int __rep_open __P((DB_ENV *)); - */ -int -__rep_open(dbenv) - DB_ENV *dbenv; -{ - DB_REP *db_rep; - int ret; - - if ((ret = __os_calloc(dbenv, 1, sizeof(DB_REP), &db_rep)) != 0) - return (ret); - dbenv->rep_handle = db_rep; - ret = __rep_region_init(dbenv); - return (ret); -} - -/* - * __rep_get_config -- - * Configure the replication subsystem. - * - * PUBLIC: int __rep_get_config __P((DB_ENV *, u_int32_t, int *)); - */ -int -__rep_get_config(dbenv, which, onp) - DB_ENV *dbenv; - u_int32_t which; - int *onp; -{ - DB_REP *db_rep; - REP *rep; - u_int32_t mapped; - -#undef OK_FLAGS -#define OK_FLAGS \ -(DB_REP_CONF_BULK | DB_REP_CONF_DELAYCLIENT | DB_REP_CONF_NOAUTOINIT \ - | DB_REP_CONF_NOWAIT) - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, dbenv->rep_handle, - "rep_get_config", DB_INIT_REP); - if (FLD_ISSET(which, ~OK_FLAGS)) - return (__db_ferr(dbenv, "DB_ENV->rep_get_config", 0)); - - db_rep = dbenv->rep_handle; - rep = db_rep->region; - - mapped = 0; - __rep_config_map(dbenv, &which, &mapped); - if (FLD_ISSET(rep->config, mapped)) - *onp = 1; - else - *onp = 0; - return (0); -} - -/* - * __rep_set_config -- - * Configure the replication subsystem. - * - * PUBLIC: int __rep_set_config __P((DB_ENV *, u_int32_t, int)); - */ -int -__rep_set_config(dbenv, which, on) - DB_ENV *dbenv; - u_int32_t which; - int on; -{ - DB_LOG *dblp; - DB_REP *db_rep; - LOG *lp; - REP *rep; - REP_BULK bulk; - int ret; - u_int32_t mapped, orig; - -#undef OK_FLAGS -#define OK_FLAGS \ -(DB_REP_CONF_BULK | DB_REP_CONF_DELAYCLIENT | DB_REP_CONF_NOAUTOINIT \ - | DB_REP_CONF_NOWAIT) - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, dbenv->rep_handle, - "rep_config", DB_INIT_REP); - if (FLD_ISSET(which, ~OK_FLAGS)) - return (__db_ferr(dbenv, "DB_ENV->rep_set_config", 0)); - - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - db_rep = dbenv->rep_handle; - rep = db_rep->region; - - mapped = ret = 0; - __rep_config_map(dbenv, &which, &mapped); - MUTEX_LOCK(dbenv, rep->mtx_clientdb); - REP_SYSTEM_LOCK(dbenv); - orig = rep->config; - if (on) - FLD_SET(rep->config, mapped); - else - FLD_CLR(rep->config, mapped); - - /* - * Bulk transfer requires special processing if it is getting - * toggled. - */ - if (FLD_ISSET(rep->config, REP_C_BULK) && - !FLD_ISSET(orig, REP_C_BULK)) - db_rep->bulk = R_ADDR(&dblp->reginfo, lp->bulk_buf); - REP_SYSTEM_UNLOCK(dbenv); - /* - * If turning bulk off and it was on, send out whatever is in the - * buffer already. - */ - if (FLD_ISSET(orig, REP_C_BULK) && - !FLD_ISSET(rep->config, REP_C_BULK) && lp->bulk_off != 0) { - memset(&bulk, 0, sizeof(bulk)); - if (db_rep->bulk == NULL) - bulk.addr = R_ADDR(&dblp->reginfo, lp->bulk_buf); - else - bulk.addr = db_rep->bulk; - bulk.offp = &lp->bulk_off; - bulk.len = lp->bulk_len; - bulk.type = REP_BULK_LOG; - bulk.eid = DB_EID_BROADCAST; - bulk.flagsp = &lp->bulk_flags; - ret = __rep_send_bulk(dbenv, &bulk, 0); - } - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - return (ret); -} - -static void -__rep_config_map(dbenv, inflagsp, outflagsp) - DB_ENV *dbenv; - u_int32_t *inflagsp, *outflagsp; -{ - COMPQUIET(dbenv, NULL); - - if (FLD_ISSET(*inflagsp, DB_REP_CONF_BULK)) { - FLD_SET(*outflagsp, REP_C_BULK); - FLD_CLR(*inflagsp, DB_REP_CONF_BULK); - } - if (FLD_ISSET(*inflagsp, DB_REP_CONF_DELAYCLIENT)) { - FLD_SET(*outflagsp, REP_C_DELAYCLIENT); - FLD_CLR(*inflagsp, DB_REP_CONF_DELAYCLIENT); - } - if (FLD_ISSET(*inflagsp, DB_REP_CONF_NOAUTOINIT)) { - FLD_SET(*outflagsp, REP_C_NOAUTOINIT); - FLD_CLR(*inflagsp, DB_REP_CONF_NOAUTOINIT); - } - if (FLD_ISSET(*inflagsp, DB_REP_CONF_NOWAIT)) { - FLD_SET(*outflagsp, REP_C_NOWAIT); - FLD_CLR(*inflagsp, DB_REP_CONF_NOWAIT); - } -} - -/* - * __rep_start -- - * Become a master or client, and start sending messages to participate - * in the replication environment. Must be called after the environment - * is open. - * - * We must protect rep_start, which may change the world, with the rest - * of the DB library. Each API interface will count itself as it enters - * the library. Rep_start checks the following: - * - * rep->msg_th - this is the count of threads currently in rep_process_message - * rep->start_th - this is set if a thread is in rep_start. - * rep->handle_cnt - number of threads actively using a dbp in library. - * rep->txn_cnt - number of active txns. - * REP_F_READY - Replication flag that indicates that we wish to run - * recovery, and want to prohibit new transactions from entering and cause - * existing ones to return immediately (with a DB_LOCK_DEADLOCK error). - * - * There is also the renv->rep_timestamp which is updated whenever significant - * events (i.e., new masters, log rollback, etc). Upon creation, a handle - * is associated with the current timestamp. Each time a handle enters the - * library it must check if the handle timestamp is the same as the one - * stored in the replication region. This prevents the use of handles on - * clients that reference non-existent files whose creation was backed out - * during a synchronizing recovery. - * - * PUBLIC: int __rep_start __P((DB_ENV *, DBT *, u_int32_t)); - */ -int -__rep_start(dbenv, dbt, flags) - DB_ENV *dbenv; - DBT *dbt; - u_int32_t flags; -{ - DB_LOG *dblp; - DB_LSN lsn; - DB_REP *db_rep; - REP *rep; - u_int32_t repflags; - int announce, init_db, redo_prepared, ret, role_chg; - int sleep_cnt, t_ret; -#ifdef DIAGNOSTIC - DB_MSGBUF mb; -#endif - - PANIC_CHECK(dbenv); - ENV_ILLEGAL_BEFORE_OPEN(dbenv, "DB_ENV->rep_start"); - ENV_REQUIRES_CONFIG(dbenv, dbenv->rep_handle, "rep_start", DB_INIT_REP); - - db_rep = dbenv->rep_handle; - rep = db_rep->region; - - if ((ret = __db_fchk(dbenv, "DB_ENV->rep_start", flags, - DB_REP_CLIENT | DB_REP_MASTER)) != 0) - return (ret); - - /* Exactly one of CLIENT and MASTER must be specified. */ - if ((ret = __db_fcchk(dbenv, - "DB_ENV->rep_start", flags, DB_REP_CLIENT, DB_REP_MASTER)) != 0) - return (ret); - if (!LF_ISSET(DB_REP_CLIENT | DB_REP_MASTER)) { - __db_err(dbenv, - "DB_ENV->rep_start: replication mode must be specified"); - return (EINVAL); - } - - /* We need a transport function. */ - if (dbenv->rep_send == NULL) { - __db_err(dbenv, - "DB_ENV->set_rep_transport must be called before DB_ENV->rep_start"); - return (EINVAL); - } - - /* - * If we are about to become (or stay) a master. Let's flush the log - * to close any potential holes that might happen when upgrading from - * client to master status. - */ - if (LF_ISSET(DB_REP_MASTER) && (ret = __log_flush(dbenv, NULL)) != 0) - return (ret); - - REP_SYSTEM_LOCK(dbenv); - /* - * We only need one thread to start-up replication, so if - * there is another thread in rep_start, we'll let it finish - * its work and have this thread simply return. - */ - if (rep->start_th != 0) { - /* - * There is already someone in rep_start. Return. - */ - RPRINT(dbenv, rep, (dbenv, &mb, "Thread already in rep_start")); - goto err; - } else - rep->start_th = 1; - - role_chg = (!F_ISSET(rep, REP_F_MASTER) && LF_ISSET(DB_REP_MASTER)) || - (!F_ISSET(rep, REP_F_CLIENT) && LF_ISSET(DB_REP_CLIENT)); - - /* - * Wait for any active txns or mpool ops to complete, and - * prevent any new ones from occurring, only if we're - * changing roles. If we are not changing roles, then we - * only need to coordinate with msg_th. - */ - if (role_chg) { - if ((ret = __rep_lockout(dbenv, rep, 0)) != 0) - goto errunlock; - } else { - for (sleep_cnt = 0; rep->msg_th != 0;) { - if (++sleep_cnt % 60 == 0) - __db_err(dbenv, - "DB_ENV->rep_start waiting %d minutes for replication message thread", - sleep_cnt / 60); - REP_SYSTEM_UNLOCK(dbenv); - __os_sleep(dbenv, 1, 0); - REP_SYSTEM_LOCK(dbenv); - } - } - - if (rep->eid == DB_EID_INVALID) - rep->eid = dbenv->rep_eid; - - if (LF_ISSET(DB_REP_MASTER)) { - if (role_chg) { - /* - * If we're upgrading from having been a client, - * preclose, so that we close our temporary database - * and any files we opened while doing a rep_apply. - * If we don't we can infinitely leak file ids if - * the master crashed with files open (the likely - * case). If we don't close them we can run into - * problems if we try to remove that file or long - * running applications end up with an unbounded - * number of used fileids, each getting written - * on checkpoint. Just close them. - */ - if ((ret = __rep_preclose(dbenv)) != 0) - goto errunlock; - } - - redo_prepared = 0; - if (!F_ISSET(rep, REP_F_MASTER)) { - /* Master is not yet set. */ - if (role_chg) { - if (rep->w_gen > rep->recover_gen) - rep->gen = ++rep->w_gen; - else if (rep->gen > rep->recover_gen) - rep->gen++; - else - rep->gen = rep->recover_gen + 1; - /* - * There could have been any number of failed - * elections, so jump the gen if we need to now. - */ - if (rep->egen > rep->gen) - rep->gen = rep->egen; - redo_prepared = 1; - } else if (rep->gen == 0) - rep->gen = rep->recover_gen + 1; - if (F_ISSET(rep, REP_F_MASTERELECT)) { - __rep_elect_done(dbenv, rep); - F_CLR(rep, REP_F_MASTERELECT); - } - if (rep->egen <= rep->gen) - rep->egen = rep->gen + 1; - RPRINT(dbenv, rep, (dbenv, &mb, - "New master gen %lu, egen %lu", - (u_long)rep->gen, (u_long)rep->egen)); - } - rep->master_id = rep->eid; - /* - * Note, setting flags below implicitly clears out - * REP_F_NOARCHIVE, REP_F_INIT and REP_F_READY. - */ - rep->flags = REP_F_MASTER; - rep->start_th = 0; - REP_SYSTEM_UNLOCK(dbenv); - dblp = (DB_LOG *)dbenv->lg_handle; - LOG_SYSTEM_LOCK(dbenv); - lsn = ((LOG *)dblp->reginfo.primary)->lsn; - LOG_SYSTEM_UNLOCK(dbenv); - - /* - * Send the NEWMASTER message first so that clients know - * subsequent messages are coming from the right master. - * We need to perform all actions below no master what - * regarding errors. - */ - (void)__rep_send_message(dbenv, - DB_EID_BROADCAST, REP_NEWMASTER, &lsn, NULL, 0, 0); - ret = 0; - if (role_chg) { - ret = __txn_reset(dbenv); - REP_SYSTEM_LOCK(dbenv); - F_CLR(rep, REP_F_READY); - rep->in_recovery = 0; - REP_SYSTEM_UNLOCK(dbenv); - } - /* - * Take a transaction checkpoint so that our new generation - * number get written to the log. - */ - if ((t_ret = __txn_checkpoint(dbenv, 0, 0, DB_FORCE)) != 0 && - ret == 0) - ret = t_ret; - if (redo_prepared && - (t_ret = __rep_restore_prepared(dbenv)) != 0 && ret == 0) - ret = t_ret; - } else { - init_db = 0; - announce = role_chg || rep->master_id == DB_EID_INVALID; - - /* - * If we're changing roles from master to client or if - * we never were any role at all, we need to init the db. - */ - if (role_chg || !F_ISSET(rep, REP_F_CLIENT)) { - rep->master_id = DB_EID_INVALID; - init_db = 1; - } - /* Zero out everything except recovery and tally flags. */ - repflags = F_ISSET(rep, REP_F_NOARCHIVE | - REP_F_RECOVER_MASK | REP_F_TALLY); - FLD_SET(repflags, REP_F_CLIENT); - - rep->flags = repflags; - REP_SYSTEM_UNLOCK(dbenv); - - /* - * Abort any prepared transactions that were restored - * by recovery. We won't be able to create any txns of - * our own until they're resolved, but we can't resolve - * them ourselves; the master has to. If any get - * resolved as commits, we'll redo them when commit - * records come in. Aborts will simply be ignored. - */ - if ((ret = __rep_abort_prepared(dbenv)) != 0) - goto errlock; - - MUTEX_LOCK(dbenv, rep->mtx_clientdb); - ret = __rep_client_dbinit(dbenv, init_db, REP_DB); - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - if (ret != 0) - goto errlock; - REP_SYSTEM_LOCK(dbenv); - rep->start_th = 0; - if (role_chg) { - F_CLR(rep, REP_F_READY); - rep->in_recovery = 0; - } - REP_SYSTEM_UNLOCK(dbenv); - - /* - * If this client created a newly replicated environment, - * then announce the existence of this client. The master - * should respond with a message that will tell this client - * the current generation number and the current LSN. This - * will allow the client to either perform recovery or - * simply join in. - */ - if (announce) - (void)__rep_send_message(dbenv, - DB_EID_BROADCAST, REP_NEWCLIENT, NULL, dbt, 0, 0); - else - (void)__rep_send_message(dbenv, - DB_EID_BROADCAST, REP_ALIVE_REQ, NULL, NULL, 0, 0); - } - - if (0) { - /* - * We have separate labels for errors. If we're returning an - * error before we've set start_th, we use 'err'. If - * we are erroring while holding the region mutex, then we use - * 'errunlock' label. If we're erroring without holding the rep - * mutex we must use 'errlock'. - */ -errlock: REP_SYSTEM_LOCK(dbenv); -errunlock: rep->start_th = 0; - if (role_chg) { - F_CLR(rep, REP_F_READY); - rep->in_recovery = 0; - } -err: REP_SYSTEM_UNLOCK(dbenv); - } - return (ret); -} - -/* - * __rep_client_dbinit -- - * - * Initialize the LSN database on the client side. This is called from the - * client initialization code. The startup flag value indicates if - * this is the first thread/process starting up and therefore should create - * the LSN database. This routine must be called once by each process acting - * as a client. - * - * Assumes caller holds appropriate mutex. - * - * PUBLIC: int __rep_client_dbinit __P((DB_ENV *, int, repdb_t)); - */ -int -__rep_client_dbinit(dbenv, startup, which) - DB_ENV *dbenv; - int startup; - repdb_t which; -{ - DB_REP *db_rep; - DB *dbp, **rdbpp; - REP *rep; - int ret, t_ret; - u_int32_t flags; - const char *name; - - PANIC_CHECK(dbenv); - db_rep = dbenv->rep_handle; - rep = db_rep->region; - dbp = NULL; - -#define REPDBNAME "__db.rep.db" -#define REPPAGENAME "__db.reppg.db" - - if (which == REP_DB) { - name = REPDBNAME; - rdbpp = &db_rep->rep_db; - } else { - name = REPPAGENAME; - rdbpp = &rep->file_dbp; - } - /* Check if this has already been called on this environment. */ - if (*rdbpp != NULL) - return (0); - - if (startup) { - if ((ret = db_create(&dbp, dbenv, 0)) != 0) - goto err; - /* - * Ignore errors, because if the file doesn't exist, this - * is perfectly OK. - */ - (void)__db_remove(dbp, NULL, name, NULL, DB_FORCE); - } - - if ((ret = db_create(&dbp, dbenv, 0)) != 0) - goto err; - if (which == REP_DB && - (ret = __bam_set_bt_compare(dbp, __rep_bt_cmp)) != 0) - goto err; - - /* Allow writes to this database on a client. */ - F_SET(dbp, DB_AM_CL_WRITER); - - flags = DB_NO_AUTO_COMMIT | - (startup ? DB_CREATE : 0) | - (F_ISSET(dbenv, DB_ENV_THREAD) ? DB_THREAD : 0); - - if ((ret = __db_open(dbp, NULL, name, NULL, - (which == REP_DB ? DB_BTREE : DB_RECNO), - flags, 0, PGNO_BASE_MD)) != 0) - goto err; - - *rdbpp= dbp; - - if (0) { -err: if (dbp != NULL && - (t_ret = __db_close(dbp, NULL, DB_NOSYNC)) != 0 && ret == 0) - ret = t_ret; - *rdbpp = NULL; - } - - return (ret); -} - -/* - * __rep_bt_cmp -- - * - * Comparison function for the LSN table. We use the entire control - * structure as a key (for simplicity, so we don't have to merge the - * other fields in the control with the data field), but really only - * care about the LSNs. - */ -static int -__rep_bt_cmp(dbp, dbt1, dbt2) - DB *dbp; - const DBT *dbt1, *dbt2; -{ - DB_LSN lsn1, lsn2; - REP_CONTROL *rp1, *rp2; - - COMPQUIET(dbp, NULL); - - rp1 = dbt1->data; - rp2 = dbt2->data; - - (void)__ua_memcpy(&lsn1, &rp1->lsn, sizeof(DB_LSN)); - (void)__ua_memcpy(&lsn2, &rp2->lsn, sizeof(DB_LSN)); - - if (lsn1.file > lsn2.file) - return (1); - - if (lsn1.file < lsn2.file) - return (-1); - - if (lsn1.offset > lsn2.offset) - return (1); - - if (lsn1.offset < lsn2.offset) - return (-1); - - return (0); -} - -/* - * __rep_abort_prepared -- - * Abort any prepared transactions that recovery restored. - * - * This is used by clients that have just run recovery, since - * they cannot/should not call txn_recover and handle prepared transactions - * themselves. - */ -static int -__rep_abort_prepared(dbenv) - DB_ENV *dbenv; -{ -#define PREPLISTSIZE 50 - DB_PREPLIST prep[PREPLISTSIZE], *p; - DB_TXNMGR *mgr; - DB_TXNREGION *region; - int do_aborts, ret; - long count, i; - u_int32_t op; - - mgr = dbenv->tx_handle; - region = mgr->reginfo.primary; - - do_aborts = 0; - TXN_SYSTEM_LOCK(dbenv); - if (region->stat.st_nrestores != 0) - do_aborts = 1; - TXN_SYSTEM_UNLOCK(dbenv); - - if (do_aborts) { - op = DB_FIRST; - do { - if ((ret = __txn_recover(dbenv, - prep, PREPLISTSIZE, &count, op)) != 0) - return (ret); - for (i = 0; i < count; i++) { - p = &prep[i]; - if ((ret = __txn_abort(p->txn)) != 0) - return (ret); - } - op = DB_NEXT; - } while (count == PREPLISTSIZE); - } - - return (0); -} - -/* - * __rep_restore_prepared -- - * Restore to a prepared state any prepared but not yet committed - * transactions. - * - * This performs, in effect, a "mini-recovery"; it is called from - * __rep_start by newly upgraded masters. There may be transactions that an - * old master prepared but did not resolve, which we need to restore to an - * active state. - */ -static int -__rep_restore_prepared(dbenv) - DB_ENV *dbenv; -{ - DB_LOGC *logc; - DB_LSN ckp_lsn, lsn; - DB_TXNHEAD *txninfo; - DBT rec; - __txn_ckp_args *ckp_args; - __txn_regop_args *regop_args; - __txn_xa_regop_args *prep_args; - int ret, t_ret; - u_int32_t hi_txn, low_txn, rectype, status; - - txninfo = NULL; - ckp_args = NULL; - prep_args = NULL; - regop_args = NULL; - ZERO_LSN(ckp_lsn); - ZERO_LSN(lsn); - - if ((ret = __log_cursor(dbenv, &logc)) != 0) - return (ret); - - /* - * We need to consider the set of records between the most recent - * checkpoint LSN and the end of the log; any txn in that - * range, and only txns in that range, could still have been - * active, and thus prepared but not yet committed (PBNYC), - * when the old master died. - * - * Find the most recent checkpoint LSN, and get the record there. - * If there is no checkpoint in the log, start off by getting - * the very first record in the log instead. - */ - memset(&rec, 0, sizeof(DBT)); - if ((ret = __txn_getckp(dbenv, &lsn)) == 0) { - if ((ret = __log_c_get(logc, &lsn, &rec, DB_SET)) != 0) { - __db_err(dbenv, - "Checkpoint record at LSN [%lu][%lu] not found", - (u_long)lsn.file, (u_long)lsn.offset); - goto err; - } - - if ((ret = __txn_ckp_read(dbenv, rec.data, &ckp_args)) != 0) { - __db_err(dbenv, - "Invalid checkpoint record at [%lu][%lu]", - (u_long)lsn.file, (u_long)lsn.offset); - goto err; - } - - ckp_lsn = ckp_args->ckp_lsn; - __os_free(dbenv, ckp_args); - - if ((ret = __log_c_get(logc, &ckp_lsn, &rec, DB_SET)) != 0) { - __db_err(dbenv, - "Checkpoint LSN record [%lu][%lu] not found", - (u_long)ckp_lsn.file, (u_long)ckp_lsn.offset); - goto err; - } - } else if ((ret = __log_c_get(logc, &lsn, &rec, DB_FIRST)) != 0) { - if (ret == DB_NOTFOUND) { - /* An empty log means no PBNYC txns. */ - ret = 0; - goto done; - } - __db_err(dbenv, "Attempt to get first log record failed"); - goto err; - } - - /* - * We use the same txnlist infrastructure that recovery does; - * it demands an estimate of the high and low txnids for - * initialization. - * - * First, the low txnid. - */ - do { - /* txnid is after rectype, which is a u_int32. */ - memcpy(&low_txn, - (u_int8_t *)rec.data + sizeof(u_int32_t), sizeof(low_txn)); - if (low_txn != 0) - break; - } while ((ret = __log_c_get(logc, &lsn, &rec, DB_NEXT)) == 0); - - /* If there are no txns, there are no PBNYC txns. */ - if (ret == DB_NOTFOUND) { - ret = 0; - goto done; - } else if (ret != 0) - goto err; - - /* Now, the high txnid. */ - if ((ret = __log_c_get(logc, &lsn, &rec, DB_LAST)) != 0) { - /* - * Note that DB_NOTFOUND is unacceptable here because we - * had to have looked at some log record to get this far. - */ - __db_err(dbenv, "Final log record not found"); - goto err; - } - do { - /* txnid is after rectype, which is a u_int32. */ - memcpy(&hi_txn, - (u_int8_t *)rec.data + sizeof(u_int32_t), sizeof(hi_txn)); - if (hi_txn != 0) - break; - } while ((ret = __log_c_get(logc, &lsn, &rec, DB_PREV)) == 0); - if (ret == DB_NOTFOUND) { - ret = 0; - goto done; - } else if (ret != 0) - goto err; - - /* We have a high and low txnid. Initialise the txn list. */ - if ((ret = - __db_txnlist_init(dbenv, low_txn, hi_txn, NULL, &txninfo)) != 0) - goto err; - - /* - * Now, walk backward from the end of the log to ckp_lsn. Any - * prepares that we hit without first hitting a commit or - * abort belong to PBNYC txns, and we need to apply them and - * restore them to a prepared state. - * - * Note that we wind up applying transactions out of order. - * Since all PBNYC txns still held locks on the old master and - * were isolated, this should be safe. - */ - for (ret = __log_c_get(logc, &lsn, &rec, DB_LAST); - ret == 0 && log_compare(&lsn, &ckp_lsn) > 0; - ret = __log_c_get(logc, &lsn, &rec, DB_PREV)) { - memcpy(&rectype, rec.data, sizeof(rectype)); - switch (rectype) { - case DB___txn_regop: - /* - * It's a commit or abort--but we don't care - * which! Just add it to the list of txns - * that are resolved. - */ - if ((ret = __txn_regop_read(dbenv, rec.data, - ®op_args)) != 0) - goto err; - - ret = __db_txnlist_find(dbenv, - txninfo, regop_args->txnid->txnid, &status); - if (ret == DB_NOTFOUND) - ret = __db_txnlist_add(dbenv, txninfo, - regop_args->txnid->txnid, - regop_args->opcode, &lsn); - else if (ret != 0) - goto err; - __os_free(dbenv, regop_args); - break; - case DB___txn_xa_regop: - /* - * It's a prepare. If its not aborted and - * we haven't put the txn on our list yet, it - * hasn't been resolved, so apply and restore it. - */ - if ((ret = __txn_xa_regop_read(dbenv, rec.data, - &prep_args)) != 0) - goto err; - ret = __db_txnlist_find(dbenv, txninfo, - prep_args->txnid->txnid, &status); - if (ret == DB_NOTFOUND) { - if (prep_args->opcode == TXN_ABORT) - ret = __db_txnlist_add(dbenv, txninfo, - prep_args->txnid->txnid, - prep_args->opcode, &lsn); - else if ((ret = - __rep_process_txn(dbenv, &rec)) == 0) - ret = __txn_restore_txn(dbenv, - &lsn, prep_args); - } else if (ret != 0) - goto err; - __os_free(dbenv, prep_args); - break; - default: - continue; - } - } - - /* It's not an error to have hit the beginning of the log. */ - if (ret == DB_NOTFOUND) - ret = 0; - -done: -err: t_ret = __log_c_close(logc); - - if (txninfo != NULL) - __db_txnlist_end(dbenv, txninfo); - - return (ret == 0 ? t_ret : ret); -} - -/* - * PUBLIC: int __rep_get_limit __P((DB_ENV *, u_int32_t *, u_int32_t *)); - */ -int -__rep_get_limit(dbenv, gbytesp, bytesp) - DB_ENV *dbenv; - u_int32_t *gbytesp, *bytesp; -{ - DB_REP *db_rep; - REP *rep; - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, dbenv->rep_handle, "rep_get_limit", - DB_INIT_REP); - - if (!REP_ON(dbenv)) { - __db_err(dbenv, - "DB_ENV->get_rep_limit: database environment not properly initialized"); - return (__db_panic(dbenv, EINVAL)); - } - db_rep = dbenv->rep_handle; - rep = db_rep->region; - - if (gbytesp != NULL) - *gbytesp = rep->gbytes; - if (bytesp != NULL) - *bytesp = rep->bytes; - - return (0); -} - -/* - * __rep_set_limit -- - * Set a limit on the amount of data that will be sent during a single - * invocation of __rep_process_message. - * - * PUBLIC: int __rep_set_limit __P((DB_ENV *, u_int32_t, u_int32_t)); - */ -int -__rep_set_limit(dbenv, gbytes, bytes) - DB_ENV *dbenv; - u_int32_t gbytes, bytes; -{ - DB_REP *db_rep; - REP *rep; - - PANIC_CHECK(dbenv); - ENV_ILLEGAL_BEFORE_OPEN(dbenv, "DB_ENV->rep_set_limit"); - ENV_REQUIRES_CONFIG(dbenv, dbenv->rep_handle, "rep_set_limit", - DB_INIT_REP); - - if (!REP_ON(dbenv)) { - __db_err(dbenv, - "DB_ENV->set_rep_limit: database environment not properly initialized"); - return (__db_panic(dbenv, EINVAL)); - } - db_rep = dbenv->rep_handle; - rep = db_rep->region; - REP_SYSTEM_LOCK(dbenv); - if (bytes > GIGABYTE) { - gbytes += bytes / GIGABYTE; - bytes = bytes % GIGABYTE; - } - rep->gbytes = gbytes; - rep->bytes = bytes; - REP_SYSTEM_UNLOCK(dbenv); - - return (0); -} - -/* - * __rep_set_request -- - * Set the minimum and maximum number of log records that we wait - * before retransmitting. - * - * !!! - * UNDOCUMENTED. - * - * PUBLIC: int __rep_set_request __P((DB_ENV *, u_int32_t, u_int32_t)); - */ -int -__rep_set_request(dbenv, min, max) - DB_ENV *dbenv; - u_int32_t min, max; -{ - LOG *lp; - DB_LOG *dblp; - DB_REP *db_rep; - REP *rep; - - PANIC_CHECK(dbenv); - ENV_ILLEGAL_BEFORE_OPEN(dbenv, "DB_ENV->rep_set_request"); - ENV_REQUIRES_CONFIG(dbenv, dbenv->rep_handle, "rep_set_request", - DB_INIT_REP); - - if (!REP_ON(dbenv)) { - __db_err(dbenv, - "DB_ENV->set_rep_request: database environment not properly initialized"); - return (__db_panic(dbenv, EINVAL)); - } - db_rep = dbenv->rep_handle; - rep = db_rep->region; - - /* - * We acquire the mtx_region or mtx_clientdb mutexes as needed. - */ - REP_SYSTEM_LOCK(dbenv); - rep->request_gap = min; - rep->max_gap = max; - REP_SYSTEM_UNLOCK(dbenv); - - MUTEX_LOCK(dbenv, rep->mtx_clientdb); - dblp = dbenv->lg_handle; - if (dblp != NULL && (lp = dblp->reginfo.primary) != NULL) { - lp->wait_recs = 0; - lp->rcvd_recs = 0; - } - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - - return (0); -} - -/* - * __rep_set_transport -- - * Set the transport function for replication. - * - * PUBLIC: int __rep_set_rep_transport __P((DB_ENV *, int, - * PUBLIC: int (*)(DB_ENV *, const DBT *, const DBT *, const DB_LSN *, - * PUBLIC: int, u_int32_t))); - */ -int -__rep_set_rep_transport(dbenv, eid, f_send) - DB_ENV *dbenv; - int eid; - int (*f_send) __P((DB_ENV *, const DBT *, const DBT *, const DB_LSN *, - int, u_int32_t)); -{ - PANIC_CHECK(dbenv); - - if (f_send == NULL) { - __db_err(dbenv, - "DB_ENV->set_rep_transport: no send function specified"); - return (EINVAL); - } - if (eid < 0) { - __db_err(dbenv, - "DB_ENV->set_rep_transport: eid must be greater than or equal to 0"); - return (EINVAL); - } - dbenv->rep_send = f_send; - dbenv->rep_eid = eid; - return (0); -} - -/* - * __rep_flush -- - * Re-push the last log record to all clients, in case they've lost - * messages and don't know it. - * - * PUBLIC: int __rep_flush __P((DB_ENV *)); - */ -int -__rep_flush(dbenv) - DB_ENV *dbenv; -{ - DBT rec; - DB_LOGC *logc; - DB_LSN lsn; - int ret, t_ret; - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, dbenv->rep_handle, "rep_flush", DB_INIT_REP); - - if ((ret = __log_cursor(dbenv, &logc)) != 0) - return (ret); - - memset(&rec, 0, sizeof(rec)); - memset(&lsn, 0, sizeof(lsn)); - - if ((ret = __log_c_get(logc, &lsn, &rec, DB_LAST)) != 0) - goto err; - - (void)__rep_send_message(dbenv, - DB_EID_BROADCAST, REP_LOG, &lsn, &rec, 0, 0); - -err: if ((t_ret = __log_c_close(logc)) != 0 && ret == 0) - ret = t_ret; - return (ret); -} - -/* - * __rep_sync -- - * Force a synchronization to occur between this client and the master. - * This is the other half of configuring DELAYCLIENT. - * - * PUBLIC: int __rep_sync __P((DB_ENV *, u_int32_t)); - */ -int -__rep_sync(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - DB_LOG *dblp; - DB_LSN lsn; - DB_REP *db_rep; - LOG *lp; - REP *rep; - int master; - u_int32_t type; - - COMPQUIET(flags, 0); - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, dbenv->rep_handle, - "rep_sync", DB_INIT_REP); - - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - db_rep = dbenv->rep_handle; - rep = db_rep->region; - - /* - * Simple cases. If we're not in the DELAY state we have nothing - * to do. If we don't know who the master is, send a MASTER_REQ. - */ - MUTEX_LOCK(dbenv, rep->mtx_clientdb); - lsn = lp->verify_lsn; - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - REP_SYSTEM_LOCK(dbenv); - master = rep->master_id; - if (master == DB_EID_INVALID) { - REP_SYSTEM_UNLOCK(dbenv); - (void)__rep_send_message(dbenv, DB_EID_BROADCAST, - REP_MASTER_REQ, NULL, NULL, 0, 0); - return (0); - } - /* - * We want to hold the rep mutex to test and then clear the - * DELAY flag. Racing threads in here could otherwise result - * in dual data streams. - */ - if (!F_ISSET(rep, REP_F_DELAY)) { - REP_SYSTEM_UNLOCK(dbenv); - return (0); - } - - /* - * If we get here, we clear the delay flag and kick off a - * synchronization. From this point forward, we will - * synchronize until the next time the master changes. - */ - F_CLR(rep, REP_F_DELAY); - REP_SYSTEM_UNLOCK(dbenv); - /* - * When we set REP_F_DELAY, we set verify_lsn to the real verify - * lsn if we need to verify, or we zeroed it out if this is a client - * that needs to sync up from the beginning. So, send the type - * of message now that __rep_new_master delayed sending. - */ - if (IS_ZERO_LSN(lsn)) - type = REP_ALL_REQ; - else - type = REP_VERIFY_REQ; - (void)__rep_send_message(dbenv, master, type, &lsn, NULL, 0, - DB_REP_ANYWHERE); - return (0); -} diff --git a/storage/bdb/rep/rep_record.c b/storage/bdb/rep/rep_record.c deleted file mode 100644 index 9944ba3eced..00000000000 --- a/storage/bdb/rep/rep_record.c +++ /dev/null @@ -1,1599 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2001-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: rep_record.c,v 12.25 2005/10/20 18:57:13 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#if TIME_WITH_SYS_TIME -#include <sys/time.h> -#include <time.h> -#else -#if HAVE_SYS_TIME_H -#include <sys/time.h> -#else -#include <time.h> -#endif -#endif - -#include <stdlib.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/db_am.h" -#include "dbinc/lock.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" -#include "dbinc/txn.h" - -static int __rep_collect_txn __P((DB_ENV *, DB_LSN *, LSN_COLLECTION *)); -static int __rep_do_ckp __P((DB_ENV *, DBT *, REP_CONTROL *)); -static int __rep_getnext __P((DB_ENV *)); -static int __rep_lsn_cmp __P((const void *, const void *)); -static int __rep_newfile __P((DB_ENV *, REP_CONTROL *, DB_LSN *)); -static int __rep_process_rec __P((DB_ENV *, - REP_CONTROL *, DBT *, u_int32_t *, DB_LSN *)); -static int __rep_remfirst __P((DB_ENV *, DBT *, DBT *)); -static int __rep_resend_req __P((DB_ENV *, int)); -static int __rep_skip_msg __P((DB_ENV *, REP *, int, u_int32_t)); - -/* Used to consistently designate which messages ought to be received where. */ - -#define MASTER_ONLY(rep, rp) do { \ - if (!F_ISSET(rep, REP_F_MASTER)) { \ - RPRINT(dbenv, rep, \ - (dbenv, &mb, "Master record received on client")); \ - REP_PRINT_MESSAGE(dbenv, \ - *eidp, rp, "rep_process_message"); \ - ret = EINVAL; \ - goto errlock; \ - } \ -} while (0) - -#define CLIENT_ONLY(rep, rp) do { \ - if (!F_ISSET(rep, REP_F_CLIENT)) { \ - RPRINT(dbenv, rep, \ - (dbenv, &mb, "Client record received on master")); \ - REP_PRINT_MESSAGE(dbenv, \ - *eidp, rp, "rep_process_message"); \ - (void)__rep_send_message(dbenv, \ - DB_EID_BROADCAST, REP_DUPMASTER, NULL, NULL, 0, 0); \ - ret = DB_REP_DUPMASTER; \ - goto errlock; \ - } \ -} while (0) - -/* - * If a client is attempting to service a request it does not have, - * call rep_skip_msg to skip this message and force a rerequest to the - * sender. We don't hold the mutex for the stats and may miscount. - */ -#define CLIENT_REREQ do { \ - if (F_ISSET(rep, REP_F_CLIENT)) { \ - rep->stat.st_client_svc_req++; \ - if (ret == DB_NOTFOUND) { \ - rep->stat.st_client_svc_miss++; \ - ret = __rep_skip_msg(dbenv, rep, *eidp, rp->rectype);\ - } \ - } \ -} while (0) - -#define MASTER_UPDATE(dbenv, renv) do { \ - REP_SYSTEM_LOCK(dbenv); \ - F_SET((renv), DB_REGENV_REPLOCKED); \ - (void)time(&(renv)->op_timestamp); \ - REP_SYSTEM_UNLOCK(dbenv); \ -} while (0) - -#define RECOVERING_SKIP do { \ - if (recovering) { \ - /* Not holding region mutex, may miscount */ \ - rep->stat.st_msgs_recover++; \ - ret = __rep_skip_msg(dbenv, rep, *eidp, rp->rectype); \ - goto errlock; \ - } \ -} while (0) - -/* - * If we're recovering the log we only want log records that are in the - * range we need to recover. Otherwise we can end up storing a huge - * number of "new" records, only to truncate the temp database later after - * we run recovery. If we are actively delaying a sync-up, we also skip - * all incoming log records until the application requests sync-up. - */ -#define RECOVERING_LOG_SKIP do { \ - if (F_ISSET(rep, REP_F_DELAY) || \ - (recovering && \ - (!F_ISSET(rep, REP_F_RECOVER_LOG) || \ - log_compare(&rp->lsn, &rep->last_lsn) > 0))) { \ - /* Not holding region mutex, may miscount */ \ - rep->stat.st_msgs_recover++; \ - ret = __rep_skip_msg(dbenv, rep, *eidp, rp->rectype); \ - goto errlock; \ - } \ -} while (0) - -#define ANYSITE(rep) - -/* - * __rep_process_message -- - * - * This routine takes an incoming message and processes it. - * - * control: contains the control fields from the record - * rec: contains the actual record - * eidp: contains the machine id of the sender of the message; - * in the case of a DB_NEWMASTER message, returns the eid - * of the new master. - * ret_lsnp: On DB_REP_ISPERM and DB_REP_NOTPERM returns, contains the - * lsn of the maximum permanent or current not permanent log record - * (respectively). - * - * PUBLIC: int __rep_process_message __P((DB_ENV *, DBT *, DBT *, int *, - * PUBLIC: DB_LSN *)); - */ -int -__rep_process_message(dbenv, control, rec, eidp, ret_lsnp) - DB_ENV *dbenv; - DBT *control, *rec; - int *eidp; - DB_LSN *ret_lsnp; -{ - DB_LOG *dblp; - DB_LSN lsn; - DB_REP *db_rep; - DBT data_dbt; - LOG *lp; - REGENV *renv; - REGINFO *infop; - REP *rep; - REP_CONTROL *rp; - u_int32_t egen, gen; - int cmp, recovering, ret; - time_t savetime; -#ifdef DIAGNOSTIC - DB_MSGBUF mb; -#endif - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, dbenv->rep_handle, "rep_process_message", - DB_INIT_REP); - - /* Control argument must be non-Null. */ - if (control == NULL || control->size == 0) { - __db_err(dbenv, - "DB_ENV->rep_process_message: control argument must be specified"); - return (EINVAL); - } - - if (!IS_REP_MASTER(dbenv) && !IS_REP_CLIENT(dbenv)) { - __db_err(dbenv, - "Environment not configured as replication master or client"); - return (EINVAL); - } - - ret = 0; - db_rep = dbenv->rep_handle; - rep = db_rep->region; - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - infop = dbenv->reginfo; - renv = infop->primary; - rp = (REP_CONTROL *)control->data; - if (ret_lsnp != NULL) - ZERO_LSN(*ret_lsnp); - - /* - * Acquire the replication lock. - */ - REP_SYSTEM_LOCK(dbenv); - if (rep->start_th != 0) { - /* - * If we're racing with a thread in rep_start, then - * just ignore the message and return. - */ - RPRINT(dbenv, rep, (dbenv, &mb, - "Racing rep_start, ignore message.")); - if (F_ISSET(rp, DB_LOG_PERM)) - ret = DB_REP_IGNORE; - REP_SYSTEM_UNLOCK(dbenv); - goto out; - } - rep->msg_th++; - gen = rep->gen; - recovering = rep->in_recovery || F_ISSET(rep, REP_F_RECOVER_MASK); - savetime = renv->rep_timestamp; - - rep->stat.st_msgs_processed++; - REP_SYSTEM_UNLOCK(dbenv); - - REP_PRINT_MESSAGE(dbenv, *eidp, rp, "rep_process_message"); - - /* Complain if we see an improper version number. */ - if (rp->rep_version != DB_REPVERSION) { - __db_err(dbenv, - "unexpected replication message version %lu, expected %d", - (u_long)rp->rep_version, DB_REPVERSION); - ret = EINVAL; - goto errlock; - } - if (rp->log_version != DB_LOGVERSION) { - __db_err(dbenv, - "unexpected log record version %lu, expected %d", - (u_long)rp->log_version, DB_LOGVERSION); - ret = EINVAL; - goto errlock; - } - - /* - * Check for generation number matching. Ignore any old messages - * except requests that are indicative of a new client that needs - * to get in sync. - */ - if (rp->gen < gen && rp->rectype != REP_ALIVE_REQ && - rp->rectype != REP_NEWCLIENT && rp->rectype != REP_MASTER_REQ && - rp->rectype != REP_DUPMASTER) { - /* - * We don't hold the rep mutex, and could miscount if we race. - */ - rep->stat.st_msgs_badgen++; - if (F_ISSET(rp, DB_LOG_PERM)) - ret = DB_REP_IGNORE; - goto errlock; - } - - if (rp->gen > gen) { - /* - * If I am a master and am out of date with a lower generation - * number, I am in bad shape and should downgrade. - */ - if (F_ISSET(rep, REP_F_MASTER)) { - rep->stat.st_dupmasters++; - ret = DB_REP_DUPMASTER; - if (rp->rectype != REP_DUPMASTER) - (void)__rep_send_message(dbenv, - DB_EID_BROADCAST, REP_DUPMASTER, - NULL, NULL, 0, 0); - goto errlock; - } - - /* - * I am a client and am out of date. If this is an election, - * or a response from the first site I contacted, then I can - * accept the generation number and participate in future - * elections and communication. Otherwise, I need to hear about - * a new master and sync up. - */ - if (rp->rectype == REP_ALIVE || - rp->rectype == REP_VOTE1 || rp->rectype == REP_VOTE2) { - REP_SYSTEM_LOCK(dbenv); - RPRINT(dbenv, rep, (dbenv, &mb, - "Updating gen from %lu to %lu", - (u_long)gen, (u_long)rp->gen)); - rep->master_id = DB_EID_INVALID; - gen = rep->gen = rp->gen; - /* - * Updating of egen will happen when we process the - * message below for each message type. - */ - REP_SYSTEM_UNLOCK(dbenv); - if (rp->rectype == REP_ALIVE) - (void)__rep_send_message(dbenv, - DB_EID_BROADCAST, REP_MASTER_REQ, NULL, - NULL, 0, 0); - } else if (rp->rectype != REP_NEWMASTER) { - /* - * Ignore this message, retransmit if needed. - */ - if (__rep_check_doreq(dbenv, rep)) - (void)__rep_send_message(dbenv, - DB_EID_BROADCAST, REP_MASTER_REQ, - NULL, NULL, 0, 0); - goto errlock; - } - /* - * If you get here, then you're a client and either you're - * in an election or you have a NEWMASTER or an ALIVE message - * whose processing will do the right thing below. - */ - } - - /* - * We need to check if we're in recovery and if we are - * then we need to ignore any messages except VERIFY*, VOTE*, - * NEW* and ALIVE_REQ, or backup related messages: UPDATE*, - * PAGE* and FILE*. We need to also accept LOG messages - * if we're copying the log for recovery/backup. - */ - switch (rp->rectype) { - case REP_ALIVE: - /* - * Handle even if we're recovering. - */ - ANYSITE(rep); - egen = *(u_int32_t *)rec->data; - REP_SYSTEM_LOCK(dbenv); - RPRINT(dbenv, rep, (dbenv, &mb, - "Received ALIVE egen of %lu, mine %lu", - (u_long)egen, (u_long)rep->egen)); - if (egen > rep->egen) { - /* - * We're changing egen, need to clear out any old - * election information. - */ - __rep_elect_done(dbenv, rep); - rep->egen = egen; - } - REP_SYSTEM_UNLOCK(dbenv); - break; - case REP_ALIVE_REQ: - /* - * Handle even if we're recovering. - */ - ANYSITE(rep); - dblp = dbenv->lg_handle; - LOG_SYSTEM_LOCK(dbenv); - lsn = ((LOG *)dblp->reginfo.primary)->lsn; - LOG_SYSTEM_UNLOCK(dbenv); - REP_SYSTEM_LOCK(dbenv); - egen = rep->egen; - REP_SYSTEM_UNLOCK(dbenv); - data_dbt.data = &egen; - data_dbt.size = sizeof(egen); - (void)__rep_send_message(dbenv, - *eidp, REP_ALIVE, &lsn, &data_dbt, 0, 0); - break; - case REP_ALL_REQ: - RECOVERING_SKIP; - ret = __rep_allreq(dbenv, rp, *eidp); - CLIENT_REREQ; - break; - case REP_BULK_LOG: - RECOVERING_LOG_SKIP; - CLIENT_ONLY(rep, rp); - ret = __rep_bulk_log(dbenv, rp, rec, savetime, ret_lsnp); - break; - case REP_BULK_PAGE: - /* - * Handle even if we're recovering. - */ - CLIENT_ONLY(rep, rp); - ret = __rep_bulk_page(dbenv, *eidp, rp, rec); - break; - case REP_DUPMASTER: - /* - * Handle even if we're recovering. - */ - if (F_ISSET(rep, REP_F_MASTER)) - ret = DB_REP_DUPMASTER; - break; -#ifdef NOTYET - case REP_FILE: /* TODO */ - CLIENT_ONLY(rep, rp); - break; - case REP_FILE_REQ: - ret = __rep_send_file(dbenv, rec, *eidp); - break; -#endif - case REP_FILE_FAIL: - /* - * Handle even if we're recovering. - */ - CLIENT_ONLY(rep, rp); - /* - * XXX - */ - break; - case REP_LOG: - case REP_LOG_MORE: - RECOVERING_LOG_SKIP; - CLIENT_ONLY(rep, rp); - ret = __rep_log(dbenv, rp, rec, savetime, ret_lsnp); - break; - case REP_LOG_REQ: - RECOVERING_SKIP; - ret = __rep_logreq(dbenv, rp, rec, *eidp); - CLIENT_REREQ; - break; - case REP_NEWSITE: - /* - * Handle even if we're recovering. - */ - /* We don't hold the rep mutex, and may miscount. */ - rep->stat.st_newsites++; - - /* This is a rebroadcast; simply tell the application. */ - if (F_ISSET(rep, REP_F_MASTER)) { - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - LOG_SYSTEM_LOCK(dbenv); - lsn = lp->lsn; - LOG_SYSTEM_UNLOCK(dbenv); - (void)__rep_send_message(dbenv, - *eidp, REP_NEWMASTER, &lsn, NULL, 0, 0); - } - ret = DB_REP_NEWSITE; - break; - case REP_NEWCLIENT: - /* - * Handle even if we're recovering. - */ - /* - * This message was received and should have resulted in the - * application entering the machine ID in its machine table. - * We respond to this with an ALIVE to send relevant information - * to the new client (if we are a master, we'll send a - * NEWMASTER, so we only need to send the ALIVE if we're a - * client). But first, broadcast the new client's record to - * all the clients. - */ - (void)__rep_send_message(dbenv, - DB_EID_BROADCAST, REP_NEWSITE, &rp->lsn, rec, 0, 0); - - ret = DB_REP_NEWSITE; - - if (F_ISSET(rep, REP_F_CLIENT)) { - REP_SYSTEM_LOCK(dbenv); - egen = rep->egen; - if (*eidp == rep->master_id) - rep->master_id = DB_EID_INVALID; - REP_SYSTEM_UNLOCK(dbenv); - data_dbt.data = &egen; - data_dbt.size = sizeof(egen); - (void)__rep_send_message(dbenv, DB_EID_BROADCAST, - REP_ALIVE, &rp->lsn, &data_dbt, 0, 0); - break; - } - /* FALLTHROUGH */ - case REP_MASTER_REQ: - RECOVERING_SKIP; - if (F_ISSET(rep, REP_F_MASTER)) { - LOG_SYSTEM_LOCK(dbenv); - lsn = lp->lsn; - LOG_SYSTEM_UNLOCK(dbenv); - (void)__rep_send_message(dbenv, - DB_EID_BROADCAST, REP_NEWMASTER, &lsn, NULL, 0, 0); - } - /* - * If there is no master, then we could get into a state - * where an old client lost the initial ALIVE message and - * is calling an election under an old gen and can - * never get to the current gen. - */ - if (F_ISSET(rep, REP_F_CLIENT) && rp->gen < gen) { - REP_SYSTEM_LOCK(dbenv); - egen = rep->egen; - if (*eidp == rep->master_id) - rep->master_id = DB_EID_INVALID; - REP_SYSTEM_UNLOCK(dbenv); - data_dbt.data = &egen; - data_dbt.size = sizeof(egen); - (void)__rep_send_message(dbenv, *eidp, - REP_ALIVE, &rp->lsn, &data_dbt, 0, 0); - } - break; - case REP_NEWFILE: - RECOVERING_LOG_SKIP; - CLIENT_ONLY(rep, rp); - ret = __rep_apply(dbenv, rp, rec, ret_lsnp, NULL); - break; - case REP_NEWMASTER: - /* - * Handle even if we're recovering. - */ - ANYSITE(rep); - if (F_ISSET(rep, REP_F_MASTER) && - *eidp != dbenv->rep_eid) { - /* We don't hold the rep mutex, and may miscount. */ - rep->stat.st_dupmasters++; - ret = DB_REP_DUPMASTER; - (void)__rep_send_message(dbenv, - DB_EID_BROADCAST, REP_DUPMASTER, NULL, NULL, 0, 0); - break; - } - ret = __rep_new_master(dbenv, rp, *eidp); - break; - case REP_PAGE: - case REP_PAGE_MORE: - /* - * Handle even if we're recovering. - */ - CLIENT_ONLY(rep, rp); - ret = __rep_page(dbenv, *eidp, rp, rec); - break; - case REP_PAGE_FAIL: - /* - * Handle even if we're recovering. - */ - CLIENT_ONLY(rep, rp); - ret = __rep_page_fail(dbenv, *eidp, rec); - break; - case REP_PAGE_REQ: - /* - * Handle even if we're recovering. - */ - MASTER_UPDATE(dbenv, renv); - ret = __rep_page_req(dbenv, *eidp, rec); - CLIENT_REREQ; - break; - case REP_REREQUEST: - /* - * Handle even if we're recovering. Don't do a master - * check. - */ - CLIENT_ONLY(rep, rp); - /* - * Don't hold any mutex, may miscount. - */ - rep->stat.st_client_rerequests++; - ret = __rep_resend_req(dbenv, 1); - break; - case REP_UPDATE: - /* - * Handle even if we're recovering. - */ - CLIENT_ONLY(rep, rp); - ret = __rep_update_setup(dbenv, *eidp, rp, rec); - break; - case REP_UPDATE_REQ: - /* - * Handle even if we're recovering. - */ - MASTER_ONLY(rep, rp); - infop = dbenv->reginfo; - renv = infop->primary; - MASTER_UPDATE(dbenv, renv); - ret = __rep_update_req(dbenv, *eidp); - break; - case REP_VERIFY: - if (recovering) { - MUTEX_LOCK(dbenv, rep->mtx_clientdb); - cmp = log_compare(&lp->verify_lsn, &rp->lsn); - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - /* - * If this is not the verify record I want, skip it. - */ - if (cmp != 0) { - ret = __rep_skip_msg( - dbenv, rep, *eidp, rp->rectype); - break; - } - } - CLIENT_ONLY(rep, rp); - ret = __rep_verify(dbenv, rp, rec, *eidp, savetime); - break; - case REP_VERIFY_FAIL: - /* - * Handle even if we're recovering. - */ - CLIENT_ONLY(rep, rp); - ret = __rep_verify_fail(dbenv, rp, *eidp); - break; - case REP_VERIFY_REQ: - RECOVERING_SKIP; - ret = __rep_verify_req(dbenv, rp, *eidp); - CLIENT_REREQ; - break; - case REP_VOTE1: - /* - * Handle even if we're recovering. - */ - ret = __rep_vote1(dbenv, rp, rec, *eidp); - break; - case REP_VOTE2: - /* - * Handle even if we're recovering. - */ - ret = __rep_vote2(dbenv, rec, eidp); - break; - default: - __db_err(dbenv, - "DB_ENV->rep_process_message: unknown replication message: type %lu", - (u_long)rp->rectype); - ret = EINVAL; - break; - } - -errlock: - REP_SYSTEM_LOCK(dbenv); - rep->msg_th--; - REP_SYSTEM_UNLOCK(dbenv); -out: - if (ret == 0 && F_ISSET(rp, DB_LOG_PERM)) { - if (ret_lsnp != NULL) - *ret_lsnp = rp->lsn; - ret = DB_REP_NOTPERM; - } - return (ret); -} - -/* - * __rep_apply -- - * - * Handle incoming log records on a client, applying when possible and - * entering into the bookkeeping table otherwise. This routine manages - * the state of the incoming message stream -- processing records, via - * __rep_process_rec, when possible and enqueuing in the __db.rep.db - * when necessary. As gaps in the stream are filled in, this is where - * we try to process as much as possible from __db.rep.db to catch up. - * - * PUBLIC: int __rep_apply __P((DB_ENV *, REP_CONTROL *, - * PUBLIC: DBT *, DB_LSN *, int *)); - */ -int -__rep_apply(dbenv, rp, rec, ret_lsnp, is_dupp) - DB_ENV *dbenv; - REP_CONTROL *rp; - DBT *rec; - DB_LSN *ret_lsnp; - int *is_dupp; -{ - DB_REP *db_rep; - DBT control_dbt, key_dbt; - DBT rec_dbt; - DB *dbp; - DB_LOG *dblp; - DB_LSN max_lsn; - LOG *lp; - REP *rep; - u_int32_t rectype; - int cmp, ret; -#ifdef DIAGNOSTIC - DB_MSGBUF mb; -#endif - - db_rep = dbenv->rep_handle; - rep = db_rep->region; - dbp = db_rep->rep_db; - rectype = 0; - ret = 0; - memset(&control_dbt, 0, sizeof(control_dbt)); - memset(&rec_dbt, 0, sizeof(rec_dbt)); - ZERO_LSN(max_lsn); - - dblp = dbenv->lg_handle; - MUTEX_LOCK(dbenv, rep->mtx_clientdb); - lp = dblp->reginfo.primary; - REP_SYSTEM_LOCK(dbenv); - if (F_ISSET(rep, REP_F_RECOVER_LOG) && - log_compare(&lp->ready_lsn, &rep->first_lsn) < 0) - lp->ready_lsn = rep->first_lsn; - REP_SYSTEM_UNLOCK(dbenv); - cmp = log_compare(&rp->lsn, &lp->ready_lsn); - - if (cmp == 0) { - if ((ret = - __rep_process_rec(dbenv, rp, rec, &rectype, &max_lsn)) != 0) - goto err; - /* - * If we get the record we are expecting, reset - * the count of records we've received and are applying - * towards the request interval. - */ - lp->rcvd_recs = 0; - ZERO_LSN(lp->max_wait_lsn); - - while (ret == 0 && - log_compare(&lp->ready_lsn, &lp->waiting_lsn) == 0) { - /* - * We just filled in a gap in the log record stream. - * Write subsequent records to the log. - */ -gap_check: - if ((ret = - __rep_remfirst(dbenv, &control_dbt, &rec_dbt)) != 0) - goto err; - - rp = (REP_CONTROL *)control_dbt.data; - rec = &rec_dbt; - if ((ret = __rep_process_rec(dbenv, - rp, rec, &rectype, &max_lsn)) != 0) - goto err; - - /* - * We may miscount, as we don't hold the rep mutex. - */ - --rep->stat.st_log_queued; - - /* - * Since we just filled a gap in the log stream, and - * we're writing subsequent records to the log, we want - * to use rcvd_recs and wait_recs so that we will - * request the next gap if we end up with a gap and - * a lot of records still in the temp db, but not - * request if it is near the end of the temp db and - * likely to arrive on its own shortly. We want to - * avoid requesting the record in that case. Also - * reset max_wait_lsn because the next gap is a - * fresh gap. - */ - lp->rcvd_recs = rep->stat.st_log_queued; - lp->wait_recs = rep->request_gap; - - if ((ret = __rep_getnext(dbenv)) == DB_NOTFOUND) { - lp->rcvd_recs = 0; - ret = 0; - break; - } else if (ret != 0) - goto err; - } - - /* - * Check if we're at a gap in the table and if so, whether we - * need to ask for any records. - */ - if (!IS_ZERO_LSN(lp->waiting_lsn) && - log_compare(&lp->ready_lsn, &lp->waiting_lsn) != 0) { - /* - * We got a record and processed it, but we may - * still be waiting for more records. If we - * filled a gap we keep a count of how many other - * records are in the temp database and if we should - * request the next gap at this time. - */ - if (__rep_check_doreq(dbenv, rep) && (ret = - __rep_loggap_req(dbenv, rep, &rp->lsn, 0)) != 0) - goto err; - } else { - lp->wait_recs = 0; - ZERO_LSN(lp->max_wait_lsn); - } - - } else if (cmp > 0) { - /* - * The LSN is higher than the one we were waiting for. - * This record isn't in sequence; add it to the temporary - * database, update waiting_lsn if necessary, and perform - * calculations to determine if we should issue requests - * for new records. - */ - memset(&key_dbt, 0, sizeof(key_dbt)); - key_dbt.data = rp; - key_dbt.size = sizeof(*rp); - if (lp->wait_recs == 0) { - /* - * This is a new gap. Initialize the number of - * records that we should wait before requesting - * that it be resent. We grab the limits out of - * the rep without the mutex. - */ - lp->wait_recs = rep->request_gap; - lp->rcvd_recs = 0; - ZERO_LSN(lp->max_wait_lsn); - } - if (__rep_check_doreq(dbenv, rep) && - (ret = __rep_loggap_req(dbenv, rep, &rp->lsn, 0) != 0)) - goto err; - - ret = __db_put(dbp, NULL, &key_dbt, rec, DB_NOOVERWRITE); - rep->stat.st_log_queued++; - rep->stat.st_log_queued_total++; - if (rep->stat.st_log_queued_max < rep->stat.st_log_queued) - rep->stat.st_log_queued_max = rep->stat.st_log_queued; - - if (ret == DB_KEYEXIST) - ret = 0; - if (ret != 0) - goto done; - - if (IS_ZERO_LSN(lp->waiting_lsn) || - log_compare(&rp->lsn, &lp->waiting_lsn) < 0) - lp->waiting_lsn = rp->lsn; - - /* - * If this is permanent; let the caller know that we have - * not yet written it to disk, but we've accepted it. - */ - if (ret == 0 && F_ISSET(rp, DB_LOG_PERM)) { - max_lsn = rp->lsn; - ret = DB_REP_NOTPERM; - } - goto done; - } else { - /* - * We may miscount if we race, since we - * don't currently hold the rep mutex. - */ - rep->stat.st_log_duplicated++; - if (is_dupp != NULL) - *is_dupp = 1; - if (F_ISSET(rp, DB_LOG_PERM)) - max_lsn = lp->max_perm_lsn; - goto done; - } - - /* Check if we need to go back into the table. */ - if (ret == 0 && log_compare(&lp->ready_lsn, &lp->waiting_lsn) == 0) - goto gap_check; - -done: -err: /* Check if we need to go back into the table. */ - REP_SYSTEM_LOCK(dbenv); - if (ret == 0 && - F_ISSET(rep, REP_F_RECOVER_LOG) && - log_compare(&lp->ready_lsn, &rep->last_lsn) >= 0) { - rep->last_lsn = max_lsn; - ZERO_LSN(max_lsn); - ret = DB_REP_LOGREADY; - } - REP_SYSTEM_UNLOCK(dbenv); - - if (ret == 0 && !F_ISSET(rep, REP_F_RECOVER_LOG) && - !IS_ZERO_LSN(max_lsn)) { - if (ret_lsnp != NULL) - *ret_lsnp = max_lsn; - ret = DB_REP_ISPERM; - DB_ASSERT(log_compare(&max_lsn, &lp->max_perm_lsn) >= 0); - lp->max_perm_lsn = max_lsn; - } - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - - /* - * Startup is complete when we process our first live record. However, - * we want to return DB_REP_STARTUPDONE on the first record we can -- - * but other return values trump this one. We know we've processed at - * least one record when rectype is non-zero. - */ - if (ret == 0 && !F_ISSET(rp, DB_LOG_RESEND) && - rectype != 0 && rep->stat.st_startup_complete == 0) { - rep->stat.st_startup_complete = 1; - ret = DB_REP_STARTUPDONE; - } - if (ret == 0 && rp->rectype == REP_NEWFILE && lp->db_log_autoremove) - __log_autoremove(dbenv); - if (control_dbt.data != NULL) - __os_ufree(dbenv, control_dbt.data); - if (rec_dbt.data != NULL) - __os_ufree(dbenv, rec_dbt.data); - - if (ret == DB_REP_NOTPERM && !F_ISSET(rep, REP_F_RECOVER_LOG) && - !IS_ZERO_LSN(max_lsn) && ret_lsnp != NULL) - *ret_lsnp = max_lsn; - -#ifdef DIAGNOSTIC - if (ret == DB_REP_ISPERM) - RPRINT(dbenv, rep, (dbenv, &mb, "Returning ISPERM [%lu][%lu]", - (u_long)max_lsn.file, (u_long)max_lsn.offset)); - else if (ret == DB_REP_LOGREADY) - RPRINT(dbenv, rep, (dbenv, &mb, - "Returning LOGREADY up to [%lu][%lu]", - (u_long)rep->last_lsn.file, - (u_long)rep->last_lsn.offset)); - else if (ret == DB_REP_NOTPERM) - RPRINT(dbenv, rep, (dbenv, &mb, "Returning NOTPERM [%lu][%lu]", - (u_long)max_lsn.file, (u_long)max_lsn.offset)); - else if (ret == DB_REP_STARTUPDONE) - RPRINT(dbenv, rep, (dbenv, &mb, - "Returning STARTUPDONE [%lu][%lu]", - (u_long)rp->lsn.file, (u_long)rp->lsn.offset)); - else if (ret != 0) - RPRINT(dbenv, rep, (dbenv, &mb, "Returning %d [%lu][%lu]", ret, - (u_long)max_lsn.file, (u_long)max_lsn.offset)); -#endif - return (ret); -} - -/* - * __rep_process_txn -- - * - * This is the routine that actually gets a transaction ready for - * processing. - * - * PUBLIC: int __rep_process_txn __P((DB_ENV *, DBT *)); - */ -int -__rep_process_txn(dbenv, rec) - DB_ENV *dbenv; - DBT *rec; -{ - DBT data_dbt, *lock_dbt; - DB_LOCKREQ req, *lvp; - DB_LOGC *logc; - DB_LSN prev_lsn, *lsnp; - DB_REP *db_rep; - DB_TXNHEAD *txninfo; - LSN_COLLECTION lc; - REP *rep; - __txn_regop_args *txn_args; - __txn_xa_regop_args *prep_args; - u_int32_t lockid, rectype; - u_int i; - int ret, t_ret; - - db_rep = dbenv->rep_handle; - rep = db_rep->region; - logc = NULL; - txn_args = NULL; - prep_args = NULL; - txninfo = NULL; - - memset(&data_dbt, 0, sizeof(data_dbt)); - if (F_ISSET(dbenv, DB_ENV_THREAD)) - F_SET(&data_dbt, DB_DBT_REALLOC); - - /* - * There are two phases: First, we have to traverse backwards through - * the log records gathering the list of all LSNs in the transaction. - * Once we have this information, we can loop through and then apply it. - * - * We may be passed a prepare (if we're restoring a prepare on upgrade) - * instead of a commit (the common case). Check which it is and behave - * appropriately. - */ - memcpy(&rectype, rec->data, sizeof(rectype)); - memset(&lc, 0, sizeof(lc)); - if (rectype == DB___txn_regop) { - /* - * We're the end of a transaction. Make sure this is - * really a commit and not an abort! - */ - if ((ret = __txn_regop_read(dbenv, rec->data, &txn_args)) != 0) - return (ret); - if (txn_args->opcode != TXN_COMMIT) { - __os_free(dbenv, txn_args); - return (0); - } - prev_lsn = txn_args->prev_lsn; - lock_dbt = &txn_args->locks; - } else { - /* We're a prepare. */ - DB_ASSERT(rectype == DB___txn_xa_regop); - - if ((ret = - __txn_xa_regop_read(dbenv, rec->data, &prep_args)) != 0) - return (ret); - prev_lsn = prep_args->prev_lsn; - lock_dbt = &prep_args->locks; - } - - /* Get locks. */ - if ((ret = __lock_id(dbenv, &lockid, NULL)) != 0) - goto err1; - - if ((ret = - __lock_get_list(dbenv, lockid, 0, DB_LOCK_WRITE, lock_dbt)) != 0) - goto err; - - /* Phase 1. Get a list of the LSNs in this transaction, and sort it. */ - if ((ret = __rep_collect_txn(dbenv, &prev_lsn, &lc)) != 0) - goto err; - qsort(lc.array, lc.nlsns, sizeof(DB_LSN), __rep_lsn_cmp); - - /* - * The set of records for a transaction may include dbreg_register - * records. Create a txnlist so that they can keep track of file - * state between records. - */ - if ((ret = __db_txnlist_init(dbenv, 0, 0, NULL, &txninfo)) != 0) - goto err; - - /* Phase 2: Apply updates. */ - if ((ret = __log_cursor(dbenv, &logc)) != 0) - goto err; - for (lsnp = &lc.array[0], i = 0; i < lc.nlsns; i++, lsnp++) { - if ((ret = __log_c_get(logc, lsnp, &data_dbt, DB_SET)) != 0) { - __db_err(dbenv, "failed to read the log at [%lu][%lu]", - (u_long)lsnp->file, (u_long)lsnp->offset); - goto err; - } - if ((ret = __db_dispatch(dbenv, dbenv->recover_dtab, - dbenv->recover_dtab_size, &data_dbt, lsnp, - DB_TXN_APPLY, txninfo)) != 0) { - __db_err(dbenv, "transaction failed at [%lu][%lu]", - (u_long)lsnp->file, (u_long)lsnp->offset); - goto err; - } - } - -err: memset(&req, 0, sizeof(req)); - req.op = DB_LOCK_PUT_ALL; - if ((t_ret = - __lock_vec(dbenv, lockid, 0, &req, 1, &lvp)) != 0 && ret == 0) - ret = t_ret; - - if ((t_ret = __lock_id_free(dbenv, lockid)) != 0 && ret == 0) - ret = t_ret; - -err1: if (txn_args != NULL) - __os_free(dbenv, txn_args); - if (prep_args != NULL) - __os_free(dbenv, prep_args); - if (lc.array != NULL) - __os_free(dbenv, lc.array); - - if (logc != NULL && (t_ret = __log_c_close(logc)) != 0 && ret == 0) - ret = t_ret; - - if (txninfo != NULL) - __db_txnlist_end(dbenv, txninfo); - - if (F_ISSET(&data_dbt, DB_DBT_REALLOC) && data_dbt.data != NULL) - __os_ufree(dbenv, data_dbt.data); - - if (ret == 0) - /* - * We don't hold the rep mutex, and could miscount if we race. - */ - rep->stat.st_txns_applied++; - - return (ret); -} - -/* - * __rep_collect_txn - * Recursive function that will let us visit every entry in a transaction - * chain including all child transactions so that we can then apply - * the entire transaction family at once. - */ -static int -__rep_collect_txn(dbenv, lsnp, lc) - DB_ENV *dbenv; - DB_LSN *lsnp; - LSN_COLLECTION *lc; -{ - __txn_child_args *argp; - DB_LOGC *logc; - DB_LSN c_lsn; - DBT data; - u_int32_t rectype; - u_int nalloc; - int ret, t_ret; - - memset(&data, 0, sizeof(data)); - F_SET(&data, DB_DBT_REALLOC); - - if ((ret = __log_cursor(dbenv, &logc)) != 0) - return (ret); - - while (!IS_ZERO_LSN(*lsnp) && - (ret = __log_c_get(logc, lsnp, &data, DB_SET)) == 0) { - memcpy(&rectype, data.data, sizeof(rectype)); - if (rectype == DB___txn_child) { - if ((ret = __txn_child_read(dbenv, - data.data, &argp)) != 0) - goto err; - c_lsn = argp->c_lsn; - *lsnp = argp->prev_lsn; - __os_free(dbenv, argp); - ret = __rep_collect_txn(dbenv, &c_lsn, lc); - } else { - if (lc->nalloc < lc->nlsns + 1) { - nalloc = lc->nalloc == 0 ? 20 : lc->nalloc * 2; - if ((ret = __os_realloc(dbenv, - nalloc * sizeof(DB_LSN), &lc->array)) != 0) - goto err; - lc->nalloc = nalloc; - } - lc->array[lc->nlsns++] = *lsnp; - - /* - * Explicitly copy the previous lsn. The record - * starts with a u_int32_t record type, a u_int32_t - * txn id, and then the DB_LSN (prev_lsn) that we - * want. We copy explicitly because we have no idea - * what kind of record this is. - */ - memcpy(lsnp, (u_int8_t *)data.data + - sizeof(u_int32_t) + sizeof(u_int32_t), - sizeof(DB_LSN)); - } - - if (ret != 0) - goto err; - } - if (ret != 0) - __db_err(dbenv, "collect failed at: [%lu][%lu]", - (u_long)lsnp->file, (u_long)lsnp->offset); - -err: if ((t_ret = __log_c_close(logc)) != 0 && ret == 0) - ret = t_ret; - if (data.data != NULL) - __os_ufree(dbenv, data.data); - return (ret); -} - -/* - * __rep_lsn_cmp -- - * qsort-type-compatible wrapper for log_compare. - */ -static int -__rep_lsn_cmp(lsn1, lsn2) - const void *lsn1, *lsn2; -{ - - return (log_compare((DB_LSN *)lsn1, (DB_LSN *)lsn2)); -} - -/* - * __rep_newfile -- - * NEWFILE messages have the LSN of the last record in the previous - * log file. When applying a NEWFILE message, make sure we haven't already - * swapped files. - */ -static int -__rep_newfile(dbenv, rc, lsnp) - DB_ENV *dbenv; - REP_CONTROL *rc; - DB_LSN *lsnp; -{ - DB_LOG *dblp; - LOG *lp; - - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - - if (rc->lsn.file + 1 > lp->lsn.file) - return (__log_newfile(dblp, lsnp, 0)); - else { - /* We've already applied this NEWFILE. Just ignore it. */ - *lsnp = lp->lsn; - return (0); - } -} - -/* - * __rep_do_ckp -- - * Perform the memp_sync necessary for this checkpoint without holding the - * REP->mtx_clientdb. Callers of this function must hold REP->mtx_clientdb - * and must not be holding the region mutex. - */ -static int -__rep_do_ckp(dbenv, rec, rp) - DB_ENV *dbenv; - DBT *rec; - REP_CONTROL *rp; -{ - DB_LSN ckp_lsn; - DB_REP *db_rep; - int ret; - - db_rep = dbenv->rep_handle; - - MUTEX_UNLOCK(dbenv, db_rep->region->mtx_clientdb); - - DB_TEST_WAIT(dbenv, dbenv->test_check); - - /* Sync the memory pool. */ - memcpy(&ckp_lsn, (u_int8_t *)rec->data + - SSZ(__txn_ckp_args, ckp_lsn), sizeof(DB_LSN)); - ret = __memp_sync(dbenv, &ckp_lsn); - - /* Update the last_ckp in the txn region. */ - if (ret == 0) - ret = __txn_updateckp(dbenv, &rp->lsn); - else { - __db_err(dbenv, "Error syncing ckp [%lu][%lu]", - (u_long)ckp_lsn.file, (u_long)ckp_lsn.offset); - ret = __db_panic(dbenv, ret); - } - MUTEX_LOCK(dbenv, db_rep->region->mtx_clientdb); - - return (ret); -} - -/* - * __rep_remfirst -- - * Remove the first entry from the __db.rep.db - */ -static int -__rep_remfirst(dbenv, cntrl, rec) - DB_ENV *dbenv; - DBT *cntrl; - DBT *rec; -{ - DB *dbp; - DBC *dbc; - DB_REP *db_rep; - int ret, t_ret; - - db_rep = dbenv->rep_handle; - dbp = db_rep->rep_db; - - if ((ret = __db_cursor(dbp, NULL, &dbc, 0)) != 0) - return (ret); - - /* The DBTs need to persist through another call. */ - F_SET(cntrl, DB_DBT_REALLOC); - F_SET(rec, DB_DBT_REALLOC); - if ((ret = __db_c_get(dbc, cntrl, rec, DB_RMW | DB_FIRST)) == 0) - ret = __db_c_del(dbc, 0); - if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __rep_getnext -- - * Get the next record out of the __db.rep.db table. - */ -static int -__rep_getnext(dbenv) - DB_ENV *dbenv; -{ - DB *dbp; - DB_REP *db_rep; - DB_LOG *dblp; - DBC *dbc; - DBT lsn_dbt, nextrec_dbt; - LOG *lp; - REP_CONTROL *rp; - int ret, t_ret; - - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - - db_rep = dbenv->rep_handle; - dbp = db_rep->rep_db; - - if ((ret = __db_cursor(dbp, NULL, &dbc, 0)) != 0) - return (ret); - - /* - * Update waiting_lsn. We need to move it - * forward to the LSN of the next record - * in the queue. - * - * If the next item in the database is a log - * record--the common case--we're not - * interested in its contents, just in its LSN. - * Optimize by doing a partial get of the data item. - */ - memset(&nextrec_dbt, 0, sizeof(nextrec_dbt)); - F_SET(&nextrec_dbt, DB_DBT_PARTIAL); - nextrec_dbt.ulen = nextrec_dbt.dlen = 0; - - memset(&lsn_dbt, 0, sizeof(lsn_dbt)); - ret = __db_c_get(dbc, &lsn_dbt, &nextrec_dbt, DB_FIRST); - if (ret != DB_NOTFOUND && ret != 0) - goto err; - - if (ret == DB_NOTFOUND) { - ZERO_LSN(lp->waiting_lsn); - /* - * Whether or not the current record is - * simple, there's no next one, and - * therefore we haven't got anything - * else to do right now. Break out. - */ - goto err; - } - rp = (REP_CONTROL *)lsn_dbt.data; - lp->waiting_lsn = rp->lsn; - -err: if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0) - ret = t_ret; - return (ret); -} - -/* - * __rep_process_rec -- - * - * Given a record in 'rp', process it. In the case of a NEWFILE, that means - * potentially switching files. In the case of a checkpoint, it means doing - * the checkpoint, and in other cases, it means simply writing the record into - * the log. - */ -static int -__rep_process_rec(dbenv, rp, rec, typep, ret_lsnp) - DB_ENV *dbenv; - REP_CONTROL *rp; - DBT *rec; - u_int32_t *typep; - DB_LSN *ret_lsnp; -{ - DB *dbp; - DB_LOG *dblp; - DB_REP *db_rep; - DBT control_dbt, key_dbt, rec_dbt; - LOG *lp; - REP *rep; - u_int32_t txnid; - int ret, t_ret; - - db_rep = dbenv->rep_handle; - rep = db_rep->region; - dbp = db_rep->rep_db; - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - ret = 0; - - if (rp->rectype == REP_NEWFILE) { - ret = __rep_newfile(dbenv, rp, &lp->ready_lsn); - - /* Make this evaluate to a simple rectype. */ - *typep = 0; - return (0); - } - - memcpy(typep, rec->data, sizeof(*typep)); - memset(&control_dbt, 0, sizeof(control_dbt)); - memset(&rec_dbt, 0, sizeof(rec_dbt)); - - /* - * We write all records except for checkpoint records here. - * All non-checkpoint records need to appear in the log before - * we take action upon them (i.e., we enforce write-ahead logging). - * However, we can't write the checkpoint record here until the - * data buffers are actually written to disk, else we are creating - * an invalid log -- one that says all data before a certain point - * has been written to disk. - * - * If two threads are both processing the same checkpoint record - * (because, for example, it was resent and the original finally - * arrived), we handle that below by checking for the existence of - * the log record when we add it to the replication database. - * - * Any log records that arrive while we are processing the checkpoint - * are added to the bookkeeping database because ready_lsn is not yet - * updated to point after the checkpoint record. - */ - if (*typep != DB___txn_ckp || F_ISSET(rep, REP_F_RECOVER_LOG)) { - if ((ret = __log_rep_put(dbenv, &rp->lsn, rec)) != 0) - return (ret); - rep->stat.st_log_records++; - if (F_ISSET(rep, REP_F_RECOVER_LOG)) { - *ret_lsnp = rp->lsn; - goto out; - } - } - - switch (*typep) { - case DB___dbreg_register: - /* - * DB opens occur in the context of a transaction, so we can - * simply handle them when we process the transaction. Closes, - * however, are not transaction-protected, so we have to - * handle them here. - * - * Note that it should be unsafe for the master to do a close - * of a file that was opened in an active transaction, so we - * should be guaranteed to get the ordering right. - */ - memcpy(&txnid, (u_int8_t *)rec->data + - SSZ(__dbreg_register_args, txnid), sizeof(u_int32_t)); - if (txnid == TXN_INVALID) - ret = __db_dispatch(dbenv, dbenv->recover_dtab, - dbenv->recover_dtab_size, rec, &rp->lsn, - DB_TXN_APPLY, NULL); - break; - case DB___txn_regop: - /* - * If an application is doing app-specific recovery - * and acquires locks while applying a transaction, - * it can deadlock. Any other locks held by this - * thread should have been discarded in the - * __rep_process_txn error path, so if we simply - * retry, we should eventually succeed. - */ - do { - ret = 0; - if (!F_ISSET(db_rep, DBREP_OPENFILES)) { - ret = __txn_openfiles(dbenv, NULL, 1); - F_SET(db_rep, DBREP_OPENFILES); - } - if (ret == 0) - ret = __rep_process_txn(dbenv, rec); - } while (ret == DB_LOCK_DEADLOCK); - - /* Now flush the log unless we're running TXN_NOSYNC. */ - if (ret == 0 && !F_ISSET(dbenv, DB_ENV_TXN_NOSYNC)) - ret = __log_flush(dbenv, NULL); - if (ret != 0) { - __db_err(dbenv, "Error processing txn [%lu][%lu]", - (u_long)rp->lsn.file, (u_long)rp->lsn.offset); - ret = __db_panic(dbenv, ret); - } - break; - case DB___txn_xa_regop: - ret = __log_flush(dbenv, NULL); - break; - case DB___txn_ckp: - /* - * We do not want to hold the REP->mtx_clientdb mutex while - * syncing the mpool, so if we get a checkpoint record we are - * supposed to process, add it to the __db.rep.db, do the - * memp_sync and then go back and process it later, when the - * sync has finished. If this record is already in the table, - * then some other thread will process it, so simply return - * REP_NOTPERM. - */ - memset(&key_dbt, 0, sizeof(key_dbt)); - key_dbt.data = rp; - key_dbt.size = sizeof(*rp); - - /* - * We want to put this record into the tmp DB only if - * it doesn't exist, so use DB_NOOVERWRITE. - */ - ret = __db_put(dbp, NULL, &key_dbt, rec, DB_NOOVERWRITE); - if (ret == DB_KEYEXIST) { - if (ret_lsnp != NULL) - *ret_lsnp = rp->lsn; - ret = DB_REP_NOTPERM; - } - if (ret != 0) - break; - - /* - * Now, do the checkpoint. Regardless of - * whether the checkpoint succeeds or not, - * we need to remove the record we just put - * in the temporary database. If the - * checkpoint failed, return an error. We - * will act like we never received the - * checkpoint. - */ - if ((ret = __rep_do_ckp(dbenv, rec, rp)) == 0) - ret = __log_rep_put(dbenv, &rp->lsn, rec); - if ((t_ret = __rep_remfirst(dbenv, - &control_dbt, &rec_dbt)) != 0 && ret == 0) - ret = t_ret; - break; - default: - break; - } - -out: - if (ret == 0 && F_ISSET(rp, DB_LOG_PERM)) - *ret_lsnp = rp->lsn; - if (control_dbt.data != NULL) - __os_ufree(dbenv, control_dbt.data); - if (rec_dbt.data != NULL) - __os_ufree(dbenv, rec_dbt.data); - - return (ret); -} - -/* - * __rep_resend_req -- - * We might have dropped a message, we need to resend our request. - * The request we send is dependent on what recovery state we're in. - * The caller holds no locks. - */ -static int -__rep_resend_req(dbenv, rereq) - DB_ENV *dbenv; - int rereq; -{ - - DB_LOG *dblp; - DB_LSN lsn; - DB_REP *db_rep; - LOG *lp; - REP *rep; - int ret; - u_int32_t gapflags, repflags; - - db_rep = dbenv->rep_handle; - rep = db_rep->region; - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - ret = 0; - - repflags = rep->flags; - /* - * If we are delayed we do not rerequest anything. - */ - if (FLD_ISSET(repflags, REP_F_DELAY)) - return (ret); - gapflags = rereq ? REP_GAP_REREQUEST : 0; - - if (FLD_ISSET(repflags, REP_F_RECOVER_VERIFY)) { - MUTEX_LOCK(dbenv, rep->mtx_clientdb); - lsn = lp->verify_lsn; - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - if (!IS_ZERO_LSN(lsn)) - (void)__rep_send_message(dbenv, rep->master_id, - REP_VERIFY_REQ, &lsn, NULL, 0, DB_REP_REREQUEST); - } else if (FLD_ISSET(repflags, REP_F_RECOVER_UPDATE)) { - /* - * UPDATE_REQ only goes to the master. - */ - (void)__rep_send_message(dbenv, rep->master_id, - REP_UPDATE_REQ, NULL, NULL, 0, 0); - } else if (FLD_ISSET(repflags, REP_F_RECOVER_PAGE)) { - REP_SYSTEM_LOCK(dbenv); - ret = __rep_pggap_req(dbenv, rep, NULL, gapflags); - REP_SYSTEM_UNLOCK(dbenv); - } else { - MUTEX_LOCK(dbenv, rep->mtx_clientdb); - ret = __rep_loggap_req(dbenv, rep, NULL, gapflags); - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - } - - return (ret); -} - -/* - * __rep_check_doreq -- - * PUBLIC: int __rep_check_doreq __P((DB_ENV *, REP *)); - * - * Check if we need to send another request. If so, compare with - * the request limits the user might have set. This assumes the - * caller holds the REP->mtx_clientdb mutex. Returns 1 if a request - * needs to be made, and 0 if it does not. - */ -int -__rep_check_doreq(dbenv, rep) - DB_ENV *dbenv; - REP *rep; -{ - - DB_LOG *dblp; - LOG *lp; - int req; - - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - req = ++lp->rcvd_recs >= lp->wait_recs; - if (req) { - lp->wait_recs *= 2; - if (lp->wait_recs > rep->max_gap) - lp->wait_recs = rep->max_gap; - lp->rcvd_recs = 0; - } - return (req); -} - -/* - * __rep_skip_msg - - * - * If we're in recovery we want to skip/ignore the message, but - * we also need to see if we need to re-request any retransmissions. - */ -static int -__rep_skip_msg(dbenv, rep, eid, rectype) - DB_ENV *dbenv; - REP *rep; - int eid; - u_int32_t rectype; -{ - int do_req, ret; - - ret = 0; - /* - * If we have a request message from a client then immediately - * send a REP_REREQUEST back to that client since we're skipping it. - */ - if (rep->master_id != DB_EID_INVALID && eid != rep->master_id) - do_req = 1; - else { - /* Check for need to retransmit. */ - MUTEX_LOCK(dbenv, rep->mtx_clientdb); - do_req = __rep_check_doreq(dbenv, rep); - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - } - /* - * Don't respond to a MASTER_REQ with - * a MASTER_REQ or REREQUEST. - */ - if (do_req && rectype != REP_MASTER_REQ) { - /* - * There are three cases: - * 1. If we don't know who the master is, then send MASTER_REQ. - * 2. If the message we're skipping came from the master, - * then we need to rerequest. - * 3. If the message didn't come from a master (i.e. client - * to client), then send a rerequest back to the sender so - * the sender can rerequest it elsewhere. - */ - if (rep->master_id == DB_EID_INVALID) /* Case 1. */ - (void)__rep_send_message(dbenv, - DB_EID_BROADCAST, REP_MASTER_REQ, NULL, NULL, 0, 0); - else if (eid == rep->master_id) /* Case 2. */ - ret = __rep_resend_req(dbenv, 0); - else /* Case 3. */ - (void)__rep_send_message(dbenv, - eid, REP_REREQUEST, NULL, NULL, 0, 0); - } - return (ret); -} diff --git a/storage/bdb/rep/rep_region.c b/storage/bdb/rep/rep_region.c deleted file mode 100644 index 000cf19330e..00000000000 --- a/storage/bdb/rep/rep_region.c +++ /dev/null @@ -1,300 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2001-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: rep_region.c,v 12.12 2005/10/19 19:10:40 sue Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#if TIME_WITH_SYS_TIME -#include <sys/time.h> -#include <time.h> -#else -#if HAVE_SYS_TIME_H -#include <sys/time.h> -#else -#include <time.h> -#endif -#endif - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_am.h" -#include "dbinc/log.h" - -static int __rep_egen_init __P((DB_ENV *, REP *)); - -/* - * __rep_region_init -- - * Initialize the shared memory state for the replication system. - * - * PUBLIC: int __rep_region_init __P((DB_ENV *)); - */ -int -__rep_region_init(dbenv) - DB_ENV *dbenv; -{ - REGENV *renv; - REGINFO *infop; - DB_REP *db_rep; - REP *rep; - int ret; - - db_rep = dbenv->rep_handle; - infop = dbenv->reginfo; - renv = infop->primary; - ret = 0; - - if (renv->rep_off == INVALID_ROFF) { - /* Must create the region. */ - if ((ret = __db_shalloc(infop, sizeof(REP), 0, &rep)) != 0) - return (ret); - memset(rep, 0, sizeof(*rep)); - rep->tally_off = INVALID_ROFF; - rep->v2tally_off = INVALID_ROFF; - renv->rep_off = R_OFFSET(infop, rep); - - if ((ret = __mutex_alloc( - dbenv, MTX_REP_REGION, 0, &rep->mtx_region)) != 0) - return (ret); - - /* - * Because we have no way to prevent deadlocks and cannot log - * changes made to it, we single-thread access to the client - * bookkeeping database. This is suboptimal, but it only gets - * accessed when messages arrive out-of-order, so it should - * stay small and not be used in a high-performance app. - */ - if ((ret = __mutex_alloc( - dbenv, MTX_REP_DATABASE, 0, &rep->mtx_clientdb)) != 0) - return (ret); - - /* We have the region; fill in the values. */ - rep->eid = DB_EID_INVALID; - rep->master_id = DB_EID_INVALID; - rep->gen = 0; - if ((ret = __rep_egen_init(dbenv, rep)) != 0) - return (ret); - /* - * Set default values for the min and max log records that we - * wait before requesting a missing log record. - */ - rep->request_gap = DB_REP_REQUEST_GAP; - rep->max_gap = DB_REP_MAX_GAP; - F_SET(rep, REP_F_NOARCHIVE); - (void)time(&renv->rep_timestamp); - renv->op_timestamp = 0; - F_CLR(renv, DB_REGENV_REPLOCKED); - } else - rep = R_ADDR(infop, renv->rep_off); - - db_rep->region = rep; - - return (0); -} - -/* - * __rep_region_destroy -- - * Destroy any system resources allocated in the replication region. - * - * PUBLIC: int __rep_region_destroy __P((DB_ENV *)); - */ -int -__rep_region_destroy(dbenv) - DB_ENV *dbenv; -{ - DB_REP *db_rep; - REGENV *renv; - REGINFO *infop; - int ret, t_ret; - - if (!REP_ON(dbenv)) - return (0); - - ret = 0; - - db_rep = dbenv->rep_handle; - if (db_rep->region != NULL) { - ret = __mutex_free(dbenv, &db_rep->region->mtx_region); - if ((t_ret = __mutex_free( - dbenv, &db_rep->region->mtx_clientdb)) != 0 && ret == 0) - ret = t_ret; - } - - infop = dbenv->reginfo; - renv = infop->primary; - if (renv->rep_off != INVALID_ROFF) - __db_shalloc_free(infop, R_ADDR(infop, renv->rep_off)); - - return (ret); -} - -/* - * __rep_dbenv_refresh -- - * Replication-specific refresh of the DB_ENV structure. - * - * PUBLIC: void __rep_dbenv_refresh __P((DB_ENV *)); - */ -void -__rep_dbenv_refresh(dbenv) - DB_ENV *dbenv; -{ - if (REP_ON(dbenv)) - ((DB_REP *)dbenv->rep_handle)->region = NULL; - return; -} - -/* - * __rep_dbenv_close -- - * Replication-specific destruction of the DB_ENV structure. - * - * PUBLIC: int __rep_dbenv_close __P((DB_ENV *)); - */ -int -__rep_dbenv_close(dbenv) - DB_ENV *dbenv; -{ - if (REP_ON(dbenv)) { - __os_free(dbenv, dbenv->rep_handle); - dbenv->rep_handle = NULL; - dbenv->rep_send = NULL; - } - - return (0); -} - -/* - * __rep_preclose -- - * If we are a client, shut down our client database and close - * all databases we've opened while applying messages as a client. - * - * PUBLIC: int __rep_preclose __P((DB_ENV *)); - */ -int -__rep_preclose(dbenv) - DB_ENV *dbenv; -{ - DB_LOG *dblp; - DB_REP *db_rep; - LOG *lp; - REP_BULK bulk; - int ret, t_ret; - - ret = 0; - - db_rep = dbenv->rep_handle; - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - - MUTEX_LOCK(dbenv, db_rep->region->mtx_clientdb); - if (db_rep->rep_db != NULL) { - ret = __db_close(db_rep->rep_db, NULL, DB_NOSYNC); - db_rep->rep_db = NULL; - } - - if ((t_ret = __dbreg_close_files(dbenv)) != 0 && ret == 0) - ret = t_ret; - F_CLR(db_rep, DBREP_OPENFILES); - /* - * If we have something in the bulk buffer, send anything in it - * if we are able to. - */ - if (lp->bulk_off != 0 && dbenv->rep_send != NULL) { - memset(&bulk, 0, sizeof(bulk)); - bulk.addr = R_ADDR(&dblp->reginfo, lp->bulk_buf); - bulk.offp = &lp->bulk_off; - bulk.len = lp->bulk_len; - bulk.type = REP_BULK_LOG; - bulk.eid = DB_EID_BROADCAST; - bulk.flagsp = &lp->bulk_flags; - if ((t_ret = __rep_send_bulk(dbenv, &bulk, 0)) != 0 && ret == 0) - ret = t_ret; - } - MUTEX_UNLOCK(dbenv, db_rep->region->mtx_clientdb); - return (ret); -} - -/* - * __rep_egen_init -- - * Initialize the value of egen in the region. Called only from - * __rep_region_init, which is guaranteed to be single-threaded - * as we create the rep region. We set the rep->egen field which - * is normally protected by db_rep->region->mutex. - */ -static int -__rep_egen_init(dbenv, rep) - DB_ENV *dbenv; - REP *rep; -{ - DB_FH *fhp; - int ret; - size_t cnt; - char *p; -#ifdef DIAGNOSTIC - DB_MSGBUF mb; -#endif - - if ((ret = - __db_appname(dbenv, DB_APP_NONE, REP_EGENNAME, 0, NULL, &p)) != 0) - return (ret); - /* - * If the file doesn't exist, create it now and initialize with 1. - */ - if (__os_exists(p, NULL) != 0) { - rep->egen = rep->gen + 1; - if ((ret = __rep_write_egen(dbenv, rep->egen)) != 0) - goto err; - } else { - /* - * File exists, open it and read in our egen. - */ - if ((ret = __os_open(dbenv, p, DB_OSO_RDONLY, - __db_omode(OWNER_RW), &fhp)) != 0) - goto err; - if ((ret = __os_read(dbenv, fhp, &rep->egen, sizeof(u_int32_t), - &cnt)) < 0 || cnt == 0) - goto err1; - RPRINT(dbenv, rep, (dbenv, &mb, "Read in egen %lu", - (u_long)rep->egen)); -err1: (void)__os_closehandle(dbenv, fhp); - } -err: __os_free(dbenv, p); - return (ret); -} - -/* - * __rep_write_egen -- - * Write out the egen into the env file. - * - * PUBLIC: int __rep_write_egen __P((DB_ENV *, u_int32_t)); - */ -int -__rep_write_egen(dbenv, egen) - DB_ENV *dbenv; - u_int32_t egen; -{ - DB_FH *fhp; - int ret; - size_t cnt; - char *p; - - if ((ret = - __db_appname(dbenv, DB_APP_NONE, REP_EGENNAME, 0, NULL, &p)) != 0) - return (ret); - if ((ret = __os_open(dbenv, p, DB_OSO_CREATE | DB_OSO_TRUNC, - __db_omode(OWNER_RW), &fhp)) == 0) { - if ((ret = __os_write(dbenv, fhp, &egen, sizeof(u_int32_t), - &cnt)) != 0 || ((ret = __os_fsync(dbenv, fhp)) != 0)) - __db_err(dbenv, "%s: %s", p, db_strerror(ret)); - (void)__os_closehandle(dbenv, fhp); - } - __os_free(dbenv, p); - return (ret); -} diff --git a/storage/bdb/rep/rep_stat.c b/storage/bdb/rep/rep_stat.c deleted file mode 100644 index 984e63938fa..00000000000 --- a/storage/bdb/rep/rep_stat.c +++ /dev/null @@ -1,521 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2001-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: rep_stat.c,v 12.6 2005/10/24 18:37:10 alanb Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#if TIME_WITH_SYS_TIME -#include <sys/time.h> -#include <time.h> -#else -#if HAVE_SYS_TIME_H -#include <sys/time.h> -#else -#include <time.h> -#endif -#endif - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_am.h" -#include "dbinc/log.h" - -#ifdef HAVE_STATISTICS -static int __rep_print_all __P((DB_ENV *, u_int32_t)); -static int __rep_print_stats __P((DB_ENV *, u_int32_t)); -static int __rep_stat __P((DB_ENV *, DB_REP_STAT **, u_int32_t)); - -/* - * __rep_stat_pp -- - * DB_ENV->rep_stat pre/post processing. - * - * PUBLIC: int __rep_stat_pp __P((DB_ENV *, DB_REP_STAT **, u_int32_t)); - */ -int -__rep_stat_pp(dbenv, statp, flags) - DB_ENV *dbenv; - DB_REP_STAT **statp; - u_int32_t flags; -{ - DB_THREAD_INFO *ip; - int ret; - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, - dbenv->rep_handle, "DB_ENV->rep_stat", DB_INIT_REP); - - if ((ret = __db_fchk(dbenv, - "DB_ENV->rep_stat", flags, DB_STAT_CLEAR)) != 0) - return (ret); - - ENV_ENTER(dbenv, ip); - ret = __rep_stat(dbenv, statp, flags); - ENV_LEAVE(dbenv, ip); - - return (ret); -} - -/* - * __rep_stat -- - * DB_ENV->rep_stat. - */ -static int -__rep_stat(dbenv, statp, flags) - DB_ENV *dbenv; - DB_REP_STAT **statp; - u_int32_t flags; -{ - DB_LOG *dblp; - DB_REP *db_rep; - DB_REP_STAT *stats; - LOG *lp; - REP *rep; - u_int32_t queued; - int dolock, ret; - - db_rep = dbenv->rep_handle; - rep = db_rep->region; - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - - *statp = NULL; - - /* Allocate a stat struct to return to the user. */ - if ((ret = __os_umalloc(dbenv, sizeof(DB_REP_STAT), &stats)) != 0) - return (ret); - - /* - * Read without holding the lock. If we are in client recovery, we - * copy just the stats struct so we won't block. We only copy out - * those stats that don't require acquiring any mutex. - */ - dolock = FLD_ISSET(rep->flags, REP_F_RECOVER_MASK) ? 0 : 1; - memcpy(stats, &rep->stat, sizeof(*stats)); - - /* Copy out election stats. */ - if (IN_ELECTION_TALLY(rep)) { - if (F_ISSET(rep, REP_F_EPHASE1)) - stats->st_election_status = 1; - else if (F_ISSET(rep, REP_F_EPHASE2)) - stats->st_election_status = 2; - - stats->st_election_nsites = rep->sites; - stats->st_election_cur_winner = rep->winner; - stats->st_election_priority = rep->w_priority; - stats->st_election_gen = rep->w_gen; - stats->st_election_lsn = rep->w_lsn; - stats->st_election_votes = rep->votes; - stats->st_election_nvotes = rep->nvotes; - stats->st_election_tiebreaker = rep->w_tiebreaker; - } - - /* Copy out other info that's protected by the rep mutex. */ - stats->st_env_id = rep->eid; - stats->st_env_priority = rep->priority; - stats->st_nsites = rep->nsites; - stats->st_master = rep->master_id; - stats->st_gen = rep->gen; - stats->st_egen = rep->egen; - - if (F_ISSET(rep, REP_F_MASTER)) - stats->st_status = DB_REP_MASTER; - else if (F_ISSET(rep, REP_F_CLIENT)) - stats->st_status = DB_REP_CLIENT; - else - stats->st_status = 0; - - if (LF_ISSET(DB_STAT_CLEAR)) { - queued = rep->stat.st_log_queued; - memset(&rep->stat, 0, sizeof(rep->stat)); - rep->stat.st_log_queued = rep->stat.st_log_queued_total = - rep->stat.st_log_queued_max = queued; - } - - /* - * Log-related replication info is stored in the log system and - * protected by the log region lock. - */ - if (dolock) - MUTEX_LOCK(dbenv, rep->mtx_clientdb); - if (F_ISSET(rep, REP_F_CLIENT)) { - stats->st_next_lsn = lp->ready_lsn; - stats->st_waiting_lsn = lp->waiting_lsn; - stats->st_next_pg = rep->ready_pg; - stats->st_waiting_pg = rep->waiting_pg; - } else { - if (F_ISSET(rep, REP_F_MASTER)) - stats->st_next_lsn = lp->lsn; - else - ZERO_LSN(stats->st_next_lsn); - ZERO_LSN(stats->st_waiting_lsn); - } - if (dolock) - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - - *statp = stats; - return (0); -} - -/* - * __rep_stat_print_pp -- - * DB_ENV->rep_stat_print pre/post processing. - * - * PUBLIC: int __rep_stat_print_pp __P((DB_ENV *, u_int32_t)); - */ -int -__rep_stat_print_pp(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - DB_THREAD_INFO *ip; - int ret; - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, - dbenv->rep_handle, "DB_ENV->rep_stat_print", DB_INIT_REP); - - if ((ret = __db_fchk(dbenv, "DB_ENV->rep_stat_print", - flags, DB_STAT_ALL | DB_STAT_CLEAR)) != 0) - return (ret); - - ENV_ENTER(dbenv, ip); - ret = __rep_stat_print(dbenv, flags); - ENV_LEAVE(dbenv, ip); - - return (ret); -} - -/* - * __rep_stat_print -- - * DB_ENV->rep_stat_print method. - * - * PUBLIC: int __rep_stat_print __P((DB_ENV *, u_int32_t)); - */ -int -__rep_stat_print(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - u_int32_t orig_flags; - int ret; - - orig_flags = flags; - LF_CLR(DB_STAT_CLEAR); - if (flags == 0 || LF_ISSET(DB_STAT_ALL)) { - ret = __rep_print_stats(dbenv, orig_flags); - if (flags == 0 || ret != 0) - return (ret); - } - - if (LF_ISSET(DB_STAT_ALL) && - (ret = __rep_print_all(dbenv, orig_flags)) != 0) - return (ret); - - return (0); -} - -/* - * __rep_print_stats -- - * Print out default statistics. - */ -static int -__rep_print_stats(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - DB_REP_STAT *sp; - int is_client, ret; - char *p; - - if ((ret = __rep_stat(dbenv, &sp, flags)) != 0) - return (ret); - - if (LF_ISSET(DB_STAT_ALL)) - __db_msg(dbenv, "Default replication region information:"); - is_client = 0; - switch (sp->st_status) { - case DB_REP_MASTER: - __db_msg(dbenv, - "Environment configured as a replication master"); - break; - case DB_REP_CLIENT: - __db_msg(dbenv, - "Environment configured as a replication client"); - is_client = 1; - break; - default: - __db_msg(dbenv, - "Environment not configured for replication"); - break; - } - - __db_msg(dbenv, "%lu/%lu\t%s", - (u_long)sp->st_next_lsn.file, (u_long)sp->st_next_lsn.offset, - is_client ? "Next LSN expected" : "Next LSN to be used"); - __db_msg(dbenv, "%lu/%lu\t%s", - (u_long)sp->st_waiting_lsn.file, (u_long)sp->st_waiting_lsn.offset, - sp->st_waiting_lsn.file == 0 ? - "Not waiting for any missed log records" : - "LSN of first log record we have after missed log records"); - - __db_dl(dbenv, "Next page number expected.", (u_long)sp->st_next_pg); - p = sp->st_waiting_pg == PGNO_INVALID ? - "Not waiting for any missed pages." : - "Page number of first page we have after missed pages."; - __db_msg(dbenv, "%lu\t%s", (u_long)sp->st_waiting_pg, p); - __db_dl(dbenv, "Number of duplicate master conditions detected.", - (u_long)sp->st_dupmasters); - if (sp->st_env_id != DB_EID_INVALID) - __db_dl(dbenv, "Current environment ID", (u_long)sp->st_env_id); - else - __db_msg(dbenv, "No current environment ID"); - __db_dl(dbenv, - "Current environment priority", (u_long)sp->st_env_priority); - __db_dl(dbenv, "Current generation number", (u_long)sp->st_gen); - __db_dl(dbenv, - "Current election generation number", (u_long)sp->st_egen); - __db_dl(dbenv, "Number of duplicate log records received", - (u_long)sp->st_log_duplicated); - __db_dl(dbenv, "Number of log records currently queued", - (u_long)sp->st_log_queued); - __db_dl(dbenv, "Maximum number of log records ever queued at once", - (u_long)sp->st_log_queued_max); - __db_dl(dbenv, "Total number of log records queued", - (u_long)sp->st_log_queued_total); - __db_dl(dbenv, - "Number of log records received and appended to the log", - (u_long)sp->st_log_records); - __db_dl(dbenv, "Number of log records missed and requested", - (u_long)sp->st_log_requested); - if (sp->st_master != DB_EID_INVALID) - __db_dl(dbenv, "Current master ID", (u_long)sp->st_master); - else - __db_msg(dbenv, "No current master ID"); - __db_dl(dbenv, "Number of times the master has changed", - (u_long)sp->st_master_changes); - __db_dl(dbenv, - "Number of messages received with a bad generation number", - (u_long)sp->st_msgs_badgen); - __db_dl(dbenv, "Number of messages received and processed", - (u_long)sp->st_msgs_processed); - __db_dl(dbenv, "Number of messages ignored due to pending recovery", - (u_long)sp->st_msgs_recover); - __db_dl(dbenv, "Number of failed message sends", - (u_long)sp->st_msgs_send_failures); - __db_dl(dbenv, "Number of messages sent", (u_long)sp->st_msgs_sent); - __db_dl(dbenv, - "Number of new site messages received", (u_long)sp->st_newsites); - __db_dl(dbenv, - "Number of environments believed to be in the replication group", - (u_long)sp->st_nsites); - __db_dl(dbenv, "Transmission limited", (u_long)sp->st_nthrottles); - __db_dl(dbenv, "Number of outdated conditions detected", - (u_long)sp->st_outdated); - __db_dl(dbenv, "Number of duplicate page records received", - (u_long)sp->st_pg_duplicated); - __db_dl(dbenv, "Number of page records received and added to databases", - (u_long)sp->st_pg_records); - __db_dl(dbenv, "Number of page records missed and requested", - (u_long)sp->st_pg_requested); - if (sp->st_startup_complete == 0) - __db_msg(dbenv, "Startup incomplete"); - else - __db_msg(dbenv, "Startup complete"); - __db_dl(dbenv, - "Number of transactions applied", (u_long)sp->st_txns_applied); - - __db_dl(dbenv, "Number of elections held", (u_long)sp->st_elections); - __db_dl(dbenv, - "Number of elections won", (u_long)sp->st_elections_won); - - if (sp->st_election_status == 0) { - __db_msg(dbenv, "No election in progress"); - if (sp->st_election_sec > 0 || sp->st_election_usec > 0) - __db_msg(dbenv, - "%lu.%.6lu\tDuration of last election (seconds)", - (u_long)sp->st_election_sec, - (u_long)sp->st_election_usec); - } else { - __db_dl(dbenv, "Current election phase", - (u_long)sp->st_election_status); - __db_dl(dbenv, "Election winner", - (u_long)sp->st_election_cur_winner); - __db_dl(dbenv, "Election generation number", - (u_long)sp->st_election_gen); - __db_msg(dbenv, "%lu/%lu\tMaximum LSN of election winner", - (u_long)sp->st_election_lsn.file, - (u_long)sp->st_election_lsn.offset); - __db_dl(dbenv, - "Number of sites expected to participate in elections", - (u_long)sp->st_election_nsites); - __db_dl(dbenv, "Number of votes needed to win an election", - (u_long)sp->st_election_nvotes); - __db_dl(dbenv, - "Election priority", (u_long)sp->st_election_priority); - __db_dl(dbenv, "Election tiebreaker value", - (u_long)sp->st_election_tiebreaker); - __db_dl(dbenv, "Votes received this election round", - (u_long)sp->st_election_votes); - } - __db_dl(dbenv, "Number of bulk buffer sends triggered by full buffer", - (u_long)sp->st_bulk_fills); - __db_dl(dbenv, "Number of single records exceeding bulk buffer size", - (u_long)sp->st_bulk_overflows); - __db_dl(dbenv, "Number of records added to a bulk buffer", - (u_long)sp->st_bulk_records); - __db_dl(dbenv, "Number of bulk buffers sent", - (u_long)sp->st_bulk_transfers); - __db_dl(dbenv, "Number of re-request messages received", - (u_long)sp->st_client_rerequests); - __db_dl(dbenv, - "Number of request messages this client failed to process", - (u_long)sp->st_client_svc_miss); - __db_dl(dbenv, "Number of request messages received by this client", - (u_long)sp->st_client_svc_req); - - __os_ufree(dbenv, sp); - - return (0); -} - -/* - * __rep_print_all -- - * Display debugging replication region statistics. - */ -static int -__rep_print_all(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - static const FN rep_fn[] = { - { REP_F_CLIENT, "REP_F_CLIENT" }, - { REP_F_EPHASE1, "REP_F_EPHASE1" }, - { REP_F_EPHASE2, "REP_F_EPHASE2" }, - { REP_F_MASTER, "REP_F_MASTER" }, - { REP_F_MASTERELECT, "REP_F_MASTERELECT" }, - { REP_F_NOARCHIVE, "REP_F_NOARCHIVE" }, - { REP_F_READY, "REP_F_READY" }, - { REP_F_RECOVER_LOG, "REP_F_RECOVER_LOG" }, - { REP_F_RECOVER_PAGE, "REP_F_RECOVER_PAGE" }, - { REP_F_RECOVER_UPDATE, "REP_F_RECOVER_UPDATE" }, - { REP_F_RECOVER_VERIFY, "REP_F_RECOVER_VERIFY" }, - { REP_F_TALLY, "REP_F_TALLY" }, - { 0, NULL } - }; - static const FN dbrep_fn[] = { - { DBREP_OPENFILES, "DBREP_OPENFILES" }, - { 0, NULL } - }; - DB_LOG *dblp; - DB_REP *db_rep; - LOG *lp; - REGENV *renv; - REGINFO *infop; - REP *rep; - - db_rep = dbenv->rep_handle; - rep = db_rep->region; - infop = dbenv->reginfo; - renv = infop->primary; - - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_msg(dbenv, "DB_REP handle information:"); - - if (db_rep->rep_db == NULL) - STAT_ISSET("Bookkeeping database", db_rep->rep_db); - else - (void)__db_stat_print(db_rep->rep_db, flags); - - __db_prflags(dbenv, NULL, db_rep->flags, dbrep_fn, NULL, "\tFlags"); - - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_msg(dbenv, "REP handle information:"); - __mutex_print_debug_single(dbenv, - "Replication region mutex", rep->mtx_region, flags); - __mutex_print_debug_single(dbenv, - "Bookkeeping database mutex", rep->mtx_clientdb, flags); - - STAT_LONG("Environment ID", rep->eid); - STAT_LONG("Master environment ID", rep->master_id); - STAT_ULONG("Election generation", rep->egen); - STAT_ULONG("Election generation number", rep->gen); - STAT_ULONG("Last generation number in log", rep->recover_gen); - STAT_LONG("Space allocated for sites", rep->asites); - STAT_LONG("Sites in group", rep->nsites); - STAT_LONG("Votes needed for election", rep->nvotes); - STAT_LONG("Priority in election", rep->priority); - __db_dlbytes(dbenv, "Limit on data sent in a single call", - rep->gbytes, (u_long)0, rep->bytes); - STAT_ULONG("Request gap", rep->request_gap); - STAT_ULONG("Maximum gap", rep->max_gap); - - STAT_LONG("Thread is in rep_elect", rep->elect_th); - STAT_ULONG("Callers in rep_proc_msg", rep->msg_th); - STAT_LONG("Thread is in rep_start", rep->start_th); - STAT_ULONG("Library handle count", rep->handle_cnt); - STAT_ULONG("Multi-step operation count", rep->op_cnt); - STAT_LONG("Running recovery", rep->in_recovery); - __db_msg(dbenv, "%.24s\tRecovery timestamp", - renv->rep_timestamp == 0 ? "0" : ctime(&renv->rep_timestamp)); - - STAT_LONG("Sites heard from", rep->sites); - STAT_LONG("Current winner", rep->winner); - STAT_LONG("Winner priority", rep->w_priority); - STAT_ULONG("Winner generation", rep->w_gen); - STAT_LSN("Winner LSN", &rep->w_lsn); - STAT_LONG("Winner tiebreaker", rep->w_tiebreaker); - STAT_LONG("Votes for this site", rep->votes); - - __db_prflags(dbenv, NULL, rep->flags, rep_fn, NULL, "\tFlags"); - - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_msg(dbenv, "LOG replication information:"); - MUTEX_LOCK(dbenv, rep->mtx_clientdb); - dblp = dbenv->lg_handle; - lp = (LOG *)dblp->reginfo.primary; - STAT_LSN("First log record after a gap", &lp->waiting_lsn); - STAT_LSN("LSN waiting to verify", &lp->verify_lsn); - STAT_LSN("Maximum LSN requested", &lp->max_wait_lsn); - STAT_ULONG("Records to wait before requesting", lp->wait_recs); - STAT_ULONG("Records received while waiting", lp->rcvd_recs); - STAT_LSN("Next LSN expected", &lp->ready_lsn); - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - - return (0); -} - -#else /* !HAVE_STATISTICS */ - -int -__rep_stat_pp(dbenv, statp, flags) - DB_ENV *dbenv; - DB_REP_STAT **statp; - u_int32_t flags; -{ - COMPQUIET(statp, NULL); - COMPQUIET(flags, 0); - - return (__db_stat_not_built(dbenv)); -} - -int -__rep_stat_print_pp(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - COMPQUIET(flags, 0); - - return (__db_stat_not_built(dbenv)); -} -#endif diff --git a/storage/bdb/rep/rep_stub.c b/storage/bdb/rep/rep_stub.c deleted file mode 100644 index 2c0b76fc83b..00000000000 --- a/storage/bdb/rep/rep_stub.c +++ /dev/null @@ -1,337 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: rep_stub.c,v 12.11 2005/10/09 16:12:07 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef HAVE_REPLICATION -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_am.h" - -/* - * If the library wasn't compiled with replication support, various routines - * aren't available. Stub them here, returning an appropriate error. - */ -static int __db_norep __P((DB_ENV *)); - -/* - * __db_norep -- - * Error when a Berkeley DB build doesn't include the access method. - */ -static int -__db_norep(dbenv) - DB_ENV *dbenv; -{ - __db_err(dbenv, - "library build did not include support for replication"); - return (DB_OPNOTSUP); -} - -int -__db_rep_enter(dbp, checkgen, checklock, return_now) - DB *dbp; - int checkgen, checklock, return_now; -{ - COMPQUIET(checkgen, 0); - COMPQUIET(checklock, 0); - COMPQUIET(return_now, 0); - return (__db_norep(dbp->dbenv)); -} - -int -__env_rep_enter(dbenv, checklock) - DB_ENV *dbenv; - int checklock; -{ - COMPQUIET(checklock, 0); - return (__db_norep(dbenv)); -} - -int -__env_db_rep_exit(dbenv) - DB_ENV *dbenv; -{ - return (__db_norep(dbenv)); -} - -int -__op_rep_enter(dbenv) - DB_ENV *dbenv; -{ - return (__db_norep(dbenv)); -} - -int -__op_rep_exit(dbenv) - DB_ENV *dbenv; -{ - return (__db_norep(dbenv)); -} - -int -__rep_bulk_message(dbenv, bulkp, repth, lsnp, dbt, flags) - DB_ENV *dbenv; - REP_BULK *bulkp; - REP_THROTTLE *repth; - DB_LSN *lsnp; - const DBT *dbt; - u_int32_t flags; -{ - COMPQUIET(bulkp, NULL); - COMPQUIET(repth, NULL); - COMPQUIET(lsnp, NULL); - COMPQUIET(dbt, NULL); - COMPQUIET(flags, 0); - return (__db_norep(dbenv)); -} - -int -__rep_dbenv_close(dbenv) - DB_ENV *dbenv; -{ - COMPQUIET(dbenv, NULL); - return (0); -} - -void -__rep_dbenv_refresh(dbenv) - DB_ENV *dbenv; -{ - COMPQUIET(dbenv, NULL); - return; -} - -int -__rep_elect(dbenv, nsites, nvotes, priority, timeout, eidp, flags) - DB_ENV *dbenv; - int nsites, nvotes, priority; - u_int32_t timeout, flags; - int *eidp; -{ - COMPQUIET(nsites, 0); - COMPQUIET(nvotes, 0); - COMPQUIET(priority, 0); - COMPQUIET(timeout, 0); - COMPQUIET(eidp, NULL); - COMPQUIET(flags, 0); - return (__db_norep(dbenv)); -} - -int -__rep_flush(dbenv) - DB_ENV *dbenv; -{ - return (__db_norep(dbenv)); -} - -int -__rep_get_config(dbenv, which, onp) - DB_ENV *dbenv; - u_int32_t which; - int *onp; -{ - COMPQUIET(which, 0); - COMPQUIET(onp, NULL); - return (__db_norep(dbenv)); -} - -int -__rep_set_config(dbenv, which, on) - DB_ENV *dbenv; - u_int32_t which; - int on; -{ - COMPQUIET(which, 0); - COMPQUIET(on, 0); - return (__db_norep(dbenv)); -} - -int -__rep_get_limit(dbenv, gbytesp, bytesp) - DB_ENV *dbenv; - u_int32_t *gbytesp, *bytesp; -{ - COMPQUIET(gbytesp, NULL); - COMPQUIET(bytesp, NULL); - return (__db_norep(dbenv)); -} - -int -__rep_get_gen(dbenv, genp) - DB_ENV *dbenv; - u_int32_t *genp; -{ - COMPQUIET(genp, NULL); - return (__db_norep(dbenv)); -} - -int -__rep_is_client(dbenv) - DB_ENV *dbenv; -{ - COMPQUIET(dbenv, NULL); - return (0); -} - -int -__rep_noarchive(dbenv) - DB_ENV *dbenv; -{ - COMPQUIET(dbenv, NULL); - return (0); -} - -int -__rep_open(dbenv) - DB_ENV *dbenv; -{ - COMPQUIET(dbenv, NULL); - return (0); -} - -int -__rep_preclose(dbenv) - DB_ENV *dbenv; -{ - return (__db_norep(dbenv)); -} - -int -__rep_process_message(dbenv, control, rec, eidp, ret_lsnp) - DB_ENV *dbenv; - DBT *control, *rec; - int *eidp; - DB_LSN *ret_lsnp; -{ - COMPQUIET(control, NULL); - COMPQUIET(rec, NULL); - COMPQUIET(eidp, NULL); - COMPQUIET(ret_lsnp, NULL); - return (__db_norep(dbenv)); -} - -int -__rep_region_destroy(dbenv) - DB_ENV *dbenv; -{ - COMPQUIET(dbenv, NULL); - return (0); -} - -int -__rep_region_init(dbenv) - DB_ENV *dbenv; -{ - COMPQUIET(dbenv, NULL); - return (0); -} - -int -__rep_send_message(dbenv, eid, rtype, lsnp, dbtp, logflags, repflags) - DB_ENV *dbenv; - int eid; - u_int32_t rtype; - DB_LSN *lsnp; - const DBT *dbtp; - u_int32_t logflags, repflags; -{ - COMPQUIET(eid, 0); - COMPQUIET(rtype, 0); - COMPQUIET(lsnp, NULL); - COMPQUIET(dbtp, NULL); - COMPQUIET(logflags, 0); - COMPQUIET(repflags, 0); - return (__db_norep(dbenv)); -} - -int -__rep_set_limit(dbenv, gbytes, bytes) - DB_ENV *dbenv; - u_int32_t gbytes, bytes; -{ - COMPQUIET(gbytes, 0); - COMPQUIET(bytes, 0); - return (__db_norep(dbenv)); -} - -int -__rep_set_rep_transport(dbenv, eid, f_send) - DB_ENV *dbenv; - int eid; - int (*f_send) __P((DB_ENV *, const DBT *, const DBT *, const DB_LSN *, - int, u_int32_t)); -{ - COMPQUIET(eid, 0); - COMPQUIET(f_send, NULL); - return (__db_norep(dbenv)); -} - -int -__rep_set_request(dbenv, min, max) - DB_ENV *dbenv; - u_int32_t min, max; -{ - COMPQUIET(min, 0); - COMPQUIET(max, 0); - return (__db_norep(dbenv)); -} - -int -__rep_start(dbenv, dbt, flags) - DB_ENV *dbenv; - DBT *dbt; - u_int32_t flags; -{ - COMPQUIET(dbt, NULL); - COMPQUIET(flags, 0); - return (__db_norep(dbenv)); -} - -int -__rep_stat_pp(dbenv, statp, flags) - DB_ENV *dbenv; - DB_REP_STAT **statp; - u_int32_t flags; -{ - COMPQUIET(statp, NULL); - COMPQUIET(flags, 0); - return (__db_norep(dbenv)); -} - -int -__rep_stat_print_pp(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - COMPQUIET(flags, 0); - return (__db_norep(dbenv)); -} - -int -__rep_stat_print(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - COMPQUIET(flags, 0); - return (__db_norep(dbenv)); -} - -int -__rep_sync(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - COMPQUIET(flags, 0); - return (__db_norep(dbenv)); -} -#endif /* !HAVE_REPLICATION */ diff --git a/storage/bdb/rep/rep_util.c b/storage/bdb/rep/rep_util.c deleted file mode 100644 index 90c5df4cc99..00000000000 --- a/storage/bdb/rep/rep_util.c +++ /dev/null @@ -1,1434 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2001-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: rep_util.c,v 12.42 2005/10/27 01:26:02 mjc Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#if TIME_WITH_SYS_TIME -#include <sys/time.h> -#include <time.h> -#else -#if HAVE_SYS_TIME_H -#include <sys/time.h> -#else -#include <time.h> -#endif -#endif - -#include <stdlib.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/log.h" -#include "dbinc/txn.h" -#ifdef REP_DIAGNOSTIC -#include "dbinc/db_page.h" -#include "dbinc/fop.h" -#include "dbinc/btree.h" -#include "dbinc/hash.h" -#include "dbinc/qam.h" -#endif - -/* - * rep_util.c: - * Miscellaneous replication-related utility functions, including - * those called by other subsystems. - */ - -#define TIMESTAMP_CHECK(dbenv, ts, renv) do { \ - if (renv->op_timestamp != 0 && \ - renv->op_timestamp + DB_REGENV_TIMEOUT < ts) { \ - REP_SYSTEM_LOCK(dbenv); \ - F_CLR(renv, DB_REGENV_REPLOCKED); \ - renv->op_timestamp = 0; \ - REP_SYSTEM_UNLOCK(dbenv); \ - } \ -} while (0) - -#ifdef REP_DIAGNOSTIC -static void __rep_print_logmsg __P((DB_ENV *, const DBT *, DB_LSN *)); -#endif - -/* - * __rep_bulk_message -- - * This is a wrapper for putting a record into a bulk buffer. Since - * we have different bulk buffers, the caller must hand us the information - * we need to put the record into the correct buffer. All bulk buffers - * are protected by the REP->mtx_clientdb. - * - * PUBLIC: int __rep_bulk_message __P((DB_ENV *, REP_BULK *, REP_THROTTLE *, - * PUBLIC: DB_LSN *, const DBT *, u_int32_t)); - */ -int -__rep_bulk_message(dbenv, bulk, repth, lsn, dbt, flags) - DB_ENV *dbenv; - REP_BULK *bulk; - REP_THROTTLE *repth; - DB_LSN *lsn; - const DBT *dbt; - u_int32_t flags; -{ - DB_REP *db_rep; - REP *rep; - int ret; - u_int32_t recsize, typemore; - u_int8_t *p; -#ifdef DIAGNOSTIC - DB_MSGBUF mb; -#endif - - db_rep = dbenv->rep_handle; - rep = db_rep->region; - ret = 0; - - /* - * Figure out the total number of bytes needed for this record. - */ - recsize = dbt->size + sizeof(DB_LSN) + sizeof(dbt->size); - - /* - * If *this* buffer is actively being transmitted, wait until - * we can use it. - */ - MUTEX_LOCK(dbenv, rep->mtx_clientdb); - while (FLD_ISSET(*(bulk->flagsp), BULK_XMIT)) { - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - __os_sleep(dbenv, 1, 0); - MUTEX_LOCK(dbenv, rep->mtx_clientdb); - } - - /* - * If the record is bigger than the buffer entirely, send the - * current buffer and then return DB_REP_BULKOVF so that this - * record is sent as a singleton. Do we have enough info to - * do that here? XXX - */ - if (recsize > bulk->len) { - RPRINT(dbenv, rep, (dbenv, &mb, - "bulk_msg: Record %d (0x%x) larger than entire buffer 0x%x", - recsize, recsize, bulk->len)); - rep->stat.st_bulk_overflows++; - (void)__rep_send_bulk(dbenv, bulk, flags); - /* - * XXX __rep_send_message... - */ - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - return (DB_REP_BULKOVF); - } - /* - * If this record doesn't fit, send the current buffer. - * Sending the buffer will reset the offset, but we will - * drop the mutex while sending so we need to keep checking - * if we're racing. - */ - while (recsize + *(bulk->offp) > bulk->len) { - RPRINT(dbenv, rep, (dbenv, &mb, - "bulk_msg: Record %lu (%#lx) doesn't fit. Send %lu (%#lx) now.", - (u_long)recsize, (u_long)recsize, - (u_long)bulk->len, (u_long)bulk->len)); - rep->stat.st_bulk_fills++; - if ((ret = __rep_send_bulk(dbenv, bulk, flags)) != 0) - break; - } - - /* - * If we're using throttling, see if we are at the throttling - * limit before we do any more work here, by checking if the - * call to rep_send_throttle changed the repth->type to the - * *_MORE message type. If the throttling code hits the limit - * then we're done here. - */ - if (bulk->type == REP_BULK_LOG) - typemore = REP_LOG_MORE; - else - typemore = REP_PAGE_MORE; - if (repth != NULL && - (ret = __rep_send_throttle(dbenv, bulk->eid, repth, - REP_THROTTLE_ONLY)) == 0 && repth->type == typemore) { - RPRINT(dbenv, rep, (dbenv, &mb, - "bulk_msg: Record %d (0x%x) hit throttle limit.", - recsize, recsize)); - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - return (ret); - } - - /* - * Now we own the buffer, and we know our record fits into it. - * The buffer is structured with the len, LSN and then the record. - * Copy the record into the buffer. Then if we need to, - * send the buffer. - */ - /* - * First thing is the length of the dbt record. - */ - p = bulk->addr + *(bulk->offp); - memcpy(p, &dbt->size, sizeof(dbt->size)); - p += sizeof(dbt->size); - /* - * The next thing is the LSN. We need LSNs for both pages and - * log records. For log records, this is obviously, the LSN of - * this record. For pages, the LSN is used by the internal init code. - */ - memcpy(p, lsn, sizeof(DB_LSN)); - RPRINT(dbenv, rep, (dbenv, &mb, - "bulk_msg: Copying LSN [%lu][%lu] of %lu bytes to %#lx", - (u_long)lsn->file, (u_long)lsn->offset, (u_long)dbt->size, - P_TO_ULONG(p))); - p += sizeof(DB_LSN); - /* - * If we're the first record, we need to save the first - * LSN in the bulk structure. - */ - if (*(bulk->offp) == 0) - bulk->lsn = *lsn; - /* - * Now copy the record and finally adjust the offset. - */ - memcpy(p, dbt->data, dbt->size); - p += dbt->size; - *(bulk->offp) = (uintptr_t)p - (uintptr_t)bulk->addr; - rep->stat.st_bulk_records++; - /* - * Send the buffer if it is a perm record or a force. - */ - if (LF_ISSET(DB_LOG_PERM) || FLD_ISSET(*(bulk->flagsp), BULK_FORCE)) { - RPRINT(dbenv, rep, (dbenv, &mb, - "bulk_msg: Send buffer after copy due to %s", - LF_ISSET(DB_LOG_PERM) ? "PERM" : "FORCE")); - ret = __rep_send_bulk(dbenv, bulk, flags); - } - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - return (ret); - -} - -/* - * __rep_send_bulk -- - * This function transmits the bulk buffer given. It assumes the - * caller holds the REP->mtx_clientdb. We may release it and reacquire - * it during this call. We will return with it held. - * - * PUBLIC: int __rep_send_bulk __P((DB_ENV *, REP_BULK *, u_int32_t)); - */ -int -__rep_send_bulk(dbenv, bulkp, flags) - DB_ENV *dbenv; - REP_BULK *bulkp; - u_int32_t flags; -{ - DB_REP *db_rep; - REP *rep; - DBT dbt; - int ret; -#ifdef DIAGNOSTIC - DB_MSGBUF mb; -#endif - - /* - * If the offset is 0, we're done. There is nothing to send. - */ - if (*(bulkp->offp) == 0) - return (0); - - db_rep = dbenv->rep_handle; - rep = db_rep->region; - - memset(&dbt, 0, sizeof(dbt)); - /* - * Set that this buffer is being actively transmitted. - */ - FLD_SET(*(bulkp->flagsp), BULK_XMIT); - dbt.data = bulkp->addr; - dbt.size = (u_int32_t)*(bulkp->offp); - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - RPRINT(dbenv, rep, (dbenv, &mb, - "send_bulk: Send %d (0x%x) bulk buffer bytes", dbt.size, dbt.size)); - /* - * Unlocked the mutex and now send the message. - */ - rep->stat.st_bulk_transfers++; - ret = __rep_send_message(dbenv, bulkp->eid, bulkp->type, &bulkp->lsn, - &dbt, flags, 0); - - MUTEX_LOCK(dbenv, rep->mtx_clientdb); - /* - * If we're successful, reset the offset pointer to 0. - * Clear the transmit flag regardless. - */ - if (ret == 0) - *(bulkp->offp) = 0; - FLD_CLR(*(bulkp->flagsp), BULK_XMIT); - return (ret); -} - -/* - * __rep_bulk_alloc -- - * This function allocates and initializes an internal bulk buffer. - * This is used by the master when fulfilling a request for a chunk of - * log records or a bunch of pages. - * - * PUBLIC: int __rep_bulk_alloc __P((DB_ENV *, REP_BULK *, int, uintptr_t *, - * PUBLIC: u_int32_t *, u_int32_t)); - */ -int -__rep_bulk_alloc(dbenv, bulkp, eid, offp, flagsp, type) - DB_ENV *dbenv; - REP_BULK *bulkp; - int eid; - uintptr_t *offp; - u_int32_t *flagsp, type; -{ - int ret; - - memset(bulkp, 0, sizeof(REP_BULK)); - *offp = *flagsp = 0; - bulkp->len = MEGABYTE; - if ((ret = __os_malloc(dbenv, bulkp->len, &bulkp->addr)) != 0) - return (ret); - bulkp->offp = offp; - bulkp->type = type; - bulkp->eid = eid; - bulkp->flagsp = flagsp; - return (ret); -} - -/* - * __rep_bulk_free -- - * This function sends the remainder of the bulk buffer and frees it. - * - * PUBLIC: int __rep_bulk_free __P((DB_ENV *, REP_BULK *, u_int32_t)); - */ -int -__rep_bulk_free(dbenv, bulkp, flags) - DB_ENV *dbenv; - REP_BULK *bulkp; - u_int32_t flags; -{ - DB_REP *db_rep; - int ret; - - db_rep = dbenv->rep_handle; - - MUTEX_LOCK(dbenv, db_rep->region->mtx_clientdb); - ret = __rep_send_bulk(dbenv, bulkp, flags); - MUTEX_UNLOCK(dbenv, db_rep->region->mtx_clientdb); - __os_free(dbenv, bulkp->addr); - return (ret); -} - -/* - * __rep_send_message -- - * This is a wrapper for sending a message. It takes care of constructing - * the REP_CONTROL structure and calling the user's specified send function. - * - * PUBLIC: int __rep_send_message __P((DB_ENV *, int, - * PUBLIC: u_int32_t, DB_LSN *, const DBT *, u_int32_t, u_int32_t)); - */ -int -__rep_send_message(dbenv, eid, rtype, lsnp, dbt, logflags, repflags) - DB_ENV *dbenv; - int eid; - u_int32_t rtype; - DB_LSN *lsnp; - const DBT *dbt; - u_int32_t logflags, repflags; -{ - DB_REP *db_rep; - REP *rep; - DBT cdbt, scrap_dbt; - REP_CONTROL cntrl; - int ret; - u_int32_t myflags, rectype; -#ifdef DIAGNOSTIC - DB_MSGBUF mb; -#endif - - db_rep = dbenv->rep_handle; - rep = db_rep->region; - - /* Set up control structure. */ - memset(&cntrl, 0, sizeof(cntrl)); - if (lsnp == NULL) - ZERO_LSN(cntrl.lsn); - else - cntrl.lsn = *lsnp; - cntrl.rectype = rtype; - cntrl.flags = logflags; - cntrl.rep_version = DB_REPVERSION; - cntrl.log_version = DB_LOGVERSION; - cntrl.gen = rep->gen; - - memset(&cdbt, 0, sizeof(cdbt)); - cdbt.data = &cntrl; - cdbt.size = sizeof(cntrl); - - /* Don't assume the send function will be tolerant of NULL records. */ - if (dbt == NULL) { - memset(&scrap_dbt, 0, sizeof(DBT)); - dbt = &scrap_dbt; - } - - REP_PRINT_MESSAGE(dbenv, eid, &cntrl, "rep_send_message"); -#ifdef REP_DIAGNOSTIC - if (FLD_ISSET(dbenv->verbose, DB_VERB_REPLICATION) && rtype == REP_LOG) - __rep_print_logmsg(dbenv, dbt, lsnp); -#endif - /* - * There are several types of records: commit and checkpoint records - * that affect database durability, regular log records that might - * be buffered on the master before being transmitted, and control - * messages which don't require the guarantees of permanency, but - * should not be buffered. - * - * There are request records that can be sent anywhere, and there - * are rerequest records that the app might want to send to the master. - */ - myflags = repflags; - if (FLD_ISSET(logflags, DB_LOG_PERM)) - myflags |= DB_REP_PERMANENT; - else if (rtype != REP_LOG || FLD_ISSET(logflags, DB_LOG_RESEND)) - myflags |= DB_REP_NOBUFFER; - if (rtype == REP_LOG && !FLD_ISSET(logflags, DB_LOG_PERM)) { - /* - * Check if this is a log record we just read that - * may need a DB_LOG_PERM. This is of type REP_LOG, - * so we know that dbt is a log record. - */ - memcpy(&rectype, dbt->data, sizeof(rectype)); - if (rectype == DB___txn_regop || rectype == DB___txn_ckp) - F_SET(&cntrl, DB_LOG_PERM); - } - - /* - * We set the LSN above to something valid. Give the master the - * actual LSN so that they can coordinate with permanent records from - * the client if they want to. - */ - ret = dbenv->rep_send(dbenv, &cdbt, dbt, &cntrl.lsn, eid, myflags); - - /* - * We don't hold the rep lock, so this could miscount if we race. - * I don't think it's worth grabbing the mutex for that bit of - * extra accuracy. - */ - if (ret == 0) - rep->stat.st_msgs_sent++; - else { - rep->stat.st_msgs_send_failures++; - RPRINT(dbenv, rep, (dbenv, &mb, - "rep_send_function returned: %d", ret)); - } - return (ret); -} - -#ifdef REP_DIAGNOSTIC -/* - * __rep_print_logmsg -- - * This is a debugging routine for printing out log records that - * we are about to transmit to a client. - */ -static void -__rep_print_logmsg(dbenv, logdbt, lsnp) - DB_ENV *dbenv; - const DBT *logdbt; - DB_LSN *lsnp; -{ - /* Static structures to hold the printing functions. */ - static int (**ptab)__P((DB_ENV *, - DBT *, DB_LSN *, db_recops, void *)) = NULL; - size_t ptabsize = 0; - - if (ptabsize == 0) { - /* Initialize the table. */ - (void)__bam_init_print(dbenv, &ptab, &ptabsize); - (void)__crdel_init_print(dbenv, &ptab, &ptabsize); - (void)__db_init_print(dbenv, &ptab, &ptabsize); - (void)__dbreg_init_print(dbenv, &ptab, &ptabsize); - (void)__fop_init_print(dbenv, &ptab, &ptabsize); - (void)__ham_init_print(dbenv, &ptab, &ptabsize); - (void)__qam_init_print(dbenv, &ptab, &ptabsize); - (void)__txn_init_print(dbenv, &ptab, &ptabsize); - } - - (void)__db_dispatch(dbenv, - ptab, ptabsize, (DBT *)logdbt, lsnp, DB_TXN_PRINT, NULL); -} -#endif - -/* - * __rep_new_master -- - * Called after a master election to sync back up with a new master. - * It's possible that we already know of this new master in which case - * we don't need to do anything. - * - * This is written assuming that this message came from the master; we - * need to enforce that in __rep_process_record, but right now, we have - * no way to identify the master. - * - * PUBLIC: int __rep_new_master __P((DB_ENV *, REP_CONTROL *, int)); - */ -int -__rep_new_master(dbenv, cntrl, eid) - DB_ENV *dbenv; - REP_CONTROL *cntrl; - int eid; -{ - DB_LOG *dblp; - DB_LOGC *logc; - DB_LSN first_lsn, lsn; - DB_REP *db_rep; - DBT dbt; - LOG *lp; - REGENV *renv; - REGINFO *infop; - REP *rep; - int change, do_req, ret, t_ret; -#ifdef DIAGNOSTIC - DB_MSGBUF mb; -#endif - - db_rep = dbenv->rep_handle; - rep = db_rep->region; - ret = 0; - logc = NULL; - REP_SYSTEM_LOCK(dbenv); - __rep_elect_done(dbenv, rep); - change = rep->gen != cntrl->gen || rep->master_id != eid; - if (change) { - RPRINT(dbenv, rep, (dbenv, &mb, - "Updating gen from %lu to %lu from master %d", - (u_long)rep->gen, (u_long)cntrl->gen, eid)); - rep->gen = cntrl->gen; - if (rep->egen <= rep->gen) - rep->egen = rep->gen + 1; - RPRINT(dbenv, rep, (dbenv, &mb, - "Egen is %lu", (u_long)rep->egen)); - rep->master_id = eid; - rep->stat.st_master_changes++; - rep->stat.st_startup_complete = 0; - /* - * If we're delaying client sync-up, we know we have a - * new/changed master now, set flag indicating we are - * actively delaying. - */ - if (FLD_ISSET(rep->config, REP_C_DELAYCLIENT)) - F_SET(rep, REP_F_DELAY); - /* - * If we are already locking out others, we're either - * in the middle of sync-up recovery or internal init - * when this newmaster comes in (we also lockout in - * rep_start, but we cannot be racing that because we - * don't allow rep_proc_msg when rep_start is going on). - * - * If we were in the middle of an internal initialization - * and we've discovered a new master instead, clean up - * our old internal init information. We need to clean - * up any flags and unlock our lockout. - */ - if (rep->in_recovery || F_ISSET(rep, REP_F_READY)) { - (void)__rep_init_cleanup(dbenv, rep, DB_FORCE); - F_CLR(rep, REP_F_RECOVER_MASK); - rep->in_recovery = 0; - F_CLR(rep, REP_F_READY); - } - F_SET(rep, REP_F_NOARCHIVE | REP_F_RECOVER_VERIFY); - } - REP_SYSTEM_UNLOCK(dbenv); - - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - LOG_SYSTEM_LOCK(dbenv); - lsn = lp->lsn; - LOG_SYSTEM_UNLOCK(dbenv); - - if (!change) { - /* - * If there wasn't a change, we might still have some - * catching up or verification to do. - */ - ret = 0; - MUTEX_LOCK(dbenv, rep->mtx_clientdb); - do_req = __rep_check_doreq(dbenv, rep); - if (F_ISSET(rep, REP_F_RECOVER_VERIFY)) { - lsn = lp->verify_lsn; - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - if (!F_ISSET(rep, REP_F_DELAY) && - !IS_ZERO_LSN(lsn) && do_req) - (void)__rep_send_message(dbenv, eid, - REP_VERIFY_REQ, &lsn, NULL, 0, - DB_REP_ANYWHERE); - } else { - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - if (log_compare(&lsn, &cntrl->lsn) < 0 && do_req) - (void)__rep_send_message(dbenv, eid, - REP_ALL_REQ, &lsn, NULL, - 0, DB_REP_ANYWHERE); - REP_SYSTEM_LOCK(dbenv); - F_CLR(rep, REP_F_NOARCHIVE); - REP_SYSTEM_UNLOCK(dbenv); - } - return (ret); - } - - /* - * If the master changed, we need to start the process of - * figuring out what our last valid log record is. However, - * if both the master and we agree that the max LSN is 0,0, - * then there is no recovery to be done. If we are at 0 and - * the master is not, then we just need to request all the log - * records from the master. - */ - if (IS_INIT_LSN(lsn) || IS_ZERO_LSN(lsn)) { - /* - * If we have no log, then we have no files to open - * in recovery, but we've opened what we can, which - * is none. Mark DBREP_OPENFILES here. - */ -empty: MUTEX_LOCK(dbenv, rep->mtx_clientdb); - F_SET(db_rep, DBREP_OPENFILES); - ZERO_LSN(lp->verify_lsn); - REP_SYSTEM_LOCK(dbenv); - F_CLR(rep, REP_F_NOARCHIVE | REP_F_RECOVER_MASK); - REP_SYSTEM_UNLOCK(dbenv); - - if (!IS_INIT_LSN(cntrl->lsn)) { - /* - * We're making an ALL_REQ. But now that we've - * cleared the flags, we're likely receiving new - * log records from the master, resulting in a gap - * immediately. So to avoid multiple data streams, - * set the wait_recs value high now to give the master - * a chance to start sending us these records before - * the gap code re-requests the same gap. Wait_recs - * will get reset once we start receiving these - * records. - */ - lp->wait_recs = rep->max_gap; - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - /* - * Don't send the ALL_REQ if we're delayed. But we - * check here, after lp->wait_recs is set up so that - * when the app calls rep_sync, everything is ready - * to go. - */ - if (!F_ISSET(rep, REP_F_DELAY)) - (void)__rep_send_message(dbenv, eid, - REP_ALL_REQ, &lsn, NULL, - 0, DB_REP_ANYWHERE); - } else - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - - return (DB_REP_NEWMASTER); - } - - memset(&dbt, 0, sizeof(dbt)); - /* - * If this client is farther ahead on the log file than the master, see - * if there is any overlap in the logs. If not, the client is too - * far ahead of the master and we cannot determine they're part of - * the same replication group. - */ - if (cntrl->lsn.file < lsn.file) { - if ((ret = __log_cursor(dbenv, &logc)) != 0) - goto err; - if ((ret = __log_c_get(logc, &first_lsn, &dbt, DB_FIRST)) != 0) - goto err; - if (cntrl->lsn.file < first_lsn.file) { - __db_err(dbenv, - "Client too far ahead of master; unable to join replication group"); - ret = DB_REP_JOIN_FAILURE; - goto err; - } - ret = __log_c_close(logc); - logc = NULL; - if (ret != 0) - goto err; - } - if ((ret = __log_cursor(dbenv, &logc)) != 0) - goto err; - ret = __rep_log_backup(logc, &lsn); -err: if (logc != NULL && (t_ret = __log_c_close(logc)) != 0 && ret == 0) - ret = t_ret; - if (ret == DB_NOTFOUND) { - /* - * If we don't have an identification record, we still might - * have some log records but we're discarding them to sync - * up with the master from the start. Therefore, - * truncate our log and go to the no log case. - */ - INIT_LSN(lsn); - RPRINT(dbenv, rep, (dbenv, &mb, - "No commit or ckp found. Truncate log.")); - (void)__log_vtruncate(dbenv, &lsn, &lsn, NULL); - infop = dbenv->reginfo; - renv = infop->primary; - REP_SYSTEM_LOCK(dbenv); - (void)time(&renv->rep_timestamp); - REP_SYSTEM_UNLOCK(dbenv); - goto empty; - } - - /* - * If we failed here, we need to clear the flags we may - * have set above because we're not going to be setting - * the verify_lsn. - */ - if (ret != 0) { - REP_SYSTEM_LOCK(dbenv); - F_CLR(rep, REP_F_RECOVER_MASK | REP_F_DELAY); - REP_SYSTEM_UNLOCK(dbenv); - return (ret); - } - - /* - * Finally, we have a record to ask for. - */ - MUTEX_LOCK(dbenv, rep->mtx_clientdb); - lp->verify_lsn = lsn; - lp->rcvd_recs = 0; - lp->wait_recs = rep->request_gap; - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - if (!F_ISSET(rep, REP_F_DELAY)) - (void)__rep_send_message(dbenv, - eid, REP_VERIFY_REQ, &lsn, NULL, 0, DB_REP_ANYWHERE); - - return (DB_REP_NEWMASTER); -} - -/* - * __rep_is_client - * Used by other subsystems to figure out if this is a replication - * client site. - * - * PUBLIC: int __rep_is_client __P((DB_ENV *)); - */ -int -__rep_is_client(dbenv) - DB_ENV *dbenv; -{ - DB_REP *db_rep; - REP *rep; - - if (!REP_ON(dbenv)) - return (0); - - db_rep = dbenv->rep_handle; - rep = db_rep->region; - - /* - * Don't just return F_ISSET since that converts unsigned - * into signed. - */ - return (F_ISSET(rep, REP_F_CLIENT) ? 1 : 0); -} - -/* - * __rep_noarchive - * Used by log_archive to determine if it is okay to remove - * log files. - * - * PUBLIC: int __rep_noarchive __P((DB_ENV *)); - */ -int -__rep_noarchive(dbenv) - DB_ENV *dbenv; -{ - DB_REP *db_rep; - REGENV *renv; - REGINFO *infop; - REP *rep; - time_t timestamp; - - infop = dbenv->reginfo; - renv = infop->primary; - - /* - * This is tested before REP_ON below because we always need - * to obey if any replication process has disabled archiving. - * Everything is in the environment region that we need here. - */ - if (F_ISSET(renv, DB_REGENV_REPLOCKED)) { - (void)time(×tamp); - TIMESTAMP_CHECK(dbenv, timestamp, renv); - /* - * Check if we're still locked out after checking - * the timestamp. - */ - if (F_ISSET(renv, DB_REGENV_REPLOCKED)) - return (EINVAL); - } - - if (!REP_ON(dbenv)) - return (0); - db_rep = dbenv->rep_handle; - rep = db_rep->region; - if (F_ISSET(rep, REP_F_NOARCHIVE)) - return (1); - return (0); -} - -/* - * __rep_send_vote - * Send this site's vote for the election. - * - * PUBLIC: void __rep_send_vote __P((DB_ENV *, DB_LSN *, int, int, int, - * PUBLIC: u_int32_t, u_int32_t, int, u_int32_t)); - */ -void -__rep_send_vote(dbenv, lsnp, nsites, nvotes, pri, tie, egen, eid, vtype) - DB_ENV *dbenv; - DB_LSN *lsnp; - int eid, nsites, nvotes, pri; - u_int32_t egen, tie, vtype; -{ - DBT vote_dbt; - REP_VOTE_INFO vi; - - memset(&vi, 0, sizeof(vi)); - - vi.egen = egen; - vi.priority = pri; - vi.nsites = nsites; - vi.nvotes = nvotes; - vi.tiebreaker = tie; - - memset(&vote_dbt, 0, sizeof(vote_dbt)); - vote_dbt.data = &vi; - vote_dbt.size = sizeof(vi); - - (void)__rep_send_message(dbenv, eid, vtype, lsnp, &vote_dbt, 0, 0); -} - -/* - * __rep_elect_done - * Clear all election information for this site. Assumes the - * caller hold the region mutex. - * - * PUBLIC: void __rep_elect_done __P((DB_ENV *, REP *)); - */ -void -__rep_elect_done(dbenv, rep) - DB_ENV *dbenv; - REP *rep; -{ - int inelect; - u_int32_t endsec, endusec; -#ifdef DIAGNOSTIC - DB_MSGBUF mb; -#else - COMPQUIET(dbenv, NULL); -#endif - inelect = IN_ELECTION_TALLY(rep); - F_CLR(rep, REP_F_EPHASE1 | REP_F_EPHASE2 | REP_F_TALLY); - rep->sites = 0; - rep->votes = 0; - if (inelect) { - if (rep->esec != 0) { - __os_clock(dbenv, &endsec, &endusec); - __db_difftime(rep->esec, endsec, rep->eusec, endusec, - &rep->stat.st_election_sec, - &rep->stat.st_election_usec); - RPRINT(dbenv, rep, (dbenv, &mb, - "Election finished in %u.%06u sec", - rep->stat.st_election_sec, - rep->stat.st_election_usec)); - rep->esec = 0; - rep->eusec = 0; - } - rep->egen++; - } - RPRINT(dbenv, rep, (dbenv, &mb, - "Election done; egen %lu", (u_long)rep->egen)); -} - -/* - * __rep_grow_sites -- - * Called to allocate more space in the election tally information. - * Called with the rep mutex held. We need to call the region mutex, so - * we need to make sure that we *never* acquire those mutexes in the - * opposite order. - * - * PUBLIC: int __rep_grow_sites __P((DB_ENV *dbenv, int nsites)); - */ -int -__rep_grow_sites(dbenv, nsites) - DB_ENV *dbenv; - int nsites; -{ - REGENV *renv; - REGINFO *infop; - REP *rep; - int nalloc, ret, *tally; - - rep = ((DB_REP *)dbenv->rep_handle)->region; - - /* - * Allocate either twice the current allocation or nsites, - * whichever is more. - */ - nalloc = 2 * rep->asites; - if (nalloc < nsites) - nalloc = nsites; - - infop = dbenv->reginfo; - renv = infop->primary; - MUTEX_LOCK(dbenv, renv->mtx_regenv); - - /* - * We allocate 2 tally regions, one for tallying VOTE1's and - * one for VOTE2's. Always grow them in tandem, because if we - * get more VOTE1's we'll always expect more VOTE2's then too. - */ - if ((ret = __db_shalloc(infop, - (size_t)nalloc * sizeof(REP_VTALLY), sizeof(REP_VTALLY), - &tally)) == 0) { - if (rep->tally_off != INVALID_ROFF) - __db_shalloc_free( - infop, R_ADDR(infop, rep->tally_off)); - rep->tally_off = R_OFFSET(infop, tally); - if ((ret = __db_shalloc(infop, - (size_t)nalloc * sizeof(REP_VTALLY), sizeof(REP_VTALLY), - &tally)) == 0) { - /* Success */ - if (rep->v2tally_off != INVALID_ROFF) - __db_shalloc_free(infop, - R_ADDR(infop, rep->v2tally_off)); - rep->v2tally_off = R_OFFSET(infop, tally); - rep->asites = nalloc; - rep->nsites = nsites; - } else { - /* - * We were unable to allocate both. So, we must - * free the first one and reinitialize. If - * v2tally_off is valid, it is from an old - * allocation and we are clearing it all out due - * to the error. - */ - if (rep->v2tally_off != INVALID_ROFF) - __db_shalloc_free(infop, - R_ADDR(infop, rep->v2tally_off)); - __db_shalloc_free(infop, - R_ADDR(infop, rep->tally_off)); - rep->v2tally_off = rep->tally_off = INVALID_ROFF; - rep->asites = 0; - rep->nsites = 0; - } - } - MUTEX_UNLOCK(dbenv, renv->mtx_regenv); - return (ret); -} - -/* - * __env_rep_enter -- - * - * Check if we are in the middle of replication initialization and/or - * recovery, and if so, disallow operations. If operations are allowed, - * increment handle-counts, so that we do not start recovery while we - * are operating in the library. - * - * PUBLIC: int __env_rep_enter __P((DB_ENV *, int)); - */ -int -__env_rep_enter(dbenv, checklock) - DB_ENV *dbenv; - int checklock; -{ - DB_REP *db_rep; - REGENV *renv; - REGINFO *infop; - REP *rep; - int cnt; - time_t timestamp; - - /* Check if locks have been globally turned off. */ - if (F_ISSET(dbenv, DB_ENV_NOLOCKING)) - return (0); - - db_rep = dbenv->rep_handle; - rep = db_rep->region; - - infop = dbenv->reginfo; - renv = infop->primary; - if (checklock && F_ISSET(renv, DB_REGENV_REPLOCKED)) { - (void)time(×tamp); - TIMESTAMP_CHECK(dbenv, timestamp, renv); - /* - * Check if we're still locked out after checking - * the timestamp. - */ - if (F_ISSET(renv, DB_REGENV_REPLOCKED)) - return (EINVAL); - } - - REP_SYSTEM_LOCK(dbenv); - for (cnt = 0; rep->in_recovery;) { - REP_SYSTEM_UNLOCK(dbenv); - if (FLD_ISSET(rep->config, REP_C_NOWAIT)) { - __db_err(dbenv, - "Operation locked out. Waiting for replication recovery to complete"); - return (DB_REP_LOCKOUT); - } - __os_sleep(dbenv, 1, 0); - REP_SYSTEM_LOCK(dbenv); - if (++cnt % 60 == 0) - __db_err(dbenv, - "DB_ENV handle waiting %d minutes for replication recovery to complete", - cnt / 60); - } - rep->handle_cnt++; - REP_SYSTEM_UNLOCK(dbenv); - - return (0); -} - -/* - * __env_db_rep_exit -- - * - * Decrement handle count upon routine exit. - * - * PUBLIC: int __env_db_rep_exit __P((DB_ENV *)); - */ -int -__env_db_rep_exit(dbenv) - DB_ENV *dbenv; -{ - DB_REP *db_rep; - REP *rep; - - /* Check if locks have been globally turned off. */ - if (F_ISSET(dbenv, DB_ENV_NOLOCKING)) - return (0); - - db_rep = dbenv->rep_handle; - rep = db_rep->region; - - REP_SYSTEM_LOCK(dbenv); - rep->handle_cnt--; - REP_SYSTEM_UNLOCK(dbenv); - - return (0); -} - -/* - * __db_rep_enter -- - * Called in replicated environments to keep track of in-use handles - * and prevent any concurrent operation during recovery. If checkgen is - * non-zero, then we verify that the dbp has the same handle as the env. - * - * If return_now is non-zero, we'll return DB_DEADLOCK immediately, else we'll - * sleep before returning DB_DEADLOCK. Without the sleep, it is likely - * the application will immediately try again and could reach a retry - * limit before replication has a chance to finish. The sleep increases - * the probability that an application retry will succeed. - * - * PUBLIC: int __db_rep_enter __P((DB *, int, int, int)); - */ -int -__db_rep_enter(dbp, checkgen, checklock, return_now) - DB *dbp; - int checkgen, checklock, return_now; -{ - DB_ENV *dbenv; - DB_REP *db_rep; - REGENV *renv; - REGINFO *infop; - REP *rep; - time_t timestamp; - - dbenv = dbp->dbenv; - /* Check if locks have been globally turned off. */ - if (F_ISSET(dbenv, DB_ENV_NOLOCKING)) - return (0); - - db_rep = dbenv->rep_handle; - rep = db_rep->region; - infop = dbenv->reginfo; - renv = infop->primary; - - if (checklock && F_ISSET(renv, DB_REGENV_REPLOCKED)) { - (void)time(×tamp); - TIMESTAMP_CHECK(dbenv, timestamp, renv); - /* - * Check if we're still locked out after checking - * the timestamp. - */ - if (F_ISSET(renv, DB_REGENV_REPLOCKED)) - return (EINVAL); - } - REP_SYSTEM_LOCK(dbenv); - if (F_ISSET(rep, REP_F_READY)) { - REP_SYSTEM_UNLOCK(dbenv); - if (!return_now) - __os_sleep(dbenv, 5, 0); - return (DB_LOCK_DEADLOCK); - } - - if (checkgen && dbp->timestamp != renv->rep_timestamp) { - REP_SYSTEM_UNLOCK(dbenv); - __db_err(dbenv, "%s %s", - "replication recovery unrolled committed transactions;", - "open DB and DBcursor handles must be closed"); - return (DB_REP_HANDLE_DEAD); - } - rep->handle_cnt++; - REP_SYSTEM_UNLOCK(dbenv); - - return (0); -} - -/* - * __op_rep_enter -- - * - * Check if we are in the middle of replication initialization and/or - * recovery, and if so, disallow new multi-step operations, such as - * transaction and memp gets. If operations are allowed, - * increment the op_cnt, so that we do not start recovery while we have - * active operations. - * - * PUBLIC: int __op_rep_enter __P((DB_ENV *)); - */ -int -__op_rep_enter(dbenv) - DB_ENV *dbenv; -{ - DB_REP *db_rep; - REP *rep; - int cnt; - - /* Check if locks have been globally turned off. */ - if (F_ISSET(dbenv, DB_ENV_NOLOCKING)) - return (0); - - db_rep = dbenv->rep_handle; - rep = db_rep->region; - - REP_SYSTEM_LOCK(dbenv); - for (cnt = 0; F_ISSET(rep, REP_F_READY);) { - REP_SYSTEM_UNLOCK(dbenv); - if (FLD_ISSET(rep->config, REP_C_NOWAIT)) { - __db_err(dbenv, - "Operation locked out. Waiting for replication recovery to complete"); - return (DB_REP_LOCKOUT); - } - __os_sleep(dbenv, 5, 0); - cnt += 5; - REP_SYSTEM_LOCK(dbenv); - if (cnt % 60 == 0) - __db_err(dbenv, - "__op_rep_enter waiting %d minutes for op count to drain", - cnt / 60); - } - rep->op_cnt++; - REP_SYSTEM_UNLOCK(dbenv); - - return (0); -} - -/* - * __op_rep_exit -- - * - * Decrement op count upon transaction commit/abort/discard or - * memp_fput. - * - * PUBLIC: int __op_rep_exit __P((DB_ENV *)); - */ -int -__op_rep_exit(dbenv) - DB_ENV *dbenv; -{ - DB_REP *db_rep; - REP *rep; - - /* Check if locks have been globally turned off. */ - if (F_ISSET(dbenv, DB_ENV_NOLOCKING)) - return (0); - - db_rep = dbenv->rep_handle; - rep = db_rep->region; - - REP_SYSTEM_LOCK(dbenv); - DB_ASSERT(rep->op_cnt > 0); - rep->op_cnt--; - REP_SYSTEM_UNLOCK(dbenv); - - return (0); -} - -/* - * __rep_get_gen -- - * - * Get the generation number from a replicated environment. - * - * PUBLIC: int __rep_get_gen __P((DB_ENV *, u_int32_t *)); - */ -int -__rep_get_gen(dbenv, genp) - DB_ENV *dbenv; - u_int32_t *genp; -{ - DB_REP *db_rep; - REP *rep; - - db_rep = dbenv->rep_handle; - rep = db_rep->region; - - REP_SYSTEM_LOCK(dbenv); - if (rep->recover_gen > rep->gen) - *genp = rep->recover_gen; - else - *genp = rep->gen; - REP_SYSTEM_UNLOCK(dbenv); - - return (0); -} - -/* - * __rep_lockout -- - * Coordinate with other threads in the library and active txns so - * that we can run single-threaded, for recovery or internal backup. - * Assumes the caller holds the region mutex. - * - * PUBLIC: int __rep_lockout __P((DB_ENV *, REP *, u_int32_t)); - */ -int -__rep_lockout(dbenv, rep, msg_th) - DB_ENV *dbenv; - REP *rep; - u_int32_t msg_th; -{ - int wait_cnt; - - /* Phase 1: set REP_F_READY and wait for op_cnt to go to 0. */ - F_SET(rep, REP_F_READY); - for (wait_cnt = 0; rep->op_cnt != 0;) { - REP_SYSTEM_UNLOCK(dbenv); - __os_sleep(dbenv, 1, 0); -#if defined(DIAGNOSTIC) || defined(CONFIG_TEST) - if (++wait_cnt % 60 == 0) - __db_err(dbenv, - "Waiting for txn_cnt to run replication recovery/backup for %d minutes", - wait_cnt / 60); -#endif - REP_SYSTEM_LOCK(dbenv); - } - - /* - * Phase 2: set in_recovery and wait for handle count to go - * to 0 and for the number of threads in __rep_process_message - * to go to 1 (us). - */ - rep->in_recovery = 1; - for (wait_cnt = 0; rep->handle_cnt != 0 || rep->msg_th > msg_th;) { - REP_SYSTEM_UNLOCK(dbenv); - __os_sleep(dbenv, 1, 0); -#ifdef DIAGNOSTIC - if (++wait_cnt % 60 == 0) - __db_err(dbenv, -"Waiting for handle count to run replication recovery/backup for %d minutes", - wait_cnt / 60); -#endif - REP_SYSTEM_LOCK(dbenv); - } - - return (0); -} - -/* - * __rep_send_throttle - - * Send a record, throttling if necessary. Callers of this function - * will throttle - breaking out of their loop, if the repth->type field - * changes from the normal message type to the *_MORE message type. - * This function will send the normal type unless throttling gets invoked. - * Then it sets the type field and sends the _MORE message. - * - * PUBLIC: int __rep_send_throttle __P((DB_ENV *, int, REP_THROTTLE *, - * PUBLIC: u_int32_t)); - */ -int -__rep_send_throttle(dbenv, eid, repth, flags) - DB_ENV *dbenv; - int eid; - REP_THROTTLE *repth; - u_int32_t flags; -{ - DB_REP *db_rep; - REP *rep; - u_int32_t size, typemore; - int check_limit; - - check_limit = repth->gbytes != 0 || repth->bytes != 0; - /* - * If we only want to do throttle processing and we don't have it - * turned on, return immediately. - */ - if (!check_limit && LF_ISSET(REP_THROTTLE_ONLY)) - return (0); - - db_rep = dbenv->rep_handle; - rep = db_rep->region; - typemore = 0; - if (repth->type == REP_LOG) - typemore = REP_LOG_MORE; - if (repth->type == REP_PAGE) - typemore = REP_PAGE_MORE; - DB_ASSERT(typemore != 0); - - /* - * data_dbt.size is only the size of the log - * record; it doesn't count the size of the - * control structure. Factor that in as well - * so we're not off by a lot if our log records - * are small. - */ - size = repth->data_dbt->size + sizeof(REP_CONTROL); - if (check_limit) { - if (repth->lsn.offset == 28) { - repth->type = typemore; - goto send; - } - while (repth->bytes <= size) { - if (repth->gbytes > 0) { - repth->bytes += GIGABYTE; - --(repth->gbytes); - continue; - } - /* - * We don't hold the rep mutex, - * and may miscount. - */ - rep->stat.st_nthrottles++; - repth->type = typemore; - goto send; - } - repth->bytes -= size; - } - /* - * Always send if it is typemore, otherwise send only if - * REP_THROTTLE_ONLY is not set. - */ -send: if ((repth->type == typemore || !LF_ISSET(REP_THROTTLE_ONLY)) && - (__rep_send_message(dbenv, eid, repth->type, - &repth->lsn, repth->data_dbt, DB_LOG_RESEND, 0) != 0)) - return (1); - return (0); -} - -#ifdef DIAGNOSTIC -/* - * PUBLIC: void __rep_print_message __P((DB_ENV *, int, REP_CONTROL *, char *)); - */ -void -__rep_print_message(dbenv, eid, rp, str) - DB_ENV *dbenv; - int eid; - REP_CONTROL *rp; - char *str; -{ - DB_MSGBUF mb; - char *type; - - switch (rp->rectype) { - case REP_ALIVE: - type = "alive"; - break; - case REP_ALIVE_REQ: - type = "alive_req"; - break; - case REP_ALL_REQ: - type = "all_req"; - break; - case REP_BULK_LOG: - type = "bulk_log"; - break; - case REP_BULK_PAGE: - type = "bulk_page"; - break; - case REP_DUPMASTER: - type = "dupmaster"; - break; - case REP_FILE: - type = "file"; - break; - case REP_FILE_FAIL: - type = "file_fail"; - break; - case REP_FILE_REQ: - type = "file_req"; - break; - case REP_LOG: - type = "log"; - break; - case REP_LOG_MORE: - type = "log_more"; - break; - case REP_LOG_REQ: - type = "log_req"; - break; - case REP_MASTER_REQ: - type = "master_req"; - break; - case REP_NEWCLIENT: - type = "newclient"; - break; - case REP_NEWFILE: - type = "newfile"; - break; - case REP_NEWMASTER: - type = "newmaster"; - break; - case REP_NEWSITE: - type = "newsite"; - break; - case REP_PAGE: - type = "page"; - break; - case REP_PAGE_FAIL: - type = "page_fail"; - break; - case REP_PAGE_MORE: - type = "page_more"; - break; - case REP_PAGE_REQ: - type = "page_req"; - break; - case REP_REREQUEST: - type = "rerequest"; - break; - case REP_UPDATE: - type = "update"; - break; - case REP_UPDATE_REQ: - type = "update_req"; - break; - case REP_VERIFY: - type = "verify"; - break; - case REP_VERIFY_FAIL: - type = "verify_fail"; - break; - case REP_VERIFY_REQ: - type = "verify_req"; - break; - case REP_VOTE1: - type = "vote1"; - break; - case REP_VOTE2: - type = "vote2"; - break; - default: - type = "NOTYPE"; - break; - } - RPRINT(dbenv, ((REP *)((DB_REP *)(dbenv)->rep_handle)->region), - (dbenv, &mb, "%s %s: gen = %lu eid %d, type %s, LSN [%lu][%lu]", - dbenv->db_home, str, (u_long)rp->gen, - eid, type, (u_long)rp->lsn.file, (u_long)rp->lsn.offset)); -} -#endif diff --git a/storage/bdb/rep/rep_verify.c b/storage/bdb/rep/rep_verify.c deleted file mode 100644 index 76fa8ae10c4..00000000000 --- a/storage/bdb/rep/rep_verify.c +++ /dev/null @@ -1,499 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2004-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: rep_verify.c,v 12.21 2005/10/19 19:06:37 sue Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#if TIME_WITH_SYS_TIME -#include <sys/time.h> -#include <time.h> -#else -#if HAVE_SYS_TIME_H -#include <sys/time.h> -#else -#include <time.h> -#endif -#endif - -#include <stdlib.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_am.h" -#include "dbinc/log.h" -#include "dbinc/txn.h" - -static int __rep_dorecovery __P((DB_ENV *, DB_LSN *, DB_LSN *)); - -/* - * __rep_verify -- - * Handle a REP_VERIFY message. - * - * PUBLIC: int __rep_verify __P((DB_ENV *, REP_CONTROL *, DBT *, int, time_t)); - */ -int -__rep_verify(dbenv, rp, rec, eid, savetime) - DB_ENV *dbenv; - REP_CONTROL *rp; - DBT *rec; - int eid; - time_t savetime; -{ - DB_LOG *dblp; - DB_LOGC *logc; - DB_LSN lsn; - DB_REP *db_rep; - DBT mylog; - LOG *lp; - REP *rep; - u_int32_t rectype; - int match, ret, t_ret; - - ret = 0; - db_rep = dbenv->rep_handle; - rep = db_rep->region; - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - - if (IS_ZERO_LSN(lp->verify_lsn)) - return (ret); - - if ((ret = __log_cursor(dbenv, &logc)) != 0) - return (ret); - memset(&mylog, 0, sizeof(mylog)); - if ((ret = __log_c_get(logc, &rp->lsn, &mylog, DB_SET)) != 0) - goto err;; - match = 0; - memcpy(&rectype, mylog.data, sizeof(rectype)); - if (mylog.size == rec->size && - memcmp(mylog.data, rec->data, rec->size) == 0) - match = 1; - /* - * If we don't have a match, backup to the previous - * identification record and try again. - */ - if (match == 0) { - ZERO_LSN(lsn); - if ((ret = __rep_log_backup(logc, &lsn)) == 0) { - MUTEX_LOCK(dbenv, rep->mtx_clientdb); - lp->verify_lsn = lsn; - lp->rcvd_recs = 0; - lp->wait_recs = rep->request_gap; - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - (void)__rep_send_message(dbenv, eid, REP_VERIFY_REQ, - &lsn, NULL, 0, DB_REP_ANYWHERE); - } else if (ret == DB_NOTFOUND) { - /* - * We've either run out of records because - * logs have been removed or we've rolled back - * all the way to the beginning. In the latter - * we don't think these sites were ever part of - * the same environment and we'll say so. - * In the former, request internal backup. - */ - if (rp->lsn.file == 1) { - __db_err(dbenv, - "Client was never part of master's environment"); - ret = DB_REP_JOIN_FAILURE; - } else { - rep->stat.st_outdated++; - - LOG_SYSTEM_LOCK(dbenv); - lsn = lp->lsn; - LOG_SYSTEM_UNLOCK(dbenv); - REP_SYSTEM_LOCK(dbenv); - F_CLR(rep, REP_F_RECOVER_VERIFY); - if (FLD_ISSET(rep->config, REP_C_NOAUTOINIT)) - ret = DB_REP_JOIN_FAILURE; - else { - F_SET(rep, REP_F_RECOVER_UPDATE); - ZERO_LSN(rep->first_lsn); - } - REP_SYSTEM_UNLOCK(dbenv); - if (ret == 0) - (void)__rep_send_message(dbenv, - eid, REP_UPDATE_REQ, NULL, - NULL, 0, DB_REP_ANYWHERE); - } - } - } else - ret = __rep_verify_match(dbenv, &rp->lsn, savetime); - -err: if ((t_ret = __log_c_close(logc)) != 0 && ret == 0) - ret = t_ret; - return (ret); -} - -/* - * __rep_verify_fail -- - * Handle a REP_VERIFY_FAIL message. - * - * PUBLIC: int __rep_verify_fail __P((DB_ENV *, REP_CONTROL *, int)); - */ -int -__rep_verify_fail(dbenv, rp, eid) - DB_ENV *dbenv; - REP_CONTROL *rp; - int eid; -{ - DB_LOG *dblp; - DB_REP *db_rep; - LOG *lp; - REP *rep; - int ret; - - ret = 0; - db_rep = dbenv->rep_handle; - rep = db_rep->region; - dblp = dbenv->lg_handle; - lp = dblp->reginfo.primary; - - /* - * If any recovery flags are set, but not VERIFY, - * then we ignore this message. We are already - * in the middle of updating. - */ - if (F_ISSET(rep, REP_F_RECOVER_MASK) && - !F_ISSET(rep, REP_F_RECOVER_VERIFY)) - return (0); - rep->stat.st_outdated++; - - MUTEX_LOCK(dbenv, rep->mtx_clientdb); - REP_SYSTEM_LOCK(dbenv); - /* - * We don't want an old or delayed VERIFY_FAIL - * message to throw us into internal initialization - * when we shouldn't be. - * - * Only go into internal initialization if: - * We are set for AUTOINIT mode. - * We are in RECOVER_VERIFY and this LSN == verify_lsn. - * We are not in any RECOVERY and we are expecting - * an LSN that no longer exists on the master. - * Otherwise, ignore this message. - */ - if (FLD_ISSET(rep->config, REP_C_NOAUTOINIT) && - ((F_ISSET(rep, REP_F_RECOVER_VERIFY) && - log_compare(&rp->lsn, &lp->verify_lsn) == 0) || - (F_ISSET(rep, REP_F_RECOVER_MASK) == 0 && - log_compare(&rp->lsn, &lp->ready_lsn) >= 0))) { - ret = DB_REP_JOIN_FAILURE; - goto unlock; - } - if (((F_ISSET(rep, REP_F_RECOVER_VERIFY)) && - log_compare(&rp->lsn, &lp->verify_lsn) == 0) || - (F_ISSET(rep, REP_F_RECOVER_MASK) == 0 && - log_compare(&rp->lsn, &lp->ready_lsn) >= 0)) { - F_CLR(rep, REP_F_RECOVER_VERIFY); - F_SET(rep, REP_F_RECOVER_UPDATE); - ZERO_LSN(rep->first_lsn); - lp->wait_recs = rep->request_gap; - REP_SYSTEM_UNLOCK(dbenv); - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - (void)__rep_send_message(dbenv, - eid, REP_UPDATE_REQ, NULL, NULL, 0, 0); - } else { -unlock: REP_SYSTEM_UNLOCK(dbenv); - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - } - return (ret); -} - -/* - * __rep_verify_req -- - * Handle a REP_VERIFY_REQ message. - * - * PUBLIC: int __rep_verify_req __P((DB_ENV *, REP_CONTROL *, int)); - */ -int -__rep_verify_req(dbenv, rp, eid) - DB_ENV *dbenv; - REP_CONTROL *rp; - int eid; -{ - DB_LOGC *logc; - DB_REP *db_rep; - DBT *d, data_dbt; - REP *rep; - u_int32_t type; - int old, ret; - - ret = 0; - db_rep = dbenv->rep_handle; - rep = db_rep->region; - - type = REP_VERIFY; - if ((ret = __log_cursor(dbenv, &logc)) != 0) - return (ret); - d = &data_dbt; - memset(d, 0, sizeof(data_dbt)); - F_SET(logc, DB_LOG_SILENT_ERR); - ret = __log_c_get(logc, &rp->lsn, d, DB_SET); - /* - * If the LSN was invalid, then we might get a not - * found, we might get an EIO, we could get anything. - * If we get a DB_NOTFOUND, then there is a chance that - * the LSN comes before the first file present in which - * case we need to return a fail so that the client can return - * a DB_OUTDATED. - * - * If we're a client servicing this request and we get a - * NOTFOUND, return it so the caller can rerequest from - * a better source. - */ - if (ret == DB_NOTFOUND) { - if (F_ISSET(rep, REP_F_CLIENT)) - goto notfound; - else if (__log_is_outdated(dbenv, rp->lsn.file, &old) == 0 && - old != 0) - type = REP_VERIFY_FAIL; - } - - if (ret != 0) - d = NULL; - - (void)__rep_send_message(dbenv, eid, type, &rp->lsn, d, 0, 0); -notfound: - ret = __log_c_close(logc); - return (ret); -} - -static int -__rep_dorecovery(dbenv, lsnp, trunclsnp) - DB_ENV *dbenv; - DB_LSN *lsnp, *trunclsnp; -{ - DB_LSN lsn; - DB_REP *db_rep; - DBT mylog; - DB_LOGC *logc; - int ret, t_ret, update; - u_int32_t rectype; - __txn_regop_args *txnrec; - - db_rep = dbenv->rep_handle; - - /* Figure out if we are backing out any committed transactions. */ - if ((ret = __log_cursor(dbenv, &logc)) != 0) - return (ret); - - memset(&mylog, 0, sizeof(mylog)); - update = 0; - while (update == 0 && - (ret = __log_c_get(logc, &lsn, &mylog, DB_PREV)) == 0 && - log_compare(&lsn, lsnp) > 0) { - memcpy(&rectype, mylog.data, sizeof(rectype)); - if (rectype == DB___txn_regop) { - if ((ret = - __txn_regop_read(dbenv, mylog.data, &txnrec)) != 0) - goto err; - if (txnrec->opcode != TXN_ABORT) - update = 1; - __os_free(dbenv, txnrec); - } - } - - /* - * If we successfully run recovery, we've opened all the necessary - * files. We are guaranteed to be single-threaded here, so no mutex - * is necessary. - */ - if ((ret = __db_apprec(dbenv, lsnp, trunclsnp, update, 0)) == 0) - F_SET(db_rep, DBREP_OPENFILES); - -err: if ((t_ret = __log_c_close(logc)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * __rep_verify_match -- - * We have just received a matching log record during verification. - * Figure out if we're going to need to run recovery. If so, wait until - * everything else has exited the library. If not, set up the world - * correctly and move forward. - * - * PUBLIC: int __rep_verify_match __P((DB_ENV *, DB_LSN *, time_t)); - */ -int -__rep_verify_match(dbenv, reclsnp, savetime) - DB_ENV *dbenv; - DB_LSN *reclsnp; - time_t savetime; -{ - DB_LOG *dblp; - DB_LSN trunclsn; - DB_REP *db_rep; - LOG *lp; - REGENV *renv; - REGINFO *infop; - REP *rep; - int done, master, ret; - u_int32_t unused; - - dblp = dbenv->lg_handle; - db_rep = dbenv->rep_handle; - rep = db_rep->region; - lp = dblp->reginfo.primary; - ret = 0; - infop = dbenv->reginfo; - renv = infop->primary; - - /* - * Check if the savetime is different than our current time stamp. - * If it is, then we're racing with another thread trying to recover - * and we lost. We must give up. - */ - MUTEX_LOCK(dbenv, rep->mtx_clientdb); - done = savetime != renv->rep_timestamp; - if (done) { - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - return (0); - } - ZERO_LSN(lp->verify_lsn); - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - - /* - * Make sure the world hasn't changed while we tried to get - * the lock. If it hasn't then it's time for us to kick all - * operations out of DB and run recovery. - */ - REP_SYSTEM_LOCK(dbenv); - if (!F_ISSET(rep, REP_F_RECOVER_LOG) && - (F_ISSET(rep, REP_F_READY) || rep->in_recovery != 0)) { - rep->stat.st_msgs_recover++; - goto errunlock; - } - - if ((ret = __rep_lockout(dbenv, rep, 1)) != 0) - goto errunlock; - - /* OK, everyone is out, we can now run recovery. */ - REP_SYSTEM_UNLOCK(dbenv); - - if ((ret = __rep_dorecovery(dbenv, reclsnp, &trunclsn)) != 0) { - REP_SYSTEM_LOCK(dbenv); - rep->in_recovery = 0; - F_CLR(rep, REP_F_READY); - goto errunlock; - } - - /* - * The log has been truncated (either directly by us or by __db_apprec) - * We want to make sure we're waiting for the LSN at the new end-of-log, - * not some later point. - */ - MUTEX_LOCK(dbenv, rep->mtx_clientdb); - lp->ready_lsn = trunclsn; - ZERO_LSN(lp->waiting_lsn); - ZERO_LSN(lp->max_wait_lsn); - lp->max_perm_lsn = *reclsnp; - lp->wait_recs = 0; - lp->rcvd_recs = 0; - ZERO_LSN(lp->verify_lsn); - - /* - * Discard any log records we have queued; we're about to re-request - * them, and can't trust the ones in the queue. We need to set the - * DB_AM_RECOVER bit in this handle, so that the operation doesn't - * deadlock. - */ - F_SET(db_rep->rep_db, DB_AM_RECOVER); - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - ret = __db_truncate(db_rep->rep_db, NULL, &unused); - MUTEX_LOCK(dbenv, rep->mtx_clientdb); - F_CLR(db_rep->rep_db, DB_AM_RECOVER); - - REP_SYSTEM_LOCK(dbenv); - rep->stat.st_log_queued = 0; - rep->in_recovery = 0; - F_CLR(rep, REP_F_NOARCHIVE | REP_F_RECOVER_MASK); - - if (ret != 0) - goto errunlock2; - - /* - * If the master_id is invalid, this means that since - * the last record was sent, somebody declared an - * election and we may not have a master to request - * things of. - * - * This is not an error; when we find a new master, - * we'll re-negotiate where the end of the log is and - * try to bring ourselves up to date again anyway. - * - * !!! - * We cannot assert the election flags though because - * somebody may have declared an election and then - * got an error, thus clearing the election flags - * but we still have an invalid master_id. - */ - master = rep->master_id; - REP_SYSTEM_UNLOCK(dbenv); - if (master == DB_EID_INVALID) { - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - ret = 0; - } else { - /* - * We're making an ALL_REQ. But now that we've - * cleared the flags, we're likely receiving new - * log records from the master, resulting in a gap - * immediately. So to avoid multiple data streams, - * set the wait_recs value high now to give the master - * a chance to start sending us these records before - * the gap code re-requests the same gap. Wait_recs - * will get reset once we start receiving these - * records. - */ - lp->wait_recs = rep->max_gap; - MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); - (void)__rep_send_message(dbenv, - master, REP_ALL_REQ, reclsnp, NULL, 0, DB_REP_ANYWHERE); - } - if (0) { -errunlock2: MUTEX_UNLOCK(dbenv, rep->mtx_clientdb); -errunlock: REP_SYSTEM_UNLOCK(dbenv); - } - return (ret); -} - -/* - * __rep_log_backup -- - * - * In the verify handshake, we walk backward looking for - * identification records. Those are the only record types - * we verify and match on. - * - * PUBLIC: int __rep_log_backup __P((DB_LOGC *, DB_LSN *)); - */ -int -__rep_log_backup(logc, lsn) - DB_LOGC *logc; - DB_LSN *lsn; -{ - DBT mylog; - u_int32_t rectype; - int ret; - - ret = 0; - memset(&mylog, 0, sizeof(mylog)); - while ((ret = __log_c_get(logc, lsn, &mylog, DB_PREV)) == 0) { - /* - * Look at the record type. Only txn_regop and txn_ckp - * are interesting to us. - */ - memcpy(&rectype, mylog.data, sizeof(rectype)); - if (rectype == DB___txn_ckp || rectype == DB___txn_regop) - break; - } - return (ret); -} diff --git a/storage/bdb/sequence/seq_stat.c b/storage/bdb/sequence/seq_stat.c deleted file mode 100644 index aeea1dda28a..00000000000 --- a/storage/bdb/sequence/seq_stat.c +++ /dev/null @@ -1,280 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2004-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: seq_stat.c,v 12.6 2005/10/07 20:21:39 ubell Exp $ - */ - -#include "db_config.h" - -#ifdef HAVE_SEQUENCE -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stdlib.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_am.h" -#include "dbinc_auto/sequence_ext.h" - -#ifdef HAVE_STATISTICS -static int __seq_print_all __P((DB_SEQUENCE *, u_int32_t)); -static int __seq_print_stats __P((DB_SEQUENCE *, u_int32_t)); - -/* - * __seq_stat -- - * Get statistics from the sequence. - * - * PUBLIC: int __seq_stat __P((DB_SEQUENCE *, DB_SEQUENCE_STAT **, u_int32_t)); - */ -int -__seq_stat(seq, spp, flags) - DB_SEQUENCE *seq; - DB_SEQUENCE_STAT **spp; - u_int32_t flags; -{ - DB *dbp; - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - DB_SEQ_RECORD record; - DB_SEQUENCE_STAT *sp; - DBT data; - int handle_check, ret, t_ret; - - dbp = seq->seq_dbp; - dbenv = dbp->dbenv; - - switch (flags) { - case DB_STAT_CLEAR: - case DB_STAT_ALL: - case 0: - break; - default: - return (__db_ferr(dbenv, "DB_SEQUENCE->stat", 0)); - } - - ENV_ENTER(dbenv, ip); - - /* Check for replication block. */ - handle_check = IS_ENV_REPLICATED(dbenv); - if (handle_check && (ret = __db_rep_enter(dbp, 1, 0, 0)) != 0) { - handle_check = 0; - goto err; - } - - /* Allocate and clear the structure. */ - if ((ret = __os_umalloc(dbenv, sizeof(*sp), &sp)) != 0) - goto err; - memset(sp, 0, sizeof(*sp)); - - if (seq->mtx_seq != MUTEX_INVALID) { - __mutex_set_wait_info( - dbenv, seq->mtx_seq, &sp->st_wait, &sp->st_nowait); - - if (LF_ISSET(DB_STAT_CLEAR)) - __mutex_clear(dbenv, seq->mtx_seq); - } - memset(&data, 0, sizeof(data)); - data.data = &record; - data.ulen = sizeof(record); - data.flags = DB_DBT_USERMEM; -retry: if ((ret = __db_get(dbp, NULL, &seq->seq_key, &data, 0)) != 0) { - if (ret == DB_BUFFER_SMALL && - data.size > sizeof(seq->seq_record)) { - if ((ret = __os_malloc(dbenv, - data.size, &data.data)) != 0) - goto err; - data.ulen = data.size; - goto retry; - } - goto err; - } - - if (data.data != &record) - memcpy(&record, data.data, sizeof(record)); - sp->st_current = record.seq_value; - sp->st_value = seq->seq_record.seq_value; - sp->st_last_value = seq->seq_last_value; - sp->st_min = seq->seq_record.seq_min; - sp->st_max = seq->seq_record.seq_max; - sp->st_cache_size = seq->seq_cache_size; - sp->st_flags = seq->seq_record.flags; - - *spp = sp; - if (data.data != &record) - __os_free(dbenv, data.data); - - /* Release replication block. */ -err: if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __seq_stat_print -- - * Print statistics from the sequence. - * - * PUBLIC: int __seq_stat_print __P((DB_SEQUENCE *, u_int32_t)); - */ -int -__seq_stat_print(seq, flags) - DB_SEQUENCE *seq; - u_int32_t flags; -{ - DB *dbp; - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int handle_check, ret, t_ret; - - dbp = seq->seq_dbp; - dbenv = dbp->dbenv; - - ENV_ENTER(dbenv, ip); - - /* Check for replication block. */ - handle_check = IS_ENV_REPLICATED(dbenv); - if (handle_check && (ret = __db_rep_enter(dbp, 1, 0, 0)) != 0) { - handle_check = 0; - goto err; - } - - if ((ret = __seq_print_stats(seq, flags)) != 0) - goto err; - - if (LF_ISSET(DB_STAT_ALL) && - (ret = __seq_print_all(seq, flags)) != 0) - goto err; - - /* Release replication block. */ -err: if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - - ENV_LEAVE(dbenv, ip); - return (ret); - -} - -static const FN __db_seq_flags_fn[] = { - { DB_SEQ_DEC, "decrement" }, - { DB_SEQ_INC, "increment" }, - { DB_SEQ_RANGE_SET, "range set (internal)" }, - { DB_SEQ_WRAP, "wraparound at end" }, - { 0, NULL } -}; - -/* - * __db_get_seq_flags_fn -- - * Return the __db_seq_flags_fn array. - * - * PUBLIC: const FN * __db_get_seq_flags_fn __P((void)); - */ -const FN * -__db_get_seq_flags_fn() -{ - return (__db_seq_flags_fn); -} - -/* - * __seq_print_stats -- - * Display sequence stat structure. - */ -static int -__seq_print_stats(seq, flags) - DB_SEQUENCE *seq; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_SEQUENCE_STAT *sp; - int ret; - - dbenv = seq->seq_dbp->dbenv; - - if ((ret = __seq_stat(seq, &sp, flags)) != 0) - return (ret); - __db_dl_pct(dbenv, - "The number of sequence locks that required waiting", - (u_long)sp->st_wait, - DB_PCT(sp->st_wait, sp->st_wait + sp->st_nowait), NULL); - STAT_FMT("The current sequence value", - INT64_FMT, int64_t, sp->st_current); - STAT_FMT("The cached sequence value", - INT64_FMT, int64_t, sp->st_value); - STAT_FMT("The last cached sequence value", - INT64_FMT, int64_t, sp->st_last_value); - STAT_FMT("The minimum sequence value", - INT64_FMT, int64_t, sp->st_value); - STAT_FMT("The maximum sequence value", - INT64_FMT, int64_t, sp->st_value); - STAT_ULONG("The cache size", sp->st_cache_size); - __db_prflags(dbenv, NULL, - sp->st_flags, __db_seq_flags_fn, NULL, "\tSequence flags"); - __os_ufree(seq->seq_dbp->dbenv, sp); - return (0); -} - -/* - * __seq_print_all -- - * Display sequence debugging information - none for now. - * (The name seems a bit strange, no?) - */ -static int -__seq_print_all(seq, flags) - DB_SEQUENCE *seq; - u_int32_t flags; -{ - COMPQUIET(seq, NULL); - COMPQUIET(flags, 0); - return (0); -} - -#else /* !HAVE_STATISTICS */ - -int -__seq_stat(seq, statp, flags) - DB_SEQUENCE *seq; - DB_SEQUENCE_STAT **statp; - u_int32_t flags; -{ - COMPQUIET(statp, NULL); - COMPQUIET(flags, 0); - - return (__db_stat_not_built(seq->seq_dbp->dbenv)); -} - -int -__seq_stat_print(seq, flags) - DB_SEQUENCE *seq; - u_int32_t flags; -{ - COMPQUIET(flags, 0); - - return (__db_stat_not_built(seq->seq_dbp->dbenv)); -} - -/* - * __db_get_seq_flags_fn -- - * Return the __db_seq_flags_fn array. - * - * PUBLIC: const FN * __db_get_seq_flags_fn __P((void)); - */ -const FN * -__db_get_seq_flags_fn() -{ - static const FN __db_seq_flags_fn[] = { - { 0, NULL } - }; - - /* - * !!! - * The Tcl API uses this interface, stub it off. - */ - return (__db_seq_flags_fn); -} -#endif /* !HAVE_STATISTICS */ -#endif /* HAVE_SEQUENCE */ diff --git a/storage/bdb/sequence/sequence.c b/storage/bdb/sequence/sequence.c deleted file mode 100644 index 925b7f5b1be..00000000000 --- a/storage/bdb/sequence/sequence.c +++ /dev/null @@ -1,896 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2004-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: sequence.c,v 12.28 2005/10/24 19:22:00 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#ifdef HAVE_RPC -#include <rpc/rpc.h> -#endif - -#include <string.h> -#endif - -#ifdef HAVE_RPC -#include "db_server.h" -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/db_am.h" -#include "dbinc/lock.h" -#include "dbinc/mp.h" -#include "dbinc/txn.h" -#include "dbinc_auto/sequence_ext.h" - -#ifdef HAVE_RPC -#include "dbinc_auto/rpc_client_ext.h" -#endif - -#ifdef HAVE_SEQUENCE -#define SEQ_ILLEGAL_AFTER_OPEN(seq, name) \ - if (seq->seq_key.data != NULL) \ - return (__db_mi_open((seq)->seq_dbp->dbenv, name, 1)); - -#define SEQ_ILLEGAL_BEFORE_OPEN(seq, name) \ - if (seq->seq_key.data == NULL) \ - return (__db_mi_open((seq)->seq_dbp->dbenv, name, 0)); - -#define SEQ_IS_OPEN(seq) ((seq)->seq_key.data != NULL) - -/* - * Sequences must be architecture independent but they are stored as user - * data in databases so the code here must handle the byte ordering. We - * store them in little-endian byte ordering. If we are on a big-endian - * machine we swap in and out when we read from the database. seq->seq_rp - * always points to the record in native ordering. - * - * Version 1 always stored things in native format so if we detect this we - * upgrade on the fly and write the record back at open time. - */ -#define SEQ_SWAP(rp) \ - do { \ - M_32_SWAP((rp)->seq_version); \ - M_32_SWAP((rp)->flags); \ - M_64_SWAP((rp)->seq_value); \ - M_64_SWAP((rp)->seq_max); \ - M_64_SWAP((rp)->seq_min); \ - } while (0) - -#define SEQ_SWAP_IN(seq) \ - do { \ - if (__db_isbigendian()) { \ - memcpy(&seq->seq_record, seq->seq_data.data, \ - sizeof(seq->seq_record)); \ - SEQ_SWAP(&seq->seq_record); \ - } \ - } while (0) - -#define SEQ_SWAP_OUT(seq) \ - do { \ - if (__db_isbigendian()) { \ - memcpy(seq->seq_data.data, \ - &seq->seq_record, sizeof(seq->seq_record));\ - SEQ_SWAP((DB_SEQ_RECORD*)seq->seq_data.data); \ - } \ - } while (0) - -static int __seq_chk_cachesize __P((DB_ENV *, int32_t, db_seq_t, db_seq_t)); -static int __seq_close __P((DB_SEQUENCE *, u_int32_t)); -static int __seq_get - __P((DB_SEQUENCE *, DB_TXN *, int32_t, db_seq_t *, u_int32_t)); -static int __seq_get_cachesize __P((DB_SEQUENCE *, int32_t *)); -static int __seq_get_db __P((DB_SEQUENCE *, DB **)); -static int __seq_get_flags __P((DB_SEQUENCE *, u_int32_t *)); -static int __seq_get_key __P((DB_SEQUENCE *, DBT *)); -static int __seq_get_range __P((DB_SEQUENCE *, db_seq_t *, db_seq_t *)); -static int __seq_initial_value __P((DB_SEQUENCE *, db_seq_t)); -static int __seq_open_pp __P((DB_SEQUENCE *, DB_TXN *, DBT *, u_int32_t)); -static int __seq_remove __P((DB_SEQUENCE *, DB_TXN *, u_int32_t)); -static int __seq_set_cachesize __P((DB_SEQUENCE *, int32_t)); -static int __seq_set_flags __P((DB_SEQUENCE *, u_int32_t)); -static int __seq_set_range __P((DB_SEQUENCE *, db_seq_t, db_seq_t)); -static int __seq_update __P((DB_SEQUENCE *, DB_TXN *, int32_t, u_int32_t)); - -/* - * db_sequence_create -- - * DB_SEQUENCE constructor. - * - * EXTERN: int db_sequence_create __P((DB_SEQUENCE **, DB *, u_int32_t)); - */ -int -db_sequence_create(seqp, dbp, flags) - DB_SEQUENCE **seqp; - DB *dbp; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_SEQUENCE *seq; - int ret; - - dbenv = dbp->dbenv; - - DB_ILLEGAL_BEFORE_OPEN(dbp, "db_sequence_create"); -#ifdef HAVE_RPC - if (RPC_ON(dbenv)) - return (__dbcl_dbenv_illegal(dbenv)); -#endif - - /* Check for invalid function flags. */ - switch (flags) { - case 0: - break; - default: - return (__db_ferr(dbenv, "db_sequence_create", 0)); - } - - /* Allocate the sequence. */ - if ((ret = __os_calloc(dbenv, 1, sizeof(*seq), &seq)) != 0) - return (ret); - - seq->seq_dbp = dbp; - seq->close = __seq_close; - seq->get = __seq_get; - seq->get_cachesize = __seq_get_cachesize; - seq->set_cachesize = __seq_set_cachesize; - seq->get_db = __seq_get_db; - seq->get_flags = __seq_get_flags; - seq->get_key = __seq_get_key; - seq->get_range = __seq_get_range; - seq->initial_value = __seq_initial_value; - seq->open = __seq_open_pp; - seq->remove = __seq_remove; - seq->set_flags = __seq_set_flags; - seq->set_range = __seq_set_range; - seq->stat = __seq_stat; - seq->stat_print = __seq_stat_print; - seq->seq_rp = &seq->seq_record; - *seqp = seq; - - return (0); -} - -/* - * __seq_open -- - * DB_SEQUENCE->open method. - * - */ -static int -__seq_open_pp(seq, txn, keyp, flags) - DB_SEQUENCE *seq; - DB_TXN *txn; - DBT *keyp; - u_int32_t flags; -{ - DB *dbp; - DB_ENV *dbenv; - DB_SEQ_RECORD *rp; - DB_THREAD_INFO *ip; - u_int32_t tflags; - int handle_check, txn_local, ret, t_ret; -#define SEQ_OPEN_FLAGS (DB_CREATE | DB_EXCL | DB_THREAD) - - dbp = seq->seq_dbp; - dbenv = dbp->dbenv; - txn_local = 0; - - STRIP_AUTO_COMMIT(flags); - SEQ_ILLEGAL_AFTER_OPEN(seq, "DB_SEQUENCE->open"); - - ENV_ENTER(dbenv, ip); - - /* Check for replication block. */ - handle_check = IS_ENV_REPLICATED(dbenv); - if (handle_check && - (ret = __db_rep_enter(dbp, 1, 0, txn != NULL)) != 0) { - handle_check = 0; - goto err; - } - - if ((ret = __db_fchk(dbenv, - "DB_SEQUENCE->open", flags, SEQ_OPEN_FLAGS)) != 0) - goto err; - - if (keyp->size == 0) { - __db_err(dbenv, "Zero length sequence key specified"); - goto err; - } - - if ((ret = __db_get_flags(dbp, &tflags)) != 0) - goto err; - - if (FLD_ISSET(tflags, DB_DUP)) { - __db_err(dbenv, - "Sequences not supported in databases configured for duplicate data"); - goto err; - } - - if (LF_ISSET(DB_THREAD)) { - if (RPC_ON(dbenv)) { - __db_err(dbenv, - "DB_SEQUENCE->open: DB_THREAD not supported with RPC"); - goto err; - } - if ((ret = __mutex_alloc(dbenv, - MTX_SEQUENCE, DB_MUTEX_THREAD, &seq->mtx_seq)) != 0) - goto err; - } - - memset(&seq->seq_data, 0, sizeof(DBT)); - if (__db_isbigendian()) { - if ((ret = __os_umalloc(dbenv, - sizeof(seq->seq_record), &seq->seq_data.data)) != 0) - goto err; - seq->seq_data.flags = DB_DBT_REALLOC; - } else { - seq->seq_data.data = &seq->seq_record; - seq->seq_data.flags = DB_DBT_USERMEM; - } - - seq->seq_data.ulen = seq->seq_data.size = sizeof(seq->seq_record); - seq->seq_rp = &seq->seq_record; - - memset(&seq->seq_key, 0, sizeof(DBT)); - if ((ret = __os_malloc(dbenv, keyp->size, &seq->seq_key.data)) != 0) - goto err; - memcpy(seq->seq_key.data, keyp->data, keyp->size); - seq->seq_key.size = seq->seq_key.ulen = keyp->size; - seq->seq_key.flags = DB_DBT_USERMEM; - -retry: if ((ret = __db_get(dbp, txn, &seq->seq_key, &seq->seq_data, 0)) != 0) { - if (ret == DB_BUFFER_SMALL && - seq->seq_data.size > sizeof(seq->seq_record)) { - seq->seq_data.flags = DB_DBT_REALLOC; - seq->seq_data.data = NULL; - goto retry; - } - if ((ret != DB_NOTFOUND && ret != DB_KEYEMPTY) || - !LF_ISSET(DB_CREATE)) - goto err; - ret = 0; - - rp = &seq->seq_record; - if (!F_ISSET(rp, DB_SEQ_RANGE_SET)) { - rp->seq_max = INT64_MAX; - rp->seq_min = INT64_MIN; - } - /* INC is the default. */ - if (!F_ISSET(rp, DB_SEQ_DEC)) - F_SET(rp, DB_SEQ_INC); - - rp->seq_version = DB_SEQUENCE_VERSION; - - if (rp->seq_value > rp->seq_max || - rp->seq_value < rp->seq_min) { - __db_err(dbenv, "Sequence value out of range"); - ret = EINVAL; - goto err; - } else { - SEQ_SWAP_OUT(seq); - if ((ret = __db_put(dbp, txn, &seq->seq_key, - &seq->seq_data, DB_NOOVERWRITE)) != 0) { - __db_err(dbenv, "Sequence create failed"); - goto err; - } - } - } else if (LF_ISSET(DB_CREATE) && LF_ISSET(DB_EXCL)) { - ret = EEXIST; - goto err; - } else if (seq->seq_data.size < sizeof(seq->seq_record)) { - __db_err(dbenv, "Bad sequence record format"); - ret = EINVAL; - goto err; - } - - if (!__db_isbigendian()) - seq->seq_rp = seq->seq_data.data; - - /* - * The first release was stored in native mode. - * Check the version number before swapping. - */ - rp = seq->seq_data.data; - if (rp->seq_version == DB_SEQUENCE_OLDVER) { -oldver: rp->seq_version = DB_SEQUENCE_VERSION; - if (__db_isbigendian()) { - if (IS_DB_AUTO_COMMIT(dbp, txn)) { - if ((ret = - __txn_begin(dbenv, NULL, &txn, 0)) != 0) - goto err; - txn_local = 1; - goto retry; - } - memcpy(&seq->seq_record, rp, sizeof(seq->seq_record)); - SEQ_SWAP_OUT(seq); - } - if ((ret = __db_put(dbp, - txn, &seq->seq_key, &seq->seq_data, 0)) != 0) - goto err; - } - rp = seq->seq_rp; - - SEQ_SWAP_IN(seq); - - if (rp->seq_version != DB_SEQUENCE_VERSION) { - /* - * The database may have moved from one type - * of machine to another, check here. - * If we moved from little-end to big-end then - * the swap above will make the version correct. - * If the move was from big to little - * then we need to swap to see if this - * is an old version. - */ - if (rp->seq_version == DB_SEQUENCE_OLDVER) - goto oldver; - M_32_SWAP(rp->seq_version); - if (rp->seq_version == DB_SEQUENCE_OLDVER) { - SEQ_SWAP(rp); - goto oldver; - } - M_32_SWAP(rp->seq_version); - __db_err(dbenv, - "Unsupported sequence version: %d", rp->seq_version); - goto err; - } - - seq->seq_last_value = rp->seq_value; - if (F_ISSET(rp, DB_SEQ_INC)) - seq->seq_last_value--; - else - seq->seq_last_value++; - - /* - * It's an error to specify a cache larger than the range of sequences. - */ - if (seq->seq_cache_size != 0 && (ret = __seq_chk_cachesize( - dbenv, seq->seq_cache_size, rp->seq_max, rp->seq_min)) != 0) - goto err; - -err: if (txn_local && - (t_ret = __db_txn_auto_resolve(dbenv, txn, 0, ret)) && ret == 0) - ret = t_ret; - if (ret != 0) { - __os_free(dbenv, seq->seq_key.data); - seq->seq_key.data = NULL; - } - /* Release replication block. */ - if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __seq_get_cachesize -- - * Accessor for value passed into DB_SEQUENCE->set_cachesize call. - * - */ -static int -__seq_get_cachesize(seq, cachesize) - DB_SEQUENCE *seq; - int32_t *cachesize; -{ - SEQ_ILLEGAL_BEFORE_OPEN(seq, "DB_SEQUENCE->get_cachesize"); - - *cachesize = seq->seq_cache_size; - return (0); -} - -/* - * __seq_set_cachesize -- - * DB_SEQUENCE->set_cachesize. - * - */ -static int -__seq_set_cachesize(seq, cachesize) - DB_SEQUENCE *seq; - int32_t cachesize; -{ - DB_ENV *dbenv; - int ret; - - dbenv = seq->seq_dbp->dbenv; - - if (cachesize < 0) { - __db_err(dbenv, "Cache size must be >= 0"); - return (EINVAL); - } - - /* - * It's an error to specify a cache larger than the range of sequences. - */ - if (SEQ_IS_OPEN(seq) && (ret = __seq_chk_cachesize(dbenv, - cachesize, seq->seq_rp->seq_max, seq->seq_rp->seq_min)) != 0) - return (ret); - - seq->seq_cache_size = cachesize; - return (0); -} - -#define SEQ_SET_FLAGS (DB_SEQ_WRAP | DB_SEQ_INC | DB_SEQ_DEC) -/* - * __seq_get_flags -- - * Accessor for flags passed into DB_SEQUENCE->open call - * - */ -static int -__seq_get_flags(seq, flagsp) - DB_SEQUENCE *seq; - u_int32_t *flagsp; -{ - SEQ_ILLEGAL_BEFORE_OPEN(seq, "DB_SEQUENCE->get_flags"); - - *flagsp = F_ISSET(seq->seq_rp, SEQ_SET_FLAGS); - return (0); -} - -/* - * __seq_set_flags -- - * DB_SEQUENCE->set_flags. - * - */ -static int -__seq_set_flags(seq, flags) - DB_SEQUENCE *seq; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_SEQ_RECORD *rp; - int ret; - - dbenv = seq->seq_dbp->dbenv; - rp = seq->seq_rp; - - SEQ_ILLEGAL_AFTER_OPEN(seq, "DB_SEQUENCE->set_flags"); - - if ((ret = __db_fchk( - dbenv, "DB_SEQUENCE->set_flags", flags, SEQ_SET_FLAGS)) != 0) - return (ret); - if ((ret = __db_fcchk(dbenv, - "DB_SEQUENCE->set_flags", flags, DB_SEQ_DEC, DB_SEQ_INC)) != 0) - return (ret); - - if (LF_ISSET(DB_SEQ_DEC | DB_SEQ_INC)) - F_CLR(rp, DB_SEQ_DEC | DB_SEQ_INC); - F_SET(rp, flags); - - return (0); -} - -/* - * __seq_initial_value -- - * DB_SEQUENCE->initial_value. - * - */ -static int -__seq_initial_value(seq, value) - DB_SEQUENCE *seq; - db_seq_t value; -{ - DB_ENV *dbenv; - DB_SEQ_RECORD *rp; - - dbenv = seq->seq_dbp->dbenv; - SEQ_ILLEGAL_AFTER_OPEN(seq, "DB_SEQUENCE->initial_value"); - - rp = seq->seq_rp; - if (F_ISSET(rp, DB_SEQ_RANGE_SET) && - (value > rp->seq_max || value < rp->seq_min)) { - __db_err(dbenv, "Sequence value out of range"); - return (EINVAL); - } - - rp->seq_value = value; - - return (0); -} - -/* - * __seq_get_range -- - * Accessor for range passed into DB_SEQUENCE->set_range call - * - */ -static int -__seq_get_range(seq, minp, maxp) - DB_SEQUENCE *seq; - db_seq_t *minp, *maxp; -{ - SEQ_ILLEGAL_BEFORE_OPEN(seq, "DB_SEQUENCE->get_range"); - - *minp = seq->seq_rp->seq_min; - *maxp = seq->seq_rp->seq_max; - return (0); -} - -/* - * __seq_set_range -- - * SEQUENCE->set_range. - * - */ -static int -__seq_set_range(seq, min, max) - DB_SEQUENCE *seq; - db_seq_t min, max; -{ - DB_ENV *dbenv; - - dbenv = seq->seq_dbp->dbenv; - SEQ_ILLEGAL_AFTER_OPEN(seq, "DB_SEQUENCE->set_range"); - - if (min >= max) { - __db_err(dbenv, - "Minimum sequence value must be less than maximum sequence value"); - return (EINVAL); - } - - seq->seq_rp->seq_min = min; - seq->seq_rp->seq_max = max; - F_SET(seq->seq_rp, DB_SEQ_RANGE_SET); - - return (0); -} - -static int -__seq_update(seq, txn, delta, flags) - DB_SEQUENCE *seq; - DB_TXN *txn; - int32_t delta; - u_int32_t flags; -{ - DB *dbp; - DB_ENV *dbenv; - DB_SEQ_RECORD *rp; - int32_t adjust; - int ret, txn_local; - - dbp = seq->seq_dbp; - dbenv = dbp->dbenv; - - /* - * Create a local transaction as necessary, check for consistent - * transaction usage, and, if we have no transaction but do have - * locking on, acquire a locker id for the handle lock acquisition. - */ - if (IS_DB_AUTO_COMMIT(dbp, txn)) { - if ((ret = __txn_begin(dbenv, NULL, &txn, 0)) != 0) - return (ret); - txn_local = 1; - } else - txn_local = 0; - - /* Check for consistent transaction usage. */ - if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 0)) != 0) - goto err; - -retry: if ((ret = __db_get(dbp, txn, &seq->seq_key, &seq->seq_data, 0)) != 0) { - if (ret == DB_BUFFER_SMALL && - seq->seq_data.size > sizeof(seq->seq_record)) { - seq->seq_data.flags = DB_DBT_REALLOC; - seq->seq_data.data = NULL; - goto retry; - } - goto err; - } - - if (!__db_isbigendian()) - seq->seq_rp = seq->seq_data.data; - SEQ_SWAP_IN(seq); - rp = seq->seq_rp; - - if (F_ISSET(rp, DB_SEQ_WRAPPED)) - goto overflow; - - if (seq->seq_data.size < sizeof(seq->seq_record)) { - __db_err(dbenv, "Bad sequence record format"); - ret = EINVAL; - goto err; - } - - adjust = delta > seq->seq_cache_size ? delta : seq->seq_cache_size; - - /* - * Check whether this operation will cause the sequence to wrap. - * - * The sequence minimum and maximum values can be INT64_MIN and - * INT64_MAX, so we need to do the test carefully to cope with - * arithmetic overflow. The first part of the test below checks - * whether we will hit the end of the 64-bit range. The second part - * checks whether we hit the end of the sequence. - */ -again: if (F_ISSET(rp, DB_SEQ_INC)) { - if (rp->seq_value + adjust - 1 < rp->seq_value || - rp->seq_value + adjust - 1 > rp->seq_max) { - /* Don't wrap just to fill the cache. */ - if (adjust > delta) { - adjust = delta; - goto again; - } - if (F_ISSET(rp, DB_SEQ_WRAP)) - rp->seq_value = rp->seq_min; - else { -overflow: __db_err(dbenv, "Sequence overflow"); - ret = EINVAL; - goto err; - } - } - /* See if we are at the end of the 64 bit range. */ - if (!F_ISSET(rp, DB_SEQ_WRAP) && - rp->seq_value + adjust < rp->seq_value) - F_SET(rp, DB_SEQ_WRAPPED); - } else { - if ((rp->seq_value - adjust) + 1 > rp->seq_value || - (rp->seq_value - adjust) + 1 < rp->seq_min) { - /* Don't wrap just to fill the cache. */ - if (adjust > delta) { - adjust = delta; - goto again; - } - if (F_ISSET(rp, DB_SEQ_WRAP)) - rp->seq_value = rp->seq_max; - else - goto overflow; - } - /* See if we are at the end of the 64 bit range. */ - if (!F_ISSET(rp, DB_SEQ_WRAP) && - rp->seq_value - adjust > rp->seq_value) - F_SET(rp, DB_SEQ_WRAPPED); - adjust = -adjust; - } - - rp->seq_value += adjust; - SEQ_SWAP_OUT(seq); - ret = __db_put(dbp, txn, &seq->seq_key, &seq->seq_data, 0); - rp->seq_value -= adjust; - if (ret != 0) { - __db_err(dbenv, "Sequence update failed"); - goto err; - } - seq->seq_last_value = rp->seq_value + adjust; - if (F_ISSET(rp, DB_SEQ_INC)) - seq->seq_last_value--; - else - seq->seq_last_value++; - -err: return (txn_local ? __db_txn_auto_resolve( - dbenv, txn, LF_ISSET(DB_TXN_NOSYNC), ret) : ret); -} - -static int -__seq_get(seq, txn, delta, retp, flags) - DB_SEQUENCE *seq; - DB_TXN *txn; - int32_t delta; - db_seq_t *retp; - u_int32_t flags; -{ - DB *dbp; - DB_ENV *dbenv; - DB_SEQ_RECORD *rp; - DB_THREAD_INFO *ip; - int handle_check, ret, t_ret; - - dbp = seq->seq_dbp; - dbenv = dbp->dbenv; - rp = seq->seq_rp; - ret = 0; - - STRIP_AUTO_COMMIT(flags); - SEQ_ILLEGAL_BEFORE_OPEN(seq, "DB_SEQUENCE->get"); - - if (delta <= 0) { - __db_err(dbenv, "Sequence delta must be greater than 0"); - return (EINVAL); - } - - if (seq->seq_cache_size != 0 && txn != NULL) { - __db_err(dbenv, - "Sequence with non-zero cache may not specify transaction handle"); - return (EINVAL); - } - - ENV_ENTER(dbenv, ip); - - /* Check for replication block. */ - handle_check = IS_ENV_REPLICATED(dbenv); - if (handle_check && (ret = __db_rep_enter(dbp, 1, 0, txn != NULL)) != 0) - return (ret); - - MUTEX_LOCK(dbenv, seq->mtx_seq); - - if (rp->seq_min + delta > rp->seq_max) { - __db_err(dbenv, "Sequence overflow"); - ret = EINVAL; - goto err; - } - - if (F_ISSET(rp, DB_SEQ_INC)) { - if (seq->seq_last_value + 1 - rp->seq_value < delta && - (ret = __seq_update(seq, txn, delta, flags)) != 0) - goto err; - - rp = seq->seq_rp; - *retp = rp->seq_value; - rp->seq_value += delta; - } else { - if ((rp->seq_value - seq->seq_last_value) + 1 < delta && - (ret = __seq_update(seq, txn, delta, flags)) != 0) - goto err; - - rp = seq->seq_rp; - *retp = rp->seq_value; - rp->seq_value -= delta; - } - -err: MUTEX_UNLOCK(dbenv, seq->mtx_seq); - - /* Release replication block. */ - if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __seq_get_db -- - * Accessor for dbp passed into DB_SEQUENCE->open call - * - */ -static int -__seq_get_db(seq, dbpp) - DB_SEQUENCE *seq; - DB **dbpp; -{ - SEQ_ILLEGAL_BEFORE_OPEN(seq, "DB_SEQUENCE->get_db"); - - *dbpp = seq->seq_dbp; - return (0); -} - -/* - * __seq_get_key -- - * Accessor for key passed into DB_SEQUENCE->open call - * - */ -static int -__seq_get_key(seq, key) - DB_SEQUENCE *seq; - DBT *key; -{ - SEQ_ILLEGAL_BEFORE_OPEN(seq, "DB_SEQUENCE->get_key"); - - key->data = seq->seq_key.data; - key->size = key->ulen = seq->seq_key.size; - key->flags = seq->seq_key.flags; - return (0); -} - -/* - * __seq_close -- - * Close a sequence - * - */ -static int -__seq_close(seq, flags) - DB_SEQUENCE *seq; - u_int32_t flags; -{ - DB_ENV *dbenv; - int ret, t_ret; - - ret = 0; - dbenv = seq->seq_dbp->dbenv; - - if (flags != 0) - ret = __db_ferr(dbenv, "DB_SEQUENCE->close", 0); - - if ((t_ret = __mutex_free(dbenv, &seq->mtx_seq)) != 0 && ret == 0) - ret = t_ret; - - if (seq->seq_key.data != NULL) - __os_free(dbenv, seq->seq_key.data); - if (seq->seq_data.data != NULL && - seq->seq_data.data != &seq->seq_record) - __os_ufree(dbenv, seq->seq_data.data); - seq->seq_key.data = NULL; - - memset(seq, CLEAR_BYTE, sizeof(*seq)); - __os_free(dbenv, seq); - - return (ret); -} - -/* - * __seq_remove -- - * Remove a sequence from the database. - */ -static int -__seq_remove(seq, txn, flags) - DB_SEQUENCE *seq; - DB_TXN *txn; - u_int32_t flags; -{ - DB *dbp; - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int handle_check, ret, t_ret; - - dbp = seq->seq_dbp; - dbenv = dbp->dbenv; - - SEQ_ILLEGAL_BEFORE_OPEN(seq, "DB_SEQUENCE->remove"); - ENV_ENTER(dbenv, ip); - - /* Check for replication block. */ - handle_check = IS_ENV_REPLICATED(dbenv); - if (handle_check && - (ret = __db_rep_enter(dbp, 1, 0, txn != NULL)) != 0) { - handle_check = 0; - goto err; - } - if (flags != 0) - ret = __db_ferr(dbenv, "DB_SEQUENCE->remove", 0); - - ret = __db_del(dbp, txn, &seq->seq_key, 0); - - if ((t_ret = __seq_close(seq, 0)) != 0 && ret == 0) - ret = t_ret; - - /* Release replication block. */ - if (handle_check && (t_ret = __env_db_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; -err: ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __seq_chk_cachesize -- - * Validate the cache size vs. the range. - */ -static int -__seq_chk_cachesize(dbenv, cachesize, max, min) - DB_ENV *dbenv; - int32_t cachesize; - db_seq_t max, min; -{ - /* - * It's an error to specify caches larger than the sequence range. - * - * The min and max of the range can be either positive or negative, - * the difference will fit in an unsigned variable of the same type. - * Assume a 2's complement machine, and simply subtract. - */ - if ((u_int32_t)cachesize > (u_int64_t)max - (u_int64_t)min) { - __db_err(dbenv, - "Number of items to be cached is larger than the sequence range"); - return (EINVAL); - } - return (0); -} - -#else /* !HAVE_SEQUENCE */ - -int -db_sequence_create(seqp, dbp, flags) - DB_SEQUENCE **seqp; - DB *dbp; - u_int32_t flags; -{ - COMPQUIET(seqp, NULL); - COMPQUIET(flags, 0); - __db_err(dbp->dbenv, - "library build did not include support for sequences"); - return (DB_OPNOTSUP); -} -#endif /* HAVE_SEQUENCE */ diff --git a/storage/bdb/txn/txn.c b/storage/bdb/txn/txn.c deleted file mode 100644 index 68ed2e6c28c..00000000000 --- a/storage/bdb/txn/txn.c +++ /dev/null @@ -1,1621 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1995, 1996 - * The President and Fellows of Harvard University. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Margo Seltzer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: txn.c,v 12.34 2005/11/01 00:44:35 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#include <stdlib.h> - -#if TIME_WITH_SYS_TIME -#include <sys/time.h> -#include <time.h> -#else -#if HAVE_SYS_TIME_H -#include <sys/time.h> -#else -#include <time.h> -#endif -#endif - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/crypto.h" -#include "dbinc/hmac.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/hash.h" -#include "dbinc/lock.h" -#include "dbinc/log.h" -#include "dbinc/txn.h" - -#define SET_LOG_FLAGS(dbenv, txn, lflags) \ - do { \ - lflags = DB_LOG_COMMIT | DB_LOG_PERM; \ - if (F_ISSET(txn, TXN_SYNC)) \ - lflags |= DB_FLUSH; \ - else if (F_ISSET(txn, TXN_WRITE_NOSYNC)) \ - lflags |= DB_LOG_WRNOSYNC; \ - else if (!F_ISSET(txn, TXN_NOSYNC) && \ - !F_ISSET(dbenv, DB_ENV_TXN_NOSYNC)) { \ - if (F_ISSET(dbenv, DB_ENV_TXN_WRITE_NOSYNC)) \ - lflags |= DB_LOG_WRNOSYNC; \ - else \ - lflags |= DB_FLUSH; \ - } \ - } while (0) - -/* - * __txn_isvalid enumerated types. We cannot simply use the transaction - * statuses, because different statuses need to be handled differently - * depending on the caller. - */ -typedef enum { - TXN_OP_ABORT, - TXN_OP_COMMIT, - TXN_OP_DISCARD, - TXN_OP_PREPARE -} txnop_t; - -static int __txn_abort_pp __P((DB_TXN *)); -static int __txn_begin_int __P((DB_TXN *, int)); -static int __txn_commit_pp __P((DB_TXN *, u_int32_t)); -static int __txn_discard __P((DB_TXN *, u_int32_t)); -static int __txn_dispatch_undo - __P((DB_ENV *, DB_TXN *, DBT *, DB_LSN *, void *)); -static int __txn_end __P((DB_TXN *, int)); -static int __txn_isvalid __P((const DB_TXN *, txnop_t)); -static int __txn_undo __P((DB_TXN *)); -static void __txn_set_txn_lsnp __P((DB_TXN *, DB_LSN **, DB_LSN **)); - -/* - * __txn_begin_pp -- - * DB_ENV->txn_begin pre/post processing. - * - * PUBLIC: int __txn_begin_pp __P((DB_ENV *, DB_TXN *, DB_TXN **, u_int32_t)); - */ -int -__txn_begin_pp(dbenv, parent, txnpp, flags) - DB_ENV *dbenv; - DB_TXN *parent, **txnpp; - u_int32_t flags; -{ - DB_THREAD_INFO *ip; - int rep_check, ret; - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, dbenv->tx_handle, "txn_begin", DB_INIT_TXN); - - if ((ret = __db_fchk(dbenv, - "txn_begin", flags, - DB_READ_COMMITTED | DB_READ_UNCOMMITTED | DB_TXN_NOWAIT | - DB_TXN_NOSYNC | DB_TXN_SYNC | DB_TXN_WRITE_NOSYNC)) != 0) - return (ret); - if ((ret = __db_fcchk(dbenv, "txn_begin", flags, - DB_TXN_WRITE_NOSYNC | DB_TXN_NOSYNC, DB_TXN_SYNC)) != 0) - return (ret); - if ((ret = __db_fcchk(dbenv, "txn_begin", - flags, DB_TXN_WRITE_NOSYNC, DB_TXN_NOSYNC)) != 0) - return (ret); - - ENV_ENTER(dbenv, ip); - - if (parent == NULL) { - rep_check = IS_ENV_REPLICATED(dbenv) ? 1 : 0; - if (rep_check && (ret = __op_rep_enter(dbenv)) != 0) - goto err; - } else - rep_check = 0; - ret = __txn_begin(dbenv, parent, txnpp, flags); - /* - * We only decrement the count if the operation fails. - * Otherwise the count will be decremented when the - * txn is resolved by txn_commit, txn_abort, etc. - */ - if (ret != 0 && rep_check) - (void)__op_rep_exit(dbenv); - -err: ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __txn_begin -- - * DB_ENV->txn_begin. - * - * This is a wrapper to the actual begin process. Normal transaction begin - * allocates a DB_TXN structure for the caller, while XA transaction begin - * does not. Other than that, both call into common __txn_begin_int code. - * - * Internally, we use TXN_DETAIL structures, but the DB_TXN structure - * provides access to the transaction ID and the offset in the transaction - * region of the TXN_DETAIL structure. - * - * PUBLIC: int __txn_begin __P((DB_ENV *, DB_TXN *, DB_TXN **, u_int32_t)); - */ -int -__txn_begin(dbenv, parent, txnpp, flags) - DB_ENV *dbenv; - DB_TXN *parent, **txnpp; - u_int32_t flags; -{ - DB_LOCKREGION *region; - DB_TXN *txn; - TXN_DETAIL *ptd, *td; - int ret; - - *txnpp = NULL; - if ((ret = __os_calloc(dbenv, 1, sizeof(DB_TXN), &txn)) != 0) - return (ret); - - txn->mgrp = dbenv->tx_handle; - txn->parent = parent; - TAILQ_INIT(&txn->kids); - TAILQ_INIT(&txn->events); - STAILQ_INIT(&txn->logs); - txn->flags = TXN_MALLOC; - if (LF_ISSET(DB_READ_COMMITTED)) - F_SET(txn, TXN_READ_COMMITTED); - if (LF_ISSET(DB_READ_UNCOMMITTED)) - F_SET(txn, TXN_READ_UNCOMMITTED); - if (LF_ISSET(DB_TXN_NOSYNC)) - F_SET(txn, TXN_NOSYNC); - if (LF_ISSET(DB_TXN_SYNC)) - F_SET(txn, TXN_SYNC); - if (LF_ISSET(DB_TXN_NOWAIT)) - F_SET(txn, TXN_NOWAIT); - if (LF_ISSET(DB_TXN_WRITE_NOSYNC)) - F_SET(txn, TXN_WRITE_NOSYNC); - - if ((ret = __txn_begin_int(txn, 0)) != 0) - goto err; - td = txn->td; - - if (parent != NULL) { - ptd = parent->td; - TAILQ_INSERT_HEAD(&parent->kids, txn, klinks); - SH_TAILQ_INSERT_HEAD(&ptd->kids, td, klinks, __txn_detail); - } - - if (LOCKING_ON(dbenv)) { - region = ((DB_LOCKTAB *)dbenv->lk_handle)->reginfo.primary; - if (parent != NULL) { - ret = __lock_inherit_timeout(dbenv, - parent->txnid, txn->txnid); - /* No parent locker set yet. */ - if (ret == EINVAL) { - parent = NULL; - ret = 0; - } - if (ret != 0) - goto err; - } - - /* - * Parent is NULL if we have no parent - * or it has no timeouts set. - */ - if (parent == NULL && region->tx_timeout != 0) - if ((ret = __lock_set_timeout(dbenv, txn->txnid, - region->tx_timeout, DB_SET_TXN_TIMEOUT)) != 0) - goto err; - } - - *txnpp = txn; - return (0); - -err: - __os_free(dbenv, txn); - return (ret); -} - -/* - * __txn_xa_begin -- - * XA version of txn_begin. - * - * PUBLIC: int __txn_xa_begin __P((DB_ENV *, DB_TXN *)); - */ -int -__txn_xa_begin(dbenv, txn) - DB_ENV *dbenv; - DB_TXN *txn; -{ - PANIC_CHECK(dbenv); - - /* - * We need to initialize the transaction structure, but must be careful - * not to smash the links. We manually initialize the structure. - */ - txn->mgrp = dbenv->tx_handle; - TAILQ_INIT(&txn->kids); - TAILQ_INIT(&txn->events); - STAILQ_INIT(&txn->logs); - txn->parent = NULL; - txn->txnid = TXN_INVALID; - txn->cursors = 0; - memset(&txn->lock_timeout, 0, sizeof(db_timeout_t)); - memset(&txn->expire, 0, sizeof(db_timeout_t)); - - return (__txn_begin_int(txn, 0)); -} - -/* - * __txn_recycle_id -- - * Find a range of useable transaction ids. - * - * PUBLIC: int __txn_recycle_id __P((DB_ENV *)); - */ -int -__txn_recycle_id(dbenv) - DB_ENV *dbenv; -{ - DB_LSN null_lsn; - DB_TXNMGR *mgr; - DB_TXNREGION *region; - TXN_DETAIL *td; - u_int32_t *ids; - int nids, ret; - - mgr = dbenv->tx_handle; - region = mgr->reginfo.primary; - - if ((ret = __os_malloc(dbenv, - sizeof(u_int32_t) * region->maxtxns, &ids)) != 0) - return (ret); - nids = 0; - for (td = SH_TAILQ_FIRST(®ion->active_txn, __txn_detail); - td != NULL; - td = SH_TAILQ_NEXT(td, links, __txn_detail)) - ids[nids++] = td->txnid; - region->last_txnid = TXN_MINIMUM - 1; - region->cur_maxid = TXN_MAXIMUM; - if (nids != 0) - __db_idspace(ids, nids, - ®ion->last_txnid, ®ion->cur_maxid); - __os_free(dbenv, ids); - /* - * Check LOGGING_ON rather than DBENV_LOGGING as - * we want to emit this record at the end of recovery. - */ - if (LOGGING_ON(dbenv)) - ret = __txn_recycle_log(dbenv, NULL, &null_lsn, - 0, region->last_txnid + 1, region->cur_maxid); - - return (ret); -} - -/* - * __txn_compensate_begin - * Begin an compensation transaction. This is a special interface - * that is used only for transactions that must be started to compensate - * for actions during an abort. Currently only used for allocations. - * - * PUBLIC: int __txn_compensate_begin __P((DB_ENV *, DB_TXN **)); - */ -int -__txn_compensate_begin(dbenv, txnpp) - DB_ENV *dbenv; - DB_TXN **txnpp; -{ - DB_TXN *txn; - int ret; - - PANIC_CHECK(dbenv); - - if ((ret = __os_calloc(dbenv, 1, sizeof(DB_TXN), &txn)) != 0) - return (ret); - - txn->mgrp = dbenv->tx_handle; - TAILQ_INIT(&txn->kids); - TAILQ_INIT(&txn->events); - STAILQ_INIT(&txn->logs); - txn->flags = TXN_COMPENSATE | TXN_MALLOC; - - *txnpp = txn; - return (__txn_begin_int(txn, 1)); -} - -/* - * __txn_begin_int -- - * Normal DB version of txn_begin. - */ -static int -__txn_begin_int(txn, internal) - DB_TXN *txn; - int internal; -{ - DB_ENV *dbenv; - DB_TXNMGR *mgr; - DB_TXNREGION *region; - TXN_DETAIL *td; - u_int32_t id; - int ret; - - mgr = txn->mgrp; - dbenv = mgr->dbenv; - region = mgr->reginfo.primary; - - TXN_SYSTEM_LOCK(dbenv); - if (!F_ISSET(txn, TXN_COMPENSATE) && F_ISSET(region, TXN_IN_RECOVERY)) { - __db_err(dbenv, "operation not permitted during recovery"); - ret = EINVAL; - goto err; - } - - /* Make sure that we aren't still recovering prepared transactions. */ - if (!internal && region->stat.st_nrestores != 0) { - __db_err(dbenv, - "recovery of prepared but not yet committed transactions is incomplete"); - ret = EINVAL; - goto err; - } - - /* - * Allocate a new transaction id. Our current valid range can span - * the maximum valid value, so check for it and wrap manually. - */ - if (region->last_txnid == TXN_MAXIMUM && - region->cur_maxid != TXN_MAXIMUM) - region->last_txnid = TXN_MINIMUM - 1; - - if (region->last_txnid == region->cur_maxid && - (ret = __txn_recycle_id(dbenv)) != 0) - goto err; - - /* Allocate a new transaction detail structure. */ - if ((ret = - __db_shalloc(&mgr->reginfo, sizeof(TXN_DETAIL), 0, &td)) != 0) { - __db_err(dbenv, - "Unable to allocate memory for transaction detail"); - goto err; - } - - /* Place transaction on active transaction list. */ - SH_TAILQ_INSERT_HEAD(®ion->active_txn, td, links, __txn_detail); - - id = ++region->last_txnid; - ++region->stat.st_nbegins; - if (++region->stat.st_nactive > region->stat.st_maxnactive) - region->stat.st_maxnactive = region->stat.st_nactive; - - td->txnid = id; - dbenv->thread_id(dbenv, &td->pid, &td->tid); - ZERO_LSN(td->last_lsn); - ZERO_LSN(td->begin_lsn); - SH_TAILQ_INIT(&td->kids); - if (txn->parent != NULL) - td->parent = R_OFFSET(&mgr->reginfo, txn->parent->td); - else - td->parent = INVALID_ROFF; - td->name = INVALID_ROFF; - td->status = TXN_RUNNING; - td->flags = 0; - td->xa_status = 0; - - TXN_SYSTEM_UNLOCK(dbenv); - - txn->txnid = id; - txn->td = td; - - txn->abort = __txn_abort_pp; - txn->commit = __txn_commit_pp; - txn->discard = __txn_discard; - txn->get_name = __txn_get_name; - txn->id = __txn_id; - txn->prepare = __txn_prepare; - txn->set_txn_lsnp = __txn_set_txn_lsnp; - txn->set_name = __txn_set_name; - txn->set_timeout = __txn_set_timeout; - - /* - * If this is a transaction family, we must link the child to the - * maximal grandparent in the lock table for deadlock detection. - */ - if (txn->parent != NULL && LOCKING_ON(dbenv)) - if ((ret = __lock_addfamilylocker(dbenv, - txn->parent->txnid, txn->txnid)) != 0) - return (ret); - - if (F_ISSET(txn, TXN_MALLOC)) { - MUTEX_LOCK(dbenv, mgr->mutex); - TAILQ_INSERT_TAIL(&mgr->txn_chain, txn, links); - MUTEX_UNLOCK(dbenv, mgr->mutex); - } - - return (0); - -err: TXN_SYSTEM_UNLOCK(dbenv); - return (ret); -} - -/* - * __txn_continue - * Fill in the fields of the local transaction structure given - * the detail transaction structure. - * - * PUBLIC: void __txn_continue __P((DB_ENV *, DB_TXN *, TXN_DETAIL *)); - */ -void -__txn_continue(env, txn, td) - DB_ENV *env; - DB_TXN *txn; - TXN_DETAIL *td; -{ - txn->mgrp = env->tx_handle; - txn->parent = NULL; - txn->txnid = td->txnid; - txn->td = td; - - txn->abort = __txn_abort_pp; - txn->commit = __txn_commit_pp; - txn->discard = __txn_discard; - txn->get_name = __txn_get_name; - txn->id = __txn_id; - txn->prepare = __txn_prepare; - txn->set_name = __txn_set_name; - - txn->flags = 0; - if (F_ISSET(td, TXN_DTL_RESTORED)) - F_SET(txn, TXN_RESTORED); -} - -/* - * __txn_commit_pp -- - * Interface routine to TXN->commit. - */ -static int -__txn_commit_pp(txn, flags) - DB_TXN *txn; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int not_child, ret, t_ret; - - dbenv = txn->mgrp->dbenv; - not_child = txn->parent == NULL; - - ENV_ENTER(dbenv, ip); - - ret = __txn_commit(txn, flags); - if (not_child && IS_ENV_REPLICATED(dbenv) && - (t_ret = __op_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __txn_commit -- - * Commit a transaction. - * - * PUBLIC: int __txn_commit __P((DB_TXN *, u_int32_t)); - */ -int -__txn_commit(txn, flags) - DB_TXN *txn; - u_int32_t flags; -{ - DBT list_dbt; - DB_ENV *dbenv; - DB_LOCKREQ request; - DB_TXN *kid; - REGENV *renv; - REGINFO *infop; - TXN_DETAIL *td; - u_int32_t id, lflags; - int ret, t_ret; - - dbenv = txn->mgrp->dbenv; - td = txn->td; - - PANIC_CHECK(dbenv); - - if ((ret = __txn_isvalid(txn, TXN_OP_COMMIT)) != 0) - return (ret); - - infop = dbenv->reginfo; - renv = infop->primary; - /* - * No mutex is needed as envid is read-only once it is set. - */ - id = renv->envid; - - /* - * We clear flags that are incorrect, ignoring any flag errors, and - * default to synchronous operations. By definition, transaction - * handles are dead when we return, and this error should never - * happen, but we don't want to fail in the field 'cause the app is - * specifying the wrong flag for some reason. - */ - if (__db_fchk(dbenv, "DB_TXN->commit", flags, - DB_TXN_NOSYNC | DB_TXN_SYNC | DB_TXN_WRITE_NOSYNC) != 0) - flags = DB_TXN_SYNC; - if (__db_fcchk(dbenv, "DB_TXN->commit", flags, - DB_TXN_SYNC, DB_TXN_NOSYNC | DB_TXN_WRITE_NOSYNC) != 0) - flags = DB_TXN_SYNC; - - if (LF_ISSET(DB_TXN_WRITE_NOSYNC)) { - F_CLR(txn, TXN_SYNC_FLAGS); - F_SET(txn, TXN_WRITE_NOSYNC); - } - if (LF_ISSET(DB_TXN_NOSYNC)) { - F_CLR(txn, TXN_SYNC_FLAGS); - F_SET(txn, TXN_NOSYNC); - } - if (LF_ISSET(DB_TXN_SYNC)) { - F_CLR(txn, TXN_SYNC_FLAGS); - F_SET(txn, TXN_SYNC); - } - - /* - * Commit any unresolved children. If anyone fails to commit, - * then try to abort the rest of the kids and then abort the parent. - * Abort should never fail; if it does, we bail out immediately. - */ - while ((kid = TAILQ_FIRST(&txn->kids)) != NULL) - if ((ret = __txn_commit(kid, flags)) != 0) - while ((kid = TAILQ_FIRST(&txn->kids)) != NULL) - if ((t_ret = __txn_abort(kid)) != 0) - return (__db_panic(dbenv, t_ret)); - - /* - * If there are any log records, write a log record and sync the log, - * else do no log writes. If the commit is for a child transaction, - * we do not need to commit the child synchronously since it may still - * abort (if its parent aborts), and otherwise its parent or ultimate - * ancestor will write synchronously. - */ - if (DBENV_LOGGING(dbenv) && (!IS_ZERO_LSN(td->last_lsn) || - STAILQ_FIRST(&txn->logs) != NULL)) { - if (txn->parent == NULL) { - /* - * We are about to free all the read locks for this - * transaction below. Some of those locks might be - * handle locks which should not be freed, because - * they will be freed when the handle is closed. Check - * the events and preprocess any trades now so we don't - * release the locks below. - */ - if ((ret = - __txn_doevents(dbenv, txn, TXN_PREPARE, 1)) != 0) - goto err; - - memset(&request, 0, sizeof(request)); - if (LOCKING_ON(dbenv)) { - request.op = DB_LOCK_PUT_READ; - if (IS_REP_MASTER(dbenv) && - !IS_ZERO_LSN(td->last_lsn)) { - memset(&list_dbt, 0, sizeof(list_dbt)); - request.obj = &list_dbt; - } - ret = __lock_vec(dbenv, - txn->txnid, 0, &request, 1, NULL); - } - - if (ret == 0 && !IS_ZERO_LSN(td->last_lsn)) { - SET_LOG_FLAGS(dbenv, txn, lflags); - ret = __txn_regop_log(dbenv, txn, - &td->last_lsn, lflags, TXN_COMMIT, - (int32_t)time(NULL), id, request.obj); - } - - if (request.obj != NULL && request.obj->data != NULL) - __os_free(dbenv, request.obj->data); - if (ret != 0) - goto err; - } else { - /* Log the commit in the parent! */ - if (!IS_ZERO_LSN(td->last_lsn) && - (ret = __txn_child_log(dbenv, txn->parent, - &((TXN_DETAIL *)txn->parent->td)->last_lsn, - 0, txn->txnid, &td->last_lsn)) != 0) { - goto err; - } - if (STAILQ_FIRST(&txn->logs) != NULL) { - /* - * Put the child first so we back it out first. - * All records are undone in reverse order. - */ - STAILQ_CONCAT(&txn->logs, &txn->parent->logs); - txn->parent->logs = txn->logs; - STAILQ_INIT(&txn->logs); - } - - F_SET(txn->parent, TXN_CHILDCOMMIT); - } - } - - /* - * Process any aborted pages from our children. We delay putting pages - * on the free list that are newly allocated and then aborted so we can - * undo other allocations, if necessary, without worrying about these - * pages which were not on the free list before. - */ - if (txn->txn_list != NULL) { -#ifndef HAVE_FTRUNCATE - t_ret = __db_do_the_limbo(dbenv, - NULL, txn, txn->txn_list, LIMBO_NORMAL); - if (t_ret != 0 && ret == 0) - ret = t_ret; -#endif - __db_txnlist_end(dbenv, txn->txn_list); - txn->txn_list = NULL; - } - - if (ret != 0) - goto err; - - /* This is OK because __txn_end can only fail with a panic. */ - return (__txn_end(txn, 1)); - -err: /* - * If we are prepared, then we "must" be able to commit. We panic here - * because even though the coordinator might be able to retry it is not - * clear it would know to do that. Otherwise we'll try to abort. If - * that is successful, then we return whatever was in ret (that is, the - * reason we failed). If the abort was unsuccessful, abort probably - * returned DB_RUNRECOVERY and we need to propagate that up. - */ - if (td->status == TXN_PREPARED) - return (__db_panic(dbenv, ret)); - - if ((t_ret = __txn_abort(txn)) != 0) - ret = t_ret; - return (ret); -} - -/* - * __txn_abort_pp -- - * Interface routine to TXN->abort. - */ -static int -__txn_abort_pp(txn) - DB_TXN *txn; -{ - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int not_child, ret, t_ret; - - dbenv = txn->mgrp->dbenv; - not_child = txn->parent == NULL; - - ENV_ENTER(dbenv, ip); - - ret = __txn_abort(txn); - if (not_child && IS_ENV_REPLICATED(dbenv) && - (t_ret = __op_rep_exit(dbenv)) != 0 && ret == 0) - ret = t_ret; - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __txn_abort -- - * Abort a transaction. - * - * PUBLIC: int __txn_abort __P((DB_TXN *)); - */ -int -__txn_abort(txn) - DB_TXN *txn; -{ - DB_ENV *dbenv; - DB_LOCKREQ request; - DB_TXN *kid; - REGENV *renv; - REGINFO *infop; - TXN_DETAIL *td; - u_int32_t id, lflags; - int ret; - - dbenv = txn->mgrp->dbenv; - td = txn->td; - - PANIC_CHECK(dbenv); - - /* Ensure that abort always fails fatally. */ - if ((ret = __txn_isvalid(txn, TXN_OP_ABORT)) != 0) - return (__db_panic(dbenv, ret)); - - /* - * Try to abort any unresolved children. - * - * Abort either succeeds or panics the region. As soon as we - * see any failure, we just get out of here and return the panic - * up. - */ - while ((kid = TAILQ_FIRST(&txn->kids)) != NULL) - if ((ret = __txn_abort(kid)) != 0) - return (ret); - - infop = dbenv->reginfo; - renv = infop->primary; - /* - * No mutex is needed as envid is read-only once it is set. - */ - id = renv->envid; - - /* - * Fast path -- no need to do anything fancy if there were no - * modifications (e.g., log records) for this transaction. - * We still call txn_undo to cleanup the txn_list from our - * children. - */ - if (IS_ZERO_LSN(td->last_lsn) && STAILQ_FIRST(&txn->logs) == NULL) { - if (txn->txn_list == NULL) - goto done; - else - goto undo; - } - - if (LOCKING_ON(dbenv)) { - /* - * We are about to free all the read locks for this transaction - * below. Some of those locks might be handle locks which - * should not be freed, because they will be freed when the - * handle is closed. Check the events and preprocess any - * trades now so that we don't release the locks below. - */ - if ((ret = __txn_doevents(dbenv, txn, TXN_ABORT, 1)) != 0) - return (__db_panic(dbenv, ret)); - - /* Turn off timeouts. */ - if ((ret = __lock_set_timeout(dbenv, - txn->txnid, 0, DB_SET_TXN_TIMEOUT)) != 0) - return (__db_panic(dbenv, ret)); - - if ((ret = __lock_set_timeout(dbenv, - txn->txnid, 0, DB_SET_LOCK_TIMEOUT)) != 0) - return (__db_panic(dbenv, ret)); - - request.op = DB_LOCK_UPGRADE_WRITE; - request.obj = NULL; - if ((ret = __lock_vec( - dbenv, txn->txnid, DB_LOCK_ABORT, &request, 1, NULL)) != 0) - return (__db_panic(dbenv, ret)); - } -undo: if ((ret = __txn_undo(txn)) != 0) - return (__db_panic(dbenv, ret)); - - /* - * Normally, we do not need to log aborts. However, if we - * are a distributed transaction (i.e., we have a prepare), - * then we log the abort so we know that this transaction - * was actually completed. - */ -done: SET_LOG_FLAGS(dbenv, txn, lflags); - if (DBENV_LOGGING(dbenv) && td->status == TXN_PREPARED && - (ret = __txn_regop_log(dbenv, txn, &td->last_lsn, - lflags, TXN_ABORT, (int32_t)time(NULL), id, NULL)) != 0) - return (__db_panic(dbenv, ret)); - - /* __txn_end always panics if it errors, so pass the return along. */ - return (__txn_end(txn, 0)); -} - -/* - * __txn_discard -- - * Interface routine to TXN->discard. - */ -static int -__txn_discard(txn, flags) - DB_TXN *txn; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_THREAD_INFO *ip; - int ret; - - dbenv = txn->mgrp->dbenv; - - ENV_ENTER(dbenv, ip); - ret = __txn_discard_int(txn, flags); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __txn_discard -- - * Free the per-process resources associated with this txn handle. - * - * PUBLIC: int __txn_discard_int __P((DB_TXN *, u_int32_t flags)); - */ -int -__txn_discard_int(txn, flags) - DB_TXN *txn; - u_int32_t flags; -{ - DB_ENV *dbenv; - DB_TXN *freep; - DB_TXNMGR *mgr; - int ret; - - COMPQUIET(flags, 0); - - mgr = txn->mgrp; - dbenv = mgr->dbenv; - freep = NULL; - - PANIC_CHECK(dbenv); - - if ((ret = __txn_isvalid(txn, TXN_OP_DISCARD)) != 0) - return (ret); - - /* Should be no children. */ - DB_ASSERT(TAILQ_FIRST(&txn->kids) == NULL); - - /* Free the space. */ - MUTEX_LOCK(dbenv, mgr->mutex); - mgr->n_discards++; - if (F_ISSET(txn, TXN_MALLOC)) { - TAILQ_REMOVE(&mgr->txn_chain, txn, links); - freep = txn; - } - MUTEX_UNLOCK(dbenv, mgr->mutex); - if (freep != NULL) - __os_free(dbenv, freep); - - return (0); -} - -/* - * __txn_prepare -- - * Flush the log so a future commit is guaranteed to succeed. - * - * PUBLIC: int __txn_prepare __P((DB_TXN *, u_int8_t *)); - */ -int -__txn_prepare(txn, gid) - DB_TXN *txn; - u_int8_t *gid; -{ - DBT list_dbt, xid; - DB_ENV *dbenv; - DB_LOCKREQ request; - DB_THREAD_INFO *ip; - DB_TXN *kid; - TXN_DETAIL *td; - u_int32_t lflags; - int ret; - - dbenv = txn->mgrp->dbenv; - td = txn->td; - - PANIC_CHECK(dbenv); - - if ((ret = __txn_isvalid(txn, TXN_OP_PREPARE)) != 0) - return (ret); - - ENV_ENTER(dbenv, ip); - - /* Commit any unresolved children. */ - while ((kid = TAILQ_FIRST(&txn->kids)) != NULL) - if ((ret = __txn_commit(kid, DB_TXN_NOSYNC)) != 0) - goto err; - -#ifndef HAVE_FTRUNCATE - if (txn->txn_list != NULL && - (ret = __db_do_the_limbo(dbenv, - NULL, txn, txn->txn_list, LIMBO_PREPARE)) != 0) - goto err; -#endif - /* - * In XA, the global transaction ID in the txn_detail structure is - * already set; in a non-XA environment, we must set it here. XA - * requires that the transaction be either ENDED or SUSPENDED when - * prepare is called, so we know that if the xa_status isn't in one - * of those states, then we are calling prepare directly and we need - * to fill in the td->xid. - */ - if ((ret = __txn_doevents(dbenv, txn, TXN_PREPARE, 1)) != 0) - goto err; - memset(&request, 0, sizeof(request)); - if (LOCKING_ON(dbenv)) { - request.op = DB_LOCK_PUT_READ; - if (IS_REP_MASTER(dbenv) && - !IS_ZERO_LSN(td->last_lsn)) { - memset(&list_dbt, 0, sizeof(list_dbt)); - request.obj = &list_dbt; - } - if ((ret = __lock_vec(dbenv, - txn->txnid, 0, &request, 1, NULL)) != 0) - goto err; - - } - if (DBENV_LOGGING(dbenv)) { - memset(&xid, 0, sizeof(xid)); - if (td->xa_status != TXN_XA_ENDED && - td->xa_status != TXN_XA_SUSPENDED) - /* Regular prepare; fill in the gid. */ - memcpy(td->xid, gid, sizeof(td->xid)); - - xid.size = sizeof(td->xid); - xid.data = td->xid; - - lflags = DB_LOG_COMMIT | DB_LOG_PERM | DB_FLUSH; - if ((ret = __txn_xa_regop_log(dbenv, txn, &td->last_lsn, - lflags, TXN_PREPARE, &xid, td->format, td->gtrid, td->bqual, - &td->begin_lsn, request.obj)) != 0) { - __db_err(dbenv, "DB_TXN->prepare: log_write failed %s", - db_strerror(ret)); - } - if (request.obj != NULL && request.obj->data != NULL) - __os_free(dbenv, request.obj->data); - if (ret != 0) - goto err; - - } - - MUTEX_LOCK(dbenv, txn->mgrp->mutex); - td->status = TXN_PREPARED; - MUTEX_UNLOCK(dbenv, txn->mgrp->mutex); -err: ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __txn_id -- - * Return the transaction ID. - * - * PUBLIC: u_int32_t __txn_id __P((DB_TXN *)); - */ -u_int32_t -__txn_id(txn) - DB_TXN *txn; -{ - return (txn->txnid); -} - -/* - * __txn_get_name -- - * Get a descriptive string from a transaction. - * - * PUBLIC: int __txn_get_name __P((DB_TXN *, const char **)); - */ -int -__txn_get_name(txn, namep) - DB_TXN *txn; - const char **namep; -{ - *namep = txn->name; - - return (0); -} - -/* - * __txn_set_name -- - * Set a descriptive string for a transaction. - * - * PUBLIC: int __txn_set_name __P((DB_TXN *, const char *)); - */ -int -__txn_set_name(txn, name) - DB_TXN *txn; - const char *name; -{ - DB_ENV *dbenv; - DB_TXNMGR *mgr; - TXN_DETAIL *td; - size_t len; - int ret; - char *p; - - mgr = txn->mgrp; - dbenv = mgr->dbenv; - td = txn->td; - len = strlen(name) + 1; - - if ((ret = __os_realloc(dbenv, len, &txn->name)) != 0) - return (ret); - memcpy(txn->name, name, len); - - if (td->name != INVALID_ROFF) { - __db_shalloc_free( - &mgr->reginfo, R_ADDR(&mgr->reginfo, td->name)); - td->name = INVALID_ROFF; - } - if ((ret = __db_shalloc(&mgr->reginfo, len, 0, &p)) != 0) { - __db_err(dbenv, - "Unable to allocate memory for transaction name"); - - __os_free(dbenv, txn->name); - txn->name = NULL; - - return (ret); - } - td->name = R_OFFSET(&mgr->reginfo, p); - memcpy(p, name, len); - -#ifdef DIAGNOSTIC - /* - * If DIAGNOSTIC is set, map the name into the log so users can track - * operations through the log. - */ - if (DBENV_LOGGING(dbenv)) - (void)__log_printf(dbenv, txn, - "transaction %#lx named %s", (u_long)txn->txnid, name); -#endif - - return (0); -} - -/* - * __txn_set_timeout -- - * DB_ENV->set_txn_timeout. - * PUBLIC: int __txn_set_timeout __P((DB_TXN *, db_timeout_t, u_int32_t)); - */ -int -__txn_set_timeout(txn, timeout, op) - DB_TXN *txn; - db_timeout_t timeout; - u_int32_t op; -{ - if (op != DB_SET_TXN_TIMEOUT && op != DB_SET_LOCK_TIMEOUT) - return (__db_ferr(txn->mgrp->dbenv, "DB_TXN->set_timeout", 0)); - - return (__lock_set_timeout( - txn->mgrp->dbenv, txn->txnid, timeout, op)); -} - -/* - * __txn_isvalid -- - * Return 0 if the DB_TXN is reasonable, otherwise panic. - */ -static int -__txn_isvalid(txn, op) - const DB_TXN *txn; - txnop_t op; -{ - DB_ENV *dbenv; - DB_TXNMGR *mgr; - DB_TXNREGION *region; - TXN_DETAIL *td; - - mgr = txn->mgrp; - dbenv = mgr->dbenv; - region = mgr->reginfo.primary; - - /* Check for recovery. */ - if (!F_ISSET(txn, TXN_COMPENSATE) && - F_ISSET(region, TXN_IN_RECOVERY)) { - __db_err(dbenv, "operation not permitted during recovery"); - goto err; - } - - /* Check for live cursors. */ - if (txn->cursors != 0) { - __db_err(dbenv, "transaction has active cursors"); - goto err; - } - - /* Check transaction's state. */ - td = txn->td; - - /* Handle any operation specific checks. */ - switch (op) { - case TXN_OP_DISCARD: - /* - * Since we're just tossing the per-process space; there are - * a lot of problems with the transaction that we can tolerate. - */ - - /* Transaction is already been reused. */ - if (txn->txnid != td->txnid) - return (0); - - /* - * What we've got had better be either a prepared or - * restored transaction. - */ - if (td->status != TXN_PREPARED && - !F_ISSET(td, TXN_DTL_RESTORED)) { - __db_err(dbenv, "not a restored transaction"); - return (__db_panic(dbenv, EINVAL)); - } - - return (0); - case TXN_OP_PREPARE: - if (txn->parent != NULL) { - /* - * This is not fatal, because you could imagine an - * application that simply prepares everybody because - * it doesn't distinguish between children and parents. - * I'm not arguing this is good, but I could imagine - * someone doing it. - */ - __db_err(dbenv, - "Prepare disallowed on child transactions"); - return (EINVAL); - } - break; - case TXN_OP_ABORT: - case TXN_OP_COMMIT: - default: - break; - } - - switch (td->status) { - case TXN_PREPARED: - if (op == TXN_OP_PREPARE) { - __db_err(dbenv, "transaction already prepared"); - /* - * Txn_prepare doesn't blow away the user handle, so - * in this case, give the user the opportunity to - * abort or commit. - */ - return (EINVAL); - } - break; - case TXN_RUNNING: - break; - case TXN_ABORTED: - case TXN_COMMITTED: - default: - __db_err(dbenv, "transaction already %s", - td->status == TXN_COMMITTED ? "committed" : "aborted"); - goto err; - } - - return (0); - -err: /* - * If there's a serious problem with the transaction, panic. TXN - * handles are dead by definition when we return, and if you use - * a cursor you forgot to close, we have no idea what will happen. - */ - return (__db_panic(dbenv, EINVAL)); -} - -/* - * __txn_end -- - * Internal transaction end routine. - */ -static int -__txn_end(txn, is_commit) - DB_TXN *txn; - int is_commit; -{ - DB_ENV *dbenv; - DB_LOCKREQ request; - DB_TXNLOGREC *lr; - DB_TXNMGR *mgr; - DB_TXNREGION *region; - TXN_DETAIL *ptd, *td; - int do_closefiles, ret; - - mgr = txn->mgrp; - dbenv = mgr->dbenv; - region = mgr->reginfo.primary; - do_closefiles = 0; - - /* Process commit events. */ - if ((ret = __txn_doevents(dbenv, - txn, is_commit ? TXN_COMMIT : TXN_ABORT, 0)) != 0) - return (__db_panic(dbenv, ret)); - - /* - * Release the locks. - * - * __txn_end cannot return an simple error, we MUST return - * success/failure from commit or abort, ignoring any internal - * errors. So, we panic if something goes wrong. We can't - * deadlock here because we're not acquiring any new locks, - * so DB_LOCK_DEADLOCK is just as fatal as any other error. - */ - if (LOCKING_ON(dbenv)) { - request.op = txn->parent == NULL || - is_commit == 0 ? DB_LOCK_PUT_ALL : DB_LOCK_INHERIT; - request.obj = NULL; - if ((ret = __lock_vec(dbenv, - txn->txnid, 0, &request, 1, NULL)) != 0) - return (__db_panic(dbenv, ret)); - } - - /* End the transaction. */ - TXN_SYSTEM_LOCK(dbenv); - - td = txn->td; - SH_TAILQ_REMOVE(®ion->active_txn, td, links, __txn_detail); - if (F_ISSET(td, TXN_DTL_RESTORED)) { - region->stat.st_nrestores--; - do_closefiles = region->stat.st_nrestores == 0; - } - - if (td->name != INVALID_ROFF) { - __db_shalloc_free( - &mgr->reginfo, R_ADDR(&mgr->reginfo, td->name)); - td->name = INVALID_ROFF; - } - if (txn->parent != NULL) { - ptd = txn->parent->td; - SH_TAILQ_REMOVE(&ptd->kids, td, klinks, __txn_detail); - } - __db_shalloc_free(&mgr->reginfo, td); - - if (is_commit) - region->stat.st_ncommits++; - else - region->stat.st_naborts++; - --region->stat.st_nactive; - - TXN_SYSTEM_UNLOCK(dbenv); - - /* - * The transaction cannot get more locks, remove its locker info, - * if any. - */ - if (LOCKING_ON(dbenv) && (ret = - __lock_freefamilylocker(dbenv->lk_handle, txn->txnid)) != 0) - return (__db_panic(dbenv, ret)); - if (txn->parent != NULL) - TAILQ_REMOVE(&txn->parent->kids, txn, klinks); - - /* Free the space. */ - while ((lr = STAILQ_FIRST(&txn->logs)) != NULL) { - STAILQ_REMOVE(&txn->logs, lr, __txn_logrec, links); - __os_free(dbenv, lr); - } - if (txn->name != NULL) { - __os_free(dbenv, txn->name); - txn->name = NULL; - } - if (F_ISSET(txn, TXN_MALLOC)) { - MUTEX_LOCK(dbenv, mgr->mutex); - TAILQ_REMOVE(&mgr->txn_chain, txn, links); - MUTEX_UNLOCK(dbenv, mgr->mutex); - - __os_free(dbenv, txn); - } - - if (do_closefiles) { - F_SET((DB_LOG *)dbenv->lg_handle, DBLOG_RECOVER); - (void)__dbreg_close_files(dbenv); - F_CLR((DB_LOG *)dbenv->lg_handle, DBLOG_RECOVER); - mgr->n_discards = 0; - (void)__txn_checkpoint(dbenv, 0, 0, DB_FORCE); - } - - return (0); -} - -static int -__txn_dispatch_undo(dbenv, txn, rdbt, key_lsn, txnlist) - DB_ENV *dbenv; - DB_TXN *txn; - DBT *rdbt; - DB_LSN *key_lsn; - void *txnlist; -{ - int ret; - - ret = __db_dispatch(dbenv, dbenv->recover_dtab, - dbenv->recover_dtab_size, rdbt, key_lsn, DB_TXN_ABORT, txnlist); - if (ret == DB_SURPRISE_KID) { - F_SET(txn, TXN_CHILDCOMMIT); - ret = 0; - } - if (ret == 0 && F_ISSET(txn, TXN_CHILDCOMMIT) && IS_ZERO_LSN(*key_lsn)) - ret = __db_txnlist_lsnget(dbenv, txnlist, key_lsn, 0); - - return (ret); -} - -/* - * __txn_undo -- - * Undo the transaction with id txnid. - */ -static int -__txn_undo(txn) - DB_TXN *txn; -{ - DBT rdbt; - DB_ENV *dbenv; - DB_LOGC *logc; - DB_LSN key_lsn; - DB_TXN *ptxn; - DB_TXNHEAD *txnlist; - DB_TXNLOGREC *lr; - DB_TXNMGR *mgr; - int ret, t_ret; - - mgr = txn->mgrp; - dbenv = mgr->dbenv; - logc = NULL; - txnlist = NULL; - ret = 0; - - if (!DBENV_LOGGING(dbenv)) - return (0); - - /* - * This is the simplest way to code this, but if the mallocs during - * recovery turn out to be a performance issue, we can do the - * allocation here and use DB_DBT_USERMEM. - */ - memset(&rdbt, 0, sizeof(rdbt)); - - /* - * Allocate a txnlist for children and aborted page allocs. - * We need to associate the list with the maximal parent - * so that aborted pages are recovered when that transaction - * is committed or aborted. - */ - for (ptxn = txn->parent; ptxn != NULL && ptxn->parent != NULL;) - ptxn = ptxn->parent; - - if (ptxn != NULL && ptxn->txn_list != NULL) - txnlist = ptxn->txn_list; - else if (txn->txn_list != NULL) - txnlist = txn->txn_list; - else if ((ret = __db_txnlist_init(dbenv, 0, 0, NULL, &txnlist)) != 0) - return (ret); - else if (ptxn != NULL) - ptxn->txn_list = txnlist; - - /* - * Take log records from the linked list stored in the transaction, - * then from the log. - */ - for (lr = STAILQ_FIRST(&txn->logs); - lr != NULL; lr = STAILQ_NEXT(lr, links)) { - rdbt.data = lr->data; - rdbt.size = 0; - LSN_NOT_LOGGED(key_lsn); - ret = - __txn_dispatch_undo(dbenv, txn, &rdbt, &key_lsn, txnlist); - if (ret != 0) { - __db_err(dbenv, - "DB_TXN->abort: In-memory log undo failed: %s", - db_strerror(ret)); - goto err; - } - } - - key_lsn = ((TXN_DETAIL *)txn->td)->last_lsn; - - if (!IS_ZERO_LSN(key_lsn) && - (ret = __log_cursor(dbenv, &logc)) != 0) - goto err; - - while (!IS_ZERO_LSN(key_lsn)) { - /* - * The dispatch routine returns the lsn of the record - * before the current one in the key_lsn argument. - */ - if ((ret = __log_c_get(logc, &key_lsn, &rdbt, DB_SET)) == 0) { - ret = __txn_dispatch_undo(dbenv, - txn, &rdbt, &key_lsn, txnlist); - } - - if (ret != 0) { - __db_err(dbenv, - "DB_TXN->abort: Log undo failed for LSN: %lu %lu: %s", - (u_long)key_lsn.file, (u_long)key_lsn.offset, - db_strerror(ret)); - goto err; - } - } - -#ifndef HAVE_FTRUNCATE - ret = __db_do_the_limbo(dbenv, ptxn, txn, txnlist, LIMBO_NORMAL); -#endif - -err: if (logc != NULL && (t_ret = __log_c_close(logc)) != 0 && ret == 0) - ret = t_ret; - - if (ptxn == NULL && txnlist != NULL) - __db_txnlist_end(dbenv, txnlist); - return (ret); -} - -/* - * __txn_activekids -- - * Return if this transaction has any active children. - * - * PUBLIC: int __txn_activekids __P((DB_ENV *, u_int32_t, DB_TXN *)); - */ -int -__txn_activekids(dbenv, rectype, txn) - DB_ENV *dbenv; - u_int32_t rectype; - DB_TXN *txn; -{ - /* - * On a child commit, we know that there are children (i.e., the - * committing child at the least. In that case, skip this check. - */ - if (F_ISSET(txn, TXN_COMPENSATE) || rectype == DB___txn_child) - return (0); - - if (TAILQ_FIRST(&txn->kids) != NULL) { - __db_err(dbenv, "Child transaction is active"); - return (EPERM); - } - return (0); -} - -/* - * __txn_force_abort -- - * Force an abort record into the log if the commit record - * failed to get to disk. - * - * PUBLIC: int __txn_force_abort __P((DB_ENV *, u_int8_t *)); - */ -int -__txn_force_abort(dbenv, buffer) - DB_ENV *dbenv; - u_int8_t *buffer; -{ - DB_CIPHER *db_cipher; - HDR *hdr; - u_int32_t hdrlen, offset, opcode, sum_len; - u_int8_t *bp, *key, chksum[DB_MAC_KEY]; - size_t hdrsize, rec_len; - int ret; - - db_cipher = dbenv->crypto_handle; - - /* - * This routine depends on the layout of HDR and the __txn_regop - * __txn_xa_regop records in txn.src. We are passed the beginning - * of the commit record in the log buffer and overwrite the - * commit with an abort and recalculate the checksum. - */ - hdrsize = CRYPTO_ON(dbenv) ? HDR_CRYPTO_SZ : HDR_NORMAL_SZ; - - hdr = (HDR *)buffer; - memcpy(&hdrlen, buffer + SSZ(HDR, len), sizeof(hdr->len)); - rec_len = hdrlen - hdrsize; - - offset = sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(DB_LSN); - if (CRYPTO_ON(dbenv)) { - key = db_cipher->mac_key; - sum_len = DB_MAC_KEY; - if ((ret = db_cipher->decrypt(dbenv, db_cipher->data, - &hdr->iv[0], buffer + hdrsize, rec_len)) != 0) - return (__db_panic(dbenv, ret)); - } else { - key = NULL; - sum_len = sizeof(u_int32_t); - } - bp = buffer + hdrsize + offset; - opcode = TXN_ABORT; - memcpy(bp, &opcode, sizeof(opcode)); - - if (CRYPTO_ON(dbenv) && - (ret = db_cipher->encrypt(dbenv, - db_cipher->data, &hdr->iv[0], buffer + hdrsize, rec_len)) != 0) - return (__db_panic(dbenv, ret)); - - __db_chksum(buffer + hdrsize, rec_len, key, chksum); - memcpy(buffer + SSZA(HDR, chksum), chksum, sum_len); - - return (0); -} - -/* - * __txn_preclose - * Before we can close an environment, we need to check if we - * were in the midst of taking care of restored transactions. If - * so, then we need to close the files that we opened. - * - * PUBLIC: int __txn_preclose __P((DB_ENV *)); - */ -int -__txn_preclose(dbenv) - DB_ENV *dbenv; -{ - DB_TXNMGR *mgr; - DB_TXNREGION *region; - int do_closefiles, ret; - - mgr = dbenv->tx_handle; - region = mgr->reginfo.primary; - do_closefiles = 0; - - TXN_SYSTEM_LOCK(dbenv); - if (region != NULL && - region->stat.st_nrestores <= mgr->n_discards && - mgr->n_discards != 0) - do_closefiles = 1; - TXN_SYSTEM_UNLOCK(dbenv); - - if (do_closefiles) { - /* - * Set the DBLOG_RECOVER flag while closing these - * files so they do not create additional log records - * that will confuse future recoveries. - */ - F_SET((DB_LOG *)dbenv->lg_handle, DBLOG_RECOVER); - ret = __dbreg_close_files(dbenv); - F_CLR((DB_LOG *)dbenv->lg_handle, DBLOG_RECOVER); - } else - ret = 0; - - return (ret); -} - -/* - * __txn_reset -- - * Reset the last txnid to its minimum value, and log the reset. - * - * PUBLIC: int __txn_reset __P((DB_ENV *)); - */ -int -__txn_reset(dbenv) - DB_ENV *dbenv; -{ - DB_LSN scrap; - DB_TXNREGION *region; - - region = ((DB_TXNMGR *)dbenv->tx_handle)->reginfo.primary; - region->last_txnid = TXN_MINIMUM; - - DB_ASSERT(LOGGING_ON(dbenv)); - return (__txn_recycle_log(dbenv, - NULL, &scrap, 0, TXN_MINIMUM, TXN_MAXIMUM)); -} - -/* - * txn_set_txn_lsnp -- - * Set the pointer to the begin_lsn field if that field is zero. - * Set the pointer to the last_lsn field. - */ -static void -__txn_set_txn_lsnp(txn, blsnp, llsnp) - DB_TXN *txn; - DB_LSN **blsnp; - DB_LSN **llsnp; -{ - DB_LSN *lsnp; - TXN_DETAIL *td; - - td = txn->td; - *llsnp = &td->last_lsn; - while (td->parent != INVALID_ROFF) - td = R_ADDR(&txn->mgrp->reginfo, td->parent); - - lsnp = &td->begin_lsn; - if (IS_ZERO_LSN(*lsnp)) - *blsnp = lsnp; -} diff --git a/storage/bdb/txn/txn.src b/storage/bdb/txn/txn.src deleted file mode 100644 index 0b1212d7eea..00000000000 --- a/storage/bdb/txn/txn.src +++ /dev/null @@ -1,114 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: txn.src,v 12.2 2005/09/21 18:34:07 sue Exp $ - */ - -PREFIX __txn -DBPRIVATE - -INCLUDE #ifndef NO_SYSTEM_INCLUDES -INCLUDE #include <sys/types.h> -INCLUDE -INCLUDE #if TIME_WITH_SYS_TIME -INCLUDE #include <sys/time.h> -INCLUDE #include <time.h> -INCLUDE #else -INCLUDE #if HAVE_SYS_TIME_H -INCLUDE #include <sys/time.h> -INCLUDE #else -INCLUDE #include <time.h> -INCLUDE #endif /* HAVE_SYS_TIME_H */ -INCLUDE #endif /* TIME_WITH SYS_TIME */ -INCLUDE -INCLUDE #include <ctype.h> -INCLUDE #include <string.h> -INCLUDE #endif -INCLUDE -INCLUDE #include "db_int.h" -INCLUDE #include "dbinc/crypto.h" -INCLUDE #include "dbinc/db_page.h" -INCLUDE #include "dbinc/db_dispatch.h" -INCLUDE #include "dbinc/db_am.h" -INCLUDE #include "dbinc/db_shash.h" -INCLUDE #include "dbinc/lock.h" -INCLUDE #include "dbinc/log.h" -INCLUDE #include "dbinc/txn.h" -INCLUDE - -/* - * This is the standard log operation for commit. - * Note that we are using an int32_t for the timestamp. This means that - * in 2039 we will need to deprecate this log record and create one that - * either changes the Epoch or has a 64-bit offset. - * envid: - * Environment ID of this operation. - */ -BEGIN regop 10 -ARG opcode u_int32_t ld -TIME timestamp int32_t ld -ARG envid u_int32_t ld -LOCKS locks DBT s -END - -/* - * This is the checkpoint record. It contains the lsn that the checkpoint - * guarantees and a pointer to the last checkpoint so we can walk backwards - * by checkpoint. - * - * ckp_lsn: - * The lsn in the log of the most recent point at which all begun - * transactions have been aborted. This is the point for which - * the checkpoint is relevant. - * last_ckp: - * The previous checkpoint. - * timestamp: - * See comment in commit about timestamps. - * envid: - * Environment ID of this checkpoint. - * rep_gen: - * Persistent replication generation number. - */ -BEGIN ckp 11 -POINTER ckp_lsn DB_LSN * lu -POINTER last_ckp DB_LSN * lu -TIME timestamp int32_t ld -ARG envid u_int32_t ld -ARG rep_gen u_int32_t ld -END - -/* - * This is the (new) log operation for a child commit. It is - * logged as a record in the PARENT. The child field contains - * the transaction ID of the child committing and the c_lsn is - * the last LSN of the child's log trail. - */ -BEGIN child 12 -ARG child u_int32_t lx -POINTER c_lsn DB_LSN * lu -END - - -/* - * This is the standard log operation for prepare. - */ -BEGIN xa_regop 13 -ARG opcode u_int32_t lu -DBT xid DBT s -ARG formatID int32_t ld -ARG gtrid u_int32_t u -ARG bqual u_int32_t u -POINTER begin_lsn DB_LSN * lu -LOCKS locks DBT s -END - -/* - * Log the fact that we are recycling txnids. - */ -BEGIN recycle 14 -ARG min u_int32_t u -ARG max u_int32_t u -END diff --git a/storage/bdb/txn/txn_chkpt.c b/storage/bdb/txn/txn_chkpt.c deleted file mode 100644 index 2e192adc74b..00000000000 --- a/storage/bdb/txn/txn_chkpt.c +++ /dev/null @@ -1,353 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1995, 1996 - * The President and Fellows of Harvard University. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Margo Seltzer. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: txn_chkpt.c,v 12.19 2005/10/20 18:57:13 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#include <stdlib.h> - -#if TIME_WITH_SYS_TIME -#include <sys/time.h> -#include <time.h> -#else -#if HAVE_SYS_TIME_H -#include <sys/time.h> -#else -#include <time.h> -#endif -#endif - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_shash.h" -#include "dbinc/log.h" -#include "dbinc/mp.h" -#include "dbinc/txn.h" - -/* - * __txn_checkpoint_pp -- - * DB_ENV->txn_checkpoint pre/post processing. - * - * PUBLIC: int __txn_checkpoint_pp - * PUBLIC: __P((DB_ENV *, u_int32_t, u_int32_t, u_int32_t)); - */ -int -__txn_checkpoint_pp(dbenv, kbytes, minutes, flags) - DB_ENV *dbenv; - u_int32_t kbytes, minutes, flags; -{ - DB_THREAD_INFO *ip; - int ret; - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, - dbenv->tx_handle, "txn_checkpoint", DB_INIT_TXN); - - /* - * On a replication client, all transactions are read-only; therefore, - * a checkpoint is a null-op. - * - * We permit txn_checkpoint, instead of just rendering it illegal, - * so that an application can just let a checkpoint thread continue - * to operate as it gets promoted or demoted between being a - * master and a client. - */ - if (IS_REP_CLIENT(dbenv)) - return (0); - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, - (__txn_checkpoint(dbenv, kbytes, minutes, flags)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __txn_checkpoint -- - * DB_ENV->txn_checkpoint. - * - * PUBLIC: int __txn_checkpoint - * PUBLIC: __P((DB_ENV *, u_int32_t, u_int32_t, u_int32_t)); - */ -int -__txn_checkpoint(dbenv, kbytes, minutes, flags) - DB_ENV *dbenv; - u_int32_t kbytes, minutes, flags; -{ - DB_LSN ckp_lsn, last_ckp; - DB_TXNMGR *mgr; - DB_TXNREGION *region; - REGENV *renv; - REGINFO *infop; - time_t last_ckp_time, now; - u_int32_t bytes, gen, id, logflags, mbytes; - int ret; - - ret = gen = 0; - /* - * A client will only call through here during recovery, - * so just sync the Mpool and go home. - */ - if (IS_REP_CLIENT(dbenv)) { - if (MPOOL_ON(dbenv) && (ret = __memp_sync(dbenv, NULL)) != 0) { - __db_err(dbenv, - "txn_checkpoint: failed to flush the buffer cache %s", - db_strerror(ret)); - return (ret); - } else - return (0); - } - - mgr = dbenv->tx_handle; - region = mgr->reginfo.primary; - infop = dbenv->reginfo; - renv = infop->primary; - /* - * No mutex is needed as envid is read-only once it is set. - */ - id = renv->envid; - - /* - * The checkpoint LSN is an LSN such that all transactions begun before - * it are complete. Our first guess (corrected below based on the list - * of active transactions) is the last-written LSN. - */ - if ((ret = __log_current_lsn(dbenv, &ckp_lsn, &mbytes, &bytes)) != 0) - return (ret); - - if (!LF_ISSET(DB_FORCE)) { - /* Don't checkpoint a quiescent database. */ - if (bytes == 0 && mbytes == 0) - return (0); - - /* - * If either kbytes or minutes is non-zero, then only take the - * checkpoint if more than "minutes" minutes have passed or if - * more than "kbytes" of log data have been written since the - * last checkpoint. - */ - if (kbytes != 0 && - mbytes * 1024 + bytes / 1024 >= (u_int32_t)kbytes) - goto do_ckp; - - if (minutes != 0) { - (void)time(&now); - - TXN_SYSTEM_LOCK(dbenv); - last_ckp_time = region->time_ckp; - TXN_SYSTEM_UNLOCK(dbenv); - - if (now - last_ckp_time >= (time_t)(minutes * 60)) - goto do_ckp; - } - - /* - * If we checked time and data and didn't go to checkpoint, - * we're done. - */ - if (minutes != 0 || kbytes != 0) - return (0); - } - - /* - * We must single thread checkpoints otherwise the chk_lsn may get out - * of order. We need to capture the start of the earliest currently - * active transaction (chk_lsn) and then flush all buffers. While - * doing this we we could then be overtaken by another checkpoint that - * sees a later chk_lsn but competes first. An archive process could - * then remove a log this checkpoint depends on. - */ -do_ckp: MUTEX_LOCK(dbenv, region->mtx_ckp); - if ((ret = __txn_getactive(dbenv, &ckp_lsn)) != 0) - goto err; - - if (MPOOL_ON(dbenv) && (ret = __memp_sync(dbenv, NULL)) != 0) { - __db_err(dbenv, - "txn_checkpoint: failed to flush the buffer cache %s", - db_strerror(ret)); - goto err; - } - - /* - * Because we can't be a replication client here, and because - * recovery (somewhat unusually) calls txn_checkpoint and expects - * it to write a log message, LOGGING_ON is the correct macro here. - */ - if (LOGGING_ON(dbenv)) { - TXN_SYSTEM_LOCK(dbenv); - last_ckp = region->last_ckp; - TXN_SYSTEM_UNLOCK(dbenv); - if (REP_ON(dbenv) && (ret = __rep_get_gen(dbenv, &gen)) != 0) - goto err; - - /* - * Put out records for the open files before we log - * the checkpoint. The records are certain to be at - * or after ckp_lsn, but before the checkpoint record - * itself, so they're sure to be included if we start - * recovery from the ckp_lsn contained in this - * checkpoint. - */ - logflags = DB_LOG_PERM | DB_LOG_CHKPNT; - if (!IS_RECOVERING(dbenv)) - logflags |= DB_FLUSH; - if ((ret = __dbreg_log_files(dbenv)) != 0 || - (ret = __txn_ckp_log(dbenv, NULL, &ckp_lsn, logflags, - &ckp_lsn, &last_ckp, (int32_t)time(NULL), id, gen)) != 0) { - __db_err(dbenv, - "txn_checkpoint: log failed at LSN [%ld %ld] %s", - (long)ckp_lsn.file, (long)ckp_lsn.offset, - db_strerror(ret)); - goto err; - } - - if ((ret = __txn_updateckp(dbenv, &ckp_lsn)) != 0) - goto err; - } - -err: MUTEX_UNLOCK(dbenv, region->mtx_ckp); - return (ret); -} - -/* - * __txn_getactive -- - * Find the oldest active transaction and figure out its "begin" LSN. - * This is the lowest LSN we can checkpoint, since any record written - * after it may be involved in a transaction and may therefore need - * to be undone in the case of an abort. - * - * We check both the file and offset for 0 since the lsn may be in - * transition. If it is then we don't care about this txn because it - * must be starting after we set the initial value of lsnp in the caller. - * All txns must initalize their begin_lsn before writing to the log. - * - * PUBLIC: int __txn_getactive __P((DB_ENV *, DB_LSN *)); - */ -int -__txn_getactive(dbenv, lsnp) - DB_ENV *dbenv; - DB_LSN *lsnp; -{ - DB_TXNMGR *mgr; - DB_TXNREGION *region; - TXN_DETAIL *td; - - mgr = dbenv->tx_handle; - region = mgr->reginfo.primary; - - TXN_SYSTEM_LOCK(dbenv); - for (td = SH_TAILQ_FIRST(®ion->active_txn, __txn_detail); - td != NULL; - td = SH_TAILQ_NEXT(td, links, __txn_detail)) - if (td->begin_lsn.file != 0 && - td->begin_lsn.offset != 0 && - log_compare(&td->begin_lsn, lsnp) < 0) - *lsnp = td->begin_lsn; - TXN_SYSTEM_UNLOCK(dbenv); - - return (0); -} - -/* - * __txn_getckp -- - * Get the LSN of the last transaction checkpoint. - * - * PUBLIC: int __txn_getckp __P((DB_ENV *, DB_LSN *)); - */ -int -__txn_getckp(dbenv, lsnp) - DB_ENV *dbenv; - DB_LSN *lsnp; -{ - DB_LSN lsn; - DB_TXNMGR *mgr; - DB_TXNREGION *region; - - mgr = dbenv->tx_handle; - region = mgr->reginfo.primary; - - TXN_SYSTEM_LOCK(dbenv); - lsn = region->last_ckp; - TXN_SYSTEM_UNLOCK(dbenv); - - if (IS_ZERO_LSN(lsn)) - return (DB_NOTFOUND); - - *lsnp = lsn; - return (0); -} - -/* - * __txn_updateckp -- - * Update the last_ckp field in the transaction region. This happens - * at the end of a normal checkpoint and also when a replication client - * receives a checkpoint record. - * - * PUBLIC: int __txn_updateckp __P((DB_ENV *, DB_LSN *)); - */ -int -__txn_updateckp(dbenv, lsnp) - DB_ENV *dbenv; - DB_LSN *lsnp; -{ - DB_TXNMGR *mgr; - DB_TXNREGION *region; - - mgr = dbenv->tx_handle; - region = mgr->reginfo.primary; - - /* - * We want to make sure last_ckp only moves forward; since we drop - * locks above and in log_put, it's possible for two calls to - * __txn_ckp_log to finish in a different order from how they were - * called. - */ - TXN_SYSTEM_LOCK(dbenv); - if (log_compare(®ion->last_ckp, lsnp) < 0) { - region->last_ckp = *lsnp; - (void)time(®ion->time_ckp); - } - TXN_SYSTEM_UNLOCK(dbenv); - - return (0); -} diff --git a/storage/bdb/txn/txn_failchk.c b/storage/bdb/txn/txn_failchk.c deleted file mode 100644 index 5348f8bb1f8..00000000000 --- a/storage/bdb/txn/txn_failchk.c +++ /dev/null @@ -1,100 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2005 - * Sleepycat Software. All rights reserved. - * - * $Id: txn_failchk.c,v 12.2 2005/10/13 00:51:51 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - -#include "db_int.h" -#include "dbinc/txn.h" - -/* - * __txn_failchk -- - * Check for transactions started by dead threads of control. - * - * PUBLIC: int __txn_failchk __P((DB_ENV *)); - */ -int -__txn_failchk(dbenv) - DB_ENV *dbenv; -{ - DB_TXN *ktxn, *txn; - DB_TXNMGR *mgr; - DB_TXNREGION *region; - TXN_DETAIL *ktd, *td; - db_threadid_t tid; - int ret; - char buf[DB_THREADID_STRLEN]; - pid_t pid; - - mgr = dbenv->tx_handle; - region = mgr->reginfo.primary; - -retry: TXN_SYSTEM_LOCK(dbenv); - - SH_TAILQ_FOREACH(td, ®ion->active_txn, links, __txn_detail) { - /* - * If this is a child transaction, skip it. - * The parent will take care of it. - */ - if (td->parent != INVALID_ROFF) - continue; - /* - * If the txn is prepared, then it does not matter - * what the state of the thread is. - */ - if (td->status == TXN_PREPARED) - continue; - - /* If the thread is still alive, it's not a problem. */ - if (dbenv->is_alive(dbenv, td->pid, td->tid)) - continue; - - if (F_ISSET(td, TXN_DTL_INMEMORY)) - return (__db_failed(dbenv, - "Transaction has in memory logs", - td->pid, td->tid)); - - /* Abort the transaction. */ - TXN_SYSTEM_UNLOCK(dbenv); - if ((ret = __os_calloc(dbenv, 1, sizeof(DB_TXN), &txn)) != 0) - return (ret); - __txn_continue(dbenv, txn, td); - F_SET(txn, TXN_MALLOC); - SH_TAILQ_FOREACH(ktd, &td->kids, klinks, __txn_detail) { - if (F_ISSET(ktd, TXN_DTL_INMEMORY)) - return (__db_failed(dbenv, - "Transaction has in memory logs", - td->pid, td->tid)); - if ((ret = - __os_calloc(dbenv, 1, sizeof(DB_TXN), &ktxn)) != 0) - return (ret); - __txn_continue(dbenv, ktxn, ktd); - F_SET(ktxn, TXN_MALLOC); - ktxn->parent = txn; - TAILQ_INSERT_HEAD(&txn->kids, txn, klinks); - } - TAILQ_INSERT_TAIL(&mgr->txn_chain, txn, links); - pid = td->pid; - tid = td->tid; - (void)dbenv->thread_id_string(dbenv, pid, tid, buf); - __db_msg(dbenv, - "Aborting txn %#lx: %s", (u_long)txn->txnid, buf); - if ((ret = __txn_abort(txn)) != 0) - return (__db_failed(dbenv, - "Transaction abort failed", pid, tid)); - goto retry; - } - - TXN_SYSTEM_UNLOCK(dbenv); - - return (0); -} diff --git a/storage/bdb/txn/txn_method.c b/storage/bdb/txn/txn_method.c deleted file mode 100644 index db92f35017e..00000000000 --- a/storage/bdb/txn/txn_method.c +++ /dev/null @@ -1,104 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: txn_method.c,v 12.2 2005/07/21 18:21:45 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/txn.h" - -/* - * __txn_dbenv_create -- - * Transaction specific initialization of the DB_ENV structure. - * - * PUBLIC: void __txn_dbenv_create __P((DB_ENV *)); - */ -void -__txn_dbenv_create(dbenv) - DB_ENV *dbenv; -{ - /* - * !!! - * Our caller has not yet had the opportunity to reset the panic - * state or turn off mutex locking, and so we can neither check - * the panic state or acquire a mutex in the DB_ENV create path. - */ - dbenv->tx_max = DEF_MAX_TXNS; -} - -/* - * PUBLIC: int __txn_get_tx_max __P((DB_ENV *, u_int32_t *)); - */ -int -__txn_get_tx_max(dbenv, tx_maxp) - DB_ENV *dbenv; - u_int32_t *tx_maxp; -{ - ENV_NOT_CONFIGURED(dbenv, - dbenv->tx_handle, "DB_ENV->get_tx_max", DB_INIT_TXN); - - if (TXN_ON(dbenv)) { - /* Cannot be set after open, no lock required to read. */ - *tx_maxp = ((DB_TXNREGION *) - ((DB_TXNMGR *)dbenv->tx_handle)->reginfo.primary)->maxtxns; - } else - *tx_maxp = dbenv->tx_max; - return (0); -} - -/* - * __txn_set_tx_max -- - * DB_ENV->set_tx_max. - * - * PUBLIC: int __txn_set_tx_max __P((DB_ENV *, u_int32_t)); - */ -int -__txn_set_tx_max(dbenv, tx_max) - DB_ENV *dbenv; - u_int32_t tx_max; -{ - ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_tx_max"); - - dbenv->tx_max = tx_max; - return (0); -} - -/* - * PUBLIC: int __txn_get_tx_timestamp __P((DB_ENV *, time_t *)); - */ -int -__txn_get_tx_timestamp(dbenv, timestamp) - DB_ENV *dbenv; - time_t *timestamp; -{ - *timestamp = dbenv->tx_timestamp; - return (0); -} - -/* - * __txn_set_tx_timestamp -- - * Set the transaction recovery timestamp. - * - * PUBLIC: int __txn_set_tx_timestamp __P((DB_ENV *, time_t *)); - */ -int -__txn_set_tx_timestamp(dbenv, timestamp) - DB_ENV *dbenv; - time_t *timestamp; -{ - ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_tx_timestamp"); - - dbenv->tx_timestamp = *timestamp; - return (0); -} diff --git a/storage/bdb/txn/txn_rec.c b/storage/bdb/txn/txn_rec.c deleted file mode 100644 index 3e1c516a0b5..00000000000 --- a/storage/bdb/txn/txn_rec.c +++ /dev/null @@ -1,489 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - */ -/* - * Copyright (c) 1996 - * The President and Fellows of Harvard University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: txn_rec.c,v 12.4 2005/10/19 15:10:45 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/txn.h" -#include "dbinc/db_am.h" - -/* - * PUBLIC: int __txn_regop_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - * - * These records are only ever written for commits. Normally, we redo any - * committed transaction, however if we are doing recovery to a timestamp, then - * we may treat transactions that committed after the timestamp as aborted. - */ -int -__txn_regop_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - DB_TXNHEAD *headp; - __txn_regop_args *argp; - int ret; - u_int32_t status; - -#ifdef DEBUG_RECOVER - (void)__txn_regop_print(dbenv, dbtp, lsnp, op, info); -#endif - - if ((ret = __txn_regop_read(dbenv, dbtp->data, &argp)) != 0) - return (ret); - - headp = info; - /* - * We are only ever called during FORWARD_ROLL or BACKWARD_ROLL. - * We check for the former explicitly and the last two clauses - * apply to the BACKWARD_ROLL case. - */ - - if (op == DB_TXN_FORWARD_ROLL) { - /* - * If this was a 2-phase-commit transaction, then it - * might already have been removed from the list, and - * that's OK. Ignore the return code from remove. - */ - if ((ret = __db_txnlist_remove(dbenv, - info, argp->txnid->txnid)) != DB_NOTFOUND && ret != 0) - goto err; - } else if ((dbenv->tx_timestamp != 0 && - argp->timestamp > (int32_t)dbenv->tx_timestamp) || - (!IS_ZERO_LSN(headp->trunc_lsn) && - log_compare(&headp->trunc_lsn, lsnp) < 0)) { - /* - * We failed either the timestamp check or the trunc_lsn check, - * so we treat this as an abort even if it was a commit record. - */ - if ((ret = __db_txnlist_update(dbenv, info, - argp->txnid->txnid, TXN_ABORT, NULL, &status, 1)) != 0) - goto err; - else if (status != TXN_IGNORE && status != TXN_OK) - goto err; - } else { - /* This is a normal commit; mark it appropriately. */ - if ((ret = __db_txnlist_update(dbenv, - info, argp->txnid->txnid, argp->opcode, lsnp, - &status, 0)) == DB_NOTFOUND) { - if ((ret = __db_txnlist_add(dbenv, - info, argp->txnid->txnid, - argp->opcode == TXN_ABORT ? - TXN_IGNORE : argp->opcode, lsnp)) != 0) - goto err; - } else if (ret != 0 || - (status != TXN_IGNORE && status != TXN_OK)) - goto err; - } - - if (ret == 0) - *lsnp = argp->prev_lsn; - - if (0) { -err: __db_err(dbenv, - "txnid %lx commit record found, already on commit list", - (u_long)argp->txnid->txnid); - ret = EINVAL; - } - __os_free(dbenv, argp); - - return (ret); -} - -/* - * PUBLIC: int __txn_xa_regop_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - * - * These records are only ever written for prepares. - */ -int -__txn_xa_regop_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __txn_xa_regop_args *argp; - int ret; - u_int32_t status; - -#ifdef DEBUG_RECOVER - (void)__txn_xa_regop_print(dbenv, dbtp, lsnp, op, info); -#endif - - if ((ret = __txn_xa_regop_read(dbenv, dbtp->data, &argp)) != 0) - return (ret); - - if (argp->opcode != TXN_PREPARE && argp->opcode != TXN_ABORT) { - ret = EINVAL; - goto err; - } - - /* - * The return value here is either a DB_NOTFOUND or it is - * the transaction status from the list. It is not a normal - * error return, so we must make sure that in each of the - * cases below, we overwrite the ret value so we return - * appropriately. - */ - ret = __db_txnlist_find(dbenv, info, argp->txnid->txnid, &status); - - /* - * If we are rolling forward, then an aborted prepare - * indicates that this may the last record we'll see for - * this transaction ID, so we should remove it from the - * list. - */ - - if (op == DB_TXN_FORWARD_ROLL) { - if ((ret = __db_txnlist_remove(dbenv, - info, argp->txnid->txnid)) != 0) - goto txn_err; - } else if (op == DB_TXN_BACKWARD_ROLL && status == TXN_PREPARE) { - /* - * On the backward pass, we have four possibilities: - * 1. The transaction is already committed, no-op. - * 2. The transaction is already aborted, no-op. - * 3. The prepare failed and was aborted, mark as abort. - * 4. The transaction is neither committed nor aborted. - * Treat this like a commit and roll forward so that - * the transaction can be resurrected in the region. - * We handle cases 3 and 4 here; cases 1 and 2 - * are the final clause below. - */ - if (argp->opcode == TXN_ABORT) { - if ((ret = __db_txnlist_update(dbenv, - info, argp->txnid->txnid, - TXN_ABORT, NULL, &status, 0)) != 0 && - status != TXN_PREPARE) - goto txn_err; - ret = 0; - } - /* - * This is prepared, but not yet committed transaction. We - * need to add it to the transaction list, so that it gets - * rolled forward. We also have to add it to the region's - * internal state so it can be properly aborted or committed - * after recovery (see txn_recover). - */ - else if ((ret = __db_txnlist_remove(dbenv, - info, argp->txnid->txnid)) != 0) { -txn_err: __db_err(dbenv, - "Transaction not in list %x", argp->txnid->txnid); - ret = DB_NOTFOUND; - } else if ((ret = __db_txnlist_add(dbenv, - info, argp->txnid->txnid, TXN_COMMIT, lsnp)) == 0) - ret = __txn_restore_txn(dbenv, lsnp, argp); - } else - ret = 0; - - if (ret == 0) - *lsnp = argp->prev_lsn; - -err: __os_free(dbenv, argp); - - return (ret); -} - -/* - * PUBLIC: int __txn_ckp_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__txn_ckp_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - DB_REP *db_rep; - REP *rep; - __txn_ckp_args *argp; - int ret; - -#ifdef DEBUG_RECOVER - __txn_ckp_print(dbenv, dbtp, lsnp, op, info); -#endif - if ((ret = __txn_ckp_read(dbenv, dbtp->data, &argp)) != 0) - return (ret); - - if (op == DB_TXN_BACKWARD_ROLL) - __db_txnlist_ckp(dbenv, info, lsnp); - - if (op == DB_TXN_FORWARD_ROLL) { - /* Record the max generation number that we've seen. */ - if (REP_ON(dbenv)) { - db_rep = dbenv->rep_handle; - rep = db_rep->region; - if (argp->rep_gen > rep->recover_gen) - rep->recover_gen = argp->rep_gen; - } - } - - *lsnp = argp->last_ckp; - __os_free(dbenv, argp); - return (DB_TXN_CKP); -} - -/* - * __txn_child_recover - * Recover a commit record for a child transaction. - * - * PUBLIC: int __txn_child_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__txn_child_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __txn_child_args *argp; - int ret, t_ret; - u_int32_t c_stat, p_stat, tmpstat; - -#ifdef DEBUG_RECOVER - (void)__txn_child_print(dbenv, dbtp, lsnp, op, info); -#endif - if ((ret = __txn_child_read(dbenv, dbtp->data, &argp)) != 0) - return (ret); - - /* - * This is a record in a PARENT's log trail indicating that a - * child committed. If we are aborting, return the childs last - * record's LSN. If we are in recovery, then if the - * parent is committing, we set ourselves up to commit, else - * we do nothing. - */ - if (op == DB_TXN_ABORT) { - *lsnp = argp->c_lsn; - ret = __db_txnlist_lsnadd(dbenv, info, &argp->prev_lsn); - goto out; - } else if (op == DB_TXN_BACKWARD_ROLL) { - /* Child might exist -- look for it. */ - ret = __db_txnlist_find(dbenv, info, argp->child, &c_stat); - t_ret = - __db_txnlist_find(dbenv, info, argp->txnid->txnid, &p_stat); - if (ret != 0 && ret != DB_NOTFOUND) - goto out; - if (t_ret != 0 && t_ret != DB_NOTFOUND) { - ret = t_ret; - goto out; - } - /* - * If the parent is in state COMMIT or IGNORE, then we apply - * that to the child, else we need to abort the child. - */ - - if (ret == DB_NOTFOUND || - c_stat == TXN_OK || c_stat == TXN_COMMIT) { - if (t_ret == DB_NOTFOUND || - (p_stat != TXN_COMMIT && p_stat != TXN_IGNORE)) - c_stat = TXN_ABORT; - else - c_stat = p_stat; - - if (ret == DB_NOTFOUND) - ret = __db_txnlist_add(dbenv, - info, argp->child, c_stat, NULL); - else - ret = __db_txnlist_update(dbenv, info, - argp->child, c_stat, NULL, &tmpstat, 0); - } else if (c_stat == TXN_EXPECTED) { - /* - * The open after this create succeeded. If the - * parent succeeded, we don't want to redo; if the - * parent aborted, we do want to undo. - */ - switch (p_stat) { - case TXN_COMMIT: - case TXN_IGNORE: - c_stat = TXN_IGNORE; - break; - default: - c_stat = TXN_ABORT; - } - ret = __db_txnlist_update(dbenv, - info, argp->child, c_stat, NULL, &tmpstat, 0); - } else if (c_stat == TXN_UNEXPECTED) { - /* - * The open after this create failed. If the parent - * is rolling forward, we need to roll forward. If - * the parent failed, then we do not want to abort - * (because the file may not be the one in which we - * are interested). - */ - ret = __db_txnlist_update(dbenv, info, argp->child, - p_stat == TXN_COMMIT ? TXN_COMMIT : TXN_IGNORE, - NULL, &tmpstat, 0); - } - } else if (op == DB_TXN_OPENFILES) { - /* - * If we have a partial subtransaction, then the whole - * transaction should be ignored. - */ - if ((ret = __db_txnlist_find(dbenv, - info, argp->child, &c_stat)) == DB_NOTFOUND) - ret = __db_txnlist_update(dbenv, info, - argp->txnid->txnid, TXN_IGNORE, - NULL, &p_stat, 1); - } else if (DB_REDO(op)) { - /* Forward Roll */ - if ((ret = - __db_txnlist_remove(dbenv, info, argp->child)) != 0) - __db_err(dbenv, - "Transaction not in list %x", argp->child); - } - - if (ret == 0) - *lsnp = argp->prev_lsn; - -out: __os_free(dbenv, argp); - - return (ret); -} - -/* - * __txn_restore_txn -- - * Using only during XA recovery. If we find any transactions that are - * prepared, but not yet committed, then we need to restore the transaction's - * state into the shared region, because the TM is going to issue an abort - * or commit and we need to respond correctly. - * - * lsnp is the LSN of the returned LSN - * argp is the prepare record (in an appropriate structure) - * - * PUBLIC: int __txn_restore_txn __P((DB_ENV *, - * PUBLIC: DB_LSN *, __txn_xa_regop_args *)); - */ -int -__txn_restore_txn(dbenv, lsnp, argp) - DB_ENV *dbenv; - DB_LSN *lsnp; - __txn_xa_regop_args *argp; -{ - DB_TXNMGR *mgr; - TXN_DETAIL *td; - DB_TXNREGION *region; - int ret; - - if (argp->xid.size == 0) - return (0); - - mgr = dbenv->tx_handle; - region = mgr->reginfo.primary; - TXN_SYSTEM_LOCK(dbenv); - - /* Allocate a new transaction detail structure. */ - if ((ret = - __db_shalloc(&mgr->reginfo, sizeof(TXN_DETAIL), 0, &td)) != 0) { - TXN_SYSTEM_UNLOCK(dbenv); - return (ret); - } - - /* Place transaction on active transaction list. */ - SH_TAILQ_INSERT_HEAD(®ion->active_txn, td, links, __txn_detail); - - td->txnid = argp->txnid->txnid; - td->begin_lsn = argp->begin_lsn; - td->last_lsn = *lsnp; - td->parent = 0; - td->status = TXN_PREPARED; - td->xa_status = TXN_XA_PREPARED; - memcpy(td->xid, argp->xid.data, argp->xid.size); - td->bqual = argp->bqual; - td->gtrid = argp->gtrid; - td->format = argp->formatID; - td->flags = 0; - F_SET(td, TXN_DTL_RESTORED); - - region->stat.st_nrestores++; - region->stat.st_nactive++; - if (region->stat.st_nactive > region->stat.st_maxnactive) - region->stat.st_maxnactive = region->stat.st_nactive; - TXN_SYSTEM_UNLOCK(dbenv); - return (0); -} - -/* - * __txn_recycle_recover -- - * Recovery function for recycle. - * - * PUBLIC: int __txn_recycle_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -__txn_recycle_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - __txn_recycle_args *argp; - int ret; - -#ifdef DEBUG_RECOVER - (void)__txn_child_print(dbenv, dbtp, lsnp, op, info); -#endif - if ((ret = __txn_recycle_read(dbenv, dbtp->data, &argp)) != 0) - return (ret); - - COMPQUIET(lsnp, NULL); - - if ((ret = __db_txnlist_gen(dbenv, info, - DB_UNDO(op) ? -1 : 1, argp->min, argp->max)) != 0) - return (ret); - - __os_free(dbenv, argp); - - return (0); -} diff --git a/storage/bdb/txn/txn_recover.c b/storage/bdb/txn/txn_recover.c deleted file mode 100644 index 00b4fabc520..00000000000 --- a/storage/bdb/txn/txn_recover.c +++ /dev/null @@ -1,346 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2001-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: txn_recover.c,v 12.11 2005/10/14 21:12:18 ubell Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/txn.h" -#include "dbinc/db_page.h" -#include "dbinc/db_dispatch.h" -#include "dbinc/log.h" -#include "dbinc_auto/db_auto.h" -#include "dbinc_auto/crdel_auto.h" -#include "dbinc_auto/db_ext.h" - -/* - * __txn_map_gid - * Return the txn that corresponds to this global ID. - * - * PUBLIC: int __txn_map_gid __P((DB_ENV *, - * PUBLIC: u_int8_t *, TXN_DETAIL **, roff_t *)); - */ -int -__txn_map_gid(dbenv, gid, tdp, offp) - DB_ENV *dbenv; - u_int8_t *gid; - TXN_DETAIL **tdp; - roff_t *offp; -{ - DB_TXNMGR *mgr; - DB_TXNREGION *region; - - mgr = dbenv->tx_handle; - region = mgr->reginfo.primary; - - /* - * Search the internal active transaction table to find the - * matching xid. If this is a performance hit, then we - * can create a hash table, but I doubt it's worth it. - */ - TXN_SYSTEM_LOCK(dbenv); - for (*tdp = SH_TAILQ_FIRST(®ion->active_txn, __txn_detail); - *tdp != NULL; - *tdp = SH_TAILQ_NEXT(*tdp, links, __txn_detail)) - if (memcmp(gid, (*tdp)->xid, sizeof((*tdp)->xid)) == 0) - break; - TXN_SYSTEM_UNLOCK(dbenv); - - if (*tdp == NULL) - return (EINVAL); - - *offp = R_OFFSET(&mgr->reginfo, *tdp); - return (0); -} - -/* - * __txn_recover_pp -- - * DB_ENV->txn_recover pre/post processing. - * - * PUBLIC: int __txn_recover_pp - * PUBLIC: __P((DB_ENV *, DB_PREPLIST *, long, long *, u_int32_t)); - */ -int -__txn_recover_pp(dbenv, preplist, count, retp, flags) - DB_ENV *dbenv; - DB_PREPLIST *preplist; - long count, *retp; - u_int32_t flags; -{ - DB_THREAD_INFO *ip; - int ret; - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG( - dbenv, dbenv->tx_handle, "txn_recover", DB_INIT_TXN); - - if (F_ISSET((DB_TXNREGION *) - ((DB_TXNMGR *)dbenv->tx_handle)->reginfo.primary, - TXN_IN_RECOVERY)) { - __db_err(dbenv, "operation not permitted while in recovery"); - return (EINVAL); - } - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, - (__txn_recover(dbenv, preplist, count, retp, flags)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __txn_recover -- - * DB_ENV->txn_recover. - * - * PUBLIC: int __txn_recover - * PUBLIC: __P((DB_ENV *, DB_PREPLIST *, long, long *, u_int32_t)); - */ -int -__txn_recover(dbenv, preplist, count, retp, flags) - DB_ENV *dbenv; - DB_PREPLIST *preplist; - long count, *retp; - u_int32_t flags; -{ - /* - * Public API to retrieve the list of prepared, but not yet committed - * transactions. See __txn_get_prepared for details. This function - * and __db_xa_recover both wrap that one. - */ - return (__txn_get_prepared(dbenv, NULL, preplist, count, retp, flags)); -} - -/* - * __txn_get_prepared -- - * Returns a list of prepared (and for XA, heuristically completed) - * transactions (less than or equal to the count parameter). One of - * xids or txns must be set to point to an array of the appropriate type. - * The count parameter indicates the number of entries in the xids and/or - * txns array. The retp parameter will be set to indicate the number of - * entries returned in the xids/txns array. Flags indicates the operation, - * one of DB_FIRST or DB_NEXT. - * - * PUBLIC: int __txn_get_prepared __P((DB_ENV *, - * PUBLIC: XID *, DB_PREPLIST *, long, long *, u_int32_t)); - */ -int -__txn_get_prepared(dbenv, xids, txns, count, retp, flags) - DB_ENV *dbenv; - XID *xids; - DB_PREPLIST *txns; - long count; /* This is long for XA compatibility. */ - long *retp; - u_int32_t flags; -{ - DB_LSN min; - DB_PREPLIST *prepp; - DB_TXNMGR *mgr; - DB_TXNREGION *region; - TXN_DETAIL *td; - XID *xidp; - long i; - int nrestores, open_files, ret; - - *retp = 0; - - MAX_LSN(min); - prepp = txns; - xidp = xids; - nrestores = ret = 0; - open_files = 1; - - /* - * If we are starting a scan, then we traverse the active transaction - * list once making sure that all transactions are marked as not having - * been collected. Then on each pass, we mark the ones we collected - * so that if we cannot collect them all at once, we can finish up - * next time with a continue. - */ - - mgr = dbenv->tx_handle; - region = mgr->reginfo.primary; - - /* - * During this pass we need to figure out if we are going to need - * to open files. We need to open files if we've never collected - * before (in which case, none of the COLLECTED bits will be set) - * and the ones that we are collecting are restored (if they aren't - * restored, then we never crashed; just the main server did). - */ - TXN_SYSTEM_LOCK(dbenv); - if (flags == DB_FIRST) { - for (td = SH_TAILQ_FIRST(®ion->active_txn, __txn_detail); - td != NULL; - td = SH_TAILQ_NEXT(td, links, __txn_detail)) { - if (F_ISSET(td, TXN_DTL_RESTORED)) - nrestores++; - if (F_ISSET(td, TXN_DTL_COLLECTED)) - open_files = 0; - F_CLR(td, TXN_DTL_COLLECTED); - } - mgr->n_discards = 0; - } else - open_files = 0; - - /* Now begin collecting active transactions. */ - for (td = SH_TAILQ_FIRST(®ion->active_txn, __txn_detail); - td != NULL && *retp < count; - td = SH_TAILQ_NEXT(td, links, __txn_detail)) { - if (td->status != TXN_PREPARED || - F_ISSET(td, TXN_DTL_COLLECTED)) - continue; - - if (xids != NULL) { - xidp->formatID = td->format; - /* - * XID structure uses longs; we use u_int32_t's as we - * log them to disk. Cast them to make the conversion - * explicit. - */ - xidp->gtrid_length = (long)td->gtrid; - xidp->bqual_length = (long)td->bqual; - memcpy(xidp->data, td->xid, sizeof(td->xid)); - xidp++; - } - - if (txns != NULL) { - if ((ret = __os_calloc(dbenv, - 1, sizeof(DB_TXN), &prepp->txn)) != 0) { - TXN_SYSTEM_UNLOCK(dbenv); - goto err; - } - __txn_continue(dbenv, prepp->txn, td); - F_SET(prepp->txn, TXN_MALLOC); - memcpy(prepp->gid, td->xid, sizeof(td->xid)); - prepp++; - } - - if (!IS_ZERO_LSN(td->begin_lsn) && - log_compare(&td->begin_lsn, &min) < 0) - min = td->begin_lsn; - - (*retp)++; - F_SET(td, TXN_DTL_COLLECTED); - if (IS_ENV_REPLICATED(dbenv) && - (ret = __op_rep_enter(dbenv)) != 0) - goto err; - } - TXN_SYSTEM_UNLOCK(dbenv); - - /* - * Now link all the transactions into the transaction manager's list. - */ - if (txns != NULL) { - MUTEX_LOCK(dbenv, mgr->mutex); - for (i = 0; i < *retp; i++) - TAILQ_INSERT_TAIL(&mgr->txn_chain, txns[i].txn, links); - MUTEX_UNLOCK(dbenv, mgr->mutex); - } - - if (open_files && nrestores && *retp != 0 && !IS_MAX_LSN(min)) { - F_SET((DB_LOG *)dbenv->lg_handle, DBLOG_RECOVER); - ret = __txn_openfiles(dbenv, &min, 0); - F_CLR((DB_LOG *)dbenv->lg_handle, DBLOG_RECOVER); - } - return (0); - -err: TXN_SYSTEM_UNLOCK(dbenv); - return (ret); -} - -/* - * __txn_openfiles -- - * Call env_openfiles. - * - * PUBLIC: int __txn_openfiles __P((DB_ENV *, DB_LSN *, int)); - */ -int -__txn_openfiles(dbenv, min, force) - DB_ENV *dbenv; - DB_LSN *min; - int force; -{ - DBT data; - DB_LOGC *logc; - DB_LSN open_lsn; - DB_TXNHEAD *txninfo; - __txn_ckp_args *ckp_args; - int ret, t_ret; - - /* - * Figure out the last checkpoint before the smallest - * start_lsn in the region. - */ - logc = NULL; - if ((ret = __log_cursor(dbenv, &logc)) != 0) - goto err; - - memset(&data, 0, sizeof(data)); - if ((ret = __txn_getckp(dbenv, &open_lsn)) == 0) - while (!IS_ZERO_LSN(open_lsn) && (ret = - __log_c_get(logc, &open_lsn, &data, DB_SET)) == 0 && - (force || - (min != NULL && log_compare(min, &open_lsn) < 0))) { - /* Format the log record. */ - if ((ret = __txn_ckp_read(dbenv, - data.data, &ckp_args)) != 0) { - __db_err(dbenv, - "Invalid checkpoint record at [%lu][%lu]", - (u_long)open_lsn.file, - (u_long)open_lsn.offset); - goto err; - } - /* - * If force is set, then we're forcing ourselves - * to go back far enough to open files. - * Use ckp_lsn and then break out of the loop. - */ - open_lsn = force ? ckp_args->ckp_lsn : - ckp_args->last_ckp; - __os_free(dbenv, ckp_args); - if (force) { - if ((ret = __log_c_get(logc, &open_lsn, - &data, DB_SET)) != 0) - goto err; - break; - } - } - - /* - * There are several ways by which we may have gotten here. - * - We got a DB_NOTFOUND -- we need to read the first - * log record. - * - We found a checkpoint before min. We're done. - * - We found a checkpoint after min who's last_ckp is 0. We - * need to start at the beginning of the log. - * - We are forcing an openfiles and we have our ckp_lsn. - */ - if ((ret == DB_NOTFOUND || IS_ZERO_LSN(open_lsn)) && (ret = - __log_c_get(logc, &open_lsn, &data, DB_FIRST)) != 0) { - __db_err(dbenv, "No log records"); - goto err; - } - - if ((ret = __db_txnlist_init(dbenv, 0, 0, NULL, &txninfo)) != 0) - goto err; - ret = __env_openfiles(dbenv, logc, - txninfo, &data, &open_lsn, NULL, 0, 0); - if (txninfo != NULL) - __db_txnlist_end(dbenv, txninfo); - -err: - if (logc != NULL && (t_ret = __log_c_close(logc)) != 0 && ret == 0) - ret = t_ret; - return (ret); -} diff --git a/storage/bdb/txn/txn_region.c b/storage/bdb/txn/txn_region.c deleted file mode 100644 index bfce068d4d1..00000000000 --- a/storage/bdb/txn/txn_region.c +++ /dev/null @@ -1,356 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: txn_region.c,v 12.10 2005/10/14 21:12:18 ubell Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#if TIME_WITH_SYS_TIME -#include <sys/time.h> -#include <time.h> -#else -#if HAVE_SYS_TIME_H -#include <sys/time.h> -#else -#include <time.h> -#endif -#endif - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/log.h" -#include "dbinc/txn.h" - -static int __txn_init __P((DB_ENV *, DB_TXNMGR *)); -static size_t __txn_region_size __P((DB_ENV *)); - -/* - * __txn_open -- - * Open a transaction region. - * - * PUBLIC: int __txn_open __P((DB_ENV *)); - */ -int -__txn_open(dbenv) - DB_ENV *dbenv; -{ - DB_TXNMGR *mgr; - int ret; - - /* Create/initialize the transaction manager structure. */ - if ((ret = __os_calloc(dbenv, 1, sizeof(DB_TXNMGR), &mgr)) != 0) - return (ret); - TAILQ_INIT(&mgr->txn_chain); - mgr->dbenv = dbenv; - - /* Join/create the txn region. */ - mgr->reginfo.dbenv = dbenv; - mgr->reginfo.type = REGION_TYPE_TXN; - mgr->reginfo.id = INVALID_REGION_ID; - mgr->reginfo.flags = REGION_JOIN_OK; - if (F_ISSET(dbenv, DB_ENV_CREATE)) - F_SET(&mgr->reginfo, REGION_CREATE_OK); - if ((ret = __db_r_attach(dbenv, - &mgr->reginfo, __txn_region_size(dbenv))) != 0) - goto err; - - /* If we created the region, initialize it. */ - if (F_ISSET(&mgr->reginfo, REGION_CREATE)) - if ((ret = __txn_init(dbenv, mgr)) != 0) - goto err; - - /* Set the local addresses. */ - mgr->reginfo.primary = - R_ADDR(&mgr->reginfo, mgr->reginfo.rp->primary); - - /* If threaded, acquire a mutex to protect the active TXN list. */ - if ((ret = __mutex_alloc( - dbenv, MTX_TXN_ACTIVE, DB_MUTEX_THREAD, &mgr->mutex)) != 0) - goto err; - - dbenv->tx_handle = mgr; - return (0); - -err: dbenv->tx_handle = NULL; - if (mgr->reginfo.addr != NULL) - (void)__db_r_detach(dbenv, &mgr->reginfo, 0); - - (void)__mutex_free(dbenv, &mgr->mutex); - __os_free(dbenv, mgr); - return (ret); -} - -/* - * __txn_init -- - * Initialize a transaction region in shared memory. - */ -static int -__txn_init(dbenv, mgr) - DB_ENV *dbenv; - DB_TXNMGR *mgr; -{ - DB_LSN last_ckp; - DB_TXNREGION *region; - int ret; - - /* - * Find the last checkpoint in the log. - */ - ZERO_LSN(last_ckp); - if (LOGGING_ON(dbenv)) { - /* - * The log system has already walked through the last - * file. Get the LSN of a checkpoint it may have found. - */ - if ((ret = __log_get_cached_ckp_lsn(dbenv, &last_ckp)) != 0) - return (ret); - - /* - * If that didn't work, look backwards from the beginning of - * the last log file until we find the last checkpoint. - */ - if (IS_ZERO_LSN(last_ckp) && - (ret = __txn_findlastckp(dbenv, &last_ckp, NULL)) != 0) - return (ret); - } - - if ((ret = __db_shalloc(&mgr->reginfo, - sizeof(DB_TXNREGION), 0, &mgr->reginfo.primary)) != 0) { - __db_err(dbenv, - "Unable to allocate memory for the transaction region"); - return (ret); - } - mgr->reginfo.rp->primary = - R_OFFSET(&mgr->reginfo, mgr->reginfo.primary); - region = mgr->reginfo.primary; - memset(region, 0, sizeof(*region)); - - if ((ret = __mutex_alloc( - dbenv, MTX_TXN_REGION, 0, ®ion->mtx_region)) != 0) - return (ret); - - region->maxtxns = dbenv->tx_max; - region->last_txnid = TXN_MINIMUM; - region->cur_maxid = TXN_MAXIMUM; - - if ((ret = __mutex_alloc( - dbenv, MTX_TXN_CHKPT, 0, ®ion->mtx_ckp)) != 0) - return (ret); - region->last_ckp = last_ckp; - region->time_ckp = time(NULL); - - memset(®ion->stat, 0, sizeof(region->stat)); - region->stat.st_maxtxns = region->maxtxns; - - SH_TAILQ_INIT(®ion->active_txn); - return (ret); -} - -/* - * __txn_findlastckp -- - * Find the last checkpoint in the log, walking backwards from the - * max_lsn given or the beginning of the last log file. (The - * log system looked through the last log file when it started up.) - * - * PUBLIC: int __txn_findlastckp __P((DB_ENV *, DB_LSN *, DB_LSN *)); - */ -int -__txn_findlastckp(dbenv, lsnp, max_lsn) - DB_ENV *dbenv; - DB_LSN *lsnp; - DB_LSN *max_lsn; -{ - DB_LOGC *logc; - DB_LSN lsn; - DBT dbt; - int ret, t_ret; - u_int32_t rectype; - - ZERO_LSN(*lsnp); - - if ((ret = __log_cursor(dbenv, &logc)) != 0) - return (ret); - - /* Get the last LSN. */ - memset(&dbt, 0, sizeof(dbt)); - if (max_lsn != NULL) { - lsn = *max_lsn; - if ((ret = __log_c_get(logc, &lsn, &dbt, DB_SET)) != 0) - goto err; - } else { - if ((ret = __log_c_get(logc, &lsn, &dbt, DB_LAST)) != 0) - goto err; - /* - * Twiddle the last LSN so it points to the beginning of the - * last file; we know there's no checkpoint after that, since - * the log system already looked there. - */ - lsn.offset = 0; - } - - /* Read backwards, looking for checkpoints. */ - while ((ret = __log_c_get(logc, &lsn, &dbt, DB_PREV)) == 0) { - if (dbt.size < sizeof(u_int32_t)) - continue; - memcpy(&rectype, dbt.data, sizeof(u_int32_t)); - if (rectype == DB___txn_ckp) { - *lsnp = lsn; - break; - } - } - -err: if ((t_ret = __log_c_close(logc)) != 0 && ret == 0) - ret = t_ret; - - /* - * Not finding a checkpoint is not an error; there may not exist - * one in the log. - */ - return ((ret == 0 || ret == DB_NOTFOUND) ? 0 : ret); -} - -/* - * __txn_dbenv_refresh -- - * Clean up after the transaction system on a close or failed open. - * - * PUBLIC: int __txn_dbenv_refresh __P((DB_ENV *)); - */ -int -__txn_dbenv_refresh(dbenv) - DB_ENV *dbenv; -{ - DB_TXN *txn; - DB_TXNMGR *mgr; - REGINFO *reginfo; - u_int32_t txnid; - int aborted, ret, t_ret; - - ret = 0; - mgr = dbenv->tx_handle; - reginfo = &mgr->reginfo; - - /* - * This function can only be called once per process (i.e., not - * once per thread), so no synchronization is required. - * - * The caller is probably doing something wrong if close is called with - * active transactions. Try and abort any active transactions that are - * not prepared, but it's quite likely the aborts will fail because - * recovery won't find open files. If we can't abort any of the - * unprepared transaction, panic, we have to run recovery to get back - * to a known state. - */ - aborted = 0; - if (TAILQ_FIRST(&mgr->txn_chain) != NULL) { - while ((txn = TAILQ_FIRST(&mgr->txn_chain)) != NULL) { - /* Prepared transactions are OK. */ - txnid = txn->txnid; - if (((TXN_DETAIL *)txn->td)->status == TXN_PREPARED) { - if ((ret = __txn_discard_int(txn, 0)) != 0) { - __db_err(dbenv, - "Unable to discard txn 0x%x: %s", - txnid, db_strerror(ret)); - break; - } - continue; - } - aborted = 1; - if ((t_ret = __txn_abort(txn)) != 0) { - __db_err(dbenv, - "Unable to abort transaction 0x%x: %s", - txnid, db_strerror(t_ret)); - ret = __db_panic(dbenv, t_ret); - break; - } - } - if (aborted) { - __db_err(dbenv, - "Error: closing the transaction region with active transactions"); - if (ret == 0) - ret = EINVAL; - } - } - - /* Flush the log. */ - if (LOGGING_ON(dbenv) && - (t_ret = __log_flush(dbenv, NULL)) != 0 && ret == 0) - ret = t_ret; - - /* Discard the per-thread lock. */ - if ((t_ret = __mutex_free(dbenv, &mgr->mutex)) != 0 && ret == 0) - ret = t_ret; - - /* Detach from the region. */ - if ((t_ret = __db_r_detach(dbenv, reginfo, 0)) != 0 && ret == 0) - ret = t_ret; - - __os_free(dbenv, mgr); - - dbenv->tx_handle = NULL; - return (ret); -} - -/* - * __txn_region_size -- - * Return the amount of space needed for the txn region. Make the - * region large enough to hold txn_max transaction detail structures - * plus some space to hold thread handles and the beginning of the - * shalloc region and anything we need for mutex system resource - * recording. - */ -static size_t -__txn_region_size(dbenv) - DB_ENV *dbenv; -{ - size_t s; - - s = sizeof(DB_TXNREGION) + - dbenv->tx_max * sizeof(TXN_DETAIL) + 10 * 1024; - return (s); -} - -/* - * __txn_id_set -- - * Set the current transaction ID and current maximum unused ID (for - * testing purposes only). - * - * PUBLIC: int __txn_id_set __P((DB_ENV *, u_int32_t, u_int32_t)); - */ -int -__txn_id_set(dbenv, cur_txnid, max_txnid) - DB_ENV *dbenv; - u_int32_t cur_txnid, max_txnid; -{ - DB_TXNMGR *mgr; - DB_TXNREGION *region; - int ret; - - ENV_REQUIRES_CONFIG(dbenv, dbenv->tx_handle, "txn_id_set", DB_INIT_TXN); - - mgr = dbenv->tx_handle; - region = mgr->reginfo.primary; - region->last_txnid = cur_txnid; - region->cur_maxid = max_txnid; - - ret = 0; - if (cur_txnid < TXN_MINIMUM) { - __db_err(dbenv, "Current ID value %lu below minimum", - (u_long)cur_txnid); - ret = EINVAL; - } - if (max_txnid < TXN_MINIMUM) { - __db_err(dbenv, "Maximum ID value %lu below minimum", - (u_long)max_txnid); - ret = EINVAL; - } - return (ret); -} diff --git a/storage/bdb/txn/txn_stat.c b/storage/bdb/txn/txn_stat.c deleted file mode 100644 index 9c02a07b019..00000000000 --- a/storage/bdb/txn/txn_stat.c +++ /dev/null @@ -1,444 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: txn_stat.c,v 12.8 2005/10/07 20:21:43 ubell Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#if TIME_WITH_SYS_TIME -#include <sys/time.h> -#include <time.h> -#else -#if HAVE_SYS_TIME_H -#include <sys/time.h> -#else -#include <time.h> -#endif -#endif - -#include <stdlib.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_am.h" -#include "dbinc/log.h" -#include "dbinc/txn.h" - -#ifdef HAVE_STATISTICS -static int __txn_compare __P((const void *, const void *)); -static int __txn_print_all __P((DB_ENV *, u_int32_t)); -static int __txn_print_stats __P((DB_ENV *, u_int32_t)); -static int __txn_stat __P((DB_ENV *, DB_TXN_STAT **, u_int32_t)); -static void __txn_xid_stats __P((DB_ENV *, DB_MSGBUF *, DB_TXN_ACTIVE *)); - -/* - * __txn_stat_pp -- - * DB_ENV->txn_stat pre/post processing. - * - * PUBLIC: int __txn_stat_pp __P((DB_ENV *, DB_TXN_STAT **, u_int32_t)); - */ -int -__txn_stat_pp(dbenv, statp, flags) - DB_ENV *dbenv; - DB_TXN_STAT **statp; - u_int32_t flags; -{ - DB_THREAD_INFO *ip; - int ret; - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, - dbenv->tx_handle, "DB_ENV->txn_stat", DB_INIT_TXN); - - if ((ret = __db_fchk(dbenv, - "DB_ENV->txn_stat", flags, DB_STAT_CLEAR)) != 0) - return (ret); - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, (__txn_stat(dbenv, statp, flags)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __txn_stat -- - * DB_ENV->txn_stat. - */ -static int -__txn_stat(dbenv, statp, flags) - DB_ENV *dbenv; - DB_TXN_STAT **statp; - u_int32_t flags; -{ - DB_TXNMGR *mgr; - DB_TXNREGION *region; - DB_TXN_STAT *stats; - TXN_DETAIL *td; - size_t nbytes; - u_int32_t maxtxn, ndx; - int ret; - - *statp = NULL; - mgr = dbenv->tx_handle; - region = mgr->reginfo.primary; - - /* - * Allocate for the maximum active transactions -- the DB_TXN_ACTIVE - * struct is small and the maximum number of active transactions is - * not going to be that large. Don't have to lock anything to look - * at the region's maximum active transactions value, it's read-only - * and never changes after the region is created. - * - * The maximum active transactions isn't a hard limit, so allocate - * some extra room, and don't walk off the end. - */ - maxtxn = region->maxtxns + (region->maxtxns / 10) + 10; - nbytes = sizeof(DB_TXN_STAT) + sizeof(DB_TXN_ACTIVE) * maxtxn; - if ((ret = __os_umalloc(dbenv, nbytes, &stats)) != 0) - return (ret); - - TXN_SYSTEM_LOCK(dbenv); - memcpy(stats, ®ion->stat, sizeof(*stats)); - stats->st_last_txnid = region->last_txnid; - stats->st_last_ckp = region->last_ckp; - stats->st_time_ckp = region->time_ckp; - stats->st_txnarray = (DB_TXN_ACTIVE *)&stats[1]; - - for (ndx = 0, - td = SH_TAILQ_FIRST(®ion->active_txn, __txn_detail); - td != NULL && ndx < maxtxn; - td = SH_TAILQ_NEXT(td, links, __txn_detail), ++ndx) { - stats->st_txnarray[ndx].txnid = td->txnid; - if (td->parent == INVALID_ROFF) - stats->st_txnarray[ndx].parentid = TXN_INVALID; - else - stats->st_txnarray[ndx].parentid = - ((TXN_DETAIL *)R_ADDR(&mgr->reginfo, - td->parent))->txnid; - stats->st_txnarray[ndx].pid = td->pid; - stats->st_txnarray[ndx].tid = td->tid; - stats->st_txnarray[ndx].lsn = td->begin_lsn; - if ((stats->st_txnarray[ndx].xa_status = td->xa_status) != 0) - memcpy(stats->st_txnarray[ndx].xid, - td->xid, DB_XIDDATASIZE); - if (td->name != INVALID_ROFF) { - (void)strncpy(stats->st_txnarray[ndx].name, - R_ADDR(&mgr->reginfo, td->name), - sizeof(stats->st_txnarray[ndx].name) - 1); - stats->st_txnarray[ndx].name[ - sizeof(stats->st_txnarray[ndx].name) - 1] = '\0'; - } else - stats->st_txnarray[ndx].name[0] = '\0'; - } - - __mutex_set_wait_info(dbenv, region->mtx_region, - &stats->st_region_wait, &stats->st_region_nowait); - stats->st_regsize = mgr->reginfo.rp->size; - if (LF_ISSET(DB_STAT_CLEAR)) { - __mutex_clear(dbenv, region->mtx_region); - memset(®ion->stat, 0, sizeof(region->stat)); - region->stat.st_maxtxns = region->maxtxns; - region->stat.st_maxnactive = - region->stat.st_nactive = stats->st_nactive; - } - - TXN_SYSTEM_UNLOCK(dbenv); - - *statp = stats; - return (0); -} - -/* - * __txn_stat_print_pp -- - * DB_ENV->txn_stat_print pre/post processing. - * - * PUBLIC: int __txn_stat_print_pp __P((DB_ENV *, u_int32_t)); - */ -int -__txn_stat_print_pp(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - DB_THREAD_INFO *ip; - int ret; - - PANIC_CHECK(dbenv); - ENV_REQUIRES_CONFIG(dbenv, - dbenv->tx_handle, "DB_ENV->txn_stat_print", DB_INIT_TXN); - - if ((ret = __db_fchk(dbenv, "DB_ENV->txn_stat", - flags, DB_STAT_ALL | DB_STAT_CLEAR)) != 0) - return (ret); - - ENV_ENTER(dbenv, ip); - REPLICATION_WRAP(dbenv, (__txn_stat_print(dbenv, flags)), ret); - ENV_LEAVE(dbenv, ip); - return (ret); -} - -/* - * __txn_stat_print - * DB_ENV->txn_stat_print method. - * - * PUBLIC: int __txn_stat_print __P((DB_ENV *, u_int32_t)); - */ -int -__txn_stat_print(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - u_int32_t orig_flags; - int ret; - - orig_flags = flags; - LF_CLR(DB_STAT_CLEAR); - if (flags == 0 || LF_ISSET(DB_STAT_ALL)) { - ret = __txn_print_stats(dbenv, orig_flags); - if (flags == 0 || ret != 0) - return (ret); - } - - if (LF_ISSET(DB_STAT_ALL) && - (ret = __txn_print_all(dbenv, orig_flags)) != 0) - return (ret); - - return (0); -} - -/* - * __txn_print_stats -- - * Display default transaction region statistics. - */ -static int -__txn_print_stats(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - DB_MSGBUF mb; - DB_TXN_STAT *sp; - u_int32_t i; - int ret; - char buf[DB_THREADID_STRLEN]; - - if ((ret = __txn_stat(dbenv, &sp, flags)) != 0) - return (ret); - - if (LF_ISSET(DB_STAT_ALL)) - __db_msg(dbenv, "Default transaction region information:"); - __db_msg(dbenv, "%lu/%lu\t%s", - (u_long)sp->st_last_ckp.file, (u_long)sp->st_last_ckp.offset, - sp->st_last_ckp.file == 0 ? - "No checkpoint LSN" : "File/offset for last checkpoint LSN"); - if (sp->st_time_ckp == 0) - __db_msg(dbenv, "0\tNo checkpoint timestamp"); - else - __db_msg(dbenv, "%.24s\tCheckpoint timestamp", - ctime(&sp->st_time_ckp)); - __db_msg(dbenv, "%#lx\tLast transaction ID allocated", - (u_long)sp->st_last_txnid); - __db_dl(dbenv, "Maximum number of active transactions configured", - (u_long)sp->st_maxtxns); - __db_dl(dbenv, "Active transactions", (u_long)sp->st_nactive); - __db_dl(dbenv, - "Maximum active transactions", (u_long)sp->st_maxnactive); - __db_dl(dbenv, - "Number of transactions begun", (u_long)sp->st_nbegins); - __db_dl(dbenv, - "Number of transactions aborted", (u_long)sp->st_naborts); - __db_dl(dbenv, - "Number of transactions committed", (u_long)sp->st_ncommits); - __db_dl(dbenv, - "Number of transactions restored", (u_long)sp->st_nrestores); - - __db_dlbytes(dbenv, "Transaction region size", - (u_long)0, (u_long)0, (u_long)sp->st_regsize); - __db_dl_pct(dbenv, - "The number of region locks that required waiting", - (u_long)sp->st_region_wait, DB_PCT(sp->st_region_wait, - sp->st_region_wait + sp->st_region_nowait), NULL); - - qsort(sp->st_txnarray, - sp->st_nactive, sizeof(sp->st_txnarray[0]), __txn_compare); - __db_msg(dbenv, "Active transactions:"); - DB_MSGBUF_INIT(&mb); - for (i = 0; i < sp->st_nactive; ++i) { - __db_msgadd(dbenv, &mb, - "\t%lx: pid/thread %s; begin LSN: file/offset %lu/%lu", - (u_long)sp->st_txnarray[i].txnid, - dbenv->thread_id_string(dbenv, - sp->st_txnarray[i].pid, sp->st_txnarray[i].tid, buf), - (u_long)sp->st_txnarray[i].lsn.file, - (u_long)sp->st_txnarray[i].lsn.offset); - if (sp->st_txnarray[i].parentid != 0) - __db_msgadd(dbenv, &mb, "; parent: %lx", - (u_long)sp->st_txnarray[i].parentid); - if (sp->st_txnarray[i].xa_status != 0) - __txn_xid_stats(dbenv, &mb, &sp->st_txnarray[i]); - if (sp->st_txnarray[i].name[0] != '\0') - __db_msgadd( - dbenv, &mb, "; \"%s\"", sp->st_txnarray[i].name); - DB_MSGBUF_FLUSH(dbenv, &mb); - } - - __os_ufree(dbenv, sp); - - return (0); -} - -/* - * __txn_print_all -- - * Display debugging transaction region statistics. - */ -static int -__txn_print_all(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - static const FN fn[] = { - { TXN_IN_RECOVERY, "TXN_IN_RECOVERY" }, - { 0, NULL } - }; - DB_TXNMGR *mgr; - DB_TXNREGION *region; - - mgr = dbenv->tx_handle; - region = mgr->reginfo.primary; - - TXN_SYSTEM_LOCK(dbenv); - - __db_print_reginfo(dbenv, &mgr->reginfo, "Transaction"); - - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_msg(dbenv, "DB_TXNMGR handle information:"); - __mutex_print_debug_single(dbenv, "DB_TXNMGR mutex", mgr->mutex, flags); - __db_dl(dbenv, - "Number of transactions discarded", (u_long)mgr->n_discards); - - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_msg(dbenv, "DB_TXNREGION handle information:"); - __mutex_print_debug_single( - dbenv, "DB_TXNREGION region mutex", region->mtx_region, flags); - STAT_ULONG("Maximum number of active txns", region->maxtxns); - STAT_HEX("Last transaction ID allocated", region->last_txnid); - STAT_HEX("Current maximum unused ID", region->cur_maxid); - - __mutex_print_debug_single( - dbenv, "checkpoint mutex", region->mtx_ckp, flags); - STAT_LSN("Last checkpoint LSN", ®ion->last_ckp); - __db_msg(dbenv, - "%.24s\tLast checkpoint timestamp", - region->time_ckp == 0 ? "0" : ctime(®ion->time_ckp)); - - __db_prflags(dbenv, NULL, region->flags, fn, NULL, "\tFlags"); - - __db_msg(dbenv, "%s", DB_GLOBAL(db_line)); - __db_msg(dbenv, "XA information:"); - STAT_LONG("XA RMID", dbenv->xa_rmid); - /* - * XXX - * Display list of XA transactions in the DB_ENV handle. - */ - - TXN_SYSTEM_UNLOCK(dbenv); - - return (0); -} - -static void -__txn_xid_stats(dbenv, mbp, txn_active) - DB_ENV *dbenv; - DB_MSGBUF *mbp; - DB_TXN_ACTIVE *txn_active; -{ - u_int32_t v, *xp; - u_int i; - int cnt; - const char *s; - - switch (txn_active->xa_status) { - case TXN_XA_ABORTED: - s = "ABORTED"; - break; - case TXN_XA_DEADLOCKED: - s = "DEADLOCKED"; - break; - case TXN_XA_ENDED: - s = "ENDED"; - break; - case TXN_XA_PREPARED: - s = "PREPARED"; - break; - case TXN_XA_STARTED: - s = "STARTED"; - break; - case TXN_XA_SUSPENDED: - s = "SUSPENDED"; - break; - default: - s = "UNKNOWN STATE"; - __db_err(dbenv, - "XA: unknown state: %lu", (u_long)txn_active->xa_status); - break; - } - __db_msgadd(dbenv, mbp, "\tXA: %s; XID:\n\t\t", s == NULL ? "" : s); - for (cnt = 0, xp = (u_int32_t *)txn_active->xid, - i = 0; i < DB_XIDDATASIZE; i += sizeof(u_int32_t)) { - memcpy(&v, xp++, sizeof(u_int32_t)); - __db_msgadd(dbenv, mbp, "%#lx ", (u_long)v); - if (++cnt == 4) { - DB_MSGBUF_FLUSH(dbenv, mbp); - __db_msgadd(dbenv, mbp, "\t\t"); - cnt = 0; - } - } -} - -static int -__txn_compare(a1, b1) - const void *a1, *b1; -{ - const DB_TXN_ACTIVE *a, *b; - - a = a1; - b = b1; - - if (a->txnid > b->txnid) - return (1); - if (a->txnid < b->txnid) - return (-1); - return (0); -} - -#else /* !HAVE_STATISTICS */ - -int -__txn_stat_pp(dbenv, statp, flags) - DB_ENV *dbenv; - DB_TXN_STAT **statp; - u_int32_t flags; -{ - COMPQUIET(statp, NULL); - COMPQUIET(flags, 0); - - return (__db_stat_not_built(dbenv)); -} - -int -__txn_stat_print_pp(dbenv, flags) - DB_ENV *dbenv; - u_int32_t flags; -{ - COMPQUIET(flags, 0); - - return (__db_stat_not_built(dbenv)); -} -#endif diff --git a/storage/bdb/txn/txn_util.c b/storage/bdb/txn/txn_util.c deleted file mode 100644 index ac9ea6d94c8..00000000000 --- a/storage/bdb/txn/txn_util.c +++ /dev/null @@ -1,330 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2001-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: txn_util.c,v 12.2 2005/09/28 17:45:20 margo Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/db_page.h" -#include "dbinc/db_shash.h" -#include "dbinc/lock.h" -#include "dbinc/mp.h" -#include "dbinc/txn.h" -#include "dbinc/db_am.h" - -typedef struct __txn_event TXN_EVENT; -struct __txn_event { - TXN_EVENT_T op; - TAILQ_ENTRY(__txn_event) links; - union { - struct { - /* Delayed close. */ - DB *dbp; - } c; - struct { - /* Delayed remove. */ - char *name; - u_int8_t *fileid; - int inmem; - } r; - struct { - /* Lock event. */ - DB_LOCK lock; - u_int32_t locker; - DB *dbp; - } t; - } u; -}; - -/* - * __txn_closeevent -- - * - * Creates a close event that can be added to the [so-called] commit list, so - * that we can redo a failed DB handle close once we've aborted the transaction. - * - * PUBLIC: int __txn_closeevent __P((DB_ENV *, DB_TXN *, DB *)); - */ -int -__txn_closeevent(dbenv, txn, dbp) - DB_ENV *dbenv; - DB_TXN *txn; - DB *dbp; -{ - int ret; - TXN_EVENT *e; - - e = NULL; - if ((ret = __os_calloc(dbenv, 1, sizeof(TXN_EVENT), &e)) != 0) - return (ret); - - e->u.c.dbp = dbp; - e->op = TXN_CLOSE; - TAILQ_INSERT_TAIL(&txn->events, e, links); - - return (0); -} - -/* - * __txn_remevent -- - * - * Creates a remove event that can be added to the commit list. - * - * PUBLIC: int __txn_remevent __P((DB_ENV *, - * PUBLIC: DB_TXN *, const char *, u_int8_t *, int)); - */ -int -__txn_remevent(dbenv, txn, name, fileid, inmem) - DB_ENV *dbenv; - DB_TXN *txn; - const char *name; - u_int8_t *fileid; - int inmem; -{ - int ret; - TXN_EVENT *e; - - e = NULL; - if ((ret = __os_calloc(dbenv, 1, sizeof(TXN_EVENT), &e)) != 0) - return (ret); - - if ((ret = __os_strdup(dbenv, name, &e->u.r.name)) != 0) - goto err; - - if (fileid != NULL) { - if ((ret = __os_calloc(dbenv, - 1, DB_FILE_ID_LEN, &e->u.r.fileid)) != 0) - return (ret); - memcpy(e->u.r.fileid, fileid, DB_FILE_ID_LEN); - } - - e->u.r.inmem = inmem; - e->op = TXN_REMOVE; - TAILQ_INSERT_TAIL(&txn->events, e, links); - - return (0); - -err: if (e != NULL) - __os_free(dbenv, e); - - return (ret); -} - -/* - * __txn_remrem -- - * Remove a remove event because the remove has been superceeded, - * by a create of the same name, for example. - * - * PUBLIC: void __txn_remrem __P((DB_ENV *, DB_TXN *, const char *)); - */ -void -__txn_remrem(dbenv, txn, name) - DB_ENV *dbenv; - DB_TXN *txn; - const char *name; -{ - TXN_EVENT *e, *next_e; - - for (e = TAILQ_FIRST(&txn->events); e != NULL; e = next_e) { - next_e = TAILQ_NEXT(e, links); - if (e->op != TXN_REMOVE || strcmp(name, e->u.r.name) != 0) - continue; - TAILQ_REMOVE(&txn->events, e, links); - __os_free(dbenv, e->u.r.name); - if (e->u.r.fileid != NULL) - __os_free(dbenv, e->u.r.fileid); - __os_free(dbenv, e); - } - - return; -} - -/* - * __txn_lockevent -- - * - * Add a lockevent to the commit-queue. The lock event indicates a locker - * trade. - * - * PUBLIC: int __txn_lockevent __P((DB_ENV *, - * PUBLIC: DB_TXN *, DB *, DB_LOCK *, u_int32_t)); - */ -int -__txn_lockevent(dbenv, txn, dbp, lock, locker) - DB_ENV *dbenv; - DB_TXN *txn; - DB *dbp; - DB_LOCK *lock; - u_int32_t locker; -{ - int ret; - TXN_EVENT *e; - - if (!LOCKING_ON(dbenv)) - return (0); - - e = NULL; - if ((ret = __os_calloc(dbenv, 1, sizeof(TXN_EVENT), &e)) != 0) - return (ret); - - e->u.t.locker = locker; - e->u.t.lock = *lock; - e->u.t.dbp = dbp; - e->op = TXN_TRADE; - TAILQ_INSERT_TAIL(&txn->events, e, links); - - return (0); -} - -/* - * __txn_remlock -- - * Remove a lock event because the locker is going away. We can remove - * by lock (using offset) or by locker_id (or by both). - * - * PUBLIC: void __txn_remlock __P((DB_ENV *, DB_TXN *, DB_LOCK *, u_int32_t)); - */ -void -__txn_remlock(dbenv, txn, lock, locker) - DB_ENV *dbenv; - DB_TXN *txn; - DB_LOCK *lock; - u_int32_t locker; -{ - TXN_EVENT *e, *next_e; - - for (e = TAILQ_FIRST(&txn->events); e != NULL; e = next_e) { - next_e = TAILQ_NEXT(e, links); - if ((e->op != TXN_TRADE && e->op != TXN_TRADED) || - (e->u.t.lock.off != lock->off && e->u.t.locker != locker)) - continue; - TAILQ_REMOVE(&txn->events, e, links); - __os_free(dbenv, e); - } - - return; -} - -/* - * __txn_doevents -- - * Process the list of events associated with a transaction. On commit, - * apply the events; on abort, just toss the entries. - * - * PUBLIC: int __txn_doevents __P((DB_ENV *, DB_TXN *, int, int)); - */ -#define DO_TRADE do { \ - memset(&req, 0, sizeof(req)); \ - req.lock = e->u.t.lock; \ - req.op = DB_LOCK_TRADE; \ - t_ret = __lock_vec(dbenv, e->u.t.locker, 0, &req, 1, NULL); \ - if (t_ret == 0) \ - e->u.t.dbp->cur_lid = e->u.t.locker; \ - else if (t_ret == DB_NOTFOUND) \ - t_ret = 0; \ - if (t_ret != 0 && ret == 0) \ - ret = t_ret; \ - e->op = TXN_TRADED; \ -} while (0) - -int -__txn_doevents(dbenv, txn, opcode, preprocess) - DB_ENV *dbenv; - DB_TXN *txn; - int opcode, preprocess; -{ - DB_LOCKREQ req; - TXN_EVENT *e; - int ret, t_ret; - - ret = 0; - - /* - * This phase only gets called if we have a phase where we - * release read locks. Since not all paths will call this - * phase, we have to check for it below as well. So, when - * we do the trade, we update the opcode of the entry so that - * we don't try the trade again. - */ - if (preprocess) { - for (e = TAILQ_FIRST(&txn->events); - e != NULL; e = TAILQ_NEXT(e, links)) { - if (e->op != TXN_TRADE) - continue; - DO_TRADE; - } - return (ret); - } - - /* - * Prepare should only cause a preprocess, since the transaction - * isn't over. - */ - DB_ASSERT(opcode != TXN_PREPARE); - while ((e = TAILQ_FIRST(&txn->events)) != NULL) { - TAILQ_REMOVE(&txn->events, e, links); - /* - * Most deferred events should only happen on - * commits, not aborts or prepares. The one exception - * is a close which gets done on commit and abort, but - * not prepare. If we're not doing operations, then we - * can just go free resources. - */ - if (opcode == TXN_ABORT && e->op != TXN_CLOSE) - goto dofree; - switch (e->op) { - case TXN_CLOSE: - /* If we didn't abort this txn, we screwed up badly. */ - DB_ASSERT(opcode == TXN_ABORT); - if ((t_ret = __db_close(e->u.c.dbp, - NULL, DB_NOSYNC)) != 0 && ret == 0) - ret = t_ret; - break; - case TXN_REMOVE: - if (e->u.r.fileid != NULL) { - if ((t_ret = __memp_nameop(dbenv, - e->u.r.fileid, NULL, e->u.r.name, - NULL, e->u.r.inmem)) != 0 && ret == 0) - ret = t_ret; - } else if ((t_ret = - __os_unlink(dbenv, e->u.r.name)) != 0 && ret == 0) - ret = t_ret; - break; - case TXN_TRADE: - DO_TRADE; - /* Fall through */ - case TXN_TRADED: - /* Downgrade the lock. */ - if ((t_ret = __lock_downgrade(dbenv, - &e->u.t.lock, DB_LOCK_READ, 0)) != 0 && ret == 0) - ret = t_ret; - break; - default: - /* This had better never happen. */ - DB_ASSERT(0); - } -dofree: - /* Free resources here. */ - switch (e->op) { - case TXN_REMOVE: - if (e->u.r.fileid != NULL) - __os_free(dbenv, e->u.r.fileid); - __os_free(dbenv, e->u.r.name); - break; - case TXN_CLOSE: - case TXN_TRADE: - case TXN_TRADED: - default: - break; - } - __os_free(dbenv, e); - } - - return (ret); -} diff --git a/storage/bdb/xa/xa.c b/storage/bdb/xa/xa.c deleted file mode 100644 index 5ba4586f566..00000000000 --- a/storage/bdb/xa/xa.c +++ /dev/null @@ -1,689 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1998-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: xa.c,v 12.5 2005/11/01 00:44:39 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <stdlib.h> -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/txn.h" - -static int __db_xa_close __P((char *, int, long)); -static int __db_xa_commit __P((XID *, int, long)); -static int __db_xa_complete __P((int *, int *, int, long)); -static int __db_xa_end __P((XID *, int, long)); -static int __db_xa_forget __P((XID *, int, long)); -static int __db_xa_open __P((char *, int, long)); -static int __db_xa_prepare __P((XID *, int, long)); -static int __db_xa_recover __P((XID *, long, int, long)); -static int __db_xa_rollback __P((XID *, int, long)); -static int __db_xa_start __P((XID *, int, long)); -static int __xa_put_txn __P((DB_ENV *, DB_TXN *)); - -/* - * Possible flag values: - * Dynamic registration 0 => no dynamic registration - * TMREGISTER => dynamic registration - * Asynchronous operation 0 => no support for asynchrony - * TMUSEASYNC => async support - * Migration support 0 => migration of transactions across - * threads is possible - * TMNOMIGRATE => no migration across threads - */ -const struct xa_switch_t db_xa_switch = { - "Berkeley DB", /* name[RMNAMESZ] */ - TMNOMIGRATE, /* flags */ - 0, /* version */ - __db_xa_open, /* xa_open_entry */ - __db_xa_close, /* xa_close_entry */ - __db_xa_start, /* xa_start_entry */ - __db_xa_end, /* xa_end_entry */ - __db_xa_rollback, /* xa_rollback_entry */ - __db_xa_prepare, /* xa_prepare_entry */ - __db_xa_commit, /* xa_commit_entry */ - __db_xa_recover, /* xa_recover_entry */ - __db_xa_forget, /* xa_forget_entry */ - __db_xa_complete /* xa_complete_entry */ -}; - -/* - * If you want your XA server to be multi-threaded, then you must (at least) - * edit this file and change: - * #undef XA_MULTI_THREAD - * to: - * #define XA_MULTI_THREAD 1 - */ -#undef XA_MULTI_THREAD - -/* - * __xa_get_txn -- - * Return a pointer to the current transaction structure for the - * designated environment. If do_init is non-zero and we don't find a - * structure for the current thread, then create a new structure for it. - * - * PUBLIC: int __xa_get_txn __P((DB_ENV *, DB_TXN **, int)); - */ -int -__xa_get_txn(dbenv, txnp, do_init) - DB_ENV *dbenv; - DB_TXN **txnp; - int do_init; -{ -#ifdef XA_MULTI_THREAD - DB_TXN *t; - DB_TXNMGR *mgr; - TXN_DETAIL *td; - db_threadid_t tid; - pid_t pid; -#endif - int ret; - - ret = 0; - -#ifdef XA_MULTI_THREAD - dbenv->thread_id(dbenv, &pid, &tid); - *txnp = NULL; - - DB_ASSERT(dbenv->tx_handle != NULL); - mgr = (DB_TXNMGR *)dbenv->tx_handle; - - /* - * We need to protect the xa_txn linked list, but the environment does - * not have a mutex. Since we are in an XA transaction environment, - * we know there is a transaction structure, we can use its mutex. - */ - MUTEX_LOCK(dbenv, mgr->mutex); - for (t = TAILQ_FIRST(&dbenv->xa_txn); - t != NULL; - t = TAILQ_NEXT(t, xalinks)) { - td = t->td; - if (td->pid != pid) - continue; -#ifdef HAVE_INTEGRAL_THREAD_TYPE - if (t->tid == tid) { - *txnp = t; - break; - } -#else - if (memcmp(&t->tid, &tid, sizeof(tid)) == 0) { - *txnp = t; - break; - } -#endif - } - MUTEX_UNLOCK(dbenv, mgr->mutex); - - if (*txnp == NULL) { - if (!do_init) - ret = EINVAL; - else if ((ret = - __os_malloc(dbenv, sizeof(DB_TXN), txnp)) == 0) { - (*txnp)->tid = tid; - MUTEX_LOCK(dbenv, mgr->mutex); - TAILQ_INSERT_HEAD(&dbenv->xa_txn, *txnp, xalinks); - MUTEX_UNLOCK(dbenv, mgr->mutex); - } - } -#else - COMPQUIET(do_init, 0); - - *txnp = TAILQ_FIRST(&dbenv->xa_txn); - if (*txnp == NULL && - (ret = __os_calloc(dbenv, 1, sizeof(DB_TXN), txnp)) == 0) { - (*txnp)->txnid = TXN_INVALID; - TAILQ_INSERT_HEAD(&dbenv->xa_txn, *txnp, xalinks); - } -#endif - - return (ret); -} - -static int -__xa_put_txn(dbenv, txnp) - DB_ENV *dbenv; - DB_TXN *txnp; -{ -#ifdef XA_MULTI_THREAD - DB_TXNMGR *mgr; - mgr = (DB_TXNMGR *)dbenv->tx_handle; - - MUTEX_LOCK(dbenv, mgr->mutex); - TAILQ_REMOVE(&dbenv->xa_txn, txnp, xalinks); - MUTEX_UNLOCK(dbenv, mgr->mutex); - __os_free(dbenv, txnp); -#else - COMPQUIET(dbenv, NULL); - txnp->txnid = TXN_INVALID; -#endif - return (0); -} - -#ifdef XA_MULTI_THREAD -#define XA_FLAGS \ - (DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | \ - DB_INIT_TXN | DB_THREAD) -#else -#define XA_FLAGS \ - (DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | \ - DB_INIT_TXN) -#endif - -/* - * __db_xa_open -- - * The open call in the XA protocol. The rmid field is an id number - * that the TM assigned us and will pass us on every xa call. We need to - * map that rmid number into a dbenv structure that we create during - * initialization. Since this id number is thread specific, we do not - * need to store it in shared memory. The file xa_map.c implements all - * such xa->db mappings. - * The xa_info field is instance specific information. We require - * that the value of DB_HOME be passed in xa_info. Since xa_info is the - * only thing that we get to pass to db_env_create, any config information - * will have to be done via a config file instead of via the db_env_create - * call. - */ -static int -__db_xa_open(xa_info, rmid, arg_flags) - char *xa_info; - int rmid; - long arg_flags; -{ - DB_ENV *dbenv; - u_long flags; - - flags = (u_long)arg_flags; /* Conversion for bit operations. */ - - if (LF_ISSET(TMASYNC)) - return (XAER_ASYNC); - if (flags != TMNOFLAGS) - return (XAER_INVAL); - - /* Verify if we already have this environment open. */ - if (__db_rmid_to_env(rmid, &dbenv) == 0) - return (XA_OK); - - /* Open a new environment. */ - if (db_env_create(&dbenv, 0) != 0) - return (XAER_RMERR); - if (dbenv->open(dbenv, xa_info, XA_FLAGS, 0) != 0) - goto err; - - /* Create the mapping. */ - if (__db_map_rmid(rmid, dbenv) != 0) - goto err; - - /* Allocate space for the current transaction. */ - TAILQ_INIT(&dbenv->xa_txn); - - return (XA_OK); - -err: (void)dbenv->close(dbenv, 0); - - return (XAER_RMERR); -} - -/* - * __db_xa_close -- - * The close call of the XA protocol. The only trickiness here - * is that if there are any active transactions, we must fail. It is - * *not* an error to call close on an environment that has already been - * closed (I am interpreting that to mean it's OK to call close on an - * environment that has never been opened). - */ -static int -__db_xa_close(xa_info, rmid, arg_flags) - char *xa_info; - int rmid; - long arg_flags; -{ - DB_ENV *dbenv; - DB_TXN *t; - int ret, t_ret; - u_long flags; - - COMPQUIET(xa_info, NULL); - - flags = (u_long)arg_flags; /* Conversion for bit operations. */ - - if (LF_ISSET(TMASYNC)) - return (XAER_ASYNC); - if (flags != TMNOFLAGS) - return (XAER_INVAL); - - /* If the environment is closed, then we're done. */ - if (__db_rmid_to_env(rmid, &dbenv) != 0) - return (XA_OK); - - /* Check if there are any pending transactions. */ - if ((t = TAILQ_FIRST(&dbenv->xa_txn)) != NULL && - t->txnid != TXN_INVALID) - return (XAER_PROTO); - - /* Destroy the mapping. */ - ret = __db_unmap_rmid(rmid); - - /* Discard space held for the current transaction. */ - while ((t = TAILQ_FIRST(&dbenv->xa_txn)) != NULL) { - TAILQ_REMOVE(&dbenv->xa_txn, t, xalinks); - __os_free(dbenv, t); - } - - /* Close the environment. */ - if ((t_ret = dbenv->close(dbenv, 0)) != 0 && ret == 0) - ret = t_ret; - - return (ret == 0 ? XA_OK : XAER_RMERR); -} - -/* - * __db_xa_start -- - * Begin a transaction for the current resource manager. - */ -static int -__db_xa_start(xid, rmid, arg_flags) - XID *xid; - int rmid; - long arg_flags; -{ - DB_ENV *dbenv; - DB_TXN *txnp; - TXN_DETAIL *td; - roff_t off; - u_long flags; - int is_known; - - flags = (u_long)arg_flags; /* Conversion for bit operations. */ - -#define OK_FLAGS (TMJOIN | TMRESUME | TMNOWAIT | TMASYNC | TMNOFLAGS) - if (LF_ISSET(~OK_FLAGS)) - return (XAER_INVAL); - - if (LF_ISSET(TMJOIN) && LF_ISSET(TMRESUME)) - return (XAER_INVAL); - - if (LF_ISSET(TMASYNC)) - return (XAER_ASYNC); - - if (__db_rmid_to_env(rmid, &dbenv) != 0) - return (XAER_PROTO); - - is_known = __db_xid_to_txn(dbenv, xid, &off) == 0; - - if (is_known && !LF_ISSET(TMRESUME) && !LF_ISSET(TMJOIN)) - return (XAER_DUPID); - - if (!is_known && LF_ISSET(TMRESUME | TMJOIN)) - return (XAER_NOTA); - - /* - * This can't block, so we can ignore TMNOWAIT. - * - * Other error conditions: RMERR, RMFAIL, OUTSIDE, PROTO, RB* - */ - if (is_known) { - td = R_ADDR(&((DB_TXNMGR *)dbenv->tx_handle)->reginfo, off); - if (td->xa_status == TXN_XA_SUSPENDED && - !LF_ISSET(TMRESUME | TMJOIN)) - return (XAER_PROTO); - if (td->xa_status == TXN_XA_DEADLOCKED) - return (XA_RBDEADLOCK); - if (td->xa_status == TXN_XA_ABORTED) - return (XA_RBOTHER); - - /* Now, fill in the global transaction structure. */ - if (__xa_get_txn(dbenv, &txnp, 1) != 0) - return (XAER_RMERR); - __txn_continue(dbenv, txnp, td); - td->xa_status = TXN_XA_STARTED; - } else { - if (__xa_get_txn(dbenv, &txnp, 1) != 0) - return (XAER_RMERR); - if (__txn_xa_begin(dbenv, txnp)) - return (XAER_RMERR); - (void)__db_map_xid(dbenv, xid, txnp->td); - td = txnp->td; - td->xa_status = TXN_XA_STARTED; - } - return (XA_OK); -} - -/* - * __db_xa_end -- - * Disassociate the current transaction from the current process. - */ -static int -__db_xa_end(xid, rmid, flags) - XID *xid; - int rmid; - long flags; -{ - DB_ENV *dbenv; - DB_TXN *txn; - TXN_DETAIL *td; - roff_t off; - - if (flags != TMNOFLAGS && !LF_ISSET(TMSUSPEND | TMSUCCESS | TMFAIL)) - return (XAER_INVAL); - - if (__db_rmid_to_env(rmid, &dbenv) != 0) - return (XAER_PROTO); - - if (__db_xid_to_txn(dbenv, xid, &off) != 0) - return (XAER_NOTA); - - if (__xa_get_txn(dbenv, &txn, 0) != 0) - return (XAER_RMERR); - - td = R_ADDR(&((DB_TXNMGR *)dbenv->tx_handle)->reginfo, off); - if (td != txn->td) - return (XAER_PROTO); - - if (td->xa_status == TXN_XA_DEADLOCKED) - return (XA_RBDEADLOCK); - - if (td->status == TXN_ABORTED) - return (XA_RBOTHER); - - if (td->xa_status != TXN_XA_STARTED) - return (XAER_PROTO); - - /* - * If we ever support XA migration, we cannot keep SUSPEND/END - * status in the shared region; it would have to be process local. - */ - if (LF_ISSET(TMSUSPEND)) - td->xa_status = TXN_XA_SUSPENDED; - else - td->xa_status = TXN_XA_ENDED; - - /* - * XXX - * This can fail in XA_MULTI_THREAD mode. - */ - (void)__xa_put_txn(dbenv, txn); - return (XA_OK); -} - -/* - * __db_xa_prepare -- - * Sync the log to disk so we can guarantee recoverability. - */ -static int -__db_xa_prepare(xid, rmid, arg_flags) - XID *xid; - int rmid; - long arg_flags; -{ - DB_ENV *dbenv; - DB_TXN *txnp; - TXN_DETAIL *td; - roff_t off; - u_long flags; - - flags = (u_long)arg_flags; /* Conversion for bit operations. */ - - if (LF_ISSET(TMASYNC)) - return (XAER_ASYNC); - if (flags != TMNOFLAGS) - return (XAER_INVAL); - - /* - * We need to know if we've ever called prepare on this. - * As part of the prepare, we set the xa_status field to - * reflect that fact that prepare has been called, and if - * it's ever called again, it's an error. - */ - if (__db_rmid_to_env(rmid, &dbenv) != 0) - return (XAER_PROTO); - - if (__db_xid_to_txn(dbenv, xid, &off) != 0) - return (XAER_NOTA); - td = R_ADDR(&((DB_TXNMGR *)dbenv->tx_handle)->reginfo, off); - if (td->xa_status == TXN_XA_DEADLOCKED) - return (XA_RBDEADLOCK); - - if (td->xa_status != TXN_XA_ENDED && td->xa_status != TXN_XA_SUSPENDED) - return (XAER_PROTO); - - /* Now, fill in the global transaction structure. */ - if (__xa_get_txn(dbenv, &txnp, 0) != 0) - return (XAER_PROTO); - __txn_continue(dbenv, txnp, td); - - if (txnp->prepare(txnp, (u_int8_t *)xid->data) != 0) - return (XAER_RMERR); - - td->xa_status = TXN_XA_PREPARED; - - /* - * XXX - * This can fail in XA_MULTI_THREAD mode. - */ - (void)__xa_put_txn(dbenv, txnp); - return (XA_OK); -} - -/* - * __db_xa_commit -- - * Commit the transaction - */ -static int -__db_xa_commit(xid, rmid, arg_flags) - XID *xid; - int rmid; - long arg_flags; -{ - DB_ENV *dbenv; - DB_TXN *txnp; - TXN_DETAIL *td; - roff_t off; - u_long flags; - - flags = (u_long)arg_flags; /* Conversion for bit operations. */ - - if (LF_ISSET(TMASYNC)) - return (XAER_ASYNC); -#undef OK_FLAGS -#define OK_FLAGS (TMNOFLAGS | TMNOWAIT | TMONEPHASE) - if (LF_ISSET(~OK_FLAGS)) - return (XAER_INVAL); - - /* - * We need to know if we've ever called prepare on this. - * We can verify this by examining the xa_status field. - */ - if (__db_rmid_to_env(rmid, &dbenv) != 0) - return (XAER_PROTO); - - if (__db_xid_to_txn(dbenv, xid, &off) != 0) - return (XAER_NOTA); - - td = R_ADDR(&((DB_TXNMGR *)dbenv->tx_handle)->reginfo, off); - if (td->xa_status == TXN_XA_DEADLOCKED) - return (XA_RBDEADLOCK); - - if (td->xa_status == TXN_XA_ABORTED) - return (XA_RBOTHER); - - if (LF_ISSET(TMONEPHASE) && - td->xa_status != TXN_XA_ENDED && td->xa_status != TXN_XA_SUSPENDED) - return (XAER_PROTO); - - if (!LF_ISSET(TMONEPHASE) && td->xa_status != TXN_XA_PREPARED) - return (XAER_PROTO); - - /* Now, fill in the global transaction structure. */ - if (__xa_get_txn(dbenv, &txnp, 0) != 0) - return (XAER_RMERR); - __txn_continue(dbenv, txnp, td); - - if (txnp->commit(txnp, 0) != 0) - return (XAER_RMERR); - - /* - * XXX - * This can fail in XA_MULTI_THREAD mode. - */ - (void)__xa_put_txn(dbenv, txnp); - return (XA_OK); -} - -/* - * __db_xa_recover -- - * Returns a list of prepared and heuristically completed transactions. - * - * The return value is the number of xids placed into the xid array (less - * than or equal to the count parameter). The flags are going to indicate - * whether we are starting a scan or continuing one. - */ -static int -__db_xa_recover(xids, count, rmid, flags) - XID *xids; - long count, flags; - int rmid; -{ - DB_ENV *dbenv; - u_int32_t newflags; - long rval; - - /* If the environment is closed, then we're done. */ - if (__db_rmid_to_env(rmid, &dbenv) != 0) - return (XAER_PROTO); - - if (LF_ISSET(TMSTARTRSCAN)) - newflags = DB_FIRST; - else if (LF_ISSET(TMENDRSCAN)) - newflags = DB_LAST; - else - newflags = DB_NEXT; - - rval = 0; - if (__txn_get_prepared(dbenv, xids, NULL, count, &rval, newflags) != 0) - return (XAER_RMERR); - else - return (rval); -} - -/* - * __db_xa_rollback - * Abort an XA transaction. - */ -static int -__db_xa_rollback(xid, rmid, arg_flags) - XID *xid; - int rmid; - long arg_flags; -{ - DB_ENV *dbenv; - DB_TXN *txnp; - TXN_DETAIL *td; - roff_t off; - u_long flags; - - flags = (u_long)arg_flags; /* Conversion for bit operations. */ - - if (LF_ISSET(TMASYNC)) - return (XAER_ASYNC); - if (flags != TMNOFLAGS) - return (XAER_INVAL); - - if (__db_rmid_to_env(rmid, &dbenv) != 0) - return (XAER_PROTO); - - if (__db_xid_to_txn(dbenv, xid, &off) != 0) - return (XAER_NOTA); - - td = R_ADDR(&((DB_TXNMGR *)dbenv->tx_handle)->reginfo, off); - if (td->xa_status == TXN_XA_DEADLOCKED) - return (XA_RBDEADLOCK); - - if (td->xa_status == TXN_XA_ABORTED) - return (XA_RBOTHER); - - if (td->xa_status != TXN_XA_ENDED && - td->xa_status != TXN_XA_SUSPENDED && - td->xa_status != TXN_XA_PREPARED) - return (XAER_PROTO); - - /* Now, fill in the global transaction structure. */ - if (__xa_get_txn(dbenv, &txnp, 0) != 0) - return (XAER_RMERR); - __txn_continue(dbenv, txnp, td); - if (txnp->abort(txnp) != 0) - return (XAER_RMERR); - - /* - * XXX - * This can fail in XA_MULTI_THREAD mode. - */ - (void)__xa_put_txn(dbenv, txnp); - return (XA_OK); -} - -/* - * __db_xa_forget -- - * Forget about an XID for a transaction that was heuristically - * completed. Since we do not heuristically complete anything, I - * don't think we have to do anything here, but we should make sure - * that we reclaim the slots in the txnid table. - */ -static int -__db_xa_forget(xid, rmid, arg_flags) - XID *xid; - int rmid; - long arg_flags; -{ - DB_ENV *dbenv; - roff_t off; - u_long flags; - - flags = (u_long)arg_flags; /* Conversion for bit operations. */ - - if (LF_ISSET(TMASYNC)) - return (XAER_ASYNC); - if (flags != TMNOFLAGS) - return (XAER_INVAL); - - if (__db_rmid_to_env(rmid, &dbenv) != 0) - return (XAER_PROTO); - - /* - * If mapping is gone, then we're done. - */ - if (__db_xid_to_txn(dbenv, xid, &off) != 0) - return (XA_OK); - - __db_unmap_xid(dbenv, xid, off); - - /* No fatal value that would require an XAER_RMFAIL. */ - return (XA_OK); -} - -/* - * __db_xa_complete -- - * Used to wait for asynchronous operations to complete. Since we're - * not doing asynch, this is an invalid operation. - */ -static int -__db_xa_complete(handle, retval, rmid, flags) - int *handle, *retval, rmid; - long flags; -{ - COMPQUIET(handle, NULL); - COMPQUIET(retval, NULL); - COMPQUIET(rmid, 0); - COMPQUIET(flags, 0); - - return (XAER_INVAL); -} diff --git a/storage/bdb/xa/xa_db.c b/storage/bdb/xa/xa_db.c deleted file mode 100644 index 54751900c11..00000000000 --- a/storage/bdb/xa/xa_db.c +++ /dev/null @@ -1,243 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1998-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: xa_db.c,v 12.4 2005/10/20 18:57:16 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> -#endif - -#include "db_int.h" -#include "dbinc/txn.h" - -static int __xa_close __P((DB *, u_int32_t)); -static int __xa_cursor __P((DB *, DB_TXN *, DBC **, u_int32_t)); -static int __xa_del __P((DB *, DB_TXN *, DBT *, u_int32_t)); -static int __xa_get __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); -static int __xa_open __P((DB *, DB_TXN *, - const char *, const char *, DBTYPE, u_int32_t, int)); -static int __xa_put __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); -static int __xa_set_txn __P((DB *, DB_TXN **, int)); -static int __xa_truncate __P((DB *, DB_TXN *, u_int32_t *, u_int32_t)); - -typedef struct __xa_methods { - int (*close) __P((DB *, u_int32_t)); - int (*cursor) __P((DB *, DB_TXN *, DBC **, u_int32_t)); - int (*del) __P((DB *, DB_TXN *, DBT *, u_int32_t)); - int (*get) __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); - int (*open) __P((DB *, DB_TXN *, - const char *, const char *, DBTYPE, u_int32_t, int)); - int (*put) __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t)); - int (*truncate) __P((DB *, DB_TXN *, u_int32_t *, u_int32_t)); -} XA_METHODS; - -/* - * __xa_set_txn -- - * Find a transaction handle. - */ -static int -__xa_set_txn(dbp, txnpp, no_xa_txn) - DB *dbp; - DB_TXN **txnpp; - int no_xa_txn; -{ - DB_ENV *dbenv; - int ret; - - dbenv = dbp->dbenv; - - /* - * It doesn't make sense for a server to specify a DB_TXN handle. - * As the server can't know if other operations it has done have - * committed/aborted, it can self-deadlock. If the server wants - * other transactions, it can open other DB handles and use them. - * Disallow specified DB_TXN handles. - */ - if (*txnpp != NULL) { - __db_err(dbenv, - "transaction handles should not be directly specified to XA interfaces"); - return (EINVAL); - } - - /* See if the TM has declared a transaction. */ - if ((ret = __xa_get_txn(dbenv, txnpp, 0)) != 0) - return (ret); - if ((*txnpp)->txnid != TXN_INVALID) - return (0); - - /* - * We may be opening databases in the server initialization routine. - * In that case, it's reasonable not to have an XA transaction. It's - * also reasonable to open a database as part of an XA transaction, - * allow both. - */ - if (no_xa_txn) { - *txnpp = NULL; - return (0); - } - - __db_err(dbenv, "no XA transaction declared"); - return (EINVAL); -} - -/* - * __db_xa_create -- - * DB XA constructor. - * - * PUBLIC: int __db_xa_create __P((DB *)); - */ -int -__db_xa_create(dbp) - DB *dbp; -{ - XA_METHODS *xam; - int ret; - - /* - * Allocate the XA internal structure, and wrap the open and close - * calls. - */ - if ((ret = __os_calloc(dbp->dbenv, 1, sizeof(XA_METHODS), &xam)) != 0) - return (ret); - - dbp->xa_internal = xam; - xam->open = dbp->open; - dbp->open = __xa_open; - xam->close = dbp->close; - dbp->close = __xa_close; - - return (0); -} - -/* - * __xa_open -- - * XA open wrapper. - */ -static int -__xa_open(dbp, txn, name, subdb, type, flags, mode) - DB *dbp; - DB_TXN *txn; - const char *name, *subdb; - DBTYPE type; - u_int32_t flags; - int mode; -{ - XA_METHODS *xam; - int ret; - - xam = (XA_METHODS *)dbp->xa_internal; - - if ((ret = - __xa_set_txn(dbp, &txn, LF_ISSET(DB_AUTO_COMMIT) ? 1 : 0)) != 0) - return (ret); - if ((ret = xam->open(dbp, txn, name, subdb, type, flags, mode)) != 0) - return (ret); - - /* Wrap any DB handle method that takes a TXN ID as an argument. */ - xam->cursor = dbp->cursor; - xam->del = dbp->del; - xam->get = dbp->get; - xam->put = dbp->put; - xam->truncate = dbp->truncate; - dbp->cursor = __xa_cursor; - dbp->del = __xa_del; - dbp->get = __xa_get; - dbp->put = __xa_put; - dbp->truncate = __xa_truncate; - - return (0); -} - -static int -__xa_cursor(dbp, txn, dbcp, flags) - DB *dbp; - DB_TXN *txn; - DBC **dbcp; - u_int32_t flags; -{ - int ret; - - if ((ret = __xa_set_txn(dbp, &txn, 0)) != 0) - return (ret); - return (((XA_METHODS *) - dbp->xa_internal)->cursor(dbp, txn, dbcp, flags)); -} - -static int -__xa_del(dbp, txn, key, flags) - DB *dbp; - DB_TXN *txn; - DBT *key; - u_int32_t flags; -{ - int ret; - - if ((ret = __xa_set_txn(dbp, &txn, 0)) != 0) - return (ret); - return (((XA_METHODS *)dbp->xa_internal)->del(dbp, txn, key, flags)); -} - -static int -__xa_close(dbp, flags) - DB *dbp; - u_int32_t flags; -{ - int (*real_close) __P((DB *, u_int32_t)); - - real_close = ((XA_METHODS *)dbp->xa_internal)->close; - - __os_free(dbp->dbenv, dbp->xa_internal); - dbp->xa_internal = NULL; - - return (real_close(dbp, flags)); -} - -static int -__xa_get(dbp, txn, key, data, flags) - DB *dbp; - DB_TXN *txn; - DBT *key, *data; - u_int32_t flags; -{ - int ret; - - if ((ret = __xa_set_txn(dbp, &txn, 0)) != 0) - return (ret); - return (((XA_METHODS *) - dbp->xa_internal)->get(dbp, txn, key, data, flags)); -} - -static int -__xa_put(dbp, txn, key, data, flags) - DB *dbp; - DB_TXN *txn; - DBT *key, *data; - u_int32_t flags; -{ - int ret; - - if ((ret = __xa_set_txn(dbp, &txn, 0)) != 0) - return (ret); - return (((XA_METHODS *) - dbp->xa_internal)->put(dbp, txn, key, data, flags)); -} - -static int -__xa_truncate(dbp, txn, countp, flags) - DB *dbp; - DB_TXN *txn; - u_int32_t *countp, flags; -{ - int ret; - - if ((ret = __xa_set_txn(dbp, &txn, 0)) != 0) - return (ret); - return (((XA_METHODS *) - dbp->xa_internal)->truncate(dbp, txn, countp, flags)); -} diff --git a/storage/bdb/xa/xa_map.c b/storage/bdb/xa/xa_map.c deleted file mode 100644 index f2bce94f252..00000000000 --- a/storage/bdb/xa/xa_map.c +++ /dev/null @@ -1,160 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2005 - * Sleepycat Software. All rights reserved. - * - * $Id: xa_map.c,v 12.4 2005/10/13 20:42:34 bostic Exp $ - */ - -#include "db_config.h" - -#ifndef NO_SYSTEM_INCLUDES -#include <sys/types.h> - -#include <string.h> -#endif - -#include "db_int.h" -#include "dbinc/txn.h" - -/* - * This file contains all the mapping information that we need to support - * the DB/XA interface. - */ - -/* - * __db_rmid_to_env - * Return the environment associated with a given XA rmid. - * - * PUBLIC: int __db_rmid_to_env __P((int rmid, DB_ENV **envp)); - */ -int -__db_rmid_to_env(rmid, dbenvp) - int rmid; - DB_ENV **dbenvp; -{ - DB_ENV *dbenv; - - dbenv = TAILQ_FIRST(&DB_GLOBAL(db_envq)); - if (dbenv != NULL && dbenv->xa_rmid == rmid) { - *dbenvp = dbenv; - return (0); - } - - /* - * When we map an rmid, move that environment to be the first one in - * the list of environments, so we acquire the correct environment - * in DB->open. - */ - for (; dbenv != NULL; dbenv = TAILQ_NEXT(dbenv, links)) - if (dbenv->xa_rmid == rmid) { - TAILQ_REMOVE(&DB_GLOBAL(db_envq), dbenv, links); - TAILQ_INSERT_HEAD(&DB_GLOBAL(db_envq), dbenv, links); - *dbenvp = dbenv; - return (0); - } - - return (1); -} - -/* - * __db_xid_to_txn - * Return the txn that corresponds to this XID. - * - * PUBLIC: int __db_xid_to_txn __P((DB_ENV *, XID *, roff_t *)); - */ -int -__db_xid_to_txn(dbenv, xid, offp) - DB_ENV *dbenv; - XID *xid; - roff_t *offp; -{ - struct __txn_detail *td; - - return (__txn_map_gid(dbenv, (u_int8_t *)xid->data, &td, offp)); -} - -/* - * __db_map_rmid - * Create a mapping between the specified rmid and environment. - * - * PUBLIC: int __db_map_rmid __P((int, DB_ENV *)); - */ -int -__db_map_rmid(rmid, dbenv) - int rmid; - DB_ENV *dbenv; -{ - dbenv->xa_rmid = rmid; - TAILQ_INSERT_TAIL(&DB_GLOBAL(db_envq), dbenv, links); - return (0); -} - -/* - * __db_unmap_rmid - * Destroy the mapping for the given rmid. - * - * PUBLIC: int __db_unmap_rmid __P((int)); - */ -int -__db_unmap_rmid(rmid) - int rmid; -{ - DB_ENV *e; - - for (e = TAILQ_FIRST(&DB_GLOBAL(db_envq)); - e->xa_rmid != rmid; - e = TAILQ_NEXT(e, links)) - ; - - if (e == NULL) - return (EINVAL); - - TAILQ_REMOVE(&DB_GLOBAL(db_envq), e, links); - return (0); -} - -/* - * __db_map_xid - * Create a mapping between this XID and the transaction - * "td" in the shared region. - * - * PUBLIC: int __db_map_xid __P((DB_ENV *, XID *, TXN_DETAIL *)); - */ -int -__db_map_xid(dbenv, xid, td) - DB_ENV *dbenv; - XID *xid; - TXN_DETAIL *td; -{ - TXN_SYSTEM_LOCK(dbenv); - memcpy(td->xid, xid->data, XIDDATASIZE); - td->bqual = (u_int32_t)xid->bqual_length; - td->gtrid = (u_int32_t)xid->gtrid_length; - td->format = (int32_t)xid->formatID; - TXN_SYSTEM_UNLOCK(dbenv); - - return (0); -} - -/* - * __db_unmap_xid - * Destroy the mapping for the specified XID. - * - * PUBLIC: void __db_unmap_xid __P((DB_ENV *, XID *, size_t)); - */ - -void -__db_unmap_xid(dbenv, xid, off) - DB_ENV *dbenv; - XID *xid; - size_t off; -{ - TXN_DETAIL *td; - - COMPQUIET(xid, NULL); - - td = R_ADDR(&((DB_TXNMGR *)dbenv->tx_handle)->reginfo, off); - memset(td->xid, 0, sizeof(td->xid)); -} |