📄 env_open.c
字号:
return (ret); /* Remove the environment. */ return (__db_e_remove(dbenv, flags));}/* * __dbenv_config -- * Initialize the DB_ENV structure. */static int__dbenv_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. */ if ((ret = __db_appname(dbenv, DB_APP_NONE, "DB_CONFIG", 0, NULL, &p)) != 0) return (ret); 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); /* * The locking file descriptor is rarely on. Set the fd to -1, not * because it's ever tested, but to make sure we catch mistakes. */ if ((ret = __os_calloc( dbenv, 1, sizeof(*dbenv->lockfhp), &dbenv->lockfhp)) != 0) return (ret); dbenv->lockfhp->fd = -1; /* Flag that the DB_ENV structure has been initialized. */ F_SET(dbenv, DB_ENV_OPEN_CALLED); return (0);}/* * __dbenv_close -- * DB_ENV destructor. * * PUBLIC: int __dbenv_close __P((DB_ENV *, u_int32_t)); */int__dbenv_close(dbenv, flags) DB_ENV *dbenv; u_int32_t flags;{ char **p; int ret, t_ret; COMPQUIET(flags, 0); PANIC_CHECK(dbenv); 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 (dbenv->rep_handle != NULL && (t_ret = __rep_preclose(dbenv, 1)) != 0 && ret == 0) ret = t_ret; if (dbenv->db_ref != 0) { __db_err(dbenv, "Database handles open during environment close"); if (ret == 0) ret = EINVAL; } /* * Detach from the regions and undo the allocations done by * DB_ENV->open. */ if ((t_ret = __dbenv_refresh(dbenv, 0)) != 0 && ret == 0) ret = t_ret; /* Do per-subsystem destruction. */ __lock_dbenv_close(dbenv); /* void */ if ((t_ret = __rep_dbenv_close(dbenv)) != 0 && ret == 0) ret = t_ret;#ifdef HAVE_CRYPTO 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); } /* Discard the structure. */ memset(dbenv, CLEAR_BYTE, sizeof(DB_ENV)); __os_free(NULL, dbenv); return (ret);}/* * __dbenv_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__dbenv_refresh(dbenv, orig_flags) DB_ENV *dbenv; u_int32_t orig_flags;{ DB_MPOOL *dbmp; int ret, t_ret; ret = 0; /* * Close 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 __dbenv_refresh, only undo * the effects of __dbenv_open. Functions that undo work done by * db_env_create or by a configurator function should go in * __dbenv_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) && (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. */ LIST_INIT(&dbenv->dblist); if (dbenv->dblist_mutexp != NULL) { dbmp = dbenv->mp_handle; __db_mutex_free(dbenv, dbmp->reginfo, dbenv->dblist_mutexp); } if (dbenv->mt_mutexp != NULL) { dbmp = dbenv->mp_handle; __db_mutex_free(dbenv, dbmp->reginfo, dbenv->mt_mutexp); } 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 = dbenv->memp_sync(dbenv, NULL)) != 0 && ret == 0) ret = t_ret; if ((t_ret = __memp_dbenv_refresh(dbenv)) != 0 && ret == 0) ret = t_ret; } /* Detach from the region. */ 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 __dbenv_open. */ if (dbenv->db_home != NULL) { __os_free(dbenv, dbenv->db_home); dbenv->db_home = NULL; } dbenv->db_mode = 0; if (dbenv->lockfhp != NULL) { __os_free(dbenv, dbenv->lockfhp); dbenv->lockfhp = NULL; } 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) { \ if ((add) != NULL) { \ /* 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; \ } \}/* * __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, fhp, namep) DB_ENV *dbenv; APPNAME appname; const char *file; u_int32_t tmp_oflags; DB_FH *fhp; 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 (fhp != NULL) F_CLR(fhp, DB_FH_VALID); 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 "BDBXXXXXX" 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, fhp)) != 0) { __os_free(dbenv, str);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -