Add kern.iscsi.fail_on_disconnection; this is required for gmultipath
to work. Sponsored by: The FreeBSD Foundation
This commit is contained in:
parent
4739008eab
commit
5bb2613820
@ -97,6 +97,10 @@ static int maxtags = 255;
|
||||
TUNABLE_INT("kern.iscsi.maxtags", &maxtags);
|
||||
SYSCTL_INT(_kern_iscsi, OID_AUTO, maxtags, CTLFLAG_RWTUN, &maxtags,
|
||||
0, "Max number of IO requests queued");
|
||||
static int fail_on_disconnection = 0;
|
||||
TUNABLE_INT("kern.iscsi.fail_on_disconnection", &fail_on_disconnection);
|
||||
SYSCTL_INT(_kern_iscsi, OID_AUTO, fail_on_disconnection, CTLFLAG_RWTUN,
|
||||
&fail_on_disconnection, 0, "Destroy CAM SIM on connection failure");
|
||||
|
||||
static MALLOC_DEFINE(M_ISCSI, "iSCSI", "iSCSI initiator");
|
||||
static uma_zone_t iscsi_outstanding_zone;
|
||||
@ -301,22 +305,11 @@ iscsi_session_terminate_tasks(struct iscsi_session *is, bool requeue)
|
||||
}
|
||||
|
||||
static void
|
||||
iscsi_maintenance_thread_reconnect(struct iscsi_session *is)
|
||||
iscsi_session_cleanup(struct iscsi_session *is, bool destroy_sim)
|
||||
{
|
||||
struct icl_pdu *pdu;
|
||||
|
||||
icl_conn_shutdown(is->is_conn);
|
||||
icl_conn_close(is->is_conn);
|
||||
|
||||
ISCSI_SESSION_LOCK(is);
|
||||
|
||||
#ifdef ICL_KERNEL_PROXY
|
||||
if (is->is_login_pdu != NULL) {
|
||||
icl_pdu_free(is->is_login_pdu);
|
||||
is->is_login_pdu = NULL;
|
||||
}
|
||||
cv_signal(&is->is_login_cv);
|
||||
#endif
|
||||
ISCSI_SESSION_LOCK_ASSERT(is);
|
||||
|
||||
/*
|
||||
* Don't queue any new PDUs.
|
||||
@ -336,12 +329,63 @@ iscsi_maintenance_thread_reconnect(struct iscsi_session *is)
|
||||
icl_pdu_free(pdu);
|
||||
}
|
||||
|
||||
/*
|
||||
* Terminate SCSI tasks, asking CAM to requeue them.
|
||||
*/
|
||||
//ISCSI_SESSION_DEBUG(is, "terminating tasks");
|
||||
iscsi_session_terminate_tasks(is, true);
|
||||
if (destroy_sim == false) {
|
||||
/*
|
||||
* Terminate SCSI tasks, asking CAM to requeue them.
|
||||
*/
|
||||
iscsi_session_terminate_tasks(is, true);
|
||||
return;
|
||||
}
|
||||
|
||||
iscsi_session_terminate_tasks(is, false);
|
||||
|
||||
if (is->is_sim == NULL)
|
||||
return;
|
||||
|
||||
ISCSI_SESSION_DEBUG(is, "deregistering SIM");
|
||||
xpt_async(AC_LOST_DEVICE, is->is_path, NULL);
|
||||
|
||||
if (is->is_simq_frozen) {
|
||||
xpt_release_simq(is->is_sim, 1);
|
||||
is->is_simq_frozen = false;
|
||||
}
|
||||
|
||||
xpt_free_path(is->is_path);
|
||||
is->is_path = NULL;
|
||||
xpt_bus_deregister(cam_sim_path(is->is_sim));
|
||||
cam_sim_free(is->is_sim, TRUE /*free_devq*/);
|
||||
is->is_sim = NULL;
|
||||
is->is_devq = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
iscsi_maintenance_thread_reconnect(struct iscsi_session *is)
|
||||
{
|
||||
|
||||
icl_conn_shutdown(is->is_conn);
|
||||
icl_conn_close(is->is_conn);
|
||||
|
||||
ISCSI_SESSION_LOCK(is);
|
||||
|
||||
is->is_connected = false;
|
||||
is->is_reconnecting = false;
|
||||
is->is_login_phase = false;
|
||||
|
||||
#ifdef ICL_KERNEL_PROXY
|
||||
if (is->is_login_pdu != NULL) {
|
||||
icl_pdu_free(is->is_login_pdu);
|
||||
is->is_login_pdu = NULL;
|
||||
}
|
||||
cv_signal(&is->is_login_cv);
|
||||
#endif
|
||||
|
||||
if (fail_on_disconnection) {
|
||||
ISCSI_SESSION_DEBUG(is, "connection failed, destroying devices");
|
||||
iscsi_session_cleanup(is, true);
|
||||
} else {
|
||||
iscsi_session_cleanup(is, false);
|
||||
}
|
||||
|
||||
KASSERT(TAILQ_EMPTY(&is->is_outstanding),
|
||||
("destroying session with active tasks"));
|
||||
KASSERT(STAILQ_EMPTY(&is->is_postponed),
|
||||
@ -351,9 +395,6 @@ iscsi_maintenance_thread_reconnect(struct iscsi_session *is)
|
||||
* Request immediate reconnection from iscsid(8).
|
||||
*/
|
||||
//ISCSI_SESSION_DEBUG(is, "waking up iscsid(8)");
|
||||
is->is_connected = false;
|
||||
is->is_reconnecting = false;
|
||||
is->is_login_phase = false;
|
||||
is->is_waiting_for_iscsid = true;
|
||||
strlcpy(is->is_reason, "Waiting for iscsid(8)", sizeof(is->is_reason));
|
||||
is->is_timeout = 0;
|
||||
@ -365,7 +406,6 @@ static void
|
||||
iscsi_maintenance_thread_terminate(struct iscsi_session *is)
|
||||
{
|
||||
struct iscsi_softc *sc;
|
||||
struct icl_pdu *pdu;
|
||||
|
||||
sc = is->is_softc;
|
||||
sx_xlock(&sc->sc_lock);
|
||||
@ -386,48 +426,9 @@ iscsi_maintenance_thread_terminate(struct iscsi_session *is)
|
||||
cv_signal(&is->is_login_cv);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Don't queue any new PDUs.
|
||||
*/
|
||||
callout_drain(&is->is_callout);
|
||||
if (is->is_sim != NULL && is->is_simq_frozen == false) {
|
||||
ISCSI_SESSION_DEBUG(is, "freezing");
|
||||
xpt_freeze_simq(is->is_sim, 1);
|
||||
is->is_simq_frozen = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove postponed PDUs.
|
||||
*/
|
||||
while (!STAILQ_EMPTY(&is->is_postponed)) {
|
||||
pdu = STAILQ_FIRST(&is->is_postponed);
|
||||
STAILQ_REMOVE_HEAD(&is->is_postponed, ip_next);
|
||||
icl_pdu_free(pdu);
|
||||
}
|
||||
|
||||
/*
|
||||
* Forcibly terminate SCSI tasks.
|
||||
*/
|
||||
ISCSI_SESSION_DEBUG(is, "terminating tasks");
|
||||
iscsi_session_terminate_tasks(is, false);
|
||||
|
||||
/*
|
||||
* Deregister CAM.
|
||||
*/
|
||||
if (is->is_sim != NULL) {
|
||||
ISCSI_SESSION_DEBUG(is, "deregistering SIM");
|
||||
xpt_async(AC_LOST_DEVICE, is->is_path, NULL);
|
||||
|
||||
if (is->is_simq_frozen) {
|
||||
xpt_release_simq(is->is_sim, 1);
|
||||
is->is_simq_frozen = false;
|
||||
}
|
||||
|
||||
xpt_free_path(is->is_path);
|
||||
xpt_bus_deregister(cam_sim_path(is->is_sim));
|
||||
cam_sim_free(is->is_sim, TRUE /*free_devq*/);
|
||||
is->is_sim = NULL;
|
||||
}
|
||||
iscsi_session_cleanup(is, true);
|
||||
|
||||
KASSERT(TAILQ_EMPTY(&is->is_outstanding),
|
||||
("destroying session with active tasks"));
|
||||
@ -1971,7 +1972,8 @@ iscsi_action(struct cam_sim *sim, union ccb *ccb)
|
||||
|
||||
ISCSI_SESSION_LOCK_ASSERT(is);
|
||||
|
||||
if (is->is_terminating) {
|
||||
if (is->is_terminating ||
|
||||
(is->is_connected == false && fail_on_disconnection)) {
|
||||
ccb->ccb_h.status = CAM_DEV_NOT_THERE;
|
||||
xpt_done(ccb);
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user