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

db_method.c

00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 1999-2005
00005  *      Sleepycat Software.  All rights reserved.
00006  *
00007  * $Id: db_method.c,v 12.15 2005/11/08 03:24:58 bostic Exp $
00008  */
00009 
00010 #include "db_config.h"
00011 
00012 #ifndef NO_SYSTEM_INCLUDES
00013 #include <sys/types.h>
00014 
00015 #ifdef HAVE_RPC
00016 #include <rpc/rpc.h>
00017 #endif
00018 
00019 #include <string.h>
00020 #endif
00021 
00022 #ifdef HAVE_RPC
00023 #include "db_server.h"
00024 #endif
00025 
00026 #include "db_int.h"
00027 #include "dbinc/crypto.h"
00028 #include "dbinc/db_page.h"
00029 #include "dbinc/db_shash.h"
00030 #include "dbinc/btree.h"
00031 #include "dbinc/hash.h"
00032 #include "dbinc/lock.h"
00033 #include "dbinc/mp.h"
00034 #include "dbinc/qam.h"
00035 #include "dbinc/txn.h"
00036 
00037 #ifdef HAVE_RPC
00038 #include "dbinc_auto/rpc_client_ext.h"
00039 #endif
00040 
00041 static int  __db_get_byteswapped __P((DB *, int *));
00042 static int  __db_get_dbname __P((DB *, const char **, const char **));
00043 static DB_ENV *__db_get_env __P((DB *));
00044 static DB_MPOOLFILE *__db_get_mpf __P((DB *));
00045 static int  __db_get_transactional __P((DB *));
00046 static int  __db_get_type __P((DB *, DBTYPE *dbtype));
00047 static int  __db_init __P((DB_ENV *, DB *, u_int32_t));
00048 static int  __db_set_alloc __P((DB *, void *(*)(size_t),
00049                 void *(*)(void *, size_t), void (*)(void *)));
00050 static int  __db_set_append_recno __P((DB *, int (*)(DB *, DBT *, db_recno_t)));
00051 static int  __db_get_cachesize __P((DB *, u_int32_t *, u_int32_t *, int *));
00052 static int  __db_set_cachesize __P((DB *, u_int32_t, u_int32_t, int));
00053 static int  __db_set_dup_compare
00054                 __P((DB *, int (*)(DB *, const DBT *, const DBT *)));
00055 static int  __db_get_encrypt_flags __P((DB *, u_int32_t *));
00056 static int  __db_set_encrypt __P((DB *, const char *, u_int32_t));
00057 static int  __db_set_feedback __P((DB *, void (*)(DB *, int, int)));
00058 static void __db_map_flags __P((DB *, u_int32_t *, u_int32_t *));
00059 static int  __db_get_pagesize __P((DB *, u_int32_t *));
00060 static int  __db_set_paniccall __P((DB *, void (*)(DB_ENV *, int)));
00061 static void __db_set_errcall
00062               __P((DB *, void (*)(const DB_ENV *, const char *, const char *)));
00063 static void __db_get_errfile __P((DB *, FILE **));
00064 static void __db_set_errfile __P((DB *, FILE *));
00065 static void __db_get_errpfx __P((DB *, const char **));
00066 static void __db_set_errpfx __P((DB *, const char *));
00067 static void __db_set_msgcall
00068               __P((DB *, void (*)(const DB_ENV *, const char *)));
00069 static void __db_get_msgfile __P((DB *, FILE **));
00070 static void __db_set_msgfile __P((DB *, FILE *));
00071 static void __dbh_err __P((DB *, int, const char *, ...));
00072 static void __dbh_errx __P((DB *, const char *, ...));
00073 
00074 /*
00075  * db_create --
00076  *      DB constructor.
00077  *
00078  * EXTERN: int db_create __P((DB **, DB_ENV *, u_int32_t));
00079  */
00080 int
00081 db_create(dbpp, dbenv, flags)
00082         DB **dbpp;
00083         DB_ENV *dbenv;
00084         u_int32_t flags;
00085 {
00086         DB *dbp;
00087         DB_THREAD_INFO *ip;
00088         DB_REP *db_rep;
00089         int ret;
00090 
00091         /* Check for invalid function flags. */
00092         switch (flags) {
00093         case 0:
00094                 break;
00095         case DB_XA_CREATE:
00096                 if (dbenv != NULL) {
00097                         __db_err(dbenv,
00098                 "XA applications may not specify an environment to db_create");
00099                         return (EINVAL);
00100                 }
00101 
00102                 /*
00103                  * If it's an XA database, open it within the XA environment,
00104                  * taken from the global list of environments.  (When the XA
00105                  * transaction manager called our xa_start() routine the
00106                  * "current" environment was moved to the start of the list.
00107                  */
00108                 dbenv = TAILQ_FIRST(&DB_GLOBAL(db_envq));
00109                 break;
00110         default:
00111                 return (__db_ferr(dbenv, "db_create", 0));
00112         }
00113 
00114         ip = NULL;
00115         if (dbenv != NULL)
00116                 ENV_ENTER(dbenv, ip);
00117         /* Allocate the DB. */
00118         if ((ret = __os_calloc(dbenv, 1, sizeof(*dbp), &dbp)) != 0) {
00119                 if (dbenv != NULL)
00120                         ENV_LEAVE(dbenv, ip);
00121                 return (ret);
00122         }
00123 
00124         if ((ret = __db_init(dbenv, dbp, flags)) != 0)
00125                 goto err;
00126 
00127         /* If we don't have an environment yet, allocate a local one. */
00128         if (dbenv == NULL) {
00129                 if ((ret = db_env_create(&dbenv, 0)) != 0)
00130                         goto err;
00131                 F_SET(dbenv, DB_ENV_DBLOCAL);
00132                 ENV_ENTER(dbenv, ip);
00133         }
00134         dbp->dbenv = dbenv;
00135         MUTEX_LOCK(dbenv, dbenv->mtx_dblist);
00136         ++dbenv->db_ref;
00137         MUTEX_UNLOCK(dbenv, dbenv->mtx_dblist);
00138 
00139         /*
00140          * Set the replication timestamp; it's 0 if we're not in a replicated
00141          * environment.  Don't acquire a lock to read the value, even though
00142          * it's opaque: all we check later is value equality, nothing else.
00143          */
00144         dbp->timestamp = REP_ON(dbenv) ?
00145             ((REGENV *)((REGINFO *)dbenv->reginfo)->primary)->rep_timestamp : 0;
00146         /*
00147          * Set the replication generation number for fid management; valid
00148          * replication generations start at 1.  Don't acquire a lock to
00149          * read the value.  All we check later is value equality.
00150          */
00151         db_rep = dbenv->rep_handle;
00152         dbp->fid_gen =
00153             (REP_ON(dbenv) && db_rep->region != NULL) ?
00154             ((REP *)db_rep->region)->gen : 0;
00155 
00156         /* If not RPC, open a backing DB_MPOOLFILE handle in the memory pool. */
00157         if (!RPC_ON(dbenv) &&
00158             (ret = __memp_fcreate(dbenv, &dbp->mpf)) != 0)
00159                 goto err;
00160 
00161         dbp->type = DB_UNKNOWN;
00162 
00163         *dbpp = dbp;
00164         return (0);
00165 
00166 err:    if (dbp->mpf != NULL)
00167                 (void)__memp_fclose(dbp->mpf, 0);
00168         if (dbenv != NULL && F_ISSET(dbenv, DB_ENV_DBLOCAL))
00169                 (void)__env_close(dbenv, 0);
00170         __os_free(dbenv, dbp);
00171         *dbpp = NULL;
00172         ENV_LEAVE(dbenv, ip);
00173         return (ret);
00174 }
00175 
00176 /*
00177  * __db_init --
00178  *      Initialize a DB structure.
00179  */
00180 static int
00181 __db_init(dbenv, dbp, flags)
00182         DB_ENV *dbenv;
00183         DB *dbp;
00184         u_int32_t flags;
00185 {
00186         int ret;
00187 
00188         dbp->lid = DB_LOCK_INVALIDID;
00189         LOCK_INIT(dbp->handle_lock);
00190 
00191         TAILQ_INIT(&dbp->free_queue);
00192         TAILQ_INIT(&dbp->active_queue);
00193         TAILQ_INIT(&dbp->join_queue);
00194         LIST_INIT(&dbp->s_secondaries);
00195 
00196         FLD_SET(dbp->am_ok,
00197             DB_OK_BTREE | DB_OK_HASH | DB_OK_QUEUE | DB_OK_RECNO);
00198 
00199         /* DB PUBLIC HANDLE LIST BEGIN */
00200         dbp->associate = __db_associate_pp;
00201         dbp->close = __db_close_pp;
00202         dbp->compact = __db_compact_pp;
00203         dbp->cursor = __db_cursor_pp;
00204         dbp->del = __db_del_pp;
00205         dbp->dump = __db_dump_pp;
00206         dbp->err = __dbh_err;
00207         dbp->errx = __dbh_errx;
00208         dbp->fd = __db_fd_pp;
00209         dbp->get = __db_get_pp;
00210         dbp->get_byteswapped = __db_get_byteswapped;
00211         dbp->get_cachesize = __db_get_cachesize;
00212         dbp->get_dbname = __db_get_dbname;
00213         dbp->get_encrypt_flags = __db_get_encrypt_flags;
00214         dbp->get_env = __db_get_env;
00215         dbp->get_errfile = __db_get_errfile;
00216         dbp->get_errpfx = __db_get_errpfx;
00217         dbp->get_flags = __db_get_flags;
00218         dbp->get_lorder = __db_get_lorder;
00219         dbp->get_mpf = __db_get_mpf;
00220         dbp->get_msgfile = __db_get_msgfile;
00221         dbp->get_open_flags = __db_get_open_flags;
00222         dbp->get_pagesize = __db_get_pagesize;
00223         dbp->get_transactional = __db_get_transactional;
00224         dbp->get_type = __db_get_type;
00225         dbp->join = __db_join_pp;
00226         dbp->key_range = __db_key_range_pp;
00227         dbp->open = __db_open_pp;
00228         dbp->pget = __db_pget_pp;
00229         dbp->put = __db_put_pp;
00230         dbp->remove = __db_remove_pp;
00231         dbp->rename = __db_rename_pp;
00232         dbp->set_alloc = __db_set_alloc;
00233         dbp->set_append_recno = __db_set_append_recno;
00234         dbp->set_cachesize = __db_set_cachesize;
00235         dbp->set_dup_compare = __db_set_dup_compare;
00236         dbp->set_encrypt = __db_set_encrypt;
00237         dbp->set_errcall = __db_set_errcall;
00238         dbp->set_errfile = __db_set_errfile;
00239         dbp->set_errpfx = __db_set_errpfx;
00240         dbp->set_feedback = __db_set_feedback;
00241         dbp->set_flags = __db_set_flags;
00242         dbp->set_lorder = __db_set_lorder;
00243         dbp->set_msgcall = __db_set_msgcall;
00244         dbp->set_msgfile = __db_set_msgfile;
00245         dbp->set_pagesize = __db_set_pagesize;
00246         dbp->set_paniccall = __db_set_paniccall;
00247         dbp->stat = __db_stat_pp;
00248         dbp->stat_print = __db_stat_print_pp;
00249         dbp->sync = __db_sync_pp;
00250         dbp->truncate = __db_truncate_pp;
00251         dbp->upgrade = __db_upgrade_pp;
00252         dbp->verify = __db_verify_pp;
00253         /* DB PUBLIC HANDLE LIST END */
00254 
00255                                         /* Access method specific. */
00256         if ((ret = __bam_db_create(dbp)) != 0)
00257                 return (ret);
00258         if ((ret = __ham_db_create(dbp)) != 0)
00259                 return (ret);
00260         if ((ret = __qam_db_create(dbp)) != 0)
00261                 return (ret);
00262 
00263         /*
00264          * XA specific: must be last, as we replace methods set by the
00265          * access methods.
00266          */
00267         if (LF_ISSET(DB_XA_CREATE) && (ret = __db_xa_create(dbp)) != 0)
00268                 return (ret);
00269 
00270 #ifdef HAVE_RPC
00271         /*
00272          * RPC specific: must be last, as we replace methods set by the
00273          * access methods.
00274          */
00275         if (dbenv != NULL && RPC_ON(dbenv)) {
00276                 __dbcl_dbp_init(dbp);
00277                 /*
00278                  * !!!
00279                  * We wrap the DB->open method for RPC, and the rpc.src file
00280                  * can't handle that.
00281                  */
00282                 dbp->open = __dbcl_db_open_wrap;
00283                 if ((ret = __dbcl_db_create(dbp, dbenv, flags)) != 0)
00284                         return (ret);
00285         }
00286 #else
00287         COMPQUIET(dbenv, NULL);
00288 #endif
00289 
00290         return (0);
00291 }
00292 
00293 /*
00294  * __dbh_am_chk --
00295  *      Error if an unreasonable method is called.
00296  *
00297  * PUBLIC: int __dbh_am_chk __P((DB *, u_int32_t));
00298  */
00299 int
00300 __dbh_am_chk(dbp, flags)
00301         DB *dbp;
00302         u_int32_t flags;
00303 {
00304         /*
00305          * We start out allowing any access methods to be called, and as the
00306          * application calls the methods the options become restricted.  The
00307          * idea is to quit as soon as an illegal method combination is called.
00308          */
00309         if ((LF_ISSET(DB_OK_BTREE) && FLD_ISSET(dbp->am_ok, DB_OK_BTREE)) ||
00310             (LF_ISSET(DB_OK_HASH) && FLD_ISSET(dbp->am_ok, DB_OK_HASH)) ||
00311             (LF_ISSET(DB_OK_QUEUE) && FLD_ISSET(dbp->am_ok, DB_OK_QUEUE)) ||
00312             (LF_ISSET(DB_OK_RECNO) && FLD_ISSET(dbp->am_ok, DB_OK_RECNO))) {
00313                 FLD_CLR(dbp->am_ok, ~flags);
00314                 return (0);
00315         }
00316 
00317         __db_err(dbp->dbenv,
00318     "call implies an access method which is inconsistent with previous calls");
00319         return (EINVAL);
00320 }
00321 
00322 /*
00323  * __dbh_err --
00324  *      Error message, including the standard error string.
00325  */
00326 static void
00327 #ifdef STDC_HEADERS
00328 __dbh_err(DB *dbp, int error, const char *fmt, ...)
00329 #else
00330 __dbh_err(dbp, error, fmt, va_alist)
00331         DB *dbp;
00332         int error;
00333         const char *fmt;
00334         va_dcl
00335 #endif
00336 {
00337         DB_REAL_ERR(dbp->dbenv, error, 1, 1, fmt);
00338 }
00339 
00340 /*
00341  * __dbh_errx --
00342  *      Error message.
00343  */
00344 static void
00345 #ifdef STDC_HEADERS
00346 __dbh_errx(DB *dbp, const char *fmt, ...)
00347 #else
00348 __dbh_errx(dbp, fmt, va_alist)
00349         DB *dbp;
00350         const char *fmt;
00351         va_dcl
00352 #endif
00353 {
00354         DB_REAL_ERR(dbp->dbenv, 0, 0, 1, fmt);
00355 }
00356 
00357 /*
00358  * __db_get_byteswapped --
00359  *      Return if database requires byte swapping.
00360  */
00361 static int
00362 __db_get_byteswapped(dbp, isswapped)
00363         DB *dbp;
00364         int *isswapped;
00365 {
00366         DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->get_byteswapped");
00367 
00368         *isswapped = F_ISSET(dbp, DB_AM_SWAP) ? 1 : 0;
00369         return (0);
00370 }
00371 
00372 /*
00373  * __db_get_dbname --
00374  *      Get the name of the database as passed to DB->open.
00375  */
00376 static int
00377 __db_get_dbname(dbp, fnamep, dnamep)
00378         DB *dbp;
00379         const char **fnamep, **dnamep;
00380 {
00381         DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->get_dbname");
00382 
00383         if (fnamep != NULL)
00384                 *fnamep = dbp->fname;
00385         if (dnamep != NULL)
00386                 *dnamep = dbp->dname;
00387         return (0);
00388 }
00389 
00390 /*
00391  * __db_get_env --
00392  *      Get the DB_ENV handle that was passed to db_create.
00393  */
00394 static DB_ENV *
00395 __db_get_env(dbp)
00396         DB *dbp;
00397 {
00398         return (dbp->dbenv);
00399 }
00400 
00401 /*
00402  * __db_get_mpf --
00403  *      Get the underlying DB_MPOOLFILE handle.
00404  */
00405 static DB_MPOOLFILE *
00406 __db_get_mpf(dbp)
00407         DB *dbp;
00408 {
00409         return (dbp->mpf);
00410 }
00411 
00412 /*
00413  * get_transactional --
00414  *      Get whether this database was created in a transaction.
00415  */
00416 static int
00417 __db_get_transactional(dbp)
00418         DB *dbp;
00419 {
00420         return (F_ISSET(dbp, DB_AM_TXN) ? 1 : 0);
00421 }
00422 
00423 /*
00424  * __db_get_type --
00425  *      Return type of underlying database.
00426  */
00427 static int
00428 __db_get_type(dbp, dbtype)
00429         DB *dbp;
00430         DBTYPE *dbtype;
00431 {
00432         DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->get_type");
00433 
00434         *dbtype = dbp->type;
00435         return (0);
00436 }
00437 
00438 /*
00439  * __db_set_append_recno --
00440  *      Set record number append routine.
00441  */
00442 static int
00443 __db_set_append_recno(dbp, func)
00444         DB *dbp;
00445         int (*func) __P((DB *, DBT *, db_recno_t));
00446 {
00447         DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_append_recno");
00448         DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO);
00449 
00450         dbp->db_append_recno = func;
00451 
00452         return (0);
00453 }
00454 
00455 /*
00456  * __db_get_cachesize --
00457  *      Get underlying cache size.
00458  */
00459 static int
00460 __db_get_cachesize(dbp, cache_gbytesp, cache_bytesp, ncachep)
00461         DB *dbp;
00462         u_int32_t *cache_gbytesp, *cache_bytesp;
00463         int *ncachep;
00464 {
00465         DB_ILLEGAL_IN_ENV(dbp, "DB->get_cachesize");
00466 
00467         return (__memp_get_cachesize(dbp->dbenv,
00468             cache_gbytesp, cache_bytesp, ncachep));
00469 }
00470 
00471 /*
00472  * __db_set_cachesize --
00473  *      Set underlying cache size.
00474  */
00475 static int
00476 __db_set_cachesize(dbp, cache_gbytes, cache_bytes, ncache)
00477         DB *dbp;
00478         u_int32_t cache_gbytes, cache_bytes;
00479         int ncache;
00480 {
00481         DB_ILLEGAL_IN_ENV(dbp, "DB->set_cachesize");
00482         DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_cachesize");
00483 
00484         return (__memp_set_cachesize(
00485             dbp->dbenv, cache_gbytes, cache_bytes, ncache));
00486 }
00487 
00488 /*
00489  * __db_set_dup_compare --
00490  *      Set duplicate comparison routine.
00491  */
00492 static int
00493 __db_set_dup_compare(dbp, func)
00494         DB *dbp;
00495         int (*func) __P((DB *, const DBT *, const DBT *));
00496 {
00497         int ret;
00498 
00499         DB_ILLEGAL_AFTER_OPEN(dbp, "DB->dup_compare");
00500         DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE | DB_OK_HASH);
00501 
00502         if ((ret = __db_set_flags(dbp, DB_DUPSORT)) != 0)
00503                 return (ret);
00504 
00505         dbp->dup_compare = func;
00506 
00507         return (0);
00508 }
00509 
00510 /*
00511  * __db_get_encrypt_flags --
00512  */
00513 static int
00514 __db_get_encrypt_flags(dbp, flagsp)
00515         DB *dbp;
00516         u_int32_t *flagsp;
00517 {
00518         DB_ILLEGAL_IN_ENV(dbp, "DB->get_encrypt_flags");
00519 
00520         return (__env_get_encrypt_flags(dbp->dbenv, flagsp));
00521 }
00522 
00523 /*
00524  * __db_set_encrypt --
00525  *      Set database passwd.
00526  */
00527 static int
00528 __db_set_encrypt(dbp, passwd, flags)
00529         DB *dbp;
00530         const char *passwd;
00531         u_int32_t flags;
00532 {
00533         DB_CIPHER *db_cipher;
00534         int ret;
00535 
00536         DB_ILLEGAL_IN_ENV(dbp, "DB->set_encrypt");
00537         DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_encrypt");
00538 
00539         if ((ret = __env_set_encrypt(dbp->dbenv, passwd, flags)) != 0)
00540                 return (ret);
00541 
00542         /*
00543          * In a real env, this gets initialized with the region.  In a local
00544          * env, we must do it here.
00545          */
00546         db_cipher = (DB_CIPHER *)dbp->dbenv->crypto_handle;
00547         if (!F_ISSET(db_cipher, CIPHER_ANY) &&
00548             (ret = db_cipher->init(dbp->dbenv, db_cipher)) != 0)
00549                 return (ret);
00550 
00551         return (__db_set_flags(dbp, DB_ENCRYPT));
00552 }
00553 
00554 static void
00555 __db_set_errcall(dbp, errcall)
00556         DB *dbp;
00557         void (*errcall) __P((const DB_ENV *, const char *, const char *));
00558 {
00559         __env_set_errcall(dbp->dbenv, errcall);
00560 }
00561 
00562 static void
00563 __db_get_errfile(dbp, errfilep)
00564         DB *dbp;
00565         FILE **errfilep;
00566 {
00567         __env_get_errfile(dbp->dbenv, errfilep);
00568 }
00569 
00570 static void
00571 __db_set_errfile(dbp, errfile)
00572         DB *dbp;
00573         FILE *errfile;
00574 {
00575         __env_set_errfile(dbp->dbenv, errfile);
00576 }
00577 
00578 static void
00579 __db_get_errpfx(dbp, errpfxp)
00580         DB *dbp;
00581         const char **errpfxp;
00582 {
00583         __env_get_errpfx(dbp->dbenv, errpfxp);
00584 }
00585 
00586 static void
00587 __db_set_errpfx(dbp, errpfx)
00588         DB *dbp;
00589         const char *errpfx;
00590 {
00591         __env_set_errpfx(dbp->dbenv, errpfx);
00592 }
00593 
00594 static int
00595 __db_set_feedback(dbp, feedback)
00596         DB *dbp;
00597         void (*feedback) __P((DB *, int, int));
00598 {
00599         dbp->db_feedback = feedback;
00600         return (0);
00601 }
00602 
00603 /*
00604  * __db_map_flags --
00605  *      Maps between public and internal flag values.
00606  *      This function doesn't check for validity, so it can't fail.
00607  */
00608 static void
00609 __db_map_flags(dbp, inflagsp, outflagsp)
00610         DB *dbp;
00611         u_int32_t *inflagsp, *outflagsp;
00612 {
00613         COMPQUIET(dbp, NULL);
00614 
00615         if (FLD_ISSET(*inflagsp, DB_CHKSUM)) {
00616                 FLD_SET(*outflagsp, DB_AM_CHKSUM);
00617                 FLD_CLR(*inflagsp, DB_CHKSUM);
00618         }
00619         if (FLD_ISSET(*inflagsp, DB_ENCRYPT)) {
00620                 FLD_SET(*outflagsp, DB_AM_ENCRYPT | DB_AM_CHKSUM);
00621                 FLD_CLR(*inflagsp, DB_ENCRYPT);
00622         }
00623         if (FLD_ISSET(*inflagsp, DB_TXN_NOT_DURABLE)) {
00624                 FLD_SET(*outflagsp, DB_AM_NOT_DURABLE);
00625                 FLD_CLR(*inflagsp, DB_TXN_NOT_DURABLE);
00626         }
00627 }
00628 
00629 /*
00630  * __db_get_flags --
00631  *      The DB->get_flags method.
00632  *
00633  * PUBLIC: int __db_get_flags __P((DB *, u_int32_t *));
00634  */
00635 int
00636 __db_get_flags(dbp, flagsp)
00637         DB *dbp;
00638         u_int32_t *flagsp;
00639 {
00640         static const u_int32_t db_flags[] = {
00641                 DB_CHKSUM,
00642                 DB_DUP,
00643                 DB_DUPSORT,
00644                 DB_ENCRYPT,
00645                 DB_INORDER,
00646                 DB_RECNUM,
00647                 DB_RENUMBER,
00648                 DB_REVSPLITOFF,
00649                 DB_SNAPSHOT,
00650                 DB_TXN_NOT_DURABLE,
00651                 0
00652         };
00653         u_int32_t f, flags, mapped_flag;
00654         int i;
00655 
00656         flags = 0;
00657         for (i = 0; (f = db_flags[i]) != 0; i++) {
00658                 mapped_flag = 0;
00659                 __db_map_flags(dbp, &f, &mapped_flag);
00660                 __bam_map_flags(dbp, &f, &mapped_flag);
00661                 __ram_map_flags(dbp, &f, &mapped_flag);
00662 #ifdef HAVE_QUEUE
00663                 __qam_map_flags(dbp, &f, &mapped_flag);
00664 #endif
00665                 DB_ASSERT(f == 0);
00666                 if (F_ISSET(dbp, mapped_flag) == mapped_flag)
00667                         LF_SET(db_flags[i]);
00668         }
00669 
00670         *flagsp = flags;
00671         return (0);
00672 }
00673 
00674 /*
00675  * __db_set_flags --
00676  *      DB->set_flags.
00677  *
00678  * PUBLIC: int  __db_set_flags __P((DB *, u_int32_t));
00679  */
00680 int
00681 __db_set_flags(dbp, flags)
00682         DB *dbp;
00683         u_int32_t flags;
00684 {
00685         DB_ENV *dbenv;
00686         int ret;
00687 
00688         dbenv = dbp->dbenv;
00689 
00690         if (LF_ISSET(DB_ENCRYPT) && !CRYPTO_ON(dbenv)) {
00691                 __db_err(dbenv,
00692                     "Database environment not configured for encryption");
00693                 return (EINVAL);
00694         }
00695         if (LF_ISSET(DB_TXN_NOT_DURABLE))
00696                 ENV_REQUIRES_CONFIG(dbenv,
00697                     dbenv->tx_handle, "DB_NOT_DURABLE", DB_INIT_TXN);
00698 
00699         __db_map_flags(dbp, &flags, &dbp->flags);
00700 
00701         if ((ret = __bam_set_flags(dbp, &flags)) != 0)
00702                 return (ret);
00703         if ((ret = __ram_set_flags(dbp, &flags)) != 0)
00704                 return (ret);
00705 #ifdef HAVE_QUEUE
00706         if ((ret = __qam_set_flags(dbp, &flags)) != 0)
00707                 return (ret);
00708 #endif
00709 
00710         return (flags == 0 ? 0 : __db_ferr(dbenv, "DB->set_flags", 0));
00711 }
00712 
00713 /*
00714  * __db_get_lorder --
00715  *      Get whether lorder is swapped or not.
00716  *
00717  * PUBLIC: int  __db_get_lorder __P((DB *, int *));
00718  */
00719 int
00720 __db_get_lorder(dbp, db_lorderp)
00721         DB *dbp;
00722         int *db_lorderp;
00723 {
00724         int ret;
00725 
00726         /* Flag if the specified byte order requires swapping. */
00727         switch (ret = __db_byteorder(dbp->dbenv, 1234)) {
00728         case 0:
00729                 *db_lorderp = F_ISSET(dbp, DB_AM_SWAP) ? 4321 : 1234;
00730                 break;
00731         case DB_SWAPBYTES:
00732                 *db_lorderp = F_ISSET(dbp, DB_AM_SWAP) ? 1234 : 4321;
00733                 break;
00734         default:
00735                 return (ret);
00736                 /* NOTREACHED */
00737         }
00738 
00739         return (0);
00740 }
00741 
00742 /*
00743  * __db_set_lorder --
00744  *      Set whether lorder is swapped or not.
00745  *
00746  * PUBLIC: int  __db_set_lorder __P((DB *, int));
00747  */
00748 int
00749 __db_set_lorder(dbp, db_lorder)
00750         DB *dbp;
00751         int db_lorder;
00752 {
00753         int ret;
00754 
00755         DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_lorder");
00756 
00757         /* Flag if the specified byte order requires swapping. */
00758         switch (ret = __db_byteorder(dbp->dbenv, db_lorder)) {
00759         case 0:
00760                 F_CLR(dbp, DB_AM_SWAP);
00761                 break;
00762         case DB_SWAPBYTES:
00763                 F_SET(dbp, DB_AM_SWAP);
00764                 break;
00765         default:
00766                 return (ret);
00767                 /* NOTREACHED */
00768         }
00769         return (0);
00770 }
00771 
00772 static int
00773 __db_set_alloc(dbp, mal_func, real_func, free_func)
00774         DB *dbp;
00775         void *(*mal_func) __P((size_t));
00776         void *(*real_func) __P((void *, size_t));
00777         void (*free_func) __P((void *));
00778 {
00779         DB_ILLEGAL_IN_ENV(dbp, "DB->set_alloc");
00780         DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_alloc");
00781 
00782         return (__env_set_alloc(dbp->dbenv, mal_func, real_func, free_func));
00783 }
00784 
00785 static void
00786 __db_set_msgcall(dbp, msgcall)
00787         DB *dbp;
00788         void (*msgcall) __P((const DB_ENV *, const char *));
00789 {
00790         __env_set_msgcall(dbp->dbenv, msgcall);
00791 }
00792 
00793 static void
00794 __db_get_msgfile(dbp, msgfilep)
00795         DB *dbp;
00796         FILE **msgfilep;
00797 {
00798         __env_get_msgfile(dbp->dbenv, msgfilep);
00799 }
00800 
00801 static void
00802 __db_set_msgfile(dbp, msgfile)
00803         DB *dbp;
00804         FILE *msgfile;
00805 {
00806         __env_set_msgfile(dbp->dbenv, msgfile);
00807 }
00808 
00809 static int
00810 __db_get_pagesize(dbp, db_pagesizep)
00811         DB *dbp;
00812         u_int32_t *db_pagesizep;
00813 {
00814         *db_pagesizep = dbp->pgsize;
00815         return (0);
00816 }
00817 
00818 /*
00819  * __db_set_pagesize --
00820  *      DB->set_pagesize
00821  *
00822  * PUBLIC: int  __db_set_pagesize __P((DB *, u_int32_t));
00823  */
00824 int
00825 __db_set_pagesize(dbp, db_pagesize)
00826         DB *dbp;
00827         u_int32_t db_pagesize;
00828 {
00829         DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_pagesize");
00830 
00831         if (db_pagesize < DB_MIN_PGSIZE) {
00832                 __db_err(dbp->dbenv, "page sizes may not be smaller than %lu",
00833                     (u_long)DB_MIN_PGSIZE);
00834                 return (EINVAL);
00835         }
00836         if (db_pagesize > DB_MAX_PGSIZE) {
00837                 __db_err(dbp->dbenv, "page sizes may not be larger than %lu",
00838                     (u_long)DB_MAX_PGSIZE);
00839                 return (EINVAL);
00840         }
00841 
00842         /*
00843          * We don't want anything that's not a power-of-2, as we rely on that
00844          * for alignment of various types on the pages.
00845          */
00846         if (!POWER_OF_TWO(db_pagesize)) {
00847                 __db_err(dbp->dbenv, "page sizes must be a power-of-2");
00848                 return (EINVAL);
00849         }
00850 
00851         /*
00852          * XXX
00853          * Should we be checking for a page size that's not a multiple of 512,
00854          * so that we never try and write less than a disk sector?
00855          */
00856         dbp->pgsize = db_pagesize;
00857 
00858         return (0);
00859 }
00860 
00861 static int
00862 __db_set_paniccall(dbp, paniccall)
00863         DB *dbp;
00864         void (*paniccall) __P((DB_ENV *, int));
00865 {
00866         return (__env_set_paniccall(dbp->dbenv, paniccall));
00867 }

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