Module Name:    src
Committed By:   mlelstv
Date:           Sun Jun 24 17:01:35 UTC 2012

Modified Files:
        src/sys/dev/iscsi: iscsi_ioctl.c iscsi_rcv.c iscsi_send.c iscsi_text.c
            iscsi_utils.c

Log Message:
Add more debugging, fix filehandle usage, login negotiation and session
shutdown.
Add #ifdef'd code to send negotiation parameters in hex instead of base64,
so it works against older Linux targets.


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/sys/dev/iscsi/iscsi_ioctl.c
cvs rdiff -u -r1.2 -r1.3 src/sys/dev/iscsi/iscsi_rcv.c \
    src/sys/dev/iscsi/iscsi_utils.c
cvs rdiff -u -r1.4 -r1.5 src/sys/dev/iscsi/iscsi_send.c \
    src/sys/dev/iscsi/iscsi_text.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/iscsi/iscsi_ioctl.c
diff -u src/sys/dev/iscsi/iscsi_ioctl.c:1.3 src/sys/dev/iscsi/iscsi_ioctl.c:1.4
--- src/sys/dev/iscsi/iscsi_ioctl.c:1.3	Sat Jun  9 06:19:58 2012
+++ src/sys/dev/iscsi/iscsi_ioctl.c	Sun Jun 24 17:01:35 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: iscsi_ioctl.c,v 1.3 2012/06/09 06:19:58 mlelstv Exp $	*/
+/*	$NetBSD: iscsi_ioctl.c,v 1.4 2012/06/24 17:01:35 mlelstv Exp $	*/
 
 /*-
  * Copyright (c) 2004,2005,2006,2011 The NetBSD Foundation, Inc.
@@ -488,7 +488,6 @@ kill_connection(connection_t *conn, uint
 
 	conn->terminating = status;
 	conn->state = ST_SETTLING;
-	callout_stop(&conn->timeout);
 
 	/* let send thread take over next step of cleanup */
 	wakeup(&conn->pdus_to_send);
@@ -634,6 +633,7 @@ create_connection(iscsi_login_parameters
 	callout_setfunc(&connection->timeout, connection_timeout, connection);
 	connection->idle_timeout_val = CONNECTION_IDLE_TIMEOUT;
 
+	init_sernum(&connection->StatSN_buf);
 	create_pdus(connection);
 
 	if ((rc = get_socket(par->socket, &connection->sock)) != 0) {
@@ -646,6 +646,9 @@ create_connection(iscsi_login_parameters
 	DEBC(connection, 1, ("get_socket: par_sock=%d, fdesc=%p\n",
 			par->socket, connection->sock));
 
+	/* close the file descriptor */
+	fd_close(par->socket);
+
 	connection->threadobj = p;
 	connection->login_par = par;
 
@@ -666,7 +669,7 @@ create_connection(iscsi_login_parameters
 				"ConnSend")) != 0) {
 		DEBOUT(("Can't create send thread (rc %d)\n", rc));
 
-		connection->terminating = TRUE;
+		connection->terminating = ISCSI_STATUS_NO_RESOURCES;
 
 		/*
 		 * We must close the socket here to force the receive
@@ -716,9 +719,6 @@ create_connection(iscsi_login_parameters
 	session->mru_connection = connection;
 	CS_END;
 
-	/* close the file descriptor */
-	fd_close(par->socket);
-
 	DEBC(connection, 5, ("Connection created successfully!\n"));
 	return 0;
 }
@@ -764,9 +764,12 @@ recreate_connection(iscsi_login_paramete
 		return rc;
 	}
 
+	/* close the file descriptor */
+	fd_close(par->socket);
+
 	connection->threadobj = p;
 	connection->login_par = par;
-	connection->terminating = 0;
+	connection->terminating = ISCSI_STATUS_SUCCESS;
 	connection->recover++;
 	connection->num_timeouts = 0;
 	connection->state = ST_SEC_NEG;
@@ -831,9 +834,6 @@ recreate_connection(iscsi_login_paramete
 	DEBC(connection, 5, ("Connection ReCreated successfully - status %d\n",
 						 par->status));
 
-	/* close the file descriptor */
-	fd_close(par->socket);
-
 	return 0;
 }
 
@@ -906,7 +906,7 @@ check_login_pars(iscsi_login_parameters_
 			return ISCSI_STATUS_PARAMETER_INVALID;
 		}
 	}
-	return ISCSI_STATUS_SUCCESS;
+	return 0;
 }
 
 
@@ -1491,6 +1491,8 @@ iscsi_cleanup_thread(void *par)
 			while (conn->usecount > 0)
 				tsleep(conn, PWAIT, "finalwait", 20);
 
+			callout_stop(&conn->timeout);
+			closef(conn->sock);
 			free(conn, M_DEVBUF);
 
 			if (!(--sess->total_connections)) {

Index: src/sys/dev/iscsi/iscsi_rcv.c
diff -u src/sys/dev/iscsi/iscsi_rcv.c:1.2 src/sys/dev/iscsi/iscsi_rcv.c:1.3
--- src/sys/dev/iscsi/iscsi_rcv.c:1.2	Tue Jun  5 16:36:06 2012
+++ src/sys/dev/iscsi/iscsi_rcv.c	Sun Jun 24 17:01:35 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: iscsi_rcv.c,v 1.2 2012/06/05 16:36:06 mhitch Exp $	*/
+/*	$NetBSD: iscsi_rcv.c,v 1.3 2012/06/24 17:01:35 mlelstv Exp $	*/
 
 /*-
  * Copyright (c) 2004,2005,2006,2011 The NetBSD Foundation, Inc.
@@ -163,6 +163,8 @@ read_pdu_data(pdu_t *pdu, uint8_t *data,
 	int i, pad;
 	connection_t *conn = pdu->connection;
 
+	DEBOUT(("read_pdu_data: data segment length = %d\n",
+		ntoh3(pdu->pdu.DataSegmentLength)));
 	if (!(len = ntoh3(pdu->pdu.DataSegmentLength))) {
 		return 0;
 	}
@@ -324,8 +326,11 @@ check_StatSN(connection_t *conn, uint32_
 		ack_sernum(&conn->StatSN_buf, sn);
 
 	if (rc != 1) {
-		if (!rc)
+		if (rc == 0) {
+			DEBOUT(("Duplicate PDU, ExpSN %d, Recvd: %d\n",
+				conn->StatSN_buf.ExpSN, sn));
 			return -1;
+		}
 
 		if (rc < 0) {
 			DEBOUT(("Excessive outstanding Status PDUs, ExpSN %d, Recvd: %d\n",
@@ -410,8 +415,9 @@ receive_login_pdu(connection_t *conn, pd
 {
 	int rc;
 
-	DEBC(conn, 9, ("Received Login Response PDU, op=%x, flags=%x\n",
-			pdu->pdu.Opcode, pdu->pdu.Flags));
+	DEBC(conn, 9, ("Received Login Response PDU, op=%x, flags=%x, sn=%u\n",
+			pdu->pdu.Opcode, pdu->pdu.Flags,
+			ntohl(pdu->pdu.p.login_rsp.StatSN)));
 
 	if (req_ccb == NULL) {
 		/* Duplicate?? */
@@ -419,31 +425,31 @@ receive_login_pdu(connection_t *conn, pd
 		return -1;
 	}
 
-	if (!conn->StatSN_buf.next_sn)
-		conn->StatSN_buf.next_sn = conn->StatSN_buf.ExpSN =
-			ntohl(pdu->pdu.p.login_rsp.StatSN) + 1;
-	else if (check_StatSN(conn, pdu->pdu.p.login_rsp.StatSN, TRUE))
-		return -1;
-
-	if (pdu->temp_data_len) {
-		if ((rc = collect_text_data(pdu, req_ccb)) != 0) {
-			return max(rc, 0);
-		}
-	}
-
 	if (pdu->pdu.p.login_rsp.StatusClass) {
 		DEBC(conn, 1, ("Login problem - Class = %x, Detail = %x\n",
 				pdu->pdu.p.login_rsp.StatusClass,
 				pdu->pdu.p.login_rsp.StatusDetail));
 
 		req_ccb->status = ISCSI_STATUS_LOGIN_FAILED;
-	} else {
-		negotiate_login(conn, pdu, req_ccb);
-		/* negotiate_login will decide whether login is complete or not */
+		/* XXX */
+		wake_ccb(req_ccb);
 		return 0;
 	}
 
-	wake_ccb(req_ccb);
+	if (!conn->StatSN_buf.next_sn) {
+		conn->StatSN_buf.next_sn = conn->StatSN_buf.ExpSN =
+			ntohl(pdu->pdu.p.login_rsp.StatSN) + 1;
+	} else if (check_StatSN(conn, pdu->pdu.p.login_rsp.StatSN, TRUE))
+		return -1;
+
+	if (pdu->temp_data_len) {
+		if ((rc = collect_text_data(pdu, req_ccb)) != 0)
+			return max(rc, 0);
+	}
+
+	negotiate_login(conn, pdu, req_ccb);
+
+	/* negotiate_login will decide whether login is complete or not */
 	return 0;
 }
 
