Re: Reject on Data-Out exceeding ExpectedDataTransferLength

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 4/1/2014 5:09 AM, Nicholas A. Bellinger wrote:
Hi Nicholas,
Hi Tejas,

On Wed, 2014-03-26 at 12:13 +0530, Tejas Vaykole wrote:
Hi,
I need clarification on the behavior of LIO regarding SCSI Response
on error when single or multiple dataout PDU's exceeds EDTL limit.

I understand this is an error. However, I am expecting the target
to return check condition (RFC section 10.4.7.2 -Sense Data) instead
what I am seeing is that LIO is returning reject.

Below is the sequence of write and r2t...

The values negotiated are MaxBurstLength=2096, FirstBurstLength=512, ,ImmediateData=No,InitiaR2t=NO and ERL>0.

On a side note, I'm not sure it's legal to use a MaxBurstLength that is
not modulo 512 bytes. (eg: smallest physical sector size)

Is there a passage in RFC-3720 that explicitly allows this..?
No,there is no such passage in RFC.
I->T:Write (EDTL=1024)
T->I:Got R2T With DesiredLength=1024
I->T:Data Out with DSL=512 and F=0
T->I:Got R2T With DesiredLength=512
I->T:Data Out with DSL=512 and F=0 (Please note: Still F=0)
T->I:Reject(Malformed Packet) X 10

At this point I am expecting check-condition,however I am
getting reject (10 of them) from target.

According to RFC Section 6.3 and 10.17.1 quoted below the target should
under this condition send out check-condition and not reject.
Please note it is also sending of 10 Rejects packets..I have attached the pcap file for the same.
Is my understanding correct ? please clarify

The rejects are actually being generated by iscsit_handle_scsi_cmd() ->
iscsit_setup_scsi_cmd() sanity checks, and not by the Data-Out PDU
processing code-path.

This is happening because the actual Data-Out payload is not being
dumped in ERL>0 mode after, I assume, the following check in
iscsi_target_erl0.c:iscsit_dataout_check_sequence() notices that all
expected data-out has been received, but no F_BIT was set:

         /*
          * Perform various MaxBurstLength and ISCSI_FLAG_CMD_FINAL sanity
          * checks for the current DataOUT Sequence.
          */
         if (hdr->flags & ISCSI_FLAG_CMD_FINAL) {

		<SNIP>

	} else {
                 if (conn->sess->sess_ops->DataSequenceInOrder) {
<SNIP>

                         if ((cmd->write_data_done + payload_length) ==
                                         cmd->se_cmd.data_length) {
                                 pr_err("Command ITT: 0x%08x reached"
                                 " last DataOUT PDU in sequence but ISCSI_FLAG_"
                                 "CMD_FINAL is not set, protocol error.\n",
                                         cmd->init_task_tag);
                                 return DATAOUT_CANNOT_RECOVER;
                         }
		} else {
			<SNIP>
		}
	}

However, neither of the above pr_err() appear in your log below..?

Would it be possible to confirm which Data-Out PDU sanity check is
actually failing for your test-case..?
(The RFC section 6.3)
Targets MUST NOT implicitly terminate an active task by sending a Reject
PDU for any PDU exchanged
   during the life of the task. If the target decides to terminate the
task, a Response PDU (SCSI, Text,
Task, etc.) must be returned by the target to conclude the task. If the
task had never been active before
   the Reject (i.e., the Reject is on the command PDU), targets should
not send any further responses
because the command itself is being discarded.

Correct.

The reject here is occurring because the target thinks that it is
processing a ISCSI_OP_SCSI_CMD with bogus flags, while in reality it's
actually the ISCSI_OP_SCSI_DATA_OUT data-payload in the TCP stream.

(The RFC section 10.17.1)
In all the cases in which a pre-instantiated SCSI task is terminated
because of the reject, the target
MUST issue a proper SCSI command response with CHECK CONDITION as
described in Section 10.4.3
Response.
So AFAICT, it's still OK to send a reject (without response) if the task
was never active on the target.  Consider Section 6.3.  Usage Of Reject
PDU in Recovery:

    Targets MUST NOT implicitly terminate an active task by sending a
    Reject PDU for any PDU exchanged during the life of the task.  If the
    target decides to terminate the task, a Response PDU (SCSI, Text,
    Task, etc.) must be returned by the target to conclude the task.  If
    the task had never been active before the Reject (i.e., the Reject is
    on the command PDU), targets should not send any further responses
    because the command itself is being discarded.

    The above rule means that the initiator can eventually expect a
    response on receiving Rejects, if the received Reject is for a PDU
    other than the command PDU itself.

AFAICT there are no REJECTs generated from within the
iscsit_handle_data_out() that implicitly terminate the task.

  In these cases in which a status for the SCSI task was already
sent before the reject, no additional
status is required. If the error is detected while data from the
initiator is still expected (i.e., the command PDU
did not contain all the data and the target has not received a Data-Out
PDU with the Final bit set to 1 for the
unsolicited data, if any, and all outstanding R2Ts, if any), the target
MUST wait until it receives the last
expected Data-Out PDUs with the F bit set to 1 before sending the
Response PDU.

The dmesg shows the following output :

[root@wfsc test_suite_iscsi]#dmesg -c

294.640821] ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL not set. Bad iSCSI Initiator.
[  294.640824] ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL not set. Bad iSCSI Initiator.
[  294.640825] ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL not set. Bad iSCSI Initiator.
[  294.640827] ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL not set. Bad iSCSI Initiator.
[  294.640828] ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL not set. Bad iSCSI Initiator.
[  294.640829] ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL not set. Bad iSCSI Initiator.
[  294.640830] ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL not set. Bad iSCSI Initiator.
[  294.640832] ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL not set. Bad iSCSI Initiator.
[  294.640833] ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL not set. Bad iSCSI Initiator.
[  294.640834] ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL not set. Bad iSCSI Initiator.
[  344.345039] device lo left promiscuous mode


So based upon the points above, I need a bit more information in order
to determine where the Data-Out sanity check is (assumed to be) failing,
the test fails at drivers/target/iscsi/iscsi_target_erl0.c :330
<SNIP>

             else {
330                         if (next_burst_len == seq->xfer_len) {
331                                 pr_err("Command ITT: 0x%08x reached"
332 " last DataOUT PDU in sequence but ISCSI_FLAG_" 333 "CMD_FINAL is not set, protocol error.\n",
334 cmd->init_task_tag);
335                                 return DATAOUT_CANNOT_RECOVER;
336                         }

<SNIP>
the dmesg logs were incomplete,apologies for that. the complete logs are as follows-

[ 1500.280343] Command ITT: 0xa3a3a3a3 reached last DataOUT PDU in sequence but ISCSI_FLAG_CMD_FINAL is not set, protocol error. [ 1500.280352] ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL not set. Bad iSCSI Initiator. [ 1500.280357] ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL not set. Bad iSCSI Initiator. [ 1500.280360] ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL not set. Bad iSCSI Initiator. [ 1500.280362] ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL not set. Bad iSCSI Initiator. [ 1500.280364] ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL not set. Bad iSCSI Initiator. [ 1500.280366] ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL not set. Bad iSCSI Initiator. [ 1500.280369] ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL not set. Bad iSCSI Initiator. [ 1500.280371] ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL not set. Bad iSCSI Initiator. [ 1500.280373] ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL not set. Bad iSCSI Initiator. [ 1500.280376] ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL not set. Bad iSCSI Initiator.


and where (if any) missing iscsit_dump_data_payload() calls should be
added in order to dump the subsequent solicited data-out payload from
the TCP stream.
Thanks,

--nab


--
Thanks and regards.
Tejas Vaykole
Development Engineer.
Calsoft Inc.

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




[Index of Archives]     [Linux SCSI]     [Kernel Newbies]     [Linux SCSI Target Infrastructure]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Device Mapper]

  Powered by Linux