LVS
lvs-users
Google
 
Web LinuxVirtualServer.org

[RFC][PATCH-2.4] per RS threshold limitation for ipvs-1.0.10

To: "LinuxVirtualServer.org users mailing list." <lvs-users@xxxxxxxxxxxxxxxxxxxxxx>
Subject: [RFC][PATCH-2.4] per RS threshold limitation for ipvs-1.0.10
From: Roberto Nibali <ratz@xxxxxxxxxxxx>
Date: Fri, 25 Jul 2003 17:16:50 +0200
Hi,

This is the second release of the per RS threshold limitation patch. With it you can set upper and lower thresholds for RS. Once the upper threshold is reached the RS is not served anymore until the amount of active + inactive connections drops below the lower threshold.

Please test and report.

Best regards,
Roberto Nibali, ratz
--
echo '[q]sa[ln0=aln256%Pln256/snlbx]sb3135071790101768542287578439snlbxq'|dc
Files ipvs-1.0.10-ratz/ipvs/core and 
ipvs-1.0.10-ratz-per_RS_threshold/ipvs/core differ
diff -Nur --exclude-from exclude-lvs ipvs-1.0.10-ratz/ipvs/ip_vs.h 
ipvs-1.0.10-ratz-per_RS_threshold/ipvs/ip_vs.h
--- ipvs-1.0.10-ratz/ipvs/ip_vs.h       2003-07-24 20:03:17.000000000 +0200
+++ ipvs-1.0.10-ratz-per_RS_threshold/ipvs/ip_vs.h      2003-07-24 
20:48:23.000000000 +0200
@@ -24,6 +24,7 @@
  *      Destination Server Flags
  */
 #define IP_VS_DEST_F_AVAILABLE        0x0001    /* Available tag */
+#define IP_VS_DEST_F_OVERLOAD         0x0002    /* server is overloaded */
 
 /*
  *      IPVS sync daemon states
@@ -113,6 +114,8 @@
        u_int16_t       dport;
        unsigned        conn_flags;     /* destination flags */
        int             weight;         /* destination weight */
+       u_int32_t       u_threshold;    /* upper threshold */
+       u_int32_t       l_threshold;    /* lower threshold */
 };
 
 
@@ -175,6 +178,9 @@
        int             weight;         /* destination weight */
        u_int32_t       activeconns;    /* active connections */
        u_int32_t       inactconns;     /* inactive connections */
+       u_int32_t       u_threshold;    /* upper threshold */
+       u_int32_t       l_threshold;    /* lower threshold */
+
 
        /* statistics */
        struct ip_vs_stats_user stats;
@@ -482,11 +488,15 @@
        unsigned                flags;    /* dest status flags */
        atomic_t                weight;   /* server weight */
        atomic_t                conn_flags;     /* flags to copy to conn */
-       atomic_t                activeconns;    /* active connections */
-       atomic_t                inactconns;     /* inactive connections */
        atomic_t                refcnt;         /* reference counter */
        struct ip_vs_stats      stats;          /* statistics */
 
+       /* connection counters and thresholds */
+       atomic_t                activeconns;    /* active connections */
+       atomic_t                inactconns;     /* inactive connections */
+       __u32                   u_threshold;    /* upper threshold */
+       __u32                   l_threshold;    /* lower threshold */
+
        /* for destination cache */
        spinlock_t              dst_lock;       /* lock dst_cache */
        struct dst_entry        *dst_cache;     /* destination cache entry */
@@ -938,6 +948,13 @@
        return 0;
 }
 
+/*
+ *     Server overloaded? 
+ */
+static inline int ip_vs_is_overloaded(struct ip_vs_dest *dest) {
+       return dest->flags & IP_VS_DEST_F_OVERLOAD;
+}
+
 #endif /* __KERNEL__ */
 
 #endif /* _IP_VS_H */
diff -Nur --exclude-from exclude-lvs ipvs-1.0.10-ratz/ipvs/ip_vs_conn.c 
ipvs-1.0.10-ratz-per_RS_threshold/ipvs/ip_vs_conn.c
--- ipvs-1.0.10-ratz/ipvs/ip_vs_conn.c  2003-07-19 08:01:45.000000000 +0200
+++ ipvs-1.0.10-ratz-per_RS_threshold/ipvs/ip_vs_conn.c 2003-07-24 
20:48:23.000000000 +0200
@@ -21,6 +21,7 @@
  * and others. Many code here is taken from IP MASQ code of kernel 2.2.
  *
  * Changes:
