|
|
b5595b |
# ./pullrev.sh 1872790
|
|
|
b5595b |
|
|
|
b5595b |
http://svn.apache.org/viewvc?view=revision&revision=1872790
|
|
|
b5595b |
|
|
|
b5595b |
- Adjusted to remove (pointless-for-RHEL) additions of #if APR_HAS_THREADS.
|
|
|
b5595b |
- merged a previous change to connection_destructor in mod_proxy_balancer.c
|
|
|
b5595b |
- s/hostname_ex/hostname since 2.4.6 doesn't have hostname_ex
|
|
|
b5595b |
|
|
|
b5595b |
--- httpd-2.4.6/modules/proxy/mod_proxy_balancer.c.r1872790
|
|
|
b5595b |
+++ httpd-2.4.6/modules/proxy/mod_proxy_balancer.c
|
|
|
b5595b |
@@ -1229,12 +1229,23 @@
|
|
|
b5595b |
bsel->wupdated = bsel->s->wupdated = nworker->s->updated = apr_time_now();
|
|
|
b5595b |
/* by default, all new workers are disabled */
|
|
|
b5595b |
ap_proxy_set_wstatus('D', 1, nworker);
|
|
|
b5595b |
+ } else {
|
|
|
b5595b |
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10163)
|
|
|
b5595b |
+ "%s: failed to add worker %s",
|
|
|
b5595b |
+ bsel->s->name, val);
|
|
|
b5595b |
+ PROXY_GLOBAL_UNLOCK(bsel);
|
|
|
b5595b |
+ return HTTP_BAD_REQUEST;
|
|
|
b5595b |
}
|
|
|
b5595b |
if ((rv = PROXY_GLOBAL_UNLOCK(bsel)) != APR_SUCCESS) {
|
|
|
b5595b |
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01203)
|
|
|
b5595b |
"%s: Unlock failed for adding worker",
|
|
|
b5595b |
bsel->s->name);
|
|
|
b5595b |
}
|
|
|
b5595b |
+ } else {
|
|
|
b5595b |
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10164)
|
|
|
b5595b |
+ "%s: failed to add worker %s",
|
|
|
b5595b |
+ bsel->s->name, val);
|
|
|
b5595b |
+ return HTTP_BAD_REQUEST;
|
|
|
b5595b |
}
|
|
|
b5595b |
|
|
|
b5595b |
}
|
|
|
b5595b |
--- httpd-2.4.6/modules/proxy/mod_proxy_ftp.c.r1872790
|
|
|
b5595b |
+++ httpd-2.4.6/modules/proxy/mod_proxy_ftp.c
|
|
|
b5595b |
@@ -972,7 +972,7 @@
|
|
|
b5595b |
conn_rec *origin, *data = NULL;
|
|
|
b5595b |
apr_status_t err = APR_SUCCESS;
|
|
|
b5595b |
apr_status_t uerr = APR_SUCCESS;
|
|
|
b5595b |
- apr_bucket_brigade *bb = apr_brigade_create(p, c->bucket_alloc);
|
|
|
b5595b |
+ apr_bucket_brigade *bb;
|
|
|
b5595b |
char *buf, *connectname;
|
|
|
b5595b |
apr_port_t connectport;
|
|
|
b5595b |
char buffer[MAX_STRING_LEN];
|
|
|
b5595b |
@@ -1112,13 +1112,15 @@
|
|
|
b5595b |
|
|
|
b5595b |
if (worker->s->is_address_reusable) {
|
|
|
b5595b |
if (!worker->cp->addr) {
|
|
|
b5595b |
+#if APR_HAS_THREADS
|
|
|
b5595b |
if ((err = PROXY_THREAD_LOCK(worker->balancer)) != APR_SUCCESS) {
|
|
|
b5595b |
ap_log_rerror(APLOG_MARK, APLOG_ERR, err, r, APLOGNO(01037) "lock");
|
|
|
b5595b |
return HTTP_INTERNAL_SERVER_ERROR;
|
|
|
b5595b |
}
|
|
|
b5595b |
+#endif
|
|
|
b5595b |
}
|
|
|
b5595b |
- connect_addr = worker->cp->addr;
|
|
|
b5595b |
- address_pool = worker->cp->pool;
|
|
|
b5595b |
+ connect_addr = AP_VOLATILIZE_T(apr_sockaddr_t *, worker->cp->addr);
|
|
|
b5595b |
+ address_pool = worker->cp->dns_pool;
|
|
|
b5595b |
}
|
|
|
b5595b |
else
|
|
|
b5595b |
address_pool = r->pool;
|
|
|
b5595b |
@@ -1206,6 +1208,7 @@
|
|
|
b5595b |
* correct directory...
|
|
|
b5595b |
*/
|
|
|
b5595b |
|
|
|
b5595b |
+ bb = apr_brigade_create(p, c->bucket_alloc);
|
|
|
b5595b |
|
|
|
b5595b |
/* possible results: */
|
|
|
b5595b |
/* 120 Service ready in nnn minutes. */
|
|
|
b5595b |
--- httpd-2.4.6/modules/proxy/mod_proxy.h.r1872790
|
|
|
b5595b |
+++ httpd-2.4.6/modules/proxy/mod_proxy.h
|
|
|
b5595b |
@@ -260,12 +260,15 @@
|
|
|
b5595b |
|
|
|
b5595b |
/* Connection pool */
|
|
|
b5595b |
struct proxy_conn_pool {
|
|
|
b5595b |
- apr_pool_t *pool; /* The pool used in constructor and destructor calls */
|
|
|
b5595b |
- apr_sockaddr_t *addr; /* Preparsed remote address info */
|
|
|
b5595b |
- apr_reslist_t *res; /* Connection resource list */
|
|
|
b5595b |
- proxy_conn_rec *conn; /* Single connection for prefork mpm */
|
|
|
b5595b |
+ apr_pool_t *pool; /* The pool used in constructor and destructor calls */
|
|
|
b5595b |
+ apr_sockaddr_t *addr; /* Preparsed remote address info */
|
|
|
b5595b |
+ apr_reslist_t *res; /* Connection resource list */
|
|
|
b5595b |
+ proxy_conn_rec *conn; /* Single connection for prefork mpm */
|
|
|
b5595b |
+ apr_pool_t *dns_pool; /* The pool used for worker scoped DNS resolutions */
|
|
|
b5595b |
};
|
|
|
b5595b |
|
|
|
b5595b |
+#define AP_VOLATILIZE_T(T, x) (*(T volatile *)&(x))
|
|
|
b5595b |
+
|
|
|
b5595b |
/* Keep below in sync with proxy_util.c! */
|
|
|
b5595b |
/* worker status bits */
|
|
|
b5595b |
#define PROXY_WORKER_INITIALIZED 0x0001
|
|
|
b5595b |
--- httpd-2.4.6/modules/proxy/proxy_util.c.r1872790
|
|
|
b5595b |
+++ httpd-2.4.6/modules/proxy/proxy_util.c
|
|
|
b5595b |
@@ -1318,16 +1324,14 @@
|
|
|
b5595b |
|
|
|
b5595b |
static apr_status_t conn_pool_cleanup(void *theworker)
|
|
|
b5595b |
{
|
|
|
b5595b |
- proxy_worker *worker = (proxy_worker *)theworker;
|
|
|
b5595b |
- if (worker->cp->res) {
|
|
|
b5595b |
- worker->cp->pool = NULL;
|
|
|
b5595b |
- }
|
|
|
b5595b |
+ ((proxy_worker *)theworker)->cp = NULL;
|
|
|
b5595b |
return APR_SUCCESS;
|
|
|
b5595b |
}
|
|
|
b5595b |
|
|
|
b5595b |
static void init_conn_pool(apr_pool_t *p, proxy_worker *worker)
|
|
|
b5595b |
{
|
|
|
b5595b |
apr_pool_t *pool;
|
|
|
b5595b |
+ apr_pool_t *dns_pool;
|
|
|
b5595b |
proxy_conn_pool *cp;
|
|
|
b5595b |
|
|
|
b5595b |
/*
|
|
|
b5595b |
@@ -1339,11 +1343,20 @@
|
|
|
b5595b |
apr_pool_create(&pool, p);
|
|
|
b5595b |
apr_pool_tag(pool, "proxy_worker_cp");
|
|
|
b5595b |
/*
|
|
|
b5595b |
+ * Create a subpool of the connection pool for worker
|
|
|
b5595b |
+ * scoped DNS resolutions. This is needed to avoid race
|
|
|
b5595b |
+ * conditions in using the connection pool by multiple
|
|
|
b5595b |
+ * threads during ramp up.
|
|
|
b5595b |
+ */
|
|
|
b5595b |
+ apr_pool_create(&dns_pool, pool);
|
|
|
b5595b |
+ apr_pool_tag(dns_pool, "proxy_worker_dns");
|
|
|
b5595b |
+ /*
|
|
|
b5595b |
* Alloc from the same pool as worker.
|
|
|
b5595b |
* proxy_conn_pool is permanently attached to the worker.
|
|
|
b5595b |
*/
|
|
|
b5595b |
cp = (proxy_conn_pool *)apr_pcalloc(p, sizeof(proxy_conn_pool));
|
|
|
b5595b |
cp->pool = pool;
|
|
|
b5595b |
+ cp->dns_pool = dns_pool;
|
|
|
b5595b |
worker->cp = cp;
|
|
|
b5595b |
}
|
|
|
b5595b |
|
|
|
b5595b |
@@ -1359,14 +1372,6 @@
|
|
|
b5595b |
proxy_conn_rec *conn = (proxy_conn_rec *)theconn;
|
|
|
b5595b |
proxy_worker *worker = conn->worker;
|
|
|
b5595b |
|
|
|
b5595b |
- /*
|
|
|
b5595b |
- * If the connection pool is NULL the worker
|
|
|
b5595b |
- * cleanup has been run. Just return.
|
|
|
b5595b |
- */
|
|
|
b5595b |
- if (!worker->cp) {
|
|
|
b5595b |
- return APR_SUCCESS;
|
|
|
b5595b |
- }
|
|
|
b5595b |
-
|
|
|
b5595b |
if (conn->r) {
|
|
|
b5595b |
apr_pool_destroy(conn->r->pool);
|
|
|
b5595b |
conn->r = NULL;
|
|
|
b5595b |
@@ -1487,10 +1492,11 @@
|
|
|
b5595b |
static apr_status_t connection_destructor(void *resource, void *params,
|
|
|
b5595b |
apr_pool_t *pool)
|
|
|
b5595b |
{
|
|
|
b5595b |
- proxy_conn_rec *conn = (proxy_conn_rec *)resource;
|
|
|
b5595b |
+ proxy_worker *worker = params;
|
|
|
b5595b |
|
|
|
b5595b |
/* Destroy the pool only if not called from reslist_destroy */
|
|
|
b5595b |
- if (conn->worker->cp->pool) {
|
|
|
b5595b |
+ if (worker->cp) {
|
|
|
b5595b |
+ proxy_conn_rec *conn = resource;
|
|
|
b5595b |
apr_pool_destroy(conn->pool);
|
|
|
b5595b |
}
|
|
|
b5595b |
|
|
|
b5595b |
@@ -1880,67 +1886,73 @@
|
|
|
b5595b |
ap_proxy_worker_name(p, worker));
|
|
|
b5595b |
}
|
|
|
b5595b |
else {
|
|
|
b5595b |
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00927)
|
|
|
b5595b |
- "initializing worker %s local",
|
|
|
b5595b |
- ap_proxy_worker_name(p, worker));
|
|
|
b5595b |
apr_global_mutex_lock(proxy_mutex);
|
|
|
b5595b |
- /* Now init local worker data */
|
|
|
b5595b |
- if (worker->tmutex == NULL) {
|
|
|
b5595b |
- rv = apr_thread_mutex_create(&(worker->tmutex), APR_THREAD_MUTEX_DEFAULT, p);
|
|
|
b5595b |
- if (rv != APR_SUCCESS) {
|
|
|
b5595b |
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00928)
|
|
|
b5595b |
- "can not create worker thread mutex");
|
|
|
b5595b |
- apr_global_mutex_unlock(proxy_mutex);
|
|
|
b5595b |
- return rv;
|
|
|
b5595b |
+ /* Check again after we got the lock if we are still uninitialized */
|
|
|
b5595b |
+ if (!(AP_VOLATILIZE_T(unsigned int, worker->local_status) & PROXY_WORKER_INITIALIZED)) {
|
|
|
b5595b |
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00927)
|
|
|
b5595b |
+ "initializing worker %s local",
|
|
|
b5595b |
+ ap_proxy_worker_name(p, worker));
|
|
|
b5595b |
+ /* Now init local worker data */
|
|
|
b5595b |
+#if APR_HAS_THREADS
|
|
|
b5595b |
+ if (worker->tmutex == NULL) {
|
|
|
b5595b |
+ rv = apr_thread_mutex_create(&(worker->tmutex), APR_THREAD_MUTEX_DEFAULT, p);
|
|
|
b5595b |
+ if (rv != APR_SUCCESS) {
|
|
|
b5595b |
+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00928)
|
|
|
b5595b |
+ "can not create worker thread mutex");
|
|
|
b5595b |
+ apr_global_mutex_unlock(proxy_mutex);
|
|
|
b5595b |
+ return rv;
|
|
|
b5595b |
+ }
|
|
|
b5595b |
}
|
|
|
b5595b |
- }
|
|
|
b5595b |
- if (worker->cp == NULL)
|
|
|
b5595b |
- init_conn_pool(p, worker);
|
|
|
b5595b |
- if (worker->cp == NULL) {
|
|
|
b5595b |
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00929)
|
|
|
b5595b |
- "can not create connection pool");
|
|
|
b5595b |
- apr_global_mutex_unlock(proxy_mutex);
|
|
|
b5595b |
- return APR_EGENERAL;
|
|
|
b5595b |
- }
|
|
|
b5595b |
-
|
|
|
b5595b |
- if (worker->s->hmax) {
|
|
|
b5595b |
- rv = apr_reslist_create(&(worker->cp->res),
|
|
|
b5595b |
- worker->s->min, worker->s->smax,
|
|
|
b5595b |
- worker->s->hmax, worker->s->ttl,
|
|
|
b5595b |
- connection_constructor, connection_destructor,
|
|
|
b5595b |
- worker, worker->cp->pool);
|
|
|
b5595b |
-
|
|
|
b5595b |
- apr_pool_cleanup_register(worker->cp->pool, (void *)worker,
|
|
|
b5595b |
- conn_pool_cleanup,
|
|
|
b5595b |
- apr_pool_cleanup_null);
|
|
|
b5595b |
-
|
|
|
b5595b |
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00930)
|
|
|
b5595b |
- "initialized pool in child %" APR_PID_T_FMT " for (%s) min=%d max=%d smax=%d",
|
|
|
b5595b |
- getpid(), worker->s->hostname, worker->s->min,
|
|
|
b5595b |
- worker->s->hmax, worker->s->smax);
|
|
|
b5595b |
-
|
|
|
b5595b |
- /* Set the acquire timeout */
|
|
|
b5595b |
- if (rv == APR_SUCCESS && worker->s->acquire_set) {
|
|
|
b5595b |
- apr_reslist_timeout_set(worker->cp->res, worker->s->acquire);
|
|
|
b5595b |
+#endif
|
|
|
b5595b |
+ if (worker->cp == NULL)
|
|
|
b5595b |
+ init_conn_pool(p, worker);
|
|
|
b5595b |
+ if (worker->cp == NULL) {
|
|
|
b5595b |
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00929)
|
|
|
b5595b |
+ "can not create connection pool");
|
|
|
b5595b |
+ apr_global_mutex_unlock(proxy_mutex);
|
|
|
b5595b |
+ return APR_EGENERAL;
|
|
|
b5595b |
}
|
|
|
b5595b |
|
|
|
b5595b |
- }
|
|
|
b5595b |
- else {
|
|
|
b5595b |
- void *conn;
|
|
|
b5595b |
+ if (worker->s->hmax) {
|
|
|
b5595b |
+ rv = apr_reslist_create(&(worker->cp->res),
|
|
|
b5595b |
+ worker->s->min, worker->s->smax,
|
|
|
b5595b |
+ worker->s->hmax, worker->s->ttl,
|
|
|
b5595b |
+ connection_constructor, connection_destructor,
|
|
|
b5595b |
+ worker, worker->cp->pool);
|
|
|
b5595b |
+
|
|
|
b5595b |
+ apr_pool_pre_cleanup_register(worker->cp->pool, worker,
|
|
|
b5595b |
+ conn_pool_cleanup);
|
|
|
b5595b |
+
|
|
|
b5595b |
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00930)
|
|
|
b5595b |
+ "initialized pool in child %" APR_PID_T_FMT " for (%s) min=%d max=%d smax=%d",
|
|
|
b5595b |
+ getpid(), worker->s->hostname, worker->s->min,
|
|
|
b5595b |
+ worker->s->hmax, worker->s->smax);
|
|
|
b5595b |
+
|
|
|
b5595b |
+ /* Set the acquire timeout */
|
|
|
b5595b |
+ if (rv == APR_SUCCESS && worker->s->acquire_set) {
|
|
|
b5595b |
+ apr_reslist_timeout_set(worker->cp->res, worker->s->acquire);
|
|
|
b5595b |
+ }
|
|
|
b5595b |
|
|
|
b5595b |
- rv = connection_constructor(&conn, worker, worker->cp->pool);
|
|
|
b5595b |
- worker->cp->conn = conn;
|
|
|
b5595b |
+ }
|
|
|
b5595b |
+ else {
|
|
|
b5595b |
+ void *conn;
|
|
|
b5595b |
+
|
|
|
b5595b |
+ rv = connection_constructor(&conn, worker, worker->cp->pool);
|
|
|
b5595b |
+ worker->cp->conn = conn;
|
|
|
b5595b |
|
|
|
b5595b |
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00931)
|
|
|
b5595b |
- "initialized single connection worker in child %" APR_PID_T_FMT " for (%s)",
|
|
|
b5595b |
- getpid(), worker->s->hostname);
|
|
|
b5595b |
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s, APLOGNO(00931)
|
|
|
b5595b |
+ "initialized single connection worker in child %" APR_PID_T_FMT " for (%s)",
|
|
|
b5595b |
+ getpid(), worker->s->hostname);
|
|
|
b5595b |
+ }
|
|
|
b5595b |
+ if (rv == APR_SUCCESS) {
|
|
|
b5595b |
+ worker->local_status |= (PROXY_WORKER_INITIALIZED);
|
|
|
b5595b |
+ }
|
|
|
b5595b |
}
|
|
|
b5595b |
apr_global_mutex_unlock(proxy_mutex);
|
|
|
b5595b |
|
|
|
b5595b |
}
|
|
|
b5595b |
if (rv == APR_SUCCESS) {
|
|
|
b5595b |
worker->s->status |= (PROXY_WORKER_INITIALIZED);
|
|
|
b5595b |
- worker->local_status |= (PROXY_WORKER_INITIALIZED);
|
|
|
b5595b |
}
|
|
|
b5595b |
return rv;
|
|
|
b5595b |
}
|
|
|
b5595b |
@@ -2183,13 +2195,13 @@
|
|
|
b5595b |
else {
|
|
|
b5595b |
/* create the new connection if the previous was destroyed */
|
|
|
b5595b |
if (!worker->cp->conn) {
|
|
|
b5595b |
- connection_constructor((void **)conn, worker, worker->cp->pool);
|
|
|
b5595b |
+ rv = connection_constructor((void **)conn, worker, worker->cp->pool);
|
|
|
b5595b |
}
|
|
|
b5595b |
else {
|
|
|
b5595b |
*conn = worker->cp->conn;
|
|
|
b5595b |
worker->cp->conn = NULL;
|
|
|
b5595b |
+ rv = APR_SUCCESS;
|
|
|
b5595b |
}
|
|
|
b5595b |
- rv = APR_SUCCESS;
|
|
|
b5595b |
}
|
|
|
b5595b |
|
|
|
b5595b |
if (rv != APR_SUCCESS) {
|
|
|
b5595b |
@@ -2374,15 +2386,25 @@
|
|
|
b5595b |
}
|
|
|
b5595b |
|
|
|
b5595b |
/*
|
|
|
b5595b |
- * Worker can have the single constant backend adress.
|
|
|
b5595b |
- * The single DNS lookup is used once per worker.
|
|
|
b5595b |
- * If dynamic change is needed then set the addr to NULL
|
|
|
b5595b |
- * inside dynamic config to force the lookup.
|
|
|
b5595b |
+ * Recheck addr after we got the lock. This may have changed
|
|
|
b5595b |
+ * while waiting for the lock.
|
|
|
b5595b |
*/
|
|
|
b5595b |
- err = apr_sockaddr_info_get(&(worker->cp->addr),
|
|
|
b5595b |
- conn->hostname, APR_UNSPEC,
|
|
|
b5595b |
- conn->port, 0,
|
|
|
b5595b |
- worker->cp->pool);
|
|
|
b5595b |
+ if (!AP_VOLATILIZE_T(apr_sockaddr_t *, worker->cp->addr)) {
|
|
|
b5595b |
+
|
|
|
b5595b |
+ apr_sockaddr_t *addr;
|
|
|
b5595b |
+
|
|
|
b5595b |
+ /*
|
|
|
b5595b |
+ * Worker can have the single constant backend address.
|
|
|
b5595b |
+ * The single DNS lookup is used once per worker.
|
|
|
b5595b |
+ * If dynamic change is needed then set the addr to NULL
|
|
|
b5595b |
+ * inside dynamic config to force the lookup.
|
|
|
b5595b |
+ */
|
|
|
b5595b |
+ err = apr_sockaddr_info_get(&addr,
|
|
|
b5595b |
+ conn->hostname, APR_UNSPEC,
|
|
|
b5595b |
+ conn->port, 0,
|
|
|
b5595b |
+ worker->cp->dns_pool);
|
|
|
b5595b |
+ worker->cp->addr = addr;
|
|
|
b5595b |
+ }
|
|
|
b5595b |
conn->addr = worker->cp->addr;
|
|
|
b5595b |
if ((uerr = PROXY_THREAD_UNLOCK(worker)) != APR_SUCCESS) {
|
|
|
b5595b |
ap_log_rerror(APLOG_MARK, APLOG_ERR, uerr, r, APLOGNO(00946) "unlock");
|