[prev in list] [next in list] [prev in thread] [next in thread] 

List:       linux-virtual-server
Subject:    Re: [lvs-users] LVS - NET SNMP Memory Leak
From:       Nick Chalk <nick () loadbalancer ! org>
Date:       2010-05-19 15:42:01
Message-ID: AANLkTilKyctxdhYxkKQC429O7C1jnocBIm-wxtkk5BBy () mail ! gmail ! com
[Download RAW message or body]

On 14 May 2010 12:53, Nick Chalk <nick@loadbalancer.org> wrote:
> Attached is a patch for the LVS net-snmp module which appears to fix
> the memory leak we were seeing. It's still under test, but results
> look good so far.

That patch didn't handle multiple virtual services properly. Attached
is an updated patch which does.

I've tidied up the patch, splitting it into its component parts:
   net-snmp-lvs-module-0.0.4-leak_fix-2.patch     Memory leak bug fix.
   net-snmp-lvs-module-0.0.4-compile.patch        Add -fPIC to Makefile CFLAGS.
   net-snmp-lvs-module-0.0.4-duplicate_registration.patch

Robin Bowes patch from 2009-09-30,

fixing the duplicate registration error.

We've since discovered another problem, affecting the size of IPv4
addresses returned by net-snmp. On an IPv6-enabled system running
net-snmp 5.5, IPv4 addresses are returned as 16 byte values; testing
with net-snmp clients doesn't show the problem, but other clients are
affected.

The LVS module doesn't allow for struct ip_vs_service_entry.addr being
a union, containing either an IPv4 or an IPv6 address.
net-snmp-lvs-module-0.0.4-IP_version.patch contains a patch to handle
this.

All the patches are still in testing - I'd recommend anyone else
applying them to test thoroughly before using in production.

Nick.

-- 
Nick Chalk.

Loadbalancer.org Ltd.
Phone: +44 (0)870 443 8779
http://www.loadbalancer.org/

["net-snmp-lvs-module-0.0.4-leak_fix-2.patch" (text/x-diff)]

diff -ur --exclude=libipvs net-snmp-lvs-module-0.0.4/lvs.c net-snmp-lvs-module-0.0.4-leak_fix/lvs.c
--- net-snmp-lvs-module-0.0.4/lvs.c	2006-01-02 14:31:54.000000000 +0000
+++ net-snmp-lvs-module-0.0.4-leak_fix/lvs.c	2010-05-19 15:15:14.000000000 +0100
@@ -37,6 +37,7 @@
 static struct ip_vs_daemon_user* ipvs_daemon;
 static struct Destination* ipvs_destination;
 static time_t last_setup;
+static struct ip_vs_get_dests** sentry_base = NULL;
 
 static
 void setup_snmp_ipvs(void)
@@ -44,7 +45,7 @@
 	int s, d;
 	struct Destination* mydestprev = NULL;
 	struct Destination* mydest = ipvs_destination;
