# ./pullrev.sh 1912477 1912571 1912718 1913654 1914438 http://svn.apache.org/viewvc?view=revision&revision=1912477 http://svn.apache.org/viewvc?view=revision&revision=1912571 http://svn.apache.org/viewvc?view=revision&revision=1912718 http://svn.apache.org/viewvc?view=revision&revision=1913654 http://svn.apache.org/viewvc?view=revision&revision=1914438 --- httpd-2.4.58/modules/dav/fs/config6.m4.r1912477+ +++ httpd-2.4.58/modules/dav/fs/config6.m4 @@ -20,4 +20,10 @@ APACHE_MODULE(dav_fs, DAV provider for the filesystem. --enable-dav also enables mod_dav_fs., $dav_fs_objects, , $dav_fs_enable,,dav) +if test "x$enable_dav_fs" = "xshared"; then + # The only symbol which needs to be exported is the module + # structure, so ask libtool to hide everything else: + APR_ADDTO(MOD_DAV_FS_LDADD, [-export-symbols-regex dav_fs_module]) +fi + APACHE_MODPATH_FINISH --- httpd-2.4.58/modules/dav/fs/dbm.c.r1912477+ +++ httpd-2.4.58/modules/dav/fs/dbm.c @@ -47,6 +47,10 @@ #include "http_log.h" #include "http_main.h" /* for ap_server_conf */ +#ifndef DEFAULT_PROPDB_DBM_TYPE +#define DEFAULT_PROPDB_DBM_TYPE "default" +#endif + APLOG_USE_MODULE(dav_fs); struct dav_db { @@ -100,7 +104,7 @@ /* There might not be a if we had problems creating it. */ if (db == NULL) { errcode = 1; - errstr = "Could not open property database."; + errstr = "Could not open database."; if (APR_STATUS_IS_EDSOOPEN(status)) ap_log_error(APLOG_MARK, APLOG_CRIT, status, ap_server_conf, APLOGNO(00576) "The DBM driver could not be loaded"); @@ -129,10 +133,10 @@ /* dav_dbm_open_direct: Opens a *dbm database specified by path. * ro = boolean read-only flag. */ -dav_error * dav_dbm_open_direct(apr_pool_t *p, const char *pathname, int ro, - dav_db **pdb) +dav_error * dav_dbm_open_direct(apr_pool_t *p, const char *pathname, + const char *dbmtype, int ro, dav_db **pdb) { -#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7) +#if APR_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7) const apr_dbm_driver_t *driver; const apu_err_t *err; #endif @@ -141,13 +145,13 @@ *pdb = NULL; -#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7) - if ((status = apr_dbm_get_driver(&driver, NULL, &err, p)) != APR_SUCCESS) { +#if APR_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7) + if ((status = apr_dbm_get_driver(&driver, dbmtype, &err, p)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, status, ap_server_conf, APLOGNO(10289) - "mod_dav_fs: The DBM library '%s' could not be loaded: %s", - err->reason, err->msg); + "mod_dav_fs: The DBM library '%s' for '%s' could not be loaded: %s", + err->reason, dbmtype, err->msg); return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 1, status, - "Could not load library for property database."); + "Could not load library for database."); } if ((status = apr_dbm_open2(&file, driver, pathname, ro ? APR_DBM_READONLY : APR_DBM_RWCREATE, @@ -156,7 +160,7 @@ return dav_fs_dbm_error(NULL, p, status); } #else - if ((status = apr_dbm_open(&file, pathname, + if ((status = apr_dbm_open_ex(&file, dbmtype, pathname, ro ? APR_DBM_READONLY : APR_DBM_RWCREATE, APR_OS_DEFAULT, p)) != APR_SUCCESS @@ -206,7 +210,7 @@ /* ### do we need to deal with the umask? */ - return dav_dbm_open_direct(p, pathname, ro, pdb); + return dav_dbm_open_direct(p, pathname, DEFAULT_PROPDB_DBM_TYPE, ro, pdb); } void dav_dbm_close(dav_db *db) --- httpd-2.4.58/modules/dav/fs/lock.c.r1912477+ +++ httpd-2.4.58/modules/dav/fs/lock.c @@ -181,8 +181,7 @@ { request_rec *r; /* for accessing the uuid state */ apr_pool_t *pool; /* a pool to use */ - const char *lockdb_path; /* where is the lock database? */ - + const dav_fs_server_conf *conf; /* lock database config & metadata */ int opened; /* we opened the database */ dav_db *db; /* if non-NULL, the lock database */ }; @@ -292,6 +291,19 @@ return dav_compare_locktoken(lt1, lt2); } +static apr_status_t dav_fs_lockdb_cleanup(void *data) +{ + dav_lockdb *lockdb = data; + + apr_global_mutex_unlock(lockdb->info->conf->lockdb_mutex); + + if (lockdb->info->db) { + dav_dbm_close(lockdb->info->db); + } + + return APR_SUCCESS; +} + /* ** dav_fs_really_open_lockdb: ** @@ -300,15 +312,27 @@ static dav_error * dav_fs_really_open_lockdb(dav_lockdb *lockdb) { dav_error *err; + apr_status_t rv; if (lockdb->info->opened) return NULL; + rv = apr_global_mutex_lock(lockdb->info->conf->lockdb_mutex); + if (rv) { + return dav_new_error(lockdb->info->pool, + HTTP_INTERNAL_SERVER_ERROR, + DAV_ERR_LOCK_OPENDB, rv, + "Could not lock mutex for lock database."); + } + err = dav_dbm_open_direct(lockdb->info->pool, - lockdb->info->lockdb_path, + lockdb->info->conf->lockdb_path, + lockdb->info->conf->lockdb_type, lockdb->ro, &lockdb->info->db); if (err != NULL) { + apr_global_mutex_unlock(lockdb->info->conf->lockdb_mutex); + return dav_push_error(lockdb->info->pool, HTTP_INTERNAL_SERVER_ERROR, DAV_ERR_LOCK_OPENDB, @@ -316,6 +340,10 @@ err); } + apr_pool_cleanup_register(lockdb->info->pool, lockdb, + dav_fs_lockdb_cleanup, + dav_fs_lockdb_cleanup); + /* all right. it is opened now. */ lockdb->info->opened = 1; @@ -341,9 +369,9 @@ comb->pub.info = &comb->priv; comb->priv.r = r; comb->priv.pool = r->pool; - - comb->priv.lockdb_path = dav_get_lockdb_path(r); - if (comb->priv.lockdb_path == NULL) { + comb->priv.conf = dav_fs_get_server_conf(r); + + if (comb->priv.conf == NULL || comb->priv.conf->lockdb_path == NULL) { return dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, DAV_ERR_LOCK_NO_DB, 0, "A lock database was not specified with the " @@ -369,8 +397,8 @@ */ static void dav_fs_close_lockdb(dav_lockdb *lockdb) { - if (lockdb->info->db != NULL) - dav_dbm_close(lockdb->info->db); + apr_pool_cleanup_run(lockdb->info->pool, lockdb, + dav_fs_lockdb_cleanup); } /* --- httpd-2.4.58/modules/dav/fs/mod_dav_fs.c.r1912477+ +++ httpd-2.4.58/modules/dav/fs/mod_dav_fs.c @@ -14,31 +14,35 @@ * limitations under the License. */ +#if !defined(_MSC_VER) && !defined(NETWARE) +#include "ap_config_auto.h" +#endif + #include "httpd.h" #include "http_config.h" +#include "http_core.h" +#include "http_log.h" #include "apr_strings.h" #include "mod_dav.h" #include "repos.h" -/* per-server configuration */ -typedef struct { - const char *lockdb_path; - -} dav_fs_server_conf; - extern module AP_MODULE_DECLARE_DATA dav_fs_module; #ifndef DEFAULT_DAV_LOCKDB #define DEFAULT_DAV_LOCKDB "davlockdb" #endif +#ifndef DEFAULT_DAV_LOCKDB_TYPE +#define DEFAULT_DAV_LOCKDB_TYPE "default" +#endif -const char *dav_get_lockdb_path(const request_rec *r) -{ - dav_fs_server_conf *conf; +static const char dav_fs_mutexid[] = "dav_fs-lockdb"; - conf = ap_get_module_config(r->server->module_config, &dav_fs_module); - return conf->lockdb_path; +static apr_global_mutex_t *dav_fs_lockdb_mutex; + +const dav_fs_server_conf *dav_fs_get_server_conf(const request_rec *r) +{ + return ap_get_module_config(r->server->module_config, &dav_fs_module); } static void *dav_fs_create_server_config(apr_pool_t *p, server_rec *s) @@ -57,15 +61,50 @@ newconf->lockdb_path = child->lockdb_path ? child->lockdb_path : parent->lockdb_path; + newconf->lockdb_type = + child->lockdb_type ? child->lockdb_type : parent->lockdb_type; return newconf; } +static int dav_fs_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp) +{ + if (ap_mutex_register(pconf, dav_fs_mutexid, NULL, APR_LOCK_DEFAULT, 0)) + return !OK; + return OK; +} + +static void dav_fs_child_init(apr_pool_t *p, server_rec *s) +{ + apr_status_t rv; + + rv = apr_global_mutex_child_init(&dav_fs_lockdb_mutex, + apr_global_mutex_lockfile(dav_fs_lockdb_mutex), + p); + if (rv) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, + APLOGNO(10488) "child init failed for mutex"); + } +} + static apr_status_t dav_fs_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *base_server) { server_rec *s; + apr_status_t rv; + /* Ignore first pass through the config. */ + if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG) + return OK; + + rv = ap_global_mutex_create(&dav_fs_lockdb_mutex, NULL, dav_fs_mutexid, NULL, + base_server, p, 0); + if (rv) { + ap_log_error(APLOG_MARK, APLOG_ERR, rv, base_server, + APLOGNO(10489) "could not create lock mutex"); + return !OK; + } + for (s = base_server; s; s = s->next) { dav_fs_server_conf *conf; @@ -74,6 +113,13 @@ if (!conf->lockdb_path) { conf->lockdb_path = ap_state_dir_relative(p, DEFAULT_DAV_LOCKDB); } + if (!conf->lockdb_type) { + conf->lockdb_type = DEFAULT_DAV_LOCKDB_TYPE; + } + + /* Mutex is common across all vhosts, but could have one per + * vhost if required. */ + conf->lockdb_mutex = dav_fs_lockdb_mutex; } return OK; @@ -98,19 +144,36 @@ return NULL; } +/* + * Command handler for the DAVLockDBType directive, which is TAKE1 + */ +static const char *dav_fs_cmd_davlockdbtype(cmd_parms *cmd, void *config, + const char *arg1) +{ + dav_fs_server_conf *conf = ap_get_module_config(cmd->server->module_config, + &dav_fs_module); + conf->lockdb_type = arg1; + + return NULL; +} + static const command_rec dav_fs_cmds[] = { /* per server */ AP_INIT_TAKE1("DAVLockDB", dav_fs_cmd_davlockdb, NULL, RSRC_CONF, "specify a lock database"), + AP_INIT_TAKE1("DAVLockDBType", dav_fs_cmd_davlockdbtype, NULL, RSRC_CONF, + "specify a lock database DBM type"), { NULL } }; static void register_hooks(apr_pool_t *p) { + ap_hook_pre_config(dav_fs_pre_config, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_post_config(dav_fs_post_config, NULL, NULL, APR_HOOK_MIDDLE); - + ap_hook_child_init(dav_fs_child_init, NULL, NULL, APR_HOOK_MIDDLE); + dav_hook_gather_propsets(dav_fs_gather_propsets, NULL, NULL, APR_HOOK_MIDDLE); dav_hook_find_liveprop(dav_fs_find_liveprop, NULL, NULL, APR_HOOK_MIDDLE); --- httpd-2.4.58/modules/dav/fs/repos.h.r1912477+ +++ httpd-2.4.58/modules/dav/fs/repos.h @@ -25,6 +25,8 @@ #ifndef _DAV_FS_REPOS_H_ #define _DAV_FS_REPOS_H_ +#include "util_mutex.h" + /* the subdirectory to hold all DAV-related information for a directory */ #define DAV_FS_STATE_DIR ".DAV" #define DAV_FS_STATE_FILE_FOR_DIR ".state_for_dir" @@ -53,8 +55,8 @@ /* DBM functions used by the repository and locking providers */ extern const dav_hooks_db dav_hooks_db_dbm; -dav_error * dav_dbm_open_direct(apr_pool_t *p, const char *pathname, int ro, - dav_db **pdb); +dav_error * dav_dbm_open_direct(apr_pool_t *p, const char *pathname, + const char *dbmtype, int ro, dav_db **pdb); void dav_dbm_get_statefiles(apr_pool_t *p, const char *fname, const char **state1, const char **state2); dav_error * dav_dbm_delete(dav_db *db, apr_datum_t key); @@ -64,8 +66,15 @@ int dav_dbm_exists(dav_db *db, apr_datum_t key); void dav_dbm_close(dav_db *db); -/* where is the lock database located? */ -const char *dav_get_lockdb_path(const request_rec *r); +/* Per-server configuration. */ +typedef struct { + const char *lockdb_path; + const char *lockdb_type; + apr_global_mutex_t *lockdb_mutex; +} dav_fs_server_conf; + +/* Returns server configuration for the request. */ +const dav_fs_server_conf *dav_fs_get_server_conf(const request_rec *r); const dav_hooks_locks *dav_fs_get_lock_hooks(request_rec *r); const dav_hooks_propdb *dav_fs_get_propdb_hooks(request_rec *r);