You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by jf...@apache.org on 2006/07/28 18:34:00 UTC

svn commit: r426604 - in /httpd/httpd/branches/httpd-proxy-scoreboard: modules/proxy/ support/

Author: jfclere
Date: Fri Jul 28 09:33:58 2006
New Revision: 426604

URL: http://svn.apache.org/viewvc?rev=426604&view=rev
Log:
First try to put togother an external health checker for mod_proxy.

Added:
    httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/health_checker_util.c
    httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy_health_checker.c
    httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy_health_checker.h
    httpd/httpd/branches/httpd-proxy-scoreboard/support/proxymonitor.c
Modified:
    httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/config.m4
    httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy.c
    httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy.h
    httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/proxy_util.c
    httpd/httpd/branches/httpd-proxy-scoreboard/support/Makefile.in

Modified: httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/config.m4
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/config.m4?rev=426604&r1=426603&r2=426604&view=diff
==============================================================================
--- httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/config.m4 (original)
+++ httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/config.m4 Fri Jul 28 09:33:58 2006
@@ -17,6 +17,7 @@
 proxy_ftp_objs="mod_proxy_ftp.lo"
 proxy_http_objs="mod_proxy_http.lo"
 proxy_fcgi_objs="mod_proxy_fcgi.lo"
+proxy_health_checker_objs="mod_proxy_health_checker.lo health_checker_util.lo"
 proxy_ajp_objs="mod_proxy_ajp.lo ajp_header.lo ajp_link.lo ajp_msg.lo"
 proxy_balancer_objs="mod_proxy_balancer.lo"
 
@@ -28,6 +29,7 @@
     proxy_ftp_objs="$proxy_ftp_objs mod_proxy.la"
     proxy_http_objs="$proxy_http_objs mod_proxy.la"
     proxy_fcgi_objs="$proxy_fcgi_objs mod_proxy.la"
+    proxy_health_checker_objs="$proxy_health_checker_objs mod_proxy.la"
     proxy_ajp_objs="$proxy_ajp_objs mod_proxy.la"
     proxy_balancer_objs="$proxy_balancer_objs mod_proxy.la"
     ;;
@@ -37,6 +39,7 @@
 APACHE_MODULE(proxy_ftp, Apache proxy FTP module, $proxy_ftp_objs, , $proxy_mods_enable)
 APACHE_MODULE(proxy_http, Apache proxy HTTP module, $proxy_http_objs, , $proxy_mods_enable)
 APACHE_MODULE(proxy_fcgi, Apache proxy FastCGI module, $proxy_fcgi_objs, , $proxy_mods_enable)
+APACHE_MODULE(proxy_health_checker, Apache proxy health checker module, $proxy_health_checker_objs, , $proxy_mods_enable)
 APACHE_MODULE(proxy_ajp, Apache proxy AJP module, $proxy_ajp_objs, , $proxy_mods_enable)
 APACHE_MODULE(proxy_balancer, Apache proxy BALANCER module, $proxy_balancer_objs, , $proxy_mods_enable)
 

Added: httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/health_checker_util.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/health_checker_util.c?rev=426604&view=auto
==============================================================================
--- httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/health_checker_util.c (added)
+++ httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/health_checker_util.c Fri Jul 28 09:33:58 2006
@@ -0,0 +1,347 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/*
+ * Internal routine of the default httpd part of a health checker
+ */
+#define CORE_PRIVATE
+
+#include "apr.h"
+#include "apr_pools.h"
+
+#include "httpd.h"
+#include "http_config.h"
+#include "http_log.h"
+
+#include "mod_proxy.h"
+#include "slotmem.h"
+#include "mod_proxy_health_checker.h"
+
+#include "ajp.h"
+
+static const slotmem_storage_method *checkstorage = NULL;
+static ap_slotmem_t *myscore=NULL;
+
+/* Check a AJP back-end server.
+ * Send a cing message and wait for the answer
+ */
+static apr_status_t pingc_backend(apr_socket_t *sock, apr_pool_t *pool)
+{
+    ajp_msg_t *msg;
+    apr_status_t rc;
+    apr_byte_t result;
+
+    rc = ajp_msg_create(pool,  &msg);
+    if (rc != APR_SUCCESS)
+        return rc;
+    ajp_msg_serialize_cping(msg);
+    rc = ajp_ilink_send(sock, msg);
+    if (rc != APR_SUCCESS)
+        return rc;
+    ajp_msg_reuse(msg);
+    rc = ajp_ilink_receive(sock, msg);
+    if (rc != APR_SUCCESS)
+        return rc;
+    rc = ajp_msg_peek_uint8(msg, &result);
+    if (rc != APR_SUCCESS)
+        return rc;
+    return APR_SUCCESS;
+}
+
+/*
+ * Build a connection to the backend server and check it
+ */
+static apr_status_t test_backend(char *scheme, char *hostname, int port, apr_pool_t *pool)
+{
+    apr_socket_t *newsock;
+    apr_sockaddr_t *epsv_addr;
+    apr_status_t rv;
+
+    if (!port) {
+        if (strcmp(scheme, "ajp") == 0)
+            port = 8009;
+        else if (strcmp(scheme, "http") == 0)
+            port = 80;
+        else
+            port = 443;
+    }
+    rv = apr_socket_create(&newsock, APR_INET, SOCK_STREAM, APR_PROTO_TCP, pool);
+    if (rv != APR_SUCCESS) {
+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
+                    "apr_socket_create failed");
+        return rv;
+    }
+    rv = apr_sockaddr_info_get(&epsv_addr, hostname, APR_INET, port, 0, pool);
+    if (rv != APR_SUCCESS) {
+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
+                     "apr_sockaddr_info_get failed");
+        apr_socket_close(newsock);
+        return rv;
+    }
+
+    rv = apr_socket_timeout_set(newsock, 10);
+    if (rv != APR_SUCCESS) {
+        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL,
+                    "apr_socket_timeout_set");
+        apr_socket_close(newsock);
+        return rv;
+    }
+    rv = apr_socket_connect(newsock, epsv_addr);
+    if (rv != APR_SUCCESS) {
+        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL,
+                    "apr_socket_connect failed");
+        apr_socket_close(newsock);
+        return rv;
+    }
+
+    /* XXX: Something is needed for http/https */
+    if (strcmp(scheme, "ajp") == 0) {
+        /* The connection is etablished send a ping and read the answer */
+        apr_socket_timeout_set(newsock, 10000);
+        rv = pingc_backend(newsock, pool);  
+        if (rv != APR_SUCCESS) {
+            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL,
+                        "pingc_backend failed");
+            apr_socket_close(newsock);
+            return rv;
+        }
+    }
+    apr_socket_close(newsock);
+    return APR_SUCCESS;
+}
+
+/* read the size of the entry: to create the shared area */
+static int getentrysize()
+{
+    return sizeof(struct proxy_worker_conf);
+}
+/* copy the worker information in the shared area so the health-checker can extract the part it need */
+static apr_status_t add_entry(proxy_worker *worker, char *balancer_name, int id)
+{
+    struct proxy_worker_conf *workerconf = NULL;
+    apr_status_t rv;
+
+    if (myscore == NULL)
+        return APR_ENOSHMAVAIL;
+    rv = checkstorage->ap_slotmem_mem(myscore, worker->id, (void *) &workerconf);
+    if (rv != APR_SUCCESS) {
+        return rv;
+    }
+
+    if (balancer_name)
+        strcpy(workerconf->balancer_name, balancer_name);
+    workerconf->id = worker->id;
+    workerconf->retry = worker->retry;
+    workerconf->lbfactor = worker->lbfactor;
+    if (worker->name)
+        strcpy(workerconf->name, worker->name);
+    if (worker->scheme)
+        strcpy(workerconf->scheme, worker->scheme);
+    if (worker->hostname)
+        strcpy(workerconf->hostname, worker->hostname);
+    if (worker->route)
+        strcpy(workerconf->route, worker->route);
+    if (worker->redirect)
+        strcpy(workerconf->redirect, worker->redirect);
+    workerconf->status = worker->status;
+    workerconf->port = worker->port;
+    workerconf->min = worker->min;
+    workerconf->smax = worker->smax;
+    workerconf->hmax = worker->hmax;
+    workerconf->ttl = worker->ttl;
+    workerconf->timeout = worker->timeout;
+    workerconf->acquire = worker->acquire;
+    workerconf->acquire_set = worker->acquire_set;
+    workerconf->recv_buffer_size = worker->recv_buffer_size;
+    workerconf->recv_buffer_size_set = worker->recv_buffer_size_set;
+    workerconf->io_buffer_size = worker->io_buffer_size;
+    workerconf->io_buffer_size_set = worker->io_buffer_size_set;
+    workerconf->keepalive = worker->keepalive;
+    workerconf->keepalive_set = worker->keepalive_set;
+    workerconf->flush_packets = worker->flush_packets;
+    workerconf->flush_wait = worker->flush_wait;
+    workerconf->health = 0;
+    workerconf->used = 1;
+    return APR_SUCCESS;
+}
+/* Remove the entry: TO BE DONE */
+static apr_status_t del_entry(int id)
+{
+    return APR_SUCCESS;
+}
+/* read the health of the entry: for httpd */
+static apr_status_t get_health(int id, int *health)
+{
+    struct proxy_worker_conf *workerconf = NULL;
+    apr_status_t rv;
+
+    if (myscore == NULL)
+        return APR_ENOSHMAVAIL;
+    rv = checkstorage->ap_slotmem_mem(myscore, id, (void *) &workerconf);
+    if (rv != APR_SUCCESS)
+        return rv;
+    *health = workerconf->health;
+    return APR_SUCCESS;
+}
+/* set the health of the entry: for the health-checker */
+static apr_status_t set_health(int id, int value)
+{
+    struct proxy_worker_conf *workerconf = NULL;
+    apr_status_t rv;
+
+    if (myscore == NULL)
+        return APR_ENOSHMAVAIL;
+    rv = checkstorage->ap_slotmem_mem(myscore, id, (void *) &workerconf);
+    if (rv != APR_SUCCESS)
+        return rv;
+    workerconf->health = value;
+    workerconf->time_checked = apr_time_now();
+    return APR_SUCCESS;
+}
+/* read the entry stored in the shared area and build the corresponding worker structure */
+static apr_status_t get_entry(int id, proxy_worker **worker, char **balancer_name, apr_pool_t *pool)
+{
+    struct proxy_worker_conf *workerconf = NULL;
+    apr_status_t rv;
+
+    if (myscore == NULL)
+        return APR_ENOSHMAVAIL;
+    rv = checkstorage->ap_slotmem_mem(myscore, id, (void *) &workerconf);
+    if (rv != APR_SUCCESS)
+        return rv;
+
+    /* allocate the data */
+    *worker = apr_pcalloc(pool, sizeof(proxy_worker));
+    if (workerconf->balancer_name)
+        *balancer_name = apr_pcalloc(pool, strlen(workerconf->balancer_name));
+    else
+        *balancer_name = NULL;
+
+    /* The httpstatus is handle by httpd don't touch it here */
+    (* worker)->id = workerconf->id;
+    // XXX: what to do (* worker)->s = workerconf;
+    (* worker)->retry = workerconf->retry;
+    (* worker)->lbfactor = workerconf->lbfactor;
+    if (workerconf->name)
+        strcpy((* worker)->name, workerconf->name);
+    if (workerconf->scheme)
+        strcpy((* worker)->scheme, workerconf->scheme);
+    if (workerconf->hostname)
+        strcpy((* worker)->hostname, workerconf->hostname);
+    if (workerconf->route)
+        strcpy((* worker)->route, workerconf->route);
+    if (workerconf->redirect)
+        strcpy((* worker)->redirect, workerconf->redirect);
+    (* worker)->status = workerconf->status;
+    (* worker)->port = workerconf->port;
+    (* worker)->min = workerconf->min;
+    (* worker)->smax = workerconf->smax;
+    (* worker)->hmax = workerconf->hmax;
+    (* worker)->ttl = workerconf->ttl;
+    (* worker)->timeout = workerconf->timeout;
+    (* worker)->acquire = workerconf->acquire;
+    (* worker)->acquire_set = workerconf->acquire_set;
+    (* worker)->recv_buffer_size = workerconf->recv_buffer_size;
+    (* worker)->recv_buffer_size_set = workerconf->recv_buffer_size_set;
+    (* worker)->io_buffer_size = workerconf->io_buffer_size;
+    (* worker)->io_buffer_size_set = workerconf->io_buffer_size_set;
+    (* worker)->keepalive = workerconf->keepalive;
+    (* worker)->keepalive_set = workerconf->keepalive_set;
+    (* worker)->flush_packets = workerconf->flush_packets;
+    (* worker)->flush_wait = workerconf->flush_wait;
+    return APR_SUCCESS;
+}
+/* read the entry stored in the shared area */
+static apr_status_t get_entryconf(int id, struct proxy_worker_conf **workerconf, char **balancer_name, apr_pool_t *pool)
+{
+    apr_status_t rv;
+
+    if (myscore == NULL)
+        return APR_ENOSHMAVAIL;
+    rv = checkstorage->ap_slotmem_mem(myscore, id, workerconf);
+    if (rv != APR_SUCCESS)
+        return rv;
+    *balancer_name = (*workerconf)->balancer_name;
+    return APR_SUCCESS;
+}
+
+/* Test the corresponding back-end server */
+static apr_status_t check_entryhealth(int id, apr_pool_t *pool) {
+    apr_status_t rv;
+    struct proxy_worker_conf *workerconf;
+
+    if (myscore == NULL)
+        return APR_ENOSHMAVAIL;
+    rv = checkstorage->ap_slotmem_mem(myscore, id, &workerconf);
+    if (rv != APR_SUCCESS)
+        return rv;
+    /* If the error is not initialized to the worker to be removed keep it */
+    if (workerconf->used != VALID)
+        return APR_SUCCESS;
+    rv = test_backend(workerconf->scheme, workerconf->hostname, workerconf->port, pool);
+    if (rv != APR_SUCCESS)
+        workerconf->health = HEALTH_NO;
+    else
+        workerconf->health = HEALTH_OK;
+    workerconf->time_checked = apr_time_now();
+    return rv;
+}
+
+/* check the connection pool used by the worker */
+static apr_status_t check_poolhealth(proxy_worker *worker, int id, apr_pool_t *pool)
+{
+    /* XXX: The code is missing */
+    return APR_SUCCESS;
+}
+
+/* The stuff we provide */
+static const health_worker_method worker_storage = {
+    &getentrysize,
+    &add_entry,
+    &del_entry,
+    &get_health,
+    &set_health,
+    &get_entry,
+    &get_entryconf,
+    &check_entryhealth
+};
+
+/* make the module usuable from outside */
+health_worker_method *health_checker_get_storage()
+{
+    return(&worker_storage);
+}
+
+/* handle the slotmem storage */
+void health_checker_init_slotmem_storage(slotmem_storage_method * storage)
+{
+    checkstorage = storage;
+}
+slotmem_storage_method * health_checker_get_slotmem_storage()
+{
+    return(checkstorage);
+}
+
+/* handle the slotmen itself */
+void health_checker_init_slotmem(ap_slotmem_t *score)
+{
+     myscore = score;
+}
+ap_slotmem_t *health_checker_get_slotmem()
+{
+    return(myscore);
+}

Modified: httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy.c?rev=426604&r1=426603&r2=426604&view=diff
==============================================================================
--- httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy.c (original)
+++ httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy.c Fri Jul 28 09:33:58 2006
@@ -1151,11 +1151,13 @@
         }
     }
     else {
+        int adding = 0;
         proxy_worker *worker = ap_proxy_get_worker(cmd->temp_pool, conf, r);
         if (!worker) {
             const char *err = ap_proxy_add_worker(&worker, cmd->pool, conf, r);
             if (err)
                 return apr_pstrcat(cmd->temp_pool, "ProxyPass ", err, NULL);
+            adding = 1;
         } else {
             ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server,
                          "worker %s already used by another worker", worker->name);
@@ -1168,6 +1170,10 @@
             if (err)
                 return apr_pstrcat(cmd->temp_pool, "ProxyPass ", err, NULL);
         }
+       
+        /* XXX: ProxyPass is not a good name look for Location? */
+        if (adding)
+            proxy_checkstorage_add_entry(worker, "ProxyPass");
     }
     return NULL;
 }
@@ -1516,7 +1522,8 @@
     apr_table_t *params = apr_table_make(cmd->pool, 5);
     const apr_array_header_t *arr;
     const apr_table_entry_t *elts;
-    int i;
+    int i; 
+    int adding = 0; 
 
     if (cmd->path)
         path = apr_pstrdup(cmd->pool, cmd->path);
@@ -1552,6 +1559,7 @@
         const char *err;
         if ((err = ap_proxy_add_worker(&worker, cmd->pool, conf, name)) != NULL)
             return apr_pstrcat(cmd->temp_pool, "BalancerMember ", err, NULL);
+        adding = 1;
     } else {
             ap_log_error(APLOG_MARK, APLOG_WARNING, 0, cmd->server,
                          "worker %s already used by another worker", worker->name);
@@ -1577,6 +1585,9 @@
     }
     /* Add the worker to the load balancer */
     ap_proxy_add_worker_to_balancer(cmd->pool, balancer, worker);
+    /* XXX: Holy cow: The worker can belong to more that one balancer! */
+    if (adding)
+        proxy_checkstorage_add_entry(worker, balancer->name);
     return NULL;
 }
 

Modified: httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy.h?rev=426604&r1=426603&r2=426604&view=diff
==============================================================================
--- httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy.h (original)
+++ httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy.h Fri Jul 28 09:33:58 2006
@@ -127,6 +127,7 @@
 typedef struct proxy_worker    proxy_worker;
 typedef struct proxy_conn_pool proxy_conn_pool;
 typedef struct proxy_balancer_method proxy_balancer_method;
+typedef struct health_worker_method health_worker_method;
 
 typedef struct {
     apr_array_header_t *proxies;
@@ -723,6 +724,7 @@
 #endif
 
 #define PROXY_LBMETHOD "proxylbmethod"
+#define PROXY_CKMETHOD "proxyckmethod"
 
 /* The number of dynamic workers that can be added when reconfiguring.
  * If this limit is reached you must stop and restart the server.

Added: httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy_health_checker.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy_health_checker.c?rev=426604&view=auto
==============================================================================
--- httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy_health_checker.c (added)
+++ httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy_health_checker.c Fri Jul 28 09:33:58 2006
@@ -0,0 +1,73 @@
+/*
+ * Default httpd part of the health checker
+ */
+#define CORE_PRIVATE
+
+#include "apr.h"
+#include "apr_pools.h"
+
+#include "httpd.h"
+#include "http_config.h"
+#include "http_log.h"
+
+#include "mod_proxy.h"
+#include "slotmem.h"
+#include "mod_proxy_health_checker.h"
+
+static int healthck_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
+                              apr_pool_t *ptemp)
+{
+    slotmem_storage_method *checkstorage;
+    health_worker_method *worker_storage = health_checker_get_storage();
+    ap_slotmem_t *myscore;
+    
+    checkstorage = ap_lookup_provider(SLOTMEM_STORAGE, "shared", "0");
+    if (checkstorage) {
+        health_checker_init_slotmem_storage(checkstorage);
+    }
+    if (checkstorage && worker_storage) {
+        checkstorage->ap_slotmem_create(&myscore, "proxy/checker", worker_storage->getentrysize(), 128, pconf);
+        health_checker_init_slotmem(myscore);
+    }
+    return OK;
+}
+
+/* XXX: Was to get ap_proxy_lb_workers()
+static int healthck_post_config(apr_pool_t *pconf, apr_pool_t *plog,
+                                apr_pool_t *ptemp, server_rec *s)
+{
+    slotmem_storage_method *checkstorage = health_checker_get_slotmem_storage();
+    health_worker_method *worker_storage = health_checker_get_storage();
+    ap_slotmem_t *myscore;
+
+    if (checkstorage && worker_storage) {
+        checkstorage->ap_slotmem_create(&myscore, "proxy/checker", worker_storage->getentrysize(), ap_proxy_lb_workers(), pconf);
+        health_checker_init_slotmem(myscore);
+    }
+    return OK;
+
+}
+ */
+
+static void ap_healthstore_register_hook(apr_pool_t *p)
+{
+    static const char * const aszPre[] = { "mod_proxy.c", NULL };
+    static const char * const aszPos[] = { "mod_sharedmem.c", NULL };
+
+    health_worker_method *worker_storage = health_checker_get_storage();
+    ap_register_provider(p, PROXY_CKMETHOD, "default", "0", worker_storage);
+    ap_hook_pre_config(healthck_pre_config, NULL, aszPos, APR_HOOK_MIDDLE);
+    /* XXX: Too late....
+    ap_hook_post_config(healthck_post_config, aszPre, NULL, APR_HOOK_MIDDLE);
+     */
+}
+
+module AP_MODULE_DECLARE_DATA proxy_health_checker_module = {
+    STANDARD20_MODULE_STUFF,
+    NULL,       /* create per-directory config structure */
+    NULL,       /* merge per-directory config structures */
+    NULL,       /* create per-server config structure */
+    NULL,       /* merge per-server config structures */
+    NULL,       /* command apr_table_t */
+    ap_healthstore_register_hook /* register hooks */
+};