-	struct ip_vs_get_dests* sentry;
+	struct ip_vs_get_dests **sentry;
 	
 	time(&last_setup);
 	if (ipvs_services) {
@@ -64,22 +65,36 @@
 	ipvs_timeout = ipvs_get_timeouts();
 #endif
 	ipvs_daemon = ipvs_get_daemon();
+
 	while (mydest) {
 		mydestprev = mydest;
 		mydest = mydest->next;
 		SNMP_FREE(mydestprev);
 	}
 	mydestprev = NULL;
+
+	/* NRC, 2010-05-18: Free old sentry structures... */
+	sentry = sentry_base;
+	if (sentry) {
+		while (*sentry) {
+			free(*sentry);
+			sentry++;
+		}
+		free(sentry_base);
+	}
+
+	sentry_base = calloc(ipvs_services->num_services + 1, sizeof(struct ip_vs_get_dests *));
 	for (s = 0; s<ipvs_services->num_services; s++) {
-		sentry = ipvs_get_dests(&ipvs_services->entrytable[s]);
-		for (d = 0; d<sentry->num_dests; d++) {
+		sentry = sentry_base + s;
+		*sentry = ipvs_get_dests(&ipvs_services->entrytable[s]);
+		for (d = 0; d < (*sentry)->num_dests; d++) {
 			mydest = SNMP_MALLOC_STRUCT(Destination);
 			if (mydestprev==NULL) {
 				ipvs_destination = mydest;
 			} else {
 				mydestprev->next = mydest;
 			}
-			mydest->dest_entry = &sentry->entrytable[d];
+			mydest->dest_entry = &(*sentry)->entrytable[d];
 			mydest->svc_index = s+1;
 			mydest->dst_index = d+1;
 			mydest->next = NULL;

["net-snmp-lvs-module-0.0.4-compile.patch" (text/x-diff)]

diff -ur --exclude=libipvs net-snmp-lvs-module-0.0.4/Makefile net-snmp-lvs-module-0.0.4-leak_fix/Makefile
--- net-snmp-lvs-module-0.0.4/Makefile	2006-03-02 09:14:56.000000000 +0000
+++ net-snmp-lvs-module-0.0.4-leak_fix/Makefile	2010-05-07 10:37:12.000000000 +0100
@@ -3,7 +3,7 @@
 VERSDIR := $(NAME)-$(VERSION)
 TARFILE := $(NAME)-$(VERSION).tar.gz
 CC := gcc 
-CFLAGS := `net-snmp-config --cflags` -Ilibipvs -I/usr/src/linux/include -Wall -g
+CFLAGS := `net-snmp-config --cflags` -Ilibipvs -I/usr/src/linux/include -Wall -g -fPIC
 DEFINES := -DHAVE_NET_IP_VS_H
 DLFLAGS := -fPIC -shared -g
 LIBS := `net-snmp-config --netsnmp-libs`

["net-snmp-lvs-module-0.0.4-duplicate_registration.patch" (text/x-diff)]

diff -ur --exclude=libipvs net-snmp-lvs-module-0.0.4/lvs.c \
                net-snmp-lvs-module-0.0.4-leak_fix/lvs.c
--- net-snmp-lvs-module-0.0.4/lvs.c	2006-01-02 14:31:54.000000000 +0000
+++ net-snmp-lvs-module-0.0.4-leak_fix/lvs.c	2010-05-19 15:15:14.000000000 +0100
@@ -495,8 +520,7 @@
 	snmp_log(LOG_INFO, "IPVS initialization for ");
 	netsnmp_register_read_only_instance(netsnmp_create_handler_registration("lvsVersion", \
get_lvs_var, lvsVersion_oid, OID_LENGTH(lvsVersion_oid), HANDLER_CAN_RONLY));  \
netsnmp_register_read_only_instance(netsnmp_create_handler_registration("lvsNumServices", \
                get_lvs_var, lvsNumServices_oid, OID_LENGTH(lvsNumServices_oid), \
                HANDLER_CAN_RONLY));
-	netsnmp_register_read_only_instance(netsnmp_create_handler_registration("lvsNumServices", \
get_lvs_var, lvsHashTableSize_oid, OID_LENGTH(lvsHashTableSize_oid), \
                HANDLER_CAN_RONLY));
-	netsnmp_register_read_only_instance(netsnmp_create_handler_registration("lvsNumServices", \
get_lvs_var, lvsHashTableSize_oid, OID_LENGTH(lvsHashTableSize_oid), \
HANDLER_CAN_RONLY)); \
+	netsnmp_register_read_only_instance(netsnmp_create_handler_registration("lvsHashTableSize", \
get_lvs_var, lvsHashTableSize_oid, OID_LENGTH(lvsHashTableSize_oid), \
HANDLER_CAN_RONLY));  \
netsnmp_register_read_only_instance(netsnmp_create_handler_registration("lvsTcpTimeOut", \
get_lvs_var, lvsTcpTimeOut_oid, OID_LENGTH(lvsTcpTimeOut_oid), HANDLER_CAN_RONLY));  \
netsnmp_register_read_only_instance(netsnmp_create_handler_registration("lvsTcpTimeOutFin", \
get_lvs_var, lvsTcpTimeOutFin_oid, OID_LENGTH(lvsTcpTimeOutFin_oid), \
HANDLER_CAN_RONLY));  \
netsnmp_register_read_only_instance(netsnmp_create_handler_registration("lvsUdpTimeOut", \
get_lvs_var, lvsUdpTimeOut_oid, OID_LENGTH(lvsUdpTimeOut_oid), HANDLER_CAN_RONLY));


["net-snmp-lvs-module-0.0.4-IP_version.patch" (text/x-diff)]

diff -ur --exclude=libipvs net-snmp-lvs-module-0.0.4/lvs.c \
                net-snmp-lvs-module-0.0.4-leak_fix/lvs.c
--- net-snmp-lvs-module-0.0.4/lvs.c	2006-01-02 14:31:54.000000000 +0000
+++ net-snmp-lvs-module-0.0.4-leak_fix/lvs.c	2010-05-19 15:15:14.000000000 +0100
@@ -243,7 +258,12 @@
 				snmp_set_var_typed_value(var, ASN_INTEGER, (u_char*)&tmp, sizeof(int));
 				break;
 			    case COLUMN_LVSSERVICEADDR:
-				snmp_set_var_typed_value(var, ASN_IPADDRESS, (u_char*) &entrytable->addr, \
sizeof(int)); +				if (entrytable->af == AF_INET) {
+					snmp_set_var_typed_value(var, ASN_IPADDRESS, (u_char*) &entrytable->addr.in, \
sizeof(entrytable->addr.in)); +				}
+				else if (entrytable->af == AF_INET6) {
+					snmp_set_var_typed_value(var, ASN_IPADDRESS, (u_char*) &entrytable->addr.in6, \
sizeof(entrytable->addr.in6)); +				}
 				break;
 			    case COLUMN_LVSSERVICEPORT:
 				tmp = htons(entrytable->port);
@@ -408,7 +428,12 @@
 				snmp_set_var_typed_value(var, ASN_INTEGER, (u_char*) &mydest->dst_index, \
sizeof(mydest->dst_index));  break;
 			    case COLUMN_LVSREALSERVERADDR:
-				snmp_set_var_typed_value(var, ASN_IPADDRESS, (u_char*) &destentry->addr, \
sizeof(destentry->addr)); +				if (destentry->af == AF_INET) {
+					snmp_set_var_typed_value(var, ASN_IPADDRESS, (u_char*) &destentry->addr.in, \
sizeof(destentry->addr.in)); +				}
+				else if (destentry->af == AF_INET6) {
+					snmp_set_var_typed_value(var, ASN_IPADDRESS, (u_char*) &destentry->addr.in6, \
sizeof(destentry->addr.in6)); +				}
 				break;
 			    case COLUMN_LVSREALSERVERPORT:
 				tmp = htons(destentry->port);



_______________________________________________
Please read the documentation before posting - it's available at:
http://www.linuxvirtualserver.org/

LinuxVirtualServer.org mailing list - lvs-users@LinuxVirtualServer.org
Send requests to lvs-users-request@LinuxVirtualServer.org
or go to http://lists.graemef.net/mailman/listinfo/lvs-users

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic