@@ -160,6 +160,178 @@ notify_fifo_rs(virtual_server_t* vs, real_server_t* rs)
160
160
FREE (line );
161
161
}
162
162
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
+
163
335
static void
164
336
do_vs_notifies (virtual_server_t * vs , bool init , long threshold , long weight_sum , bool stopping )
165
337
{
@@ -177,8 +349,10 @@ do_vs_notifies(virtual_server_t* vs, bool init, long threshold, long weight_sum,
177
349
if (notify_script ) {
178
350
if (stopping )
179
351
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 ));
181
354
notify_exec (notify_script );
355
+ }
182
356
}
183
357
184
358
notify_fifo_vs (vs );
0 commit comments