On Thu, 27 Aug 2009 08:43:34 +0100 Chris Webb <chris@xxxxxxxxxxxx> wrote: > FUJITA Tomonori <fujita.tomonori@xxxxxxxxxxxxx> writes: > > > On Mon, 24 Aug 2009 21:56:24 +0100 > > Chris Webb <chris@xxxxxxxxxxxx> 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@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html