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

env_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: env_method.c,v 12.19 2005/11/10 17:12:17 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 /*
00027  * This is the file that initializes the global array.  Do it this way because
00028  * people keep changing one without changing the other.  Having declaration and
00029  * initialization in one file will hopefully fix that.
00030  */
00031 #define DB_INITIALIZE_DB_GLOBALS        1
00032 
00033 #include "db_int.h"
00034 #include "dbinc/crypto.h"
00035 #include "dbinc/hmac.h"
00036 #include "dbinc/db_shash.h"
00037 #include "dbinc/db_page.h"
00038 #include "dbinc/db_am.h"
00039 #include "dbinc/lock.h"
00040 #include "dbinc/log.h"
00041 #include "dbinc/mp.h"
00042 #include "dbinc/txn.h"
00043 
00044 #ifdef HAVE_RPC
00045 #include "dbinc_auto/rpc_client_ext.h"
00046 #endif
00047 
00048 static void __env_err __P((const DB_ENV *, int, const char *, ...));
00049 static void __env_errx __P((const DB_ENV *, const char *, ...));
00050 static int  __env_get_data_dirs __P((DB_ENV *, const char ***));
00051 static int  __env_get_flags __P((DB_ENV *, u_int32_t *));
00052 static int  __env_get_home __P((DB_ENV *, const char **));
00053 static int  __env_get_shm_key __P((DB_ENV *, long *));
00054 static int  __env_get_tmp_dir __P((DB_ENV *, const char **));
00055 static int  __env_get_verbose __P((DB_ENV *, u_int32_t, int *));
00056 static int  __env_init __P((DB_ENV *));
00057 static void __env_map_flags __P((DB_ENV *, u_int32_t *, u_int32_t *));
00058 static int  __env_set_app_dispatch
00059                 __P((DB_ENV *, int (*)(DB_ENV *, DBT *, DB_LSN *, db_recops)));
00060 static int  __env_set_feedback __P((DB_ENV *, void (*)(DB_ENV *, int, int)));
00061 static int  __env_set_isalive __P((DB_ENV *, int (*)(DB_ENV *,
00062                 pid_t, db_threadid_t)));
00063 static int  __env_set_thread_id __P((DB_ENV *, void (*)(DB_ENV *,
00064                 pid_t *, db_threadid_t *)));
00065 static int  __env_set_thread_id_string __P((DB_ENV *,
00066                 char * (*)(DB_ENV *, pid_t, db_threadid_t, char *)));
00067 static int  __env_set_thread_count __P((DB_ENV *, u_int32_t));
00068 static int  __env_set_rpc_server
00069                 __P((DB_ENV *, void *, const char *, long, long, u_int32_t));
00070 
00071 /*
00072  * db_env_create --
00073  *      DB_ENV constructor.
00074  *
00075  * EXTERN: int db_env_create __P((DB_ENV **, u_int32_t));
00076  */
00077 int
00078 db_env_create(dbenvpp, flags)
00079         DB_ENV **dbenvpp;
00080         u_int32_t flags;
00081 {
00082         DB_ENV *dbenv;
00083         int ret;
00084 
00085         /*
00086          * !!!
00087          * Our caller has not yet had the opportunity to reset the panic
00088          * state or turn off mutex locking, and so we can neither check
00089          * the panic state or acquire a mutex in the DB_ENV create path.
00090          *
00091          * !!!
00092          * We can't call the flags-checking routines, we don't have an
00093          * environment yet.
00094          */
00095         if (flags != 0 && !LF_ISSET(DB_RPCCLIENT))
00096                 return (EINVAL);
00097         if ((ret = __os_calloc(NULL, 1, sizeof(*dbenv), &dbenv)) != 0)
00098                 return (ret);
00099 
00100 #ifdef HAVE_RPC
00101         if (LF_ISSET(DB_RPCCLIENT))
00102                 F_SET(dbenv, DB_ENV_RPCCLIENT);
00103 #endif
00104         if ((ret = __env_init(dbenv)) != 0) {
00105                 __os_free(NULL, dbenv);
00106                 return (ret);
00107         }
00108 
00109         *dbenvpp = dbenv;
00110         return (0);
00111 }
00112 
00113 /*
00114  * __env_init --
00115  *      Initialize a DB_ENV structure.
00116  */
00117 static int
00118 __env_init(dbenv)
00119         DB_ENV *dbenv;
00120 {
00121         /*
00122          * !!!
00123          * Our caller has not yet had the opportunity to reset the panic
00124          * state or turn off mutex locking, and so we can neither check
00125          * the panic state or acquire a mutex in the DB_ENV create path.
00126          *
00127          * Initialize the method handles.
00128          */
00129         /* DB_ENV PUBLIC HANDLE LIST BEGIN */
00130         dbenv->close = __env_close_pp;
00131         dbenv->dbremove = __env_dbremove_pp;
00132         dbenv->dbrename = __env_dbrename_pp;
00133         dbenv->err = __env_err;
00134         dbenv->errx = __env_errx;
00135         dbenv->failchk = __env_failchk_pp;
00136         dbenv->fileid_reset = __env_fileid_reset_pp;
00137         dbenv->get_cachesize = __memp_get_cachesize;
00138         dbenv->get_data_dirs = __env_get_data_dirs;
00139         dbenv->get_encrypt_flags = __env_get_encrypt_flags;
00140         dbenv->get_errfile = __env_get_errfile;
00141         dbenv->get_errpfx = __env_get_errpfx;
00142         dbenv->get_flags = __env_get_flags;
00143         dbenv->get_home = __env_get_home;
00144         dbenv->get_lg_bsize = __log_get_lg_bsize;
00145         dbenv->get_lg_dir = __log_get_lg_dir;
00146         dbenv->get_lg_filemode = __log_get_lg_filemode;
00147         dbenv->get_lg_max = __log_get_lg_max;
00148         dbenv->get_lg_regionmax = __log_get_lg_regionmax;
00149         dbenv->get_lk_conflicts = __lock_get_lk_conflicts;
00150         dbenv->get_lk_detect = __lock_get_lk_detect;
00151         dbenv->get_lk_max_lockers = __lock_get_lk_max_lockers;
00152         dbenv->get_lk_max_locks = __lock_get_lk_max_locks;
00153         dbenv->get_lk_max_objects = __lock_get_lk_max_objects;
00154         dbenv->get_mp_max_openfd = __memp_get_mp_max_openfd;
00155         dbenv->get_mp_max_write = __memp_get_mp_max_write;
00156         dbenv->get_mp_mmapsize = __memp_get_mp_mmapsize;
00157         dbenv->get_msgfile = __env_get_msgfile;
00158         dbenv->get_open_flags = __env_get_open_flags;
00159         dbenv->get_rep_limit = __rep_get_limit;
00160         dbenv->get_shm_key = __env_get_shm_key;
00161         dbenv->get_timeout = __lock_get_env_timeout;
00162         dbenv->get_tmp_dir = __env_get_tmp_dir;
00163         dbenv->get_tx_max = __txn_get_tx_max;
00164         dbenv->get_tx_timestamp = __txn_get_tx_timestamp;
00165         dbenv->get_verbose = __env_get_verbose;
00166         dbenv->is_bigendian = __db_isbigendian;
00167         dbenv->lock_detect = __lock_detect_pp;
00168         dbenv->lock_get = __lock_get_pp;
00169         dbenv->lock_id = __lock_id_pp;
00170         dbenv->lock_id_free = __lock_id_free_pp;
00171         dbenv->lock_put = __lock_put_pp;
00172         dbenv->lock_stat = __lock_stat_pp;
00173         dbenv->lock_stat_print = __lock_stat_print_pp;
00174         dbenv->lock_vec = __lock_vec_pp;
00175         dbenv->log_archive = __log_archive_pp;
00176         dbenv->log_cursor = __log_cursor_pp;
00177         dbenv->log_file = __log_file_pp;
00178         dbenv->log_flush = __log_flush_pp;
00179         dbenv->log_printf = __log_printf_capi;
00180         dbenv->log_put = __log_put_pp;
00181         dbenv->log_stat = __log_stat_pp;
00182         dbenv->log_stat_print = __log_stat_print_pp;
00183         dbenv->lsn_reset = __env_lsn_reset_pp;
00184         dbenv->memp_fcreate = __memp_fcreate_pp;
00185         dbenv->memp_register = __memp_register_pp;
00186         dbenv->memp_stat = __memp_stat_pp;
00187         dbenv->memp_stat_print = __memp_stat_print_pp;
00188         dbenv->memp_sync = __memp_sync_pp;
00189         dbenv->memp_trickle = __memp_trickle_pp;
00190         dbenv->mutex_alloc = __mutex_alloc_pp;
00191         dbenv->mutex_free = __mutex_free_pp;
00192         dbenv->mutex_get_align = __mutex_get_align;
00193         dbenv->mutex_get_increment = __mutex_get_increment;
00194         dbenv->mutex_get_max = __mutex_get_max;
00195         dbenv->mutex_get_tas_spins = __mutex_get_tas_spins;
00196         dbenv->mutex_lock = __mutex_lock_pp;
00197         dbenv->mutex_set_align = __mutex_set_align;
00198         dbenv->mutex_set_increment = __mutex_set_increment;
00199         dbenv->mutex_set_max = __mutex_set_max;
00200         dbenv->mutex_set_tas_spins = __mutex_set_tas_spins;
00201         dbenv->mutex_stat = __mutex_stat;
00202         dbenv->mutex_stat_print = __mutex_stat_print;
00203         dbenv->mutex_unlock = __mutex_unlock_pp;
00204         dbenv->open = __env_open_pp;
00205         dbenv->remove = __env_remove;
00206         dbenv->rep_elect = __rep_elect;
00207         dbenv->rep_flush = __rep_flush;
00208         dbenv->rep_get_config = __rep_get_config;
00209         dbenv->rep_process_message = __rep_process_message;
00210         dbenv->rep_set_config = __rep_set_config;
00211         dbenv->rep_start = __rep_start;
00212         dbenv->rep_stat = __rep_stat_pp;
00213         dbenv->rep_stat_print = __rep_stat_print_pp;
00214         dbenv->rep_sync = __rep_sync;
00215         dbenv->set_alloc = __env_set_alloc;
00216         dbenv->set_app_dispatch = __env_set_app_dispatch;
00217         dbenv->set_cachesize = __memp_set_cachesize;
00218         dbenv->set_data_dir = __env_set_data_dir;
00219         dbenv->set_encrypt = __env_set_encrypt;
00220         dbenv->set_errcall = __env_set_errcall;
00221         dbenv->set_errfile = __env_set_errfile;
00222         dbenv->set_errpfx = __env_set_errpfx;
00223         dbenv->set_feedback = __env_set_feedback;
00224         dbenv->set_flags = __env_set_flags;
00225         dbenv->set_intermediate_dir = __env_set_intermediate_dir;
00226         dbenv->set_isalive = __env_set_isalive;
00227         dbenv->set_lg_bsize = __log_set_lg_bsize;
00228         dbenv->set_lg_dir = __log_set_lg_dir;
00229         dbenv->set_lg_filemode = __log_set_lg_filemode;
00230         dbenv->set_lg_max = __log_set_lg_max;
00231         dbenv->set_lg_regionmax = __log_set_lg_regionmax;
00232         dbenv->set_lk_conflicts = __lock_set_lk_conflicts;
00233         dbenv->set_lk_detect = __lock_set_lk_detect;
00234         dbenv->set_lk_max = __lock_set_lk_max;
00235         dbenv->set_lk_max_lockers = __lock_set_lk_max_lockers;
00236         dbenv->set_lk_max_locks = __lock_set_lk_max_locks;
00237         dbenv->set_lk_max_objects = __lock_set_lk_max_objects;
00238         dbenv->set_mp_max_openfd = __memp_set_mp_max_openfd;
00239         dbenv->set_mp_max_write = __memp_set_mp_max_write;
00240         dbenv->set_mp_mmapsize = __memp_set_mp_mmapsize;
00241         dbenv->set_msgcall = __env_set_msgcall;
00242         dbenv->set_msgfile = __env_set_msgfile;
00243         dbenv->set_paniccall = __env_set_paniccall;
00244         dbenv->set_rep_limit = __rep_set_limit;
00245         dbenv->set_rep_request = __rep_set_request;
00246         dbenv->set_rep_transport = __rep_set_rep_transport;
00247         dbenv->set_rpc_server = __env_set_rpc_server;
00248         dbenv->set_shm_key = __env_set_shm_key;
00249         dbenv->set_thread_count = __env_set_thread_count;
00250         dbenv->set_thread_id = __env_set_thread_id;
00251         dbenv->set_thread_id_string = __env_set_thread_id_string;
00252         dbenv->set_timeout = __lock_set_env_timeout;
00253         dbenv->set_tmp_dir = __env_set_tmp_dir;
00254         dbenv->set_tx_max = __txn_set_tx_max;
00255         dbenv->set_tx_timestamp = __txn_set_tx_timestamp;
00256         dbenv->set_verbose = __env_set_verbose;
00257         dbenv->stat_print = __env_stat_print_pp;
00258         dbenv->txn_begin = __txn_begin_pp;
00259         dbenv->txn_checkpoint = __txn_checkpoint_pp;
00260         dbenv->txn_recover = __txn_recover_pp;
00261         dbenv->txn_stat = __txn_stat_pp;
00262         dbenv->txn_stat_print = __txn_stat_print_pp;
00263         /* DB_ENV PUBLIC HANDLE LIST END */
00264 
00265         /* DB_ENV PRIVATE HANDLE LIST BEGIN */
00266         dbenv->prdbt = __db_prdbt;
00267         /* DB_ENV PRIVATE HANDLE LIST END */
00268 
00269         __os_id(NULL, &dbenv->pid_cache, NULL);
00270         dbenv->thread_id = __os_id;
00271         dbenv->thread_id_string = __env_thread_id_string;
00272         dbenv->db_ref = 0;
00273         dbenv->shm_key = INVALID_REGION_SEGID;
00274 
00275         __lock_dbenv_create(dbenv);     /* Subsystem specific. */
00276         __log_dbenv_create(dbenv);
00277         __memp_dbenv_create(dbenv);
00278         __txn_dbenv_create(dbenv);
00279 
00280 #ifdef HAVE_RPC
00281         /*
00282          * RPC specific: must be last, as we replace methods set by the
00283          * access methods.
00284          */
00285         if (F_ISSET(dbenv, DB_ENV_RPCCLIENT)) {
00286                 __dbcl_dbenv_init(dbenv);
00287                 /*
00288                  * !!!
00289                  * We wrap the DB_ENV->open and close methods for RPC, and
00290                  * the rpc.src file can't handle that.
00291                  */
00292                 dbenv->open = __dbcl_env_open_wrap;
00293                 dbenv->close = __dbcl_env_close_wrap;
00294         }
00295 #endif
00296 
00297         return (0);
00298 }
00299 
00300 /*
00301  * __env_err --
00302  *      Error message, including the standard error string.
00303  */
00304 static void
00305 #ifdef STDC_HEADERS
00306 __env_err(const DB_ENV *dbenv, int error, const char *fmt, ...)
00307 #else
00308 __env_err(dbenv, error, fmt, va_alist)
00309         const DB_ENV *dbenv;
00310         int error;
00311         const char *fmt;
00312         va_dcl
00313 #endif
00314 {
00315         DB_REAL_ERR(dbenv, error, 1, 1, fmt);
00316 }
00317 
00318 /*
00319  * __env_errx --
00320  *      Error message.
00321  */
00322 static void
00323 #ifdef STDC_HEADERS
00324 __env_errx(const DB_ENV *dbenv, const char *fmt, ...)
00325 #else
00326 __env_errx(dbenv, fmt, va_alist)
00327         const DB_ENV *dbenv;
00328         const char *fmt;
00329         va_dcl
00330 #endif
00331 {
00332         DB_REAL_ERR(dbenv, 0, 0, 1, fmt);
00333 }
00334 
00335 static int
00336 __env_get_home(dbenv, homep)
00337         DB_ENV *dbenv;
00338         const char **homep;
00339 {
00340         ENV_ILLEGAL_BEFORE_OPEN(dbenv, "DB_ENV->get_home");
00341         *homep = dbenv->db_home;
00342         return (0);
00343 }
00344 
00345 /*
00346  * __env_set_alloc --
00347  *      {DB_ENV,DB}->set_alloc.
00348  *
00349  * PUBLIC: int  __env_set_alloc __P((DB_ENV *, void *(*)(size_t),
00350  * PUBLIC:          void *(*)(void *, size_t), void (*)(void *)));
00351  */
00352 int
00353 __env_set_alloc(dbenv, mal_func, real_func, free_func)
00354         DB_ENV *dbenv;
00355         void *(*mal_func) __P((size_t));
00356         void *(*real_func) __P((void *, size_t));
00357         void (*free_func) __P((void *));
00358 {
00359         ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_alloc");
00360 
00361         dbenv->db_malloc = mal_func;
00362         dbenv->db_realloc = real_func;
00363         dbenv->db_free = free_func;
00364         return (0);
00365 }
00366 
00367 /*
00368  * __env_set_app_dispatch --
00369  *      Set the transaction abort recover function.
00370  */
00371 static int
00372 __env_set_app_dispatch(dbenv, app_dispatch)
00373         DB_ENV *dbenv;
00374         int (*app_dispatch) __P((DB_ENV *, DBT *, DB_LSN *, db_recops));
00375 {
00376         ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_app_dispatch");
00377 
00378         dbenv->app_dispatch = app_dispatch;
00379         return (0);
00380 }
00381 
00382 /*
00383  * __env_get_encrypt_flags --
00384  *      {DB_ENV,DB}->get_encrypt_flags.
00385  *
00386  * PUBLIC: int __env_get_encrypt_flags __P((DB_ENV *, u_int32_t *));
00387  */
00388 int
00389 __env_get_encrypt_flags(dbenv, flagsp)
00390         DB_ENV *dbenv;
00391         u_int32_t *flagsp;
00392 {
00393 #ifdef HAVE_CRYPTO
00394         DB_CIPHER *db_cipher;
00395 
00396         db_cipher = dbenv->crypto_handle;
00397         if (db_cipher != NULL && db_cipher->alg == CIPHER_AES)
00398                 *flagsp = DB_ENCRYPT_AES;
00399         else
00400                 *flagsp = 0;
00401         return (0);
00402 #else
00403         COMPQUIET(flagsp, 0);
00404         __db_err(dbenv,
00405             "library build did not include support for cryptography");
00406         return (DB_OPNOTSUP);
00407 #endif
00408 }
00409 
00410 /*
00411  * __env_set_encrypt --
00412  *      DB_ENV->set_encrypt.
00413  *
00414  * PUBLIC: int __env_set_encrypt __P((DB_ENV *, const char *, u_int32_t));
00415  */
00416 int
00417 __env_set_encrypt(dbenv, passwd, flags)
00418         DB_ENV *dbenv;
00419         const char *passwd;
00420         u_int32_t flags;
00421 {
00422 #ifdef HAVE_CRYPTO
00423         DB_CIPHER *db_cipher;
00424         int ret;
00425 
00426         ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_encrypt");
00427 #define OK_CRYPTO_FLAGS (DB_ENCRYPT_AES)
00428 
00429         if (flags != 0 && LF_ISSET(~OK_CRYPTO_FLAGS))
00430                 return (__db_ferr(dbenv, "DB_ENV->set_encrypt", 0));
00431 
00432         if (passwd == NULL || strlen(passwd) == 0) {
00433                 __db_err(dbenv, "Empty password specified to set_encrypt");
00434                 return (EINVAL);
00435         }
00436         if (!CRYPTO_ON(dbenv)) {
00437                 if ((ret = __os_calloc(dbenv, 1, sizeof(DB_CIPHER), &db_cipher))
00438                     != 0)
00439                         goto err;
00440                 dbenv->crypto_handle = db_cipher;
00441         } else
00442                 db_cipher = (DB_CIPHER *)dbenv->crypto_handle;
00443 
00444         if (dbenv->passwd != NULL)
00445                 __os_free(dbenv, dbenv->passwd);
00446         if ((ret = __os_strdup(dbenv, passwd, &dbenv->passwd)) != 0) {
00447                 __os_free(dbenv, db_cipher);
00448                 goto err;
00449         }
00450         /*
00451          * We're going to need this often enough to keep around
00452          */
00453         dbenv->passwd_len = strlen(dbenv->passwd) + 1;
00454         /*
00455          * The MAC key is for checksumming, and is separate from
00456          * the algorithm.  So initialize it here, even if they
00457          * are using CIPHER_ANY.
00458          */
00459         __db_derive_mac((u_int8_t *)dbenv->passwd,
00460             dbenv->passwd_len, db_cipher->mac_key);
00461         switch (flags) {
00462         case 0:
00463                 F_SET(db_cipher, CIPHER_ANY);
00464                 break;
00465         case DB_ENCRYPT_AES:
00466                 if ((ret = __crypto_algsetup(dbenv, db_cipher, CIPHER_AES, 0))
00467                     != 0)
00468                         goto err1;
00469                 break;
00470         default:                                /* Impossible. */
00471                 break;
00472         }
00473         return (0);
00474 
00475 err1:
00476         __os_free(dbenv, dbenv->passwd);
00477         __os_free(dbenv, db_cipher);
00478         dbenv->crypto_handle = NULL;
00479 err:
00480         return (ret);
00481 #else
00482         COMPQUIET(passwd, NULL);
00483         COMPQUIET(flags, 0);
00484 
00485         __db_err(dbenv,
00486             "library build did not include support for cryptography");
00487         return (DB_OPNOTSUP);
00488 #endif
00489 }
00490 
00491 static void
00492 __env_map_flags(dbenv, inflagsp, outflagsp)
00493         DB_ENV *dbenv;
00494         u_int32_t *inflagsp, *outflagsp;
00495 {
00496         COMPQUIET(dbenv, NULL);
00497 
00498         if (FLD_ISSET(*inflagsp, DB_AUTO_COMMIT)) {
00499                 FLD_SET(*outflagsp, DB_ENV_AUTO_COMMIT);
00500                 FLD_CLR(*inflagsp, DB_AUTO_COMMIT);
00501         }
00502         if (FLD_ISSET(*inflagsp, DB_CDB_ALLDB)) {
00503                 FLD_SET(*outflagsp, DB_ENV_CDB_ALLDB);
00504                 FLD_CLR(*inflagsp, DB_CDB_ALLDB);
00505         }
00506         if (FLD_ISSET(*inflagsp, DB_DIRECT_DB)) {
00507                 FLD_SET(*outflagsp, DB_ENV_DIRECT_DB);
00508                 FLD_CLR(*inflagsp, DB_DIRECT_DB);
00509         }
00510         if (FLD_ISSET(*inflagsp, DB_DIRECT_LOG)) {
00511                 FLD_SET(*outflagsp, DB_ENV_DIRECT_LOG);
00512                 FLD_CLR(*inflagsp, DB_DIRECT_LOG);
00513         }
00514         if (FLD_ISSET(*inflagsp, DB_DSYNC_DB)) {
00515                 FLD_SET(*outflagsp, DB_ENV_DSYNC_DB);
00516                 FLD_CLR(*inflagsp, DB_DSYNC_DB);
00517         }
00518         if (FLD_ISSET(*inflagsp, DB_DSYNC_LOG)) {
00519                 FLD_SET(*outflagsp, DB_ENV_DSYNC_LOG);
00520                 FLD_CLR(*inflagsp, DB_DSYNC_LOG);
00521         }
00522         if (FLD_ISSET(*inflagsp, DB_LOG_AUTOREMOVE)) {
00523                 FLD_SET(*outflagsp, DB_ENV_LOG_AUTOREMOVE);
00524                 FLD_CLR(*inflagsp, DB_LOG_AUTOREMOVE);
00525         }
00526         if (FLD_ISSET(*inflagsp, DB_LOG_INMEMORY)) {
00527                 FLD_SET(*outflagsp, DB_ENV_LOG_INMEMORY);
00528                 FLD_CLR(*inflagsp, DB_LOG_INMEMORY);
00529         }
00530         if (FLD_ISSET(*inflagsp, DB_NOLOCKING)) {
00531                 FLD_SET(*outflagsp, DB_ENV_NOLOCKING);
00532                 FLD_CLR(*inflagsp, DB_NOLOCKING);
00533         }
00534         if (FLD_ISSET(*inflagsp, DB_NOMMAP)) {
00535                 FLD_SET(*outflagsp, DB_ENV_NOMMAP);
00536                 FLD_CLR(*inflagsp, DB_NOMMAP);
00537         }
00538         if (FLD_ISSET(*inflagsp, DB_NOPANIC)) {
00539                 FLD_SET(*outflagsp, DB_ENV_NOPANIC);
00540                 FLD_CLR(*inflagsp, DB_NOPANIC);
00541         }
00542         if (FLD_ISSET(*inflagsp, DB_OVERWRITE)) {
00543                 FLD_SET(*outflagsp, DB_ENV_OVERWRITE);
00544                 FLD_CLR(*inflagsp, DB_OVERWRITE);
00545         }
00546         if (FLD_ISSET(*inflagsp, DB_REGION_INIT)) {
00547                 FLD_SET(*outflagsp, DB_ENV_REGION_INIT);
00548                 FLD_CLR(*inflagsp, DB_REGION_INIT);
00549         }
00550         if (FLD_ISSET(*inflagsp, DB_TIME_NOTGRANTED)) {
00551                 FLD_SET(*outflagsp, DB_ENV_TIME_NOTGRANTED);
00552                 FLD_CLR(*inflagsp, DB_TIME_NOTGRANTED);
00553         }
00554         if (FLD_ISSET(*inflagsp, DB_TXN_NOSYNC)) {
00555                 FLD_SET(*outflagsp, DB_ENV_TXN_NOSYNC);
00556                 FLD_CLR(*inflagsp, DB_TXN_NOSYNC);
00557         }
00558         if (FLD_ISSET(*inflagsp, DB_TXN_WRITE_NOSYNC)) {
00559                 FLD_SET(*outflagsp, DB_ENV_TXN_WRITE_NOSYNC);
00560                 FLD_CLR(*inflagsp, DB_TXN_WRITE_NOSYNC);
00561         }
00562         if (FLD_ISSET(*inflagsp, DB_YIELDCPU)) {
00563                 FLD_SET(*outflagsp, DB_ENV_YIELDCPU);
00564                 FLD_CLR(*inflagsp, DB_YIELDCPU);
00565         }
00566 }
00567 
00568 static int
00569 __env_get_flags(dbenv, flagsp)
00570         DB_ENV *dbenv;
00571         u_int32_t *flagsp;
00572 {
00573         static const u_int32_t env_flags[] = {
00574                 DB_AUTO_COMMIT,
00575                 DB_CDB_ALLDB,
00576                 DB_DIRECT_DB,
00577                 DB_DIRECT_LOG,
00578                 DB_DSYNC_DB,
00579                 DB_DSYNC_LOG,
00580                 DB_LOG_AUTOREMOVE,
00581                 DB_LOG_INMEMORY,
00582                 DB_NOLOCKING,
00583                 DB_NOMMAP,
00584                 DB_NOPANIC,
00585                 DB_OVERWRITE,
00586                 DB_REGION_INIT,
00587                 DB_TIME_NOTGRANTED,
00588                 DB_TXN_NOSYNC,
00589                 DB_TXN_WRITE_NOSYNC,
00590                 DB_YIELDCPU,
00591                 0
00592         };
00593         u_int32_t f, flags, mapped_flag;
00594         int i;
00595 
00596         flags = 0;
00597         for (i = 0; (f = env_flags[i]) != 0; i++) {
00598                 mapped_flag = 0;
00599                 __env_map_flags(dbenv, &f, &mapped_flag);
00600                 DB_ASSERT(f == 0);
00601                 if (F_ISSET(dbenv, mapped_flag) == mapped_flag)
00602                         LF_SET(env_flags[i]);
00603         }
00604 
00605         /* Some flags are persisted in the regions. */
00606         if (dbenv->reginfo != NULL &&
00607             ((REGENV *)((REGINFO *)dbenv->reginfo)->primary)->panic != 0) {
00608                 LF_SET(DB_PANIC_ENVIRONMENT);
00609         }
00610         __log_get_flags(dbenv, &flags);
00611 
00612         *flagsp = flags;
00613         return (0);
00614 }
00615 
00616 /*
00617  * __env_set_flags --
00618  *      DB_ENV->set_flags.
00619  *
00620  * PUBLIC: int  __env_set_flags __P((DB_ENV *, u_int32_t, int));
00621  */
00622 int
00623 __env_set_flags(dbenv, flags, on)
00624         DB_ENV *dbenv;
00625         u_int32_t flags;
00626         int on;
00627 {
00628         u_int32_t mapped_flags;
00629         int ret;
00630 
00631 #define OK_FLAGS                                                        \
00632         (DB_AUTO_COMMIT | DB_CDB_ALLDB | DB_DIRECT_DB | DB_DIRECT_LOG | \
00633             DB_DSYNC_DB | DB_DSYNC_LOG | DB_LOG_AUTOREMOVE |            \
00634             DB_LOG_INMEMORY | DB_NOLOCKING | DB_NOMMAP | DB_NOPANIC |   \
00635             DB_OVERWRITE | DB_PANIC_ENVIRONMENT | DB_REGION_INIT |      \
00636             DB_TIME_NOTGRANTED | DB_TXN_NOSYNC | DB_TXN_WRITE_NOSYNC |  \
00637             DB_YIELDCPU)
00638 
00639         if (LF_ISSET(~OK_FLAGS))
00640                 return (__db_ferr(dbenv, "DB_ENV->set_flags", 0));
00641         if (on) {
00642                 if ((ret = __db_fcchk(dbenv, "DB_ENV->set_flags",
00643                     flags, DB_LOG_INMEMORY, DB_TXN_NOSYNC)) != 0)
00644                         return (ret);
00645                 if ((ret = __db_fcchk(dbenv, "DB_ENV->set_flags",
00646                     flags, DB_LOG_INMEMORY, DB_TXN_WRITE_NOSYNC)) != 0)
00647                         return (ret);
00648                 if ((ret = __db_fcchk(dbenv, "DB_ENV->set_flags",
00649                     flags, DB_TXN_NOSYNC, DB_TXN_WRITE_NOSYNC)) != 0)
00650                         return (ret);
00651                 if (LF_ISSET(DB_DIRECT_DB |
00652                     DB_DIRECT_LOG) && __os_have_direct() == 0) {
00653                         __db_err(dbenv,
00654         "DB_ENV->set_flags: direct I/O either not configured or not supported");
00655                         return (EINVAL);
00656                 }
00657         }
00658 
00659         if (LF_ISSET(DB_CDB_ALLDB))
00660                 ENV_ILLEGAL_AFTER_OPEN(dbenv,
00661                     "DB_ENV->set_flags: DB_CDB_ALLDB");
00662         if (LF_ISSET(DB_PANIC_ENVIRONMENT)) {
00663                 ENV_ILLEGAL_BEFORE_OPEN(dbenv,
00664                     "DB_ENV->set_flags: DB_PANIC_ENVIRONMENT");
00665                 if (on) {
00666                         __db_err(dbenv, "Environment panic set");
00667                         (void)__db_panic(dbenv, EACCES);
00668                 } else
00669                         __db_panic_set(dbenv, 0);
00670         }
00671         if (LF_ISSET(DB_REGION_INIT))
00672                 ENV_ILLEGAL_AFTER_OPEN(dbenv,
00673                     "DB_ENV->set_flags: DB_REGION_INIT");
00674         if (LF_ISSET(DB_LOG_INMEMORY))
00675                 ENV_ILLEGAL_AFTER_OPEN(dbenv,
00676                     "DB_ENV->set_flags: DB_LOG_INMEMORY");
00677 
00678         /*
00679          * DB_LOG_INMEMORY, DB_TXN_NOSYNC and DB_TXN_WRITE_NOSYNC are
00680          * mutually incompatible.  If we're setting one of them, clear all
00681          * current settings.
00682          */
00683         if (LF_ISSET(
00684             DB_LOG_INMEMORY | DB_TXN_NOSYNC | DB_TXN_WRITE_NOSYNC))
00685                 F_CLR(dbenv,
00686                     DB_ENV_LOG_INMEMORY |
00687                     DB_ENV_TXN_NOSYNC | DB_ENV_TXN_WRITE_NOSYNC);
00688 
00689         /* Some flags are persisted in the regions. */
00690         __log_set_flags(dbenv, flags, on);
00691 
00692         mapped_flags = 0;
00693         __env_map_flags(dbenv, &flags, &mapped_flags);
00694         if (on)
00695                 F_SET(dbenv, mapped_flags);
00696         else
00697                 F_CLR(dbenv, mapped_flags);
00698 
00699         return (0);
00700 }
00701 
00702 static int
00703 __env_get_data_dirs(dbenv, dirpp)
00704         DB_ENV *dbenv;
00705         const char ***dirpp;
00706 {
00707         *dirpp = (const char **)dbenv->db_data_dir;
00708         return (0);
00709 }
00710 
00711 /*
00712  * __env_set_data_dir --
00713  *      DB_ENV->set_data_dir.
00714  *
00715  * PUBLIC: int  __env_set_data_dir __P((DB_ENV *, const char *));
00716  */
00717 int
00718 __env_set_data_dir(dbenv, dir)
00719         DB_ENV *dbenv;
00720         const char *dir;
00721 {
00722         int ret;
00723 
00724         /*
00725          * The array is NULL-terminated so it can be returned by get_data_dirs
00726          * without a length.
00727          */
00728 
00729 #define DATA_INIT_CNT   20                      /* Start with 20 data slots. */
00730         if (dbenv->db_data_dir == NULL) {
00731                 if ((ret = __os_calloc(dbenv, DATA_INIT_CNT,
00732                     sizeof(char **), &dbenv->db_data_dir)) != 0)
00733                         return (ret);
00734                 dbenv->data_cnt = DATA_INIT_CNT;
00735         } else if (dbenv->data_next == dbenv->data_cnt - 2) {
00736                 dbenv->data_cnt *= 2;
00737                 if ((ret = __os_realloc(dbenv,
00738                     (u_int)dbenv->data_cnt * sizeof(char **),
00739                     &dbenv->db_data_dir)) != 0)
00740                         return (ret);
00741         }
00742 
00743         ret = __os_strdup(dbenv,
00744             dir, &dbenv->db_data_dir[dbenv->data_next++]);
00745         dbenv->db_data_dir[dbenv->data_next] = NULL;
00746         return (ret);
00747 }
00748 
00749 /*
00750  * __env_set_intermediate_dir --
00751  *      DB_ENV->set_intermediate_dir.
00752  *
00753  * !!!
00754  * Undocumented routine allowing applications to configure Berkeley DB to
00755  * create intermediate directories.
00756  *
00757  * PUBLIC: int  __env_set_intermediate_dir __P((DB_ENV *, int, u_int32_t));
00758  */
00759 int
00760 __env_set_intermediate_dir(dbenv, mode, flags)
00761         DB_ENV *dbenv;
00762         int mode;
00763         u_int32_t flags;
00764 {
00765         if (flags != 0)
00766                 return (__db_ferr(dbenv, "DB_ENV->set_intermediate_dir", 0));
00767         if (mode == 0) {
00768                 __db_err(dbenv,
00769                     "DB_ENV->set_intermediate_dir: mode may not be set to 0");
00770                 return (EINVAL);
00771         }
00772 
00773         dbenv->dir_mode = mode;
00774         return (0);
00775 }
00776 
00777 /*
00778  * __env_set_errcall --
00779  *      {DB_ENV,DB}->set_errcall.
00780  *
00781  * PUBLIC: void __env_set_errcall __P((DB_ENV *,
00782  * PUBLIC:              void (*)(const DB_ENV *, const char *, const char *)));
00783  */
00784 void
00785 __env_set_errcall(dbenv, errcall)
00786         DB_ENV *dbenv;
00787         void (*errcall) __P((const DB_ENV *, const char *, const char *));
00788 {
00789         dbenv->db_errcall = errcall;
00790 }
00791 
00792 /*
00793  * __env_get_errfile --
00794  *      {DB_ENV,DB}->get_errfile.
00795  *
00796  * PUBLIC: void __env_get_errfile __P((DB_ENV *, FILE **));
00797  */
00798 void
00799 __env_get_errfile(dbenv, errfilep)
00800         DB_ENV *dbenv;
00801         FILE **errfilep;
00802 {
00803         *errfilep = dbenv->db_errfile;
00804 }
00805 
00806 /*
00807  * __env_set_errfile --
00808  *      {DB_ENV,DB}->set_errfile.
00809  *
00810  * PUBLIC: void __env_set_errfile __P((DB_ENV *, FILE *));
00811  */
00812 void
00813 __env_set_errfile(dbenv, errfile)
00814         DB_ENV *dbenv;
00815         FILE *errfile;
00816 {
00817         dbenv->db_errfile = errfile;
00818 }
00819 
00820 /*
00821  * __env_get_errpfx --
00822  *      {DB_ENV,DB}->get_errpfx.
00823  *
00824  * PUBLIC: void __env_get_errpfx __P((DB_ENV *, const char **));
00825  */
00826 void
00827 __env_get_errpfx(dbenv, errpfxp)
00828         DB_ENV *dbenv;
00829         const char **errpfxp;
00830 {
00831         *errpfxp = dbenv->db_errpfx;
00832 }
00833 
00834 /*
00835  * __env_set_errpfx --
00836  *      {DB_ENV,DB}->set_errpfx.
00837  *
00838  * PUBLIC: void __env_set_errpfx __P((DB_ENV *, const char *));
00839  */
00840 void
00841 __env_set_errpfx(dbenv, errpfx)
00842         DB_ENV *dbenv;
00843         const char *errpfx;
00844 {
00845         dbenv->db_errpfx = errpfx;
00846 }
00847 
00848 static int
00849 __env_set_feedback(dbenv, feedback)
00850         DB_ENV *dbenv;
00851         void (*feedback) __P((DB_ENV *, int, int));
00852 {
00853         dbenv->db_feedback = feedback;
00854         return (0);
00855 }
00856 
00857 /*
00858  * __env_set_thread_id --
00859  *      DB_ENV->set_thread_id
00860  */
00861 static int
00862 __env_set_thread_id(dbenv, id)
00863         DB_ENV *dbenv;
00864         void (*id) __P((DB_ENV *, pid_t *, db_threadid_t *));
00865 {
00866         dbenv->thread_id = id;
00867         return (0);
00868 }
00869 
00870 /*
00871  * __env_set_threadid_string --
00872  *      DB_ENV->set_threadid_string
00873  */
00874 static int
00875 __env_set_thread_id_string(dbenv, thread_id_string)
00876         DB_ENV *dbenv;
00877         char *(*thread_id_string) __P((DB_ENV *, pid_t, db_threadid_t, char *));
00878 {
00879         dbenv->thread_id_string = thread_id_string;
00880         return (0);
00881 }
00882 
00883 /*
00884  * __env_set_isalive --
00885  *      DB_ENV->set_isalive
00886  */
00887 static int
00888 __env_set_isalive(dbenv, is_alive)
00889         DB_ENV *dbenv;
00890         int (*is_alive) __P((DB_ENV *, pid_t, db_threadid_t));
00891 {
00892         if (F_ISSET((dbenv), DB_ENV_OPEN_CALLED) &&
00893             dbenv->thr_nbucket == 0) {
00894                 __db_err(dbenv,
00895                     "is_alive method specified but no thread region allocated");
00896                 return (EINVAL);
00897         }
00898         dbenv->is_alive = is_alive;
00899         return (0);
00900 }
00901 
00902 /*
00903  * __env_set_thread_count --
00904  *      DB_ENV->set_thread_count
00905  */
00906 static int
00907 __env_set_thread_count(dbenv, count)
00908         DB_ENV *dbenv;
00909         u_int32_t count;
00910 {
00911         ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_thread_count");
00912         dbenv->thr_max = count;
00913 
00914         /*
00915          * Set the number of buckets to be 1/8th the number of
00916          * proposed threads control blocks.  This is rather
00917          * arbitrary.
00918          */
00919         dbenv->thr_nbucket = count / 8;
00920         return (0);
00921 }
00922 
00923 /*
00924  * __env_set_msgcall --
00925  *      {DB_ENV,DB}->set_msgcall.
00926  *
00927  * PUBLIC: void __env_set_msgcall
00928  * PUBLIC:     __P((DB_ENV *, void (*)(const DB_ENV *, const char *)));
00929  */
00930 void
00931 __env_set_msgcall(dbenv, msgcall)
00932         DB_ENV *dbenv;
00933         void (*msgcall) __P((const DB_ENV *, const char *));
00934 {
00935         dbenv->db_msgcall = msgcall;
00936 }
00937 
00938 /*
00939  * __env_get_msgfile --
00940  *      {DB_ENV,DB}->get_msgfile.
00941  *
00942  * PUBLIC: void __env_get_msgfile __P((DB_ENV *, FILE **));
00943  */
00944 void
00945 __env_get_msgfile(dbenv, msgfilep)
00946         DB_ENV *dbenv;
00947         FILE **msgfilep;
00948 {
00949         *msgfilep = dbenv->db_msgfile;
00950 }
00951 
00952 /*
00953  * __env_set_msgfile --
00954  *      {DB_ENV,DB}->set_msgfile.
00955  *
00956  * PUBLIC: void __env_set_msgfile __P((DB_ENV *, FILE *));
00957  */
00958 void
00959 __env_set_msgfile(dbenv, msgfile)
00960         DB_ENV *dbenv;
00961         FILE *msgfile;
00962 {
00963         dbenv->db_msgfile = msgfile;
00964 }
00965 
00966 /*
00967  * __env_set_paniccall --
00968  *      {DB_ENV,DB}->set_paniccall.
00969  *
00970  * PUBLIC: int  __env_set_paniccall __P((DB_ENV *, void (*)(DB_ENV *, int)));
00971  */
00972 int
00973 __env_set_paniccall(dbenv, paniccall)
00974         DB_ENV *dbenv;
00975         void (*paniccall) __P((DB_ENV *, int));
00976 {
00977         dbenv->db_paniccall = paniccall;
00978         return (0);
00979 }
00980 
00981 static int
00982 __env_get_shm_key(dbenv, shm_keyp)
00983         DB_ENV *dbenv;
00984         long *shm_keyp;                 /* !!!: really a key_t *. */
00985 {
00986         *shm_keyp = dbenv->shm_key;
00987         return (0);
00988 }
00989 
00990 /*
00991  * __env_set_shm_key --
00992  *      DB_ENV->set_shm_key.
00993  *
00994  * PUBLIC: int  __env_set_shm_key __P((DB_ENV *, long));
00995  */
00996 int
00997 __env_set_shm_key(dbenv, shm_key)
00998         DB_ENV *dbenv;
00999         long shm_key;                   /* !!!: really a key_t. */
01000 {
01001         ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_shm_key");
01002 
01003         dbenv->shm_key = shm_key;
01004         return (0);
01005 }
01006 
01007 static int
01008 __env_get_tmp_dir(dbenv, dirp)
01009         DB_ENV *dbenv;
01010         const char **dirp;
01011 {
01012         *dirp = dbenv->db_tmp_dir;
01013         return (0);
01014 }
01015 
01016 /*
01017  * __env_set_tmp_dir --
01018  *      DB_ENV->set_tmp_dir.
01019  *
01020  * PUBLIC: int  __env_set_tmp_dir __P((DB_ENV *, const char *));
01021  */
01022 int
01023 __env_set_tmp_dir(dbenv, dir)
01024         DB_ENV *dbenv;
01025         const char *dir;
01026 {
01027         if (dbenv->db_tmp_dir != NULL)
01028                 __os_free(dbenv, dbenv->db_tmp_dir);
01029         return (__os_strdup(dbenv, dir, &dbenv->db_tmp_dir));
01030 }
01031 
01032 static int
01033 __env_get_verbose(dbenv, which, onoffp)
01034         DB_ENV *dbenv;
01035         u_int32_t which;
01036         int *onoffp;
01037 {
01038         switch (which) {
01039         case DB_VERB_DEADLOCK:
01040         case DB_VERB_RECOVERY:
01041         case DB_VERB_REGISTER:
01042         case DB_VERB_REPLICATION:
01043         case DB_VERB_WAITSFOR:
01044                 *onoffp = FLD_ISSET(dbenv->verbose, which) ? 1 : 0;
01045                 break;
01046         default:
01047                 return (EINVAL);
01048         }
01049         return (0);
01050 }
01051 
01052 /*
01053  * __env_set_verbose --
01054  *      DB_ENV->set_verbose.
01055  *
01056  * PUBLIC: int  __env_set_verbose __P((DB_ENV *, u_int32_t, int));
01057  */
01058 int
01059 __env_set_verbose(dbenv, which, on)
01060         DB_ENV *dbenv;
01061         u_int32_t which;
01062         int on;
01063 {
01064         switch (which) {
01065         case DB_VERB_DEADLOCK:
01066         case DB_VERB_RECOVERY:
01067         case DB_VERB_REGISTER:
01068         case DB_VERB_REPLICATION:
01069         case DB_VERB_WAITSFOR:
01070                 if (on)
01071                         FLD_SET(dbenv->verbose, which);
01072                 else
01073                         FLD_CLR(dbenv->verbose, which);
01074                 break;
01075         default:
01076                 return (EINVAL);
01077         }
01078         return (0);
01079 }
01080 
01081 /*
01082  * __db_mi_env --
01083  *      Method illegally called with public environment.
01084  *
01085  * PUBLIC: int __db_mi_env __P((DB_ENV *, const char *));
01086  */
01087 int
01088 __db_mi_env(dbenv, name)
01089         DB_ENV *dbenv;
01090         const char *name;
01091 {
01092         __db_err(dbenv, "%s: method not permitted when environment specified",
01093             name);
01094         return (EINVAL);
01095 }
01096 
01097 /*
01098  * __db_mi_open --
01099  *      Method illegally called after open.
01100  *
01101  * PUBLIC: int __db_mi_open __P((DB_ENV *, const char *, int));
01102  */
01103 int
01104 __db_mi_open(dbenv, name, after)
01105         DB_ENV *dbenv;
01106         const char *name;
01107         int after;
01108 {
01109         __db_err(dbenv, "%s: method not permitted %s handle's open method",
01110             name, after ? "after" : "before");
01111         return (EINVAL);
01112 }
01113 
01114 /*
01115  * __db_env_config --
01116  *      Method or function called without required configuration.
01117  *
01118  * PUBLIC: int __db_env_config __P((DB_ENV *, char *, u_int32_t));
01119  */
01120 int
01121 __db_env_config(dbenv, i, flags)
01122         DB_ENV *dbenv;
01123         char *i;
01124         u_int32_t flags;
01125 {
01126         char *sub;
01127 
01128         switch (flags) {
01129         case DB_INIT_LOCK:
01130                 sub = "locking";
01131                 break;
01132         case DB_INIT_LOG:
01133                 sub = "logging";
01134                 break;
01135         case DB_INIT_MPOOL:
01136                 sub = "memory pool";
01137                 break;
01138         case DB_INIT_REP:
01139                 sub = "replication";
01140                 break;
01141         case DB_INIT_TXN:
01142                 sub = "transaction";
01143                 break;
01144         default:
01145                 sub = "<unspecified>";
01146                 break;
01147         }
01148         __db_err(dbenv,
01149     "%s interface requires an environment configured for the %s subsystem",
01150             i, sub);
01151         return (EINVAL);
01152 }
01153 
01154 static int
01155 __env_set_rpc_server(dbenv, cl, host, tsec, ssec, flags)
01156         DB_ENV *dbenv;
01157         void *cl;
01158         const char *host;
01159         long tsec, ssec;
01160         u_int32_t flags;
01161 {
01162         COMPQUIET(host, NULL);
01163         COMPQUIET(cl, NULL);
01164         COMPQUIET(tsec, 0);
01165         COMPQUIET(ssec, 0);
01166         COMPQUIET(flags, 0);
01167 
01168         __db_err(dbenv, "Berkeley DB was not configured for RPC support");
01169         return (DB_OPNOTSUP);
01170 }

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