From b98454ae976c1ab5d3abf395c19a875a3f68fb02 Mon Sep 17 00:00:00 2001 From: zhenwei pi Date: Fri, 28 Feb 2020 18:29:41 +0800 Subject: [PATCH] iser: fix resource leak during reconnect After iser reconnects successfully, iser drive should close old connection and release resources. Fix resource leak in this patch, and test a lot, this patch works fine. Test env: 192.168.122.204: run as a software gateway 192.168.122.205: run iser target, default gateway 192.168.122.204 192.168.122.206: run QEMU as intiator, default gateway 192.168.122.204 run script on 192.168.122.204: for i in `seq 1 100` do iptables -s 192.168.122.205/32 -A FORWARD -m statistic --mode random --probability 1 -j DROP iptables -s 192.168.122.206/32 -A FORWARD -m statistic --mode random --probability 1 -j DROP sleep 30 iptables -F sleep 30 done Signed-off-by: zhenwei pi --- lib/iser.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/lib/iser.c b/lib/iser.c index c727be1..81f3687 100644 --- a/lib/iser.c +++ b/lib/iser.c @@ -294,8 +294,10 @@ iscsi_iser_disconnect(struct iscsi_context *iscsi) { struct iser_conn *iser_conn = iscsi->opaque; - iser_conn_terminate(iser_conn); - iser_conn_release(iser_conn); + if (iser_conn) { + iser_conn_terminate(iser_conn); + iser_conn_release(iser_conn); + } iscsi->fd = -1; iscsi->is_connected = 0; @@ -1462,6 +1464,25 @@ iscsi_iser_connect(struct iscsi_context *iscsi, union socket_address *sa,__attri iscsi->socket_status_cb(iscsi, SCSI_STATUS_GOOD, NULL, iscsi->connect_data); iscsi->socket_status_cb = NULL; + if (iscsi->old_iscsi && iscsi->opaque != iscsi->old_iscsi->opaque) { + struct iser_conn *old_iser_conn = iscsi->old_iscsi->opaque; + int oldfd = old_iser_conn->comp_channel->fd; + int newfd = iser_conn->comp_channel->fd; + + iser_conn_terminate(old_iser_conn); + iser_conn_release(old_iser_conn); + + if (dup2(newfd, oldfd) == -1) { + return -1; + } + + close(newfd); + iser_conn->comp_channel->fd = oldfd; + + iscsi_free(iscsi->old_iscsi, iscsi->old_iscsi->opaque); + iscsi->old_iscsi->opaque = NULL; + } + return 0; }