Fail pending LOGOUT commands on session reconnect

Certain iSCSI commands such as NOP and LOGOUT commands are discarded instead
of re-queued when we have a session failure and reconnect.
Change the LOGOUT command to instead fail with SCSI_STATUS_ERROR when this
happens.

Otherwise, IF we are in iscsi_logout_sync() and we get a session failure
at the same-ish time we may end up automatically re-connecting the
session, but since we have discarded the logout command we will never
get a reply and will hang indefinitely in the event loop for synchronous
commands.
Arguably, we could also just return SCSI_STATUS_GOOD here since
when we perform a logout, we probably don't care too much about how we
disconnected from the server, only that we did disconnect from the server.
That is academic anyway since this only affects the sync API which is only
meant for trivial applications, which will likely not inspect the result
and just do a:
...
iscsi_logout_sync()
iscsi_destroy_context()
...
anyway.

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
This commit is contained in:
Ronnie Sahlberg
2015-12-15 21:17:50 -08:00
parent 8e1332d70a
commit 0407cf6aed
3 changed files with 15 additions and 1 deletions

View File

@@ -233,6 +233,8 @@ struct iscsi_pdu {
#define ISCSI_PDU_DROP_ON_RECONNECT 0x00000004
/* stop sending after this PDU has been sent */
#define ISCSI_PDU_CORK_WHEN_SENT 0x00000008
/* Fail the command with error on reconnect */
#define ISCSI_PDU_ERROR_ON_RECONNECT 0x00000016
uint32_t flags;

View File

@@ -336,6 +336,18 @@ void iscsi_reconnect_cb(struct iscsi_context *iscsi _U_, int status,
continue;
}
if (pdu->flags & ISCSI_PDU_ERROR_ON_RECONNECT) {
/*
* We only want to re-queue SCSI COMMAND PDUs.
* All other PDUs are discarded at this point.
* This includes DATA-OUT, NOP and task management.
*/
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
pdu->private_data);
iscsi_free_pdu(old_iscsi, pdu);
continue;
}
if (pdu->flags & ISCSI_PDU_DROP_ON_RECONNECT) {
/*
* We only want to re-queue SCSI COMMAND PDUs.

View File

@@ -1266,7 +1266,7 @@ iscsi_logout_async(struct iscsi_context *iscsi, iscsi_command_cb cb,
ISCSI_PDU_LOGOUT_REQUEST,
ISCSI_PDU_LOGOUT_RESPONSE,
iscsi_itt_post_increment(iscsi),
ISCSI_PDU_DROP_ON_RECONNECT|ISCSI_PDU_CORK_WHEN_SENT);
ISCSI_PDU_ERROR_ON_RECONNECT|ISCSI_PDU_CORK_WHEN_SENT);
if (pdu == NULL) {
iscsi_set_error(iscsi, "Out-of-memory: Failed to allocate "
"logout pdu.");