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.
In case there is an error condition e.g. out of memory. We are heavily
disconnecting and reconnecting without any limit. This patch
adds a 5 seconds period that has to go by between 2 reconnects.
DPRINTF was blindly sending all debug output to fd 2 (stderr).
The new function iscsi_set_debug_fd() will set the debug fd.
In general debugging is completely disabled by default.
If a process opens more than once connection the interfaces are assigned
round-robin from the available ones. However, different processes will
uses a random interface of as starting point. This patch will also
make the redirect case handled correctly.
This patch adds a wrapper around all memory allocations and frees.
The idea is to get warned immediately if the application leaks memory.
Additionally the wrapper functions make it easy to add different
memory allocators or memory pools in the future.
This patch adds support for setting TCP_SYNCNT to overwrite
the system default values. This allows indirect support
for a configurable connect timeout.
Linux uses a exponential backoff for SYN retries starting
with 1 second.
This means for a value n for TCP_SYNCNT, the connect will
effectively timeout after 2^(n+1)-1 seconds.
This patch adds 3 functions to set the 3 keepalive values TCP_KEEPIDLE, TCP_KEEPCNT
and TCP_KEEPINTVL. The values have to be set after iscsi context creation and are
then configured on the socket on each new connection.
This patch adds a user configurable option to set the TCP_USER_TIMEOUT
socket option. With this timeout set a broken TCP session is shutdown
after a given timeout even there are unacked packets. SO_KEEPALIVE
seems not to work in this case.
Some tests may cause a target to drop the session.
For these tests we DO want the test tool to detect that the command
failed and later reconnect the session again when we proceed to the next subtest
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
For writes that span across multiple DATA-OUT segments we have to
increment the DATASN field for each segment.
We didnt use to, and most targets were perfectly happy, ignoring that the DATASN was constant 0 for every DATAOUT we sent.
LIO however does check this and did cause it to reject the libiscsi test tool.
(This is something we should write a iscsi test for so we can flag all non-LIO targets as broken and needing to be fixed)
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
It is not real zero-copy since the data is still copied in the kernel,
but it avoids copying the data inside libiscsi as well as in the callback.
For SCSI tasks that will return data from the target, the application can now
specify application buffers for libiscsi to read the data directly into.
This is done by calling scsi_task_add_data_in_buffer(task, ...
These buffers need not be linear, you can specify different areas to read into
by calling this function several times.
See examples/iscsiclient.c for an example.
Update the "send scsi command" fucntion to honour
"FirstBurstLength" so that we only send this many bytes as unsolicited data.
The wait for a train of R2T from the target to clock out additional
busrts of data until the full task data has been sent to the Target.
We should now honour, and handle the case of
ImmediateData=No
InitialR2T=No
correctly for targets that are limited on receiveing data too fast.
Update the send pdu command to trap when we need to send data to the target
but we are not allowed to send using immediate data.
For this case, send the data as a separate DATAOUT pdu instead.
Twiddle the flags and other fields to now manage that we send the data
as two separate PDUs.
This function can allocate a new pdu using a specific itt value
and specific flags instead of using the defaults of, next iff, no flags set.
This can be used when we need to allocate additional PDUs in a chain,
for commands that span across multiple PDUs and where all need to keep
the same itt value.
For example
->WRITE10 cdb
->DATAOUT
-<RESPONSE
Here the DATAOUT PDU belongs to the same task that was started by write10
so it need to use the same itt value.