svn commit: r268356 - head/sys/cam/ctl

Alexander Motin mav at FreeBSD.org
Mon Jul 7 05:48:12 UTC 2014


Author: mav
Date: Mon Jul  7 05:48:11 2014
New Revision: 268356
URL: http://svnweb.freebsd.org/changeset/base/268356

Log:
  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.

Modified:
  head/sys/cam/ctl/ctl_frontend_iscsi.c
  head/sys/cam/ctl/ctl_frontend_iscsi.h

Modified: head/sys/cam/ctl/ctl_frontend_iscsi.c
==============================================================================
--- head/sys/cam/ctl/ctl_frontend_iscsi.c	Mon Jul  7 05:31:50 2014	(r268355)
+++ head/sys/cam/ctl/ctl_frontend_iscsi.c	Mon Jul  7 05:48:11 2014	(r268356)
@@ -1087,7 +1087,8 @@ cfiscsi_session_terminate_tasks(struct c
 			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 *
 	    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 *
 	}
 #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 *
 	}
 #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;
 	}

Modified: head/sys/cam/ctl/ctl_frontend_iscsi.h
==============================================================================
--- head/sys/cam/ctl/ctl_frontend_iscsi.h	Mon Jul  7 05:31:50 2014	(r268355)
+++ head/sys/cam/ctl/ctl_frontend_iscsi.h	Mon Jul  7 05:48:11 2014	(r268356)
@@ -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;


More information about the svn-src-head mailing list