Commit Graph

709 Commits

Author SHA1 Message Date
Ronnie Sahlberg
e90b16ef43 Merge pull request #51 from plieven/outqueue-fixes-v3
SOCKET queue cmd PDUs directly in waitpdu queue
2012-12-03 06:55:01 -08:00
Peter Lieven
dbe9a1e73a SOCKET queue cmd PDUs directly in waitpdu queue
A storage might sent an R2T response for a WRITE command while
we still sending out the WRITE command PDU. This is especially
the case when the command PDU carries immediata data.

Without this patch the R2T response will get lost as
the cmdpdu for the R2T cannot be found in iscsi_process_pdu()
leading to a deadlock.

Signed-off-by: Peter Lieven <pl@kamp.de>
2012-12-03 11:05:21 +01:00
Ronnie Sahlberg
39f42dbd2f Update comments explaining how we send unsolicited data.
Add comments to explain how/why we send unsolicited data.
This is a somewhat hairy area and it is easy to make mistakes here, so
extra comments on the how/why is useful.
2012-12-02 13:09:12 -08:00
Ronnie Sahlberg
023c7f855a Simplify the logic for when we need to send unsolicited DATA-OUT 2012-12-02 12:58:52 -08:00
Ronnie Sahlberg
338a8e26f5 When sending unsolicited data out, beginning of buffer to send is pdu->out_len, not pdu->offset.
We might have already sent pdu->out_len amount of data as immediate data.
2012-12-02 10:05:32 -08:00
Ronnie Sahlberg
a3ce92c93c Fix sending of unsolicited data in the first burst
When deciding if to generate a data out queue for the first sequence
the test was wrong.
We should not check if INITIAL_R2T is NO and IMMEDIATE_DATA=NO.
Immediate data does not matter here.

What we should check is IF we have more data we need to send and IF
INITIAL_R2T allows us to send more data, then we generate a train of DATA-OUT.

If MaxRecvDataSegmentLength is less than FirstBurstLength we will often have
to send unsolicited data as both ImmediateData and also as unsolicited
DATA-OUT PDUs.

Example:
Assume Target has responded :
MaxRecvDataSegmentLength = 8k
FirstBurstLength = 64k
ImmediateData=YES
InitialR2T=NO

Then this should generate the following sequence :
I->T   ISCSI_COMMAND + 8K of immediate data. F-Bit is not set.
I->T   DATA-OUT 8K
I->T   DATA-OUT 8K
I->T   DATA-OUT 8K
I->T   DATA-OUT 8K
I->T   DATA-OUT 8K
I->T   DATA-OUT 8K
I->T   DATA-OUT 8K. Final PDU in sequence   so F-bit is set.
T->I   R2T
...
2012-12-02 09:55:07 -08:00
Ronnie Sahlberg
564fc9963a Max immediate data we can send is MIN(maxrecvdatasegmentlength, firstburstlength)
Also, we can send unsolicited DATA-OUT if we need to regardless of whether we also sent immediate data.
2012-12-02 09:37:18 -08:00
Ronnie Sahlberg
f1d5510e9c TESTS: Add test that we can talk to a target with IMMEDIATE_DATA==NO and INITIAL_R2T==NO 2012-12-01 11:40:07 -08:00
Ronnie Sahlberg
56707bcdf9 Fix how we negotiate IMMEDIATE_DATA. It defaults to YES and is negotiated
unless one side said NO
2012-12-01 11:21:24 -08:00
Ronnie Sahlberg
04970ef95e TESTS: Add a new test that does a one block write using unsilicited immediate data
As part of the test also validate the PDU that libiscsi generates and verify that
1, the PDU we send has the F flag set
2, that datasegmentlength for the PDU is one block
2012-12-01 10:45:42 -08:00
Ronnie Sahlberg
edb0df07d6 INITIAL_R2T defaults to YES 2012-12-01 09:43:49 -08:00
Ronnie Sahlberg
276f600181 Add functions to control how IMMEDIATE_DATA and INITIAL_R2T is negotiated 2012-12-01 09:19:50 -08:00
Ronnie Sahlberg
9a570e0b37 Dont clear the F-flag when we we have more data to send later as solicited data.
If we do a write that spans more than first-burst-length amount of data
and we can use immediate data.

This will lead to a sequence
I->T  SCSI_COMMAND + furst_burst_length of immediate data
T->I  R2T
I->T  DATA-OUT with the remainder of the data.
T->I  SCSI_RESPONSE

In this situation we still have to set the F-bit in the flags for the ISCSI_COMMAND.

The F-bit indicates that the PDU is the final PDU in the current sequence
and is what will trigger the target to process what it has currently received
after which the target will either respond with a SCSI-RESULT or DATA-IN if this
was the final sequence of the command,
Or in the case this was not the last sequence, then the target will send a R2T
to request the next sequence for this command.

In this scenario above we have two sequences.
the first sequence is the SCSI_COMMAND with immediate data and since it has filled the full amount of immediate data and can not send any more data until an R2T, this means this pdu ends the sequence and thus has the F-bit set.

Once we receive the R2T the second sequence starts, which also will have the F-bit set in the PDU.
2012-12-01 08:28:47 -08:00
Ronnie Sahlberg
6661f290a0 Remove next/prev pointers from the scsi_cbdata structure 2012-12-01 08:14:49 -08:00
Ronnie Sahlberg
f062483c7a Merge pull request #50 from plieven/outqueue-fixes-v2
Outqueue fixes v2
2012-12-01 07:46:45 -08:00
Peter Lieven
92114f5d7a ISCSI fix broken send logic in iscsi_scsi_async_command [v2]
This fixes the IMMEDIATE_DATA_YES case if the paylaod did
not fit into the first PDU and fixes no unsolicited data
sent out iff IMMEDIATE_DATA_NO and INITIAL_R2T_NO.

Signed-off-by: Peter Lieven <pl@kamp.de>
2012-11-30 21:06:39 +01:00
Peter Lieven
30df192634 DATA-OUT set pdu->cmdsn appropriately
set the cmdsn in the pdu struct so we can compare with
maxcmdsn when sending to socket even if data-out pdus
do not carry a cmdsn on the wire.

if we would not set pdu->cmdsn comparsion with
iscsi->maxcmdsn would cause a deadlock after
maxcmdsn increases to 2^31.

Signed-off-by: Peter Lieven <pl@kamp.de>
2012-11-30 18:18:17 +01:00
Ronnie Sahlberg
3ae7cec51d Revert "ISCSI fix broken send logic in iscsi_scsi_async_command"
This reverts commit 548bd22f51.

Revert for now. Will check it later today.
Causes 0130 and other tests to fail/hang when sending a solicited data-out
2012-11-30 06:49:53 -08:00
Ronnie Sahlberg
6f51d21111 Merge pull request #48 from plieven/iov-upstream-fixes
iov write important upstream fixes
2012-11-30 06:44:52 -08:00
Peter Lieven
58e5ef5cbc SCSI_IOVECTOR remove size field
Remove the size field as it is not used. If we would keep it
we would have to calculate it in scsi_task_set_iov_in/out which
would add unneccassry wals to the iovec array.

Signed-off-by: Peter Lieven <pl@kamp.de>
2012-11-30 08:44:33 +01:00
Peter Lieven
548bd22f51 ISCSI fix broken send logic in iscsi_scsi_async_command
The send logic was completely broken for any cases except
ISCSI_INITIAL_R2T_NO and ISCSI_IMMEDIATE_DATA_YES.
The final flag was set wrong or no data was sent.

It was also broken if the data did not fit into the cmd_pdu as
the consecutive pdus did not have the scsi_cbdata set which
lead to a segfault in iscsi_get_user_out_buffer().

Unfortunately we need to include scsi-lowlevel.h again in iscsi-private.h.
This should be fixed asap by introduction of an iscsi_task struct
to avoid to store iscsi relevant data in the scsi_task.

Signed-off-by: Peter Lieven <pl@kamp.de>

Conflicts:

	lib/iscsi-command.c