+ *     Roberto Nibali, ratz: backported per RS threshold limitation from 2.5.x
  *
  */
 
@@ -1043,6 +1044,11 @@
        }
 }
 
+static inline int ip_vs_dest_totalconns(struct ip_vs_dest *dest)
+{
+       return atomic_read(&dest->activeconns)
+               + atomic_read(&dest->inactconns);
+}
 
 /*
  *  Bind a connection entry with a virtual service destination
@@ -1071,6 +1077,9 @@
                  ip_vs_fwd_tag(cp), ip_vs_state_name(cp->state),
                  cp->flags, atomic_read(&cp->refcnt),
                  atomic_read(&dest->refcnt));
+       if (dest->u_threshold != 0 &&
+           ip_vs_dest_totalconns(dest) >= dest->u_threshold)
+               dest->flags |= IP_VS_DEST_F_OVERLOAD;
 }
 
 
@@ -1141,6 +1150,21 @@
                          NIPQUAD(ct->vaddr), ntohs(ct->vport),
                          NIPQUAD(ct->daddr), ntohs(ct->dport));
 
+               if (dest->l_threshold != 0) {
+                       if (ip_vs_dest_totalconns(dest) < dest->l_threshold) {
+                               dest->flags &= ~IP_VS_DEST_F_OVERLOAD;
+                       }
+               } else if (dest->u_threshold != 0) {
+                       /* I'm not so sure if this is a good idea. --ratz */
+                       if (ip_vs_dest_totalconns(dest) * 4 < dest->u_threshold 
* 3) {
+                               dest->flags &= ~IP_VS_DEST_F_OVERLOAD;
+                       }
+               } else {
+                       if (dest->flags & IP_VS_DEST_F_OVERLOAD) {
+                               dest->flags &= ~IP_VS_DEST_F_OVERLOAD;
+                       }
+               }
+
                /*
                 * Invalidate the connection template
                 */
diff -Nur --exclude-from exclude-lvs ipvs-1.0.10-ratz/ipvs/ip_vs_ctl.c 
ipvs-1.0.10-ratz-per_RS_threshold/ipvs/ip_vs_ctl.c
--- ipvs-1.0.10-ratz/ipvs/ip_vs_ctl.c   2003-07-19 08:01:45.000000000 +0200
+++ ipvs-1.0.10-ratz-per_RS_threshold/ipvs/ip_vs_ctl.c  2003-07-24 
20:48:23.000000000 +0200
@@ -17,6 +17,7 @@
  *              2 of the License, or (at your option) any later version.
  *
  * Changes:
+ *     Roberto Nibali, ratz: backported per RS threshold limitation from 2.5.x
  *
  */
 
@@ -700,6 +701,12 @@
 
        /* set the dest status flags */
        dest->flags |= IP_VS_DEST_F_AVAILABLE;
+
+       if (ur->u_threshold == 0 || ur->u_threshold > dest->u_threshold) {
+               dest->flags &= ~IP_VS_DEST_F_OVERLOAD;
+       }
+       dest->u_threshold = ur->u_threshold;
+       dest->l_threshold = ur->l_threshold;
 }
 
 
@@ -1896,6 +1903,8 @@
                        entry.port = dest->port;
                        entry.flags = atomic_read(&dest->conn_flags);
                        entry.weight = atomic_read(&dest->weight);
+                       entry.u_threshold = dest->u_threshold;
+                       entry.l_threshold = dest->l_threshold;
                        entry.activeconns = atomic_read(&dest->activeconns);
                        entry.inactconns = atomic_read(&dest->inactconns);
                        __ip_vs_copy_stats(&entry.stats, &dest->stats);
diff -Nur --exclude-from exclude-lvs ipvs-1.0.10-ratz/ipvs/ip_vs_dh.c 
ipvs-1.0.10-ratz-per_RS_threshold/ipvs/ip_vs_dh.c
--- ipvs-1.0.10-ratz/ipvs/ip_vs_dh.c    2001-10-19 17:05:17.000000000 +0200
+++ ipvs-1.0.10-ratz-per_RS_threshold/ipvs/ip_vs_dh.c   2003-07-24 
20:48:23.000000000 +0200
@@ -218,7 +218,8 @@
        if (!dest
            || !(dest->flags & IP_VS_DEST_F_AVAILABLE)
            || atomic_read(&dest->weight) <= 0
-           || is_overloaded(dest)) {
+           || is_overloaded(dest)
+           || ip_vs_is_overloaded(dest)) {
                return NULL;
        }
 
