summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Frederic Clere <jfclere@apache.org>2009-07-30 17:37:22 +0200
committerJean-Frederic Clere <jfclere@apache.org>2009-07-30 17:37:22 +0200
commit0d6b9d370d17ee5726ccb718d0e718053547c47c (patch)
tree0742b2ed98410a6675b734ca7a76bf27560f3d2c
parentCatch up to apr_dbm projects (diff)
downloadapache2-0d6b9d370d17ee5726ccb718d0e718053547c47c.tar.xz
apache2-0d6b9d370d17ee5726ccb718d0e718053547c47c.zip
Add the file logic for the handler.
(Next step add the slotmem logic for the multicast socket). git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@799334 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--modules/cluster/mod_heartmonitor.c186
1 files changed, 185 insertions, 1 deletions
diff --git a/modules/cluster/mod_heartmonitor.c b/modules/cluster/mod_heartmonitor.c
index 4d95d0b387..f24ae27b51 100644
--- a/modules/cluster/mod_heartmonitor.c
+++ b/modules/cluster/mod_heartmonitor.c
@@ -203,6 +203,188 @@ static apr_status_t hm_slotmem_update_stat(hm_server_t *s, request_rec *r)
}
return APR_SUCCESS;
}
+/* Copied from mod_lbmethod_heartbeat.c... */
+static void
+argstr_to_table(apr_pool_t *p, char *str, apr_table_t *parms)
+{
+ char *key;
+ char *value;
+ char *strtok_state;
+
+ key = apr_strtok(str, "&", &strtok_state);
+ while (key) {
+ value = strchr(key, '=');
+ if (value) {
+ *value = '\0'; /* Split the string in two */
+ value++; /* Skip passed the = */
+ }
+ else {
+ value = "1";
+ }
+ ap_unescape_url(key);
+ ap_unescape_url(value);
+ apr_table_set(parms, key, value);
+ /*
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+ "Found query arg: %s = %s", key, value);
+ */
+ key = apr_strtok(NULL, "&", &strtok_state);
+ }
+}
+static apr_status_t hm_file_update_stat(hm_ctx_t *ctx, hm_server_t *s, apr_pool_t *pool)
+{
+ apr_status_t rv;
+ apr_file_t *fp;
+ apr_file_t *fpin;
+ apr_hash_index_t *hi;
+ apr_time_t now;
+ unsigned int fage;
+ apr_finfo_t fi;
+ int updated = 0;
+ char *path = apr_pstrcat(pool, ctx->storage_path, ".tmp.XXXXXX", NULL);
+
+
+ /* TODO: Update stats file (!) */
+ rv = apr_file_mktemp(&fp, path, APR_CREATE | APR_WRITE, pool);
+
+ if (rv) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s,
+ "Heartmonitor: Unable to open tmp file: %s", path);
+ return rv;
+ }
+ rv = apr_file_open(&fpin, ctx->storage_path, APR_READ|APR_BINARY|APR_BUFFERED,
+ APR_OS_DEFAULT, pool);
+
+ now = apr_time_now();
+ if (rv == APR_SUCCESS) {
+ char *t;
+ apr_table_t *hbt = apr_table_make(pool, 10);
+ apr_bucket_alloc_t *ba = apr_bucket_alloc_create(pool);
+ apr_bucket_brigade *bb = apr_brigade_create(pool, ba);
+ apr_bucket_brigade *tmpbb = apr_brigade_create(pool, ba);
+ rv = apr_file_info_get(&fi, APR_FINFO_SIZE | APR_FINFO_MTIME, fpin);
+ if (rv) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s,
+ "Heartmonitor: Unable to read file: %s", ctx->storage_path);
+ return rv;
+ }
+
+ /* Read the file and update the line corresponding to the node */
+ ba = apr_bucket_alloc_create(pool);
+ bb = apr_brigade_create(pool, ba);
+ apr_brigade_insert_file(bb, fpin, 0, fi.size, pool);
+ tmpbb = apr_brigade_create(pool, ba);
+ fage = (unsigned int) apr_time_sec(now - fi.mtime);
+ do {
+ char buf[4096];
+ const char *ip;
+ apr_size_t bsize = sizeof(buf);
+ apr_brigade_cleanup(tmpbb);
+ if (APR_BRIGADE_EMPTY(bb)) {
+ break;
+ }
+ rv = apr_brigade_split_line(tmpbb, bb,
+ APR_BLOCK_READ, sizeof(buf));
+
+ if (rv) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s,
+ "Heartmonitor: Unable to read from file: %s", ctx->storage_path);
+ return rv;
+ }
+
+ apr_brigade_flatten(tmpbb, buf, &bsize);
+ if (bsize == 0) {
+ break;
+ }
+ buf[bsize - 1] = 0;
+ t = strchr(buf, ' ');
+ if (t) {
+ ip = apr_pstrndup(pool, buf, t - buf);
+ } else {
+ ip = NULL;
+ }
+ if (!ip || buf[0] == '#') {
+ /* copy things we can't process */
+ apr_file_printf(fp, "%s\n", buf);
+ } else if (strcmp(ip, s->ip) !=0 ) {
+ hm_server_t node;
+ unsigned int seen;
+ /* Update seen time according to the last file modification */
+ apr_table_clear(hbt);
+ argstr_to_table(pool, apr_pstrdup(pool, t), hbt);
+ if (apr_table_get(hbt, "busy")) {
+ node.busy = atoi(apr_table_get(hbt, "busy"));
+ }
+
+ if (apr_table_get(hbt, "ready")) {
+ node.ready = atoi(apr_table_get(hbt, "ready"));
+ }
+
+ if (apr_table_get(hbt, "lastseen")) {
+ node.seen = atoi(apr_table_get(hbt, "lastseen"));
+ }
+ seen = fage + node.seen;
+ apr_file_printf(fp, "%s &ready=%u&busy=%u&lastseen=%u\n",
+ ip, node.ready, node.busy, (unsigned int) seen);
+ } else {
+ apr_time_t seen;
+ seen = apr_time_sec(now - s->seen);
+ apr_file_printf(fp, "%s &ready=%u&busy=%u&lastseen=%u\n",
+ s->ip, s->ready, s->busy, (unsigned int) seen);
+ updated = 1;
+ }
+ } while (1);
+ }
+
+ if (!updated) {
+ apr_time_t seen;
+ seen = apr_time_sec(now - s->seen);
+ apr_file_printf(fp, "%s &ready=%u&busy=%u&lastseen=%u\n",
+ s->ip, s->ready, s->busy, (unsigned int) seen);
+ }
+
+ rv = apr_file_flush(fp);
+ if (rv) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s,
+ "Heartmonitor: Unable to flush file: %s", path);
+ return rv;
+ }
+
+ rv = apr_file_close(fp);
+ if (rv) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s,
+ "Heartmonitor: Unable to close file: %s", path);
+ return rv;
+ }
+
+ rv = apr_file_perms_set(path,
+ APR_FPROT_UREAD | APR_FPROT_GREAD |
+ APR_FPROT_WREAD);
+ if (rv && rv != APR_INCOMPLETE) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s,
+ "Heartmonitor: Unable to set file permssions on %s",
+ path);
+ return rv;
+ }
+
+ rv = apr_file_rename(path, ctx->storage_path, pool);
+
+ if (rv) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ctx->s,
+ "Heartmonitor: Unable to move file: %s -> %s", path,
+ ctx->storage_path);
+ return rv;
+ }
+
+ return APR_SUCCESS;
+}
+static apr_status_t hm_update_stat(hm_ctx_t *ctx, hm_server_t *s, request_rec *r)
+{
+ if (slotmem)
+ return hm_slotmem_update_stat(s, r);
+ else
+ return hm_file_update_stat(ctx, s, r->pool);
+}
/* Store in a file */
static apr_status_t hm_file_update_stats(hm_ctx_t *ctx, apr_pool_t *p)
@@ -504,6 +686,8 @@ static int hm_handler(request_rec *r)
apr_table_t *tbl;
hm_server_t hmserver;
char *ip;
+ hm_ctx_t *ctx = ap_get_module_config(r->server->module_config,
+ &heartmonitor_module);
if (strcmp(r->handler, "hearthbeat")) {
return DECLINED;
@@ -528,7 +712,7 @@ static int hm_handler(request_rec *r)
hmserver.busy = atoi(apr_table_get(tbl, "busy"));
hmserver.ready = atoi(apr_table_get(tbl, "ready"));
hmserver.seen = apr_time_now();
- hm_slotmem_update_stat(&hmserver, r);
+ hm_update_stat(ctx, &hmserver, r);
ap_set_content_type(r, "text/plain");
ap_set_content_length(r, 2);