Added: httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy_health_checker.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy_health_checker.h?rev=426604&view=auto
==============================================================================
--- httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy_health_checker.h (added)
+++ httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy_health_checker.h Fri Jul 28 09:33:58 2006
@@ -0,0 +1,98 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* health checker routines for proxies */
+#define HEALTH_OK      1
+#define HEALTH_NO      2
+#define HEALTH_UNKNOWN 0
+
+/* Validity of the entry */
+#define VALID          1
+#define REMOVED        2
+#define UNINITIALIZED  0
+
+typedef struct proxy_worker_conf proxy_worker_conf;
+
+/* allow health check method on workers in a non httpd process */
+struct health_worker_method {
+    /* read the size of the entry: to create the shared area */
+    int (* getentrysize)();
+    /* copy the worker information in the shared area so the health-checker can extract the part it need */
+    apr_status_t (*add_entry)(proxy_worker *worker, char *balancer_name, int id);
+    /* XXX : Remove the entry */
+    apr_status_t (*del_entry)(int id);
+    /* read the health of the entry: for httpd */
+    apr_status_t (*get_health)(int id, int *health);
+    /* set the health of the entry: for the health-checker */
+    apr_status_t (*set_health)(int id, int value);
+    /* read the entry stored in the shared area */
+    apr_status_t (*get_entry)(proxy_worker **worker, char **balancer_name, apr_pool_t *pool);
+    /* read the conf part. */
+    apr_status_t (*get_entryconf)(int id, proxy_worker_conf **worker, char **balancer_name, apr_pool_t *pool);
+    /* check the back-end server health */
+    apr_status_t (*check_entryhealth)(int id, apr_pool_t *pool);
+    /* check the pool of sockets (are they still connected) */
+    apr_status_t (*check_poolhealth)(int id, proxy_worker *worker, apr_pool_t *pool);
+};
+
+/* To store the configuration of the balancers and workers.
+ */
+struct proxy_balancer_conf {
+    char name[32];
+    char sticky[32];
+    int sticky_force;
+    apr_interval_time_t timeout;
+    int max_attempts;
+    char max_attempts_set;
+    char lbmethod_name[32];
+};
+
+struct proxy_worker_conf {
+    proxy_worker_stat httpstatus;      /* httpd private */
+    char balancer_name[32];
+    int             id;            /* scoreboard id */
+    apr_interval_time_t retry;     /* retry interval */
+    int             lbfactor;      /* initial load balancing factor */
+    char            name[64];
+    char            scheme[6];     /* scheme to use ajp|http|https */
+    char            hostname[64];  /* remote backend address */
+    char            route[128];    /* balancing route */
+    char            redirect[128]; /* temporary balancing redirection route */
+    int             status;        /* temporary worker status */
+    apr_port_t      port;
+    int             min;           /* Desired minimum number of available connections */
+    int             smax;          /* Soft maximum on the total number of connections */
+    int             hmax;          /* Hard maximum on the total number of connections */
+    apr_interval_time_t ttl;       /* maximum amount of time in seconds a connection
+                                    * may be available while exceeding the soft limit */
+    apr_interval_time_t timeout;   /* connection timeout */
+    char                timeout_set;
+    apr_interval_time_t acquire; /* acquire timeout when the maximum number of connections is exceeded */
+    char                acquire_set;
+    apr_size_t          recv_buffer_size;
+    char                recv_buffer_size_set;
+    apr_size_t          io_buffer_size;
+    char                io_buffer_size_set;
+    char                keepalive;
+    char                keepalive_set;
+    int                 is_address_reusable;
+    int                 flush_packets;
+    int                 flush_wait;  /* poll wait time in microseconds if flush_auto */
+    int                 health;
+    int                 used;  /* 1 : valid entry 2 : remove 0 : free slot */
+    apr_time_t          time_checked;
+};
+

Modified: httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/proxy_util.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/proxy_util.c?rev=426604&r1=426603&r2=426604&view=diff
==============================================================================
--- httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/proxy_util.c (original)
+++ httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/proxy_util.c Fri Jul 28 09:33:58 2006
@@ -17,6 +17,7 @@
 /* Utility routines for Apache proxy */
 #include "mod_proxy.h"
 #include "slotmem.h"
+#include "mod_proxy_health_checker.h"
 #include "ap_mpm.h"
 #include "apr_version.h"
 
@@ -43,6 +44,8 @@
                                    OK, DECLINED)
 /* Storage for the comarea */
 static const slotmem_storage_method *storage = NULL;
+/* Health checker handler */
+static const health_worker_method *checkstorage = NULL;
 
 /* already called in the knowledge that the characters are hex digits */
 PROXY_DECLARE(int) ap_proxy_hex2c(const char *x)
@@ -1639,6 +1642,13 @@
               worker->name);
         return;
     }
+
+    /* Health checker handler: to create the correct size. */
+    if (checkstorage) {
+        item_size = checkstorage->getentrysize();
+    }
+
+    /* Use storage provider when a storage is existing */
     if (storage) {
 
         rv = storage->ap_slotmem_create(&myscore, "proxy/comarea", item_size, ap_proxy_lb_workers(), conf->pool);
@@ -2224,6 +2234,8 @@
 {
     ap_slotmem_t *myscore;
     apr_size_t item_size = sizeof(proxy_worker_stat);
+    if (checkstorage)
+        item_size = checkstorage->getentrysize();
     if (storage)
         storage->ap_slotmem_create(&myscore, "proxy/comarea", item_size, ap_proxy_lb_workers(), pconf);
 }
@@ -2235,4 +2247,13 @@
         storage = ap_lookup_provider(SLOTMEM_STORAGE, "score", "0");
     if (!storage)
         storage = ap_lookup_provider(SLOTMEM_STORAGE, "plain", "0");
+    checkstorage = ap_lookup_provider(PROXY_CKMETHOD, "default", "0");
+}
+
+/* Store the worker information in the comarea */
+PROXY_DECLARE(void) proxy_checkstorage_add_entry(proxy_worker *worker, char *balancer_name)
+{
+    if (checkstorage) {
+        checkstorage->add_entry(worker, balancer_name, worker->id);
+    }
 }

Modified: httpd/httpd/branches/httpd-proxy-scoreboard/support/Makefile.in
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/httpd-proxy-scoreboard/support/Makefile.in?rev=426604&r1=426603&r2=426604&view=diff
==============================================================================
--- httpd/httpd/branches/httpd-proxy-scoreboard/support/Makefile.in (original)
+++ httpd/httpd/branches/httpd-proxy-scoreboard/support/Makefile.in Fri Jul 28 09:33:58 2006
@@ -3,7 +3,7 @@
 
 CLEAN_TARGETS = suexec
 
-PROGRAMS = htpasswd htdigest rotatelogs logresolve ab checkgid htdbm htcacheclean httxt2dbm fcgistarter
+PROGRAMS = htpasswd htdigest rotatelogs logresolve ab checkgid htdbm htcacheclean httxt2dbm fcgistarter proxymonitor
 TARGETS  = $(PROGRAMS)
 
 PROGRAM_LDADD        = $(UTIL_LDFLAGS) $(PROGRAM_DEPENDENCIES) $(EXTRA_LIBS) $(AP_LIBS)
@@ -73,3 +73,17 @@
 fcgistarter_OBJECTS = fcgistarter.lo
 fcgistarter: $(fcgistarter_OBJECTS)
 	$(LINK) $(fcgistarter_LTFLAGS) $(fcgistarter_OBJECTS) $(PROGRAM_LDADD)
+
+#proxymonitor_OBJECTS = proxymonitor.lo ../modules/proxy/ajp_msg.lo ../modules/proxy/ajp_link.lo ../modules/proxy/health_checker_util.lo ../modules/mem/sharedmem_util.lo
+proxymonitor_OBJECTS = proxymonitor.lo ajp_msg.lo ajp_link.lo health_checker_util.lo sharedmem_util.lo
+ajp_msg.c: ../modules/proxy/ajp_msg.c
+	cp ../modules/proxy/ajp_msg.c .
+ajp_link.c: ../modules/proxy/ajp_link.c
+	cp ../modules/proxy/ajp_link.c .
+health_checker_util.c: ../modules/proxy/health_checker_util.c
+	cp ../modules/proxy/health_checker_util.c .
+sharedmem_util.c: ../modules/mem/sharedmem_util.c
+	cp ../modules/mem/sharedmem_util.c .
+
+proxymonitor: $(proxymonitor_OBJECTS)
+	$(LINK) $(proxymonitor_LTFLAGS) $(proxymonitor_OBJECTS) $(PROGRAM_LDADD)

