From owner-svn-src-all@FreeBSD.ORG Mon Jul 7 05:48:12 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 E5B21E5B; Mon, 7 Jul 2014 05:48:11 +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 D38922BD6; Mon, 7 Jul 2014 05:48:11 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s675mB9i062639; Mon, 7 Jul 2014 05:48:11 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s675mBUm062637; Mon, 7 Jul 2014 05:48:11 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201407070548.s675mBUm062637@svn.freebsd.org> From: Alexander Motin Date: Mon, 7 Jul 2014 05:48:11 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r268356 - head/sys/cam/ctl X-SVN-Group: head 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: Mon, 07 Jul 2014 05:48:12 -0000 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;