RECONNECT add option to limit the number of reconnect retries

In specific situation it might be useful to give up if a reconnect
is not successful or after a given number reconnect retries.
This patch adds the ability to change that. The default remains
the same: retry forever.

Signed-off-by: Peter Lieven <pl@kamp.de>
This commit is contained in:
Peter Lieven
2012-12-04 13:38:50 +01:00
parent 042a1deb07
commit ee83c7ce75
6 changed files with 61 additions and 29 deletions

View File

@@ -121,6 +121,7 @@ struct iscsi_context {
int lun; int lun;
int no_auto_reconnect; int no_auto_reconnect;
int reconnect_deferred; int reconnect_deferred;
int reconnect_max_retries;
int log_level; int log_level;
iscsi_log_fn log_fn; iscsi_log_fn log_fn;

View File

@@ -1076,6 +1076,16 @@ iscsi_set_tcp_syncnt(struct iscsi_context *iscsi, int value);
EXTERN void EXTERN void
iscsi_set_bind_interfaces(struct iscsi_context *iscsi, char * interfaces); 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 #ifdef __cplusplus
} }
#endif #endif

View File

@@ -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) int iscsi_reconnect(struct iscsi_context *old_iscsi)
{ {
struct iscsi_context *iscsi = 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 the target drops the session.
*/ */
if (iscsi->no_auto_reconnect) { if (iscsi->no_auto_reconnect) {
struct iscsi_pdu *pdu; iscsi_defer_reconnect(iscsi);
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);
}
return 0; return 0;
} }
@@ -255,7 +266,13 @@ try_again:
iscsi->tcp_keepintvl = old_iscsi->tcp_keepintvl; iscsi->tcp_keepintvl = old_iscsi->tcp_keepintvl;
iscsi->tcp_syncnt = old_iscsi->tcp_syncnt; 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_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; int backoff=retry;
if (backoff > 10) { if (backoff > 10) {
backoff+=rand()%10; backoff+=rand()%10;

View File

@@ -112,6 +112,8 @@ iscsi_create_context(const char *initiator_name)
iscsi->tcp_keepcnt=3; iscsi->tcp_keepcnt=3;
iscsi->tcp_keepintvl=30; iscsi->tcp_keepintvl=30;
iscsi->tcp_keepidle=30; iscsi->tcp_keepidle=30;
iscsi->reconnect_max_retries = -1;
if (getenv("LIBISCSI_DEBUG") != NULL) { if (getenv("LIBISCSI_DEBUG") != NULL) {
iscsi_set_log_level(iscsi, atoi(getenv("LIBISCSI_DEBUG"))); iscsi_set_log_level(iscsi, atoi(getenv("LIBISCSI_DEBUG")));

View File

@@ -57,6 +57,7 @@ iscsi_report_supported_opcodes_sync
iscsi_report_supported_opcodes_task iscsi_report_supported_opcodes_task
iscsi_reconnect iscsi_reconnect
iscsi_set_noautoreconnect iscsi_set_noautoreconnect
iscsi_set_reconnect_max_retries
iscsi_reportluns_sync iscsi_reportluns_sync
iscsi_reportluns_task iscsi_reportluns_task
iscsi_scsi_cancel_all_tasks iscsi_scsi_cancel_all_tasks

View File

@@ -55,6 +55,7 @@ iscsi_report_supported_opcodes_sync
iscsi_report_supported_opcodes_task iscsi_report_supported_opcodes_task
iscsi_reconnect iscsi_reconnect
iscsi_set_noautoreconnect iscsi_set_noautoreconnect
iscsi_set_reconnect_max_retries
iscsi_reportluns_sync iscsi_reportluns_sync
iscsi_reportluns_task iscsi_reportluns_task
iscsi_scsi_cancel_all_tasks iscsi_scsi_cancel_all_tasks