Added: httpd/httpd/branches/httpd-proxy-scoreboard/support/proxymonitor.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/httpd-proxy-scoreboard/support/proxymonitor.c?rev=426604&view=auto
==============================================================================
--- httpd/httpd/branches/httpd-proxy-scoreboard/support/proxymonitor.c (added)
+++ httpd/httpd/branches/httpd-proxy-scoreboard/support/proxymonitor.c Fri Jul 28 09:33:58 2006
@@ -0,0 +1,304 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/*
+ * proxymonitor.c: simple program for monitor proxy back-end server.
+ *
+ */
+
+#include "apr.h"
+#include "apr_lib.h"
+#include "apr_strings.h"
+#include "apr_file_io.h"
+#include "apr_file_info.h"
+#include "apr_pools.h"
+#include "apr_hash.h"
+#include "apr_thread_proc.h"
+#include "apr_signal.h"
+#include "apr_getopt.h"
+#include "apr_ring.h"
+#include "apr_date.h"
+
+#include "mod_proxy.h"
+#include "ajp.h"
+
+#include "mod_proxy_health_checker.h"
+#include "slotmem.h"
+
+#if APR_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if APR_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+static int interrupted; /* flag: true if SIGINT or SIGTERM occurred */
+
+static apr_time_t now;  /* start time of this processing run */
+
+extern int AP_DECLARE_DATA ap_default_loglevel = APLOG_ERR;
+
+static apr_file_t *errfile;   /* stderr file handle */
+static apr_file_t *outfile;   /* stdout file handle */
+
+/* short program name as called */
+static const char *shortname = "proxymonitor";
+
+static const health_worker_method *worker_storage;
+
+char *basedir = NULL;
+
+/* XXX: hack to use a part of the mod_sharedmem and mod_proxy_health_checker */
+static apr_status_t init_healthck(apr_pool_t *pool, int *num)
+{
+    apr_size_t size;
+    apr_status_t rv;
+    slotmem_storage_method *checkstorage;
+    ap_slotmem_t *myscore;
+    
+    sharedmem_initglobalpool(pool);
+    checkstorage = sharedmem_getstorage();
+    rv = checkstorage->ap_slotmem_attach(&myscore, "proxy/checker", &size, num, pool);
+
+    health_checker_init_slotmem_storage(checkstorage);
+    health_checker_init_slotmem(myscore);
+    worker_storage = health_checker_get_storage();
+
+    return rv;
+}
+
+/*
+ * httpd routine to be able to link with the modules.
+ */
+char * ap_server_root_relative(apr_pool_t *p, const char *name)
+{
+    char *fname;
+
+    /* XXX: apr_filepath_merge better ? */
+    if (basedir && name[0] != '/') {
+        fname = apr_pcalloc(p, strlen(basedir)+strlen(name)+1);
+        strcpy(fname, basedir);
+        strcat(fname, "/");
+        strcat(fname, name);
+    } else {
+        fname = apr_pstrdup(p, name);
+    }
+    return fname;
+}
+
+/*
+ * called on SIGINT or SIGTERM
+ */
+static void setterm(int unused)
+{
+    interrupted = 1;
+}
+
+/*
+ * called in out of memory condition
+ */
+static int oom(int unused)
+{
+    static int called = 0;
+
+    /* be careful to call exit() only once */
+    if (!called) {
+        called = 1;
+        exit(1);
+    }
+    return APR_ENOMEM;
+}
+
+/*
+ * usage info
+ */
+#define NL APR_EOL_STR
+static void usage(void)
+{
+    apr_file_printf(errfile,
+    "%s -- program for monitoring proxies of httpd."                         NL
+    "Usage: %s [-n] [-pPATH] [-dINTERVAL] [-rN]"                             NL
+                                                                             NL
+    "Options:"                                                               NL
+    "  -d   Repeat checking every INTERVAL seconds."                         NL
+                                                                             NL
+    "  -r   Repeat checking N times."                                        NL
+                                                                             NL
+    "  -p   Specify PATH where the httpd is running."                        NL,
+
+    shortname,
+    shortname,
+    shortname
+    );
+
+    exit(1);
+}
+#undef NL
+
+/* Quick hack to allow logging */
+AP_DECLARE(void) ap_log_error(const char *file, int line, int level,
+                              apr_status_t status, const server_rec *s,
+                              const char *fmt, ...)
+{
+    va_list args;
+    char scratch[MAX_STRING_LEN];
+
+    va_start(args, fmt);
+    apr_vsnprintf(scratch, MAX_STRING_LEN, fmt, args);
+    apr_file_printf(errfile,"%s\n", scratch);
+    va_end(args);
+}
+
+/*
+ * Reads the configuration from shared memory
+ */
+int process_sharedmem(apr_pool_t *pool, int num)
+{
+    apr_status_t rv;
+    int n;
+    struct proxy_worker_conf *worker;
+    char *balancer_name;
+    int status;
+
+    for (n = 0; n < num; n++) {
+
+        rv = worker_storage->get_entryconf(n, &worker, &balancer_name, pool);
+        if (worker->used == 0 || worker->used  == 2)
+            continue;
+        worker_storage->get_health(n, &status);
+         apr_file_printf(outfile, "balancer %s worker %s: host %s port %d status: %d ", 
+                worker->balancer_name,  worker->name,
+                worker->hostname,  worker->port, status);
+        rv = worker_storage->check_entryhealth(n, pool);
+        if (rv != APR_SUCCESS) {
+            apr_file_printf(outfile, "now: FAILED\n");
+            worker_storage->set_health(n, HEALTH_NO);
+        } else {
+            apr_file_printf(outfile, "now: OK\n");
+            worker_storage->set_health(n, HEALTH_OK);
+        }
+    }
+}
+
+/*
+ * main
+ */
+int main(int argc, const char * const argv[])
+{
+    apr_time_t current, delay;
+    apr_status_t status;
+    apr_pool_t *pool, *instance, *instance_socket;
+    apr_getopt_t *o;
+    int repeat = -1;
+    char opt;
+    const char *arg;
+    char datestring[APR_RFC822_DATE_LEN];
+    int num;
+
+    /* only log errors */
+    // ap_default_loglevel = APLOG_ERR;
+
+    delay = 5 * APR_USEC_PER_SEC;
+
+    if (apr_app_initialize(&argc, &argv, NULL) != APR_SUCCESS) {
+        return 1;
+    }
+    atexit(apr_terminate);
+
+    if (argc) {
+        shortname = apr_filepath_name_get(argv[0]);
+    }
+
+    if (apr_pool_create(&pool, NULL) != APR_SUCCESS) {
+        return 1;
+    }
+    apr_pool_abort_set(oom, pool);
+    apr_file_open_stderr(&errfile, pool);
+    apr_file_open_stdout(&outfile, pool);
+    apr_signal(SIGINT, setterm);
+    apr_signal(SIGTERM, setterm);
+
+    apr_getopt_init(&o, pool, argc, argv);
+
+    while (1) {
+        status = apr_getopt(o, "p:d:r:", &opt, &arg);
+        if (status == APR_EOF) {
+            break;
+        }
+        else if (status != APR_SUCCESS) {
+            usage();
+        }
+        else {
+            switch (opt) {
+            case 'd':
+                delay = apr_atoi64(arg);
+                delay *= APR_USEC_PER_SEC;
+                break;
+
+
+            case 'r':
+                repeat = apr_atoi64(arg);
+                break;
+
+            case 'p':
+                if (basedir) {
+                    usage();
+                }
+                basedir = apr_pstrdup(pool, arg);
+                break;
+            default:
+                usage();
+            } /* switch */
+        } /* else */
+    } /* while */
+    if (basedir == NULL)
+        usage();
+
+    instance_socket = NULL;
+
+    while (repeat && ! interrupted) {
+
+        if (instance_socket == NULL) {
+            apr_pool_create(&instance_socket, pool);
+            init_healthck(instance_socket, &num);
+        }
+
+        apr_pool_create(&instance, instance_socket);
+        apr_sleep(delay);
+        now = apr_time_now();
+        process_sharedmem(instance_socket, num);
+        current = apr_time_now();
+        apr_rfc822_date(datestring, current);
+        apr_file_printf(outfile,"at %s in %d\n", datestring, current-now);
+
+        if (repeat>0)
+            repeat--;
+        apr_pool_destroy(instance);
+        /* If something goes really wrong we should clean all */
+        if (0) {
+            apr_pool_destroy(instance_socket);
+            instance_socket = NULL;
+        }
+    }
+    if (interrupted) {
+        apr_file_printf(errfile, "Monitoring aborted due to user "
+                                 "request." APR_EOL_STR);
+        return 1;
+    }
+
+    return 0;
+}



Re: svn commit: r426604 - in /httpd/httpd/branches/httpd-proxy-scoreboard: modules/proxy/ support/

Posted by Jean-frederic Clere <jf...@gmail.com>.
Ruediger Pluem wrote:

