linux-2.6.11.7.oq/net/ipv4/ipvs/だけに発見: :w diff -ru linux-2.6.11.7/net/ipv4/ipvs/ip_vs_conn.c linux-2.6.11.7.oq/net/ipv4/ipvs/ip_vs_conn.c --- linux-2.6.11.7/net/ipv4/ipvs/ip_vs_conn.c 2005-04-08 03:58:28.000000000 +0900 +++ linux-2.6.11.7.oq/net/ipv4/ipvs/ip_vs_conn.c 2005-04-15 14:26:28.000000000 +0900 @@ -454,8 +454,9 @@ */ if ((dest == NULL) || !(dest->flags & IP_VS_DEST_F_AVAILABLE) || + (atomic_read(&dest->conn_flags) & IP_VS_CONN_F_OFFLINE) || (sysctl_ip_vs_expire_quiescent_template && - (atomic_read(&dest->weight) == 0))) { + (atomic_read(&dest->conn_flags) & IP_VS_CONN_F_QUIESCENT))) { IP_VS_DBG(9, "check_template: dest not available for " "protocol %s s:%u.%u.%u.%u:%d v:%u.%u.%u.%u:%d " "-> d:%u.%u.%u.%u:%d\n", diff -ru linux-2.6.11.7/net/ipv4/ipvs/ip_vs_core.c linux-2.6.11.7.oq/net/ipv4/ipvs/ip_vs_core.c --- linux-2.6.11.7/net/ipv4/ipvs/ip_vs_core.c 2005-04-08 03:57:08.000000000 +0900 +++ linux-2.6.11.7.oq/net/ipv4/ipvs/ip_vs_core.c 2005-04-15 14:26:51.000000000 +0900 @@ -1002,7 +1002,9 @@ IP_VS_DBG_PKT(11, pp, skb, 0, "Incoming packet"); /* Check the server status */ - if (cp->dest && !(cp->dest->flags & IP_VS_DEST_F_AVAILABLE)) { + if (cp->dest && (!(cp->dest->flags & IP_VS_DEST_F_AVAILABLE) || + (atomic_read(&cp->dest->conn_flags) & + IP_VS_CONN_F_OFFLINE))) { /* the destination server is not availabe */ if (sysctl_ip_vs_expire_nodest_conn) { diff -ru linux-2.6.11.7/net/ipv4/ipvs/ip_vs_ctl.c linux-2.6.11.7.oq/net/ipv4/ipvs/ip_vs_ctl.c --- linux-2.6.11.7/net/ipv4/ipvs/ip_vs_ctl.c 2005-04-08 03:58:28.000000000 +0900 +++ linux-2.6.11.7.oq/net/ipv4/ipvs/ip_vs_ctl.c 2005-04-14 18:52:29.000000000 +0900 @@ -667,8 +667,10 @@ int conn_flags; /* set the weight and the flags */ - atomic_set(&dest->weight, udest->weight); conn_flags = udest->conn_flags | IP_VS_CONN_F_INACTIVE; + atomic_set(&dest->weight, udest->weight); + if (!udest->weight) + conn_flags |= IP_VS_CONN_F_QUIESCENT; /* check if local node and update the flags */ if (inet_addr_type(udest->addr) == RTN_LOCAL) { diff -ru linux-2.6.11.7/net/ipv4/ipvs/ip_vs_dh.c linux-2.6.11.7.oq/net/ipv4/ipvs/ip_vs_dh.c --- linux-2.6.11.7/net/ipv4/ipvs/ip_vs_dh.c 2005-04-08 03:58:04.000000000 +0900 +++ linux-2.6.11.7.oq/net/ipv4/ipvs/ip_vs_dh.c 2005-04-15 14:30:58.000000000 +0900 @@ -23,7 +23,7 @@ * * n <- servernode[dest_ip]; * if (n is dead) OR - * (n is overloaded) OR (n.weight <= 0) then + * (n is overloaded) OR (n is unschedulable) then * return NULL; * * return n; @@ -210,7 +210,7 @@ dest = ip_vs_dh_get(tbl, iph->daddr); if (!dest || !(dest->flags & IP_VS_DEST_F_AVAILABLE) - || atomic_read(&dest->weight) <= 0 + || (atomic_read(&dest->conn_flags) & IP_VS_CONN_F_NOSCHED) || is_overloaded(dest)) { return NULL; } diff -ru linux-2.6.11.7/net/ipv4/ipvs/ip_vs_lblc.c linux-2.6.11.7.oq/net/ipv4/ipvs/ip_vs_lblc.c --- linux-2.6.11.7/net/ipv4/ipvs/ip_vs_lblc.c 2005-04-08 03:58:28.000000000 +0900 +++ linux-2.6.11.7.oq/net/ipv4/ipvs/ip_vs_lblc.c 2005-04-15 14:29:22.000000000 +0900 @@ -472,18 +472,17 @@ * h1/w1 > h2/w2 * if every weight is larger than zero. * - * The server with weight=0 is quiesced and will not receive any - * new connection. + * The server with conn_flags&IP_VS_CONN_F_NOSHED!=0 is not available + * to accept new connections. */ list_for_each_entry(dest, &svc->destinations, n_list) { - if (dest->flags & IP_VS_DEST_F_OVERLOAD) + if ((dest->flags & IP_VS_DEST_F_OVERLOAD) || + (atomic_read(&dest->conn_flags) & IP_VS_CONN_F_NOSCHED)) continue; - if (atomic_read(&dest->weight) > 0) { - least = dest; - loh = atomic_read(&least->activeconns) * 50 - + atomic_read(&least->inactconns); - goto nextstage; - } + least = dest; + loh = atomic_read(&least->activeconns) * 50 + + atomic_read(&least->inactconns); + goto nextstage; } return NULL; @@ -565,7 +564,7 @@ } else { dest = en->dest; if (!(dest->flags & IP_VS_DEST_F_AVAILABLE) - || atomic_read(&dest->weight) <= 0 + || (atomic_read(&dest->conn_flags) & IP_VS_CONN_F_NOSCHED) || is_overloaded(dest, svc)) { dest = __ip_vs_wlc_schedule(svc, iph); if (dest == NULL) { diff -ru linux-2.6.11.7/net/ipv4/ipvs/ip_vs_lblcr.c linux-2.6.11.7.oq/net/ipv4/ipvs/ip_vs_lblcr.c --- linux-2.6.11.7/net/ipv4/ipvs/ip_vs_lblcr.c 2005-04-08 03:58:03.000000000 +0900 +++ linux-2.6.11.7.oq/net/ipv4/ipvs/ip_vs_lblcr.c 2005-04-15 14:29:46.000000000 +0900 @@ -175,13 +175,13 @@ return NULL; read_lock(&set->lock); - /* select the first destination server, whose weight > 0 */ + /* select the first schedulable destination server */ for (e=set->list; e!=NULL; e=e->next) { least = e->dest; if (least->flags & IP_VS_DEST_F_OVERLOAD) continue; - if ((atomic_read(&least->weight) > 0) + if (! (atomic_read(&dest->conn_flags) & IP_VS_CONN_F_NOSCHED) && (least->flags & IP_VS_DEST_F_AVAILABLE)) { loh = atomic_read(&least->activeconns) * 50 + atomic_read(&least->inactconns); @@ -202,6 +202,7 @@ + atomic_read(&dest->inactconns); if ((loh * atomic_read(&dest->weight) > doh * atomic_read(&least->weight)) + && ! (atomic_read(&dest->conn_flags) & IP_VS_CONN_F_NOSCHED) && (dest->flags & IP_VS_DEST_F_AVAILABLE)) { least = dest; loh = doh; @@ -230,10 +231,10 @@ return NULL; read_lock(&set->lock); - /* select the first destination server, whose weight > 0 */ + /* select the first schedulable destination server */ for (e=set->list; e!=NULL; e=e->next) { most = e->dest; - if (atomic_read(&most->weight) > 0) { + if (! (atomic_read(&dest->conn_flags) & IP_VS_CONN_F_NOSCHED)) { moh = atomic_read(&most->activeconns) * 50 + atomic_read(&most->inactconns); goto nextstage; @@ -251,7 +252,8 @@ /* moh/mw < doh/dw ==> moh*dw < doh*mw, where mw,dw>0 */ if ((moh * atomic_read(&dest->weight) < doh * atomic_read(&most->weight)) - && (atomic_read(&dest->weight) > 0)) { + && (! (atomic_read(&dest->conn_flags) & + IP_VS_CONN_F_NOSCHED))) { most = dest; moh = doh; } @@ -725,19 +727,18 @@ * h1/w1 > h2/w2 * if every weight is larger than zero. * - * The server with weight=0 is quiesced and will not receive any - * new connection. + * The server with conn_flag&IP_VS_CONN_NOSHED!=0 is not available + * to accept new connections. */ list_for_each_entry(dest, &svc->destinations, n_list) { - if (dest->flags & IP_VS_DEST_F_OVERLOAD) + if ((dest->flags & IP_VS_DEST_F_OVERLOAD) || + (atomic_read(&dest->conn_flags) & IP_VS_CONN_F_NOSCHED)) continue; - if (atomic_read(&dest->weight) > 0) { - least = dest; - loh = atomic_read(&least->activeconns) * 50 - + atomic_read(&least->inactconns); - goto nextstage; - } + least = dest; + loh = atomic_read(&least->activeconns) * 50 + + atomic_read(&least->inactconns); + goto nextstage; } return NULL; diff -ru linux-2.6.11.7/net/ipv4/ipvs/ip_vs_sed.c linux-2.6.11.7.oq/net/ipv4/ipvs/ip_vs_sed.c --- linux-2.6.11.7/net/ipv4/ipvs/ip_vs_sed.c 2005-04-08 03:58:30.000000000 +0900 +++ linux-2.6.11.7.oq/net/ipv4/ipvs/ip_vs_sed.c 2005-04-15 14:36:19.000000000 +0900 @@ -95,13 +95,13 @@ * h1/w1 > h2/w2 * if every weight is larger than zero. * - * The server with weight=0 is quiesced and will not receive any - * new connections. + * If the server has conn_flag&IP_VS_CONN_F_NOSCHED!=0, then the + * server is not available to accept new connections. */ list_for_each_entry(dest, &svc->destinations, n_list) { if (!(dest->flags & IP_VS_DEST_F_OVERLOAD) && - atomic_read(&dest->weight) > 0) { + !(atomic_read(&dest->conn_flags) & IP_VS_CONN_F_NOSCHED)) { least = dest; loh = ip_vs_sed_dest_overhead(least); goto nextstage; diff -ru linux-2.6.11.7/net/ipv4/ipvs/ip_vs_sh.c linux-2.6.11.7.oq/net/ipv4/ipvs/ip_vs_sh.c --- linux-2.6.11.7/net/ipv4/ipvs/ip_vs_sh.c 2005-04-08 03:57:55.000000000 +0900 +++ linux-2.6.11.7.oq/net/ipv4/ipvs/ip_vs_sh.c 2005-04-15 14:31:49.000000000 +0900 @@ -20,7 +20,7 @@ * * n <- servernode[src_ip]; * if (n is dead) OR - * (n is overloaded) or (n.weight <= 0) then + * (n is overloaded) or (n is nosched) then * return NULL; * * return n; @@ -206,8 +206,8 @@ tbl = (struct ip_vs_sh_bucket *)svc->sched_data; dest = ip_vs_sh_get(tbl, iph->saddr); if (!dest + || (atomic_read(&dest->conn_flags) & IP_VS_CONN_F_NOSCHED) || !(dest->flags & IP_VS_DEST_F_AVAILABLE) - || atomic_read(&dest->weight) <= 0 || is_overloaded(dest)) { return NULL; } diff -ru linux-2.6.11.7/net/ipv4/ipvs/ip_vs_wlc.c linux-2.6.11.7.oq/net/ipv4/ipvs/ip_vs_wlc.c --- linux-2.6.11.7/net/ipv4/ipvs/ip_vs_wlc.c 2005-04-08 03:57:45.000000000 +0900 +++ linux-2.6.11.7.oq/net/ipv4/ipvs/ip_vs_wlc.c 2005-04-15 14:28:52.000000000 +0900 @@ -83,13 +83,14 @@ * h1/w1 > h2/w2 * if every weight is larger than zero. * - * The server with weight=0 is quiesced and will not receive any - * new connections. + * If the server has conn_flag&IP_VS_CONN_F_NOSHED!=0, + * then is is not available to accept new connections. */ list_for_each_entry(dest, &svc->destinations, n_list) { if (!(dest->flags & IP_VS_DEST_F_OVERLOAD) && - atomic_read(&dest->weight) > 0) { + !(atomic_read(&dest->conn_flags) & IP_VS_CONN_F_NOSCHED)) { + least = dest; loh = ip_vs_wlc_dest_overhead(least); goto nextstage; diff -ru linux-2.6.11.7/net/ipv4/ipvs/ip_vs_wrr.c linux-2.6.11.7.oq/net/ipv4/ipvs/ip_vs_wrr.c --- linux-2.6.11.7/net/ipv4/ipvs/ip_vs_wrr.c 2005-04-08 03:57:08.000000000 +0900 +++ linux-2.6.11.7.oq/net/ipv4/ipvs/ip_vs_wrr.c 2005-04-15 14:28:16.000000000 +0900 @@ -180,6 +180,8 @@ /* not at the head of the list */ dest = list_entry(mark->cl, struct ip_vs_dest, n_list); if (!(dest->flags & IP_VS_DEST_F_OVERLOAD) && + !(atomic_read(&dest->conn_flags) & + IP_VS_CONN_F_NOSCHED) && atomic_read(&dest->weight) >= mark->cw) { /* got it */ break; diff -ru linux-2.6.11.7/include/net/ip_vs.h linux-2.6.11.7.oq/include/net/ip_vs.h --- linux-2.6.11.7/include/net/ip_vs.h 2005-04-08 03:57:08.000000000 +0900 +++ linux-2.6.11.7.oq/include/net/ip_vs.h 2005-04-15 15:07:09.000000000 +0900 @@ -84,6 +84,15 @@ #define IP_VS_CONN_F_IN_SEQ 0x0400 /* must do input seq adjust */ #define IP_VS_CONN_F_SEQ_MASK 0x0600 /* in/out sequence mask */ #define IP_VS_CONN_F_NO_CPORT 0x0800 /* no client port set yet */ +#define IP_VS_CONN_F_OFFLINE 0x1000 /* server marked as offline + by admin. Takes precedence + over quiescent */ +#define IP_VS_CONN_F_QUIESCENT 0x2000 /* server marked as quiescent + by admin */ +#define IP_VS_CONN_F_NOSCHED 0x3000 /* server is not allowed to + accept new connections. + I.e is quiescent or + offline */ /* Move it to better place one day, for now keep it unique */ #define NFC_IPVS_PROPERTY 0x10000