Index: src/sys/dev/iscsi/iscsi_utils.c
diff -u src/sys/dev/iscsi/iscsi_utils.c:1.2 src/sys/dev/iscsi/iscsi_utils.c:1.3
--- src/sys/dev/iscsi/iscsi_utils.c:1.2	Sat Jun  9 06:19:58 2012
+++ src/sys/dev/iscsi/iscsi_utils.c	Sun Jun 24 17:01:35 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: iscsi_utils.c,v 1.2 2012/06/09 06:19:58 mlelstv Exp $	*/
+/*	$NetBSD: iscsi_utils.c,v 1.3 2012/06/24 17:01:35 mlelstv Exp $	*/
 
 /*-
  * Copyright (c) 2004,2005,2006,2008 The NetBSD Foundation, Inc.
@@ -624,7 +624,9 @@ init_sernum(sernum_buffer_t *buff)
 int
 add_sernum(sernum_buffer_t *buff, uint32_t num)
 {
-	int i, t, b, n, diff;
+	int i, t, b;
+	uint32_t n;
+	int32_t diff;
 
 	/*
 	 * next_sn is the next expected SN, so normally diff should be 1.
@@ -633,7 +635,7 @@ add_sernum(sernum_buffer_t *buff, uint32
 	diff = (num - n) + 1;
 
 	if (diff <= 0) {
-		PDEB(1, ("Rx Duplicate Block: SN %d < Next SN %d\n", num, n));
+		PDEB(1, ("Rx Duplicate Block: SN %u < Next SN %u\n", num, n));
 		return 0;				/* ignore if SN is smaller than expected (dup or retransmit) */
 	}
 
@@ -652,7 +654,7 @@ add_sernum(sernum_buffer_t *buff, uint32
 	}
 
 	buff->top = t;