>On 07/28/2006 06:34 PM, jfclere@apache.org wrote:
>
>  
>
>>Added: httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/health_checker_util.c
>>URL: http://svn.apache.org/viewvc/httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/health_checker_util.c?rev=426604&view=auto
>>==============================================================================
>>--- httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/health_checker_util.c (added)
>>+++ httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/health_checker_util.c Fri Jul 28 09:33:58 2006
>>    
>>
>
>  
>
>>+/* read the entry stored in the shared area and build the corresponding worker structure */
>>+static apr_status_t get_entry(int id, proxy_worker **worker, char **balancer_name, apr_pool_t *pool)
>>+{
>>+    struct proxy_worker_conf *workerconf = NULL;
>>+    apr_status_t rv;
>>+
>>+    if (myscore == NULL)
>>+        return APR_ENOSHMAVAIL;
>>+    rv = checkstorage->ap_slotmem_mem(myscore, id, (void *) &workerconf);
>>    
>>
>
>What should be done if we never have added an worker to this id and thus all fields
>in **workerconf are zero? Wouldn't it make sense to set *worker to NULL and return
>an error (something like NOT_INIT)?
>  
>
I like the idea but the only error code I have found for it is APR_EINIT.
Any comments?

Cheers

Jean-Frederic

>Regards
>
>Rüdiger
>
>
>  
>


Re: svn commit: r426604 - in /httpd/httpd/branches/httpd-proxy-scoreboard: modules/proxy/ support/

Posted by Ruediger Pluem <rp...@apache.org>.

On 07/28/2006 06:34 PM, jfclere@apache.org wrote:

> Added: httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/health_checker_util.c
> URL: http://svn.apache.org/viewvc/httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/health_checker_util.c?rev=426604&view=auto
> ==============================================================================
> --- httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/health_checker_util.c (added)
> +++ httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/health_checker_util.c Fri Jul 28 09:33:58 2006

> +/* read the entry stored in the shared area and build the corresponding worker structure */
> +static apr_status_t get_entry(int id, proxy_worker **worker, char **balancer_name, apr_pool_t *pool)
> +{
> +    struct proxy_worker_conf *workerconf = NULL;
> +    apr_status_t rv;
> +
> +    if (myscore == NULL)
> +        return APR_ENOSHMAVAIL;
> +    rv = checkstorage->ap_slotmem_mem(myscore, id, (void *) &workerconf);

What should be done if we never have added an worker to this id and thus all fields
in **workerconf are zero? Wouldn't it make sense to set *worker to NULL and return
an error (something like NOT_INIT)?

Regards

Rüdiger


Re: svn commit: r426604 - in /httpd/httpd/branches/httpd-proxy-scoreboard: modules/proxy/ support/

Posted by Jean-frederic Clere <jf...@gmail.com>.
Jim Jagielski wrote:

> Many compile warnings when compiling with maint-mode:

Fixed. Thanks,

Cheers

Jean-Frederic

>
> mod_proxy.c: In function 'add_pass':
> mod_proxy.c:1176: warning: implicit declaration of function  
> 'proxy_checkstorage_add_entry'
> mod_proxy.c: In function 'proxy_post_config':
> mod_proxy.c:1870: warning: implicit declaration of function  
> 'proxy_create_comarea'
> mod_proxy.c: In function 'proxy_pre_config':
> mod_proxy.c:2014: warning: implicit declaration of function  
> 'proxy_lookup_storage_provider'
>
>
> In file included from proxy_util.c:20:
> mod_proxy_health_checker.h:32: warning: function declaration isn't a  
> prototype
> proxy_util.c:2234: warning: no previous prototype for  
> 'proxy_create_comarea'
> proxy_util.c:2244: warning: function declaration isn't a prototype
> proxy_util.c:2255: warning: no previous prototype for  
> 'proxy_checkstorage_add_entry'
>
> In file included from mod_proxy_health_checker.c:15:
> mod_proxy_health_checker.h:32: warning: function declaration isn't a  
> prototype
> mod_proxy_health_checker.c: In function 'healthck_pre_config':
> mod_proxy_health_checker.c:21: warning: implicit declaration of  
> function 'health_checker_get_storage'
> mod_proxy_health_checker.c:21: warning: initialization makes pointer  
> from integer without a cast
> mod_proxy_health_checker.c:26: warning: implicit declaration of  
> function 'health_checker_init_slotmem_storage'
> mod_proxy_health_checker.c:30: warning: implicit declaration of  
> function 'health_checker_init_slotmem'
> mod_proxy_health_checker.c: In function 'ap_healthstore_register_hook':
> mod_proxy_health_checker.c:57: warning: initialization makes pointer  
> from integer without a cast
> mod_proxy_health_checker.c:54: warning: unused variable 'aszPre'
>
> In file included from health_checker_util.c:32:
> mod_proxy_health_checker.h:32: warning: function declaration isn't a  
> prototype
> health_checker_util.c:129: warning: function declaration isn't a  
> prototype
> health_checker_util.c: In function 'get_entry':
> health_checker_util.c:240: warning: passing argument 1 of 'strcpy'  
> discards qualifiers from pointer target type
> health_checker_util.c:242: warning: passing argument 1 of 'strcpy'  
> discards qualifiers from pointer target type
> health_checker_util.c:244: warning: passing argument 1 of 'strcpy'  
> discards qualifiers from pointer target type
> health_checker_util.c:246: warning: passing argument 1 of 'strcpy'  
> discards qualifiers from pointer target type
> health_checker_util.c:248: warning: passing argument 1 of 'strcpy'  
> discards qualifiers from pointer target type
> health_checker_util.c: In function 'get_entryconf':
> health_checker_util.c:275: warning: passing argument 3 of  
> 'checkstorage->ap_slotmem_mem' from incompatible pointer type
> health_checker_util.c: In function 'check_entryhealth':
> health_checker_util.c:289: warning: passing argument 3 of  
> 'checkstorage->ap_slotmem_mem' from incompatible pointer type
> health_checker_util.c: At top level:
> health_checker_util.c:318: warning: initialization from incompatible  
> pointer type
> health_checker_util.c:325: warning: function declaration isn't a  
> prototype
> health_checker_util.c: In function 'health_checker_get_storage':
> health_checker_util.c:326: warning: return discards qualifiers from  
> pointer target type
> health_checker_util.c: At top level:
> health_checker_util.c:331: warning: no previous prototype for  
> 'health_checker_init_slotmem_storage'
> health_checker_util.c:335: warning: function declaration isn't a  
> prototype
> health_checker_util.c: In function 'health_checker_get_slotmem_storage':
> health_checker_util.c:336: warning: return discards qualifiers from  
> pointer target type
> health_checker_util.c: At top level:
> health_checker_util.c:341: warning: no previous prototype for  
> 'health_checker_init_slotmem'
> health_checker_util.c:345: warning: function declaration isn't a  
> prototype
> health_checker_util.c:306: warning: 'check_poolhealth' defined but  
> not used
>
> sharedmem_util.c:52: warning: no previous prototype for  
> 'cleanup_slotmem'
> sharedmem_util.c: In function 'ap_slotmem_create':
> sharedmem_util.c:139: warning: implicit declaration of function  
> 'apr_pstrdup'
> sharedmem_util.c:139: warning: assignment makes pointer from integer  
> without a cast
> sharedmem_util.c:83: warning: unused variable 'slotmem'
> sharedmem_util.c: In function 'ap_slotmem_attach':
> sharedmem_util.c:192: warning: assignment makes pointer from integer  
> without a cast
> sharedmem_util.c:154: warning: unused variable 'slotmem'
> sharedmem_util.c: At top level:
> sharedmem_util.c:234: warning: function declaration isn't a prototype
> sharedmem_util.c: In function 'sharedmem_getstorage':
> sharedmem_util.c:235: warning: return discards qualifiers from  
> pointer target type
> sharedmem_util.c: At top level:
> sharedmem_util.c:239: warning: no previous prototype for  
> 'sharedmem_initglobalpool'
> sharedmem_util.c:244: warning: no previous prototype for  
> 'sharedmem_initialize_cleanup'
>
>


Re: svn commit: r426604 - in /httpd/httpd/branches/httpd-proxy-scoreboard: modules/proxy/ support/

Posted by Jim Jagielski <ji...@jaguNET.com>.
Many compile warnings when compiling with maint-mode:

mod_proxy.c: In function 'add_pass':
mod_proxy.c:1176: warning: implicit declaration of function  
'proxy_checkstorage_add_entry'
mod_proxy.c: In function 'proxy_post_config':
mod_proxy.c:1870: warning: implicit declaration of function  
'proxy_create_comarea'
mod_proxy.c: In function 'proxy_pre_config':
mod_proxy.c:2014: warning: implicit declaration of function  
'proxy_lookup_storage_provider'


In file included from proxy_util.c:20:
mod_proxy_health_checker.h:32: warning: function declaration isn't a  
prototype
proxy_util.c:2234: warning: no previous prototype for  
'proxy_create_comarea'
proxy_util.c:2244: warning: function declaration isn't a prototype
proxy_util.c:2255: warning: no previous prototype for  
'proxy_checkstorage_add_entry'

In file included from mod_proxy_health_checker.c:15:
mod_proxy_health_checker.h:32: warning: function declaration isn't a  
prototype
mod_proxy_health_checker.c: In function 'healthck_pre_config':
mod_proxy_health_checker.c:21: warning: implicit declaration of  
function 'health_checker_get_storage'
mod_proxy_health_checker.c:21: warning: initialization makes pointer  
from integer without a cast
mod_proxy_health_checker.c:26: warning: implicit declaration of  
function 'health_checker_init_slotmem_storage'
mod_proxy_health_checker.c:30: warning: implicit declaration of  
function 'health_checker_init_slotmem'
mod_proxy_health_checker.c: In function 'ap_healthstore_register_hook':
mod_proxy_health_checker.c:57: warning: initialization makes pointer  
from integer without a cast
mod_proxy_health_checker.c:54: warning: unused variable 'aszPre'

In file included from health_checker_util.c:32:
mod_proxy_health_checker.h:32: warning: function declaration isn't a  
prototype
health_checker_util.c:129: warning: function declaration isn't a  
prototype
health_checker_util.c: In function 'get_entry':
health_checker_util.c:240: warning: passing argument 1 of 'strcpy'  
discards qualifiers from pointer target type
health_checker_util.c:242: warning: passing argument 1 of 'strcpy'  
discards qualifiers from pointer target type
health_checker_util.c:244: warning: passing argument 1 of 'strcpy'  
discards qualifiers from pointer target type
health_checker_util.c:246: warning: passing argument 1 of 'strcpy'  
discards qualifiers from pointer target type
health_checker_util.c:248: warning: passing argument 1 of 'strcpy'  
discards qualifiers from pointer target type
health_checker_util.c: In function 'get_entryconf':
health_checker_util.c:275: warning: passing argument 3 of  
'checkstorage->ap_slotmem_mem' from incompatible pointer type
health_checker_util.c: In function 'check_entryhealth':
health_checker_util.c:289: warning: passing argument 3 of  
'checkstorage->ap_slotmem_mem' from incompatible pointer type
health_checker_util.c: At top level:
health_checker_util.c:318: warning: initialization from incompatible  
pointer type
health_checker_util.c:325: warning: function declaration isn't a  
prototype
health_checker_util.c: In function 'health_checker_get_storage':
health_checker_util.c:326: warning: return discards qualifiers from  
pointer target type
health_checker_util.c: At top level:
health_checker_util.c:331: warning: no previous prototype for  
'health_checker_init_slotmem_storage'
health_checker_util.c:335: warning: function declaration isn't a  
prototype
health_checker_util.c: In function 'health_checker_get_slotmem_storage':
health_checker_util.c:336: warning: return discards qualifiers from  
pointer target type
health_checker_util.c: At top level:
health_checker_util.c:341: warning: no previous prototype for  
'health_checker_init_slotmem'
health_checker_util.c:345: warning: function declaration isn't a  
prototype
health_checker_util.c:306: warning: 'check_poolhealth' defined but  
not used

sharedmem_util.c:52: warning: no previous prototype for  
'cleanup_slotmem'
sharedmem_util.c: In function 'ap_slotmem_create':
sharedmem_util.c:139: warning: implicit declaration of function  
'apr_pstrdup'
sharedmem_util.c:139: warning: assignment makes pointer from integer  
without a cast
sharedmem_util.c:83: warning: unused variable 'slotmem'
sharedmem_util.c: In function 'ap_slotmem_attach':
sharedmem_util.c:192: warning: assignment makes pointer from integer  
without a cast
sharedmem_util.c:154: warning: unused variable 'slotmem'
sharedmem_util.c: At top level:
sharedmem_util.c:234: warning: function declaration isn't a prototype
sharedmem_util.c: In function 'sharedmem_getstorage':
sharedmem_util.c:235: warning: return discards qualifiers from  
pointer target type
sharedmem_util.c: At top level:
sharedmem_util.c:239: warning: no previous prototype for  
'sharedmem_initglobalpool'
sharedmem_util.c:244: warning: no previous prototype for  
'sharedmem_initialize_cleanup'


Re: svn commit: r426604 - in /httpd/httpd/branches/httpd-proxy-scoreboard: modules/proxy/ support/

Posted by Jean-frederic Clere <jf...@gmail.com>.
Jim Jagielski wrote:

>
> On Jul 28, 2006, at 12:34 PM, jfclere@apache.org wrote:
>
>> Author: jfclere
>> Date: Fri Jul 28 09:33:58 2006
>> New Revision: 426604
>>
>> URL: http://svn.apache.org/viewvc?rev=426604&view=rev
>> Log:
>> First try to put togother an external health checker for mod_proxy.
>>
>
> Just coming back from OSCON, I haven't had a chance to take
> a deeper look but MAN that's a lot of code and data duplication.
>
> What's the goal for the code? What's the push for an
> external health checker?
>
>
>
I see different reasons to have an external health checker:
- It does not need a request to start.
- It tests the back-end server not only the socket used to send the data.
- It allows to have the information that a worker is down before send a 
request to it (prevent useless retries).

Cheers

Jean-Frederic


Re: svn commit: r426604 - in /httpd/httpd/branches/httpd-proxy-scoreboard: modules/proxy/ support/

Posted by Jim Jagielski <ji...@jaguNET.com>.
On Jul 28, 2006, at 12:34 PM, jfclere@apache.org wrote:

> Author: jfclere
> Date: Fri Jul 28 09:33:58 2006
> New Revision: 426604
>
> URL: http://svn.apache.org/viewvc?rev=426604&view=rev
> Log:
> First try to put togother an external health checker for mod_proxy.
>

Just coming back from OSCON, I haven't had a chance to take
a deeper look but MAN that's a lot of code and data duplication.

What's the goal for the code? What's the push for an
external health checker?



Re: svn commit: r426604 - in /httpd/httpd/branches/httpd-proxy-scoreboard: modules/proxy/ support/

Posted by Jean-frederic Clere <jf...@gmail.com>.
Hi,

I have committed the code to get comments on some points:
- Does it make sense to include from support objects from modules/proxy?
- Does the mod_proxy_health_checker is the right to do? - I mean: one 
part is storing the worker information to use it in an external process 
and the other is the health check of a worker, should  the module be cut 
in 2 pieces? -
- Any other comments?

Cheers

Jean-Frederic


jfclere@apache.org wrote:

>Author: jfclere
>Date: Fri Jul 28 09:33:58 2006
>New Revision: 426604
>
>URL: http://svn.apache.org/viewvc?rev=426604&view=rev
>Log:
>First try to put togother an external health checker for mod_proxy.
>
>Added:
>    httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/health_checker_util.c
>    httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy_health_checker.c
>    httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy_health_checker.h
>    httpd/httpd/branches/httpd-proxy-scoreboard/support/proxymonitor.c
>Modified:
>    httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/config.m4
>    httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy.c
>    httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy.h
>    httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/proxy_util.c
>    httpd/httpd/branches/httpd-proxy-scoreboard/support/Makefile.in
>
>  
>
+++ CUT +++

Re: svn commit: r426604 - in /httpd/httpd/branches/httpd-proxy-scoreboard: modules/proxy/ support/

Posted by Jim Jagielski <ji...@jaguNET.com>.
On Jul 28, 2006, at 4:03 PM, Jean-frederic Clere wrote:

> Jim Jagielski wrote:
>
>>
>> On Jul 28, 2006, at 1:54 PM, jean-frederic clere wrote:
>>
>>> Hi,
>>>
>>> I have committed the code to get comments on some points:
>>> - Does it make sense to include from support objects from  
>>> modules/ proxy?
>>> - Does the mod_proxy_health_checker is the right way to go? - I   
>>> mean: one part is storing the worker information to use it in an   
>>> external process and the other is the health check of a worker,   
>>> should  the module be cut in 2 pieces? -
>>> - Any other comments?
>>>
>>
>> I thought that this was about abstracting out scoreboard
>> so that other modules could have scoreboard-like
>> access without mucking around with the real scoreboard...
>>
> The scoreboard abstract is in modules/mem.
>

That is very specific to the proxy module implementation...
It basically just "moves" the current scoreboard access for
the proxy module to a different area, wraps them in
some function redirection, but with an impl that isn't useful to
anyone else but the proxy module... at least that's how
it appears to me :/

Unless I'm missing something...

Re: svn commit: r426604 - in /httpd/httpd/branches/httpd-proxy-scoreboard: modules/proxy/ support/

Posted by Jean-frederic Clere <jf...@gmail.com>.
Jim Jagielski wrote:

>
> On Jul 28, 2006, at 1:54 PM, jean-frederic clere wrote:
>
>> Hi,
>>
>> I have committed the code to get comments on some points:
>> - Does it make sense to include from support objects from modules/ 
>> proxy?
>> - Does the mod_proxy_health_checker is the right way to go? - I  
>> mean: one part is storing the worker information to use it in an  
>> external process and the other is the health check of a worker,  
>> should  the module be cut in 2 pieces? -
>> - Any other comments?
>>
>
> I thought that this was about abstracting out scoreboard
> so that other modules could have scoreboard-like
> access without mucking around with the real scoreboard...
>
The scoreboard abstract is in modules/mem.

Cheers

Jean-Frederic

Re: svn commit: r426604 - in /httpd/httpd/branches/httpd-proxy-scoreboard: modules/proxy/ support/

Posted by Brian Akins <br...@turner.com>.
Jim Jagielski wrote:
> I thought that this was about abstracting out scoreboard
> so that other modules could have scoreboard-like
> access without mucking around with the real scoreboard...

+1.  The proxy could just use this mechanism.  We need to separate the 
two "issues."  I am all in favor of a generic scoreboard, that, in the 
future, the "real" scoreboard might use.


-- 
Brian Akins
Chief Operations Engineer
Turner Digital Media Technologies

Re: svn commit: r426604 - in /httpd/httpd/branches/httpd-proxy-scoreboard: modules/proxy/ support/

Posted by Jim Jagielski <ji...@jaguNET.com>.
On Jul 28, 2006, at 1:54 PM, jean-frederic clere wrote:

> Hi,
>
> I have committed the code to get comments on some points:
> - Does it make sense to include from support objects from modules/ 
> proxy?
> - Does the mod_proxy_health_checker is the right way to go? - I  
> mean: one part is storing the worker information to use it in an  
> external process and the other is the health check of a worker,  
> should  the module be cut in 2 pieces? -
> - Any other comments?
>

I thought that this was about abstracting out scoreboard
so that other modules could have scoreboard-like
access without mucking around with the real scoreboard...

Re: svn commit: r426604 - in /httpd/httpd/branches/httpd-proxy-scoreboard: modules/proxy/ support/

Posted by jean-frederic clere <jf...@gmail.com>.
Hi,

I have committed the code to get comments on some points:
- Does it make sense to include from support objects from modules/proxy?
- Does the mod_proxy_health_checker is the right way to go? - I mean: one
part is storing the worker information to use it in an external process and
the other is the health check of a worker, should  the module be cut in 2
pieces? -
- Any other comments?

Cheers

Jean-Frederic



On 7/28/06, jfclere@apache.org <jf...@apache.org> wrote:
>
> Author: jfclere
> Date: Fri Jul 28 09:33:58 2006
> New Revision: 426604
>
> URL: http://svn.apache.org/viewvc?rev=426604&view=rev
> Log:
> First try to put togother an external health checker for mod_proxy.
>
> Added:
>
>     httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/health_checker_util.c
>
>     httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy_health_checker.c
>
>     httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy_health_checker.h
>     httpd/httpd/branches/httpd-proxy-scoreboard/support/proxymonitor.c
> Modified:
>     httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/config.m4
>     httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy.c
>     httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy.h
>     httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/proxy_util.c
>     httpd/httpd/branches/httpd-proxy-scoreboard/support/Makefile.in
>
> +++ CUT +++
>

Re: svn commit: r426604 - in /httpd/httpd/branches/httpd-proxy-scoreboard: modules/proxy/ support/

Posted by Jean-frederic Clere <jf...@gmail.com>.
Davi Arnaut wrote:

>
> Em 28/07/2006, às 13:34, jfclere@apache.org escreveu:
>
>> Author: jfclere
>> Date: Fri Jul 28 09:33:58 2006
>> New Revision: 426604
>
>
> ...
>
>> +
>> +static const slotmem_storage_method *checkstorage = NULL;
>> +static ap_slotmem_t *myscore=NULL;
>
>
> Indentation consistency ? "myscore=NULL"

fixed.

>
>> +
>> +    if (!port) {
>> +        if (strcmp(scheme, "ajp") == 0)
>> +            port = 8009;
>> +        else if (strcmp(scheme, "http") == 0)
>> +            port = 80;
>> +        else
>> +            port = 443;
>> +    }
>
>
> apr_uri_port_of_scheme ? (it may not have the ajp scheme, a patch is  
> appreciated)

Done.

>
>>
>> +    rv = apr_sockaddr_info_get(&epsv_addr, hostname, APR_INET,  
>> port, 0, pool);
>> +    if (rv != APR_SUCCESS) {
>> +        ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
>> +                     "apr_sockaddr_info_get failed");
>> +        apr_socket_close(newsock);
>> +        return rv;
>> +    }
>
>
>
> ap_log_error(..APLOG_ERR, rv, NULL..) so we may have a hint why it  
> failed

Yep.

>
>> +    rv = apr_socket_timeout_set(newsock, 10);
>> +    if (rv != APR_SUCCESS) {
>> +        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL,
>> +                    "apr_socket_timeout_set");
>> +        apr_socket_close(newsock);
>> +        return rv;
>
>
> same for ap_log_error
>
>> +    rv = apr_socket_connect(newsock, epsv_addr);
>> +    if (rv != APR_SUCCESS) {
>> +        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL,
>> +                    "apr_socket_connect failed");
>> +        apr_socket_close(newsock);
>> +        return rv;
>> +    }
>
>
> same for ap_log_error..and so on.
>
>> +
>> +    if (balancer_name)
>> +        strcpy(workerconf->balancer_name, balancer_name);
>> +    workerconf->id = worker->id;
>> +    workerconf->retry = worker->retry;
>> +    workerconf->lbfactor = worker->lbfactor;
>> +    if (worker->name)
>> +        strcpy(workerconf->name, worker->name);
>> +    if (worker->scheme)
>> +        strcpy(workerconf->scheme, worker->scheme);
>> +    if (worker->hostname)
>> +        strcpy(workerconf->hostname, worker->hostname);
>> +    if (worker->route)
>> +        strcpy(workerconf->route, worker->route);
>> +    if (worker->redirect)
>> +        strcpy(workerconf->redirect, worker->redirect);
>
>
> strncpy ?

