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>
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>
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.
This has the nice side effect to remove the compiler warning
"dereferencing type-punned pointer will break strict-aliasing rules"
which occur since gcc-4.7.
There are 79 locations where the warning occurs. All of them are in
statements where the htonl/htons/ntohl/ntohs functions are used, e.g.:
in lib/pdu.c itt = ntohl(*(uint32_t *)&in->hdr[16]);
in lib/scsi-lowlevel.c *(uint32_t *)&task->cdb[2] = htonl(lba);
The warning is not related to the htonl/htons/ntohl/ntohs functions but
to the casting/dereferencing operation. If the dereferenced variable is
already a pointer, the warning does not not occur, e.g. this one:
in lib/pdu.c itt = ntohl(*(uint32_t *)&in->data[16]);
The warning is caused by the -fstrict-aliasing option. The
-fstrict-aliasing option is enabled at optimization levels -O2, -O3, -Os.
Signed-off-by: Bernhard Kohl <bernhard.kohl@gmx.net>
As long as we have no struct iscsi_task we cannot track the
free() of data.indata buffer. This leads to a leaked memory
report in iscsi_context_destroy().
We fix this by assuming it has been freed when we pass it
it to scsi_task.
Signed-off-by: Peter Lieven <pl@kamp.de>
This patch defines an scsi_iovec struct which is guaranteed
to be POSIX compatible. It furthermore adds support for
in+out iovectors for bi-directional operations
Signed-off-by: Peter Lieven <pl@kamp.de>
If an application passes buffers to libiscsi for reading they are
currently added to a linked list one by one. This leads to a malloc
for each buffer object plus O(n) walks trough the list to add
the buffer to then end of the list. Additionally the buffer read
routine takes up to O(n) iterations to find the right buffer
for a request.
This patch introduces an scsi_iovector struct to pass buffers to
an scsi task. Adding a new buffer is in O(1) and finding the
right buffer to also. Malloc requirements are in O(log(n)).
Additionally the scsi_iovector struct is itended to be binary
compatible to an QEMUIOVector allowing to pass this structure
directly to the library.
Initial tests have been made booting an Ubuntu LTS 12.04.1
Desktop server up to the login prompt. The following observations
have been made with regards to scsi_malloc calls:
original implementation: ~11.500 mallocs
using iovector instead of list: ~ 7.500 mallocs
passing the iovector directly: 0 mallocs
To enable this feature in qemu for testing the following patch might
be used:
diff --git a/block/iscsi.c b/block/iscsi.c
index a6a819d..2809c15 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -390,11 +390,16 @@ iscsi_aio_readv(BlockDriverState *bs, int64_t sector_num,
return NULL;
}
+#if defined(LIBISCSI_FEATURE_IOVECTOR)
+ assert(sizeof(struct QEMUIOVector) == sizeof(struct scsi_iovector));
+ scsi_iovector_assign(acb->task, (struct scsi_iovector*) acb->qiov);
+#else
for (i = 0; i < acb->qiov->niov; i++) {
scsi_task_add_data_in_buffer(acb->task,
acb->qiov->iov[i].iov_len,
acb->qiov->iov[i].iov_base);
}
+#endif
iscsi_set_events(iscsilun);
---
Signed-off-by: Peter Lieven <pl@kamp.de>
added a few tweaks to further remove the need to memory
allocation resizing by preallocating the right buffer size.
Signed-off-by: Peter Lieven <pl@kamp.de>
If there is an error in iscsi_service or on poll we
exit the event_loop. But in this case scsi_sync_cb is
never reached and the status is 0. This will make
the caller think that the sync task has been completed
successfully.
If there is an error during reconnect we should not loop in event_loop
as this will cause a deadlock in case there is actually an error like
connection drop etc. If this reconnect fails the reconnect routine
will retry itself.
Split the INQUIRY data-in unmarshalling into smaller chunks, fixing some
potential memory leaks along the way.
Signed-off-by: Arne Redlich <arne.redlich@googlemail.com>