Signed-off-by: Peter Lieven <pl@kamp.de>
2012-11-30 08:43:34 +01:00
Ronnie Sahlberg
b1da7311c4 change u_int to uint 2012-11-29 19:14:26 -08:00
Ronnie Sahlberg
7704215bcc SCSI: Revert some of the changes to introcuce iovectors and prepare to
obsolete the old api.

After discussions, It is probably not the right thing to do.
Lets leave the old api as is. Most simpler applications will
continue to pass a single linear buffer to the iscsi_<send-data-out-to-device>_task() for convenience  so it would be wrong to force them all to
migrate to amore complex iovector api.

Convert any linear buffers, if provided, to a one element data-out iovector
if a buffer was provided.
2012-11-29 19:08:57 -08:00
Ronnie Sahlberg
9449753a5d Remove iscsi_scsi_free_cbdata from the headers 2012-11-29 18:49:06 -08:00
Ronnie Sahlberg
5ffb58c55f Merge branch 'zero_copy_write-3' into resolve-conflicts
Conflicts:
	lib/iscsi-command.c
	lib/pdu.c
	lib/socket.c
2012-11-29 18:46:51 -08:00
Ronnie Sahlberg
6eb523af64 Merge pull request #45 from plieven/nest-scsi_cbdata
ISCSI_PDU nest iscsi_scsi_cbdata
2012-11-29 06:36:06 -08:00
Ronnie Sahlberg
00d80dda46 Merge pull request #47 from plieven/nop-fix
NOP make the message optional
2012-11-29 06:35:48 -08:00
Peter Lieven
14bee1007f RECONNECT do not increase CmdSN for immediate PDUs
Immediate PDUs such as queued NOP-Outs will cause
a protocol error on reconnect.

Signed-off-by: Peter Lieven <pl@kamp.de>
2012-11-29 15:17:30 +01:00
Peter Lieven
5da6ea7275 NOP make the message optional
Signed-off-by: Peter Lieven <pl@kamp.de>
2012-11-28 18:44:22 +01:00
Ronnie Sahlberg
bd86570b4f minor style changes 2012-11-28 07:40:10 -08:00
Ronnie Sahlberg
4f32723b4c Merge pull request #46 from plieven/fix_outqueue
Fix outqueue deadlock
2012-11-28 06:25:24 -08:00
Peter Lieven
1f4a66abc8 PDU queue out PDUs in order of itt.
This patch fixes a deadlock case where all available
cmdsns have been used for command PDUs which need
additional Data-OUT PDUs to succeed (e.g. a write16
which is larger than first_burst_len).
In this case the target will never increase the maxcmdsn
leading to a deadlock in iscsi_write_to_socket().
If we receive the R2T for such a write request we will
queue the Data-OUT PDUs but at the end of queue. As
a result they will never be sent as the outqueue is already
stuck.

We fix this by sorting the outqueue by ascending itt.

Signed-off-by: Peter Lieven <pl@kamp.de>
2012-11-28 14:04:14 +01:00
Peter Lieven
722eb013c8 TESTS really fix T1040
This finally makes T1040 trigger the cmdsn overflow deadlock.
Its a bad idea to mangle on negotiated parameters as this leads
to protocol errors.
We also need to avoid overlapping writes as this leads also
to protocol errors.
Additionally we test with and with (if available) immediate data.

Signed-off-by: Peter Lieven <pl@kamp.de>
2012-11-28 13:55:55 +01:00
Peter Lieven
c09ee1dab8 Fix test 1040 to really trigger cmdsn deadlock
Signed-off-by: Peter Lieven <pl@kamp.de>
2012-11-28 11:37:23 +01:00
Peter Lieven
562dd46833 PDU avoid incrementing itt to 0xffffffff
This patch avoid incrementing itt to 0xffffffff which is
a reserved value for immediate pdus. Avoid incrementing
it to 0xfffffff to avoid unexpected behaviour.

