📄 overview-ffp
字号:
First DataIn PDU of third burst (77824 bytes total so far) Opcode = 0x25; F = 0; DataSN = 7; DSL = 12288; Buffer Offset = 77824 Second DataIn PDU of third burst (90112 bytes total so far) Opcode = 0x25; F = 1; DataSN = 8; DSL = 8192; Buffer Offset = 90112 Third (last) DataIn PDU of third burst (98304 bytes total so far) Opcode = 0x25; F = 1; DataSN = 9; DSL = 4096; Buffer Offset = 98304 First (last) DataIn PDU of fourth burst (102400 bytes total so far) Opcode = 0x21; F = 1; DSL = 0; Response = 0; Status = 0x00 StatSN = 415.1.6.2 Implementation The grouping of successive DataIn PDUs into bursts or sequences is controlled by the "recvd_length" field in the "struct command". This is initialized to 0 in the initiator's "iscsi_initiator_queuecommand" function when the READ command is first set up. Whenever it receives a DataIn PDU, the "rx_thread" will add the DSL of the DataIn PDU to the recvd_length field in the associated command and will check the result in the recvd_length field against the value of the negotiated MaxBurstSize key to ensure that the burst is not too long. Once this has been done, if the F-bit in the DataIn PDU is set to 1, then the recvd_length field will be reset to 0 in preparation for the start of the next burst (if any) that may follow. In all cases (F-bit set to 0 or 1), the data_in_sn field of the associated command is checked against the DataSN field in the DataIn PDU and is then incremented by 1, as was already discussed above.5.1.7 Using Phase Collapse The preceding discussions assumed that "phase collapse" was not being used. "phase collapse" is the term used when the target decides to send the final status of an entire SCSI READ command in the last DataIn PDU it sends for that command and thereby no longer needs to send the final SCSIResponse PDU. This can be done only if the Response field in the SCSIResponse PDU would have been 0, indicating "Command Completed at Target" (any other Response field value, such as 1 ("Target Failure"), requires the use of a SCSIResponse PDU). This is also something that the target can choose to do or not at any time -- it is not negotiated, and the initiator must always be prepared to deal with it. The target indicates that is using "phase collapse" by setting the S-bit to 1 in the final DataIn PDU it sends back to the initiator at the end of a READ command. (In everything discussed so far, the S-bit in every DataIn PDU has been set to 0). When this S-bit is set to 1, the information normally carried in the SCSIResponse PDU must now be carried in the DataIn PDU (in addition to all the information already carried in the DataIn PDU, of course). This means that the following fields, which are normally reserved in a DataIn PDU, will now contain meaningful information: StatSN - the target fills this field with the current value of its StatSN counter, and will then increment this counter (just as it normally does when sending a SCSIResponse PDU). Status - the target fills this field with the same status value that it would normally put in the Status field of a SCSIResponse PDU, with the understanding that this value must indicate a successful completion. (The usual successful completion value used is 0, meaning "GOOD".) O-bit - the target sets this bit if it wanted to send more data than the initiator asked for in the EDTL field of the SCSICommand PDU. In this case, the ResidualCount field will contain the number of bytes of extra data that were not transfered. U-bit - the target sets this bit if it could not send all the data that the initiator asked for in the EDTL field of the SCSICommand PDU. In this case, the ResidualCount field will contain the number of bytes of missing data that were not transfered. ResidualCount - set only if the either O-bit or U-bit is set. 0 otherwise.5.1.7.1 PDU trace Using the same example discussed above to illustrate the use of MaxBurstSize during a READ operation, the only effect of a "phase collapse" is to eliminate the last SCSIResponse PDU and add extra information to the last DataIn PDU in the last burst. The complete sequence of PDUs for this operation follows (note that all these PDUs carry the same ITT = 88905, and all the PDUs sent by the target contain ExpCmdSN=22239): Initiator->Target Opcode = 0x01; F = 1; R = 1; DSL = 0; EDTL = 102400; CmdSN = 22238; ExpStatSN = 41 Target -> Initiator Opcode = 0x25; F=0; S=0; DataSN = 0; DSL = 12288; Buffer Offset = 0 First DataIn PDU of first burst (12288 bytes total so far) Opcode = 0x25; F=0; S=0; DataSN = 1; DSL = 12288; Buffer Offset = 12288 Second DataIn PDU of first burst (24576 bytes total so far) Opcode = 0x25; F=1; S=0; DataSN = 2; DSL = 8192; Buffer Offset = 24576 Third (last) DataIn PDU of first burst (32768 bytes total so far) Opcode = 0x25; F=0; S=0; DataSN = 3; DSL = 12288; Buffer Offset = 32768 First DataIn PDU of second burst (45056 bytes total so far) Opcode = 0x25; F=0; S=0; DataSN = 4; DSL = 12288; Buffer Offset = 45056 Second DataIn PDU of second burst (57344 bytes total so far) Opcode = 0x25; F=1; S=0; DataSN = 5; DSL = 8192; Buffer Offset = 57344 Third (last) DataIn PDU of second burst (65536 bytes total so far) Opcode = 0x25; F=0; S=0; DataSN = 6; DSL = 12288; Buffer Offset = 65536 First DataIn PDU of third burst (77824 bytes total so far) Opcode = 0x25; F=0; S=0; DataSN = 7; DSL = 12288; Buffer Offset = 77824 Second DataIn PDU of third burst (90112 bytes total so far) Opcode = 0x25; F=1; S=0; DataSN = 8; DSL = 8192; Buffer Offset = 90112 Third (last) DataIn PDU of third burst (98304 bytes total so far) Opcode = 0x25; F=1; S=1; DataSN = 9; DSL = 4096; Buffer Offset = 98304 Status = 0x00; StatSN = 41 First (last) DataIn PDU of fourth burst (102400 bytes total so far)5.1.7.2 Implementation On the initiator side, "phase collapse" is handled entirely within the "rx_data" function of the rx_thread. After doing all the processing already described above for the rx_data function, the S-bit is checked, and if it is set to 1, then the function "do_scsi_response" is called. "do_scsi_response" performs the common processing for the SCSIResponse PDU and the DataIn PDU with phase collapse. This has already been discussed above under the discussion of SCSIResponse PDU processing done by the rx_rsp function (steps 2 through 7 inclusive of that function).6.0 FFP Testing In order to test Initiators and Targets on READ and WRITE commands in Full Feature Phase, it is obvious that the test scripts will have to be fairly long, since they have to complete a full login phase and get past the initial discovery steps in the Full Feature Phase (i.e., the "iscsi_config up" step). Furthermore, since the initiator controls all transactions, the vendor will have to run programs on the initiator side that exhibit certain behavior patterns that the target test script will look for. A good situation would be to have the target script simulate a target disk, and have the vendor's initiator mount that disk and then read/write large files from/to that disk. In doing this you have to be sure that the data in the files is actually forced to disk (for example, Linux likes to keep data in its buffer cache, and only periodically flushes the cache to the actual disk. Similarly, if data to be read is already in its buffer cache, Linux will avoid reading it from the disk again. This makes Linux more efficient, but defeats the tests we want to run on the target!) The Linux "sync" command should probably be used after every copy command to ensure that the data is forced from the buffer cache to disk.6.1 Testing READ when DUT is an initiator In this situation, the test script will simulate a target. This target will wait to receive a READ command from the initiator, and then will send responses to the initiator in order to test it.6.1.1 Testing for correctness Clearly an important type of test will be a target script that checks all commands sent to it by the initiator (the formats are correct, the counters are all incrementing correctly, the various negotiated keys are being applied correctly, etc.) and then responds correctly to these commands. Thus this one script will verify that under "normal" circumstances, an initiator under test is correctly performing a whole set of testable items. Examples of this type of test follow.6.1.1.1 Testing MaxRecvPDULength Testable item: The amount of data attached to any PDU sent by the target must not exceed the MaxRecvPDULength key sent to the target by the initiator during login phase. Procedure: Have the initiator agree to send a fairly small value for the MaxRecvPDULength key during the login phase (the target cannot negotiate this, so you will have to get the vendor to configure this value in his initiator). Then when the target receives a READ SCSICommand with the EDTL greater than MaxRecvPDULength, reply with a sequence of DataIn PDUs each containing no more than MaxRecvPDULength bytes of data (but not more than the EDTL of the SCSICommand). Result: Everything about this transmission should be correct. Therefore, the initiator should not detect any errors.6.1.1.2 Testing MaxBurstSize and DataSN Testable Item: The amount of data sent in a sequence of DataIn PDUs must not exceed the value of the MaxBurstSize key negotiated during login phase. Furthermore, the DataSN field in a sequence of DataIN PDUs sent in response to a READ SCSICommand should start at 0 for the first DataIn PDU sent, and should increment by 1 for all following DataIN PDUs for this SCSICommand, regardless of the number of bursts needed to satisfy this SCSICommand. Procedure: During login phase, negotiate a value for MaxBurstSize that is fairly small. Then when the target receives a READ SCSICommand with the EDTL greater than MaxBurstSize, compute the number of DataIn PDUs needed to satisfy one burst, and the total number of bursts that are needed. Suppose there are N PDUs per burst, and B bursts. Then send the first burst: N-1 PDUs, each containing MaxRecvPDULength bytes and having the F-bit set to 0, followed by the Nth PDU with the F-bit set to 1. The DataSN field of the first PDU should be set to 0, and should be incremented by 1 in all subsequent DataIn PDUs. Then send the second burst, with the DataSN field in the first DataIn PDU of that burst simply continuing to increment from the value in the previous DataIn PDU, regardless of the burst structure. Continue in this way for all subsequent bursts that are part of this SCSICommand. Result: There are no errors in this transmission. Therefore, the initiator should not detect any.6.1.2 Testing for error detection Another important type of test will be a target script that is similar to the previous one, but which sends back to the initiator responses that contain errors. We then observe the behavior of the initiator to see if it detects the error and takes the appropriate action. Again, one script should simultaneously test a whole set of testable items. Examples of this second type of test follow.6.1.2.1 Testing MaxRecvPDULength Testable item: The amount of data attached to any PDU sent by the target must not exceed the MaxRecvPDULength key sent to the target by the initiator during login phase. Procedure: Have the initiator agree to send a fairly small value for the MaxRecvPDULength key during the login phase (the target cannot negotiate this, so you will have to get the vendor to configure this value in his initiator). Then when the target receives a READ SCSICommand with the EDTL greater than MaxRecvPDULength, reply with a DataIn PDU containing more than MaxRecvPDULength bytes of data (but not more than the EDTL of the SCSICommand). Result: Except for the fact that the DataIn PDU contains too much data according to the MaxRecvPDULength key, everything else about this transmission should be correct. Therefore, the initiator should detect the oversized DataIn PDU, but no other error, and should take appropriate action. This is a Format Error, as defined in section 8.3 of draft 9.6.1.2.2 Testing MaxBurstSize Testable Item: The amount of data sent in a sequence of DataIn PDUs must not exceed the value of the MaxBurstSize key negotiated during login phase. Procedure: During login phase, negotiate a value for MaxBurstSize that is fairly small. Then when the target receives a READ SCSICommand with the EDTL greater than MaxBurstSize, reply with a sequence of DataIn PDUs, each having the F-bit set to 0 and each containing no more than MaxRecvPDULength bytes of data, yet with the total number of bytes being equal to the EDTL of the SCSICommand (and therefore greater than the MaxBurstSize). Result: Except for the fact that the sequence of DataIn PDUs contain more than the MaxBurstSize amount of data, there are no other errors in this transmission. Therefore, the initiator should detect that the sequence or burst is too long and take appropriate action. This is a protocol error, as defined in section 8.8 of draft 9.6.1.2.3 Testing DataSN Testable Item: The DataSN field in a sequence of DataIN PDUs sent in response to a READ SCSICommand should start at 0 for the first DataIn PDU sent, and should increment by 1 for all following DataIN PDUs for this SCSICommand, regardless of the number of bursts needed to satisfy this SCSICommand. Procedure: During login phase, negotiate a value for MaxBurstSize that is fairly small. Then when the target receives a READ SCSICommand with the EDTL greater than MaxBurstSize, compute the number of DataIn PDUs needed to satisfy one burst, and the total number of bursts that are needed. Suppose there are N PDUs per burst, and B bursts. Then send the first burst: N-1 PDUs, each containing MaxRecvPDULength bytes and having the F-bit set to 0, followed by the Nth PDU with the F-bit set to 1. The DataSN field of the first PDU should be set to 0, and should be incremented by 1 in all subsequent DataIn PDUs. Then send the second burst, but reset the DataSN field in the first DataIn PDU of that burst to 0. Continue in this way for all subsequent bursts that are part of this SCSICommand. Result: Except for the fact that the sequence number of the DataIn PDUs is being reset at the start of every burst, there are no other errors in this transmission. Therefore, the initiator should detect that the DataSN field is not correct and take appropriate action. This is a sequence error, as defined in section 8.5 of draft 9.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -