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:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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")));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user