diff -Nur --exclude-from exclude-lvs ipvs-1.0.10-ratz/ipvs/ip_vs_lblc.c 
ipvs-1.0.10-ratz-per_RS_threshold/ipvs/ip_vs_lblc.c
--- ipvs-1.0.10-ratz/ipvs/ip_vs_lblc.c  2002-03-25 13:44:35.000000000 +0100
+++ ipvs-1.0.10-ratz-per_RS_threshold/ipvs/ip_vs_lblc.c 2003-07-24 
20:48:23.000000000 +0200
@@ -478,6 +478,8 @@
        l = &svc->destinations;
        for (e=l->next; e!=l; e=e->next) {
                least = list_entry(e, struct ip_vs_dest, n_list);
+               if (ip_vs_is_overloaded(least))
+                       continue;
                if (atomic_read(&least->weight) > 0) {
                        loh = atomic_read(&least->activeconns) * 50
                                + atomic_read(&least->inactconns);
@@ -492,6 +494,8 @@
   nextstage:
        for (e=e->next; e!=l; e=e->next) {
                dest = list_entry(e, struct ip_vs_dest, n_list);
+               if (ip_vs_is_overloaded(dest))
+                       continue;
                doh = atomic_read(&dest->activeconns) * 50
                        + atomic_read(&dest->inactconns);
                if (loh * atomic_read(&dest->weight) >
diff -Nur --exclude-from exclude-lvs ipvs-1.0.10-ratz/ipvs/ip_vs_lblcr.c 
ipvs-1.0.10-ratz-per_RS_threshold/ipvs/ip_vs_lblcr.c
--- ipvs-1.0.10-ratz/ipvs/ip_vs_lblcr.c 2002-03-25 13:44:35.000000000 +0100
+++ ipvs-1.0.10-ratz-per_RS_threshold/ipvs/ip_vs_lblcr.c        2003-07-24 
20:48:23.000000000 +0200
@@ -183,6 +183,8 @@
        /* select the first destination server, whose weight > 0 */
        for (e=set->list; e!=NULL; e=e->next) {
                least = e->dest;
+               if (ip_vs_is_overloaded(least))
+                       continue;
                if ((atomic_read(&least->weight) > 0)
                    && (least->flags & IP_VS_DEST_F_AVAILABLE)) {
                        loh = atomic_read(&least->activeconns) * 50
@@ -197,6 +199,8 @@
   nextstage:
        for (e=e->next; e!=NULL; e=e->next) {
                dest = e->dest;
+               if (ip_vs_is_overloaded(dest))
+                       continue;
                doh = atomic_read(&dest->activeconns) * 50
                        + atomic_read(&dest->inactconns);
                if ((loh * atomic_read(&dest->weight) >
@@ -728,6 +732,8 @@
        l = &svc->destinations;
        for (e=l->next; e!=l; e=e->next) {
                least = list_entry(e, struct ip_vs_dest, n_list);
+               if (ip_vs_is_overloaded(least))
+                       continue;
                if (atomic_read(&least->weight) > 0) {
                        loh = atomic_read(&least->activeconns) * 50
                                + atomic_read(&least->inactconns);
@@ -742,6 +748,8 @@
   nextstage:
        for (e=e->next; e!=l; e=e->next) {
                dest = list_entry(e, struct ip_vs_dest, n_list);
+               if (ip_vs_is_overloaded(dest))
+                       continue;
                doh = atomic_read(&dest->activeconns) * 50
                        + atomic_read(&dest->inactconns);
                if (loh * atomic_read(&dest->weight) >
diff -Nur --exclude-from exclude-lvs ipvs-1.0.10-ratz/ipvs/ip_vs_lc.c 
ipvs-1.0.10-ratz-per_RS_threshold/ipvs/ip_vs_lc.c
--- ipvs-1.0.10-ratz/ipvs/ip_vs_lc.c    2003-04-11 16:02:35.000000000 +0200
+++ ipvs-1.0.10-ratz-per_RS_threshold/ipvs/ip_vs_lc.c   2003-07-24 
20:48:23.000000000 +0200
@@ -84,6 +84,8 @@
        l = &svc->destinations;
        for (e=l->next; e!=l; e=e->next) {
                least = list_entry (e, struct ip_vs_dest, n_list);
+               if (ip_vs_is_overloaded(least))
+                       continue;
                if (atomic_read(&least->weight) > 0) {
                        loh = ip_vs_lc_dest_overhead(least);
                        goto nextstage;
@@ -97,7 +99,8 @@
   nextstage:
        for (e=e->next; e!=l; e=e->next) {
                dest = list_entry(e, struct ip_vs_dest, n_list);
-               if (atomic_read(&dest->weight) == 0)
+               if (ip_vs_is_overloaded(dest)
+                   || atomic_read(&dest->weight) == 0)
                        continue;
                doh = ip_vs_lc_dest_overhead(dest);
                if (doh < loh) {
diff -Nur --exclude-from exclude-lvs ipvs-1.0.10-ratz/ipvs/ip_vs_nq.c 
ipvs-1.0.10-ratz-per_RS_threshold/ipvs/ip_vs_nq.c
--- ipvs-1.0.10-ratz/ipvs/ip_vs_nq.c    2003-05-20 19:05:02.000000000 +0200
+++ ipvs-1.0.10-ratz-per_RS_threshold/ipvs/ip_vs_nq.c   2003-07-24 
20:48:23.000000000 +0200
@@ -104,6 +104,8 @@
        l = &svc->destinations;
        for (e=l->next; e!=l; e=e->next) {
                least = list_entry(e, struct ip_vs_dest, n_list);
+               if (ip_vs_is_overloaded(least))
+                       continue;
                if (atomic_read(&least->weight) > 0) {
                        loh = ip_vs_nq_dest_overhead(least);
 
@@ -122,6 +124,8 @@
   nextstage:
        for (e=e->next; e!=l; e=e->next) {
                dest = list_entry(e, struct ip_vs_dest, n_list);
+               if (ip_vs_is_overloaded(dest))
+                       continue;
                doh = ip_vs_nq_dest_overhead(dest);
 
                /* return the server directly if it is idle */
diff -Nur --exclude-from exclude-lvs ipvs-1.0.10-ratz/ipvs/ip_vs_rr.c 
ipvs-1.0.10-ratz-per_RS_threshold/ipvs/ip_vs_rr.c
--- ipvs-1.0.10-ratz/ipvs/ip_vs_rr.c    2001-10-19 17:05:17.000000000 +0200
+++ ipvs-1.0.10-ratz-per_RS_threshold/ipvs/ip_vs_rr.c   2003-07-24 
20:48:23.000000000 +0200
@@ -73,7 +73,8 @@
                        continue;
                }
                dest = list_entry(q, struct ip_vs_dest, n_list);
-               if (atomic_read(&dest->weight) > 0)
+               if (!ip_vs_is_overloaded(dest)
+                   && atomic_read(&dest->weight) > 0)
                        /* HIT */
                        goto out;
                q = q->next;
diff -Nur --exclude-from exclude-lvs ipvs-1.0.10-ratz/ipvs/ip_vs_sed.c 
ipvs-1.0.10-ratz-per_RS_threshold/ipvs/ip_vs_sed.c
--- ipvs-1.0.10-ratz/ipvs/ip_vs_sed.c   2003-05-20 19:05:02.000000000 +0200
+++ ipvs-1.0.10-ratz-per_RS_threshold/ipvs/ip_vs_sed.c  2003-07-24 
20:48:23.000000000 +0200
@@ -108,6 +108,8 @@
        l = &svc->destinations;
        for (e=l->next; e!=l; e=e->next) {
                least = list_entry(e, struct ip_vs_dest, n_list);
+               if (ip_vs_is_overloaded(least))
+                       continue;
                if (atomic_read(&least->weight) > 0) {
                        loh = ip_vs_sed_dest_overhead(least);
                        goto nextstage;
@@ -121,6 +123,8 @@
   nextstage:
        for (e=e->next; e!=l; e=e->next) {
                dest = list_entry(e, struct ip_vs_dest, n_list);
+               if (ip_vs_is_overloaded(dest))
+                       continue;
                doh = ip_vs_sed_dest_overhead(dest);
                if (loh * atomic_read(&dest->weight) >
                    doh * atomic_read(&least->weight)) {
diff -Nur --exclude-from exclude-lvs ipvs-1.0.10-ratz/ipvs/ip_vs_sh.c 
ipvs-1.0.10-ratz-per_RS_threshold/ipvs/ip_vs_sh.c
--- ipvs-1.0.10-ratz/ipvs/ip_vs_sh.c    2001-10-19 17:05:17.000000000 +0200
+++ ipvs-1.0.10-ratz-per_RS_threshold/ipvs/ip_vs_sh.c   2003-07-24 
20:48:23.000000000 +0200
@@ -215,7 +215,8 @@
        if (!dest
            || !(dest->flags & IP_VS_DEST_F_AVAILABLE)
            || atomic_read(&dest->weight) <= 0
-           || is_overloaded(dest)) {
+           || is_overloaded(dest)
+           || ip_vs_is_overloaded(dest)) {
                return NULL;
        }
 
diff -Nur --exclude-from exclude-lvs ipvs-1.0.10-ratz/ipvs/ip_vs_wlc.c 
ipvs-1.0.10-ratz-per_RS_threshold/ipvs/ip_vs_wlc.c
--- ipvs-1.0.10-ratz/ipvs/ip_vs_wlc.c   2003-04-11 16:02:35.000000000 +0200
+++ ipvs-1.0.10-ratz-per_RS_threshold/ipvs/ip_vs_wlc.c  2003-07-24 
20:48:23.000000000 +0200
@@ -96,6 +96,8 @@
        l = &svc->destinations;
        for (e=l->next; e!=l; e=e->next) {
                least = list_entry(e, struct ip_vs_dest, n_list);
+               if (ip_vs_is_overloaded(least))
+                       continue;
                if (atomic_read(&least->weight) > 0) {
                        loh = ip_vs_wlc_dest_overhead(least);
                        goto nextstage;
@@ -109,7 +111,8 @@
   nextstage:
        for (e=e->next; e!=l; e=e->next) {
                dest = list_entry(e, struct ip_vs_dest, n_list);
-
+               if (ip_vs_is_overloaded(dest))
+                       continue;
                doh = ip_vs_wlc_dest_overhead(dest);
                if (loh * atomic_read(&dest->weight) >
                    doh * atomic_read(&least->weight)) {
diff -Nur --exclude-from exclude-lvs ipvs-1.0.10-ratz/ipvs/ip_vs_wrr.c 
ipvs-1.0.10-ratz-per_RS_threshold/ipvs/ip_vs_wrr.c
--- ipvs-1.0.10-ratz/ipvs/ip_vs_wrr.c   2002-03-25 13:44:35.000000000 +0100
+++ ipvs-1.0.10-ratz-per_RS_threshold/ipvs/ip_vs_wrr.c  2003-07-24 
20:48:23.000000000 +0200
@@ -196,7 +196,8 @@
                if (mark->cl != &svc->destinations) {
                        /* not at the head of the list */
                        dest = list_entry(mark->cl, struct ip_vs_dest, n_list);
-                       if (atomic_read(&dest->weight) >= mark->cw) {
+                       if (!ip_vs_is_overloaded(dest)
+                           && atomic_read(&dest->weight) >= mark->cw) {
                                write_unlock(&svc->sched_lock);
                                break;
                        }
diff -Nur --exclude-from exclude-lvs ipvs-1.0.10-ratz/ipvs/ipvsadm/ipvsadm.c 
ipvs-1.0.10-ratz-per_RS_threshold/ipvs/ipvsadm/ipvsadm.c
--- ipvs-1.0.10-ratz/ipvs/ipvsadm/ipvsadm.c     2003-04-11 16:02:38.000000000 
+0200
+++ ipvs-1.0.10-ratz-per_RS_threshold/ipvs/ipvsadm/ipvsadm.c    2003-07-25 
07:52:20.000000000 +0200
@@ -52,6 +52,7 @@
  *        Horms               :   added -v option
  *        Wensong Zhang       :   rewrite most code of parsing options and
  *                                processing options.
+ *        Roberto Nibali, ratz:   Added support for threshold limitation
  *
  *
  *      ippfvsadm - Port Fowarding & Virtual Server ADMinistration program
@@ -168,7 +169,10 @@
 #define OPT_STATS      0x01000
 #define OPT_RATE       0x02000
 #define OPT_SORT       0x04000
-#define NUMBER_OF_OPT  15
+#define OPT_UTHRESHOLD  0x08000
+#define OPT_LTHRESHOLD  0x10000
+#define OPT_THRESHOLDS  0x20000
+#define NUMBER_OF_OPT  18
 
 static const char* optnames[] = {
        "numeric",
@@ -186,6 +190,9 @@
        "stats",
        "rate",
        "sort",
+       "u-threshold",
+       "l-threshold",
+       "thresholds",
 };
 
 /*
@@ -198,22 +205,22 @@
  */
 static const char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] =
 {
-       /*     -n   -c   svc  -s   -p   -M   -r   fwd  -w   -mc  -to  dmn  -st  
-rt  srt */
-/*INSERT*/    {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', 'x', 
'x', 'x', 'x'},
-/*ADD*/       {'x', 'x', '+', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 
'x', 'x', 'x'},
-/*EDIT*/      {'x', 'x', '+', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 
'x', 'x', 'x'},
-/*DEL*/       {'x', 'x', '+', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 
'x', 'x', 'x'},
-/*FLUSH*/     {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 
'x', 'x', 'x'},
-/*LIST*/      {' ', '1', '1', 'x', 'x', 'x', 'x', 'x', 'x', 'x', '1', '1', ' 
', ' ', ' '},
-/*ADD-SERVER*/{'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', 'x', 'x', 'x', 
'x', 'x', 'x'},
-/*DEL-SERVER*/{'x', 'x', '+', 'x', 'x', 'x', '+', 'x', 'x', 'x', 'x', 'x', 
'x', 'x', 'x'},
-/*EDIT-SRV*/  {'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', 'x', 'x', 'x', 
'x', 'x', 'x'},
-/*TIMEOUT*/   {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 
'x', 'x', 'x'},
-/*START-D*/   {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' ', 'x', 'x', 
'x', 'x', 'x'},
-/*STOP-D*/    {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 
'x', 'x', 'x'},
-/*RESTORE*/   {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 
'x', 'x', 'x'},
-/*SAVE*/      {' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 
'x', 'x', 'x'},
-/*ZERO*/      {'x', 'x', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 
'x', 'x', 'x'},
+       /*     -n   -c   svc  -s   -p   -M   -r   fwd  -w   -mc  -to  dmn  -st  
-rt  srt  -x   -y   thr */
+/*INSERT*/    {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', 'x', 
'x', 'x', 'x', 'x', 'x', 'x'},
+/*ADD*/       {'x', 'x', '+', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 
'x', 'x', 'x', 'x', 'x', 'x'},
+/*EDIT*/      {'x', 'x', '+', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 
'x', 'x', 'x', 'x', 'x', 'x'},
+/*DEL*/       {'x', 'x', '+', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 
'x', 'x', 'x', 'x', 'x', 'x'},
+/*FLUSH*/     {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 
'x', 'x', 'x', 'x', 'x', 'x'},
+/*LIST*/      {' ', '1', '1', 'x', 'x', 'x', 'x', 'x', 'x', 'x', '1', '1', ' 
', ' ', ' ', 'x', 'x', ' '},
+/*ADD-SERVER*/{'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', 'x', 'x', 'x', 
'x', 'x', 'x', ' ', ' ', 'x'},
+/*DEL-SERVER*/{'x', 'x', '+', 'x', 'x', 'x', '+', 'x', 'x', 'x', 'x', 'x', 
'x', 'x', 'x', 'x', 'x', 'x'},
+/*EDIT-SRV*/  {'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', 'x', 'x', 'x', 
'x', 'x', 'x', ' ', ' ', 'x'},
+/*TIMEOUT*/   {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 
'x', 'x', 'x', 'x', 'x', 'x'},
+/*START-D*/   {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' ', 'x', 'x', 
'x', 'x', 'x', 'x', 'x', 'x'},
+/*STOP-D*/    {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 
'x', 'x', 'x', 'x', 'x', 'x'},
+/*RESTORE*/   {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 
'x', 'x', 'x', 'x', 'x', 'x'},
+/*SAVE*/      {' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 
'x', 'x', 'x', 'x', 'x', 'x'},
+/*ZERO*/      {'x', 'x', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 
'x', 'x', 'x', 'x', 'x', 'x'},
 };
 
 /* printing format flags */
@@ -223,6 +230,7 @@
 #define FMT_STATS      0x0004
 #define FMT_RATE       0x0008
 #define FMT_SORT       0x0010
+#define FMT_THRESHOLDS 0x0020
 
 #define SERVICE_NONE    0x0
 #define SERVICE_ADDR    0x1
@@ -238,7 +246,7 @@
 
 /* various parsing helpers & parsing functions */
 static int str_is_digit(const char *str);
-static int string_to_number(const char *s, int min, int max);
+static int string_to_number(const char *s, unsigned int min, unsigned int max);
 static int host_to_addr(const char *name, struct in_addr *addr);
 static char * addr_to_host(struct in_addr *addr);
 static char * addr_to_anyname(struct in_addr *addr);
@@ -355,6 +363,9 @@
                {"stats", '\0', POPT_ARG_NONE, NULL, '7'},
                {"rate", '\0', POPT_ARG_NONE, NULL, '8'},
                {"sort", '\0', POPT_ARG_NONE, NULL, '9'},
+               {"u-threshold", 'x', POPT_ARG_STRING, &optarg, 'x'},
+               {"l-threshold", 'y', POPT_ARG_STRING, &optarg, 'y'},
+               {"thresholds", '\0', POPT_ARG_NONE, NULL, '0'},
                {NULL, 0, 0, NULL, 0}
        };
 
@@ -490,9 +501,24 @@
                case 'w':
                        set_option(options, OPT_WEIGHT);
                        if ((ur->weight =
-                            string_to_number(optarg, 0, 65535)) == -1)
+                            string_to_number(optarg, 0, UINT16_MAX)) == -1)
                                fail(2, "illegal weight specified");
                        break;
+               case 'x':
+                       set_option(options, OPT_UTHRESHOLD);
+                       if ((ur->u_threshold =
+                           string_to_number(optarg, 0, UINT32_MAX)) == -1)
+                               fail(2, "illegal u_threshold specified");
+                       break;
+               case 'y':
+                       set_option(options, OPT_LTHRESHOLD);
+                       if ((ur->l_threshold =
+                           string_to_number(optarg, 0, UINT32_MAX)) == -1)
+                               fail(2, "illegal l_threshold specified");
+                       if (ur->l_threshold > ur->u_threshold) {
+                               fail(2, "l_threshold must be smaller than 
u_threshold");
+                       }
+                       break;
                case 'c':
                        set_option(options, OPT_CONNECTION);
                        break;
@@ -522,6 +548,10 @@
                        set_option(options, OPT_SORT);
                        *format |= FMT_SORT;
                        break;
+               case '0':
+                       set_option(options, OPT_THRESHOLDS);
+                       *format |= FMT_THRESHOLDS;
+                       break;
                default:
                        fail(2, "invalid option");
                }
@@ -604,6 +634,9 @@
                {"stats", 0, 0, '7'},
                {"rate", 0, 0, '8'},
                {"sort", 0, 0, '9'},
+               {"u-threshold", 1, 0, 'x'},
+               {"l-threshold", 1, 0, 'y'},
+               {"thresholds", 0, 0, '0'},
                {"help", 0, 0, 'h'},
                {0, 0, 0, 0}
        };
@@ -762,9 +795,24 @@
                case 'w':
                        set_option(options, OPT_WEIGHT);
                        if ((ur->weight =
-                            string_to_number(optarg,0,65535)) == -1)
+                            string_to_number(optarg, 0, UINT16_MAX)) == -1)
                                fail(2, "illegal weight specified");
                        break;
+               case 'x':
+                       set_option(options, OPT_UTHRESHOLD);
+                       if ((ur->u_threshold =
+                           string_to_number(optarg, 0, UINT32_MAX)) == -1)
+                               fail(2, "illegal u_threshold specified");
+                       break;
+               case 'y':
+                       set_option(options, OPT_LTHRESHOLD);
+                       if ((ur->l_threshold =
+                           string_to_number(optarg, 0, UINT32_MAX)) == -1)
+                               fail(2, "illegal l_threshold specified");
+                       if (ur->l_threshold > ur->u_threshold) {
+                               fail(2, "l_threshold must be smaller than 
u_threshold");
+                       }
+                       break;
                case 'c':
                        set_option(options, OPT_CONNECTION);
                        break;
@@ -794,6 +842,10 @@
                        set_option(options, OPT_SORT);
                        *format |= FMT_SORT;
                        break;
+               case '0':
+                       set_option(options, OPT_THRESHOLDS);
+                       *format |= FMT_THRESHOLDS;
+                       break;
                default:
                        fail(2, "invalid option");
                }
@@ -853,7 +905,8 @@
                if ((options & OPT_CONNECTION
                     || options & OPT_TIMEOUT
                     || options & OPT_DAEMON)
-                   && (options & OPT_STATS || options & OPT_RATE))
+                   && (options & OPT_STATS || options & OPT_RATE
+                    || options & OPT_THRESHOLDS))
                        fail(2, "options conflicts in the list command");
 
                if (options & OPT_CONNECTION)
@@ -914,13 +967,13 @@
 }
 
 
-static int string_to_number(const char *s, int min, int max)
+static int string_to_number(const char *s, unsigned int min, unsigned int max)
 {
-       long number;
+       unsigned long number;
        char *end;
 
        errno = 0;
-       number = strtol(s, &end, 10);
+       number = strtoul(s, &end, 10);
        if (*end == '\0' && end != s) {
                /* We parsed a number, let's see if we want this. */
                if (errno != ERANGE && min <= number && number <= max)
@@ -1023,7 +1076,7 @@
        if (portp != NULL){
                result |= SERVICE_PORT;
 
-               if ((portn=string_to_number(portp+1, 0, 65535)) != -1)
+               if ((portn=string_to_number(portp+1, 0, UINT16_MAX)) != -1)
                        *port = htons(portn);
                else if ((portn=service_to_port(portp+1, proto)) != -1)
                        *port = htons(portn);
@@ -1120,7 +1173,7 @@
                "  %s -C\n"
                "  %s -R\n"
                "  %s -S [-n]\n"
-               "  %s -a|e -t|u|f service-address -r server-address [-g|i|m] 
[-w weight]\n"
+               "  %s -a|e -t|u|f service-address -r server-address [Options]\n"
                "  %s -d -t|u|f service-address -r server-address\n"
                "  %s -L|l [options]\n"
                "  %s -Z [-t|u|f service-address]\n"
@@ -1166,12 +1219,15 @@
                "  --ipip         -i                   ipip encapsulation 
(tunneling)\n"
                "  --masquerading -m                   masquerading (NAT)\n"
                "  --weight       -w weight            capacity of real 
server\n"
+               "  --u-threshold  -x uthreshold        upper threshold of 
connections\n"
+               "  --l-threshold  -y lthreshold        lower threshold of 
connections\n"
                "  --mcast-interface interface         multicast interface for 
connection sync\n"
                "  --connection   -c                   output of current IPVS 
connections\n"
                "  --timeout                           output of timeout (tcp 
tcpfin udp)\n"
                "  --daemon                            output of daemon 
information\n"
                "  --stats                             output of statistics 
information\n"
                "  --rate                              output of rate 
information\n"
+               "  --thresholds                        output of thresholds 
information\n"
                "  --sort                              sorting output of 
service/server entries\n"
                "  --numeric      -n                   numeric output of 
addresses and ports\n",
                DEF_SCHED);
@@ -1411,6 +1467,12 @@
                       "  -> RemoteAddress:Port\n",
                       "Prot LocalAddress:Port",
                       "CPS", "InPPS", "OutPPS", "InBPS", "OutBPS");
+       else if (format & FMT_THRESHOLDS)
+               printf("%-33s %-10s %-10s %-10s %-10s\n"
+                       "  -> RemoteAddress:Port\n",
+                       "Prot LocalAddress:Port",
+                       "Uthreshold", "Lthreshold", "ActiveConn", "InActConn");
+
        else if (!(format & FMT_RULE))
                printf("Prot LocalAddress:Port Scheduler Flags\n"
                       "  -> RemoteAddress:Port           Forward Weight 
ActiveConn InActConn\n");
@@ -1527,6 +1589,11 @@
                        print_largenum(e->stats.inbps);
                        print_largenum(e->stats.outbps);
                        printf("\n");
+               } else if (format & FMT_THRESHOLDS) {
+                       printf("  -> %-28s %-10u %-10u %-10u %-10u\n", dname,
+                               e->u_threshold, e->l_threshold,
+                               e->activeconns, e->inactconns);
+
                } else
                        printf("  -> %-28s %-7s %-6d %-10u %-10u\n",
                               dname, fwd_name(e->flags),
<Prev in Thread] Current Thread [Next in Thread>
  • [RFC][PATCH-2.4] per RS threshold limitation for ipvs-1.0.10, Roberto Nibali <=