changeset 3719:0a19a978a89c

6482030 stale comment in usr/src/cmd/iscsi/iscsitgtd/main.c 6482080 memory leak in iscsi_handle_login_pkt() 6521041 MODE_SENSE on errors attempts to send both STATUS_CHECK and STATUS_GOOD 6521425 When sending a NOP-In message the statsn value should not be incremented. 6522093 target returns wrong status when invalid LUN is used. 6523439 Just Say No to Nagle
author mcneal
date Mon, 26 Feb 2007 14:34:33 -0800
parents a7973eff65f3
children 35ed4f76e395
files usr/src/cmd/iscsi/iscsitgtd/iscsi_conn.c usr/src/cmd/iscsi/iscsitgtd/iscsi_login.c usr/src/cmd/iscsi/iscsitgtd/main.c usr/src/cmd/iscsi/iscsitgtd/t10_sam.c usr/src/cmd/iscsi/iscsitgtd/t10_spc.c usr/src/cmd/iscsi/iscsitgtd/util_port.c
diffstat 6 files changed, 67 insertions(+), 62 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/iscsi/iscsitgtd/iscsi_conn.c	Mon Feb 26 14:11:03 2007 -0800
+++ b/usr/src/cmd/iscsi/iscsitgtd/iscsi_conn.c	Mon Feb 26 14:34:33 2007 -0800
@@ -471,8 +471,27 @@
 		free(in);
 		return;
 	}
+
 	(void) pthread_mutex_lock(&c->c_mutex);
-	in->statsn	= htonl(c->c_statsn++);
+	/*
+	 * Make any final per command adjustments.
+	 */
+	switch (in->opcode & ISCSI_OPCODE_MASK) {
+	case ISCSI_OP_NOOP_IN:
+		in->statsn	= htonl(c->c_statsn);
+		/*
+		 * Only bump the STATSN value if this packet is in response to
+		 * an initiator's ping. Section 10.19.1 of RFC3720 specifies
+		 * that the value must be 0xffffffff when responding to an
+		 * initiator. So, if the value is the reserved ITT value then
+		 * this packet was generated in reponse to an initiator ping.
+		 * Otherwise, we timed out on the connection and are requesting
+		 * a ping.
+		 */
+		if (((iscsi_nop_in_hdr_t *)in)->ttt == ISCSI_RSVD_TASK_TAG)
+			c->c_statsn++;
+		break;
+	}
 	(void) pthread_mutex_lock(&c->c_sess->s_mutex);
 	in->expcmdsn	= htonl(c->c_sess->s_seencmdsn + 1);
 	in->maxcmdsn	= htonl(iscsi_cmd_window(c) + c->c_sess->s_seencmdsn);
@@ -611,6 +630,8 @@
 				 * initiator expected and we're sending.
 				 */
 
+				queue_prt(c->c_mgmtq, Q_CONN_ERRS,
+				    "CON%x  Underflow occurred\n", c->c_num);
 				send_datain_pdu(c, t, 0);
 				send_scsi_rsp(c, t);
 			}
@@ -762,13 +783,21 @@
 	(void) pthread_mutex_unlock(&c->c_sess->s_mutex);
 	rsp.cmd_status	= T10_CMD_STATUS(t);
 
+	if (cmd->c_writeop == True) {
+		if (cmd->c_offset_out != cmd->c_dlen_expected)
+			rsp.flags |= ISCSI_FLAG_CMD_OVERFLOW;
+		rsp.residual_count = htonl(cmd->c_dlen_expected -
+		    cmd->c_offset_out);
+	} else {
+		if (cmd->c_offset_in != cmd->c_dlen_expected)
+			rsp.flags |= ISCSI_FLAG_CMD_UNDERFLOW;
+		rsp.residual_count = htonl(cmd->c_dlen_expected -
+		    cmd->c_offset_in);
+	}
+
 	if (rsp.cmd_status) {
 		rsp.response		= ISCSI_STATUS_CMD_COMPLETED;
 		rsp.residual_count	= htonl(T10_CMD_RESID(t));
-		if (cmd->c_writeop == True)
-			rsp.flags |= ISCSI_FLAG_CMD_OVERFLOW;
-		else
-			rsp.flags |= ISCSI_FLAG_CMD_UNDERFLOW;
 
 		if (T10_SENSE_LEN(t) != 0) {
 			/*
@@ -784,16 +813,6 @@
 	} else {
 		rsp.response	= ISCSI_STATUS_CMD_COMPLETED;
 		rsp.expdatasn	= htonl(cmd->c_datasn);
-		if (cmd->c_writeop == True) {
-			if (cmd->c_offset_out != cmd->c_dlen_expected)
-				rsp.flags |= ISCSI_FLAG_CMD_OVERFLOW;
-			rsp.residual_count = htonl(cmd->c_dlen_expected -
-			    cmd->c_offset_out);
-		} else {
-			rsp.flags |= ISCSI_FLAG_CMD_UNDERFLOW;
-			rsp.residual_count = htonl(cmd->c_dlen_expected -
-			    cmd->c_offset_in);
-		}
 	}
 
 	send_iscsi_pkt(c, (iscsi_hdr_t *)&rsp, auto_sense);
@@ -1217,6 +1236,11 @@
 			return;
 		}
 		free(abuf);
+#ifdef FULL_DEBUG
+		queue_prt(c->c_mgmtq, Q_CONN_IO,
+		    "CON%x  Response(0x%x), Data: len=0x%x addr=0x%llx\n",
+		    c->c_num, h->opcode, dlen, opt_text);
+#endif
 		return;
 	}
 #endif
--- a/usr/src/cmd/iscsi/iscsitgtd/iscsi_login.c	Mon Feb 26 14:11:03 2007 -0800
+++ b/usr/src/cmd/iscsi/iscsitgtd/iscsi_login.c	Mon Feb 26 14:34:33 2007 -0800
@@ -208,6 +208,7 @@
 		    ISCSI_LOGIN_STATUS_NO_VERSION);
 		queue_str(c->c_mgmtq, Q_CONN_ERRS, msg_log, debug);
 		conn_state(c, T7);
+		free(rsp);
 		return (True);
 	}
 
--- a/usr/src/cmd/iscsi/iscsitgtd/main.c	Mon Feb 26 14:11:03 2007 -0800
+++ b/usr/src/cmd/iscsi/iscsitgtd/main.c	Mon Feb 26 14:34:33 2007 -0800
@@ -842,8 +842,8 @@
 	(void) sigignore(SIGPIPE);
 
 	/*
-	 * Look at the function lu_buserr_handler() above to see the details
-	 * of why we need to handle segmentation violations.
+	 * Look at the function lu_buserr_handler() in t10_sam.c to see the
+	 * details of why we need to handle segmentation violations.
 	 */
 	bzero(&act, sizeof (act));
 	act.sa_sigaction	= lu_buserr_handler;
--- a/usr/src/cmd/iscsi/iscsitgtd/t10_sam.c	Mon Feb 26 14:11:03 2007 -0800
+++ b/usr/src/cmd/iscsi/iscsitgtd/t10_sam.c	Mon Feb 26 14:34:33 2007 -0800
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -498,9 +498,6 @@
 t10_cmd_state_machine(t10_cmd_t *c, t10_cmd_event_t e)
 {
 	t10_lu_impl_t	*lu		= c->c_lu;
-#ifdef FULL_DEBUG
-	t10_cmd_state_t	oldstate	= c->c_state;
-#endif
 
 	/* ---- Callers must already hold the mutex ---- */
 	assert(pthread_mutex_trylock(&lu->l_cmd_mutex) != 0);
@@ -516,12 +513,6 @@
 
 		case T10_Cmd_T5:
 			c->c_state = T10_Cmd_S1_Free;
-#ifdef FULL_DEBUG
-			queue_prt(mgmtq, Q_STE_IO,
-			    "SAM:  %s(%s) -> %s -- %llx\n",
-			    state_to_str(oldstate), event_to_str(e),
-			    state_to_str(c->c_state), c->c_trans_id);
-#endif
 			cmd_common_free(c);
 			return (T10_Cmd_S1_Free);
 
@@ -548,12 +539,6 @@
 
 		case T10_Cmd_T5:
 			c->c_state = T10_Cmd_S1_Free;
-#ifdef FULL_DEBUG
-			queue_prt(mgmtq, Q_STE_IO,
-			    "SAM:  %s(%s) -> %s -- %llx\n",
-			    state_to_str(oldstate), event_to_str(e),
-			    state_to_str(c->c_state), c->c_trans_id);
-#endif
 			cmd_common_free(c);
 			return (T10_Cmd_S1_Free);
 
@@ -581,12 +566,6 @@
 			/*FALLTHRU*/
 		case T10_Cmd_T6:
 			c->c_state = T10_Cmd_S1_Free;
-#ifdef FULL_DEBUG
-			queue_prt(mgmtq, Q_STE_IO,
-			    "SAM:  %s(%s) -> %s -- %llx\n",
-			    state_to_str(oldstate), event_to_str(e),
-			    state_to_str(c->c_state), c->c_trans_id);
-#endif
 			cmd_common_free(c);
 			return (T10_Cmd_S1_Free);
 
@@ -628,12 +607,6 @@
 
 		case T10_Cmd_T6:
 			c->c_state = T10_Cmd_S1_Free;
-#ifdef FULL_DEBUG
-			queue_prt(mgmtq, Q_STE_IO,
-			    "SAM:  %s(%s) -> %s -- %llx\n",
-			    state_to_str(oldstate), event_to_str(e),
-			    state_to_str(c->c_state), c->c_trans_id);
-#endif
 			cmd_common_free(c);
 			return (T10_Cmd_S1_Free);
 
@@ -651,12 +624,6 @@
 		case T10_Cmd_T3:
 		case T10_Cmd_T4:
 			c->c_state = T10_Cmd_S1_Free;
-#ifdef FULL_DEBUG
-			queue_prt(mgmtq, Q_STE_IO,
-			    "SAM:  %s(%s) -> %s -- %llx\n",
-			    state_to_str(oldstate), event_to_str(e),
-			    state_to_str(c->c_state), c->c_trans_id);
-#endif
 			cmd_common_free(c);
 			return (T10_Cmd_S1_Free);
 
@@ -671,11 +638,6 @@
 	default:
 		assert(0);
 	}
-#ifdef FULL_DEBUG
-	queue_prt(mgmtq, Q_STE_IO, "SAM:  %s(%s) -> %s -- %llx\n",
-	    state_to_str(oldstate), event_to_str(e), state_to_str(c->c_state),
-	    c->c_trans_id);
-#endif
 	return (c->c_state);
 }
 
@@ -1424,8 +1386,18 @@
 
 	if ((ll = tgt_node_next(targ, XML_ELEMENT_LUNLIST, NULL)) == NULL)
 		goto error;
-	if ((n = tgt_node_next(ll, XML_ELEMENT_LUN, NULL)) == NULL)
+	n = NULL;
+	while ((n = tgt_node_next(ll, XML_ELEMENT_LUN, n)) != NULL) {
+		if (strtol(n->x_value, NULL, 0) == lun)
+			break;
+	}
+	if (n == NULL) {
+		spc_sense_create(cmd, KEY_ILLEGAL_REQUEST, 0);
+		/* ---- ACCESS DENIED - INVALID LU IDENTIFIER ---- */
+		spc_sense_ascq(cmd, 0x20, 0x9);
 		goto error;
+	}
+
 	if (tgt_find_value_str(n, XML_ELEMENT_GUID, &guid) == False) {
 		/*
 		 * Set the targ variable back to NULL to indicate that
--- a/usr/src/cmd/iscsi/iscsitgtd/t10_spc.c	Mon Feb 26 14:11:03 2007 -0800
+++ b/usr/src/cmd/iscsi/iscsitgtd/t10_spc.c	Mon Feb 26 14:34:33 2007 -0800
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -572,7 +572,7 @@
 		spc_sense_create(cmd, KEY_ILLEGAL_REQUEST, 0);
 		spc_sense_ascq(cmd, SPC_ASC_INVALID_CDB, 0x00);
 		trans_send_complete(cmd, STATUS_CHECK);
-		break;
+		return;
 	}
 	trans_send_complete(cmd, STATUS_GOOD);
 }
@@ -671,8 +671,9 @@
 				continue;
 			lun_idx += SCSI_REPORTLUNS_ADDRESS_SIZE;
 		}
-		if (trans_send_datain(cmd, (char *)buf, expected_data, 0,
-		    spc_free, True, buf) == False) {
+		if (trans_send_datain(cmd, (char *)buf,
+		    len + SCSI_REPORTLUNS_ADDRESS_SIZE, 0, spc_free, True,
+		    buf) == False) {
 			trans_send_complete(cmd, STATUS_BUSY);
 		}
 	} else {
--- a/usr/src/cmd/iscsi/iscsitgtd/util_port.c	Mon Feb 26 14:11:03 2007 -0800
+++ b/usr/src/cmd/iscsi/iscsitgtd/util_port.c	Mon Feb 26 14:34:33 2007 -0800
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -34,6 +34,7 @@
 #include <stdio.h>
 #include <errno.h>
 #include <netinet/in.h>
+#include <netinet/tcp.h>
 #include <assert.h>
 #include <syslog.h>
 #include <unistd.h>
@@ -71,6 +72,7 @@
 	target_queue_t		*q = p->port_mgmtq;
 	int			l,
 				accept_err_sleep = 1;
+	const int		just_say_no = 1;
 	pthread_t		junk;
 	struct in_addr		addr;
 	struct in6_addr		addr6;
@@ -162,6 +164,11 @@
 			queue_str(q, Q_GEN_ERRS, msg_status,
 			    "setsockopt keepalive failed");
 
+		if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
+		    (char *)&just_say_no, sizeof (just_say_no)) != 0)
+			queue_str(q, Q_GEN_ERRS, msg_status,
+			    "setsockopt NODELAY failed");
+
 		if ((conn = (iscsi_conn_t *)calloc(sizeof (iscsi_conn_t),
 		    1)) == NULL) {
 			/*