LVS
lvs-users
Google
 
Web LinuxVirtualServer.org

Re: [PATCH 2.4] add per real server threshold limitation against ipvsadm

To: "LinuxVirtualServer.org users mailing list." <lvs-users@xxxxxxxxxxxxxxxxxxxxxx>
Subject: Re: [PATCH 2.4] add per real server threshold limitation against ipvsadm-1.21-11
From: Roberto Nibali <ratz@xxxxxx>
Date: Fri, 04 Nov 2005 11:25:23 +0100
And the user space patch this time. I should probably start a new thread
with less confusion ...

Cheers,
Roberto Nibali, ratz
-- 
-------------------------------------------------------------
addr://Kasinostrasse 30, CH-5001 Aarau tel://++41 62 823 9355
http://www.terreactive.com             fax://++41 62 823 9356
-------------------------------------------------------------
terreActive AG                       Wir sichern Ihren Erfolg
-------------------------------------------------------------
diff -X ../2.4.x/dontdiff -Nur ipvsadm-1.21-11/Makefile 
ipvsadm-1.21-11-ratz/Makefile
--- ipvsadm-1.21-11/Makefile    2005-01-22 05:07:42 +0100
+++ ipvsadm-1.21-11-ratz/Makefile       2005-10-17 13:46:08 +0200
@@ -38,6 +38,7 @@
 else
     CFLAGS = -Wall -Wunused -Wstrict-prototypes -g -O2
 endif
+LDFLAGS =
 SBIN    = $(BUILD_ROOT)/sbin
 MANDIR = usr/man
 MAN    = $(BUILD_ROOT)/$(MANDIR)/man8
@@ -87,7 +88,7 @@
 all:            ipvsadm
 
 ipvsadm:       $(OBJS) $(STATIC_LIBS)
-               $(CC) $(CFLAGS) -o $@ $^ $(LIBS)
+               $(CC) $(CFLAGS) -o $@ $^ $(LIBS) $(LDFLAGS)
 
 install:        ipvsadm
                if [ ! -d $(SBIN) ]; then $(MKDIR) -p $(SBIN); fi
Files ipvsadm-1.21-11/ipvsadm and ipvsadm-1.21-11-ratz/ipvsadm differ
diff -X ../2.4.x/dontdiff -Nur ipvsadm-1.21-11/ipvsadm.c 
ipvsadm-1.21-11-ratz/ipvsadm.c
--- ipvsadm-1.21-11/ipvsadm.c   2005-01-22 05:07:42 +0100
+++ ipvsadm-1.21-11-ratz/ipvsadm.c      2005-11-04 09:04:00 +0100
@@ -54,6 +54,7 @@
  *                                processing options.
  *        Horms               :   added to load ip_vs_ftp for VS/NAT at port 21
  *        Alexandre Cassen    :   added SyncID support
+ *        Roberto Nibali, ratz:   added support for threshold limitation
  *
  *
  *      ippfvsadm - Port Fowarding & Virtual Server ADMinistration program
@@ -168,7 +169,11 @@
 #define OPT_RATE       0x02000
 #define OPT_SORT       0x04000
 #define OPT_SYNCID     0x08000
