aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRumen G. Bogdanovski <rumen@voicecho.com>2007-11-07 05:36:55 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2007-11-07 07:15:10 -0500
commitefac52762b1e3fe3035d29e82d8ee1aebc45e4a7 (patch)
tree3979958b12d4a3b326b657f52f960f013c6cb560
parent1e356f9cdfa885c78791d5d6e5d2baef22f01853 (diff)
[IPVS]: Synchronize closing of Connections
This patch makes the master daemon to sync the connection when it is about to close. This makes the connections on the backup to close or timeout according their state. Before the sync was performed only if the connection is in ESTABLISHED state which always made the connections to timeout in the hard coded 3 minutes. However the Andy Gospodarek's patch ([IPVS]: use proper timeout instead of fixed value) effectively did nothing more than increasing this to 15 minutes (Established state timeout). So this patch makes use of proper timeout since it syncs the connections on status changes to FIN_WAIT (2min timeout) and CLOSE (10sec timeout). However if the backup misses CLOSE hopefully it did not miss FIN_WAIT. Otherwise we will just have to wait for the ESTABLISHED state timeout. As it is without this patch. This way the number of the hanging connections on the backup is kept to minimum. And very few of them will be left to timeout with a long timeout. This is important if we want to make use of the fix for the real server overcommit on master/backup fail-over. Signed-off-by: Rumen G. Bogdanovski <rumen@voicecho.com> Signed-off-by: Simon Horman <horms@verge.net.au> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/ip_vs.h4
-rw-r--r--net/ipv4/ipvs/ip_vs_core.c20
-rw-r--r--net/ipv4/ipvs/ip_vs_sync.c2
3 files changed, 19 insertions, 7 deletions
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index 1fd1ee896f39..67ea2c0c0ab7 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -520,6 +520,10 @@ struct ip_vs_conn {
520 spinlock_t lock; /* lock for state transition */ 520 spinlock_t lock; /* lock for state transition */
521 volatile __u16 flags; /* status flags */ 521 volatile __u16 flags; /* status flags */
522 volatile __u16 state; /* state info */ 522 volatile __u16 state; /* state info */
523 volatile __u16 old_state; /* old state, to be used for
524 * state transition triggerd
525 * synchronization
526 */
523 527
524 /* Control members */ 528 /* Control members */
525 struct ip_vs_conn *control; /* Master control connection */ 529 struct ip_vs_conn *control; /* Master control connection */
diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c
index c6ed7654e839..20c884a57721 100644
--- a/net/ipv4/ipvs/ip_vs_core.c
+++ b/net/ipv4/ipvs/ip_vs_core.c
@@ -979,15 +979,23 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb,
979 ret = NF_ACCEPT; 979 ret = NF_ACCEPT;
980 } 980 }
981 981
982 /* increase its packet counter and check if it is needed 982 /* Increase its packet counter and check if it is needed
983 to be synchronized */ 983 * to be synchronized
984 *
985 * Sync connection if it is about to close to
986 * encorage the standby servers to update the connections timeout
987 */
984 atomic_inc(&cp->in_pkts); 988 atomic_inc(&cp->in_pkts);
985 if ((ip_vs_sync_state & IP_VS_STATE_MASTER) && 989 if ((ip_vs_sync_state & IP_VS_STATE_MASTER) &&
986 (cp->protocol != IPPROTO_TCP || 990 (((cp->protocol != IPPROTO_TCP ||
987 cp->state == IP_VS_TCP_S_ESTABLISHED) && 991 cp->state == IP_VS_TCP_S_ESTABLISHED) &&
988 (atomic_read(&cp->in_pkts) % sysctl_ip_vs_sync_threshold[1] 992 (atomic_read(&cp->in_pkts) % sysctl_ip_vs_sync_threshold[1]
989 == sysctl_ip_vs_sync_threshold[0])) 993 == sysctl_ip_vs_sync_threshold[0])) ||
994 ((cp->protocol == IPPROTO_TCP) && (cp->old_state != cp->state) &&
995 ((cp->state == IP_VS_TCP_S_FIN_WAIT) ||
996 (cp->state == IP_VS_TCP_S_CLOSE)))))
990 ip_vs_sync_conn(cp); 997 ip_vs_sync_conn(cp);
998 cp->old_state = cp->state;
991 999
992 ip_vs_conn_put(cp); 1000 ip_vs_conn_put(cp);
993 return ret; 1001 return ret;
diff --git a/net/ipv4/ipvs/ip_vs_sync.c b/net/ipv4/ipvs/ip_vs_sync.c
index b1694d67abb9..bd930efc18da 100644
--- a/net/ipv4/ipvs/ip_vs_sync.c
+++ b/net/ipv4/ipvs/ip_vs_sync.c
@@ -343,7 +343,6 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
343 if (!dest) { 343 if (!dest) {
344 /* it is an unbound entry created by 344 /* it is an unbound entry created by
345 * synchronization */ 345 * synchronization */
346 cp->state = ntohs(s->state);
347 cp->flags = flags | IP_VS_CONN_F_HASHED; 346 cp->flags = flags | IP_VS_CONN_F_HASHED;
348 } else 347 } else
349 atomic_dec(&dest->refcnt); 348 atomic_dec(&dest->refcnt);
@@ -358,6 +357,7 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
358 p += SIMPLE_CONN_SIZE; 357 p += SIMPLE_CONN_SIZE;
359 358
360 atomic_set(&cp->in_pkts, sysctl_ip_vs_sync_threshold[0]); 359 atomic_set(&cp->in_pkts, sysctl_ip_vs_sync_threshold[0]);
360 cp->state = ntohs(s->state);
361 pp = ip_vs_proto_get(s->protocol); 361 pp = ip_vs_proto_get(s->protocol);
362 cp->timeout = pp->timeout_table[cp->state]; 362 cp->timeout = pp->timeout_table[cp->state];
363 ip_vs_conn_put(cp); 363 ip_vs_conn_put(cp);