1
0
mirror of https://github.com/apache/httpd.git synced 2025-11-06 16:49:32 +03:00

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
This commit is contained in:
Jean-Frederic Clere
2009-07-30 15:37:22 +00:00
parent ed6da4f1b9
commit 0d6b9d370d

View File

@@ -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);