-#define NUMBER_OF_OPT  16
+#define OPT_UTHRESHOLD 0x10000
+#define OPT_LTHRESHOLD 0x20000
+#define OPT_THRESHOLDS 0x40000
+#define OPT_OVERFLOW   0x80000
+#define NUMBER_OF_OPT  20
 
 static const char* optnames[] = {
        "numeric",
@@ -187,6 +192,10 @@
        "rate",
        "sort",
        "syncid",
+       "u_threshold",
+       "l_threshold",
+       "thresholds",
+       "overflow",
 };
 
 /*
@@ -199,22 +208,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  sid */
-/*INSERT*/    {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', 'x', 
'x', 'x', 'x', ' '},
-/*ADD*/       {'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'},
-/*DEL*/       {'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'},
-/*LIST*/      {' ', '1', '1', 'x', 'x', 'x', 'x', 'x', 'x', 'x', '1', '1', ' 
', ' ', ' ', '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'},
-/*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'},
-/*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', 'x'},
-/*SAVE*/      {' ', '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'},
+       /*     -n   -c   svc  -s   -p   -M   -r   fwd  -w   -mc  -to  dmn  -st  
-rt  srt  sid  -x   -y   thr  -o  */
+/*INSERT*/    {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', 'x', 
'x', 'x', 'x', ' ', 'x', 'x', 'x', 'x'},
+/*ADD*/       {'x', 'x', '+', ' ', ' ', ' ', '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', 'x', 'x'},
+/*DEL*/       {'x', 'x', '+', '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', 'x', 'x'},
+/*LIST*/      {' ', '1', '1', 'x', 'x', 'x', 'x', 'x', 'x', 'x', '1', '1', ' 
', ' ', ' ', 'x', 'x', 'x', ' ', '1'},
+/*ADD-SERVER*/{'x', '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', 'x', 'x'},
+/*EDIT-SRV*/  {'x', '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', 'x', 'x'},
+/*START-D*/   {'x', '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', 'x'},
+/*RESTORE*/   {'x', 'x', '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', 'x', 'x'},
+/*ZERO*/      {'x', 'x', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 
'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'},
 };
 
 /* printing format flags */
@@ -224,6 +233,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
@@ -246,7 +256,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);
@@ -346,8 +356,7 @@
                {"udp-service", 'u', POPT_ARG_STRING, &optarg, 'u'},
                {"fwmark-service", 'f', POPT_ARG_STRING, &optarg, 'f'},
                {"scheduler", 's', POPT_ARG_STRING, &optarg, 's'},
-               {"persistent", 'p', POPT_ARG_STRING|POPT_ARGFLAG_OPTIONAL,
-                &optarg, 'p'},
+               {"persistent", 'p', POPT_ARG_STRING, &optarg, 'p'},
                {"netmask", 'M', POPT_ARG_STRING, &optarg, 'M'},
                {"real-server", 'r', POPT_ARG_STRING, &optarg, 'r'},
                {"masquerading", 'm', POPT_ARG_NONE, NULL, 'm'},
@@ -363,6 +372,10 @@
                {"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'},
+               {"overflow", 'o', POPT_ARG_NONE, NULL, 'o'},
                {NULL, 0, 0, NULL, 0}
        };
 
@@ -468,6 +481,10 @@
                        ur->vs_flags = IP_VS_SVC_F_PERSISTENT;
                        ur->timeout = parse_timeout(optarg, 1, MAX_TIMEOUT);
                        break;
+               case 'o':
+                       set_option(options, OPT_OVERFLOW);
+                       ur->dest_flags |= IP_VS_DEST_F_OVERFLOW;
+                       break;
                case 'M':
                        set_option(options, OPT_NETMASK);
                        parse = parse_netmask(optarg, &ur->netmask);
@@ -503,9 +520,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;
@@ -541,6 +573,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");
                }
@@ -586,7 +622,7 @@
              int *cmd, unsigned int *options, unsigned int *format)
 {
        int c, parse;
-       const char *optstring = "AEDCZSRaedlLhvt:u:f:s:M:p::w:r:gmicn";
+       const char *optstring = "AEDCZSRaedlLhvot:u:f:s:M:p::w:r:x:y:gmicn";
        const struct option long_options[] = {
                {"add-service", 0, 0, 'A'},
                {"edit-service", 0, 0, 'E'},
@@ -599,6 +635,7 @@
                {"delete-server", 0, 0, 'd'},
                {"help", 0, 0, 'h'},
                {"version", 0, 0, 'v'},
+               {"overflow", 0, 0, 'o'},
                {"save", 0, 0, 'S'},
                {"restore", 0, 0, 'R'},
                {"set", 1, 0, '4'},
@@ -624,6 +661,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}
        };
@@ -744,6 +784,10 @@
                        set_option(options, OPT_SCHEDULER);
                        strncpy(ur->sched_name, optarg, IP_VS_SCHEDNAME_MAXLEN);
                        break;
+               case 'o':
+                       set_option(options, OPT_OVERFLOW);
+                       ur->dest_flags |= IP_VS_DEST_F_OVERFLOW;
+                       break;
                case 'p':
                        set_option(options, OPT_PERSISTENT);
                        ur->vs_flags = IP_VS_SVC_F_PERSISTENT;
@@ -787,9 +831,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;
@@ -825,6 +884,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");
                }
@@ -884,7 +947,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)
@@ -955,13 +1019,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)
@@ -1064,9 +1128,9 @@
        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)
