Beispiel #1
0
static void test_timeout(abts_case *tc, apr_reslist_t *rl)
{
    apr_status_t rv;
    my_resource_t *resources[RESLIST_HMAX];
    my_resource_t *res;
    void *vp;
    int i;

    apr_reslist_timeout_set(rl, 1000);

    /* deplete all possible resources from the resource list
     * so that the next call will block until timeout is reached
     * (since there are no other threads to make a resource
     * available)
     */

    for (i = 0; i < RESLIST_HMAX; i++) {
        rv = apr_reslist_acquire(rl, (void**)&resources[i]);
        ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
    }

    /* next call will block until timeout is reached */
    rv = apr_reslist_acquire(rl, &vp);
    ABTS_TRUE(tc, APR_STATUS_IS_TIMEUP(rv));

    res = vp;

    /* release the resources; otherwise the destroy operation
     * will blow
     */
    for (i = 0; i < RESLIST_HMAX; i++) {
        rv = apr_reslist_release(rl, resources[i]);
        ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
    }
}
Beispiel #2
0
/* Functions we export for modules to use:
	- open acquires a connection from the pool (opens one if necessary)
	- close releases it back in to the pool
*/
PGconn* pgasp_pool_open(server_rec* s) {
  PGconn* ret = NULL ;
  pgasp_config* pgasp = (pgasp_config*)
	ap_get_module_config(s->module_config, &pgasp_module) ;
  apr_uint32_t acquired_cnt ;

  if (pgasp->dbpool == NULL) {
    pgasp = apr_hash_get(pgasp_pool_config, pgasp->key, APR_HASH_KEY_STRING);
  }
  if ( apr_reslist_acquire(pgasp->dbpool, (void**)&ret) != APR_SUCCESS ) {
    ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_pgasp: Failed to acquire PgSQL connection from pool!") ;
    return NULL ;
  }
  if (PQstatus(ret) != CONNECTION_OK) {
    PQreset(ret);
    if (PQstatus(ret) != CONNECTION_OK) {
      ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
	"PgSQL Error: %s", PQerrorMessage(ret) ) ;
      apr_reslist_release(pgasp->dbpool, ret) ;
      return NULL ;
    }
  }
  if (pgasp->nkeep < (acquired_cnt = apr_reslist_acquired_count	( pgasp->dbpool	))) {
    ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, "mod_pgasp: %d connections in the %s pool acquired (%d,%d,%d)",
		 acquired_cnt, pgasp->key, pgasp->nmin, pgasp->nkeep, pgasp->nmax
		 ) ;
  }
  return ret ;
}
Beispiel #3
0
static void * APR_THREAD_FUNC resource_consuming_thread(apr_thread_t *thd,
                                                        void *data)
{
    apr_status_t rv;
    my_thread_info_t *thread_info = data;
    apr_reslist_t *rl = thread_info->reslist;
    int i;

    for (i = 0; i < CONSUMER_ITERATIONS; i++) {
        my_resource_t *res;
        rv = apr_reslist_acquire(rl, (void**)&res);
        if (rv != APR_SUCCESS) {
            fprintf(stderr, "Failed to retrieve resource from reslist\n");
            apr_thread_exit(thd, rv);
            return NULL;
        }
        printf("  [tid:%d,iter:%d] using resource id:%d\n", thread_info->tid,
               i, res->id);
        apr_sleep(thread_info->work_delay_sleep);
        rv = apr_reslist_release(rl, res);
        if (rv != APR_SUCCESS) {
            fprintf(stderr, "Failed to return resource to reslist\n");
            apr_thread_exit(thd, rv);
            return NULL;
        }
    }

    return APR_SUCCESS;
}
Beispiel #4
0
int ml_reslist_acquire(lua_State*L)
{
  request_rec* r = CHECK_REQUEST_OBJECT(1);
  size_t l;
  const char* o = luaL_checklstring(L, 2, &l);
  struct dir_config *d = ap_get_module_config(r->per_dir_config, &luaex_module);
  apr_reslist_t *reslist = apr_hash_get(d->resource, o, l);
  void *resource;

  apr_status_t status = apr_reslist_acquire(reslist, &resource);
  if (status || resource == NULL)
  {
    lua_pushnil(L);
    lua_pushnumber(L, status);
    return 2;
  }
  *(void**)lua_newuserdata(L, sizeof(void*)) = resource;
  luaL_getmetatable(L, o);
  if (lua_istable(L, -1))
  {
    lua_getfield(L, -1, "__gc");
    if (lua_isfunction(L, -1))
    {
      lua_pushnil(L);
      lua_setfield(L, -3, "__gc");
    }
    lua_pop(L, 1);
  }
  lua_setmetatable(L, -2);
  return 1;
}
Beispiel #5
0
/**
 * Get redis context on redis pool
 */
