55f76cfb0cdba9a52357117495ecccba6c8cffcc
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>
Libiscsi is a clientside library to implement the iSCSI protocol
that can be used to access resource of an iSCSI Target.
The library is fully async with regards to iscsi commands and scsi
tasks, but a sync layer is also provided for ease of use for simpler
applications.
The src directory contain a handful of useful iscsi utilities
such as logging in to and enumerating all targets on a portal
and all devices of a target.
The examples directory contain example implementation of how to
access both the sync and acync api of libiscsi.
Libiscsi is a work in progress.
It aims to become a full async library for iscsi functionality,
including all features required to establish and maintain a iscsi
session, as well as a low level scsi library to create scsi cdb's
and parse/unmarshall data-in structures.
Installation
============
./autogen.sh
./configure
make
sudo make install
Build RPM
=========
To build RPMs run the following script from the libiscsi root directory
./packaging/RPM/makerpms.sh
iSCSI URL Format
================
iSCSI devices are specified by a URL format on the following form :
iscsi://[<username>[%<password>]@]<host>[:<port>]/<target-iqn>/<lun>
Example:
iscsi://server/iqn.ronnie.test/1
When using CHAP authentication, username and password can be specified as part of the URL
iscsi://ronnie%password@server/iqn.ronnie.test/1
but this may make the user and password visible in log files as well as in ps aux output.
So it is also possible to provide either just the password or both the password and username
via environment variables.
The username and/or password can be set via
LIBISCSI_CHAP_USERNAME=ronnie
LIBISCSI_CHAP_PASSWORD=password
Example:
LIBISCSI_CHAP_PASSWORD=password iscsi-inq iscsi://ronnie@10.1.1.27/iqn.ronnie.test/1
IPv6 support
============
Libiscsi supports IPv6, either as names resolving into IPv6 addresses or when
IPv6 addresses are explicitely set in the URL.
When specifying IPv6 addresses in the URL, they have to be specified in
[...] bracket form.
Example:
iscsi://[fec0:2727::3]:3260/iqn.ronnie.test/1
Header Digest
=============
Libiscsi supports HeaderDigest.
By default, libiscsi will offer None,CRC32C and let the target pick whether
Header digest is to be used or not.
This can be overridden by an application by calling iscsi_set_header_digest()
if the application wants to force a specific setting.
Patches
=======
The patches subdirectory contains patches to make some external packages iscsi
aware and make them use libiscsi.
Currently we have SG3-UTILS and MTX.
Patches for other packages would be welcome.
ISCSI-TEST
==========
The test-tool subdirectory contains a iscsi/scsi test tool.
This is a tool that is aimed at providing a comprehensive iscsi and scsi
emulation test suite.
Run 'make iscsi-test' to compile it.
Run ./test-tool/iscsi-test --help and
Run ./test-tool/iscsi-test --list
for instructions
Example:
$ ./test-tool/iscsi-test --initiator-name=iqn.ronnie.test --test=T0105_read10_invalid iscsi://127.0.0.1/iqn.ronnie.test/1
=========
Running test T0105_read10_invalid
Read10 1 block but with iscsi ExpectedDataTransferLength==0 ... [FAILED]
Read10 of 1 block with iscsi ExpectedDataTransferLength==0 should fail.
TEST T0105_read10_invalid [FAILED]
LD_PRELOAD FUN
==============
There is a small LD_PRELOAD hack in the src directory that intercepts a handful
of system calls and converts ISCSI URLs to look and behave as if they are
normal read-only files.
This allows using standard unix tools to become iscsi aware with no modifications.
For example:
The stat command: this shows the size of the iSCSI LUN as if it was a normal file:
$ LD_PRELOAD=./bin/ld_iscsi.so stat iscsi://127.0.0.1:3262/iqn.ronnie.test/2
File: `iscsi://127.0.0.1:3262/iqn.ronnie.test/2'
Size: 3431540736 Blocks: 0 IO Block: 0 regular file
Device: 0h/0d Inode: 0 Links: 0
Access: (0444/-r--r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 1970-01-01 10:00:00.000000000 +1000
Modify: 1970-01-01 10:00:00.000000000 +1000
Change: 1970-01-01 10:00:00.000000000 +1000
The cat command, which allows you to read/dump a iSCSI LUN to a file :
$ LD_PRELOAD=./bin/ld_iscsi.so cat iscsi://127.0.0.1:3262/iqn.ronnie.test/2 >copy_of_iscsi_lun
Or using dd even :
LD_PRELOAD=./bin/ld_iscsi.so dd if=iscsi://127.0.0.1:3262/iqn.ronnie.test/2 of=copy_of_LUN bs=10M count=1
The LD_PRELOAD hack is incomplete and needs more functions to be intercepted before becomming fully functional. Patches welcome!
For now, it is sufficiently complete for trivial commands like stat and cat.
You probably need to implement at least lseek, pread, pwrite before it becomes really useful.
SUPPORTED PLATFORMS
===================
libiscsi is pure posix and should with some tweaks run on any host that
provides a posix-like environment.
Libiscsi has been tested on:
* Linux (32 and 64 bit)
* Cygwin
* FreeBSD
* Windows (Win7-VisualStudio10)
* OpenSolaris
RELEASE TARBALLS
================
Release tarballs are available at https://github.com/sahlberg/libiscsi/downloads
MAILINGLIST
===========
A libiscsi mailinglist is available at http://groups.google.com/group/libiscsi
Announcements of new versions of libiscsi will be posted to this list.
Description
Languages
C
97.7%
Shell
1.2%
Makefile
0.6%
M4
0.5%