+               else if ((portn=service_to_port(portp + 1, proto)) != -1)
                        *port = htons(portn);
                else
                        return SERVICE_NONE;
@@ -1207,6 +1271,8 @@
                "  --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 for 
amount of connections per RS\n"
+               "  --l_threshold  -y lthreshold        lower threshold for 
amount of connections per RS\n"
                "  --mcast-interface interface         multicast interface for 
connection sync\n"
                "  --syncid sid                        syncid for connection 
sync (default=255)\n"
                "  --connection   -c                   output of current IPVS 
connections\n"
@@ -1214,6 +1280,8 @@
                "  --daemon                            output of daemon 
information\n"
                "  --stats                             output of statistics 
information\n"
                "  --rate                              output of rate 
information\n"
+               "  --thresholds                        information on threshold 
settings\n"
+               "  --overflow     -o                   flag realserver as 
spillover server\n"
                "  --sort                              sorting output of 
service/server entries\n"
                "  --numeric      -n                   numeric output of 
addresses and ports\n",
                DEF_SCHED);
@@ -1453,6 +1521,14 @@
                       "  -> RemoteAddress:Port\n",
                       "Prot LocalAddress:Port",
                       "CPS", "InPPS", "OutPPS", "InBPS", "OutBPS");
+       else if (format & FMT_THRESHOLDS)
+               printf("%-33s %-7s %-6s %-10s %-10s %-10s %-10s %-10s %-10s 
%-10s\n"
+                      "  -> RemoteAddress:Port\n",
+                      "Prot LocalAddress:Port",
+                      "Forward", "Weight",
+                      "Uthreshold", "Lthreshold",
+                      "ActiveConn", "InActConn", "PersConn",
+                      "RS-Usage", "RS-Status");
        else if (!(format & FMT_RULE))
                printf("Prot LocalAddress:Port Scheduler Flags\n"
                       "  -> RemoteAddress:Port           Forward Weight 
ActiveConn InActConn\n");
@@ -1510,6 +1586,15 @@
                                printf(" -M %s", inet_ntoa(mask));
                        }
                }
+               if (svc->flags & IP_VS_SVC_F_PERSISTENT) {
+                       printf(" %s", "PERSISTENT");
+               }
+               if (svc->flags & IP_VS_SVC_F_HASHED) {
+                       printf(" %s", "HASHED");
+               }
+               if (svc->flags & IP_VS_SVC_F_OVERLOAD) {
+                       printf(" %s", "OVERLOAD");
+               }
        } else if (format & FMT_STATS) {
                printf("%-33s", svc_name);
                print_largenum(svc->stats.conns);
@@ -1528,11 +1613,15 @@
                printf("%s %s", svc_name, svc->sched_name);
                if (svc->flags & IP_VS_SVC_F_PERSISTENT) {
                        printf(" persistent %u", svc->timeout);
-                       if (svc->netmask != (unsigned long int) 0xffffffff) {
+                       //if (svc->netmask != (unsigned long int) 0xffffffff) {
                                struct in_addr mask;
                                mask.s_addr = svc->netmask;
                                printf(" mask %s", inet_ntoa(mask));
-                       }
+                       //}
+               }
+               printf(" avail_dests: %d", svc->avail_dests);
+               if (svc->flags & IP_VS_SVC_F_OVERLOAD) {
+                       printf(" %s", "OVERLOAD");
                }
        }
        printf("\n");
@@ -1569,6 +1658,13 @@
                        print_largenum(e->stats.inbps);
                        print_largenum(e->stats.outbps);
                        printf("\n");
+               } else if (format & FMT_THRESHOLDS) {
+                       printf("  -> %-28s %-7s %-6d %-10u %-10u %-10u %-10u 
%-10u %-10s %s\n", dname,
+                               fwd_name(e->flags), e->weight,
+                               e->u_threshold, e->l_threshold,
+                               e->activeconns, e->inactconns, e->persistconns,
+                               e->dest_flags & IP_VS_DEST_F_OVERFLOW ? 
"SPILLOVER"  : "POOL",
+                               e->dest_flags & IP_VS_DEST_F_OVERLOAD ? 
"OVERLOADED" : "ONLINE");
                } else
                        printf("  -> %-28s %-7s %-6d %-10u %-10u\n",
                               dname, fwd_name(e->flags),




<Prev in Thread] Current Thread [Next in Thread>