You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
50 lines
1.6 KiB
50 lines
1.6 KiB
From b104afd497502321765c2c1ed3f020b1fe4b400a Mon Sep 17 00:00:00 2001 |
|
From: Chris Leech <cleech@redhat.com> |
|
Date: Mon, 29 Feb 2016 14:13:27 -0800 |
|
Subject: [PATCH v2 4/9] iscsi_tcp set SO_LINGER to abort connection for error |
|
handling |
|
|
|
When requests are being failed it's important to abort the TCP |
|
connection rather than let TCP wait and attempt a graceful shutdown. |
|
|
|
That can be accomplished by setting the SO_LINGER socket option with a |
|
linger time of 0 to drop queued data and close the connection with a RST |
|
instead of a FIN. |
|
|
|
Signed-off-by: Chris Leech <cleech@redhat.com> |
|
--- |
|
usr/io.c | 15 +++++++++++++++ |
|
1 file changed, 15 insertions(+) |
|
|
|
diff --git a/usr/io.c b/usr/io.c |
|
index f552e1e..48b233c 100644 |
|
--- a/usr/io.c |
|
+++ b/usr/io.c |
|
@@ -391,9 +391,24 @@ iscsi_io_tcp_poll(iscsi_conn_t *conn, int timeout_ms) |
|
void |
|
iscsi_io_tcp_disconnect(iscsi_conn_t *conn) |
|
{ |
|
+ struct linger so_linger = { .l_onoff = 1, .l_linger = 0 }; |
|
+ |
|
if (conn->socket_fd >= 0) { |
|
log_debug(1, "disconnecting conn %p, fd %d", conn, |
|
conn->socket_fd); |
|
+ |
|
+ /* If the state is not IN_LOGOUT, this isn't a clean shutdown |
|
+ * and there's some sort of error handling going on. In that |
|
+ * case, set a 0 SO_LINGER to force an abortive close (RST) and |
|
+ * free whatever is sitting in the TCP transmit queue. This is |
|
+ * done to prevent stale data from being sent should the |
|
+ * network connection be restored before TCP times out. |
|
+ */ |
|
+ if (conn->state != ISCSI_CONN_STATE_IN_LOGOUT) { |
|
+ setsockopt(conn->socket_fd, SOL_SOCKET, SO_LINGER, |
|
+ &so_linger, sizeof(so_linger)); |
|
+ } |
|
+ |
|
close(conn->socket_fd); |
|
conn->socket_fd = -1; |
|
} |
|
-- |
|
2.5.5 |
|
|
|
|