summaryrefslogtreecommitdiff
path: root/usr
diff options
context:
space:
mode:
authorWenchao Hao <haowenchao@huawei.com>2022-03-04 00:37:56 +0800
committerWenchao Hao <haowenchao@huawei.com>2022-03-04 00:46:49 +0800
commit194bf3a70339e001ea468f0b930ac2011b2d472a (patch)
treee42dd5ca277d9e252f27a1a9221b33152c30cd38 /usr
parentd3d27e4a4d4e86a59509c8cfe369f5e3738212c0 (diff)
downloadopen-iscsi-194bf3a70339e001ea468f0b930ac2011b2d472a.tar.gz
initiator: return ENOMEM if failed to get ev_context in iscsi_send_logout()
If iscsi_send_logout() is called from iscsi_stop() or session_login_task() and return 0, the next logout flow such as session_conn_shutdown() depends on target's logout response and logout timeout. While if iscsi_send_logout() failed to trigger a logout timeout task, and target's logout response absent, the logout flow would hang. So we should return error if iscsi_send_logout() failed to trigger a logout timeout task. And add comment about handle logic if iscsi_send_logout() failed from iscsi_recv_async_msg() by hand. Signed-off-by: Wenchao Hao <haowenchao@huawei.com>
Diffstat (limited to 'usr')
-rw-r--r--usr/initiator.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/usr/initiator.c b/usr/initiator.c
index 503ccba..bc0908b 100644
--- a/usr/initiator.c
+++ b/usr/initiator.c
@@ -1124,11 +1124,12 @@ static int iscsi_send_logout(iscsi_conn_t *conn)
conn->state = ISCSI_CONN_STATE_IN_LOGOUT;
ev_context = iscsi_ev_context_get(conn, 0);
- if (!ev_context)
+ if (!ev_context) {
/* unbounded logout */
log_warning("connection%d:%d Could not allocate conn context for logout.",
conn->session->id, conn->id);
- else {
+ return ENOMEM;
+ } else {
iscsi_sched_ev_context(ev_context, conn,
conn->logout_timeout,
EV_CONN_LOGOUT_TIMER);
@@ -1199,6 +1200,7 @@ static void iscsi_recv_async_msg(iscsi_conn_t *conn, struct iscsi_hdr *hdr)
char *buf = conn->data;
unsigned int senselen;
struct scsi_sense_hdr sshdr;
+ int rc = 0;
conn_debug(3, conn, "Read AEN %d", async_hdr->async_event);
@@ -1219,9 +1221,23 @@ static void iscsi_recv_async_msg(iscsi_conn_t *conn, struct iscsi_hdr *hdr)
break;
case ISCSI_ASYNC_MSG_REQUEST_LOGOUT:
conn_warn(conn, "Target requests logout within %u seconds" , ntohs(async_hdr->param3));
- if (iscsi_send_logout(conn))
+ /*
+ * for ASYNC LOUOUT request, initiator would try to send a
+ * logout request and desire target's logout response, in
+ * logout response handler, initiator would call __conn_error_handle()
+ * to try to relogin.
+ *
+ * While if iscsi_send_logout() failed, we don't know what target
+ * would do, maybe target would close connection? Which would trigger
+ * initiator relogin too.
+ *
+ * Now we just print an error log to tell the iscsi_send_logout()
+ * failed and the failed reason, do nothing special.
+ */
+ rc = iscsi_send_logout(conn);
+ if (rc)
conn_error(conn, "Could not send logout in response to"
- "logout request aen");
+ "logout request aen:%s", strerror(rc));
break;
case ISCSI_ASYNC_MSG_DROPPING_CONNECTION:
conn_warn(conn, "Target dropping %u, reconnect min %u max %u", ntohs(async_hdr->param1),