static redisContext* pool_open(server_rec* s) {
	redisContext *ctx = NULL;
	redis_cfg *config = (redis_cfg*) ap_get_module_config(s->module_config, &apachelog_module);
	if (apr_reslist_acquire(config->redis_pool, (void**) &ctx) != APR_SUCCESS) {
		ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "[APACHELOG][GET REDIS CONTEXT FAIL]");
	}
	return ctx;
}
Beispiel #6
0
static void test_shrinking(abts_case *tc, apr_reslist_t *rl)
{
    apr_status_t rv;
    my_resource_t *resources[RESLIST_HMAX];
    my_resource_t *res;
    void *vp;
    int i;
    int sleep_time = RESLIST_TTL / RESLIST_HMAX;

    /* deplete all possible resources from the resource list */
    for (i = 0; i < RESLIST_HMAX; i++) {
        rv = apr_reslist_acquire(rl, (void**)&resources[i]);
        ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
    }

    /* Free all resources above RESLIST_SMAX - 1 */
    for (i = RESLIST_SMAX - 1; i < RESLIST_HMAX; i++) {
        rv = apr_reslist_release(rl, resources[i]);
        ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
    }

    for (i = 0; i < RESLIST_HMAX; i++) {
        rv = apr_reslist_acquire(rl, &vp);
        ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
        res = vp;
        apr_sleep(sleep_time);
        rv = apr_reslist_release(rl, res);
        ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
    }
    apr_sleep(sleep_time);

    /*
     * Now free the remaining elements. This should trigger the shrinking of
     * the list
     */
    for (i = 0; i < RESLIST_SMAX - 1; i++) {
        rv = apr_reslist_release(rl, resources[i]);
        ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
    }
}
Beispiel #7
0
static libcouchbase_t* _couchbase_get_connection(mapcache_context *ctx, mapcache_tile *tile)
{
   apr_status_t rv;
   libcouchbase_t *instance;
   mapcache_cache_couchbase *cache = (mapcache_cache_couchbase*)tile->tileset->cache;
   
   rv = apr_reslist_acquire(cache->connection_pool, (void **)&instance);
   if(rv != APR_SUCCESS) {
      ctx->set_error(ctx, 500, "failed to aquire connection to couchbase backend: %s", ctx->get_error_message(ctx));
      return NULL;
   }

   return instance;
}
Beispiel #8
0
static struct mc_mapobj* _get_mapboj(mapcache_context *ctx, mapcache_map *map) {
   apr_status_t rv;
   mapcache_source_mapserver *src = (mapcache_source_mapserver*) map->tileset->source;
   struct mc_mapobj *mcmap;
   apr_reslist_t *mapobjs = NULL;
   if(!mapobj_container || NULL == (mapobjs = apr_hash_get(mapobj_container,src->source.name,APR_HASH_KEY_STRING))) {
#ifdef APR_HAS_THREADS
      if(ctx->threadlock)
         apr_thread_mutex_lock((apr_thread_mutex_t*)ctx->threadlock);
#endif
      if(!mapobj_container) {
         mapobj_container = apr_hash_make(ctx->process_pool);
      }
      mapobjs = apr_hash_get(mapobj_container,src->source.name,APR_HASH_KEY_STRING);
      if(!mapobjs) {
         apr_status_t rv;
         rv = apr_reslist_create(&mapobjs,
                 0 /* min */,
                 1 /* soft max */,
                 30 /* hard max */,
                 6 * 1000000 /*6 seconds, ttl*/,
                 _ms_get_mapobj, /* resource constructor */
                 _ms_free_mapobj, /* resource destructor */
                 src, ctx->process_pool);
         if (rv != APR_SUCCESS) {
            ctx->set_error(ctx, 500, "failed to create mapobj connection pool for cache %s", src->source.name);
#ifdef APR_HAS_THREADS
            if(ctx->threadlock)
               apr_thread_mutex_unlock((apr_thread_mutex_t*)ctx->threadlock);
#endif
            return NULL;
         }
         apr_hash_set(mapobj_container,src->source.name,APR_HASH_KEY_STRING,mapobjs);
      }
      assert(mapobjs);
#ifdef APR_HAS_THREADS
      if(ctx->threadlock)
         apr_thread_mutex_unlock((apr_thread_mutex_t*)ctx->threadlock);
#endif
   }
   rv = apr_reslist_acquire(mapobjs, (void **) &mcmap);
   if (rv != APR_SUCCESS) {
      ctx->set_error(ctx, 500, "failed to aquire mappObj instance: %s", mcmap->error);
      return NULL;
   }
   return mcmap;
}
Beispiel #9
0
static struct bdb_env* _bdb_get_conn(mapcache_context *ctx, mapcache_tile* tile, int readonly) {
   apr_status_t rv;
   mapcache_cache_bdb *cache = (mapcache_cache_bdb*)tile->tileset->cache;
   struct bdb_env *benv;
   apr_reslist_t *pool;
   if(readonly) 
      pool = cache->ro_connection_pool;
   else
      pool = cache->rw_connection_pool;
   rv = apr_reslist_acquire(pool, (void **)&benv);
   if(rv != APR_SUCCESS) {
      ctx->set_error(ctx,500,"failed to aquire connection to bdb backend: %s", cache->ctx->get_error_message(cache->ctx));
      cache->ctx->clear_errors(cache->ctx);
      return NULL;
   }
   benv->readonly = readonly;
   return benv;
}
Beispiel #10
0
static void * APR_THREAD_FUNC resource_consuming_thread(apr_thread_t *thd,
                                                        void *data)
{
    int i;
    apr_uint32_t chance;
    void *vp;
    apr_status_t rv;
    my_resource_t *res;
    my_thread_info_t *thread_info = data;
    apr_reslist_t *rl = thread_info->reslist;

#if APR_HAS_RANDOM
    apr_generate_random_bytes((void*)&chance, sizeof(chance));
#else
    chance = (apr_uint32_t)(apr_time_now() % APR_TIME_C(4294967291));
#endif

    for (i = 0; i < CONSUMER_ITERATIONS; i++) {
        rv = apr_reslist_acquire(rl, &vp);
        ABTS_INT_EQUAL(thread_info->tc, APR_SUCCESS, rv);
        res = vp;
        apr_sleep(thread_info->work_delay_sleep);

        /* simulate a 5% chance of the resource being bad */
        chance = lgc(chance);
        if ( chance < PERCENT95th ) {
            rv = apr_reslist_release(rl, res);
            ABTS_INT_EQUAL(thread_info->tc, APR_SUCCESS, rv);
        } else {
            rv = apr_reslist_invalidate(rl, res);
            ABTS_INT_EQUAL(thread_info->tc, APR_SUCCESS, rv);
        }
    }

    return APR_SUCCESS;
}
Beispiel #11
0
static struct sqlite_conn* _sqlite_get_conn(mapcache_context *ctx, mapcache_tile* tile, int readonly) {
  apr_status_t rv;
  mapcache_cache_sqlite *cache = (mapcache_cache_sqlite*) tile->tileset->cache;
  struct sqlite_conn *conn = NULL;
  apr_reslist_t *pool = NULL;
  apr_hash_t *pool_container;
  if (readonly) {
    pool_container = ro_connection_pools;
  } else {
    pool_container = rw_connection_pools;
  }
  if(!pool_container || NULL == (pool = apr_hash_get(pool_container,cache->cache.name, APR_HASH_KEY_STRING)) ) {
#ifdef APR_HAS_THREADS
    if(ctx->threadlock)
      apr_thread_mutex_lock((apr_thread_mutex_t*)ctx->threadlock);
#endif
    if(!ro_connection_pools) {
      ro_connection_pools = apr_hash_make(ctx->process_pool);
      rw_connection_pools = apr_hash_make(ctx->process_pool);
    }

    /* probably doesn't exist, unless the previous mutex locked us, so we check */
    pool = apr_hash_get(ro_connection_pools,cache->cache.name, APR_HASH_KEY_STRING);
    if(!pool) {
      /* there where no existing connection pools, create them*/
      rv = apr_reslist_create(&pool,
                              0 /* min */,
                              10 /* soft max */,
                              200 /* hard max */,
                              60*1000000 /*60 seconds, ttl*/,
                              _sqlite_reslist_get_ro_connection, /* resource constructor */
                              _sqlite_reslist_free_connection, /* resource destructor */
                              cache, ctx->process_pool);
      if(rv != APR_SUCCESS) {
        ctx->set_error(ctx,500,"failed to create bdb ro connection pool");
#ifdef APR_HAS_THREADS
        if(ctx->threadlock)
          apr_thread_mutex_unlock((apr_thread_mutex_t*)ctx->threadlock);
#endif
        return NULL;
      }
      apr_hash_set(ro_connection_pools,cache->cache.name,APR_HASH_KEY_STRING,pool);
      rv = apr_reslist_create(&pool,
                              0 /* min */,
                              1 /* soft max */,
                              1 /* hard max */,
                              60*1000000 /*60 seconds, ttl*/,
                              _sqlite_reslist_get_rw_connection, /* resource constructor */
                              _sqlite_reslist_free_connection, /* resource destructor */
                              cache, ctx->process_pool);
      if(rv != APR_SUCCESS) {
        ctx->set_error(ctx,500,"failed to create bdb rw connection pool");
#ifdef APR_HAS_THREADS
        if(ctx->threadlock)
          apr_thread_mutex_unlock((apr_thread_mutex_t*)ctx->threadlock);
#endif
        return NULL;
      }
      apr_hash_set(rw_connection_pools,cache->cache.name,APR_HASH_KEY_STRING,pool);
    }
#ifdef APR_HAS_THREADS
    if(ctx->threadlock)
      apr_thread_mutex_unlock((apr_thread_mutex_t*)ctx->threadlock);
#endif
    if(readonly)
      pool = apr_hash_get(ro_connection_pools,cache->cache.name, APR_HASH_KEY_STRING);
    else
      pool = apr_hash_get(rw_connection_pools,cache->cache.name, APR_HASH_KEY_STRING);
    assert(pool);
  }
  rv = apr_reslist_acquire(pool, (void **) &conn);
  if (rv != APR_SUCCESS) {
    ctx->set_error(ctx, 500, "failed to aquire connection to sqlite backend: %s", (conn && conn->errmsg)?conn->errmsg:"unknown error");
    return NULL;
  }
  return conn;
}
Beispiel #12
0
/*
 * This function gets a connection back either by connecting it, or reuse one.
 */
