Commit Graph

83 Commits

Author SHA1 Message Date
Ronnie Sahlberg
b555bbebdd Add a cast to ssize_t 2013-06-29 11:12:41 -07:00
Ronnie Sahlberg
4a8d967541 Add support for synchronous command timeout.
Default to 0 meaning no timeout.

Implement a test for iSCS to test what happens if we send a command
with CMDSN being higher than the target allows.
In this case we dont strictly know what will happen, just that what should
NOT happen is the target responding with success.
But we have to be prepared for any kind of failure, including a timeout,
scsi sense, or even iscsi reject or session failure.
2013-04-29 20:42:33 -07:00
Ronnie Sahlberg
402653b9f3 portability updates
add check if ipv6/sockaddr_in6 is availavble or not
add check for poll.h and only include when available
add includes for AROS
2013-04-18 19:43:36 -07:00
Peter Lieven
8bc0046f51 changed iscsi_data.size from int to size_t
iscsi_data.size is used as parameter to memory
operation functions (such as malloc) which except
size_t rather than int.

Signed-off-by: Peter Lieven <pl@kamp.de>
2013-01-28 09:36:00 +01:00
Peter Lieven
4cbbc0e1e9 SOCKET order packets in outqueue by CmdSN
Ordering by itt adds the special case of handling
itt == 0xffffffff. Order by CmdSN instead as described
by RFC3720.

Signed-off-by: Peter Lieven <pl@kamp.de>
2012-12-16 12:36:34 +01:00
Peter Lieven
2f9fda19d2 SOCKET do not queue PDUs with itt==0xffffffff head of queue
Queing packets with itt = 0xffffffff (e.g. NOP-Out replies) ahead
of queue because they might have a higher CmdSN than following
packets. This again could lead to a deadlock AND its a protocol
violotion:

RFC3720 Section 3.2.2.1 second last paragraph on Page 21:
"On any connection, the iSCSI initiator MUST send the commands in
increasing order of CmdSN, except for commands that are retransmitted
due to digest error recovery and connection recovery."

Signed-off-by: Peter Lieven <pl@kamp.de>
2012-12-15 13:27:52 +01:00
Peter Lieven
446b1829c8 SOCKET use readv/writev to write directly into iovectors
This patch adds support for read/writev to directly read and write
from/to iovectors. Before this patch on read and write from/to socket
the operation was limited by the iovec boundaries. If there is enough
data in the buffer or enough buffer space available its now possible
to transfer the whole data in one atomic operaion.

Signed-off-by: Peter Lieven <pl@kamp.de>
2012-12-10 19:24:28 +01:00
Peter Lieven
752c0ad396 SOCKET set TCP_NODELAY on iscsi->fd
This will set TCP_NODELAY on the socket connection
to the target. This is the first step to improve latency.
For systems supporting TCP_CORK we plan to add a cork
around certain PDUs e.g. DATA-Out, but this needs further
testing.

Signed-off-by: Peter Lieven <pl@kamp.de>
2012-12-07 15:01:19 +01:00
Peter Lieven
36be387547 SOCKET remove useless code
At this point in iscsi_write_to_socket() pdu->written can only be
equal to total.

Signed-off-by: Peter Lieven <pl@kamp.de>
2012-12-06 10:42:30 +01:00
Peter Lieven
5f18c72706 RECONNCT fix broken reconnect for iov out vectors
We where modifying out_offset and out_len in iscsi_write_to_socket().
If the packet that was being sent before reconnect was a write command
the was a significant change that out_offset and out_len where already
touched. When requeing the packet after reconnect we where
sending garbage!

Signed-off-by: Peter Lieven <pl@kamp.de>
2012-12-06 10:42:16 +01: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
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
bd86570b4f minor style changes 2012-11-28 07:40:10 -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
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
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
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
Peter Lieven
f9dc2da672 Revert "CONNECT only read/write from sockets when connection is established"
Fixed the login process in qemu-kvm. This makes this fix obsolete.

