add iscsi_force_reconnect()
If a connection attempt is hung, then iscsi_reconnect() won't do anything. This makes sense if we'd just re-try to connect to the same target, but if (for example) login redirect might point us to a different, healthy, target, it should be possible to restart the full connection process on request. Signed-off-by: John Levon <john.levon@nutanix.com>
This commit is contained in:
committed by
Bart Van Assche
parent
314aa26576
commit
30dd7c6429
@@ -492,6 +492,33 @@ EXTERN int iscsi_reconnect(struct iscsi_context *iscsi);
|
|||||||
*/
|
*/
|
||||||
EXTERN int iscsi_reconnect_sync(struct iscsi_context *iscsi);
|
EXTERN int iscsi_reconnect_sync(struct iscsi_context *iscsi);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disconnect a connection to a target and try to reconnect (async version).
|
||||||
|
* This call returns immediately and the reconnect is processed in the
|
||||||
|
* background. Commands send to this connection will be queued and not
|
||||||
|
* processed until we have successfully reconnected.
|
||||||
|
*
|
||||||
|
* This will re-start connection (to the configured original portal) even if a
|
||||||
|
* pending reconnection is already underway, which may be useful if the current
|
||||||
|
* connection is not progressing. It does not over-ride any existing re-try
|
||||||
|
* backoff or max retries state.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* 0 reconnect was successful
|
||||||
|
* <0 error
|
||||||
|
*/
|
||||||
|
EXTERN int iscsi_force_reconnect(struct iscsi_context *iscsi);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disconnect a connection to a target and try to force reconnection (sync
|
||||||
|
* version). This call will block until the connection is reestablished.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* 0 reconnect was successful
|
||||||
|
* <0 error
|
||||||
|
*/
|
||||||
|
EXTERN int iscsi_force_reconnect_sync(struct iscsi_context *iscsi);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Asynchronous call to perform an ISCSI login.
|
* Asynchronous call to perform an ISCSI login.
|
||||||
*
|
*
|
||||||
|
|||||||
+12
-2
@@ -378,7 +378,7 @@ void iscsi_reconnect_cb(struct iscsi_context *iscsi, int status,
|
|||||||
iscsi->pending_reconnect = 0;
|
iscsi->pending_reconnect = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int iscsi_reconnect(struct iscsi_context *iscsi)
|
static int reconnect(struct iscsi_context *iscsi, int force)
|
||||||
{
|
{
|
||||||
struct iscsi_context *tmp_iscsi;
|
struct iscsi_context *tmp_iscsi;
|
||||||
|
|
||||||
@@ -397,7 +397,7 @@ int iscsi_reconnect(struct iscsi_context *iscsi)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iscsi->old_iscsi && !iscsi->pending_reconnect) {
|
if (iscsi->old_iscsi && !iscsi->pending_reconnect && !force) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -477,3 +477,13 @@ int iscsi_reconnect(struct iscsi_context *iscsi)
|
|||||||
return iscsi_full_connect_async(iscsi, iscsi->portal,
|
return iscsi_full_connect_async(iscsi, iscsi->portal,
|
||||||
iscsi->lun, iscsi_reconnect_cb, NULL);
|
iscsi->lun, iscsi_reconnect_cb, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int iscsi_reconnect(struct iscsi_context *iscsi)
|
||||||
|
{
|
||||||
|
return reconnect(iscsi, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int iscsi_force_reconnect(struct iscsi_context *iscsi)
|
||||||
|
{
|
||||||
|
return reconnect(iscsi, 1);
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ LIBRARY libiscsi
|
|||||||
EXPORTS
|
EXPORTS
|
||||||
iscsi_connect_async
|
iscsi_connect_async
|
||||||
iscsi_connect_sync
|
iscsi_connect_sync
|
||||||
|
iscsi_force_reconnect_sync
|
||||||
iscsi_reconnect_sync
|
iscsi_reconnect_sync
|
||||||
iscsi_create_context
|
iscsi_create_context
|
||||||
iscsi_destroy_context
|
iscsi_destroy_context
|
||||||
@@ -10,6 +11,7 @@ iscsi_disconnect
|
|||||||
iscsi_discovery_async
|
iscsi_discovery_async
|
||||||
iscsi_discovery_sync
|
iscsi_discovery_sync
|
||||||
iscsi_free_discovery_data
|
iscsi_free_discovery_data
|
||||||
|
iscsi_force_reconnect
|
||||||
iscsi_full_connect_async
|
iscsi_full_connect_async
|
||||||
iscsi_full_connect_sync
|
iscsi_full_connect_sync
|
||||||
iscsi_get_error
|
iscsi_get_error
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ iscsi_discovery_sync
|
|||||||
iscsi_extended_copy_sync
|
iscsi_extended_copy_sync
|
||||||
iscsi_extended_copy_task
|
iscsi_extended_copy_task
|
||||||
iscsi_free_discovery_data
|
iscsi_free_discovery_data
|
||||||
|
iscsi_force_reconnect
|
||||||
|
iscsi_force_reconnect_sync
|
||||||
iscsi_full_connect_async
|
iscsi_full_connect_async
|
||||||
iscsi_full_connect_sync
|
iscsi_full_connect_sync
|
||||||
iscsi_get_error
|
iscsi_get_error
|
||||||
|
|||||||
+16
@@ -226,6 +226,22 @@ int iscsi_reconnect_sync(struct iscsi_context *iscsi)
|
|||||||
return (state.status == SCSI_STATUS_GOOD) ? 0 : -1;
|
return (state.status == SCSI_STATUS_GOOD) ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int iscsi_force_reconnect_sync(struct iscsi_context *iscsi)
|
||||||
|
{
|
||||||
|
struct iscsi_sync_state state;
|
||||||
|
|
||||||
|
memset(&state, 0, sizeof(state));
|
||||||
|
|
||||||
|
if (iscsi_force_reconnect(iscsi) != 0) {
|
||||||
|
iscsi_set_error(iscsi, "Failed to reconnect. %s", iscsi_get_error(iscsi));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
reconnect_event_loop(iscsi, &state);
|
||||||
|
|
||||||
|
return (state.status == SCSI_STATUS_GOOD) ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
iscsi_task_mgmt_sync_cb(struct iscsi_context *iscsi, int status,
|
iscsi_task_mgmt_sync_cb(struct iscsi_context *iscsi, int status,
|
||||||
void *command_data, void *private_data)
|
void *command_data, void *private_data)
|
||||||
|
|||||||
Reference in New Issue
Block a user