[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