apr_status_t jxr_conn_open(jaxer_worker* aw, jaxer_connection **pac, request_rec *r)
{
	apr_status_t rv = APR_SUCCESS;
	
	*pac = 0;

	compat_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, "mod_jaxer: entered jxr_conn_open for worker %s", aw->name);

	if (!aw->ac_cache)
	{
		// Create the resource first.  Grab the mutex
#if APR_HAS_THREADS
		rv = apr_thread_mutex_lock(aw->mutex);
		if (rv != APR_SUCCESS)
		{
			compat_log_rerror(APLOG_MARK, APLOG_CRIT, rv, r, "mod_jaxer: Failed to acquire thread mutex for jaxerworker %s", aw->name);
			return rv;
		}
#endif

		// Make sure it is indeed uncreated
		if (!aw->ac_cache)
		{
			compat_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, "mod_jaxer: jxr_conn_open: creating the connection pool for worker %s", aw->name);
			rv = jxr_conn_setup(aw);
		}

		// Before we do anything else, release the mutex.
#if APR_HAS_THREADS
		if (apr_thread_mutex_unlock(aw->mutex) != APR_SUCCESS)
		{
			compat_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, "mod_jaxer: Failed to release thread mutex for jaxerworker %s", aw->name);
		}
#endif

		if (rv != APR_SUCCESS)
		{
			compat_log_rerror(APLOG_MARK, APLOG_CRIT, rv, r, "mod_jaxer: jxr_conn_setup failed for jaxerworker %s", aw->name);
			return rv;
		}
		compat_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, "mod_jaxer: jxr_conn_open: created the connection pool for worker %s", aw->name);

	}

	// At this point, we have a cache
	compat_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, "mod_jaxer: jxr_conn_open: acquiring a connection for worker %s", aw->name);

	rv = apr_reslist_acquire(aw->ac_cache, (void **)pac);
	if (rv != APR_SUCCESS)
	{
		compat_log_rerror(APLOG_MARK, APLOG_CRIT, rv, r, "mod_jaxer: Failed to acquire connection from pool for jaxerworker %s", aw->name);
		return rv;
	}

	compat_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, "mod_jaxer: jxr_conn_open: acquired a connection (%d) for worker %s", (*pac)->sock, aw->name);

	// Setup additional parameters
	(*pac)->request = r;
	(*pac)->has_error = 0;
	(*pac)->last_active_time = apr_time_now();
	
	compat_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, "mod_jaxer: jxr_conn_open: checking connection (%d) for worker %s", (*pac)->sock, aw->name);

	// Make sure it is connected
	if((rv = jxr_send_begin_request_messsage(*pac, 0)) != APR_SUCCESS &&
			((rv = jxr_connect_and_begin_request(*pac)) != APR_SUCCESS))
	{
		compat_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r, "mod_jaxer: reuse connection or reconnect failed");
		apr_reslist_invalidate(aw->ac_cache, *pac);
		*pac = 0;

		return rv;
	}

	compat_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, "mod_jaxer: jxr_conn_open: acquiredconnection (%d) successfully for worker %s", (*pac)->sock, aw->name);

	return rv;

}
Beispiel #13
0
/**
 * Function used to create a lua_State instance bound into the web
 * server in the appropriate scope.
 */
