Apache HTTPD
mod_heartbeat.c
Go to the documentation of this file.
1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "httpd.h"
18#include "http_config.h"
19#include "http_log.h"
20#include "apr_strings.h"
21
22#include "ap_mpm.h"
23#include "scoreboard.h"
24#include "mod_watchdog.h"
25
26#ifndef HEARTBEAT_INTERVAL
27#define HEARTBEAT_INTERVAL (1)
28#endif
29
30module AP_MODULE_DECLARE_DATA heartbeat_module;
31
40
41static const char *msg_format = "v=%u&ready=%u&busy=%u";
42
43#define MSG_VERSION (1)
44
46{
49 char buf[256];
50 int i, j;
51 apr_uint32_t ready = 0;
52 apr_uint32_t busy = 0;
54
56
57 for (i = 0; i < ctx->server_limit; i++) {
60
61 for (j = 0; j < ctx->thread_limit; j++) {
62 int res;
63
65
67
68 res = ws->status;
69
70 if (res == SERVER_READY && ps->generation == mpm_generation) {
71 ready++;
72 }
73 else if (res != SERVER_DEAD &&
75 ps->generation == mpm_generation) {
76 busy++;
77 }
78 }
79 }
80
81 len = apr_snprintf(buf, sizeof(buf), msg_format, MSG_VERSION, ready, busy);
82
83 do {
84 apr_status_t rv;
85 rv = apr_socket_create(&sock, ctx->mcast_addr->family,
87 if (rv) {
89 NULL, APLOGNO(02097) "Heartbeat: apr_socket_create failed");
90 break;
91 }
92
93 rv = apr_mcast_loopback(sock, 1);
94 if (rv) {
96 NULL, APLOGNO(02098) "Heartbeat: apr_mcast_loopback failed");
97 break;
98 }
99
100 rv = apr_socket_sendto(sock, ctx->mcast_addr, 0, buf, &len);
101 if (rv) {
103 NULL, APLOGNO(02099) "Heartbeat: apr_socket_sendto failed");
104 break;
105 }
106 } while (0);
107
108 if (sock) {
110 }
111
112 return OK;
113}
114
115static int hb_watchdog_init(server_rec *s, const char *name, apr_pool_t *pool)
116{
117 hb_ctx_t *ctx = ap_get_module_config(s->module_config, &heartbeat_module);
118
121
122 return OK;
123}
124
125static int hb_watchdog_exit(server_rec *s, const char *name, apr_pool_t *pool)
126{
127 return OK;
128}
129
130static int hb_watchdog_step(server_rec *s, const char *name, apr_pool_t *pool)
131{
132 hb_ctx_t *ctx = ap_get_module_config(s->module_config, &heartbeat_module);
133
134 if (!ctx->active || strcmp(name, AP_WATCHDOG_SINGLETON)) {
135 return OK;
136 }
137 return hb_monitor(ctx, pool);
138}
139
140static int hb_watchdog_need(server_rec *s, const char *name,
141 int parent, int singleton)
142{
143 hb_ctx_t *ctx = ap_get_module_config(s->module_config, &heartbeat_module);
144
145 if (ctx->active && singleton && !strcmp(name, AP_WATCHDOG_SINGLETON))
146 return OK;
147 else
148 return DECLINED;
149}
150
158
160{
161 hb_ctx_t *cfg = (hb_ctx_t *) apr_pcalloc(p, sizeof(hb_ctx_t));
162
163 return cfg;
164}
165
166static const char *cmd_hb_address(cmd_parms *cmd,
167 void *dconf, const char *addr)
168{
169 apr_status_t rv;
170 char *host_str;
171 char *scope_id;
172 apr_port_t port = 0;
173 apr_pool_t *p = cmd->pool;
174 hb_ctx_t *ctx =
175 (hb_ctx_t *) ap_get_module_config(cmd->server->module_config,
176 &heartbeat_module);
177 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
178
179 if (err != NULL) {
180 return err;
181 }
182
183 if (!ctx->active) {
184 ctx->active = 1;
185 }
186 else {
187 return "HeartbeatAddress: May only be specified once.";
188 }
189
190 rv = apr_parse_addr_port(&host_str, &scope_id, &port, addr, cmd->temp_pool);
191
192 if (rv) {
193 return "HeartbeatAddress: Unable to parse address.";
194 }
195
196 if (host_str == NULL) {
197 return "HeartbeatAddress: No host provided in address";
198 }
199
200 if (port == 0) {
201 return "HeartbeatAddress: No port provided in address";
202 }
203
204 rv = apr_sockaddr_info_get(&ctx->mcast_addr, host_str, APR_INET, port, 0,
205 p);
206
207 if (rv) {
208 return "HeartbeatAddress: apr_sockaddr_info_get failed.";
209 }
210
211 return NULL;
212}
213
214static const command_rec hb_cmds[] = {
215 AP_INIT_TAKE1("HeartbeatAddress", cmd_hb_address, NULL, RSRC_CONF,
216 "Address to send heartbeat requests"),
217 {NULL}
218};
219
222 NULL, /* create per-directory config structure */
223 NULL, /* merge per-directory config structures */
224 hb_create_config, /* create per-server config structure */
225 NULL, /* merge per-server config structures */
226 hb_cmds, /* command apr_table_t */
228};
Apache Multi-Processing Module library.
const char apr_size_t len
Definition ap_regex.h:187
APR Strings library.
#define AP_INIT_TAKE1(directive, func, mconfig, where, help)
#define ap_get_module_config(v, m)
#define AP_DECLARE_MODULE(foo)
const char server_rec server_rec ** ps
#define DECLINED
Definition httpd.h:457
#define OK
Definition httpd.h:456
#define APLOGNO(n)
Definition http_log.h:117
#define ap_log_error
Definition http_log.h:370
#define APLOG_MARK
Definition http_log.h:283
#define APLOG_WARNING
Definition http_log.h:68
const unsigned char * buf
Definition util_md5.h:50
const char apr_port_t port
Definition http_vhost.h:125
apr_brigade_flush void * ctx
apr_pool_t apr_dbd_t apr_dbd_results_t ** res
Definition apr_dbd.h:287
#define APR_HOOK_MIDDLE
Definition apr_hooks.h:303
#define RSRC_CONF
#define APR_PROTO_UDP
void ap_hook_watchdog_exit(ap_HOOK_watchdog_exit_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
void ap_hook_watchdog_step(ap_HOOK_watchdog_step_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
void ap_hook_watchdog_need(ap_HOOK_watchdog_need_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
#define AP_WATCHDOG_SINGLETON
void ap_hook_watchdog_init(ap_HOOK_watchdog_init_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
#define STANDARD20_MODULE_STUFF
#define GLOBAL_ONLY
const char * ap_check_cmd_context(cmd_parms *cmd, unsigned forbidden)
Definition core.c:1301
apr_size_t size
const char int apr_pool_t * pool
Definition apr_cstr.h:84
int apr_status_t
Definition apr_errno.h:44
apr_sockaddr_t * addr
apr_socket_t * sock
apr_uint16_t apr_port_t
#define APR_INET
char ** scope_id
apr_pool_t * parent
Definition apr_pools.h:197
#define apr_pcalloc(p, size)
Definition apr_pools.h:465
const char * s
Definition apr_strings.h:95
apr_int32_t apr_int32_t apr_int32_t err
apr_cmdtype_e cmd
apr_status_t ap_mpm_query(int query_code, int *result)
Definition mpm_common.c:421
#define AP_MPMQ_HARD_LIMIT_THREADS
Definition ap_mpm.h:158
#define AP_MPMQ_GENERATION
Definition ap_mpm.h:178
#define AP_MPMQ_HARD_LIMIT_DAEMONS
Definition ap_mpm.h:156
Apache Configuration.
Apache Logging library.
HTTP Daemon routines.
apr_pool_t * p
Definition md_event.c:32
static void * hb_create_config(apr_pool_t *p, server_rec *s)
static const command_rec hb_cmds[]
static int hb_watchdog_init(server_rec *s, const char *name, apr_pool_t *pool)
static int hb_monitor(hb_ctx_t *ctx, apr_pool_t *p)
static void hb_register_hooks(apr_pool_t *p)
static const char * cmd_hb_address(cmd_parms *cmd, void *dconf, const char *addr)
#define MSG_VERSION
static int hb_watchdog_step(server_rec *s, const char *name, apr_pool_t *pool)
static int hb_watchdog_exit(server_rec *s, const char *name, apr_pool_t *pool)
static const char * msg_format
static int hb_watchdog_need(server_rec *s, const char *name, int parent, int singleton)
static const proxy_balancer_method heartbeat
return NULL
Definition mod_so.c:359
int i
Definition mod_so.c:347
Watchdog module for Apache.
Apache scoreboard library.
#define SERVER_STARTING
Definition scoreboard.h:57
int ap_generation_t
Definition scoreboard.h:78
scoreboard * ap_scoreboard_image
Definition scoreboard.c:44
#define SERVER_DEAD
Definition scoreboard.h:56
#define SERVER_IDLE_KILL
Definition scoreboard.h:66
#define SERVER_READY
Definition scoreboard.h:58
process_score * ap_get_scoreboard_process(int x)
Definition scoreboard.c:702
char * name
int server_limit
apr_status_t status
apr_sockaddr_t * mcast_addr
int thread_limit
worker_score ** servers
Definition scoreboard.h:163
A structure to store information for each virtual server.
Definition httpd.h:1322
apr_status_t apr_socket_sendto(apr_socket_t *sock, apr_sockaddr_t *where, apr_int32_t flags, const char *buf, apr_size_t *len)
Definition sendrecv.c:112
apr_status_t apr_socket_close(apr_socket_t *thesocket)
Definition sockets.c:211
apr_status_t apr_socket_create(apr_socket_t **new, int ofamily, int type, int protocol, apr_pool_t *cont)
Definition sockets.c:116