Signed-off-by: Peter Lieven <pl@kamp.de>
2012-11-28 10:58:33 +01:00
Peter Lieven
cd09c0f17d PDU use serial32 arithmetic for cmdsn, maxcmdsn and expcmdsn.
RFC3720 says that cmdsn comparison must be done using
serial32 arithmetic. This will definetly avoid a deadlock
if cmdsn wraps from 2^32-1 to 0.

Signed-off-by: Peter Lieven <pl@kamp.de>
2012-11-28 10:37:28 +01:00
Ronnie Sahlberg
700d363a88 Create a wrapper function for when we add pdus to the out queue
so that we can add them so that they are send in increasing itt order.
2012-11-27 20:26:13 -08:00
Ronnie Sahlberg
efc556e2e9 TESTS: Create a test that tries to overflow the maxcmdsn counter
so that i/o from the initiator stops flowing and are just queued locally
until teh cmdsn window opens up again.

Send a lot of writes that block until we have processed the R2T
back from the target and verify we can still make process when we
have saturated the cmdsn window and are also blocked waiting for R2Ts.
2012-11-27 19:51:22 -08:00
Ronnie Sahlberg
22a8d221bf Merge pull request #43 from plieven/connection_info
SOCKET add debug info about local ip and port
2012-11-27 19:19:13 -08:00
Ronnie Sahlberg
20416529d6 Merge pull request #42 from plieven/fix-leaked-mem-report
ISCSI fix leaked memory report
2012-11-27 19:17:27 -08:00
Peter Lieven
d9f0464232 ISCSI_PDU nest iscsi_scsi_cbdata
We can simply next the iscsi_scsi_cbdata in the iscsi_pdu struct
since it is only used inside the iscsi_pdu.

This saves one malloc for each pdu.

Signed-off-by: Peter Lieven <pl@kamp.de>
2012-11-27 11:48:53 +01:00
Peter Lieven
00e267620c SOCKET add debug info about local ip and port
Signed-off-by: Peter Lieven <pl@kamp.de>
2012-11-26 10:15:29 +01:00
Ronnie Sahlberg
9f741ad2e3 Remove the iscsi data alloc_size field.
Avoiding to realloc data over and over should rather be handled with something
similar to iovectors instead.
2012-11-25 19:22:37 -08:00
Ronnie Sahlberg
bb755104e5 Remove iscsi_allocate_pdu_with_itt_flags_size()
We dont need this anymore.
2012-11-25 19:11:51 -08:00
Ronnie Sahlberg
7b1c0a19bb Remove iscsi_allocate_pdu_size. This is not use any more. 2012-11-25 19:02:34 -08:00
Ronnie Sahlberg
4237d8c257 Remove 'nidata' from the iscsi pdu structure. We dont use it any more. 2012-11-25 19:01:26 -08:00
Ronnie Sahlberg
cbfb086d40 Update the documentation for read/write iovectors 2012-11-25 18:56:33 -08:00
Ronnie Sahlberg
718c71b7a3 Update iscsiclient example to use the new iovector api 2012-11-25 18:47:12 -08:00
Ronnie Sahlberg
e86703b3aa Convert all scsi task functions to use iovectors. 2012-11-25 18:45:36 -08:00
Ronnie Sahlberg
3ac9fdcbff Change iscsi_scsi_command_async() to use iovectors for writes.
Change iscsi_scsi_command_async() to write data-out using iovectors
attached to the scsi task structure instead of copying the data into
the buffer holding the header.
Still allow passing the data via an argument to the funtcion so that the
ABI does not change but then just conver the data to an iovector.

Update the write_to_socket functions to know about the iovectors and write them
as part of the pdu.

Convert write10_task to use iovectors.

This will allow 'zero-copy' writes through libiscsi.
However, as 'zero-copy writes does mean that we do more send() calls into
the kernel this may degrade performance for very small i/o.

A scsi write will not take at least 2 send() calls.
One send call for the iscsi header structure and a second send call for the
payload data.
This will be more expensive than the old memcpy() of payload data plus one send() call since the send() will be a lot more expensive than memcpy() of a small amount of data.
2012-11-25 18:17:51 -08:00