lua_State *ap_lua_get_lua_state(apr_pool_t *lifecycle_pool,
                                               ap_lua_vm_spec *spec, request_rec* r)
{
    lua_State *L = NULL;
    ap_lua_finfo *cache_info = NULL;
    int tryCache = 0;
    
    if (spec->scope == AP_LUA_SCOPE_SERVER) {
        char *hash;
        apr_reslist_t* reslist = NULL;
        ap_lua_server_spec* sspec = NULL;
        hash = apr_psprintf(r->pool, "reslist:%s", spec->file);
#if APR_HAS_THREADS
        apr_thread_mutex_lock(ap_lua_mutex);
#endif
        if (apr_pool_userdata_get((void **)&reslist, hash,
                                  r->server->process->pool) == APR_SUCCESS) {
            if (reslist != NULL) {
                if (apr_reslist_acquire(reslist, (void**) &sspec) == APR_SUCCESS) {
                    L = sspec->L;
                    cache_info = sspec->finfo;
                }
            }
        }
        if (L == NULL) {
            ap_lua_vm_spec* server_spec = copy_vm_spec(r->server->process->pool, spec);
            if (
                    apr_reslist_create(&reslist, spec->vm_min, spec->vm_max, spec->vm_max, 0, 
                                (apr_reslist_constructor) server_vm_construct, 
                                (apr_reslist_destructor) server_cleanup_lua, 
                                server_spec, r->server->process->pool)
                    == APR_SUCCESS && reslist != NULL) {
                apr_pool_userdata_set(reslist, hash, NULL,
                                            r->server->process->pool);
                if (apr_reslist_acquire(reslist, (void**) &sspec) == APR_SUCCESS) {
                    L = sspec->L;
                    cache_info = sspec->finfo;
                }
                else {
                    return NULL;
                }
            }
        }
#if APR_HAS_THREADS
        apr_thread_mutex_unlock(ap_lua_mutex);
#endif
    }
    else {
        if (apr_pool_userdata_get((void **)&L, spec->file,
                              lifecycle_pool) != APR_SUCCESS) {
            L = NULL;
        }
    }
    if (L == NULL) {
        ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool, APLOGNO(01483)
                        "creating lua_State with file %s", spec->file);
        /* not available, so create */

        if (!vm_construct(&L, spec, lifecycle_pool)) {
            AP_DEBUG_ASSERT(L != NULL);
            apr_pool_userdata_set(L, spec->file, cleanup_lua, lifecycle_pool);
        }
    }

    if (spec->codecache == AP_LUA_CACHE_FOREVER || (spec->bytecode && spec->bytecode_len > 0)) {
        tryCache = 1;
    }
    else {
        char* mkey;
        if (spec->scope != AP_LUA_SCOPE_SERVER) {
            mkey = apr_psprintf(r->pool, "ap_lua_modified:%s", spec->file);
            apr_pool_userdata_get((void **)&cache_info, mkey, lifecycle_pool);
            if (cache_info == NULL) {
                cache_info = apr_pcalloc(lifecycle_pool, sizeof(ap_lua_finfo));
                apr_pool_userdata_set((void*) cache_info, mkey, NULL, lifecycle_pool);
            }
        }
        if (spec->codecache == AP_LUA_CACHE_STAT) {
            apr_finfo_t lua_finfo;
            apr_stat(&lua_finfo, spec->file, APR_FINFO_MTIME|APR_FINFO_SIZE, lifecycle_pool);

            /* On first visit, modified will be zero, but that's fine - The file is 
            loaded in the vm_construct function.
            */
            if ((cache_info->modified == lua_finfo.mtime && cache_info->size == lua_finfo.size)
                    || cache_info->modified == 0) {
                tryCache = 1;
            }
            cache_info->modified = lua_finfo.mtime;
            cache_info->size = lua_finfo.size;
        }
        else if (spec->codecache == AP_LUA_CACHE_NEVER) {
            if (cache_info->runs == 0)
                tryCache = 1;
        }
        cache_info->runs++;
    }
    if (tryCache == 0 && spec->scope != AP_LUA_SCOPE_ONCE) {
        int rc;
        ap_log_perror(APLOG_MARK, APLOG_DEBUG, 0, lifecycle_pool, APLOGNO(02332)
            "(re)loading lua file %s", spec->file);
        rc = luaL_loadfile(L, spec->file);
        if (rc != 0) {
            ap_log_perror(APLOG_MARK, APLOG_ERR, 0, lifecycle_pool, APLOGNO(02333)
                          "Error loading %s: %s", spec->file,
                          rc == LUA_ERRMEM ? "memory allocation error"
                                           : lua_tostring(L, 0));
            return 0;
        }
        lua_pcall(L, 0, LUA_MULTRET, 0);
    }

    return L;
}
Beispiel #14
0
static ftpd_chroot_status_t ftpd_dbi_map_chroot(const request_rec *r,
        const char **ret_chroot,
        const char **ret_initroot)
{
    ftpd_chroot_status_t ARV = FTPD_CHROOT_USER_NOT_FOUND;
    ftpd_dbi_config *conf;
    const char *query;
    const char *chroot;
    ftpd_dbi_rest *dbi_res;
    dbi_result result;
    ftpd_dbi_dconfig *dconf = ap_get_module_config(r->per_dir_config,
                              &ftpd_dbi_module);


    conf = apr_hash_get(ftpd_dbi_config_hash, dconf->id, APR_HASH_KEY_STRING);
    if (conf == NULL) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                      "[mod_ftpd_dbi.c] - Server Config for \"%s\" was not found",
                      dconf->id);
        return FTPD_CHROOT_FAIL;
    }

    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                  "[mod_ftpd_dbi.c] Attempting to Acquire DBI Connection");
    apr_reslist_acquire(conf->pool, (void **) &dbi_res);

    /* make the query to get the user's password */
    if (conf->rec.isactive_field) {
        if (conf->rec.chroot_query == NULL) {
            query =
                "SELECT &{ChrootField} FROM &{Table} WHERE &{UsernameField}=&{GivenUsername} AND &{IsActiveField}!=0 LIMIT 0,1";
        }
        else {
            query = conf->rec.chroot_query;
        }
    }
    else {
        if (conf->rec.chroot_query == NULL) {
            query =
                "SELECT &{ChrootField} FROM &{Table} WHERE &{UsernameField}=&{GivenUsername} LIMIT 0,1";
        }
        else {
            query = conf->rec.chroot_query;
        }
    }
    /* perform the query */

    if ((query =
                populate_querystring(r, query, conf, dconf, dbi_res, r->user))
            && safe_dbi_query(dbi_res, &result, r, query) == 0) {
        /* store the query result */
        if (dbi_result_next_row(result)
                && dbi_result_get_numrows(result) == 1) {

            chroot =
                dbi_result_get_string_copy(result, conf->rec.chroot_field);
            if ((chroot == NULL) || (strcmp(chroot, "ERROR") == 0)) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                              "[mod_ftpd_dbi.c] - libdbi returned an error when retrieving the chroot.");
                ARV = FTPD_CHROOT_FAIL;
            }
            else {
                // XXXX: Do more checks of the chroot here!
                *ret_chroot = apr_pstrdup(r->pool, chroot);
                ARV = FTPD_CHROOT_USER_FOUND;
            }
        }
        else {
            if (dbi_result_get_numrows(result) == 0) {
                ARV = FTPD_CHROOT_USER_NOT_FOUND;
            }
            else {
                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                              "[mod_ftpd_dbi.c] %lu row(s) was not returned by dbi_result_get_numrows(result)",
                              (unsigned long) dbi_result_get_numrows(result));
                ARV = FTPD_CHROOT_FAIL;
            }
        }
        dbi_result_free(result);
    }
    else {
        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
                      "[mod_ftpd_dbi.c] Query Failed!");
        ARV = FTPD_CHROOT_FAIL;
    }

    safe_dbi_rel_server(conf->pool, dbi_res, r);
    return ARV;
}