From 228ba86ffa55ce58d20d474bcc04d7287a0410e0 Mon Sep 17 00:00:00 2001 From: Paul Millar Date: Mon, 7 Jan 2013 15:53:55 +0000 Subject: [PATCH] dcap client: close tunnel when closing control channel The dcap client includes the concept of optionally encoding the control channel. This is enabled through loading a DSO plugin. In addition to the encoding and decoding functions, the plugins also have an initialise and destroy functions. The dcap code calls the initialise method but fails to ever call the destroy function of the plugin. Under certain circumstances this can lead to a memory leak. This patch updates the dcap client so it calls the tunnel's destroy function (if a tunnel is being used) when the control channel is closed. FOR RELEASE NOTES: Mention that a memory leak for gsidcap under rare conditions has been fixed. Target: trunk Require-notes: yes Require-book: no Patch: http://rb.dcache.org/r/5043/ Acked-by: Tigran Mkrtchyan Require-notes: yes Require-book: no --- modules/dcap/src/dcap.c | 19 +++++++++++++++---- modules/dcap/src/dcap_close.c | 2 +- modules/dcap/src/dcap_functions.h | 1 + modules/dcap/src/dcap_poll.c | 2 +- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/modules/dcap/src/dcap.c b/modules/dcap/src/dcap.c index 4bc5b33d516..49ba596d7f4 100644 --- a/modules/dcap/src/dcap.c +++ b/modules/dcap/src/dcap.c @@ -420,7 +420,7 @@ serverConnect(struct vsp_node * node) pollDelete(node->fd); /* file descriptor can be reused by system */ - system_close(node->fd); + close_control_socket(node->fd, node->tunnel); node->fd = -1; continue; } @@ -733,7 +733,7 @@ cache_connect(server * srv) setTunnelPair(fd, srv->tunnel); if( sayHello(fd, srv->tunnel) < 0 ) { - system_close(fd); + close_control_socket(fd, srv->tunnel); dc_errno = DEHELLO; return -1; } @@ -1158,9 +1158,20 @@ ascii_open_conversation(struct vsp_node * node) int close_data_socket(int dataFd) { - return system_close(dataFd); + return system_close(dataFd); } + +int close_control_socket(int ctlFd, ioTunnel *tunnel) +{ + if(tunnel != NULL) { + tunnel->eDestroy(ctlFd); + } + + return system_close(ctlFd); +} + + int sendControlMessage(int to, const char *buff, size_t len, ioTunnel *en) { int n; @@ -1856,7 +1867,7 @@ int newControlLine(struct vsp_node *node) pollDelete(node->fd); /* file descriptor can be reused by system */ - system_close(node->fd); + close_control_socket(node->fd, node->tunnel); if ( initControlLine(node) < 0) { return 0; diff --git a/modules/dcap/src/dcap_close.c b/modules/dcap/src/dcap_close.c index aed21bd7faa..a4d7b857661 100644 --- a/modules/dcap/src/dcap_close.c +++ b/modules/dcap/src/dcap_close.c @@ -191,7 +191,7 @@ dc_close(int fd) deleteMemberByValue(node->fd); unlockMember(); pollDelete(node->fd); - system_close(node->fd); + close_control_socket(node->fd, node->tunnel); } } } diff --git a/modules/dcap/src/dcap_functions.h b/modules/dcap/src/dcap_functions.h index b3e684a2877..977782c29dc 100644 --- a/modules/dcap/src/dcap_functions.h +++ b/modules/dcap/src/dcap_functions.h @@ -26,6 +26,7 @@ int cache_open(struct vsp_node *); int close_data_socket(int); +int close_control_socket(int, ioTunnel *); int sendControlMessage(int, const char *, size_t, ioTunnel *); asciiMessage *getControlMessage(int, struct vsp_node *); int data_hello_conversation(struct vsp_node *); diff --git a/modules/dcap/src/dcap_poll.c b/modules/dcap/src/dcap_poll.c index e29d76e757b..a996a412e4d 100644 --- a/modules/dcap/src/dcap_poll.c +++ b/modules/dcap/src/dcap_poll.c @@ -253,7 +253,7 @@ dcap_poll(int mode, struct vsp_node *node, int what) int_pollDelete(node->fd); /* file descriptor can be reused by system */ - system_close(node->fd); + close_control_socket(node->fd, node->tunnel); break; case ASCII_CONNECT: