LVS
lvs-users
Google
 
Web LinuxVirtualServer.org

[PATCH 2.4] add per real server threshold limitation against ipvsadm-1.2

To: "LinuxVirtualServer.org users mailing list." <lvs-users@xxxxxxxxxxxxxxxxxxxxxx>
Subject: [PATCH 2.4] add per real server threshold limitation against ipvsadm-1.21-11
From: Roberto Nibali <ratz@xxxxxx>
Date: Thu, 27 Oct 2005 18:58:16 +0200
Hello,

This is the user space part for the threshold limitation backport to the
2.4.x kernel. Among the implementation I've once again addressed some
minor nits which IMNSHO should finally be applied. Guys, the code does
nothing magic and should not be considered holy:

o added support for threshold limitation in 2.4.x kernels
o string_to_number() should use unsigned int
o POPT_ARGFLAG_OPTIONAL is unfortunately still not available on
  all Linux systems, so drop it.
  - Actually either drop it or rewrite the stuff without the popt
    dependency, which would also make it easier to extend
  - Or rewrite the stuff from scatch with netlink support (also needs
    kernel part support for netlink, as discussed with Horms)
o Change 65535 to UINT16_MAX
o Add support for LDFLAGS passing so I can link the thing statically

Please discuss and consider merging selected pieces of the patch.
Actually consider (once again) merging all the ipvsadm versions.

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 -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.000000000 +0100
+++ ipvsadm-1.21-11-ratz/ipvsadm.c      2005-10-17 14:59:22.000000000 +0200
@@ -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,10 @@
 #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 NUMBER_OF_OPT  19
 
 static const char* optnames[] = {
        "numeric",
@@ -187,6 +191,9 @@
        "rate",
        "sort",
        "syncid",
+       "u_threshold",
+       "l_threshold",
+       "thresholds",
 };
 
 /*
@@ -199,22 +206,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 */
+/*INSERT*/    {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', 'x', 
'x', 'x', 'x', ' ', 'x', 'x', 'x'},
+/*ADD*/       {'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'},
+/*DEL*/       {'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'},
+/*LIST*/      {' ', '1', '1', 'x', 'x', 'x', 'x', 'x', 'x', 'x', '1', '1', ' 
', ' ', ' ', 'x', 'x', 'x', ' '},
+/*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'},
+/*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'},
+/*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', 'x'},
+/*SAVE*/      {' ', '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'},
 };
 
 /* printing format flags */
@@ -224,6 +231,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 +254,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 +354,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 +370,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}
        };
 
@@ -503,9 +513,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 +566,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 +615,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 = "AEDCZSRaedlLhvt: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'},
@@ -624,6 +653,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}
        };
@@ -787,9 +819,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 +872,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 +935,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 +1007,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 +1116,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 +1259,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 +1268,7 @@
                "  --daemon                            output of daemon 
information\n"
                "  --stats                             output of statistics 
information\n"
                "  --rate                              output of rate 
information\n"
+               "  --thresholds                        information on threshold 
settings\n"
                "  --sort                              sorting output of 
service/server entries\n"
                "  --numeric      -n                   numeric output of 
addresses and ports\n",
                DEF_SCHED);
@@ -1453,6 +1508,11 @@
                       "  -> 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");
@@ -1569,6 +1629,10 @@
                        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),
diff -Nur ipvsadm-1.21-11/Makefile ipvsadm-1.21-11-ratz/Makefile
--- ipvsadm-1.21-11/Makefile    2005-01-22 05:07:42.000000000 +0100
+++ ipvsadm-1.21-11-ratz/Makefile       2005-10-17 13:46:08.000000000 +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




<Prev in Thread] Current Thread [Next in Thread>
  • [PATCH 2.4] add per real server threshold limitation against ipvsadm-1.21-11, Roberto Nibali <=