Skip to content

Commit 95fae21

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 95fae21

File tree

1 file changed

+182
-1
lines changed

1 file changed

+182
-1
lines changed

tools/keepalived/keepalived/check/ipwrapper.c

Lines changed: 182 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,185 @@ 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 addr_ip list */
220+
l = vsg->addr_ip;
221+
for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
222+
vsg_entry = ELEMENT_DATA(e);
223+
ret |= vs_addr_cmp(addr, &vsg_entry->addr);
224+
}
225+
226+
/* visit range list */
227+
l = vsg->addr_range;
228+
for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
229+
vsg_entry = ELEMENT_DATA(e);
230+
ret |= __vs_group_rang_addr_cmp(addr, vsg_entry);
231+
}
232+
233+
return ret;
234+
}
235+
236+
static int __vs_group_rang_cmp(virtual_server_group_entry_t *vsg_entry,
237+
virtual_server_group_t *vsg)
238+
{
239+
uint32_t addr_ip, ip;
240+
struct sockaddr_storage vip_addr;
241+
int ret = 0;
242+
243+
vip_addr = vsg_entry->addr;
244+
if (vsg_entry->addr.ss_family == AF_INET6) {
245+
//inet_sockaddrip6(&vsg_entry->addr, &addr.in6);
246+
ip = ((struct sockaddr_in6*)&vip_addr)->sin6_addr.s6_addr32[3];
247+
} else {
248+
ip = ((struct sockaddr_in*)&vip_addr)->sin_addr.s_addr;
249+
}
250+
251+
/* Parse the whole range */
252+
for (addr_ip = ip;
253+
((addr_ip >> 24) & 0xFF) <= vsg_entry->range;
254+
addr_ip += 0x01000000) {
255+
if (vsg_entry->addr.ss_family == AF_INET6) {
256+
((struct sockaddr_in6*)&vip_addr)->sin6_addr.s6_addr32[3] = addr_ip;
257+
} else {
258+
((struct sockaddr_in*)&vip_addr)->sin_addr.s_addr = addr_ip;
259+
}
260+
ret |= __vs_group_addr_cmp(&vip_addr, vsg);
261+
}
262+
return ret;
263+
}
264+
265+
static int vs_group_addr_cmp(virtual_server_t *vs_a, virtual_server_t *vs_b)
266+
{
267+
virtual_server_group_t *vsg_a = ipvs_get_group_by_name(vs_a->vsgname, check_data->vs_group);
268+
virtual_server_group_t *vsg_b = ipvs_get_group_by_name(vs_b->vsgname, check_data->vs_group);
269+
virtual_server_group_entry_t *vsg_entry;
270+
list l;
271+
element e;
272+
int ret = 0;
273+
274+
if (vsg_a == NULL || vsg_b == NULL)
275+
return 0;
276+
277+
if (vsg_a == vsg_b)
278+
return 1;
279+
280+
/* visit addr_ip list */
281+
l = vsg_a->addr_ip;
282+
for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
283+
vsg_entry = ELEMENT_DATA(e);
284+
ret |= __vs_group_addr_cmp(&vsg_entry->addr, vsg_b);
285+
}
286+
287+
/* visit range list */
288+
l = vsg_a->addr_range;
289+
for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
290+
vsg_entry = ELEMENT_DATA(e);
291+
ret |= __vs_group_rang_cmp(vsg_entry, vsg_b);
292+
}
293+
294+
return ret;
295+
}
296+
297+
static int all_vs_quorum_down(virtual_server_t *var_vs)
298+
{
299+
element e;
300+
virtual_server_t *tmp_vs = NULL;
301+
virtual_server_group_t *vsg = NULL;
302+
list l;
303+
int ret = 0;
304+
305+
if (NULL == check_data) {
306+
return 1;
307+
}
308+
309+
l = check_data->vs;
310+
311+
if (LIST_ISEMPTY(l)) {
312+
return 1;
313+
}
314+
315+
for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
316+
tmp_vs = ELEMENT_DATA(e);
317+
if (false == tmp_vs->quorum_state_up)
318+
continue;
319+
320+
if (var_vs->vsgname && tmp_vs->vsgname) {
321+
ret = vs_group_addr_cmp(var_vs, tmp_vs);
322+
} else if (var_vs->vsgname && NULL == tmp_vs->vsgname) {
323+
vsg = ipvs_get_group_by_name(var_vs->vsgname, check_data->vs_group);
324+
ret = __vs_group_addr_cmp(&tmp_vs->addr, vsg);
325+
} else if (NULL == var_vs->vsgname && tmp_vs->vsgname) {
326+
vsg = ipvs_get_group_by_name(tmp_vs->vsgname, check_data->vs_group);
327+
ret = __vs_group_addr_cmp(&var_vs->addr, vsg);
328+
} else {
329+
ret = vs_addr_cmp(&var_vs->addr, &tmp_vs->addr);
330+
}
331+
332+
if (ret) {
333+
log_message(LOG_INFO, "VS [%s] have the same vip with VS [%s], and the quorum_state is UP",
334+
(tmp_vs->vsgname) ? tmp_vs->vsgname : FMT_VS(tmp_vs)
335+
,(var_vs->vsgname) ? var_vs->vsgname : FMT_VS(var_vs));
336+
return 0;
337+
}
338+
}
339+
return 1;
340+
}
341+
163342
static void
164343
do_vs_notifies(virtual_server_t* vs, bool init, long threshold, long weight_sum, bool stopping)
165344
{
@@ -177,8 +356,10 @@ do_vs_notifies(virtual_server_t* vs, bool init, long threshold, long weight_sum,
177356
if (notify_script) {
178357
if (stopping)
179358
system_call_script(master, child_killed_thread, NULL, TIMER_HZ, notify_script);
180-
else
359+
else if (vs->quorum_state_up || ((!vs->quorum_state_up) && all_vs_quorum_down(vs))) {
360+
log_message(LOG_INFO, "Execute script: %s.", cmd_str(notify_script));
181361
notify_exec(notify_script);
362+
}
182363
}
183364

184365
notify_fifo_vs(vs);

0 commit comments

Comments
 (0)