Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 4 Jul 2014 16:09:09 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r268259 - stable/10/sys/cam/ctl
Message-ID:  <201407041609.s64G99me037055@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Fri Jul  4 16:09:09 2014
New Revision: 268259
URL: http://svnweb.freebsd.org/changeset/base/268259

Log:
  MFC r267610 (by trasz):
  Rework session termination in iSCSI target to actually wait
  for any outstanding commands to be properly aborted by CTL.
  Without it, in some cases (such as files backing the LUNs
  stored on failing disk drives), terminating a busy session
  would result in panic.

Modified:
  stable/10/sys/cam/ctl/ctl_frontend_iscsi.c
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	Fri Jul  4 16:07:57 2014	(r268258)
+++ stable/10/sys/cam/ctl/ctl_frontend_iscsi.c	Fri Jul  4 16:09:09 2014	(r268259)
@@ -1044,7 +1044,7 @@ cfiscsi_session_terminate_tasks(struct c
 {
 	struct cfiscsi_data_wait *cdw, *tmpcdw;
 	union ctl_io *io;
-	int error;
+	int error, last;
 
 #ifdef notyet
 	io = ctl_alloc_io(cs->cs_target->ct_softc->fe.ctl_pool_ref);
@@ -1101,12 +1101,31 @@ cfiscsi_session_terminate_tasks(struct c
 		CFISCSI_SESSION_DEBUG(cs, "removing csw for initiator task tag "
 		    "0x%x", cdw->cdw_initiator_task_tag);
 #endif
+		/*
+		 * Set nonzero port status; this prevents backends from
+		 * assuming that the data transfer actually succeeded
+		 * and writing uninitialized data to disk.
+		 */
+		cdw->cdw_ctl_io->scsiio.io_hdr.port_status = 42;
 		cdw->cdw_ctl_io->scsiio.be_move_done(cdw->cdw_ctl_io);
 		TAILQ_REMOVE(&cs->cs_waiting_for_data_out, cdw, cdw_next);
 		uma_zfree(cfiscsi_data_wait_zone, cdw);
 	}
 	CFISCSI_SESSION_UNLOCK(cs);
 #endif
+
+	/*
+	 * Wait for CTL to terminate all the tasks.
+	 */
+	for (;;) {
+		refcount_acquire(&cs->cs_outstanding_ctl_pdus);
+		last = refcount_release(&cs->cs_outstanding_ctl_pdus);
+		if (last != 0)
+			break;
+		CFISCSI_SESSION_WARN(cs, "waiting for CTL to terminate tasks, "
+		    "%d remaining", cs->cs_outstanding_ctl_pdus);
+		pause("cfiscsi_terminate", 1);
+	}
 }
 
 static void
@@ -1123,19 +1142,22 @@ cfiscsi_maintenance_thread(void *arg)
 		CFISCSI_SESSION_UNLOCK(cs);
 
 		if (cs->cs_terminating) {
-			cfiscsi_session_terminate_tasks(cs);
-			callout_drain(&cs->cs_callout);
 
+			/*
+			 * We used to wait up to 30 seconds to deliver queued
+			 * PDUs to the initiator.  We also tried hard to deliver
+			 * SCSI Responses for the aborted PDUs.  We don't do
+			 * that anymore.  We might need to revisit that.
+			 */
+			callout_drain(&cs->cs_callout);
 			icl_conn_shutdown(cs->cs_conn);
 			icl_conn_close(cs->cs_conn);
 
 			/*
-			 * XXX: We used to wait up to 30 seconds to deliver queued PDUs
-			 * 	to the initiator.  We also tried hard to deliver SCSI Responses
-			 * 	for the aborted PDUs.  We don't do that anymore.  We might need
-			 * 	to revisit that.
+			 * At this point ICL receive thread is no longer
+			 * running; no new tasks can be queued.
 			 */
-
+			cfiscsi_session_terminate_tasks(cs);
 			cfiscsi_session_delete(cs);
 			kthread_exit();
 			return;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201407041609.s64G99me037055>