Ok fixed.

>
>> +    /* allocate the data */
>> +    *worker = apr_pcalloc(pool, sizeof(proxy_worker));
>> +    if (workerconf->balancer_name)
>> +        *balancer_name = apr_pcalloc(pool, strlen(workerconf- 
>> >balancer_name));
>> +    else
>> +        *balancer_name = NULL;
>
>
> allocated for what ? the string is not copied. Also, shoudn't it be  
> strlen(..) + 1 ?

Fixed.

>
>>
>> +/* make the module usuable from outside */
>> +health_worker_method *health_checker_get_storage()
>> +{
>> +    return(&worker_storage);
>> +}
>> +
>> +/* handle the slotmem storage */
>> +void health_checker_init_slotmem_storage(slotmem_storage_method *  
>> storage)
>> +{
>> +    checkstorage = storage;
>> +}
>> +slotmem_storage_method * health_checker_get_slotmem_storage()
>> +{
>> +    return(checkstorage);
>> +}
>> +
>> +/* handle the slotmen itself */
>> +void health_checker_init_slotmem(ap_slotmem_t *score)
>> +{
>> +     myscore = score;
>> +}
>> +ap_slotmem_t *health_checker_get_slotmem()
>> +{
>> +    return(myscore);
>> +}
>
>
> static APR_INLINE ...

No, why?

>
>> +char * ap_server_root_relative(apr_pool_t *p, const char *name)
>> +{
>> +    char *fname;
>> +
>> +    /* XXX: apr_filepath_merge better ? */
>> +    if (basedir && name[0] != '/') {
>> +        fname = apr_pcalloc(p, strlen(basedir)+strlen(name)+1);
>> +        strcpy(fname, basedir);
>> +        strcat(fname, "/");
>> +        strcat(fname, name);
>
>
> apr_pstrcat ?

Yes, done

>
>
>


Re: svn commit: r426604 - in /httpd/httpd/branches/httpd-proxy-scoreboard: modules/proxy/ support/

Posted by Davi Arnaut <da...@haxent.com.br>.
Em 28/07/2006, às 13:34, jfclere@apache.org escreveu:

> Author: jfclere
> Date: Fri Jul 28 09:33:58 2006
> New Revision: 426604

...

> +
> +static const slotmem_storage_method *checkstorage = NULL;
> +static ap_slotmem_t *myscore=NULL;

Indentation consistency ? "myscore=NULL"

> +
> +    if (!port) {
> +        if (strcmp(scheme, "ajp") == 0)
> +            port = 8009;
> +        else if (strcmp(scheme, "http") == 0)
> +            port = 80;
> +        else
> +            port = 443;
> +    }

apr_uri_port_of_scheme ? (it may not have the ajp scheme, a patch is  
appreciated)

>
> +    rv = apr_sockaddr_info_get(&epsv_addr, hostname, APR_INET,  
> port, 0, pool);
> +    if (rv != APR_SUCCESS) {
> +        ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
> +                     "apr_sockaddr_info_get failed");
> +        apr_socket_close(newsock);
> +        return rv;
> +    }


ap_log_error(..APLOG_ERR, rv, NULL..) so we may have a hint why it  
failed

> +    rv = apr_socket_timeout_set(newsock, 10);
> +    if (rv != APR_SUCCESS) {
> +        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL,
> +                    "apr_socket_timeout_set");
> +        apr_socket_close(newsock);
> +        return rv;

same for ap_log_error

> +    rv = apr_socket_connect(newsock, epsv_addr);
> +    if (rv != APR_SUCCESS) {
> +        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL,
> +                    "apr_socket_connect failed");
> +        apr_socket_close(newsock);
> +        return rv;
> +    }

same for ap_log_error..and so on.

> +
> +    if (balancer_name)
> +        strcpy(workerconf->balancer_name, balancer_name);
> +    workerconf->id = worker->id;
> +    workerconf->retry = worker->retry;
> +    workerconf->lbfactor = worker->lbfactor;
> +    if (worker->name)
> +        strcpy(workerconf->name, worker->name);
> +    if (worker->scheme)
> +        strcpy(workerconf->scheme, worker->scheme);
> +    if (worker->hostname)
> +        strcpy(workerconf->hostname, worker->hostname);
> +    if (worker->route)
> +        strcpy(workerconf->route, worker->route);
> +    if (worker->redirect)
> +        strcpy(workerconf->redirect, worker->redirect);

strncpy ?

> +    /* allocate the data */
> +    *worker = apr_pcalloc(pool, sizeof(proxy_worker));
> +    if (workerconf->balancer_name)
> +        *balancer_name = apr_pcalloc(pool, strlen(workerconf- 
> >balancer_name));
> +    else
> +        *balancer_name = NULL;

allocated for what ? the string is not copied. Also, shoudn't it be  
strlen(..) + 1 ?

>
> +/* make the module usuable from outside */
> +health_worker_method *health_checker_get_storage()
> +{
> +    return(&worker_storage);
> +}
> +
> +/* handle the slotmem storage */
> +void health_checker_init_slotmem_storage(slotmem_storage_method *  
> storage)
> +{
> +    checkstorage = storage;
> +}
> +slotmem_storage_method * health_checker_get_slotmem_storage()
> +{
> +    return(checkstorage);
> +}
> +
> +/* handle the slotmen itself */
> +void health_checker_init_slotmem(ap_slotmem_t *score)
> +{
> +     myscore = score;
> +}
> +ap_slotmem_t *health_checker_get_slotmem()
> +{
> +    return(myscore);
> +}

static APR_INLINE ...

> +char * ap_server_root_relative(apr_pool_t *p, const char *name)
> +{
> +    char *fname;
> +
> +    /* XXX: apr_filepath_merge better ? */
> +    if (basedir && name[0] != '/') {
> +        fname = apr_pcalloc(p, strlen(basedir)+strlen(name)+1);
> +        strcpy(fname, basedir);
> +        strcat(fname, "/");
> +        strcat(fname, name);

apr_pstrcat ?



Re: svn commit: r426604 - in /httpd/httpd/branches/httpd-proxy-scoreboard: modules/proxy/ support/

Posted by Ruediger Pluem <rp...@apache.org>.

On 07/29/2006 09:59 AM, Ruediger Pluem wrote:

> 
> But it is not used in this implementation. Instead you use worker->id here.
> Should it be used by other implementations where worker->id cannot / shouldn't be used?

Never mind. Obsoleted by  r426732.

Regards

Rüdiger


Re: svn commit: r426604 - in /httpd/httpd/branches/httpd-proxy-scoreboard: modules/proxy/ support/

Posted by Ruediger Pluem <rp...@apache.org>.

On 07/29/2006 03:01 AM, Jean-frederic Clere wrote:
> Ruediger Pluem wrote:
> 
>> On 28.07.2006 18:34, jfclere@apache.org wrote:
>>  
>>
>>> Author: jfclere
>>> Date: Fri Jul 28 09:33:58 2006
>>> New Revision: 426604
>>>
>>> URL: http://svn.apache.org/viewvc?rev=426604&view=rev
>>> Log:
>>> First try to put togother an external health checker for mod_proxy.
>>
>>> +}
>>> +/* copy the worker information in the shared area so the
>>> health-checker can extract the part it need */
>>> +static apr_status_t add_entry(proxy_worker *worker, char
>>> *balancer_name, int id)
>>>   
>>
>>
>> What is the purpose of the id parameter. I do not see that it is used.
>>  
>>
> The id of the slot where the worker has to be stored.

But it is not used in this implementation. Instead you use worker->id here.
Should it be used by other implementations where worker->id cannot / shouldn't be used?

Regards

Rüdiger


Re: svn commit: r426604 - in /httpd/httpd/branches/httpd-proxy-scoreboard: modules/proxy/ support/

Posted by Jean-frederic Clere <jf...@gmail.com>.
Ruediger Pluem wrote:

>On 28.07.2006 18:34, jfclere@apache.org wrote:
>  
>
>>Author: jfclere
>>Date: Fri Jul 28 09:33:58 2006
>>New Revision: 426604
>>
>>URL: http://svn.apache.org/viewvc?rev=426604&view=rev
>>Log:
>>First try to put togother an external health checker for mod_proxy.
>>
>>    
>>
>
>  
>
>>Modified: httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/config.m4
>>URL: http://svn.apache.org/viewvc/httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/config.m4?rev=426604&r1=426603&r2=426604&view=diff
>>==============================================================================
>>--- httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/config.m4 (original)
>>+++ httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/config.m4 Fri Jul 28 09:33:58 2006
>>@@ -17,6 +17,7 @@
>>    
>>
>
>
>  
>
>>+}
>>+/* copy the worker information in the shared area so the health-checker can extract the part it need */
>>+static apr_status_t add_entry(proxy_worker *worker, char *balancer_name, int id)
>>    
>>
>
>What is the purpose of the id parameter. I do not see that it is used.
>  
>
The id of the slot where the worker has to be stored.

