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;