[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