]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: server: set the macro for server's max weight SRV_UWGHT_MAX to SRV_UWGHT_...
authorGodbach <nylzhaowei@gmail.com>
Sun, 21 Jul 2013 23:44:53 +0000 (07:44 +0800)
committerWilly Tarreau <w@1wt.eu>
Mon, 22 Jul 2013 07:29:34 +0000 (09:29 +0200)
The max weight of server is 256 now, but SRV_UWGHT_MAX is still 255. As a result,
FWRR will not work well when server's weight is 256. The description is as below:

There are some macros related to server's weight in include/types/server.h:
    #define SRV_UWGHT_RANGE 256
    #define SRV_UWGHT_MAX   (SRV_UWGHT_RANGE - 1)
    #define SRV_EWGHT_MAX   (SRV_UWGHT_MAX   * BE_WEIGHT_SCALE)

Since weight of server can be reach to 256 and BE_WEIGHT_SCALE equals to 16,
the max eweight of server should be 256*16 = 4096, it will exceed SRV_EWGHT_MAX
which equals to SRV_UWGHT_MAX*BE_WEIGHT_SCALE = 255*16 = 4080. When a server
with weight 256 is insterted into FWRR tree during initialization, the key value
of this server should be SRV_EWGHT_MAX - s->eweight = 4080 - 4096 = -16 which
is closed to UINT_MAX in unsigned type, so the server with highest weight will
be not elected as the first server to process request.

In addition, it is a better choice to compare with SRV_UWGHT_MAX than a magic
number 256 while doing check for the weight. The max number of servers for
round-robin algorithm is also updated.

Signed-off-by: Godbach <nylzhaowei@gmail.com>
doc/configuration.txt
include/types/backend.h
include/types/server.h
src/cfgparse.c
src/lb_fwrr.c

index 5140ff1e8eaa4ae7c298e2aa0b4b425ec2aa2d00..5a0269e3cada817827aa63451efd85008a96d468 100644 (file)
@@ -1400,7 +1400,7 @@ balance url_param <param> [check_post [<max_wait>]]
                   processing time remains equally distributed. This algorithm
                   is dynamic, which means that server weights may be adjusted
                   on the fly for slow starts for instance. It is limited by
-                  design to 4128 active servers per backend. Note that in some
+                  design to 4095 active servers per backend. Note that in some
                   large farms, when a server becomes up after having been down
                   for a very short time, it may sometimes take a few hundreds
                   requests for it to be re-integrated into the farm and start
index fd66e407a6acfde752ec0e7dadabd642830bb79b..1183b36582a7028c6ed2809e68dbb7b17026812b 100644 (file)
  * weight modulation even with small weights (eg: 1). It should not be too high
  * though because it limits the number of servers in FWRR mode in order to
  * prevent any integer overflow. The max number of servers per backend is
- * limited to about 2^32/255^2/scale ~= 66051/scale. A scale of 16 looks like
- * a good value, as it allows more than 4000 servers per backend while leaving
+ * limited to about (2^32-1)/256^2/scale ~= 65535.9999/scale. A scale of 16
+ * looks like a good value, as it allows 4095 servers per backend while leaving
  * modulation steps of about 6% for servers with the lowest weight (1).
  */
 #define BE_WEIGHT_SCALE 16
index b58a06207b5c90c2e9b11a9a623dafcf1238e411..e70ad8f9dfed0727d7e167e118aa8d5542fe05e8 100644 (file)
@@ -72,7 +72,7 @@
 
 /* various constants */
 #define SRV_UWGHT_RANGE 256
-#define SRV_UWGHT_MAX   (SRV_UWGHT_RANGE - 1)
+#define SRV_UWGHT_MAX   (SRV_UWGHT_RANGE)
 #define SRV_EWGHT_RANGE (SRV_UWGHT_RANGE * BE_WEIGHT_SCALE)
 #define SRV_EWGHT_MAX   (SRV_UWGHT_MAX   * BE_WEIGHT_SCALE)
 
index b3435ef6fb5f63053366d0137d283650616e47d2..a85bbedf0611f285104fa7587a5e727f8692c0ef 100644 (file)
@@ -4392,9 +4392,9 @@ stats_error_parsing:
                        else if (!strcmp(args[cur_arg], "weight")) {
                                int w;
                                w = atol(args[cur_arg + 1]);
-                               if (w < 0 || w > 256) {
-                                       Alert("parsing [%s:%d] : weight of server %s is not within 0 and 256 (%d).\n",
-                                             file, linenum, newsrv->id, w);
+                               if (w < 0 || w > SRV_UWGHT_MAX) {
+                                       Alert("parsing [%s:%d] : weight of server %s is not within 0 and %d (%d).\n",
+                                             file, linenum, newsrv->id, SRV_UWGHT_MAX, w);
                                        err_code |= ERR_ALERT | ERR_FATAL;
                                        goto out;
                                }
index d92b6eb827eaccb516d3ce8fe24e3b678ef6ed1f..7f5c8a9fbafae0f7a324a6e08f658fc90c4f0101 100644 (file)
@@ -343,7 +343,7 @@ static void fwrr_queue_srv(struct server *s)
                 * lower the scale, the rougher the weights modulation, and the
                 * higher the scale, the lower the number of servers without
                 * overflow. With this formula, the result is always positive,
-                * so we can use eb3é_insert().
+                * so we can use eb32_insert().
                 */
                s->lb_node.key = SRV_UWGHT_RANGE * s->npos +
                        (unsigned)(SRV_EWGHT_MAX + s->rweight - s->eweight) / BE_WEIGHT_SCALE;