This reverts commit a9257d52a7.
2012-11-18 13:57:57 -08:00
Peter Lieven
8cb369b87f Merge remote-tracking branch 'upstream-git/master'
Conflicts:
	include/iscsi-private.h
	include/iscsi.h
	lib/connect.c
	lib/init.c
	lib/scsi-lowlevel.c
2012-11-12 16:02:57 +01:00
Ronnie Sahlberg
50e7c682bb Add a logging subsystem and change all DPRINTF to ISCSI_LOG
Add a mechanism where we can set a logging subsystem that libiscsi can use.
Create an example 'log to stderr' that utilities can use for convenience.
2012-11-07 06:34:38 -08:00
Peter Lieven
3e57a612db SOCKET add more skill to interface binding
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.
2012-11-06 15:47:30 +01:00
Peter Lieven
f00cd04810 INIT call srand() once at iscsi_create_context()
currently the rng is not seeded at all which makes the isid not really random
at all.
2012-11-06 15:01:34 +01:00
Peter Lieven
6cad82532a SOCKET add option to bind to connection to interface(s) 2012-11-06 14:53:55 +01:00
Peter Lieven
36527c5122 Merge remote-tracking branch 'aredlich/master'
Conflicts:
	lib/init.c
	lib/socket.c
2012-11-03 10:39:23 +01:00
Peter Lieven
871c56ce7a MEMORY add compatibility for qemu-kvm
qemu-kvm iscsi block driver calls iscsi_parse_full_url without
a valid iscsi_context. The driver also creates its own scsi_task
objects.
2012-11-03 02:05:16 +01:00
Peter Lieven
7f98233169 Merge remote-tracking branch 'upstream/master' 2012-11-03 01:07:40 +01:00
Peter Lieven
d327ab09c6 MEMORY add wrappers around all mallocs and frees and trace them
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.
2012-11-03 01:05:57 +01:00
Arne Redlich
558ad00038 iscsi_service_reconnect_if_loggedin: fix compiler warning and make it static
Quoth gcc-4.6.3:
  libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I. -I./include "-D_U_=__attribute__((unused))" -Wall -W -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-align -Wwrite-strings -g -O2 -MT lib/socket.lo -MD -MP -MF lib/.deps/socket.Tpo -c lib/socket.c  -fPIC -DPIC -o lib/.libs/socket.o
  lib/socket.c:445:1: warning: 'inline' is not at beginning of declaration [-Wold-style-declaration]

Fix this and make it a static function.
Also remove trailing whitespace from this file while at it.

Signed-off-by: Arne Redlich <arne.redlich@googlemail.com>
2012-10-31 14:39:51 +01:00
Ronnie Sahlberg
6507f4050f Merge pull request #31 from plieven/master
memory leak fixes + suggestion for iscsi context + qemu-kvm bug
2012-10-30 18:54:38 -07:00
Ronnie Sahlberg
9e9c6946c0 TESTS: Add a test that a target handles an unsolicited DATA-OUT correctly.
Send a large number of DATA-OUT PDUs that do not have a matching SCSI-COMMAND
PDU and verify that the target responds correctly. Either by terminating the
session or by just ignoring the data.

Verify also that the target is not "surprised" and crashes.

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
2012-10-30 18:44:35 -07:00
Peter Lieven
a9257d52a7 CONNECT only read/write from sockets when connection is established
qemu-kvm/qemu-img starts in+out polls from the socket before the connection is
established. This leads to a hang if the connection cant be established
(i.e. the target is down when qemu-kvm is started).

before:
LIBISCSI_DEBUG=2 qemu-img convert -f iscsi -O raw iscsi://127.0.0.1/iqn.2004-04.com.qnap:ts-809u:iscsi.lieven20.c53dac/0 /dev/null
libiscsi: connecting to portal 127.0.0.1 [iqn.2004-04.com.qnap:ts-809u:iscsi.lieven20.c53dac]
libiscsi: read from socket failed, errno:111 [iqn.2004-04.com.qnap:ts-809u:iscsi.lieven20.c53dac]
libiscsi: connection to 127.0.0.1 established [iqn.2004-04.com.qnap:ts-809u:iscsi.lieven20.c53dac]
->success!!

