diff --git a/include/iscsi-private.h b/include/iscsi-private.h index 1be0f61..2df63cf 100644 --- a/include/iscsi-private.h +++ b/include/iscsi-private.h @@ -121,6 +121,7 @@ struct iscsi_context { int lun; int no_auto_reconnect; int reconnect_deferred; + int reconnect_max_retries; int log_level; iscsi_log_fn log_fn; diff --git a/include/iscsi.h b/include/iscsi.h index 56237ce..162756d 100644 --- a/include/iscsi.h +++ b/include/iscsi.h @@ -1076,6 +1076,16 @@ iscsi_set_tcp_syncnt(struct iscsi_context *iscsi, int value); EXTERN void iscsi_set_bind_interfaces(struct iscsi_context *iscsi, char * interfaces); +/* This function is to set if we should retry a failed reconnect + + count is defined as follows: + -1 -> retry forever (default) + 0 -> never retry + n -> retry n times +*/ +EXTERN void +iscsi_set_reconnect_max_retries(struct iscsi_context *iscsi, int count); + #ifdef __cplusplus } #endif diff --git a/lib/connect.c b/lib/connect.c index fd4c97b..fabf198 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -176,6 +176,45 @@ void iscsi_set_noautoreconnect(struct iscsi_context *iscsi, int state) } } +void iscsi_set_reconnect_max_retries(struct iscsi_context *iscsi, int count) +{ + iscsi->reconnect_max_retries = count; +} + +void iscsi_defer_reconnect(struct iscsi_context *iscsi) +{ + struct iscsi_pdu *pdu; + + iscsi->reconnect_deferred = 1; + + ISCSI_LOG(iscsi, 2, "reconnect deferred, cancelling all tasks"); + + while ((pdu = iscsi->outqueue)) { + SLIST_REMOVE(&iscsi->outqueue, pdu); + if ( !(pdu->flags & ISCSI_PDU_NO_CALLBACK)) { + /* If an error happened during connect/login, + we dont want to call any of the callbacks. + */ + if (iscsi->is_loggedin) { + pdu->callback(iscsi, SCSI_STATUS_CANCELLED, + NULL, pdu->private_data); + } + } + iscsi_free_pdu(iscsi, pdu); + } + while ((pdu = iscsi->waitpdu)) { + SLIST_REMOVE(&iscsi->waitpdu, pdu); + /* If an error happened during connect/login, + we dont want to call any of the callbacks. + */ + if (iscsi->is_loggedin) { + pdu->callback(iscsi, SCSI_STATUS_CANCELLED, + NULL, pdu->private_data); + } + iscsi_free_pdu(iscsi, pdu); + } +} + int iscsi_reconnect(struct iscsi_context *old_iscsi) { struct iscsi_context *iscsi = old_iscsi; @@ -187,35 +226,7 @@ int iscsi_reconnect(struct iscsi_context *old_iscsi) if the target drops the session. */ if (iscsi->no_auto_reconnect) { - struct iscsi_pdu *pdu; - - iscsi->reconnect_deferred = 1; - - while ((pdu = iscsi->outqueue)) { - SLIST_REMOVE(&iscsi->outqueue, pdu); - if ( !(pdu->flags & ISCSI_PDU_NO_CALLBACK)) { - /* If an error happened during connect/login, - we dont want to call any of the callbacks. - */ - if (iscsi->is_loggedin) { - pdu->callback(iscsi, SCSI_STATUS_CANCELLED, - NULL, pdu->private_data); - } - } - iscsi_free_pdu(iscsi, pdu); - } - while ((pdu = iscsi->waitpdu)) { - SLIST_REMOVE(&iscsi->waitpdu, pdu); - /* If an error happened during connect/login, - we dont want to call any of the callbacks. - */ - if (iscsi->is_loggedin) { - pdu->callback(iscsi, SCSI_STATUS_CANCELLED, - NULL, pdu->private_data); - } - iscsi_free_pdu(iscsi, pdu); - } - + iscsi_defer_reconnect(iscsi); return 0; } @@ -255,7 +266,13 @@ try_again: iscsi->tcp_keepintvl = old_iscsi->tcp_keepintvl; iscsi->tcp_syncnt = old_iscsi->tcp_syncnt; + iscsi->reconnect_max_retries = old_iscsi->reconnect_max_retries; + if (iscsi_full_connect_sync(iscsi, iscsi->portal, iscsi->lun) != 0) { + if (iscsi->reconnect_max_retries != -1 && retry >= iscsi->reconnect_max_retries) { + iscsi_defer_reconnect(old_iscsi); + return -1; + } int backoff=retry; if (backoff > 10) { backoff+=rand()%10; diff --git a/lib/init.c b/lib/init.c index b08e3c3..beebd4f 100644 --- a/lib/init.c +++ b/lib/init.c @@ -112,6 +112,8 @@ iscsi_create_context(const char *initiator_name) iscsi->tcp_keepcnt=3; iscsi->tcp_keepintvl=30; iscsi->tcp_keepidle=30; + + iscsi->reconnect_max_retries = -1; if (getenv("LIBISCSI_DEBUG") != NULL) { iscsi_set_log_level(iscsi, atoi(getenv("LIBISCSI_DEBUG"))); diff --git a/lib/libiscsi.def b/lib/libiscsi.def index ea7e49b..b7220da 100644 --- a/lib/libiscsi.def +++ b/lib/libiscsi.def @@ -57,6 +57,7 @@ iscsi_report_supported_opcodes_sync iscsi_report_supported_opcodes_task iscsi_reconnect iscsi_set_noautoreconnect +iscsi_set_reconnect_max_retries iscsi_reportluns_sync iscsi_reportluns_task iscsi_scsi_cancel_all_tasks diff --git a/lib/libiscsi.syms b/lib/libiscsi.syms index 60e3b09..5e410c4 100644 --- a/lib/libiscsi.syms +++ b/lib/libiscsi.syms @@ -55,6 +55,7 @@ iscsi_report_supported_opcodes_sync iscsi_report_supported_opcodes_task iscsi_reconnect iscsi_set_noautoreconnect +iscsi_set_reconnect_max_retries iscsi_reportluns_sync iscsi_reportluns_task iscsi_scsi_cancel_all_tasks