diff options
author | Jean-Frederic Clere <jfclere@apache.org> | 2009-07-30 17:37:22 +0200 |
---|---|---|
committer | Jean-Frederic Clere <jfclere@apache.org> | 2009-07-30 17:37:22 +0200 |
commit | 0d6b9d370d17ee5726ccb718d0e718053547c47c (patch) | |
tree | 0742b2ed98410a6675b734ca7a76bf27560f3d2c | |
parent | Catch up to apr_dbm projects (diff) | |
download | apache2-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.c | 186 |
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); |