On 14 May 2010 12:53, Nick Chalk <[email protected]> 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/
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;
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`
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));
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 - [email protected]
Send requests to [email protected]
or go to http://lists.graemef.net/mailman/listinfo/lvs-users