Skip to content

Commit 7e1e159

Browse files
author
weiyanhua
committed
different virutal-service may refer to the same address,when the address is operated by the script specified by quorum_own var, Add judgment of other virtual-service's quorum_state that refer the same address.
1 parent 6972a0a commit 7e1e159

File tree

1 file changed

+175
-1
lines changed

1 file changed

+175
-1
lines changed

tools/keepalived/keepalived/check/ipwrapper.c

+175-1
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,178 @@ notify_fifo_rs(virtual_server_t* vs, real_server_t* rs)
160160
FREE(line);
161161
}
162162

163+
static int vs_addr_cmp(struct sockaddr_storage *addr_a, struct sockaddr_storage *addr_b)
164+
{
165+
int ret = 0;
166+
167+
if (addr_a->ss_family != addr_b->ss_family)
168+
return 0;
169+
170+
if (addr_a->ss_family == AF_INET6) {
171+
ret = inaddr_equal(AF_INET6, &((struct sockaddr_in6 *)addr_a)->sin6_addr,
172+
&((struct sockaddr_in6 *)addr_b)->sin6_addr);
173+
} else {
174+
ret = inaddr_equal(AF_INET, &((struct sockaddr_in *)addr_a)->sin_addr,
175+
&((struct sockaddr_in *)addr_b)->sin_addr);
176+
}
177+
178+
return ret;
179+
}
180+
181+
static int __vs_group_rang_addr_cmp(struct sockaddr_storage *addr,
182+
virtual_server_group_entry_t *vsg_entry)
183+
{
184+
uint32_t addr_ip, ip;
185+
struct sockaddr_storage vip_addr;
186+
int ret = 0;
187+
188+
vip_addr = vsg_entry->addr;
189+
if (vsg_entry->addr.ss_family == AF_INET6) {
190+
//inet_sockaddrip6(&vsg_entry->addr, &addr.in6);
191+
ip = ((struct sockaddr_in6*)&vip_addr)->sin6_addr.s6_addr32[3];
192+
} else {
193+
ip = ((struct sockaddr_in*)&vip_addr)->sin_addr.s_addr;
194+
}
195+
196+
/* Parse the whole range */
197+
for (addr_ip = ip;
198+
((addr_ip >> 24) & 0xFF) <= vsg_entry->range;
199+
addr_ip += 0x01000000) {
200+
if (vsg_entry->addr.ss_family == AF_INET6) {
201+
((struct sockaddr_in6*)&vip_addr)->sin6_addr.s6_addr32[3] = addr_ip;
202+
} else {
203+
((struct sockaddr_in*)&vip_addr)->sin_addr.s_addr = addr_ip;
204+
}
205+
206+
ret |= vs_addr_cmp(addr, &vip_addr);
207+
}
208+
return ret;
209+
210+
}
211+
212+
static int __vs_group_addr_cmp(struct sockaddr_storage *addr, virtual_server_group_t *vsg)
213+
{
214+
virtual_server_group_entry_t *vsg_entry = NULL;
215+
list l;
216+
element e;
217+
int ret = 0;
218+
219+
/* visit range list */
220+
l = vsg->addr_range;
221+
for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
222+
vsg_entry = ELEMENT_DATA(e);
223+
ret |= __vs_group_rang_addr_cmp(addr, vsg_entry);
224+
}
225+
226+
return ret;
227+
}
228+
229+
static int __vs_group_rang_cmp(virtual_server_group_entry_t *vsg_entry,
230+
virtual_server_group_t *vsg)
231+
{
232+
uint32_t addr_ip, ip;
233+
struct sockaddr_storage vip_addr;
234+
int ret = 0;
235+
236+
vip_addr = vsg_entry->addr;
237+
if (vsg_entry->addr.ss_family == AF_INET6) {
238+
//inet_sockaddrip6(&vsg_entry->addr, &addr.in6);
239+
ip = ((struct sockaddr_in6*)&vip_addr)->sin6_addr.s6_addr32[3];
240+
} else {
241+
ip = ((struct sockaddr_in*)&vip_addr)->sin_addr.s_addr;
242+
}
243+
244+
/* Parse the whole range */
245+
for (addr_ip = ip;
246+
((addr_ip >> 24) & 0xFF) <= vsg_entry->range;
247+
addr_ip += 0x01000000) {
248+
if (vsg_entry->addr.ss_family == AF_INET6) {
249+
((struct sockaddr_in6*)&vip_addr)->sin6_addr.s6_addr32[3] = addr_ip;
250+
} else {
251+
((struct sockaddr_in*)&vip_addr)->sin_addr.s_addr = addr_ip;
252+
}
253+
ret |= __vs_group_addr_cmp(&vip_addr, vsg);
254+
}
255+
return ret;
256+
}
257+
258+
static int vs_group_addr_cmp(virtual_server_t *vs_a, virtual_server_t *vs_b)
259+
{
260+
virtual_server_group_t *vsg_a = ipvs_get_group_by_name(vs_a->vsgname, check_data->vs_group);
261+
virtual_server_group_t *vsg_b = ipvs_get_group_by_name(vs_b->vsgname, check_data->vs_group);
262+
virtual_server_group_entry_t *vsg_entry;
263+
list l;
264+
element e;
265+
int ret = 0;
266+
267+
if (vsg_a == NULL || vsg_b == NULL)
268+
return 0;
269+
270+
if (vsg_a == vsg_b)
271+
return 1;
272+
273+
/* visit addr_ip list */
274+
l = vsg_a->addr_ip;
275+
for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
276+
vsg_entry = ELEMENT_DATA(e);
277+
ret |= __vs_group_addr_cmp(&vsg_entry->addr, vsg_b);
278+
}
279+
280+
/* visit range list */
281+
l = vsg_a->addr_range;
282+
for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
283+
vsg_entry = ELEMENT_DATA(e);
284+
ret |= __vs_group_rang_cmp(vsg_entry, vsg_b);
285+
}
286+
287+
return ret;
288+
}
289+
290+
static int all_vs_quorum_down(virtual_server_t *var_vs)
291+
{
292+
element e;
293+
virtual_server_t *tmp_vs = NULL;
294+
virtual_server_group_t *vsg = NULL;
295+
list l;
296+
int ret = 0;
297+
298+
if (NULL == check_data) {
299+
return 1;
300+
}
301+
302+
l = check_data->vs;
303+
304+
if (LIST_ISEMPTY(l)) {
305+
return 1;
306+
}
307+
308+
for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
309+
tmp_vs = ELEMENT_DATA(e);
310+
if (false == tmp_vs->quorum_state_up)
311+
continue;
312+
313+
if (var_vs->vsgname && tmp_vs->vsgname) {
314+
ret = vs_group_addr_cmp(var_vs, tmp_vs);
315+
} else if (var_vs->vsgname && NULL == tmp_vs->vsgname) {
316+
vsg = ipvs_get_group_by_name(var_vs->vsgname, check_data->vs_group);
317+
ret = __vs_group_addr_cmp(&tmp_vs->addr, vsg);
318+
} else if (NULL == var_vs->vsgname && tmp_vs->vsgname) {
319+
vsg = ipvs_get_group_by_name(tmp_vs->vsgname, check_data->vs_group);
320+
ret = __vs_group_addr_cmp(&var_vs->addr, vsg);
321+
} else {
322+
ret = vs_addr_cmp(&var_vs->addr, &tmp_vs->addr);
323+
}
324+
325+
if (ret) {
326+
log_message(LOG_INFO, "VS [%s] have the same vip with VS [%s], and the quorum_state is UP",
327+
(tmp_vs->vsgname) ? tmp_vs->vsgname : FMT_VS(tmp_vs)
328+
,(var_vs->vsgname) ? var_vs->vsgname : FMT_VS(var_vs));
329+
return 0;
330+
}
331+
}
332+
return 1;
333+
}
334+
163335
static void
164336
do_vs_notifies(virtual_server_t* vs, bool init, long threshold, long weight_sum, bool stopping)
165337
{
@@ -177,8 +349,10 @@ do_vs_notifies(virtual_server_t* vs, bool init, long threshold, long weight_sum,
177349
if (notify_script) {
178350
if (stopping)
179351
system_call_script(master, child_killed_thread, NULL, TIMER_HZ, notify_script);
180-
else
352+
else if (vs->quorum_state_up || ((!vs->quorum_state_up) && all_vs_quorum_down(vs))) {
353+
log_message(LOG_INFO, "Execute script: %s.", cmd_str(notify_script));
181354
notify_exec(notify_script);
355+
}
182356
}
183357

184358
notify_fifo_vs(vs);

0 commit comments

Comments
 (0)