⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fs-loader.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * fs_loader.c:  Front-end to the various FS back ends * * ==================================================================== * Copyright (c) 2000-2004 CollabNet.  All rights reserved. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution.  The terms * are also available at http://subversion.tigris.org/license-1.html. * If newer versions of this license are posted there, you may use a * newer version instead, at your option. * * This software consists of voluntary contributions made by many * individuals.  For exact contribution history, see the revision * history and logs, available at http://subversion.tigris.org/. * ==================================================================== */#include <string.h>#include <apr.h>#include <apr_hash.h>#include <apr_thread_mutex.h>#include "svn_types.h"#include "svn_dso.h"#include "svn_version.h"#include "svn_fs.h"#include "svn_path.h"#include "svn_xml.h"#include "svn_pools.h"#include "svn_string.h"#include "svn_private_config.h"#include "fs-loader.h"/* This is defined by configure on platforms which use configure, but   we need to define a fallback for Windows. */#ifndef DEFAULT_FS_TYPE#define DEFAULT_FS_TYPE "fsfs"#endif#define FS_TYPE_FILENAME "fs-type"/* A pool common to all FS objects.  See the documentation on the   serialized_init function in fs-loader.h and for   svn_fs_initialize(). */static apr_pool_t *common_pool;#if APR_HAS_THREADSstatic apr_thread_mutex_t *common_pool_lock;#endif/* --- Utility functions for the loader --- */static const struct fs_type_defn {  const char *fs_type;  const char *fsap_name;  fs_init_func_t initfunc;} fs_modules[] = {  {    SVN_FS_TYPE_BDB, "base",#ifdef SVN_LIBSVN_FS_LINKS_FS_BASE    svn_fs_base__init#endif  },  {    SVN_FS_TYPE_FSFS, "fs",#ifdef SVN_LIBSVN_FS_LINKS_FS_FS    svn_fs_fs__init#endif  },  { NULL }};static svn_error_t *load_module(fs_init_func_t *initfunc, const char *name, apr_pool_t *pool){  *initfunc = NULL;#if APR_HAS_DSO  {    apr_dso_handle_t *dso;    apr_dso_handle_sym_t symbol;    const char *libname;    const char *funcname;    apr_status_t status;    libname = apr_psprintf(pool, "libsvn_fs_%s-%d.so.0",                           name, SVN_VER_MAJOR);    funcname = apr_psprintf(pool, "svn_fs_%s__init", name);    /* Find/load the specified library.  If we get an error, assume       the library doesn't exist.  The library will be unloaded when       pool is destroyed. */    SVN_ERR(svn_dso_load(&dso, libname));    if (! dso)      return SVN_NO_ERROR;    /* find the initialization routine */    status = apr_dso_sym(&symbol, dso, funcname);    if (status)      return svn_error_wrap_apr(status, _("'%s' does not define '%s()'"),                                libname, funcname);    *initfunc = (fs_init_func_t) symbol;  }#endif /* APR_HAS_DSO */  return SVN_NO_ERROR;}/* Fetch a library vtable by a pointer into the library definitions array. */static svn_error_t *get_library_vtable_direct(fs_library_vtable_t **vtable,                          const struct fs_type_defn *fst,                          apr_pool_t *pool){  fs_init_func_t initfunc = NULL;  const svn_version_t *my_version = svn_fs_version();  const svn_version_t *fs_version;  initfunc = fst->initfunc;  if (! initfunc)    SVN_ERR(load_module(&initfunc, fst->fsap_name, pool));  if (! initfunc)    return svn_error_createf(SVN_ERR_FS_UNKNOWN_FS_TYPE, NULL,                             _("Failed to load module for FS type '%s'"),                             fst->fs_type);  SVN_ERR(initfunc(my_version, vtable));  fs_version = (*vtable)->get_version();  if (!svn_ver_equal(my_version, fs_version))    return svn_error_createf(SVN_ERR_VERSION_MISMATCH, NULL,                             _("Mismatched FS module version for '%s':"                               " found %d.%d.%d%s,"                               " expected %d.%d.%d%s"),                             fst->fs_type,                             my_version->major, my_version->minor,                             my_version->patch, my_version->tag,                             fs_version->major, fs_version->minor,                             fs_version->patch, fs_version->tag);  return SVN_NO_ERROR;}/* Fetch a library vtable by FS type. */static svn_error_t *get_library_vtable(fs_library_vtable_t **vtable, const char *fs_type,                   apr_pool_t *pool){  const struct fs_type_defn *fst;  for (fst = fs_modules; fst->fs_type; fst++)    {      if (strcmp(fs_type, fst->fs_type) == 0)        return get_library_vtable_direct(vtable, fst, pool);    }    return svn_error_createf(SVN_ERR_FS_UNKNOWN_FS_TYPE, NULL,                           _("Unknown FS type '%s'"), fs_type);}svn_error_t *svn_fs_type(const char **fs_type, const char *path, apr_pool_t *pool){  const char *filename;  char buf[128];  svn_error_t *err;  apr_file_t *file;  apr_size_t len;  /* Read the fsap-name file to get the FSAP name, or assume the default. */  filename = svn_path_join(path, FS_TYPE_FILENAME, pool);  err = svn_io_file_open(&file, filename, APR_READ|APR_BUFFERED, 0, pool);  if (err && APR_STATUS_IS_ENOENT(err->apr_err))    {      svn_error_clear(err);      *fs_type = apr_pstrdup(pool, SVN_FS_TYPE_BDB);      return SVN_NO_ERROR;    }  else if (err)    return err;  len = sizeof(buf);  SVN_ERR(svn_io_read_length_line(file, buf, &len, pool));  SVN_ERR(svn_io_file_close(file, pool));  *fs_type = apr_pstrdup(pool, buf);  return SVN_NO_ERROR;}/* Fetch the library vtable for an existing FS. */static svn_error_t *fs_library_vtable(fs_library_vtable_t **vtable, const char *path,                  apr_pool_t *pool){  const char *fs_type;  SVN_ERR(svn_fs_type(&fs_type, path, pool));  /* Fetch the library vtable by name, now that we've chosen one. */  return get_library_vtable(vtable, fs_type, pool);}static svn_error_t *write_fs_type(const char *path, const char *fs_type, apr_pool_t *pool){  const char *filename;  apr_file_t *file;  filename = svn_path_join(path, FS_TYPE_FILENAME, pool);  SVN_ERR(svn_io_file_open(&file, filename,                           APR_WRITE|APR_CREATE|APR_TRUNCATE|APR_BUFFERED,                           APR_OS_DEFAULT, pool));  SVN_ERR(svn_io_file_write_full(file, fs_type, strlen(fs_type), NULL,                                 pool));  SVN_ERR(svn_io_file_write_full(file, "\n", 1, NULL, pool));  SVN_ERR(svn_io_file_close(file, pool));  return SVN_NO_ERROR;}/* --- Functions for operating on filesystems by pathname --- */static apr_status_t uninit(void *data){  common_pool = NULL;#if APR_HAS_THREADS  common_pool_lock = NULL;#endif  return APR_SUCCESS;}svn_error_t *svn_fs_initialize(apr_pool_t *pool){#if APR_HAS_THREADS  apr_status_t status;#endif  /* Protect against multiple calls. */  if (common_pool)    return SVN_NO_ERROR;  common_pool = svn_pool_create(pool);#if APR_HAS_THREADS  status = apr_thread_mutex_create(&common_pool_lock,                                   APR_THREAD_MUTEX_DEFAULT, common_pool);  if (status)    return svn_error_wrap_apr(status, _("Can't allocate FS mutex"));#endif  /* ### This won't work if POOL is NULL and libsvn_fs is loaded as a DSO     ### (via libsvn_ra_local say) since the global common_pool will live     ### longer than the DSO, which gets unloaded when the pool used to     ### load it is cleared, and so when the handler runs it will refer to     ### a function that no longer exists.  libsvn_ra_local attempts to     ### work around this by explicitly calling svn_fs_initialize. */  apr_pool_cleanup_register(common_pool, NULL, uninit, apr_pool_cleanup_null);  return SVN_NO_ERROR;}static svn_error_t *serialized_init(svn_fs_t *fs, apr_pool_t *pool){  svn_error_t *err;#if APR_HAS_THREADS  apr_status_t status;#endif  /* Per our API compatibility rules, we cannot ensure that     svn_fs_initialize is called by the application.  If not, we     cannot create the common pool and lock in a thread-safe fashion,     nor can we clean up the common pool if libsvn_fs is dynamically     unloaded.  This function makes a best effort by creating the     common pool as a child of the global pool; the window of failure     due to thread collision is small. */  if (!common_pool)    SVN_ERR(svn_fs_initialize(NULL));  /* Invoke the FS module's serialized_init function with the common     pool protected by a lock. */#if APR_HAS_THREADS  status = apr_thread_mutex_lock(common_pool_lock);  if (status)    return svn_error_wrap_apr(status, _("Can't grab FS mutex"));#endif  err = fs->vtable->serialized_init(fs, common_pool, pool);#if APR_HAS_THREADS  status = apr_thread_mutex_unlock(common_pool_lock);  if (status && !err)    return svn_error_wrap_apr(status, _("Can't ungrab FS mutex"));#endif  return err;}/* A default warning handling function.  */static voiddefault_warning_func(void *baton, svn_error_t *err){  /* The one unforgiveable sin is to fail silently.  Dumping to stderr     or /dev/tty is not acceptable default behavior for server     processes, since those may both be equivalent to /dev/null.  */  abort();}svn_fs_t *svn_fs_new(apr_hash_t *fs_config, apr_pool_t *pool){  svn_fs_t *fs;  fs = apr_palloc(pool, sizeof(*fs));  fs->pool = pool;  fs->path = NULL;  fs->warning = default_warning_func;  fs->warning_baton = NULL;  fs->config = fs_config;  fs->access_ctx = NULL;  fs->vtable = NULL;  fs->fsap_data = NULL;  return fs;}voidsvn_fs_set_warning_func(svn_fs_t *fs, svn_fs_warning_callback_t warning,                        void *warning_baton){  fs->warning = warning;  fs->warning_baton = warning_baton;}svn_error_t *svn_fs_create(svn_fs_t **fs_p, const char *path, apr_hash_t *fs_config,              apr_pool_t *pool){  fs_library_vtable_t *vtable;  const char *fs_type = NULL;  if (fs_config)    fs_type = apr_hash_get(fs_config, SVN_FS_CONFIG_FS_TYPE,                           APR_HASH_KEY_STRING);  if (fs_type == NULL)    fs_type = DEFAULT_FS_TYPE;  SVN_ERR(get_library_vtable(&vtable, fs_type, pool));  /* Create the FS directory and write out the fsap-name file. */  SVN_ERR(svn_io_dir_make_sgid(path, APR_OS_DEFAULT, pool));  SVN_ERR(write_fs_type(path, fs_type, pool));  /* Perform the actual creation. */  *fs_p = svn_fs_new(fs_config, pool);  SVN_ERR(vtable->create(*fs_p, path, pool));  return serialized_init(*fs_p, pool);}svn_error_t *svn_fs_open(svn_fs_t **fs_p, const char *path, apr_hash_t *fs_config,            apr_pool_t *pool){  fs_library_vtable_t *vtable;  SVN_ERR(fs_library_vtable(&vtable, path, pool));  *fs_p = svn_fs_new(fs_config, pool);  SVN_ERR(vtable->open(*fs_p, path, pool));  return serialized_init(*fs_p, pool);}const char *svn_fs_path(svn_fs_t *fs, apr_pool_t *pool){  return apr_pstrdup(pool, fs->path);}svn_error_t *svn_fs_delete_fs(const char *path, apr_pool_t *pool){  fs_library_vtable_t *vtable;  SVN_ERR(fs_library_vtable(&vtable, path, pool));  return vtable->delete_fs(path, pool);}svn_error_t *svn_fs_hotcopy(const char *src_path, const char *dest_path,               svn_boolean_t clean, apr_pool_t *pool){  fs_library_vtable_t *vtable;  const char *fs_type;  SVN_ERR(svn_fs_type(&fs_type, src_path, pool));  SVN_ERR(get_library_vtable(&vtable, fs_type, pool));  SVN_ERR(vtable->hotcopy(src_path, dest_path, clean, pool));  SVN_ERR(write_fs_type(dest_path, fs_type, pool));  return SVN_NO_ERROR;}/* --- Berkeley-specific functions --- */svn_error_t *svn_fs_create_berkeley(svn_fs_t *fs, const char *path){  fs_library_vtable_t *vtable;  SVN_ERR(get_library_vtable(&vtable, SVN_FS_TYPE_BDB, fs->pool));  /* Create the FS directory and write out the fsap-name file. */  SVN_ERR(svn_io_dir_make_sgid(path, APR_OS_DEFAULT, fs->pool));  SVN_ERR(write_fs_type(path, SVN_FS_TYPE_BDB, fs->pool));  /* Perform the actual creation. */  SVN_ERR(vtable->create(fs, path, fs->pool));  return serialized_init(fs, fs->pool);}svn_error_t *svn_fs_open_berkeley(svn_fs_t *fs, const char *path){  fs_library_vtable_t *vtable;  SVN_ERR(fs_library_vtable(&vtable, path, fs->pool));  SVN_ERR(vtable->open(fs, path, fs->pool));  return serialized_init(fs, fs->pool);}const char *svn_fs_berkeley_path(svn_fs_t *fs, apr_pool_t *pool){  return svn_fs_path(fs, pool);}svn_error_t *svn_fs_delete_berkeley(const char *path, apr_pool_t *pool){  return svn_fs_delete_fs(path, pool);}svn_error_t *svn_fs_hotcopy_berkeley(const char *src_path, const char *dest_path,                        svn_boolean_t clean_logs, apr_pool_t *pool){  return svn_fs_hotcopy(src_path, dest_path, clean_logs, pool);}svn_error_t *svn_fs_berkeley_recover(const char *path, apr_pool_t *pool){  fs_library_vtable_t *vtable;  SVN_ERR(fs_library_vtable(&vtable, path, pool));  return vtable->bdb_recover(path, pool);}svn_error_t *svn_fs_set_berkeley_errcall(svn_fs_t *fs,                            void (*handler)(const char *errpfx, char *msg)){  return fs->vtable->bdb_set_errcall(fs, handler);}svn_error_t *svn_fs_berkeley_logfiles(apr_array_header_t **logfiles,                         const char *path,                         svn_boolean_t only_unused,                         apr_pool_t *pool){  fs_library_vtable_t *vtable;  SVN_ERR(fs_library_vtable(&vtable, path, pool));  return vtable->bdb_logfiles(logfiles, path, only_unused, pool);}/* --- Transaction functions --- */svn_error_t *svn_fs_begin_txn2(svn_fs_txn_t **txn_p, svn_fs_t *fs, svn_revnum_t rev,                  apr_uint32_t flags, apr_pool_t *pool){  return fs->vtable->begin_txn(txn_p, fs, rev, flags, pool);}svn_error_t *svn_fs_begin_txn(svn_fs_txn_t **txn_p, svn_fs_t *fs, svn_revnum_t rev,                 apr_pool_t *pool){  return fs->vtable->begin_txn(txn_p, fs, rev, 0, pool);}svn_error_t *svn_fs_commit_txn(const char **conflict_p, svn_revnum_t *new_rev,                  svn_fs_txn_t *txn, apr_pool_t *pool){  return txn->vtable->commit(conflict_p, new_rev, txn, pool);}svn_error_t *svn_fs_abort_txn(svn_fs_txn_t *txn, apr_pool_t *pool){  return txn->vtable->abort(txn, pool);}svn_error_t *svn_fs_purge_txn(svn_fs_t *fs, const char *txn_id, apr_pool_t *pool){  return fs->vtable->purge_txn(fs, txn_id, pool);}svn_error_t *svn_fs_txn_name(const char **name_p, svn_fs_txn_t *txn, apr_pool_t *pool){  *name_p = apr_pstrdup(pool, txn->id);  return SVN_NO_ERROR;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -