From owner-svn-src-all@FreeBSD.ORG Tue Jul 15 17:13:50 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 1CFC88CB; Tue, 15 Jul 2014 17:13:50 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 08E812D84; Tue, 15 Jul 2014 17:13:50 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s6FHDn87089304; Tue, 15 Jul 2014 17:13:49 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s6FHDnG8089301; Tue, 15 Jul 2014 17:13:49 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201407151713.s6FHDnG8089301@svn.freebsd.org> From: Alexander Motin Date: Tue, 15 Jul 2014 17:13:49 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r268691 - stable/10/sys/cam/ctl X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 Jul 2014 17:13:50 -0000 Author: mav Date: Tue Jul 15 17:13:49 2014 New Revision: 268691 URL: http://svnweb.freebsd.org/changeset/base/268691 Log: MFC r268356, r268357: 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: stable/10/sys/cam/ctl/ctl_frontend_iscsi.c stable/10/sys/cam/ctl/ctl_frontend_iscsi.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cam/ctl/ctl_frontend_iscsi.c ============================================================================== --- stable/10/sys/cam/ctl/ctl_frontend_iscsi.c Tue Jul 15 17:12:37 2014 (r268690) +++ stable/10/sys/cam/ctl/ctl_frontend_iscsi.c Tue Jul 15 17:13:49 2014 (r268691) @@ -1091,7 +1091,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); } } @@ -1408,7 +1409,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; @@ -1504,12 +1505,36 @@ 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 && + cs->cs_target == cs2->cs_target && + cs->cs_portal_group_tag == cs2->cs_portal_group_tag && + 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", @@ -1520,11 +1545,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; @@ -1539,6 +1559,7 @@ cfiscsi_ioctl_handoff(struct ctl_iscsi * } #endif + refcount_release(&cs->cs_outstanding_ctl_pdus); ci->status = CTL_ISCSI_OK; } @@ -2847,7 +2868,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: stable/10/sys/cam/ctl/ctl_frontend_iscsi.h ============================================================================== --- stable/10/sys/cam/ctl/ctl_frontend_iscsi.h Tue Jul 15 17:12:37 2014 (r268690) +++ stable/10/sys/cam/ctl/ctl_frontend_iscsi.h Tue Jul 15 17:13:49 2014 (r268691) @@ -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;