[lvs-users] [PATCH 3/3] ipvsadm: Add support for mh scheduler

Quentin Armitage quentin at armitage.org.uk
Fri Jan 4 20:26:54 GMT 2019


Signed-off-by: Quentin Armitage <quentin at armitage.org.uk>
---
 SCHEDULERS |  2 +-
 ipvsadm.8  | 10 ++++++++++
 ipvsadm.c  | 31 +++++++++++++++++++++++++++----
 3 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/SCHEDULERS b/SCHEDULERS
index 187c07d..06d3357 100644
--- a/SCHEDULERS
+++ b/SCHEDULERS
@@ -1 +1 @@
-rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq|fo|ovf
+rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq|fo|ovf|mh
diff --git a/ipvsadm.8 b/ipvsadm.8
index 18b6dc5..f0439dd 100644
--- a/ipvsadm.8
+++ b/ipvsadm.8
@@ -276,6 +276,16 @@ of connections exceeds its weight.
 server if there is one, instead of waiting for a fast one; if all the
 servers are busy, it adopts the Shortest Expected Delay policy to
 assign the job.
+.sp
+\fBmh\fR - Maglev Hashing: assigns a preference list of all the lookup
+table positions to each destination and populate the table with
+the most-preferred position of destinations. Then it is to select
+destination with the hash key of source IP address through looking
+up a the lookup table. This provides consistent hashing with minimal
+disruption on destination changes and load balancing.
+This scheduler has two flags: mh-fallback, which enables fallback to a
+different server if the selected server was unavailable, and mh-port,
+which adds the source port number to the hash computation.
 .TP
 .B -p, --persistent [\fItimeout\fP]
 Specify that a virtual service is persistent. If this option is
diff --git a/ipvsadm.c b/ipvsadm.c
index 7695006..7942908 100644
--- a/ipvsadm.c
+++ b/ipvsadm.c
@@ -270,6 +270,16 @@ static const char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] =
 
 #define CONN_PROC_FILE         "/proc/net/ip_vs_conn"
 
+/* Unfortunately include/linux/ip_vs.h doesn't yet define
+ * the following
+ */
+#ifndef IP_VS_SVC_F_SCHED_MH_FALLBACK
+#define IP_VS_SVC_F_SCHED_MH_FALLBACK IP_VS_SVC_F_SCHED1
+#endif
+#ifndef IP_VS_SVC_F_SCHED_MH_PORT
+#define IP_VS_SVC_F_SCHED_MH_PORT IP_VS_SVC_F_SCHED2
+#endif
+
 struct ipvs_command_entry {
        int                     cmd;
        ipvs_service_t          svc;
@@ -1145,6 +1155,16 @@ static unsigned int parse_sched_flags(const char *sched, char *optarg)
                        if (strcmp(sched, "sh"))
                                fail(2, "incompatible scheduler flag `%s'",
                                     flag);
+               } else if (!strcmp(flag, "mh-fallback")) {
+                       flags |= IP_VS_SVC_F_SCHED_MH_FALLBACK;
+                       if (strcmp(sched, "mh"))
+                               fail(2, "incompatible scheduler flag `%s'",
+                                    flag);
+               } else if (!strcmp(flag, "mh-port")) {
+                       flags |= IP_VS_SVC_F_SCHED_MH_PORT;
+                       if (strcmp(sched, "mh"))
+                               fail(2, "incompatible scheduler flag `%s'",
+                                    flag);
                } else {
                        fail(2, "invalid scheduler flag `%s'", flag);
                }
@@ -1589,16 +1609,19 @@ static void print_sched_flags(ipvs_service_entry_t *se)
                        strcat(flags, "sh-fallback,");
                if (se->flags & IP_VS_SVC_F_SCHED_SH_PORT)
                        strcat(flags, "sh-port,");
-               if (se->flags & IP_VS_SVC_F_SCHED3)
-                       strcat(flags, "flag-3,");
+       } else if (!strcmp(se->sched_name, "mh")) {
+               if (se->flags & IP_VS_SVC_F_SCHED_MH_FALLBACK)
+                       strcat(flags, "mh-fallback,");
+               if (se->flags & IP_VS_SVC_F_SCHED_MH_PORT)
+                       strcat(flags, "mh-port,");
        } else {
                if (se->flags & IP_VS_SVC_F_SCHED1)
                        strcat(flags, "flag-1,");
                if (se->flags & IP_VS_SVC_F_SCHED2)
                        strcat(flags, "flag-2,");
-               if (se->flags & IP_VS_SVC_F_SCHED3)
-                       strcat(flags, "flag-3,");
        }
+       if (se->flags & IP_VS_SVC_F_SCHED3)
+               strcat(flags, "flag-3,");
 
        if (flags[0]) {
                flags[strlen(flags)-1] = '\0';
-- 
2.13.7



More information about the lvs-users mailing list