diff --git a/lib/discovery.c b/lib/discovery.c index d38004d..a6077cb 100644 --- a/lib/discovery.c +++ b/lib/discovery.c @@ -127,8 +127,10 @@ iscsi_process_text_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, if (in->hdr[1] != ISCSI_PDU_TEXT_FINAL) { iscsi_set_error(iscsi, "unsupported flags in text " "reply %02x", in->hdr[1]); - pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, - pdu->private_data); + if (pdu->callback) { + pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, + pdu->private_data); + } 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 " "when parsing discovery data", (long)(ptr - in->data)); - pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, - pdu->private_data); + if (pdu->callback) { + pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, + pdu->private_data); + } iscsi_free_discovery_addresses(iscsi, targets); 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 " "data for new discovered " "target"); - pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, - pdu->private_data); + if (pdu->callback) { + pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, + pdu->private_data); + } iscsi_free_discovery_addresses(iscsi, targets); 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 " "data for new discovered " "target name"); - pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, - pdu->private_data); + if (pdu->callback) { + pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, + pdu->private_data); + } iscsi_free(iscsi, target); target = NULL; 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) { iscsi_set_error(iscsi, "Invalid discovery " "reply"); - pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, - pdu->private_data); + if (pdu->callback) { + pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, + pdu->private_data); + } iscsi_free_discovery_addresses(iscsi, targets); return -1; } @@ -195,8 +205,10 @@ iscsi_process_text_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, if (portal == NULL) { iscsi_set_error(iscsi, "Failed to malloc " "portal structure"); - pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, - pdu->private_data); + if (pdu->callback) { + pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, + pdu->private_data); + } iscsi_free_discovery_addresses(iscsi, targets); 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 " "data for new discovered " "target address"); - pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, - pdu->private_data); + if (pdu->callback) { + pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, + pdu->private_data); + } iscsi_free_discovery_addresses(iscsi, targets); return -1; } } else { iscsi_set_error(iscsi, "Don't know how to handle " "discovery string : %s", ptr); - pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, - pdu->private_data); + if (pdu->callback) { + pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, + pdu->private_data); + } iscsi_free_discovery_addresses(iscsi, targets); return -1; } @@ -227,7 +243,9 @@ iscsi_process_text_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, 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); return 0; diff --git a/lib/iscsi-command.c b/lib/iscsi-command.c index c879ecf..a2c4463 100644 --- a/lib/iscsi-command.c +++ b/lib/iscsi-command.c @@ -59,15 +59,19 @@ iscsi_scsi_response_cb(struct iscsi_context *iscsi, int status, case SCSI_STATUS_CANCELLED: case SCSI_STATUS_TIMEOUT: scsi_cbdata->task->status = status; - scsi_cbdata->callback(iscsi, status, scsi_cbdata->task, - scsi_cbdata->private_data); + if (scsi_cbdata->callback) { + scsi_cbdata->callback(iscsi, status, scsi_cbdata->task, + scsi_cbdata->private_data); + } return; default: scsi_cbdata->task->status = SCSI_STATUS_ERROR; iscsi_set_error(iscsi, "Cant handle scsi status %d yet.", - status); - scsi_cbdata->callback(iscsi, SCSI_STATUS_ERROR, scsi_cbdata->task, - scsi_cbdata->private_data); + status); + if (scsi_cbdata->callback) { + scsi_cbdata->callback(iscsi, SCSI_STATUS_ERROR, scsi_cbdata->task, + scsi_cbdata->private_data); + } } } @@ -90,13 +94,7 @@ iscsi_send_data_out(struct iscsi_context *iscsi, struct iscsi_pdu *cmd_pdu, if (pdu == NULL) { iscsi_set_error(iscsi, "Out-of-memory, Failed to allocate " "scsi data out pdu."); - ISCSI_LIST_REMOVE(&iscsi->outqueue, cmd_pdu); - 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; - + goto error; } pdu->scsi_cbdata.task = cmd_pdu->scsi_cbdata.task; /* set the cmdsn in the pdu struct so we can compare with @@ -134,19 +132,23 @@ iscsi_send_data_out(struct iscsi_context *iscsi, struct iscsi_pdu *cmd_pdu, if (iscsi_queue_pdu(iscsi, pdu) != 0) { iscsi_set_error(iscsi, "Out-of-memory: failed to queue iscsi " "scsi pdu."); - ISCSI_LIST_REMOVE(&iscsi->outqueue, cmd_pdu); - 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; + goto error; } tot_len -= len; offset += len; } 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 @@ -370,15 +372,19 @@ iscsi_process_scsi_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, if ((flags&ISCSI_PDU_DATA_FINAL) == 0) { iscsi_set_error(iscsi, "scsi response pdu but Final bit is " "not set: 0x%02x.", flags); - pdu->callback(iscsi, SCSI_STATUS_ERROR, task, - pdu->private_data); + if (pdu->callback) { + pdu->callback(iscsi, SCSI_STATUS_ERROR, task, + pdu->private_data); + } return -1; } if ((flags&ISCSI_PDU_DATA_ACK_REQUESTED) != 0) { iscsi_set_error(iscsi, "scsi response asked for ACK " "0x%02x.", flags); - pdu->callback(iscsi, SCSI_STATUS_ERROR, task, - pdu->private_data); + if (pdu->callback) { + pdu->callback(iscsi, SCSI_STATUS_ERROR, task, + pdu->private_data); + } return -1; } @@ -392,8 +398,10 @@ iscsi_process_scsi_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, if (response != 0) { iscsi_set_error(iscsi, "protocol error: flags %#02x;" " response %#02x.", flags, response); - pdu->callback(iscsi, SCSI_STATUS_ERROR, task, - pdu->private_data); + if (pdu->callback) { + pdu->callback(iscsi, SCSI_STATUS_ERROR, task, + pdu->private_data); + } return -1; } task->residual = scsi_get_uint32(&in->hdr[44]); @@ -421,8 +429,10 @@ iscsi_process_scsi_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, pdu->indata.data = NULL; pdu->indata.size = 0; - pdu->callback(iscsi, SCSI_STATUS_GOOD, task, - pdu->private_data); + if (pdu->callback) { + pdu->callback(iscsi, SCSI_STATUS_GOOD, task, + pdu->private_data); + } break; case SCSI_STATUS_CHECK_CONDITION: task->datain.size = in->data_pos; @@ -440,39 +450,52 @@ iscsi_process_scsi_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, task->sense.key, scsi_sense_ascq_str(task->sense.ascq), task->sense.ascq); - pdu->callback(iscsi, SCSI_STATUS_CHECK_CONDITION, task, - pdu->private_data); + if (pdu->callback) { + pdu->callback(iscsi, SCSI_STATUS_CHECK_CONDITION, task, + pdu->private_data); + } break; case SCSI_STATUS_RESERVATION_CONFLICT: iscsi_set_error(iscsi, "RESERVATION CONFLICT"); - pdu->callback(iscsi, SCSI_STATUS_RESERVATION_CONFLICT, - task, pdu->private_data); + if (pdu->callback) { + pdu->callback(iscsi, SCSI_STATUS_RESERVATION_CONFLICT, + task, pdu->private_data); + } break; case SCSI_STATUS_TASK_SET_FULL: iscsi_set_error(iscsi, "TASK_SET_FULL"); - pdu->callback(iscsi, SCSI_STATUS_TASK_SET_FULL, - task, pdu->private_data); + if (pdu->callback) { + pdu->callback(iscsi, SCSI_STATUS_TASK_SET_FULL, + task, pdu->private_data); + } break; case SCSI_STATUS_ACA_ACTIVE: iscsi_set_error(iscsi, "ACA_ACTIVE"); - pdu->callback(iscsi, SCSI_STATUS_ACA_ACTIVE, - task, pdu->private_data); + if (pdu->callback) { + pdu->callback(iscsi, SCSI_STATUS_ACA_ACTIVE, + task, pdu->private_data); + } break; case SCSI_STATUS_TASK_ABORTED: iscsi_set_error(iscsi, "TASK_ABORTED"); - pdu->callback(iscsi, SCSI_STATUS_TASK_ABORTED, - task, pdu->private_data); + if (pdu->callback) { + pdu->callback(iscsi, SCSI_STATUS_TASK_ABORTED, + task, pdu->private_data); + } break; case SCSI_STATUS_BUSY: iscsi_set_error(iscsi, "BUSY"); - pdu->callback(iscsi, SCSI_STATUS_BUSY, - task, pdu->private_data); + if (pdu->callback) { + pdu->callback(iscsi, SCSI_STATUS_BUSY, + task, pdu->private_data); + } break; default: iscsi_set_error(iscsi, "Unknown SCSI status :%d.", status); - - pdu->callback(iscsi, SCSI_STATUS_ERROR, task, - pdu->private_data); + if (pdu->callback) { + pdu->callback(iscsi, SCSI_STATUS_ERROR, + task, pdu->private_data); + } return -1; } @@ -492,8 +515,10 @@ iscsi_process_scsi_data_in(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, if ((flags&ISCSI_PDU_DATA_ACK_REQUESTED) != 0) { iscsi_set_error(iscsi, "scsi response asked for ACK " "0x%02x.", flags); - pdu->callback(iscsi, SCSI_STATUS_ERROR, task, - pdu->private_data); + if (pdu->callback) { + pdu->callback(iscsi, SCSI_STATUS_ERROR, task, + pdu->private_data); + } return -1; } dsl = scsi_get_uint32(&in->hdr[4]) & 0x00ffffff; @@ -550,7 +575,9 @@ iscsi_process_scsi_data_in(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, pdu->indata.data = NULL; 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; } diff --git a/lib/login.c b/lib/login.c index bd91953..bc1c50e 100644 --- a/lib/login.c +++ b/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 " "when parsing login data", (long)((unsigned char *)ptr - in->data)); - pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, - pdu->private_data); + if (pdu->callback) { + pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, + pdu->private_data); + } 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) { iscsi_set_error(iscsi, "Wrong length of CHAP_C received from" " target (%d, max: %d)", len-9, MAX_CHAP_C_LENGTH); - pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, - pdu->private_data); + if (pdu->callback) { + pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, + pdu->private_data); + } return 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" " target. Wrong CHAP targetname" " received: %s", ptr + 7); - pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, - pdu->private_data); + if (pdu->callback) { + pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, + pdu->private_data); + } return 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) { iscsi_set_error(iscsi, "Wrong size of CHAP_R" " received from target."); - pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, - pdu->private_data); + if (pdu->callback) { + pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, + pdu->private_data); + } return 0; } 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 " "failed. Invalid CHAP_R " "response from the target"); - pdu->callback(iscsi, SCSI_STATUS_ERROR, - NULL, pdu->private_data); + if (pdu->callback) { + pdu->callback(iscsi, SCSI_STATUS_ERROR, + NULL, pdu->private_data); + } 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]) { ISCSI_LOG(iscsi, 2, "target requests redirect to %s",iscsi->target_address); - pdu->callback(iscsi, SCSI_STATUS_REDIRECT, NULL, - pdu->private_data); + if (pdu->callback) { + pdu->callback(iscsi, SCSI_STATUS_REDIRECT, NULL, + pdu->private_data); + } return 0; } if (status != 0) { iscsi_set_error(iscsi, "Failed to log in to target. Status: %s(%d)", login_error_str(status), status); - pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, - pdu->private_data); + if (pdu->callback) { + pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, + pdu->private_data); + } return 0; } if (must_have_chap_n) { iscsi_set_error(iscsi, "Failed to log in to target. " "It did not return CHAP_N during SECNEG."); - pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, - pdu->private_data); + if (pdu->callback) { + pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, + pdu->private_data); + } return 0; } if (must_have_chap_r) { iscsi_set_error(iscsi, "Failed to log in to target. " "It did not return CHAP_R during SECNEG."); - pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, - pdu->private_data); + if (pdu->callback) { + pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, + pdu->private_data); + } return 0; } @@ -1256,7 +1274,9 @@ iscsi_process_login_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, } else { if (iscsi_login_async(iscsi, pdu->callback, pdu->private_data) != 0) { 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_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; } diff --git a/lib/pdu.c b/lib/pdu.c index ebffe17..dc04244 100644 --- a/lib/pdu.c +++ b/lib/pdu.c @@ -365,7 +365,7 @@ int iscsi_process_reject(struct iscsi_context *iscsi, if (pdu->callback) { pdu->callback(iscsi, SCSI_STATUS_ERROR, NULL, - pdu->private_data); + pdu->private_data); } 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); if (pdu->callback) { pdu->callback(iscsi, SCSI_STATUS_TIMEOUT, - NULL, pdu->private_data); + NULL, pdu->private_data); } iscsi_free_pdu(iscsi, pdu); } @@ -728,7 +728,7 @@ iscsi_timeout_scan(struct iscsi_context *iscsi) iscsi_dump_pdu_header(iscsi, pdu->outdata.data); if (pdu->callback) { pdu->callback(iscsi, SCSI_STATUS_TIMEOUT, - NULL, pdu->private_data); + NULL, pdu->private_data); } iscsi_free_pdu(iscsi, pdu); } diff --git a/lib/task_mgmt.c b/lib/task_mgmt.c index b00b6fa..1fd3f5f 100644 --- a/lib/task_mgmt.c +++ b/lib/task_mgmt.c @@ -78,7 +78,6 @@ iscsi_task_mgmt_async(struct iscsi_context *iscsi, /* rcmdsn */ iscsi_pdu_set_rcmdsn(pdu, rcmdsn); - pdu->callback = cb; 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]; - 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; }