diff --git a/examples/iscsi-dd.c b/examples/iscsi-dd.c index 9b12670..998477e 100644 --- a/examples/iscsi-dd.c +++ b/examples/iscsi-dd.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "iscsi.h" #include "scsi-lowlevel.h" @@ -377,6 +378,11 @@ int main(int argc, char *argv[]) pfd[1].fd = iscsi_get_fd(client.dst_iscsi); pfd[1].events = iscsi_which_events(client.dst_iscsi); + if (!pfd[0].events && !pfd[1].events) { + sleep(1); + continue; + } + if (poll(&pfd[0], 2, -1) < 0) { printf("Poll failed"); exit(10); diff --git a/examples/iscsiclient.c b/examples/iscsiclient.c index f89f2b3..2aadf0b 100644 --- a/examples/iscsiclient.c +++ b/examples/iscsiclient.c @@ -47,6 +47,7 @@ WSADATA wsaData; #include #include #include +#include #include "iscsi.h" #include "scsi-lowlevel.h" diff --git a/include/iscsi-private.h b/include/iscsi-private.h index 66c4b07..9d50d6a 100644 --- a/include/iscsi-private.h +++ b/include/iscsi-private.h @@ -111,7 +111,6 @@ struct iscsi_context { int secneg_phase; int login_attempts; int is_loggedin; - int is_reconnecting; int bind_interfaces_cnt; int nops_in_flight; @@ -317,7 +316,7 @@ int iscsi_process_r2t(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, struct iscsi_in_pdu *in); int iscsi_process_reject(struct iscsi_context *iscsi, struct iscsi_in_pdu *in); -int iscsi_send_target_nop_out(struct iscsi_context *iscsi, uint32_t ttt); +int iscsi_send_target_nop_out(struct iscsi_context *iscsi, uint32_t ttt, uint32_t lun); #if defined(WIN32) void iscsi_set_error(struct iscsi_context *iscsi, const char *error_string, @@ -368,6 +367,9 @@ uint32_t iscsi_itt_post_increment(struct iscsi_context *iscsi); void iscsi_timeout_scan(struct iscsi_context *iscsi); +void iscsi_reconnect_cb(struct iscsi_context *iscsi _U_, int status, + void *command_data, void *private_data); + #ifdef __cplusplus } #endif diff --git a/lib/connect.c b/lib/connect.c index 048f19c..a4354d1 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -130,7 +130,7 @@ iscsi_login_cb(struct iscsi_context *iscsi, int status, void *command_data _U_, return; } - if (ct->lun != -1 && !iscsi->old_iscsi) { + if (ct->lun != -1) { if (iscsi_testunitready_task(iscsi, ct->lun, iscsi_testunitready_cb, ct) == NULL) { iscsi_set_error(iscsi, "iscsi_testunitready_async failed."); @@ -249,8 +249,8 @@ void iscsi_defer_reconnect(struct iscsi_context *iscsi) } } -static void iscsi_reconnect_cb(struct iscsi_context *iscsi _U_, int status, - void *command_data _U_, void *private_data _U_) +void iscsi_reconnect_cb(struct iscsi_context *iscsi _U_, int status, + void *command_data _U_, void *private_data _U_) { int i; if (status != SCSI_STATUS_GOOD) { @@ -344,7 +344,6 @@ static void iscsi_reconnect_cb(struct iscsi_context *iscsi _U_, int status, ISCSI_LOG(iscsi, 2, "reconnect was successful"); iscsi->pending_reconnect = 0; - iscsi->is_reconnecting = 0; } int iscsi_reconnect(struct iscsi_context *old_iscsi) @@ -366,7 +365,7 @@ int iscsi_reconnect(struct iscsi_context *old_iscsi) return 0; } - if (old_iscsi->is_reconnecting && !old_iscsi->pending_reconnect) { + if (old_iscsi->old_iscsi && !old_iscsi->pending_reconnect) { return 0; } @@ -389,9 +388,6 @@ int iscsi_reconnect(struct iscsi_context *old_iscsi) ISCSI_LOG(old_iscsi, 2, "reconnect initiated"); - old_iscsi->is_reconnecting = 1; - iscsi->is_reconnecting = 1; - iscsi_set_targetname(iscsi, old_iscsi->target_name); iscsi_set_header_digest(iscsi, old_iscsi->want_header_digest); diff --git a/lib/iscsi-command.c b/lib/iscsi-command.c index 493e288..66f442b 100644 --- a/lib/iscsi-command.c +++ b/lib/iscsi-command.c @@ -206,7 +206,8 @@ iscsi_scsi_command_async(struct iscsi_context *iscsi, int lun, struct iscsi_pdu *pdu; int flags; - if (iscsi->old_iscsi) { + if (iscsi->old_iscsi && + (iscsi->is_loggedin == 0 || task->cdb[0] != SCSI_OPCODE_TESTUNITREADY)) { iscsi = iscsi->old_iscsi; ISCSI_LOG(iscsi, 2, "iscsi_scsi_command_async: queuing cmd to old_iscsi while reconnecting"); } diff --git a/lib/nop.c b/lib/nop.c index af7a2a6..80ac12f 100644 --- a/lib/nop.c +++ b/lib/nop.c @@ -91,7 +91,7 @@ iscsi_nop_out_async(struct iscsi_context *iscsi, iscsi_command_cb cb, } int -iscsi_send_target_nop_out(struct iscsi_context *iscsi, uint32_t ttt) +iscsi_send_target_nop_out(struct iscsi_context *iscsi, uint32_t ttt, uint32_t lun) { struct iscsi_pdu *pdu; @@ -115,7 +115,7 @@ iscsi_send_target_nop_out(struct iscsi_context *iscsi, uint32_t ttt) iscsi_pdu_set_ttt(pdu, ttt); /* lun */ - iscsi_pdu_set_lun(pdu, 0); + iscsi_pdu_set_lun(pdu, lun); /* cmdsn is not increased if Immediate delivery*/ iscsi_pdu_set_cmdsn(pdu, iscsi->cmdsn); @@ -127,8 +127,8 @@ iscsi_send_target_nop_out(struct iscsi_context *iscsi, uint32_t ttt) } ISCSI_LOG(iscsi, (iscsi->nops_in_flight > 1) ? 1 : 6, - "NOP Out Send (nops_in_flight: %d, pdu->cmdsn %08x, pdu->itt %08x, pdu->ttt %08x, iscsi->maxcmdsn %08x, iscsi->expcmdsn %08x)", - iscsi->nops_in_flight, pdu->cmdsn, 0xffffffff, ttt, iscsi->maxcmdsn, iscsi->expcmdsn); + "NOP Out Send (nops_in_flight: %d, pdu->cmdsn %08x, pdu->itt %08x, pdu->ttt %08x, pdu->lun %8x, iscsi->maxcmdsn %08x, iscsi->expcmdsn %08x)", + iscsi->nops_in_flight, pdu->cmdsn, 0xffffffff, ttt, lun, iscsi->maxcmdsn, iscsi->expcmdsn); return 0; } diff --git a/lib/pdu.c b/lib/pdu.c index 383db20..f0e8491 100644 --- a/lib/pdu.c +++ b/lib/pdu.c @@ -321,12 +321,13 @@ int iscsi_process_target_nop_in(struct iscsi_context *iscsi, { uint32_t ttt = scsi_get_uint32(&in->hdr[20]); uint32_t itt = scsi_get_uint32(&in->hdr[16]); + uint32_t lun = scsi_get_uint16(&in->hdr[8]); iscsi_adjust_statsn(iscsi, in); iscsi_adjust_maxexpcmdsn(iscsi, in); ISCSI_LOG(iscsi, (iscsi->nops_in_flight > 1) ? 1 : 6, - "NOP-In received (pdu->itt %08x, pdu->ttt %08x, iscsi->maxcmdsn %08x, iscsi->expcmdsn %08x, iscsi->statsn %08x)", + "NOP-In received (pdu->itt %08x, pdu->ttt %08x, pdu->lun %8x, iscsi->maxcmdsn %08x, iscsi->expcmdsn %08x, iscsi->statsn %08x)", itt, ttt, iscsi->maxcmdsn, iscsi->expcmdsn, iscsi->statsn); /* if the server does not want a response */ @@ -334,7 +335,7 @@ int iscsi_process_target_nop_in(struct iscsi_context *iscsi, return 0; } - iscsi_send_target_nop_out(iscsi, ttt); + iscsi_send_target_nop_out(iscsi, ttt, lun); return 0; } @@ -671,8 +672,7 @@ iscsi_pdu_set_cdb(struct iscsi_pdu *pdu, struct scsi_task *task) void iscsi_pdu_set_lun(struct iscsi_pdu *pdu, uint32_t lun) { - pdu->outdata.data[8] = lun >> 8; - pdu->outdata.data[9] = lun & 0xff; + scsi_set_uint16(&pdu->outdata.data[8], lun); } void diff --git a/lib/socket.c b/lib/socket.c index 0646532..5e76055 100644 --- a/lib/socket.c +++ b/lib/socket.c @@ -402,7 +402,7 @@ iscsi_which_events(struct iscsi_context *iscsi) { int events = iscsi->is_connected ? POLLIN : POLLOUT; - if (iscsi->pending_reconnect && iscsi->is_reconnecting && + if (iscsi->pending_reconnect && iscsi->old_iscsi && time(NULL) < iscsi->next_reconnect) { return 0; } @@ -779,7 +779,10 @@ iscsi_service_reconnect_if_loggedin(struct iscsi_context *iscsi) return 0; } } - if (iscsi->is_reconnecting) { + if (iscsi->old_iscsi) { + if (!iscsi->pending_reconnect) { + iscsi_reconnect_cb(iscsi, SCSI_STATUS_ERROR, NULL, NULL); + } return 0; } return -1; @@ -796,7 +799,7 @@ iscsi_service(struct iscsi_context *iscsi, int revents) if (time(NULL) >= iscsi->next_reconnect) { return iscsi_reconnect(iscsi); } else { - if (iscsi->is_reconnecting) { + if (iscsi->old_iscsi) { return 0; } } diff --git a/lib/sync.c b/lib/sync.c index d9f929c..d89ee7d 100644 --- a/lib/sync.c +++ b/lib/sync.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "iscsi.h" #include "iscsi-private.h" #include "scsi-lowlevel.h" @@ -172,10 +173,15 @@ reconnect_event_loop(struct iscsi_context *iscsi, struct iscsi_sync_state *state { struct pollfd pfd; int ret; - while (iscsi->is_reconnecting) { + while (iscsi->old_iscsi) { pfd.fd = iscsi_get_fd(iscsi); pfd.events = iscsi_which_events(iscsi); + if (!pfd.events) { + sleep(1); + continue; + } + if ((ret = poll(&pfd, 1, 1000)) < 0) { iscsi_set_error(iscsi, "Poll failed"); state->status = -1; diff --git a/utils/iscsi-ls.c b/utils/iscsi-ls.c index e4bd93e..3776208 100644 --- a/utils/iscsi-ls.c +++ b/utils/iscsi-ls.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "iscsi.h" #include "scsi-lowlevel.h" @@ -54,21 +55,26 @@ struct client_state { void event_loop(struct iscsi_context *iscsi, struct client_state *state) { - struct pollfd pfd; + struct pollfd pfd; - while (state->finished == 0) { - pfd.fd = iscsi_get_fd(iscsi); - pfd.events = iscsi_which_events(iscsi); + while (state->finished == 0) { + pfd.fd = iscsi_get_fd(iscsi); + pfd.events = iscsi_which_events(iscsi); - if (poll(&pfd, 1, -1) < 0) { - fprintf(stderr, "Poll failed"); - exit(10); - } - if (iscsi_service(iscsi, pfd.revents) < 0) { - fprintf(stderr, "iscsi_service failed with : %s\n", iscsi_get_error(iscsi)); - exit(10); - } - } + if (!pfd.events) { + sleep(1); + continue; + } + + if (poll(&pfd, 1, -1) < 0) { + fprintf(stderr, "Poll failed"); + exit(10); + } + if (iscsi_service(iscsi, pfd.revents) < 0) { + fprintf(stderr, "iscsi_service failed with : %s\n", iscsi_get_error(iscsi)); + exit(10); + } + } } void show_lun(struct iscsi_context *iscsi, int lun) diff --git a/utils/iscsi-perf.c b/utils/iscsi-perf.c index 77ae39b..ed99d18 100644 --- a/utils/iscsi-perf.c +++ b/utils/iscsi-perf.c @@ -395,6 +395,7 @@ int main(int argc, char *argv[]) while (client.in_flight && !client.err_cnt && finished < 2) { pfd[0].fd = iscsi_get_fd(client.iscsi); pfd[0].events = iscsi_which_events(client.iscsi); + if (proc_alarm) { if (iscsi_get_nops_in_flight(client.iscsi) > MAX_NOP_FAILURES) { iscsi_reconnect(client.iscsi); @@ -407,6 +408,11 @@ int main(int argc, char *argv[]) proc_alarm = 0; } + if (!pfd[0].events) { + sleep(1); + continue; + } + if (poll(&pfd[0], 1, -1) < 0) { continue; }