When new connection comes in, check whether we already have session from

the same intiator (Name+ISID).  If so -- terminate the old session and let
the new one take its place, as required by iSCSI RFC.
This commit is contained in:
Alexander Motin 2014-07-07 05:48:11 +00:00
parent 88e0a63961
commit 2c6c9e47b2
2 changed files with 30 additions and 8 deletions

View File

@ -1087,7 +1087,8 @@ cfiscsi_session_terminate_tasks(struct cfiscsi_session *cs)
break;
CFISCSI_SESSION_WARN(cs, "waiting for CTL to terminate tasks, "
"%d remaining", cs->cs_outstanding_ctl_pdus);
pause("cfiscsi_terminate", hz / 100);
tsleep(__DEVOLATILE(void *, &cs->cs_outstanding_ctl_pdus),
0, "cfiscsi_terminate", hz / 100);
}
}
@ -1404,7 +1405,7 @@ static void
cfiscsi_ioctl_handoff(struct ctl_iscsi *ci)
{
struct cfiscsi_softc *softc;
struct cfiscsi_session *cs;
struct cfiscsi_session *cs, *cs2;
struct cfiscsi_target *ct;
struct ctl_iscsi_handoff_params *cihp;
int error;
@ -1500,12 +1501,34 @@ cfiscsi_ioctl_handoff(struct ctl_iscsi *ci)
cihp->initiator_isid[2], cihp->initiator_isid[3],
cihp->initiator_isid[4], cihp->initiator_isid[5]);
refcount_acquire(&cs->cs_outstanding_ctl_pdus);
restart:
if (!cs->cs_terminating) {
mtx_lock(&softc->lock);
TAILQ_FOREACH(cs2, &softc->sessions, cs_next) {
if (cs2 != cs && cs2->cs_tasks_aborted == false &&
strcmp(cs->cs_initiator_id, cs2->cs_initiator_id) == 0) {
cfiscsi_session_terminate(cs2);
mtx_unlock(&softc->lock);
pause("cfiscsi_reinstate", 1);
goto restart;
}
}
mtx_unlock(&softc->lock);
}
/*
* Register initiator with CTL.
*/
cfiscsi_session_register_initiator(cs);
#ifdef ICL_KERNEL_PROXY
if (cihp->socket > 0) {
#endif
error = icl_conn_handoff(cs->cs_conn, cihp->socket);
if (error != 0) {
cfiscsi_session_delete(cs);
cfiscsi_session_terminate(cs);
refcount_release(&cs->cs_outstanding_ctl_pdus);
ci->status = CTL_ISCSI_ERROR;
snprintf(ci->error_str, sizeof(ci->error_str),
"%s: icl_conn_handoff failed with error %d",
@ -1516,11 +1539,6 @@ cfiscsi_ioctl_handoff(struct ctl_iscsi *ci)
}
#endif
/*
* Register initiator with CTL.
*/
cfiscsi_session_register_initiator(cs);
#ifdef ICL_KERNEL_PROXY
cs->cs_login_phase = false;
@ -1535,6 +1553,7 @@ cfiscsi_ioctl_handoff(struct ctl_iscsi *ci)
}
#endif
refcount_release(&cs->cs_outstanding_ctl_pdus);
ci->status = CTL_ISCSI_OK;
}
@ -2833,7 +2852,9 @@ cfiscsi_done(union ctl_io *io)
* Implicit task termination has just completed; nothing to do.
*/
cs = io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr;
cs->cs_tasks_aborted = true;
refcount_release(&cs->cs_outstanding_ctl_pdus);
wakeup(__DEVOLATILE(void *, &cs->cs_outstanding_ctl_pdus));
ctl_free_io(io);
return;
}

View File

@ -80,6 +80,7 @@ struct cfiscsi_session {
int cs_portal_group_tag;
struct cv cs_maintenance_cv;
bool cs_terminating;
bool cs_tasks_aborted;
size_t cs_max_data_segment_length;
size_t cs_max_burst_length;
bool cs_immediate_data;