b5d34bc3082c1164ce20df48567d192e3e9f229fjim/* Licensed to the Apache Software Foundation (ASF) under one or more
b5d34bc3082c1164ce20df48567d192e3e9f229fjim * contributor license agreements. See the NOTICE file distributed with
b5d34bc3082c1164ce20df48567d192e3e9f229fjim * this work for additional information regarding copyright ownership.
b5d34bc3082c1164ce20df48567d192e3e9f229fjim * The ASF licenses this file to You under the Apache License, Version 2.0
b5d34bc3082c1164ce20df48567d192e3e9f229fjim * (the "License"); you may not use this file except in compliance with
b5d34bc3082c1164ce20df48567d192e3e9f229fjim * the License. You may obtain a copy of the License at
b5d34bc3082c1164ce20df48567d192e3e9f229fjim * Unless required by applicable law or agreed to in writing, software
b5d34bc3082c1164ce20df48567d192e3e9f229fjim * distributed under the License is distributed on an "AS IS" BASIS,
b5d34bc3082c1164ce20df48567d192e3e9f229fjim * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
b5d34bc3082c1164ce20df48567d192e3e9f229fjim * See the License for the specific language governing permissions and
b5d34bc3082c1164ce20df48567d192e3e9f229fjim * limitations under the License.
a231b4cbdf1bd3d65dc13ead8d8a4f7e8b307314pquerna/* If we haven't seen a heartbeat in the last N seconds, don't count this IP
a231b4cbdf1bd3d65dc13ead8d8a4f7e8b307314pquerna * as allive.
4ab0fd1b54ce76f0fb6812b89b0b4dc7541014d6minfrinstatic int (*ap_proxy_retry_worker_fn)(const char *proxy_function,
2806775e45dfd5164d53fcb3d850d358f8ec2415jfclere * configuration structure
2806775e45dfd5164d53fcb3d850d358f8ec2415jfclere * path: path of the file where the heartbeat information is stored.
b5d34bc3082c1164ce20df48567d192e3e9f229fjimstatic void
b5d34bc3082c1164ce20df48567d192e3e9f229fjimargstr_to_table(apr_pool_t *p, char *str, apr_table_t *parms)
b5d34bc3082c1164ce20df48567d192e3e9f229fjim ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
b5d34bc3082c1164ce20df48567d192e3e9f229fjim "Found query arg: %s = %s", key, value);
2806775e45dfd5164d53fcb3d850d358f8ec2415jfclerestatic apr_status_t readfile_heartbeats(const char *path, apr_hash_t *servers,
b5d34bc3082c1164ce20df48567d192e3e9f229fjim rv = apr_file_open(&fp, path, APR_READ|APR_BINARY|APR_BUFFERED,
b5d34bc3082c1164ce20df48567d192e3e9f229fjim apr_bucket_brigade *tmpbb = apr_brigade_create(pool, ba);
b5d34bc3082c1164ce20df48567d192e3e9f229fjim if (bsize == 0) {
b5d34bc3082c1164ce20df48567d192e3e9f229fjim /* comment */
b5d34bc3082c1164ce20df48567d192e3e9f229fjim /* line format: <IP> <query_string>\n */
b5d34bc3082c1164ce20df48567d192e3e9f229fjim server = apr_hash_get(servers, ip, APR_HASH_KEY_STRING);
b5d34bc3082c1164ce20df48567d192e3e9f229fjim apr_hash_set(servers, server->ip, APR_HASH_KEY_STRING, server);
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim /* Server has zero threads active, but lots of them ready,
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim * it likely just started up, so lets /4 the number ready,
5bfaaf573bacb45c1cf290ce85ecc676587e8a64jim * to prevent us from completely flooding it with all new
b5d34bc3082c1164ce20df48567d192e3e9f229fjim * requests.
b5d34bc3082c1164ce20df48567d192e3e9f229fjim } while (1);
2806775e45dfd5164d53fcb3d850d358f8ec2415jfclerestatic apr_status_t hm_read(void* mem, void *data, apr_pool_t *pool)
2806775e45dfd5164d53fcb3d850d358f8ec2415jfclere hm_slot_server_t *slotserver = (hm_slot_server_t *) mem;
2806775e45dfd5164d53fcb3d850d358f8ec2415jfclere hb_server_t *server = apr_hash_get(servers, slotserver->ip, APR_HASH_KEY_STRING);
2806775e45dfd5164d53fcb3d850d358f8ec2415jfclere apr_hash_set(servers, server->ip, APR_HASH_KEY_STRING, server);
a515c3892232a3497bb58eeec5a1b9523571cf67jfclere server->seen = apr_time_sec(ctx->now - slotserver->seen);
a515c3892232a3497bb58eeec5a1b9523571cf67jfclerestatic apr_status_t readslot_heartbeats(ctx_servers_t *ctx,
dc75ae85aef46bf3df41b96a4509ab19c07fe20cjimstatic apr_status_t read_heartbeats(const char *path, apr_hash_t *servers,
b5d34bc3082c1164ce20df48567d192e3e9f229fjimstatic proxy_worker *find_best_hb(proxy_balancer *balancer,
4ab0fd1b54ce76f0fb6812b89b0b4dc7541014d6minfrin /* can only happen if mod_proxy isn't loaded */
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01213)
b5d34bc3082c1164ce20df48567d192e3e9f229fjim "lb_heartbeat: Unable to read heartbeats at '%s'",
b5d34bc3082c1164ce20df48567d192e3e9f229fjim up_servers = apr_array_make(tpool, apr_hash_count(servers), sizeof(hb_server_t *));
834fc281be8e0f7f2614961f12d8bbf603382a17jfclere worker = &APR_ARRAY_IDX(balancer->workers, i, proxy_worker *);
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim server = apr_hash_get(servers, (*worker)->s->hostname, APR_HASH_KEY_STRING);
185aa71728867671e105178b4c66fbc22b65ae26sf ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, APLOGNO(01214)
23a31b10f869a72c9197b5f153f4f3e1a4c68f28jim "lb_heartbeat: No server for worker %s", (*worker)->s->name);
4ab0fd1b54ce76f0fb6812b89b0b4dc7541014d6minfrin ap_proxy_retry_worker_fn("BALANCER", *worker, r->server);
19f5359fc7b955a110e5ebe345ef4962cdd76473jailletcstatic apr_status_t reset(proxy_balancer *balancer, server_rec *s)
19f5359fc7b955a110e5ebe345ef4962cdd76473jailletcstatic apr_status_t age(proxy_balancer *balancer, server_rec *s)
b5d34bc3082c1164ce20df48567d192e3e9f229fjim "heartbeat",
2806775e45dfd5164d53fcb3d850d358f8ec2415jfclerestatic int lb_hb_init(apr_pool_t *p, apr_pool_t *plog,
dc75ae85aef46bf3df41b96a4509ab19c07fe20cjim lb_hb_ctx_t *ctx = ap_get_module_config(s->module_config,
59d316b83d42d2a07e25c20d8c35a07b369618bdsf /* do nothing on first call */
59d316b83d42d2a07e25c20d8c35a07b369618bdsf if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG)
e8a023c6d3ea9f0faa895cbc7bdd649efb8a01d6sf storage = ap_lookup_provider(AP_SLOTMEM_PROVIDER_GROUP, "shm",
5400544d62947907986d570435dd16f02ca824e0sf ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, APLOGNO(02281)
e8a023c6d3ea9f0faa895cbc7bdd649efb8a01d6sf "Failed to lookup provider 'shm' for '%s'. Maybe you "
e8a023c6d3ea9f0faa895cbc7bdd649efb8a01d6sf "need to load mod_slotmem_shm?",
2806775e45dfd5164d53fcb3d850d358f8ec2415jfclere /* Try to use a slotmem created by mod_heartmonitor */
2806775e45dfd5164d53fcb3d850d358f8ec2415jfclere storage->attach(&hm_serversmem, "mod_heartmonitor", &size, &num, p);
5400544d62947907986d570435dd16f02ca824e0sf ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, APLOGNO(02282)
5a493ffe535de283863dcaa6756b00e5324e5f61sf "No slotmem from mod_heartmonitor");
5400544d62947907986d570435dd16f02ca824e0sf ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, APLOGNO(02283)
5a493ffe535de283863dcaa6756b00e5324e5f61sf "Using slotmem from mod_heartmonitor");
2806775e45dfd5164d53fcb3d850d358f8ec2415jfclere static const char * const aszPred[]={ "mod_heartmonitor.c", NULL };
b5d34bc3082c1164ce20df48567d192e3e9f229fjim ap_register_provider(p, PROXY_LBMETHOD, "heartbeat", "0", &heartbeat);
2806775e45dfd5164d53fcb3d850d358f8ec2415jfclere ap_hook_post_config(lb_hb_init, aszPred, NULL, APR_HOOK_MIDDLE);
b5d34bc3082c1164ce20df48567d192e3e9f229fjimstatic void *lb_hb_create_config(apr_pool_t *p, server_rec *s)
b5d34bc3082c1164ce20df48567d192e3e9f229fjim lb_hb_ctx_t *ctx = (lb_hb_ctx_t *) apr_palloc(p, sizeof(lb_hb_ctx_t));
9b778cf6122bc2ecd5704aaec99ee22f95764e62trawick ctx->path = ap_runtime_dir_relative(p, DEFAULT_HEARTBEAT_STORAGE);
b5d34bc3082c1164ce20df48567d192e3e9f229fjimstatic void *lb_hb_merge_config(apr_pool_t *p, void *basev, void *overridesv)
b5d34bc3082c1164ce20df48567d192e3e9f229fjim (lb_hb_ctx_t *) ap_get_module_config(cmd->server->module_config,
b5d34bc3082c1164ce20df48567d192e3e9f229fjim const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
b5d34bc3082c1164ce20df48567d192e3e9f229fjim AP_INIT_TAKE1("HeartbeatStorage", cmd_lb_hb_storage, NULL, RSRC_CONF,
b5d34bc3082c1164ce20df48567d192e3e9f229fjim "Path to read heartbeat data."),
b5d34bc3082c1164ce20df48567d192e3e9f229fjim lb_hb_create_config, /* create per-server config structure */
b5d34bc3082c1164ce20df48567d192e3e9f229fjim lb_hb_merge_config, /* merge per-server config structures */