diff --git a/aros/iscsi-ls.c b/aros/iscsi-ls.c index 3a2778d..2acbfa0 100644 --- a/aros/iscsi-ls.c +++ b/aros/iscsi-ls.c @@ -174,29 +174,21 @@ void list_luns(struct client_state *clnt, const char *target, const char *portal printf("Failed to create context\n"); exit(10); } - if (clnt->username != NULL) { - if (iscsi_set_initiator_username_pwd(iscsi, clnt->username, clnt->password) != 0) { - fprintf(stderr, "Failed to set initiator username and password\n"); - exit(10); - } - } + + iscsi_set_initiator_username_pwd(iscsi, clnt->username, clnt->password); + if (iscsi_set_targetname(iscsi, target)) { fprintf(stderr, "Failed to set target name\n"); exit(10); } iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL); iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C); - if (iscsi_connect_sync(iscsi, portal) != 0) { + + if (iscsi_full_connect_sync(iscsi, portal, -1) != 0) { printf("iscsi_connect failed. %s\n", iscsi_get_error(iscsi)); exit(10); } - if (iscsi_login_sync(iscsi) != 0) { - fprintf(stderr, "login failed :%s\n", iscsi_get_error(iscsi)); - exit(10); - } - - /* get initial reportluns data, all targets can report 16 bytes but some * fail if we ask for too much. */ @@ -404,14 +396,9 @@ int main(int argc, char *argv[]) iscsi_set_session_type(iscsi, ISCSI_SESSION_DISCOVERY); - if (iscsi_url->user[0] != '\0') { - state.username = iscsi_url->user; - state.password = iscsi_url->passwd; - if (iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user, iscsi_url->passwd) != 0) { - fprintf(stderr, "Failed to set initiator username and password\n"); - exit(10); - } - } + state.username = iscsi_url->user; + state.password = iscsi_url->passwd; + if (iscsi_connect_async(iscsi, iscsi_url->portal, discoveryconnect_cb, &state) != 0) { fprintf(stderr, "iscsi_connect failed. %s\n", iscsi_get_error(iscsi)); exit(10); diff --git a/examples/iscsi-dd.c b/examples/iscsi-dd.c index 37015fa..9b12670 100644 --- a/examples/iscsi-dd.c +++ b/examples/iscsi-dd.c @@ -266,15 +266,8 @@ int main(int argc, char *argv[]) iscsi_get_error(client.src_iscsi)); exit(10); } - iscsi_set_targetname(client.src_iscsi, iscsi_url->target); iscsi_set_session_type(client.src_iscsi, ISCSI_SESSION_NORMAL); iscsi_set_header_digest(client.src_iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C); - if (iscsi_url->user[0] != '\0') { - if (iscsi_set_initiator_username_pwd(client.src_iscsi, iscsi_url->user, iscsi_url->passwd) != 0) { - fprintf(stderr, "Failed to set initiator username and password\n"); - exit(10); - } - } if (iscsi_full_connect_sync(client.src_iscsi, iscsi_url->portal, iscsi_url->lun) != 0) { fprintf(stderr, "Login Failed. %s\n", iscsi_get_error(client.src_iscsi)); iscsi_destroy_url(iscsi_url); @@ -325,15 +318,8 @@ int main(int argc, char *argv[]) iscsi_get_error(client.dst_iscsi)); exit(10); } - iscsi_set_targetname(client.dst_iscsi, iscsi_url->target); iscsi_set_session_type(client.dst_iscsi, ISCSI_SESSION_NORMAL); iscsi_set_header_digest(client.dst_iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C); - if (iscsi_url->user[0] != '\0') { - if (iscsi_set_initiator_username_pwd(client.dst_iscsi, iscsi_url->user, iscsi_url->passwd) != 0) { - fprintf(stderr, "Failed to set initiator username and password\n"); - exit(10); - } - } if (iscsi_full_connect_sync(client.dst_iscsi, iscsi_url->portal, iscsi_url->lun) != 0) { fprintf(stderr, "Login Failed. %s\n", iscsi_get_error(client.dst_iscsi)); iscsi_destroy_url(iscsi_url); diff --git a/examples/ld_iscsi.c b/examples/ld_iscsi.c index 8fe0963..836ba93 100644 --- a/examples/ld_iscsi.c +++ b/examples/ld_iscsi.c @@ -92,19 +92,9 @@ int open(const char *path, int flags, mode_t mode) return -1; } - iscsi_set_targetname(iscsi, iscsi_url->target); iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL); iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C); - if (iscsi_url->user[0] != '\0') { - if (iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user, iscsi_url->passwd) != 0) { - LD_ISCSI_DPRINTF(0,"Failed to set initiator username and password"); - iscsi_destroy_context(iscsi); - errno = ENOMEM; - return -1; - } - } - if (iscsi_full_connect_sync(iscsi, iscsi_url->portal, iscsi_url->lun) != 0) { LD_ISCSI_DPRINTF(0,"Login Failed. %s\n", iscsi_get_error(iscsi)); iscsi_destroy_url(iscsi_url); diff --git a/include/iscsi.h b/include/iscsi.h index cf3309e..7fff12c 100644 --- a/include/iscsi.h +++ b/include/iscsi.h @@ -91,6 +91,8 @@ struct iscsi_url { char target[MAX_STRING_SIZE + 1]; char user[MAX_STRING_SIZE + 1]; char passwd[MAX_STRING_SIZE + 1]; + char target_user[MAX_STRING_SIZE + 1]; + char target_passwd[MAX_STRING_SIZE + 1]; int lun; struct iscsi_context *iscsi; }; diff --git a/lib/connect.c b/lib/connect.c index 308e906..617710f 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -130,10 +130,14 @@ iscsi_login_cb(struct iscsi_context *iscsi, int status, void *command_data _U_, return; } - if (iscsi_testunitready_task(iscsi, ct->lun, - iscsi_testunitready_cb, ct) == NULL) { - iscsi_set_error(iscsi, "iscsi_testunitready_async failed."); - ct->cb(iscsi, SCSI_STATUS_ERROR, NULL, ct->private_data); + if (ct->lun != -1) { + if (iscsi_testunitready_task(iscsi, ct->lun, + iscsi_testunitready_cb, ct) == NULL) { + iscsi_set_error(iscsi, "iscsi_testunitready_async failed."); + ct->cb(iscsi, SCSI_STATUS_ERROR, NULL, ct->private_data); + } + } else { + ct->cb(iscsi, SCSI_STATUS_GOOD, NULL, ct->private_data); } } @@ -282,12 +286,8 @@ try_again: iscsi_set_header_digest(iscsi, old_iscsi->want_header_digest); - if (old_iscsi->user[0]) { - iscsi_set_initiator_username_pwd(iscsi, old_iscsi->user, old_iscsi->passwd); - } - if (old_iscsi->target_user[0]) { - iscsi_set_target_username_pwd(iscsi, old_iscsi->target_user, old_iscsi->target_passwd); - } + iscsi_set_initiator_username_pwd(iscsi, old_iscsi->user, old_iscsi->passwd); + iscsi_set_target_username_pwd(iscsi, old_iscsi->target_user, old_iscsi->target_passwd); iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL); diff --git a/lib/init.c b/lib/init.c index afe88e7..2db2fa7 100644 --- a/lib/init.c +++ b/lib/init.c @@ -453,6 +453,8 @@ iscsi_parse_url(struct iscsi_context *iscsi, const char *url, int full) char *portal; char *user = NULL; char *passwd = NULL; + char *target_user = NULL; + char *target_passwd = NULL; char *target = NULL; char *lun; char *tmp; @@ -474,12 +476,10 @@ iscsi_parse_url(struct iscsi_context *iscsi, const char *url, int full) strncpy(str,url + 8, MAX_STRING_SIZE); portal = str; - iscsi_set_target_username_pwd(iscsi, - getenv("LIBISCSI_CHAP_TARGET_USERNAME"), - getenv("LIBISCSI_CHAP_TARGET_PASSWORD")); - - user = getenv("LIBISCSI_CHAP_USERNAME"); - passwd = getenv("LIBISCSI_CHAP_PASSWORD"); + user = getenv("LIBISCSI_CHAP_USERNAME"); + passwd = getenv("LIBISCSI_CHAP_PASSWORD"); + target_user = getenv("LIBISCSI_CHAP_TARGET_USERNAME"); + target_passwd = getenv("LIBISCSI_CHAP_TARGET_PASSWORD"); tmp = strchr(portal, '?'); if (tmp) { @@ -487,7 +487,6 @@ iscsi_parse_url(struct iscsi_context *iscsi, const char *url, int full) while (tmp && *tmp) { char *next = strchr(tmp, '&'); char *key, *value; - if (next != NULL) { *next++ = 0; } @@ -497,15 +496,9 @@ iscsi_parse_url(struct iscsi_context *iscsi, const char *url, int full) *value++ = 0; } if (!strcmp(key, "target_user")) { - if (value) { - strncpy(iscsi->target_user, - value, MAX_STRING_SIZE); - } + target_user = value; } else if (!strcmp(key, "target_password")) { - if (value) { - strncpy(iscsi->target_passwd, - value, MAX_STRING_SIZE); - } + target_passwd = value; } tmp = next; } @@ -587,19 +580,16 @@ iscsi_parse_url(struct iscsi_context *iscsi, const char *url, int full) strncpy(iscsi_url->portal,portal,MAX_STRING_SIZE); - if (!iscsi->target_user[0] || !iscsi->target_passwd[0]) { - iscsi->target_user[0] = 0; - iscsi->target_passwd[0] = 0; - } - if (user != NULL && passwd != NULL) { + if (user && passwd && user[0] && passwd[0]) { strncpy(iscsi_url->user, user, MAX_STRING_SIZE); strncpy(iscsi_url->passwd, passwd, MAX_STRING_SIZE); - } else { /* if we do not have normal CHAP, that means we do not have * bidirectional either. */ - iscsi->target_user[0] = 0; - iscsi->target_passwd[0] = 0; + if (target_user && target_passwd && target_user[0] && target_passwd[0]) { + strncpy(iscsi_url->target_user, target_user, MAX_STRING_SIZE); + strncpy(iscsi_url->target_passwd, target_passwd, MAX_STRING_SIZE); + } } if (full) { @@ -609,6 +599,14 @@ iscsi_parse_url(struct iscsi_context *iscsi, const char *url, int full) iscsi_decode_url_string(&iscsi_url->target[0]); + /* NOTE: iscsi is allowed to be NULL. Especially qemu does call us with iscsi == NULL. + * If we receive iscsi != NULL we apply the parsed settings to the context. */ + if (iscsi) { + iscsi_set_targetname(iscsi, iscsi_url->target); + iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user, iscsi_url->passwd); + iscsi_set_target_username_pwd(iscsi, iscsi_url->target_user, iscsi_url->target_passwd); + } + return iscsi_url; } @@ -640,6 +638,11 @@ int iscsi_set_initiator_username_pwd(struct iscsi_context *iscsi, const char *user, const char *passwd) { + if (!user || !passwd || !user[0] || !passwd[0]) { + iscsi->user[0] = 0; + iscsi->passwd[0] = 0; + return 0; + } strncpy(iscsi->user,user,MAX_STRING_SIZE); strncpy(iscsi->passwd,passwd,MAX_STRING_SIZE); return 0; @@ -650,7 +653,7 @@ int iscsi_set_target_username_pwd(struct iscsi_context *iscsi, const char *user, const char *passwd) { - if (!user || !passwd) { + if (!user || !passwd || !user[0] || !passwd[0]) { iscsi->target_user[0] = 0; iscsi->target_passwd[0] = 0; return 0; diff --git a/lib/nop.c b/lib/nop.c index 1729d1b..993ed77 100644 --- a/lib/nop.c +++ b/lib/nop.c @@ -83,6 +83,7 @@ iscsi_nop_out_async(struct iscsi_context *iscsi, iscsi_command_cb cb, } iscsi->nops_in_flight++; + ISCSI_LOG(iscsi, 6, "NOP Out Send (nops_in_flight: %d)", iscsi->nops_in_flight); return 0; } @@ -138,6 +139,8 @@ iscsi_process_nop_out_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, iscsi->nops_in_flight = 0; + ISCSI_LOG(iscsi, 6, "NOP Out Reply received"); + if (pdu->callback == NULL) { return 0; } diff --git a/lib/socket.c b/lib/socket.c index 92ed5bf..d73859c 100644 --- a/lib/socket.c +++ b/lib/socket.c @@ -455,17 +455,17 @@ iscsi_iovector_readv_writev(struct iscsi_context *iscsi, struct scsi_iovector *i int niov=1; /* number of iovectors to pass */ uint32_t len2 = pos + count; /* adjust length of iov2 */ - + /* forward until iov2 points to the last iovec we pass later. it might happen that we have a lot of iovectors but are limited by count */ while (len2 > iov2->iov_len) { - if (iovector->niov <= iovector->consumed+niov-1) { + niov++; + if (iovector->niov < iovector->consumed + niov) { errno = EINVAL; return -1; } - niov++; len2 -= iov2->iov_len; - iov2 = &iovector->iov[iovector->consumed+niov-1]; + iov2 = &iovector->iov[iovector->consumed + niov - 1]; } /* we might limit the length of the last iovec we pass to readv/writev @@ -627,15 +627,24 @@ iscsi_write_to_socket(struct iscsi_context *iscsi) if (iscsi->is_corked) { /* connection is corked we are not allowed to send * additional PDUs */ + ISCSI_LOG(iscsi, 6, "iscsi_write_to_socket: socket is corked"); return 0; } if (iscsi_serial32_compare(iscsi->outqueue->cmdsn, iscsi->maxcmdsn) > 0 && !(iscsi->outqueue->outdata.data[0] & ISCSI_PDU_IMMEDIATE)) { /* stop sending for non-immediate PDUs. maxcmdsn is reached */ + ISCSI_LOG(iscsi, 6, + "iscsi_write_to_socket: maxcmdsn reached (outqueue[0]->cmdsnd %08x > maxcmdsn %08x)", + iscsi->outqueue->cmdsn, iscsi->maxcmdsn); return 0; } /* pop first element of the outqueue */ + if (iscsi_serial32_compare(iscsi->outqueue->cmdsn, iscsi->expcmdsn) < 0) { + iscsi_set_error(iscsi, "iscsi_write_to_scoket: outqueue[0]->cmdsn < expcmdsn (%08x < %08x)", + iscsi->outqueue->cmdsn, iscsi->expcmdsn); + return -1; + } iscsi->outqueue_current = iscsi->outqueue; ISCSI_LIST_REMOVE(&iscsi->outqueue, iscsi->outqueue_current); if (!(iscsi->outqueue_current->flags & ISCSI_PDU_DELETE_WHEN_SENT)) { diff --git a/utils/iscsi-inq.c b/utils/iscsi-inq.c index 638beb0..1d88b89 100644 --- a/utils/iscsi-inq.c +++ b/utils/iscsi-inq.c @@ -322,17 +322,9 @@ int main(int argc, char *argv[]) exit(10); } - iscsi_set_targetname(iscsi, iscsi_url->target); iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL); iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C); - if (iscsi_url->user[0]) { - if (iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user, iscsi_url->passwd) != 0) { - fprintf(stderr, "Failed to set initiator username and password\n"); - exit(10); - } - } - if (iscsi_full_connect_sync(iscsi, iscsi_url->portal, iscsi_url->lun) != 0) { fprintf(stderr, "Login Failed. %s\n", iscsi_get_error(iscsi)); iscsi_destroy_url(iscsi_url); diff --git a/utils/iscsi-ls.c b/utils/iscsi-ls.c index abdd4cc..e4bd93e 100644 --- a/utils/iscsi-ls.c +++ b/utils/iscsi-ls.c @@ -172,29 +172,20 @@ void list_luns(struct client_state *clnt, const char *target, const char *portal printf("Failed to create context\n"); exit(10); } - if (clnt->username != NULL) { - if (iscsi_set_initiator_username_pwd(iscsi, clnt->username, clnt->password) != 0) { - fprintf(stderr, "Failed to set initiator username and password\n"); - exit(10); - } - } + + iscsi_set_initiator_username_pwd(iscsi, clnt->username, clnt->password); if (iscsi_set_targetname(iscsi, target)) { fprintf(stderr, "Failed to set target name\n"); exit(10); } iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL); iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C); - if (iscsi_connect_sync(iscsi, portal) != 0) { + + if (iscsi_full_connect_sync(iscsi, portal, -1) != 0) { printf("iscsi_connect failed. %s\n", iscsi_get_error(iscsi)); exit(10); } - if (iscsi_login_sync(iscsi) != 0) { - fprintf(stderr, "login failed :%s\n", iscsi_get_error(iscsi)); - exit(10); - } - - /* get initial reportluns data, all targets can report 16 bytes but some * fail if we ask for too much. */ @@ -430,14 +421,9 @@ int main(int argc, char *argv[]) iscsi_set_session_type(iscsi, ISCSI_SESSION_DISCOVERY); - if (iscsi_url->user[0]) { - state.username = iscsi_url->user; - state.password = iscsi_url->passwd; - if (iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user, iscsi_url->passwd) != 0) { - fprintf(stderr, "Failed to set initiator username and password\n"); - exit(10); - } - } + state.username = iscsi_url->user; + state.password = iscsi_url->passwd; + if (iscsi_connect_async(iscsi, iscsi_url->portal, discoveryconnect_cb, &state) != 0) { fprintf(stderr, "iscsi_connect failed. %s\n", iscsi_get_error(iscsi)); exit(10); diff --git a/utils/iscsi-perf.c b/utils/iscsi-perf.c index 070019d..a9a84c3 100644 --- a/utils/iscsi-perf.c +++ b/utils/iscsi-perf.c @@ -45,6 +45,8 @@ struct client { int random; struct iscsi_context *iscsi; + struct scsi_iovec perf_iov; + int lun; int blocksize; uint64_t num_blocks; @@ -133,6 +135,7 @@ void cb(struct iscsi_context *iscsi _U_, int status, void *command_data, void *p fprintf(stderr, "failed to send read16 command\n"); client->err_cnt++; } + scsi_task_set_iov_in(task2, &client->perf_iov, 1); if (status == SCSI_STATUS_BUSY) { client->busy_cnt++; } @@ -184,12 +187,12 @@ void fill_read_queue(struct client *client) num_blocks * client->blocksize, client->blocksize, 0, 0, 0, 0, 0, cb, client); - if (task == NULL) { fprintf(stderr, "failed to send read16 command\n"); iscsi_destroy_context(client->iscsi); exit(10); } + scsi_task_set_iov_in(task, &client->perf_iov, 1); client->pos += num_blocks; } } @@ -270,27 +273,17 @@ int main(int argc, char *argv[]) fprintf(stderr, "Failed to create context\n"); exit(10); } - iscsi_url = iscsi_parse_full_url(client.iscsi, url); + iscsi_url = iscsi_parse_full_url(client.iscsi, url); if (iscsi_url == NULL) { fprintf(stderr, "Failed to parse URL: %s\n", iscsi_get_error(client.iscsi)); exit(10); } - iscsi_set_targetname(client.iscsi, iscsi_url->target); iscsi_set_session_type(client.iscsi, ISCSI_SESSION_NORMAL); iscsi_set_header_digest(client.iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C); - if (iscsi_url->user[0] != '\0') { - if (iscsi_set_initiator_username_pwd(client.iscsi, iscsi_url->user, iscsi_url->passwd) != 0) { - fprintf(stderr, "Failed to set initiator username and password\n"); - iscsi_destroy_url(iscsi_url); - iscsi_destroy_context(client.iscsi); - exit(10); - } - } - if (iscsi_full_connect_sync(client.iscsi, iscsi_url->portal, iscsi_url->lun) != 0) { fprintf(stderr, "Login Failed. %s\n", iscsi_get_error(client.iscsi)); iscsi_destroy_url(iscsi_url); @@ -321,6 +314,13 @@ int main(int argc, char *argv[]) scsi_free_scsi_task(task); + client.perf_iov.iov_base = malloc(blocks_per_io * client.blocksize); + if (!client.perf_iov.iov_base) { + fprintf(stderr, "Out of Memory\n"); + exit(10); + } + client.perf_iov.iov_len = blocks_per_io * client.blocksize; + printf("capacity is %" PRIu64 " blocks or %" PRIu64 " byte (%" PRIu64 " MB)\n", client.num_blocks, client.num_blocks * client.blocksize, (client.num_blocks * client.blocksize) >> 20); @@ -370,6 +370,8 @@ int main(int argc, char *argv[]) } iscsi_destroy_context(client.iscsi); + free(client.perf_iov.iov_base); + return client.err_cnt ? 1 : 0; } diff --git a/utils/iscsi-readcapacity16.c b/utils/iscsi-readcapacity16.c index 0a51a6f..48c6d00 100644 --- a/utils/iscsi-readcapacity16.c +++ b/utils/iscsi-readcapacity16.c @@ -145,17 +145,9 @@ int main(int argc, char *argv[]) exit(10); } - iscsi_set_targetname(iscsi, iscsi_url->target); iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL); iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C); - if (iscsi_url->user[0]) { - if (iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user, iscsi_url->passwd) != 0) { - fprintf(stderr, "Failed to set initiator username and password\n"); - exit(10); - } - } - if (iscsi_full_connect_sync(iscsi, iscsi_url->portal, iscsi_url->lun) != 0) { fprintf(stderr, "Login Failed. %s\n", iscsi_get_error(iscsi)); iscsi_destroy_url(iscsi_url); diff --git a/utils/iscsi-swp.c b/utils/iscsi-swp.c index c282df4..c67d4c3 100644 --- a/utils/iscsi-swp.c +++ b/utils/iscsi-swp.c @@ -158,18 +158,9 @@ int main(int argc, char *argv[]) goto finished; } - iscsi_set_targetname(iscsi, iscsi_url->target); iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL); iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C); - if (iscsi_url->user[0]) { - if (iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user, iscsi_url->passwd) != 0) { - fprintf(stderr, "Failed to set initiator username and password\n"); - ret = 10; - goto finished; - } - } - if (iscsi_full_connect_sync(iscsi, iscsi_url->portal, iscsi_url->lun) != 0) { fprintf(stderr, "Login Failed. %s\n", iscsi_get_error(iscsi)); ret = 10;