diff options
author | Wenchao Hao <haowenchao@huawei.com> | 2022-03-04 00:37:56 +0800 |
---|---|---|
committer | Wenchao Hao <haowenchao@huawei.com> | 2022-03-04 00:46:49 +0800 |
commit | 194bf3a70339e001ea468f0b930ac2011b2d472a (patch) | |
tree | e42dd5ca277d9e252f27a1a9221b33152c30cd38 /usr | |
parent | d3d27e4a4d4e86a59509c8cfe369f5e3738212c0 (diff) | |
download | open-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.c | 24 |
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), |