after:
LIBISCSI_DEBUG=1 qemu-img convert -f iscsi -O raw iscsi://127.0.0.1/iqn.2004-04.com.qnap:ts-809u:iscsi.lieven20.c53dac/0 /dev/null
libiscsi: iscsi_service: socket error Connection refused(111) while connecting. [iqn.2004-04.com.qnap:ts-809u:iscsi.lieven20.c53dac]
libiscsi: Failed to connect to iSCSI socket. iscsi_service: socket error Connection refused(111) while connecting. [iqn.2004-04.com.qnap:ts-809u:iscsi.lieven20.c53dac]
qemu-img: iSCSI: Failed to connect to LUN : Failed to connect to iSCSI socket. iscsi_service: socket error Connection refused(111) while connecting.
qemu-img: Could not open 'iscsi://127.0.0.1/iqn.2004-04.com.qnap:ts-809u:iscsi.lieven20.c53dac/0': Invalid argument
qemu-img: Could not open 'iscsi://127.0.0.1/iqn.2004-04.com.qnap:ts-809u:iscsi.lieven20.c53dac/0'
2012-10-30 17:22:39 +01:00
Peter Lieven
923b9a4fb2 ISCSI-CONTEXT change dynamic string allocations to statics 2012-10-27 17:23:40 +02:00
Peter Lieven
89e918e9d7 SOCKET validate data_size in in_pdu header 2012-10-26 17:12:07 +02:00
Peter Lieven
a26a6e12d5 Fix paramter to DPRINTF in tcp_set_user_timeout() 2012-10-20 19:13:53 +02:00
Peter Lieven
d30b279474 Unify paramters in tcp_set_user_timeout()
Use the same function definition as in the other tcp setters.
2012-10-20 19:12:13 +02:00
Peter Lieven
20cf2b279e Fix incorrect whitespaces
At a few places there where spaces where tabulators where appropriate
2012-10-20 19:08:57 +02:00
Peter Lieven
3f5a75ce5e Remove redundant code in iscsi_service() 2012-10-20 19:00:32 +02:00
Peter Lieven
881fc9743a Use generic tcp_set_sockopt function for tcp setsockopt operations 2012-10-20 18:54:46 +02:00
Peter Lieven
cbae6ae058 Remove accidently left debug message in iscsi_service 2012-10-20 18:44:43 +02:00
Peter Lieven
78a31ad4a1 Add iscsi_set_tcp_syncnt function
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.
2012-10-20 18:43:48 +02:00
Peter Lieven
236aaa011f Fix compiler warnings
These patch fixes 3 compiler warnings introduce by my recent patches.
2012-10-19 23:48:04 +02:00
Peter Lieven
ad9cd56b2d Add setters for TCP keepalive values
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.
2012-10-19 23:40:12 +02:00
Peter Lieven
cc2b0c9b1d Set SO_KEEPALIVE before TCP_USER_TIMEOUT
For TCP_USER_TIMEOUT to work it seems to be necessary that SO_KEEPALIVE is
enabled. RFC5482 section 4.2 also says that the TCP_USER_TIMEOUT has to be
less than the keepalive timeout. This means less than 30000 ms in the
current libiscsi default settings for TCP keepalives.
2012-10-18 14:31:09 +02:00
Peter Lieven
f973608578 Add iscsi_tcp_set_user_timeout function
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.
2012-10-18 11:55:15 +02:00
Peter Lieven
4cb845477d Add debugging framework
This patch adds a user configurable debug level. For testing
it includes connection info and reporting errors.
2012-10-18 10:36:26 +02:00
Peter Lieven
c4592550d6 Move iscsi_set_tcp_keepalive after socket creation
Socket options should be set directly after socket creation.
2012-10-18 09:40:05 +02:00
Ronnie Sahlberg
06cc2d2ece CONNECT: connect data is not always malloc()ed so we can demand it is free()able
After a sync connection, make sure to clear connect_data since it will otherwise
point to a structure on the stack.
2012-08-09 08:27:48 +10:00
Ronnie Sahlberg
a98b6e63f0 MAXCMDSN: Stop sending new PDUs to the target when maxcmdsn is reached
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
2012-08-02 09:46:42 +10:00