Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=efac52762b1e3fe3035d29e82d8ee1aebc45e4a7
Commit:     efac52762b1e3fe3035d29e82d8ee1aebc45e4a7
Parent:     1e356f9cdfa885c78791d5d6e5d2baef22f01853
Author:     Rumen G. Bogdanovski <[EMAIL PROTECTED]>
AuthorDate: Wed Nov 7 02:36:55 2007 -0800
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Wed Nov 7 04:15:10 2007 -0800

    [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 <[EMAIL PROTECTED]>
    Signed-off-by: Simon Horman <[EMAIL PROTECTED]>
    Signed-off-by: David S. Miller <[EMAIL PROTECTED]>
---
 include/net/ip_vs.h        |    4 ++++
 net/ipv4/ipvs/ip_vs_core.c |   20 ++++++++++++++------
 net/ipv4/ipvs/ip_vs_sync.c |    2 +-
 3 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index 1fd1ee8..67ea2c0 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -520,6 +520,10 @@ struct ip_vs_conn {
        spinlock_t              lock;           /* lock for state transition */
        volatile __u16          flags;          /* status flags */
        volatile __u16          state;          /* state info */
+       volatile __u16          old_state;      /* old state, to be used for
+                                                * state transition triggerd
+                                                * synchronization
+                                                */
 
        /* Control members */
        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 c6ed765..20c884a 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,
                ret = NF_ACCEPT;
        }
 
-       /* increase its packet counter and check if it is needed
-          to be synchronized */
+       /* Increase its packet counter and check if it is needed
+        * to be synchronized
+        *
+        * Sync connection if it is about to close to
+        * encorage the standby servers to update the connections timeout
+        */
        atomic_inc(&cp->in_pkts);
        if ((ip_vs_sync_state & IP_VS_STATE_MASTER) &&
-           (cp->protocol != IPPROTO_TCP ||
-            cp->state == IP_VS_TCP_S_ESTABLISHED) &&
-           (atomic_read(&cp->in_pkts) % sysctl_ip_vs_sync_threshold[1]
-            == sysctl_ip_vs_sync_threshold[0]))
+           (((cp->protocol != IPPROTO_TCP ||
+              cp->state == IP_VS_TCP_S_ESTABLISHED) &&
+             (atomic_read(&cp->in_pkts) % sysctl_ip_vs_sync_threshold[1]
+              == sysctl_ip_vs_sync_threshold[0])) ||
+            ((cp->protocol == IPPROTO_TCP) && (cp->old_state != cp->state) &&
+             ((cp->state == IP_VS_TCP_S_FIN_WAIT) ||
+              (cp->state == IP_VS_TCP_S_CLOSE)))))
                ip_vs_sync_conn(cp);
+       cp->old_state = cp->state;
 
        ip_vs_conn_put(cp);
        return ret;
diff --git a/net/ipv4/ipvs/ip_vs_sync.c b/net/ipv4/ipvs/ip_vs_sync.c
index b1694d6..bd930ef 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)
                        if (!dest) {
                                /* it is an unbound entry created by
                                 * synchronization */
-                               cp->state = ntohs(s->state);
                                cp->flags = flags | IP_VS_CONN_F_HASHED;
                        } else
                                atomic_dec(&dest->refcnt);
@@ -358,6 +357,7 @@ static void ip_vs_process_message(const char *buffer, const 
size_t buflen)
                        p += SIMPLE_CONN_SIZE;
 
                atomic_set(&cp->in_pkts, sysctl_ip_vs_sync_threshold[0]);
+               cp->state = ntohs(s->state);
                pp = ip_vs_proto_get(s->protocol);
                cp->timeout = pp->timeout_table[cp->state];
                ip_vs_conn_put(cp);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to