-	DEB(10, ("AddSernum bottom %d [%d], top %d, num %d, diff %d\n",
+	DEB(10, ("AddSernum bottom %d [%d], top %d, num %u, diff %d\n",
 			 b, buff->sernum[b], buff->top, num, diff));
 
 	return diff;

Index: src/sys/dev/iscsi/iscsi_send.c
diff -u src/sys/dev/iscsi/iscsi_send.c:1.4 src/sys/dev/iscsi/iscsi_send.c:1.5
--- src/sys/dev/iscsi/iscsi_send.c:1.4	Tue Jun 19 14:19:46 2012
+++ src/sys/dev/iscsi/iscsi_send.c	Sun Jun 24 17:01:35 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: iscsi_send.c,v 1.4 2012/06/19 14:19:46 martin Exp $	*/
+/*	$NetBSD: iscsi_send.c,v 1.5 2012/06/24 17:01:35 mlelstv Exp $	*/
 
 /*-
  * Copyright (c) 2004,2005,2006,2011 The NetBSD Foundation, Inc.
@@ -344,19 +344,20 @@ iscsi_send_thread(void *par)
 		fp = conn->sock;
 
 		/*
-		 * We must close the socket here to force the receive
+		 * We shutdown the socket here to force the receive
 		 * thread to wake up
 		 */
 		DEBC(conn, 9, ("Closing Socket %p\n", conn->sock));
 		solock((struct socket *) fp->f_data);
 		soshutdown((struct socket *) fp->f_data, SHUT_RDWR);
 		sounlock((struct socket *) fp->f_data);
-		closef(fp);
 
 		/* wake up any non-reassignable waiting CCBs */
 		for (ccb = TAILQ_FIRST(&conn->ccbs_waiting); ccb != NULL; ccb = nccb) {
 			nccb = TAILQ_NEXT(ccb, chain);
 			if (!(ccb->flags & CCBF_REASSIGN) || ccb->pdu_waiting == NULL) {
+				DEBC(conn, 9, ("Terminating CCB %p (t=%p)\n",
+					ccb,&ccb->timeout));
 				ccb->status = conn->terminating;
 				wake_ccb(ccb);
 			} else {
Index: src/sys/dev/iscsi/iscsi_text.c
diff -u src/sys/dev/iscsi/iscsi_text.c:1.4 src/sys/dev/iscsi/iscsi_text.c:1.5
--- src/sys/dev/iscsi/iscsi_text.c:1.4	Sat Jun  9 06:19:58 2012
+++ src/sys/dev/iscsi/iscsi_text.c	Sun Jun 24 17:01:35 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: iscsi_text.c,v 1.4 2012/06/09 06:19:58 mlelstv Exp $	*/
+/*	$NetBSD: iscsi_text.c,v 1.5 2012/06/24 17:01:35 mlelstv Exp $	*/
 
 /*-
  * Copyright (c) 2005,2006,2011 The NetBSD Foundation, Inc.
@@ -34,6 +34,9 @@
 #include <sys/md5.h>
 #include <sys/cprng.h>
 
+/* define to send T_BIGNUM in hex format instead of base64 */
+/* #define ISCSI_HEXBIGNUMS */
+
 #define isdigit(x) ((x) >= '0' && (x) <= '9')
 #define toupper(x) ((x) & ~0x20)
 
@@ -555,6 +558,10 @@ get_parameter(uint8_t *buf, negotiation_
 		return skiptozero(bp);
 	}
 
+	DEB(10, ("get_par: key <%s>=%d, val=%d, ret %p\n",
+			buf, i, entries[i].val, bp));
+	DEB(10, ("get_par: value '%s'\n",bp));
+
 	switch (entries[i].val) {
 	case T_NUM:
 		bp = get_numval(bp, &par->val.nval[0]);
@@ -589,8 +596,6 @@ get_parameter(uint8_t *buf, negotiation_
 		bp = NULL;
 		break;
 	}
-	DEB(10, ("get_par: key <%s>=%d, val=%d, ret %p\n",
-			buf, i, entries[i].val, bp));
 	return bp;
 }
 
@@ -619,6 +624,38 @@ my_strcpy(uint8_t *dest, const uint8_t *
 	return cc;
 }
 
+/*
+ * put_bignumval:
+ *    Write a large numeric value.
+ *    NOTE: Overwrites source string.
+ *
+ *    Parameter:
+ *          buf      The buffer pointer
+ *          par      The parameter
+ *
+ *    Returns:    The pointer to the next parameter, NULL on error.
+ */
+
+STATIC unsigned
+put_bignumval(negotiation_parameter_t *par, uint8_t *buf)
+{
+#ifdef ISCSI_HEXBIGNUMS
+	int k, c;
+
+	my_strcpy(buf, "0x");
+	for (k=0; k<par->list_num; ++k) {
+		c = par->val.sval[k] >> 4;
+		buf[2+2*k] = c < 10 ? '0' + c : 'a' + (c-10);
+		c = par->val.sval[k] & 0xf;
+		buf[2+2*k+1] = c < 10 ? '0' + c : 'a' + (c-10);
+	}
+	buf[2+2*k] = '\0';
+
+	return 2+2*par->list_num;
+#else
+	return base64_encode(par->val.sval, par->list_num, buf);
+#endif
+}
 
 /*
  * put_parameter:
@@ -635,9 +672,12 @@ STATIC unsigned
 put_parameter(uint8_t *buf, unsigned len, negotiation_parameter_t *par)
 {
 	int i;
-	unsigned	cc;
+	unsigned	cc, cl;
 	const uint8_t *sp;
 
+	DEB(10, ("put_par: key <%s>=%d, val=%d\n",
+		entries[par->key].name, par->key, entries[par->key].val));
+
 	if (par->key > MAX_KEY) {
 		return snprintf(buf, len, "%s=NotUnderstood", par->val.sval);
 	}
@@ -647,21 +687,21 @@ put_parameter(uint8_t *buf, unsigned len
 	for (i = 0; i < par->list_num; i++) {
 		switch (entries[par->key].val) {
 		case T_NUM:
-			cc += snprintf(&buf[cc], len - cc, "%d", par->val.nval[i]);
+			cl = snprintf(&buf[cc], len - cc, "%d",
+			               par->val.nval[i]);
 			break;
 
 		case T_BIGNUM:
-			/* list_num holds value size */
-			cc += base64_encode(par->val.sval, par->list_num, &buf[cc]);
+			cl = put_bignumval(par, &buf[cc]);
 			i = par->list_num;
 			break;
 
 		case T_STRING:
-			cc += my_strcpy(&buf[cc], par->val.sval);
+			cl =  my_strcpy(&buf[cc], par->val.sval);
 			break;
 
 		case T_YESNO:
-			cc += my_strcpy(&buf[cc],
+			cl = my_strcpy(&buf[cc],
 				(par->val.nval[i]) ? "Yes" : "No");
 			break;
 
@@ -680,18 +720,19 @@ put_parameter(uint8_t *buf, unsigned len
 				sp = "None";
 				break;
 			}
-			cc += my_strcpy(&buf[cc], sp);
+			cl = my_strcpy(&buf[cc], sp);
 			break;
 
 		case T_DIGEST:
-			cc += my_strcpy(&buf[cc], (par->val.nval[i]) ? "CRC32C" : "None");
+			cl = my_strcpy(&buf[cc],
+				(par->val.nval[i]) ? "CRC32C" : "None");
 			break;
 
 		case T_RANGE:
 			if ((i + 1) >= par->list_num) {
-				cc += my_strcpy(&buf[cc], "Reject");
+				cl = my_strcpy(&buf[cc], "Reject");
 			} else {
-				cc += snprintf(&buf[cc], len - cc,
+				cl = snprintf(&buf[cc], len - cc,
 						"%d~%d", par->val.nval[i],
 						par->val.nval[i + 1]);
 				i++;
@@ -699,26 +740,31 @@ put_parameter(uint8_t *buf, unsigned len
 			break;
 
 		case T_SENDT:
-			cc += my_strcpy(&buf[cc], par->val.sval);
+			cl = my_strcpy(&buf[cc], par->val.sval);
 			break;
 
 		case T_SESS:
-			cc += my_strcpy(&buf[cc],
+			cl = my_strcpy(&buf[cc],
 				(par->val.nval[i]) ? "Normal" : "Discovery");
 			break;
 
 		default:
+			cl = 0;
 			/* We should't be here... */
 			DEBOUT(("Invalid type %d in put_parameter!\n",
 					entries[par->key].val));
 			break;
 		}
+
+		DEB(10, ("put_par: value '%s'\n",&buf[cc]));
+
+		cc += cl;
 		if ((i + 1) < par->list_num) {
 			buf[cc++] = ',';
 		}
 	}
 
-	buf[cc] = 0x0;					/* make sure it's terminated */
+	buf[cc] = 0x0;				/* make sure it's terminated */
 	return cc + 1;				/* return next place in list */
 }
 
@@ -781,7 +827,11 @@ parameter_size(negotiation_parameter_t *
 
 		case T_BIGNUM:
 			/* list_num holds value size */
+#ifdef ISCSI_HEXBIGNUMS
+			size += 2 + 2*par->list_num;
+#else
 			size += base64_enclen(par->list_num);
+#endif
 			i = par->list_num;
 			break;
 

Reply via email to