mirror of
https://github.com/apache/httpd.git
synced 2025-11-05 05:30:39 +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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user