Merge pull request #204 from plieven/fix_segv
Fix seg fault on reconnect/timeout
This commit is contained in:
@@ -228,8 +228,6 @@ struct iscsi_pdu {
|
|||||||
|
|
||||||
/* There will not be a response to this pdu, so delete it once it is sent on the wire. Don't put it on the wait-queue */
|
/* There will not be a response to this pdu, so delete it once it is sent on the wire. Don't put it on the wait-queue */
|
||||||
#define ISCSI_PDU_DELETE_WHEN_SENT 0x00000001
|
#define ISCSI_PDU_DELETE_WHEN_SENT 0x00000001
|
||||||
/* Don't call the CANCEL callback when the context is destroyed */
|
|
||||||
#define ISCSI_PDU_NO_CALLBACK 0x00000002
|
|
||||||
/* When reconnecting, just drop all these PDUs. Don't re-queue them.
|
/* When reconnecting, just drop all these PDUs. Don't re-queue them.
|
||||||
* This includes any DATA-OUT PDU as well as all NOPs.
|
* This includes any DATA-OUT PDU as well as all NOPs.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -270,25 +270,23 @@ void iscsi_defer_reconnect(struct iscsi_context *iscsi)
|
|||||||
|
|
||||||
while ((pdu = iscsi->outqueue)) {
|
while ((pdu = iscsi->outqueue)) {
|
||||||
ISCSI_LIST_REMOVE(&iscsi->outqueue, pdu);
|
ISCSI_LIST_REMOVE(&iscsi->outqueue, pdu);
|
||||||
if ( !(pdu->flags & ISCSI_PDU_NO_CALLBACK)) {
|
if (iscsi->is_loggedin && pdu->callback) {
|
||||||
/* If an error happened during connect/login,
|
/* If an error happened during connect/login,
|
||||||
we don't want to call any of the callbacks.
|
we don't want to call any of the callbacks.
|
||||||
*/
|
*/
|
||||||
if (iscsi->is_loggedin) {
|
pdu->callback(iscsi, SCSI_STATUS_CANCELLED,
|
||||||
pdu->callback(iscsi, SCSI_STATUS_CANCELLED,
|
NULL, pdu->private_data);
|
||||||
NULL, pdu->private_data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
iscsi_free_pdu(iscsi, pdu);
|
iscsi_free_pdu(iscsi, pdu);
|
||||||
}
|
}
|
||||||
while ((pdu = iscsi->waitpdu)) {
|
while ((pdu = iscsi->waitpdu)) {
|
||||||
ISCSI_LIST_REMOVE(&iscsi->waitpdu, pdu);
|
ISCSI_LIST_REMOVE(&iscsi->waitpdu, pdu);
|
||||||
/* If an error happened during connect/login,
|
if (iscsi->is_loggedin && pdu->callback) {
|
||||||
we don't want to call any of the callbacks.
|
/* If an error happened during connect/login,
|
||||||
*/
|
we don't want to call any of the callbacks.
|
||||||
if (iscsi->is_loggedin) {
|
*/
|
||||||
pdu->callback(iscsi, SCSI_STATUS_CANCELLED,
|
pdu->callback(iscsi, SCSI_STATUS_CANCELLED,
|
||||||
NULL, pdu->private_data);
|
NULL, pdu->private_data);
|
||||||
}
|
}
|
||||||
iscsi_free_pdu(iscsi, pdu);
|
iscsi_free_pdu(iscsi, pdu);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,8 +127,10 @@ iscsi_process_text_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
|||||||
if (in->hdr[1] != ISCSI_PDU_TEXT_FINAL) {
|
if (in->hdr[1] != ISCSI_PDU_TEXT_FINAL) {
|
||||||
iscsi_set_error(iscsi, "unsupported flags in text "
|
iscsi_set_error(iscsi, "unsupported flags in text "
|
||||||
"reply %02x", in->hdr[1]);
|
"reply %02x", in->hdr[1]);
|
||||||
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
if (pdu->callback) {
|
||||||
pdu->private_data);
|
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
||||||
|
pdu->private_data);
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,8 +143,10 @@ iscsi_process_text_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
|||||||
iscsi_set_error(iscsi, "NUL not found after offset %ld "
|
iscsi_set_error(iscsi, "NUL not found after offset %ld "
|
||||||
"when parsing discovery data",
|
"when parsing discovery data",
|
||||||
(long)(ptr - in->data));
|
(long)(ptr - in->data));
|
||||||
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
if (pdu->callback) {
|
||||||
pdu->private_data);
|
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
||||||
|
pdu->private_data);
|
||||||
|
}
|
||||||
iscsi_free_discovery_addresses(iscsi, targets);
|
iscsi_free_discovery_addresses(iscsi, targets);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -161,8 +165,10 @@ iscsi_process_text_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
|||||||
iscsi_set_error(iscsi, "Failed to allocate "
|
iscsi_set_error(iscsi, "Failed to allocate "
|
||||||
"data for new discovered "
|
"data for new discovered "
|
||||||
"target");
|
"target");
|
||||||
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
if (pdu->callback) {
|
||||||
pdu->private_data);
|
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
||||||
|
pdu->private_data);
|
||||||
|
}
|
||||||
iscsi_free_discovery_addresses(iscsi, targets);
|
iscsi_free_discovery_addresses(iscsi, targets);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -171,8 +177,10 @@ iscsi_process_text_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
|||||||
iscsi_set_error(iscsi, "Failed to allocate "
|
iscsi_set_error(iscsi, "Failed to allocate "
|
||||||
"data for new discovered "
|
"data for new discovered "
|
||||||
"target name");
|
"target name");
|
||||||
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
if (pdu->callback) {
|
||||||
pdu->private_data);
|
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
||||||
|
pdu->private_data);
|
||||||
|
}
|
||||||
iscsi_free(iscsi, target);
|
iscsi_free(iscsi, target);
|
||||||
target = NULL;
|
target = NULL;
|
||||||
iscsi_free_discovery_addresses(iscsi, targets);
|
iscsi_free_discovery_addresses(iscsi, targets);
|
||||||
@@ -186,8 +194,10 @@ iscsi_process_text_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
|||||||
if (targets == NULL) {
|
if (targets == NULL) {
|
||||||
iscsi_set_error(iscsi, "Invalid discovery "
|
iscsi_set_error(iscsi, "Invalid discovery "
|
||||||
"reply");
|
"reply");
|
||||||
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
if (pdu->callback) {
|
||||||
pdu->private_data);
|
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
||||||
|
pdu->private_data);
|
||||||
|
}
|
||||||
iscsi_free_discovery_addresses(iscsi, targets);
|
iscsi_free_discovery_addresses(iscsi, targets);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -195,8 +205,10 @@ iscsi_process_text_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
|||||||
if (portal == NULL) {
|
if (portal == NULL) {
|
||||||
iscsi_set_error(iscsi, "Failed to malloc "
|
iscsi_set_error(iscsi, "Failed to malloc "
|
||||||
"portal structure");
|
"portal structure");
|
||||||
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
if (pdu->callback) {
|
||||||
pdu->private_data);
|
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
||||||
|
pdu->private_data);
|
||||||
|
}
|
||||||
iscsi_free_discovery_addresses(iscsi, targets);
|
iscsi_free_discovery_addresses(iscsi, targets);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -209,16 +221,20 @@ iscsi_process_text_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
|||||||
iscsi_set_error(iscsi, "Failed to allocate "
|
iscsi_set_error(iscsi, "Failed to allocate "
|
||||||
"data for new discovered "
|
"data for new discovered "
|
||||||
"target address");
|
"target address");
|
||||||
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
if (pdu->callback) {
|
||||||
pdu->private_data);
|
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
||||||
|
pdu->private_data);
|
||||||
|
}
|
||||||
iscsi_free_discovery_addresses(iscsi, targets);
|
iscsi_free_discovery_addresses(iscsi, targets);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
iscsi_set_error(iscsi, "Don't know how to handle "
|
iscsi_set_error(iscsi, "Don't know how to handle "
|
||||||
"discovery string : %s", ptr);
|
"discovery string : %s", ptr);
|
||||||
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
if (pdu->callback) {
|
||||||
pdu->private_data);
|
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
||||||
|
pdu->private_data);
|
||||||
|
}
|
||||||
iscsi_free_discovery_addresses(iscsi, targets);
|
iscsi_free_discovery_addresses(iscsi, targets);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -227,7 +243,9 @@ iscsi_process_text_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
|||||||
size -= len + 1;
|
size -= len + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pdu->callback(iscsi, SCSI_STATUS_GOOD, targets, pdu->private_data);
|
if (pdu->callback) {
|
||||||
|
pdu->callback(iscsi, SCSI_STATUS_GOOD, targets, pdu->private_data);
|
||||||
|
}
|
||||||
iscsi_free_discovery_addresses(iscsi, targets);
|
iscsi_free_discovery_addresses(iscsi, targets);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
18
lib/init.c
18
lib/init.c
@@ -304,25 +304,23 @@ iscsi_destroy_context(struct iscsi_context *iscsi)
|
|||||||
|
|
||||||
while ((pdu = iscsi->outqueue)) {
|
while ((pdu = iscsi->outqueue)) {
|
||||||
ISCSI_LIST_REMOVE(&iscsi->outqueue, pdu);
|
ISCSI_LIST_REMOVE(&iscsi->outqueue, pdu);
|
||||||
if ( !(pdu->flags & ISCSI_PDU_NO_CALLBACK)) {
|
if (iscsi->is_loggedin && pdu->callback) {
|
||||||
/* If an error happened during connect/login, we don't want to
|
/* If an error happened during connect/login, we don't want to
|
||||||
call any of the callbacks.
|
call any of the callbacks.
|
||||||
*/
|
*/
|
||||||
if (iscsi->is_loggedin && pdu->callback != NULL) {
|
pdu->callback(iscsi, SCSI_STATUS_CANCELLED, NULL,
|
||||||
pdu->callback(iscsi, SCSI_STATUS_CANCELLED, NULL,
|
pdu->private_data);
|
||||||
pdu->private_data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
iscsi_free_pdu(iscsi, pdu);
|
iscsi_free_pdu(iscsi, pdu);
|
||||||
}
|
}
|
||||||
while ((pdu = iscsi->waitpdu)) {
|
while ((pdu = iscsi->waitpdu)) {
|
||||||
ISCSI_LIST_REMOVE(&iscsi->waitpdu, pdu);
|
ISCSI_LIST_REMOVE(&iscsi->waitpdu, pdu);
|
||||||
/* If an error happened during connect/login, we don't want to
|
if (iscsi->is_loggedin && pdu->callback) {
|
||||||
call any of the callbacks.
|
/* If an error happened during connect/login, we don't want to
|
||||||
*/
|
call any of the callbacks.
|
||||||
if (iscsi->is_loggedin && pdu->callback != NULL) {
|
*/
|
||||||
pdu->callback(iscsi, SCSI_STATUS_CANCELLED, NULL,
|
pdu->callback(iscsi, SCSI_STATUS_CANCELLED, NULL,
|
||||||
pdu->private_data);
|
pdu->private_data);
|
||||||
}
|
}
|
||||||
iscsi_free_pdu(iscsi, pdu);
|
iscsi_free_pdu(iscsi, pdu);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,15 +59,19 @@ iscsi_scsi_response_cb(struct iscsi_context *iscsi, int status,
|
|||||||
case SCSI_STATUS_CANCELLED:
|
case SCSI_STATUS_CANCELLED:
|
||||||
case SCSI_STATUS_TIMEOUT:
|
case SCSI_STATUS_TIMEOUT:
|
||||||
scsi_cbdata->task->status = status;
|
scsi_cbdata->task->status = status;
|
||||||
scsi_cbdata->callback(iscsi, status, scsi_cbdata->task,
|
if (scsi_cbdata->callback) {
|
||||||
scsi_cbdata->private_data);
|
scsi_cbdata->callback(iscsi, status, scsi_cbdata->task,
|
||||||
|
scsi_cbdata->private_data);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
scsi_cbdata->task->status = SCSI_STATUS_ERROR;
|
scsi_cbdata->task->status = SCSI_STATUS_ERROR;
|
||||||
iscsi_set_error(iscsi, "Cant handle scsi status %d yet.",
|
iscsi_set_error(iscsi, "Cant handle scsi status %d yet.",
|
||||||
status);
|
status);
|
||||||
scsi_cbdata->callback(iscsi, SCSI_STATUS_ERROR, scsi_cbdata->task,
|
if (scsi_cbdata->callback) {
|
||||||
scsi_cbdata->private_data);
|
scsi_cbdata->callback(iscsi, SCSI_STATUS_ERROR, scsi_cbdata->task,
|
||||||
|
scsi_cbdata->private_data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,17 +90,11 @@ iscsi_send_data_out(struct iscsi_context *iscsi, struct iscsi_pdu *cmd_pdu,
|
|||||||
ISCSI_PDU_DATA_OUT,
|
ISCSI_PDU_DATA_OUT,
|
||||||
ISCSI_PDU_NO_PDU,
|
ISCSI_PDU_NO_PDU,
|
||||||
cmd_pdu->itt,
|
cmd_pdu->itt,
|
||||||
ISCSI_PDU_DROP_ON_RECONNECT|ISCSI_PDU_DELETE_WHEN_SENT|ISCSI_PDU_NO_CALLBACK);
|
ISCSI_PDU_DROP_ON_RECONNECT|ISCSI_PDU_DELETE_WHEN_SENT);
|
||||||
if (pdu == NULL) {
|
if (pdu == NULL) {
|
||||||
iscsi_set_error(iscsi, "Out-of-memory, Failed to allocate "
|
iscsi_set_error(iscsi, "Out-of-memory, Failed to allocate "
|
||||||
"scsi data out pdu.");
|
"scsi data out pdu.");
|
||||||
ISCSI_LIST_REMOVE(&iscsi->outqueue, cmd_pdu);
|
goto error;
|
||||||
ISCSI_LIST_REMOVE(&iscsi->waitpdu, cmd_pdu);
|
|
||||||
cmd_pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
|
||||||
cmd_pdu->private_data);
|
|
||||||
iscsi_free_pdu(iscsi, cmd_pdu);
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
pdu->scsi_cbdata.task = cmd_pdu->scsi_cbdata.task;
|
pdu->scsi_cbdata.task = cmd_pdu->scsi_cbdata.task;
|
||||||
/* set the cmdsn in the pdu struct so we can compare with
|
/* set the cmdsn in the pdu struct so we can compare with
|
||||||
@@ -131,25 +129,26 @@ iscsi_send_data_out(struct iscsi_context *iscsi, struct iscsi_pdu *cmd_pdu,
|
|||||||
/* update data segment length */
|
/* update data segment length */
|
||||||
scsi_set_uint32(&pdu->outdata.data[4], pdu->payload_len);
|
scsi_set_uint32(&pdu->outdata.data[4], pdu->payload_len);
|
||||||
|
|
||||||
pdu->callback = cmd_pdu->callback;
|
|
||||||
pdu->private_data = cmd_pdu->private_data;
|
|
||||||
|
|
||||||
if (iscsi_queue_pdu(iscsi, pdu) != 0) {
|
if (iscsi_queue_pdu(iscsi, pdu) != 0) {
|
||||||
iscsi_set_error(iscsi, "Out-of-memory: failed to queue iscsi "
|
iscsi_set_error(iscsi, "Out-of-memory: failed to queue iscsi "
|
||||||
"scsi pdu.");
|
"scsi pdu.");
|
||||||
ISCSI_LIST_REMOVE(&iscsi->outqueue, cmd_pdu);
|
goto error;
|
||||||
ISCSI_LIST_REMOVE(&iscsi->waitpdu, cmd_pdu);
|
|
||||||
cmd_pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
|
||||||
cmd_pdu->private_data);
|
|
||||||
iscsi_free_pdu(iscsi, cmd_pdu);
|
|
||||||
iscsi_free_pdu(iscsi, pdu);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tot_len -= len;
|
tot_len -= len;
|
||||||
offset += len;
|
offset += len;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
ISCSI_LIST_REMOVE(&iscsi->outqueue, cmd_pdu);
|
||||||
|
ISCSI_LIST_REMOVE(&iscsi->waitpdu, cmd_pdu);
|
||||||
|
if (cmd_pdu->callback) {
|
||||||
|
cmd_pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
||||||
|
cmd_pdu->private_data);
|
||||||
|
}
|
||||||
|
iscsi_free_pdu(iscsi, cmd_pdu);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -373,15 +372,19 @@ iscsi_process_scsi_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
|||||||
if ((flags&ISCSI_PDU_DATA_FINAL) == 0) {
|
if ((flags&ISCSI_PDU_DATA_FINAL) == 0) {
|
||||||
iscsi_set_error(iscsi, "scsi response pdu but Final bit is "
|
iscsi_set_error(iscsi, "scsi response pdu but Final bit is "
|
||||||
"not set: 0x%02x.", flags);
|
"not set: 0x%02x.", flags);
|
||||||
pdu->callback(iscsi, SCSI_STATUS_ERROR, task,
|
if (pdu->callback) {
|
||||||
pdu->private_data);
|
pdu->callback(iscsi, SCSI_STATUS_ERROR, task,
|
||||||
|
pdu->private_data);
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if ((flags&ISCSI_PDU_DATA_ACK_REQUESTED) != 0) {
|
if ((flags&ISCSI_PDU_DATA_ACK_REQUESTED) != 0) {
|
||||||
iscsi_set_error(iscsi, "scsi response asked for ACK "
|
iscsi_set_error(iscsi, "scsi response asked for ACK "
|
||||||
"0x%02x.", flags);
|
"0x%02x.", flags);
|
||||||
pdu->callback(iscsi, SCSI_STATUS_ERROR, task,
|
if (pdu->callback) {
|
||||||
pdu->private_data);
|
pdu->callback(iscsi, SCSI_STATUS_ERROR, task,
|
||||||
|
pdu->private_data);
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -395,8 +398,10 @@ iscsi_process_scsi_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
|||||||
if (response != 0) {
|
if (response != 0) {
|
||||||
iscsi_set_error(iscsi, "protocol error: flags %#02x;"
|
iscsi_set_error(iscsi, "protocol error: flags %#02x;"
|
||||||
" response %#02x.", flags, response);
|
" response %#02x.", flags, response);
|
||||||
pdu->callback(iscsi, SCSI_STATUS_ERROR, task,
|
if (pdu->callback) {
|
||||||
pdu->private_data);
|
pdu->callback(iscsi, SCSI_STATUS_ERROR, task,
|
||||||
|
pdu->private_data);
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
task->residual = scsi_get_uint32(&in->hdr[44]);
|
task->residual = scsi_get_uint32(&in->hdr[44]);
|
||||||
@@ -424,8 +429,10 @@ iscsi_process_scsi_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
|||||||
pdu->indata.data = NULL;
|
pdu->indata.data = NULL;
|
||||||
pdu->indata.size = 0;
|
pdu->indata.size = 0;
|
||||||
|
|
||||||
pdu->callback(iscsi, SCSI_STATUS_GOOD, task,
|
if (pdu->callback) {
|
||||||
pdu->private_data);
|
pdu->callback(iscsi, SCSI_STATUS_GOOD, task,
|
||||||
|
pdu->private_data);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SCSI_STATUS_CHECK_CONDITION:
|
case SCSI_STATUS_CHECK_CONDITION:
|
||||||
task->datain.size = in->data_pos;
|
task->datain.size = in->data_pos;
|
||||||
@@ -443,39 +450,52 @@ iscsi_process_scsi_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
|||||||
task->sense.key,
|
task->sense.key,
|
||||||
scsi_sense_ascq_str(task->sense.ascq),
|
scsi_sense_ascq_str(task->sense.ascq),
|
||||||
task->sense.ascq);
|
task->sense.ascq);
|
||||||
pdu->callback(iscsi, SCSI_STATUS_CHECK_CONDITION, task,
|
if (pdu->callback) {
|
||||||
pdu->private_data);
|
pdu->callback(iscsi, SCSI_STATUS_CHECK_CONDITION, task,
|
||||||
|
pdu->private_data);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SCSI_STATUS_RESERVATION_CONFLICT:
|
case SCSI_STATUS_RESERVATION_CONFLICT:
|
||||||
iscsi_set_error(iscsi, "RESERVATION CONFLICT");
|
iscsi_set_error(iscsi, "RESERVATION CONFLICT");
|
||||||
pdu->callback(iscsi, SCSI_STATUS_RESERVATION_CONFLICT,
|
if (pdu->callback) {
|
||||||
task, pdu->private_data);
|
pdu->callback(iscsi, SCSI_STATUS_RESERVATION_CONFLICT,
|
||||||
|
task, pdu->private_data);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SCSI_STATUS_TASK_SET_FULL:
|
case SCSI_STATUS_TASK_SET_FULL:
|
||||||
iscsi_set_error(iscsi, "TASK_SET_FULL");
|
iscsi_set_error(iscsi, "TASK_SET_FULL");
|
||||||
pdu->callback(iscsi, SCSI_STATUS_TASK_SET_FULL,
|
if (pdu->callback) {
|
||||||
task, pdu->private_data);
|
pdu->callback(iscsi, SCSI_STATUS_TASK_SET_FULL,
|
||||||
|
task, pdu->private_data);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SCSI_STATUS_ACA_ACTIVE:
|
case SCSI_STATUS_ACA_ACTIVE:
|
||||||
iscsi_set_error(iscsi, "ACA_ACTIVE");
|
iscsi_set_error(iscsi, "ACA_ACTIVE");
|
||||||
pdu->callback(iscsi, SCSI_STATUS_ACA_ACTIVE,
|
if (pdu->callback) {
|
||||||
task, pdu->private_data);
|
pdu->callback(iscsi, SCSI_STATUS_ACA_ACTIVE,
|
||||||
|
task, pdu->private_data);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SCSI_STATUS_TASK_ABORTED:
|
case SCSI_STATUS_TASK_ABORTED:
|
||||||
iscsi_set_error(iscsi, "TASK_ABORTED");
|
iscsi_set_error(iscsi, "TASK_ABORTED");
|
||||||
pdu->callback(iscsi, SCSI_STATUS_TASK_ABORTED,
|
if (pdu->callback) {
|
||||||
task, pdu->private_data);
|
pdu->callback(iscsi, SCSI_STATUS_TASK_ABORTED,
|
||||||
|
task, pdu->private_data);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SCSI_STATUS_BUSY:
|
case SCSI_STATUS_BUSY:
|
||||||
iscsi_set_error(iscsi, "BUSY");
|
iscsi_set_error(iscsi, "BUSY");
|
||||||
pdu->callback(iscsi, SCSI_STATUS_BUSY,
|
if (pdu->callback) {
|
||||||
task, pdu->private_data);
|
pdu->callback(iscsi, SCSI_STATUS_BUSY,
|
||||||
|
task, pdu->private_data);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
iscsi_set_error(iscsi, "Unknown SCSI status :%d.", status);
|
iscsi_set_error(iscsi, "Unknown SCSI status :%d.", status);
|
||||||
|
if (pdu->callback) {
|
||||||
pdu->callback(iscsi, SCSI_STATUS_ERROR, task,
|
pdu->callback(iscsi, SCSI_STATUS_ERROR,
|
||||||
pdu->private_data);
|
task, pdu->private_data);
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -495,8 +515,10 @@ iscsi_process_scsi_data_in(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
|||||||
if ((flags&ISCSI_PDU_DATA_ACK_REQUESTED) != 0) {
|
if ((flags&ISCSI_PDU_DATA_ACK_REQUESTED) != 0) {
|
||||||
iscsi_set_error(iscsi, "scsi response asked for ACK "
|
iscsi_set_error(iscsi, "scsi response asked for ACK "
|
||||||
"0x%02x.", flags);
|
"0x%02x.", flags);
|
||||||
pdu->callback(iscsi, SCSI_STATUS_ERROR, task,
|
if (pdu->callback) {
|
||||||
pdu->private_data);
|
pdu->callback(iscsi, SCSI_STATUS_ERROR, task,
|
||||||
|
pdu->private_data);
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
dsl = scsi_get_uint32(&in->hdr[4]) & 0x00ffffff;
|
dsl = scsi_get_uint32(&in->hdr[4]) & 0x00ffffff;
|
||||||
@@ -553,7 +575,9 @@ iscsi_process_scsi_data_in(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
|||||||
pdu->indata.data = NULL;
|
pdu->indata.data = NULL;
|
||||||
pdu->indata.size = 0;
|
pdu->indata.size = 0;
|
||||||
|
|
||||||
pdu->callback(iscsi, status, task, pdu->private_data);
|
if (pdu->callback) {
|
||||||
|
pdu->callback(iscsi, status, task, pdu->private_data);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1894,7 +1918,7 @@ iscsi_scsi_cancel_task(struct iscsi_context *iscsi,
|
|||||||
for (pdu = iscsi->waitpdu; pdu; pdu = pdu->next) {
|
for (pdu = iscsi->waitpdu; pdu; pdu = pdu->next) {
|
||||||
if (pdu->itt == task->itt) {
|
if (pdu->itt == task->itt) {
|
||||||
ISCSI_LIST_REMOVE(&iscsi->waitpdu, pdu);
|
ISCSI_LIST_REMOVE(&iscsi->waitpdu, pdu);
|
||||||
if ( !(pdu->flags & ISCSI_PDU_NO_CALLBACK)) {
|
if (pdu->callback) {
|
||||||
pdu->callback(iscsi, SCSI_STATUS_CANCELLED, NULL,
|
pdu->callback(iscsi, SCSI_STATUS_CANCELLED, NULL,
|
||||||
pdu->private_data);
|
pdu->private_data);
|
||||||
}
|
}
|
||||||
@@ -1905,7 +1929,7 @@ iscsi_scsi_cancel_task(struct iscsi_context *iscsi,
|
|||||||
for (pdu = iscsi->outqueue; pdu; pdu = pdu->next) {
|
for (pdu = iscsi->outqueue; pdu; pdu = pdu->next) {
|
||||||
if (pdu->itt == task->itt) {
|
if (pdu->itt == task->itt) {
|
||||||
ISCSI_LIST_REMOVE(&iscsi->outqueue, pdu);
|
ISCSI_LIST_REMOVE(&iscsi->outqueue, pdu);
|
||||||
if ( !(pdu->flags & ISCSI_PDU_NO_CALLBACK)) {
|
if (pdu->callback) {
|
||||||
pdu->callback(iscsi, SCSI_STATUS_CANCELLED, NULL,
|
pdu->callback(iscsi, SCSI_STATUS_CANCELLED, NULL,
|
||||||
pdu->private_data);
|
pdu->private_data);
|
||||||
}
|
}
|
||||||
@@ -1923,7 +1947,7 @@ iscsi_scsi_cancel_all_tasks(struct iscsi_context *iscsi)
|
|||||||
|
|
||||||
while ((pdu = iscsi->waitpdu)) {
|
while ((pdu = iscsi->waitpdu)) {
|
||||||
ISCSI_LIST_REMOVE(&iscsi->waitpdu, pdu);
|
ISCSI_LIST_REMOVE(&iscsi->waitpdu, pdu);
|
||||||
if ( !(pdu->flags & ISCSI_PDU_NO_CALLBACK)) {
|
if (pdu->callback) {
|
||||||
pdu->callback(iscsi, SCSI_STATUS_CANCELLED, NULL,
|
pdu->callback(iscsi, SCSI_STATUS_CANCELLED, NULL,
|
||||||
pdu->private_data);
|
pdu->private_data);
|
||||||
}
|
}
|
||||||
@@ -1931,7 +1955,7 @@ iscsi_scsi_cancel_all_tasks(struct iscsi_context *iscsi)
|
|||||||
}
|
}
|
||||||
while ((pdu = iscsi->outqueue)) {
|
while ((pdu = iscsi->outqueue)) {
|
||||||
ISCSI_LIST_REMOVE(&iscsi->outqueue, pdu);
|
ISCSI_LIST_REMOVE(&iscsi->outqueue, pdu);
|
||||||
if ( !(pdu->flags & ISCSI_PDU_NO_CALLBACK)) {
|
if (pdu->callback) {
|
||||||
pdu->callback(iscsi, SCSI_STATUS_CANCELLED, NULL,
|
pdu->callback(iscsi, SCSI_STATUS_CANCELLED, NULL,
|
||||||
pdu->private_data);
|
pdu->private_data);
|
||||||
}
|
}
|
||||||
|
|||||||
62
lib/login.c
62
lib/login.c
@@ -1082,8 +1082,10 @@ iscsi_process_login_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
|||||||
iscsi_set_error(iscsi, "NUL not found after offset %ld "
|
iscsi_set_error(iscsi, "NUL not found after offset %ld "
|
||||||
"when parsing login data",
|
"when parsing login data",
|
||||||
(long)((unsigned char *)ptr - in->data));
|
(long)((unsigned char *)ptr - in->data));
|
||||||
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
if (pdu->callback) {
|
||||||
pdu->private_data);
|
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
||||||
|
pdu->private_data);
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1161,8 +1163,10 @@ iscsi_process_login_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
|||||||
if (len-9 > MAX_CHAP_C_LENGTH) {
|
if (len-9 > MAX_CHAP_C_LENGTH) {
|
||||||
iscsi_set_error(iscsi, "Wrong length of CHAP_C received from"
|
iscsi_set_error(iscsi, "Wrong length of CHAP_C received from"
|
||||||
" target (%d, max: %d)", len-9, MAX_CHAP_C_LENGTH);
|
" target (%d, max: %d)", len-9, MAX_CHAP_C_LENGTH);
|
||||||
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
if (pdu->callback) {
|
||||||
pdu->private_data);
|
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
||||||
|
pdu->private_data);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
*iscsi->chap_c = '\0';
|
*iscsi->chap_c = '\0';
|
||||||
@@ -1175,8 +1179,10 @@ iscsi_process_login_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
|||||||
iscsi_set_error(iscsi, "Failed to log in to"
|
iscsi_set_error(iscsi, "Failed to log in to"
|
||||||
" target. Wrong CHAP targetname"
|
" target. Wrong CHAP targetname"
|
||||||
" received: %s", ptr + 7);
|
" received: %s", ptr + 7);
|
||||||
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
if (pdu->callback) {
|
||||||
pdu->private_data);
|
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
||||||
|
pdu->private_data);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
must_have_chap_n = 0;
|
must_have_chap_n = 0;
|
||||||
@@ -1188,8 +1194,10 @@ iscsi_process_login_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
|||||||
if (len != 9 + 2 * CHAP_R_SIZE) {
|
if (len != 9 + 2 * CHAP_R_SIZE) {
|
||||||
iscsi_set_error(iscsi, "Wrong size of CHAP_R"
|
iscsi_set_error(iscsi, "Wrong size of CHAP_R"
|
||||||
" received from target.");
|
" received from target.");
|
||||||
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
if (pdu->callback) {
|
||||||
pdu->private_data);
|
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
||||||
|
pdu->private_data);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
for (i = 0; i < CHAP_R_SIZE; i++) {
|
for (i = 0; i < CHAP_R_SIZE; i++) {
|
||||||
@@ -1199,8 +1207,10 @@ iscsi_process_login_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
|||||||
iscsi_set_error(iscsi, "Authentication "
|
iscsi_set_error(iscsi, "Authentication "
|
||||||
"failed. Invalid CHAP_R "
|
"failed. Invalid CHAP_R "
|
||||||
"response from the target");
|
"response from the target");
|
||||||
pdu->callback(iscsi, SCSI_STATUS_ERROR,
|
if (pdu->callback) {
|
||||||
NULL, pdu->private_data);
|
pdu->callback(iscsi, SCSI_STATUS_ERROR,
|
||||||
|
NULL, pdu->private_data);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1213,32 +1223,40 @@ iscsi_process_login_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
|||||||
|
|
||||||
if (status == SCSI_STATUS_REDIRECT && iscsi->target_address[0]) {
|
if (status == SCSI_STATUS_REDIRECT && iscsi->target_address[0]) {
|
||||||
ISCSI_LOG(iscsi, 2, "target requests redirect to %s",iscsi->target_address);
|
ISCSI_LOG(iscsi, 2, "target requests redirect to %s",iscsi->target_address);
|
||||||
pdu->callback(iscsi, SCSI_STATUS_REDIRECT, NULL,
|
if (pdu->callback) {
|
||||||
pdu->private_data);
|
pdu->callback(iscsi, SCSI_STATUS_REDIRECT, NULL,
|
||||||
|
pdu->private_data);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
iscsi_set_error(iscsi, "Failed to log in to target. Status: %s(%d)",
|
iscsi_set_error(iscsi, "Failed to log in to target. Status: %s(%d)",
|
||||||
login_error_str(status), status);
|
login_error_str(status), status);
|
||||||
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
if (pdu->callback) {
|
||||||
pdu->private_data);
|
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
||||||
|
pdu->private_data);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (must_have_chap_n) {
|
if (must_have_chap_n) {
|
||||||
iscsi_set_error(iscsi, "Failed to log in to target. "
|
iscsi_set_error(iscsi, "Failed to log in to target. "
|
||||||
"It did not return CHAP_N during SECNEG.");
|
"It did not return CHAP_N during SECNEG.");
|
||||||
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
if (pdu->callback) {
|
||||||
pdu->private_data);
|
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
||||||
|
pdu->private_data);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (must_have_chap_r) {
|
if (must_have_chap_r) {
|
||||||
iscsi_set_error(iscsi, "Failed to log in to target. "
|
iscsi_set_error(iscsi, "Failed to log in to target. "
|
||||||
"It did not return CHAP_R during SECNEG.");
|
"It did not return CHAP_R during SECNEG.");
|
||||||
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
if (pdu->callback) {
|
||||||
pdu->private_data);
|
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
||||||
|
pdu->private_data);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1256,7 +1274,9 @@ iscsi_process_login_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
|||||||
} else {
|
} else {
|
||||||
if (iscsi_login_async(iscsi, pdu->callback, pdu->private_data) != 0) {
|
if (iscsi_login_async(iscsi, pdu->callback, pdu->private_data) != 0) {
|
||||||
iscsi_set_error(iscsi, "Failed to send continuation login pdu");
|
iscsi_set_error(iscsi, "Failed to send continuation login pdu");
|
||||||
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, pdu->private_data);
|
if (pdu->callback) {
|
||||||
|
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, pdu->private_data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1315,7 +1335,9 @@ struct iscsi_in_pdu *in _U_)
|
|||||||
{
|
{
|
||||||
iscsi->is_loggedin = 0;
|
iscsi->is_loggedin = 0;
|
||||||
ISCSI_LOG(iscsi, 2, "logout successful");
|
ISCSI_LOG(iscsi, 2, "logout successful");
|
||||||
pdu->callback(iscsi, SCSI_STATUS_GOOD, NULL, pdu->private_data);
|
if (pdu->callback) {
|
||||||
|
pdu->callback(iscsi, SCSI_STATUS_GOOD, NULL, pdu->private_data);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ iscsi_send_target_nop_out(struct iscsi_context *iscsi, uint32_t ttt, uint32_t lu
|
|||||||
ISCSI_PDU_NOP_OUT,
|
ISCSI_PDU_NOP_OUT,
|
||||||
ISCSI_PDU_NO_PDU,
|
ISCSI_PDU_NO_PDU,
|
||||||
0xffffffff,
|
0xffffffff,
|
||||||
ISCSI_PDU_DROP_ON_RECONNECT|ISCSI_PDU_DELETE_WHEN_SENT|ISCSI_PDU_NO_CALLBACK);
|
ISCSI_PDU_DROP_ON_RECONNECT|ISCSI_PDU_DELETE_WHEN_SENT);
|
||||||
if (pdu == NULL) {
|
if (pdu == NULL) {
|
||||||
iscsi_set_error(iscsi, "Failed to allocate nop-out pdu");
|
iscsi_set_error(iscsi, "Failed to allocate nop-out pdu");
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -365,7 +365,7 @@ int iscsi_process_reject(struct iscsi_context *iscsi,
|
|||||||
|
|
||||||
if (pdu->callback) {
|
if (pdu->callback) {
|
||||||
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL,
|
||||||
pdu->private_data);
|
pdu->private_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
ISCSI_LIST_REMOVE(&iscsi->waitpdu, pdu);
|
ISCSI_LIST_REMOVE(&iscsi->waitpdu, pdu);
|
||||||
@@ -708,7 +708,7 @@ iscsi_timeout_scan(struct iscsi_context *iscsi)
|
|||||||
iscsi_dump_pdu_header(iscsi, pdu->outdata.data);
|
iscsi_dump_pdu_header(iscsi, pdu->outdata.data);
|
||||||
if (pdu->callback) {
|
if (pdu->callback) {
|
||||||
pdu->callback(iscsi, SCSI_STATUS_TIMEOUT,
|
pdu->callback(iscsi, SCSI_STATUS_TIMEOUT,
|
||||||
NULL, pdu->private_data);
|
NULL, pdu->private_data);
|
||||||
}
|
}
|
||||||
iscsi_free_pdu(iscsi, pdu);
|
iscsi_free_pdu(iscsi, pdu);
|
||||||
}
|
}
|
||||||
@@ -728,7 +728,7 @@ iscsi_timeout_scan(struct iscsi_context *iscsi)
|
|||||||
iscsi_dump_pdu_header(iscsi, pdu->outdata.data);
|
iscsi_dump_pdu_header(iscsi, pdu->outdata.data);
|
||||||
if (pdu->callback) {
|
if (pdu->callback) {
|
||||||
pdu->callback(iscsi, SCSI_STATUS_TIMEOUT,
|
pdu->callback(iscsi, SCSI_STATUS_TIMEOUT,
|
||||||
NULL, pdu->private_data);
|
NULL, pdu->private_data);
|
||||||
}
|
}
|
||||||
iscsi_free_pdu(iscsi, pdu);
|
iscsi_free_pdu(iscsi, pdu);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,7 +78,6 @@ iscsi_task_mgmt_async(struct iscsi_context *iscsi,
|
|||||||
/* rcmdsn */
|
/* rcmdsn */
|
||||||
iscsi_pdu_set_rcmdsn(pdu, rcmdsn);
|
iscsi_pdu_set_rcmdsn(pdu, rcmdsn);
|
||||||
|
|
||||||
|
|
||||||
pdu->callback = cb;
|
pdu->callback = cb;
|
||||||
pdu->private_data = private_data;
|
pdu->private_data = private_data;
|
||||||
|
|
||||||
@@ -97,7 +96,9 @@ iscsi_process_task_mgmt_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu
|
|||||||
{
|
{
|
||||||
uint32_t response = in->hdr[2];
|
uint32_t response = in->hdr[2];
|
||||||
|
|
||||||
pdu->callback(iscsi, SCSI_STATUS_GOOD, &response, pdu->private_data);
|
if (pdu->callback) {
|
||||||
|
pdu->callback(iscsi, SCSI_STATUS_GOOD, &response, pdu->private_data);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user