[stgt] Strange sendtargets behaviour

FUJITA Tomonori fujita.tomonori at lab.ntt.co.jp
Sat Sep 5 20:40:40 CEST 2009


On Thu, 27 Aug 2009 08:43:34 +0100
Chris Webb <chris at arachsys.com> wrote:

> FUJITA Tomonori <fujita.tomonori at lab.ntt.co.jp> writes:
> 
> > On Mon, 24 Aug 2009 21:56:24 +0100
> > Chris Webb <chris at arachsys.com> wrote:
> > 
> > > I'm seeing an odd behaviour from sendtargets discovery from open-iscsi to
> > > tgt. We're running open-iscsi 2.0-871 against a remote linux tgt 0.9.7.
> > > discovery.sendtargets.iscsi.MaxRecvDataSegmentLength is set to 262144 to
> > 
> > discovery.sendtargets.iscsi.MaxRecvDataSegmentLength is open-iscsi's
> > parameter, right?
> 
> That's right, yes: it needs to be set large as tgtd uses it as a cap on
> sendtargets output and we don't want to truncate the this at a small number
> of targets.

Ok, I hacked up a patch to support multiple PDUs in SendTarget
session. Can you try this with the default
discovery.sendtargets.iscsi.MaxRecvDataSegmentLength?

BTW, if getnameinfo or getsockname fails, you still see a corrupted
response. Better to handle those errors but if getnameinfo or
getsockname fails, there is something wrong with your environment,
isn't it?


diff --git a/usr/iscsi/iscsid.c b/usr/iscsi/iscsid.c
index 79c6e2d..52dfbcb 100644
--- a/usr/iscsi/iscsid.c
+++ b/usr/iscsi/iscsid.c
@@ -168,7 +168,8 @@ void text_key_add(struct iscsi_connection *conn, char *key, char *value)
 
 	buffer = conn->rsp_buffer;
 
-	if (conn->rsp.datasize + len > max_len)
+	if (conn->rsp.datasize + len > max_len &&
+	    (conn->req.bhs.opcode & ISCSI_OPCODE_MASK) != ISCSI_OP_TEXT)
 		goto drop;
 
 	if (conn->rsp.datasize + len > INCOMING_BUFSIZE) {
@@ -805,26 +806,45 @@ static void cmnd_exec_text(struct iscsi_connection *conn)
 {
 	struct iscsi_text *req = (struct iscsi_text *)&conn->req.bhs;
 	struct iscsi_text_rsp *rsp = (struct iscsi_text_rsp *)&conn->rsp.bhs;
+	int max_len = conn->session_param[ISCSI_PARAM_MAX_XMIT_DLENGTH].val;
 
 	memset(rsp, 0, BHS_SIZE);
 
-	if (be32_to_cpu(req->ttt) != 0xffffffff) {
-		/* reject */;
-	}
 	rsp->opcode = ISCSI_OP_TEXT_RSP;
 	rsp->itt = req->itt;
-	/* rsp->ttt = rsp->ttt; */
-	rsp->ttt = 0xffffffff;
 	conn->exp_cmd_sn = be32_to_cpu(req->cmdsn);
 	if (!(req->opcode & ISCSI_OP_IMMEDIATE))
 		conn->exp_cmd_sn++;
 
-	dprintf("Text request: %d\n", conn->state);
-	text_scan_text(conn);
+	if (be32_to_cpu(req->ttt) == ISCSI_RESERVED_TAG) {
+		conn->text_datasize = 0;
+		conn->text_rsp_buffer = conn->rsp_buffer;
+
+		text_scan_text(conn);
+
+		conn->text_datasize = conn->rsp.datasize;
+
+		if (conn->text_datasize > max_len) {
+			conn->ttt++;
+			if (conn->ttt == ISCSI_RESERVED_TAG)
+				conn->ttt++;
+		} else
+			conn->ttt = ISCSI_RESERVED_TAG;
+	} else if (!conn->text_datasize || conn->ttt != be32_to_cpu(req->ttt)) {
+		/* reject */
+		return;
+	}
 
-	if (req->flags & ISCSI_FLAG_CMD_FINAL)
+	if (conn->text_datasize < max_len)
 		rsp->flags = ISCSI_FLAG_CMD_FINAL;
 
+	conn->rsp.datasize = min(max_len, conn->text_datasize);
+	conn->rsp.data = conn->text_rsp_buffer;
+	conn->text_rsp_buffer += conn->rsp.datasize;
+	conn->text_datasize -= conn->rsp.datasize;
+
+	rsp->ttt = cpu_to_be32(conn->ttt);
+
 	rsp->statsn = cpu_to_be32(conn->stat_sn++);
 	rsp->exp_cmdsn = cpu_to_be32(conn->exp_cmd_sn);
 	rsp->max_cmdsn = cpu_to_be32(conn->max_cmd_sn);
diff --git a/usr/iscsi/iscsid.h b/usr/iscsi/iscsid.h
index b301c78..091ad8f 100644
--- a/usr/iscsi/iscsid.h
+++ b/usr/iscsi/iscsid.h
@@ -170,6 +170,10 @@ struct iscsi_connection {
 	int rx_size;
 	int tx_size;
 
+	uint32_t ttt;
+	int text_datasize;
+	void *text_rsp_buffer;
+
 	struct iscsi_task *rx_task;
 	struct iscsi_task *tx_task;
 

--
To unsubscribe from this list: send the line "unsubscribe stgt" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



More information about the stgt mailing list