@@ -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+
163342static void
164343do_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