>  
>
>>+{
>>+    struct proxy_worker_conf *workerconf = NULL;
>>+    apr_status_t rv;
>>+
>>+    if (myscore == NULL)
>>+        return APR_ENOSHMAVAIL;
>>+    rv = checkstorage->ap_slotmem_mem(myscore, worker->id, (void *) &workerconf);
>>+    if (rv != APR_SUCCESS) {
>>+        return rv;
>>+    }
>>+
>>+    if (balancer_name)
>>+        strcpy(workerconf->balancer_name, balancer_name);
>>+    workerconf->id = worker->id;
>>+    workerconf->retry = worker->retry;
>>+    workerconf->lbfactor = worker->lbfactor;
>>    
>>
>
>Is this approach thread safe / process safe or is there no need to be?
>  
>
It should be used while parse the configuration or adding an entry... 
Well it isn't my idea is to have the thread/process synchro stuff before 
calling add_entry.

>  
>
>>+    if (worker->name)
>>+        strcpy(workerconf->name, worker->name);
>>+    if (worker->scheme)
>>+        strcpy(workerconf->scheme, worker->scheme);
>>+    if (worker->hostname)
>>+        strcpy(workerconf->hostname, worker->hostname);
>>+    if (worker->route)
>>+        strcpy(workerconf->route, worker->route);
>>+    if (worker->redirect)
>>+        strcpy(workerconf->redirect, worker->redirect);
>>    
>>
>
>Don't you need to use strncpy here to avoid buffer overflows?
>  
>
Of course.

>
>  
>
>>+/* read the entry stored in the shared area and build the corresponding worker structure */
>>+static apr_status_t get_entry(int id, proxy_worker **worker, char **balancer_name, apr_pool_t *pool)
>>+{
>>+    struct proxy_worker_conf *workerconf = NULL;
>>+    apr_status_t rv;
>>+
>>+    if (myscore == NULL)
>>+        return APR_ENOSHMAVAIL;
>>+    rv = checkstorage->ap_slotmem_mem(myscore, id, (void *) &workerconf);
>>+    if (rv != APR_SUCCESS)
>>+        return rv;
>>+
>>+    /* allocate the data */
>>+    *worker = apr_pcalloc(pool, sizeof(proxy_worker));
>>+    if (workerconf->balancer_name)
>>+        *balancer_name = apr_pcalloc(pool, strlen(workerconf->balancer_name));
>>+    else
>>+        *balancer_name = NULL;
>>+
>>+    /* The httpstatus is handle by httpd don't touch it here */
>>+    (* worker)->id = workerconf->id;
>>+    // XXX: what to do (* worker)->s = workerconf;
>>+    (* worker)->retry = workerconf->retry;
>>+    (* worker)->lbfactor = workerconf->lbfactor;
>>+    if (workerconf->name)
>>+        strcpy((* worker)->name, workerconf->name);
>>+    if (workerconf->scheme)
>>+        strcpy((* worker)->scheme, workerconf->scheme);
>>+    if (workerconf->hostname)
>>+        strcpy((* worker)->hostname, workerconf->hostname);
>>+    if (workerconf->route)
>>+        strcpy((* worker)->route, workerconf->route);
>>+    if (workerconf->redirect)
>>+        strcpy((* worker)->redirect, workerconf->redirect);
>>    
>>
>
>Don't you need to allocate space for this first (like with the balancer name)?
>  
>
Yes, done.

>
>  
>
>>Added: httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy_health_checker.c
>>URL: http://svn.apache.org/viewvc/httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy_health_checker.c?rev=426604&view=auto
>>==============================================================================
>>--- httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy_health_checker.c (added)
>>+++ httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy_health_checker.c Fri Jul 28 09:33:58 2006
>>    
>>
>
>  
>
>>+
>>+static int healthck_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
>>+                              apr_pool_t *ptemp)
>>+{
>>+    slotmem_storage_method *checkstorage;
>>+    health_worker_method *worker_storage = health_checker_get_storage();
>>+    ap_slotmem_t *myscore;
>>+    
>>+    checkstorage = ap_lookup_provider(SLOTMEM_STORAGE, "shared", "0");
>>+    if (checkstorage) {
>>+        health_checker_init_slotmem_storage(checkstorage);
>>+    }
>>+    if (checkstorage && worker_storage) {
>>+        checkstorage->ap_slotmem_create(&myscore, "proxy/checker", worker_storage->getentrysize(), 128, pconf);
>>+        health_checker_init_slotmem(myscore);
>>+    }
>>+    return OK;
>>+}
>>+
>>+/* XXX: Was to get ap_proxy_lb_workers()
>>+static int healthck_post_config(apr_pool_t *pconf, apr_pool_t *plog,
>>+                                apr_pool_t *ptemp, server_rec *s)
>>+{
>>+    slotmem_storage_method *checkstorage = health_checker_get_slotmem_storage();
>>+    health_worker_method *worker_storage = health_checker_get_storage();
>>+    ap_slotmem_t *myscore;
>>+
>>+    if (checkstorage && worker_storage) {
>>+        checkstorage->ap_slotmem_create(&myscore, "proxy/checker", worker_storage->getentrysize(), ap_proxy_lb_workers(), pconf);
>>    
>>
>
>Sorry, but I am confused, but this only returns myscore created in preconfig
>without changing anything.
>  
>
Oops I have forgotten to remove it.

>
>  
>
>>Added: httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy_health_checker.h
>>URL: http://svn.apache.org/viewvc/httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy_health_checker.h?rev=426604&view=auto
>>==============================================================================
>>    
>>
>
>  
>
>>+/* allow health check method on workers in a non httpd process */
>>+struct health_worker_method {
>>+    /* read the size of the entry: to create the shared area */
>>+    int (* getentrysize)();
>>+    /* copy the worker information in the shared area so the health-checker can extract the part it need */
>>+    apr_status_t (*add_entry)(proxy_worker *worker, char *balancer_name, int id);
>>    
>>
>
>What about dynamic updates via the manager? Do they get updated or is there no
>need to update the health check data with the manager data?
>  
>
They have to be updated. ;-)

>
>
>
>  
>
>>Added: httpd/httpd/branches/httpd-proxy-scoreboard/support/proxymonitor.c
>>URL: http://svn.apache.org/viewvc/httpd/httpd/branches/httpd-proxy-scoreboard/support/proxymonitor.c?rev=426604&view=auto
>>==============================================================================
>>--- httpd/httpd/branches/httpd-proxy-scoreboard/support/proxymonitor.c (added)
>>+++ httpd/httpd/branches/httpd-proxy-scoreboard/support/proxymonitor.c Fri Jul 28 09:33:58 2006
>>    
>>
>
>  
>
>>+/*
>>+ * httpd routine to be able to link with the modules.
>>+ */
>>+char * ap_server_root_relative(apr_pool_t *p, const char *name)
>>+{
>>+    char *fname;
>>+
>>+    /* XXX: apr_filepath_merge better ? */
>>+    if (basedir && name[0] != '/') {
>>+        fname = apr_pcalloc(p, strlen(basedir)+strlen(name)+1);
>>+        strcpy(fname, basedir);
>>+        strcat(fname, "/");
>>+        strcat(fname, name);
>>    
>>
>
>fname = apr_strcat(p, basedir, "/", name, NULL) ?
>
>
>  
>
>>+int main(int argc, const char * const argv[])
>>+{
>>    
>>
>
>  
>
>>+
>>+    while (repeat && ! interrupted) {
>>+
>>+        if (instance_socket == NULL) {
>>+            apr_pool_create(&instance_socket, pool);
>>+            init_healthck(instance_socket, &num);
>>+        }
>>+
>>+        apr_pool_create(&instance, instance_socket);
>>+        apr_sleep(delay);
>>+        now = apr_time_now();
>>+        process_sharedmem(instance_socket, num);
>>+        current = apr_time_now();
>>+        apr_rfc822_date(datestring, current);
>>+        apr_file_printf(outfile,"at %s in %d\n", datestring, current-now);
>>+
>>+        if (repeat>0)
>>+            repeat--;
>>+        apr_pool_destroy(instance);
>>+        /* If something goes really wrong we should clean all */
>>+        if (0) {
>>    
>>
>
>When does this condition become true?
>  
>
I have removed the code.

Thanks

Jean-Frederic

>Regards
>
>Rüdiger
>
>  
>


Re: svn commit: r426604 - in /httpd/httpd/branches/httpd-proxy-scoreboard: modules/proxy/ support/

Posted by Ruediger Pluem <rp...@apache.org>.
On 28.07.2006 18:34, jfclere@apache.org wrote:
> Author: jfclere
> Date: Fri Jul 28 09:33:58 2006
> New Revision: 426604
> 
> URL: http://svn.apache.org/viewvc?rev=426604&view=rev
> Log:
> First try to put togother an external health checker for mod_proxy.
> 

> 
> Modified: httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/config.m4
> URL: http://svn.apache.org/viewvc/httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/config.m4?rev=426604&r1=426603&r2=426604&view=diff
> ==============================================================================
> --- httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/config.m4 (original)
> +++ httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/config.m4 Fri Jul 28 09:33:58 2006
> @@ -17,6 +17,7 @@


> +}
> +/* copy the worker information in the shared area so the health-checker can extract the part it need */
> +static apr_status_t add_entry(proxy_worker *worker, char *balancer_name, int id)

What is the purpose of the id parameter. I do not see that it is used.

> +{
> +    struct proxy_worker_conf *workerconf = NULL;
> +    apr_status_t rv;
> +
> +    if (myscore == NULL)
> +        return APR_ENOSHMAVAIL;
> +    rv = checkstorage->ap_slotmem_mem(myscore, worker->id, (void *) &workerconf);
> +    if (rv != APR_SUCCESS) {
> +        return rv;
> +    }
> +
> +    if (balancer_name)
> +        strcpy(workerconf->balancer_name, balancer_name);
> +    workerconf->id = worker->id;
> +    workerconf->retry = worker->retry;
> +    workerconf->lbfactor = worker->lbfactor;

Is this approach thread safe / process safe or is there no need to be?

> +    if (worker->name)
> +        strcpy(workerconf->name, worker->name);
> +    if (worker->scheme)
> +        strcpy(workerconf->scheme, worker->scheme);
> +    if (worker->hostname)
> +        strcpy(workerconf->hostname, worker->hostname);
> +    if (worker->route)
> +        strcpy(workerconf->route, worker->route);
> +    if (worker->redirect)
> +        strcpy(workerconf->redirect, worker->redirect);

Don't you need to use strncpy here to avoid buffer overflows?


>
> +/* read the entry stored in the shared area and build the corresponding worker structure */
> +static apr_status_t get_entry(int id, proxy_worker **worker, char **balancer_name, apr_pool_t *pool)
> +{
> +    struct proxy_worker_conf *workerconf = NULL;
> +    apr_status_t rv;
> +
> +    if (myscore == NULL)
> +        return APR_ENOSHMAVAIL;
> +    rv = checkstorage->ap_slotmem_mem(myscore, id, (void *) &workerconf);
> +    if (rv != APR_SUCCESS)
> +        return rv;
> +
> +    /* allocate the data */
> +    *worker = apr_pcalloc(pool, sizeof(proxy_worker));
> +    if (workerconf->balancer_name)
> +        *balancer_name = apr_pcalloc(pool, strlen(workerconf->balancer_name));
> +    else
> +        *balancer_name = NULL;
> +
> +    /* The httpstatus is handle by httpd don't touch it here */
> +    (* worker)->id = workerconf->id;
> +    // XXX: what to do (* worker)->s = workerconf;
> +    (* worker)->retry = workerconf->retry;
> +    (* worker)->lbfactor = workerconf->lbfactor;
> +    if (workerconf->name)
> +        strcpy((* worker)->name, workerconf->name);
> +    if (workerconf->scheme)
> +        strcpy((* worker)->scheme, workerconf->scheme);
> +    if (workerconf->hostname)
> +        strcpy((* worker)->hostname, workerconf->hostname);
> +    if (workerconf->route)
> +        strcpy((* worker)->route, workerconf->route);
> +    if (workerconf->redirect)
> +        strcpy((* worker)->redirect, workerconf->redirect);

Don't you need to allocate space for this first (like with the balancer name)?


> Added: httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy_health_checker.c
> URL: http://svn.apache.org/viewvc/httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy_health_checker.c?rev=426604&view=auto
> ==============================================================================
> --- httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy_health_checker.c (added)
> +++ httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy_health_checker.c Fri Jul 28 09:33:58 2006

> +
> +static int healthck_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
> +                              apr_pool_t *ptemp)
> +{
> +    slotmem_storage_method *checkstorage;
> +    health_worker_method *worker_storage = health_checker_get_storage();
> +    ap_slotmem_t *myscore;
> +    
> +    checkstorage = ap_lookup_provider(SLOTMEM_STORAGE, "shared", "0");
> +    if (checkstorage) {
> +        health_checker_init_slotmem_storage(checkstorage);
> +    }
> +    if (checkstorage && worker_storage) {
> +        checkstorage->ap_slotmem_create(&myscore, "proxy/checker", worker_storage->getentrysize(), 128, pconf);
> +        health_checker_init_slotmem(myscore);
> +    }
> +    return OK;
> +}
> +
> +/* XXX: Was to get ap_proxy_lb_workers()
> +static int healthck_post_config(apr_pool_t *pconf, apr_pool_t *plog,
> +                                apr_pool_t *ptemp, server_rec *s)
> +{
> +    slotmem_storage_method *checkstorage = health_checker_get_slotmem_storage();
> +    health_worker_method *worker_storage = health_checker_get_storage();
> +    ap_slotmem_t *myscore;
> +
> +    if (checkstorage && worker_storage) {
> +        checkstorage->ap_slotmem_create(&myscore, "proxy/checker", worker_storage->getentrysize(), ap_proxy_lb_workers(), pconf);

Sorry, but I am confused, but this only returns myscore created in preconfig
without changing anything.


> 
> Added: httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy_health_checker.h
> URL: http://svn.apache.org/viewvc/httpd/httpd/branches/httpd-proxy-scoreboard/modules/proxy/mod_proxy_health_checker.h?rev=426604&view=auto
> ==============================================================================

> +/* allow health check method on workers in a non httpd process */
> +struct health_worker_method {
> +    /* read the size of the entry: to create the shared area */
> +    int (* getentrysize)();
> +    /* copy the worker information in the shared area so the health-checker can extract the part it need */
> +    apr_status_t (*add_entry)(proxy_worker *worker, char *balancer_name, int id);

What about dynamic updates via the manager? Do they get updated or is there no
need to update the health check data with the manager data?




> Added: httpd/httpd/branches/httpd-proxy-scoreboard/support/proxymonitor.c
> URL: http://svn.apache.org/viewvc/httpd/httpd/branches/httpd-proxy-scoreboard/support/proxymonitor.c?rev=426604&view=auto
> ==============================================================================
> --- httpd/httpd/branches/httpd-proxy-scoreboard/support/proxymonitor.c (added)
> +++ httpd/httpd/branches/httpd-proxy-scoreboard/support/proxymonitor.c Fri Jul 28 09:33:58 2006

> +/*
> + * httpd routine to be able to link with the modules.
> + */
> +char * ap_server_root_relative(apr_pool_t *p, const char *name)
> +{
> +    char *fname;
> +
> +    /* XXX: apr_filepath_merge better ? */
> +    if (basedir && name[0] != '/') {
> +        fname = apr_pcalloc(p, strlen(basedir)+strlen(name)+1);
> +        strcpy(fname, basedir);
> +        strcat(fname, "/");
> +        strcat(fname, name);

fname = apr_strcat(p, basedir, "/", name, NULL) ?


> +int main(int argc, const char * const argv[])
> +{

> +
> +    while (repeat && ! interrupted) {
> +
> +        if (instance_socket == NULL) {
> +            apr_pool_create(&instance_socket, pool);
> +            init_healthck(instance_socket, &num);
> +        }
> +
> +        apr_pool_create(&instance, instance_socket);
> +        apr_sleep(delay);
> +        now = apr_time_now();
> +        process_sharedmem(instance_socket, num);
> +        current = apr_time_now();
> +        apr_rfc822_date(datestring, current);
> +        apr_file_printf(outfile,"at %s in %d\n", datestring, current-now);
> +
> +        if (repeat>0)
> +            repeat--;
> +        apr_pool_destroy(instance);
> +        /* If something goes really wrong we should clean all */
> +        if (0) {

When does this condition become true?

Regards

Rüdiger