00001 /*- 00002 * See the file LICENSE for redistribution information. 00003 * 00004 * Copyright (c) 1999, 2000 00005 * Sleepycat Software. All rights reserved. 00006 */ 00007 00008 #include "config.h" 00009 00010 #ifndef lint 00011 static const char revid[] = "$Id: env__method_8c-source.html,v 1.1 2008年06月08日 10:18:39 sebdiaz Exp $"; 00012 #endif /* not lint */ 00013 00014 #ifndef NO_SYSTEM_INCLUDES 00015 #include <sys/types.h> 00016 00017 #include <errno.h> 00018 #include <string.h> 00019 #endif 00020 00021 #ifdef HAVE_RPC 00022 #include "db_server.h" 00023 #endif 00024 00025 /* 00026 * This is the file that initializes the global array. Do it this way because 00027 * people keep changing one without changing the other. Having declaration and 00028 * initialization in one file will hopefully fix that. 00029 */ 00030 #define DB_INITIALIZE_DB_GLOBALS 1 00031 00032 #include "db_int.h" 00033 #include "db_shash.h" 00034 #include "db_page.h" 00035 #include "db_am.h" 00036 #include "lock.h" 00037 #include "log.h" 00038 #include "mp.h" 00039 #include "txn.h" 00040 00041 #ifdef HAVE_RPC 00042 #include "gen_client_ext.h" 00043 #include "rpc_client_ext.h" 00044 #endif 00045 00046 static void __dbenv_err __P((const DB_ENV *, int, const char *, ...)); 00047 static void __dbenv_errx __P((const DB_ENV *, const char *, ...)); 00048 static int __dbenv_set_data_dir __P((DB_ENV *, const char *)); 00049 static void __dbenv_set_errcall __P((DB_ENV *, void (*)(const char *, char *))); 00050 static void __dbenv_set_errfile __P((DB_ENV *, FILE *)); 00051 static void __dbenv_set_errpfx __P((DB_ENV *, const char *)); 00052 static int __dbenv_set_feedback __P((DB_ENV *, void (*)(DB_ENV *, int, int))); 00053 static int __dbenv_set_paniccall __P((DB_ENV *, void (*)(DB_ENV *, int))); 00054 static int __dbenv_set_recovery_init __P((DB_ENV *, int (*)(DB_ENV *))); 00055 static int __dbenv_set_server_noclnt 00056 __P((DB_ENV *, char *, long, long, u_int32_t)); 00057 static int __dbenv_set_shm_key __P((DB_ENV *, long)); 00058 static int __dbenv_set_tmp_dir __P((DB_ENV *, const char *)); 00059 static int __dbenv_set_verbose __P((DB_ENV *, u_int32_t, int)); 00060 00061 /* 00062 * CDB_db_env_create -- 00063 * DB_ENV constructor. 00064 */ 00065 int 00066 CDB_db_env_create(dbenvpp, flags) 00067 DB_ENV **dbenvpp; 00068 u_int32_t flags; 00069 { 00070 DB_ENV *dbenv; 00071 int ret; 00072 00073 /* 00074 * !!! 00075 * We can't call the flags-checking routines, we don't have an 00076 * environment yet. 00077 */ 00078 if (flags != 0 && flags != DB_CLIENT) 00079 return (EINVAL); 00080 00081 if ((ret = CDB___os_calloc(NULL, 1, sizeof(*dbenv), &dbenv)) != 0) 00082 return (ret); 00083 00084 #ifdef HAVE_RPC 00085 if (LF_ISSET(DB_CLIENT)) 00086 F_SET(dbenv, DB_ENV_RPCCLIENT); 00087 #endif 00088 ret = CDB___dbenv_init(dbenv); 00089 00090 if (ret != 0) { 00091 CDB___os_free(dbenv, sizeof(*dbenv)); 00092 return (ret); 00093 } 00094 00095 *dbenvpp = dbenv; 00096 return (0); 00097 } 00098 00099 /* 00100 * CDB___dbenv_init -- 00101 * Initialize a DB_ENV structure. 00102 * 00103 * PUBLIC: int CDB___dbenv_init __P((DB_ENV *)); 00104 */ 00105 int 00106 CDB___dbenv_init(dbenv) 00107 DB_ENV *dbenv; 00108 { 00109 /* 00110 * Set up methods that are the same in both normal and RPC 00111 */ 00112 dbenv->err = __dbenv_err; 00113 dbenv->errx = __dbenv_errx; 00114 dbenv->set_errcall = __dbenv_set_errcall; 00115 dbenv->set_errfile = __dbenv_set_errfile; 00116 dbenv->set_errpfx = __dbenv_set_errpfx; 00117 00118 #ifdef HAVE_RPC 00119 if (F_ISSET(dbenv, DB_ENV_RPCCLIENT)) { 00120 dbenv->close = __dbcl_env_close; 00121 dbenv->open = __dbcl_env_open; 00122 dbenv->remove = __dbcl_env_remove; 00123 dbenv->set_data_dir = __dbcl_set_data_dir; 00124 dbenv->set_feedback = __dbcl_env_set_feedback; 00125 dbenv->set_paniccall = __dbcl_env_paniccall; 00126 dbenv->set_recovery_init = __dbcl_set_recovery_init; 00127 dbenv->set_server = __dbcl_envserver; 00128 dbenv->set_shm_key = __dbcl_set_shm_key; 00129 dbenv->set_tmp_dir = __dbcl_set_tmp_dir; 00130 dbenv->set_verbose = __dbcl_set_verbose; 00131 } else { 00132 #endif 00133 dbenv->close = CDB___dbenv_close; 00134 dbenv->open = CDB___dbenv_open; 00135 dbenv->remove = CDB___dbenv_remove; 00136 dbenv->set_data_dir = __dbenv_set_data_dir; 00137 dbenv->set_feedback = __dbenv_set_feedback; 00138 dbenv->set_paniccall = __dbenv_set_paniccall; 00139 dbenv->set_recovery_init = __dbenv_set_recovery_init; 00140 dbenv->set_server = __dbenv_set_server_noclnt; 00141 dbenv->set_shm_key = __dbenv_set_shm_key; 00142 dbenv->set_tmp_dir = __dbenv_set_tmp_dir; 00143 dbenv->set_verbose = __dbenv_set_verbose; 00144 #ifdef HAVE_RPC 00145 } 00146 #endif 00147 dbenv->shm_key = INVALID_REGION_SEGID; 00148 00149 CDB___log_dbenv_create(dbenv); /* Subsystem specific. */ 00150 CDB___lock_dbenv_create(dbenv); 00151 CDB___memp_dbenv_create(dbenv); 00152 CDB___txn_dbenv_create(dbenv); 00153 00154 return (0); 00155 } 00156 00157 /* 00158 * __dbenv_err -- 00159 * Error message, including the standard error string. 00160 */ 00161 static void 00162 #ifdef __STDC__ 00163 __dbenv_err(const DB_ENV *dbenv, int error, const char *fmt, ...) 00164 #else 00165 __dbenv_err(dbenv, error, fmt, va_alist) 00166 const DB_ENV *dbenv; 00167 int error; 00168 const char *fmt; 00169 va_dcl 00170 #endif 00171 { 00172 va_list ap; 00173 00174 #ifdef __STDC__ 00175 va_start(ap, fmt); 00176 #else 00177 va_start(ap); 00178 #endif 00179 CDB___db_real_err(dbenv, error, 1, 1, fmt, ap); 00180 00181 va_end(ap); 00182 } 00183 00184 /* 00185 * __dbenv_errx -- 00186 * Error message. 00187 */ 00188 static void 00189 #ifdef __STDC__ 00190 __dbenv_errx(const DB_ENV *dbenv, const char *fmt, ...) 00191 #else 00192 __dbenv_errx(dbenv, fmt, va_alist) 00193 const DB_ENV *dbenv; 00194 const char *fmt; 00195 va_dcl 00196 #endif 00197 { 00198 va_list ap; 00199 00200 #ifdef __STDC__ 00201 va_start(ap, fmt); 00202 #else 00203 va_start(ap); 00204 #endif 00205 CDB___db_real_err(dbenv, 0, 0, 1, fmt, ap); 00206 00207 va_end(ap); 00208 } 00209 00210 static int 00211 __dbenv_set_data_dir(dbenv, dir) 00212 DB_ENV *dbenv; 00213 const char *dir; 00214 { 00215 int ret; 00216 00217 #define DATA_INIT_CNT 20 /* Start with 20 data slots. */ 00218 if (dbenv->db_data_dir == NULL) { 00219 if ((ret = CDB___os_calloc(dbenv, DATA_INIT_CNT, 00220 sizeof(char **), &dbenv->db_data_dir)) != 0) 00221 return (ret); 00222 dbenv->data_cnt = DATA_INIT_CNT; 00223 } else if (dbenv->data_next == dbenv->data_cnt - 1) { 00224 dbenv->data_cnt *= 2; 00225 if ((ret = CDB___os_realloc(dbenv, 00226 dbenv->data_cnt * sizeof(char **), 00227 NULL, &dbenv->db_data_dir)) != 0) 00228 return (ret); 00229 } 00230 return (CDB___os_strdup(dbenv, 00231 dir, &dbenv->db_data_dir[dbenv->data_next++])); 00232 } 00233 00234 static void 00235 __dbenv_set_errcall(dbenv, errcall) 00236 DB_ENV *dbenv; 00237 void (*errcall) __P((const char *, char *)); 00238 { 00239 dbenv->db_errcall = errcall; 00240 } 00241 00242 static void 00243 __dbenv_set_errfile(dbenv, errfile) 00244 DB_ENV *dbenv; 00245 FILE *errfile; 00246 { 00247 dbenv->db_errfile = errfile; 00248 } 00249 00250 static void 00251 __dbenv_set_errpfx(dbenv, errpfx) 00252 DB_ENV *dbenv; 00253 const char *errpfx; 00254 { 00255 dbenv->db_errpfx = errpfx; 00256 } 00257 00258 static int 00259 __dbenv_set_feedback(dbenv, feedback) 00260 DB_ENV *dbenv; 00261 void (*feedback) __P((DB_ENV *, int, int)); 00262 { 00263 dbenv->db_feedback = feedback; 00264 return (0); 00265 } 00266 00267 static int 00268 __dbenv_set_paniccall(dbenv, paniccall) 00269 DB_ENV *dbenv; 00270 void (*paniccall) __P((DB_ENV *, int)); 00271 { 00272 dbenv->db_paniccall = paniccall; 00273 return (0); 00274 } 00275 00276 static int 00277 __dbenv_set_recovery_init(dbenv, recovery_init) 00278 DB_ENV *dbenv; 00279 int (*recovery_init) __P((DB_ENV *)); 00280 { 00281 ENV_ILLEGAL_AFTER_OPEN(dbenv, "set_recovery_init"); 00282 00283 dbenv->db_recovery_init = recovery_init; 00284 00285 return (0); 00286 } 00287 00288 static int 00289 __dbenv_set_shm_key(dbenv, shm_key) 00290 DB_ENV *dbenv; 00291 long shm_key; /* !!!: really a key_t. */ 00292 { 00293 ENV_ILLEGAL_AFTER_OPEN(dbenv, "set_shm_key"); 00294 00295 dbenv->shm_key = shm_key; 00296 return (0); 00297 } 00298 00299 static int 00300 __dbenv_set_tmp_dir(dbenv, dir) 00301 DB_ENV *dbenv; 00302 const char *dir; 00303 { 00304 if (dbenv->db_tmp_dir != NULL) 00305 CDB___os_freestr(dbenv->db_tmp_dir); 00306 return (CDB___os_strdup(dbenv, dir, &dbenv->db_tmp_dir)); 00307 } 00308 00309 static int 00310 __dbenv_set_verbose(dbenv, which, onoff) 00311 DB_ENV *dbenv; 00312 u_int32_t which; 00313 int onoff; 00314 { 00315 switch (which) { 00316 case DB_VERB_CHKPOINT: 00317 case DB_VERB_DEADLOCK: 00318 case DB_VERB_RECOVERY: 00319 case DB_VERB_WAITSFOR: 00320 if (onoff) 00321 FLD_SET(dbenv->verbose, which); 00322 else 00323 FLD_CLR(dbenv->verbose, which); 00324 break; 00325 default: 00326 return (EINVAL); 00327 } 00328 return (0); 00329 } 00330 00331 /* 00332 * CDB___db_mi_env -- 00333 * Method illegally called with public environment. 00334 * 00335 * PUBLIC: int CDB___db_mi_env __P((DB_ENV *, const char *)); 00336 */ 00337 int 00338 CDB___db_mi_env(dbenv, name) 00339 DB_ENV *dbenv; 00340 const char *name; 00341 { 00342 CDB___db_err(dbenv, "%s: method meaningless in shared environment", name); 00343 return (EINVAL); 00344 } 00345 00346 /* 00347 * CDB___db_mi_open -- 00348 * Method illegally called after open. 00349 * 00350 * PUBLIC: int CDB___db_mi_open __P((DB_ENV *, const char *, int)); 00351 */ 00352 int 00353 CDB___db_mi_open(dbenv, name, after) 00354 DB_ENV *dbenv; 00355 const char *name; 00356 int after; 00357 { 00358 CDB___db_err(dbenv, 00359 "%s: method meaningless %s open", name, after ? "after" : "before"); 00360 return (EINVAL); 00361 } 00362 00363 /* 00364 * CDB___db_env_config -- 00365 * Method or function called without subsystem being configured. 00366 * 00367 * PUBLIC: int CDB___db_env_config __P((DB_ENV *, int)); 00368 */ 00369 int 00370 CDB___db_env_config(dbenv, subsystem) 00371 DB_ENV *dbenv; 00372 int subsystem; 00373 { 00374 const char *name; 00375 00376 switch (subsystem) { 00377 case DB_INIT_LOCK: 00378 name = "lock"; 00379 break; 00380 case DB_INIT_LOG: 00381 name = "log"; 00382 break; 00383 case DB_INIT_MPOOL: 00384 name = "mpool"; 00385 break; 00386 case DB_INIT_TXN: 00387 name = "txn"; 00388 break; 00389 default: 00390 name = "unknown"; 00391 break; 00392 } 00393 CDB___db_err(dbenv, 00394 "%s interface called with environment not configured for that subsystem", 00395 name); 00396 return (EINVAL); 00397 } 00398 00399 static int 00400 __dbenv_set_server_noclnt(dbenv, host, tsec, ssec, flags) 00401 DB_ENV *dbenv; 00402 char *host; 00403 long tsec, ssec; 00404 u_int32_t flags; 00405 { 00406 COMPQUIET(host, NULL); 00407 COMPQUIET(tsec, 0); 00408 COMPQUIET(ssec, 0); 00409 COMPQUIET(flags, 0); 00410 00411 CDB___db_err(dbenv, "set_server method meaningless in non-RPC enviroment"); 00412 return(CDB___db_eopnotsup(dbenv)); 00413 }