Commit Graph

118 Commits

Author SHA1 Message Date
Brian Meagher
882bcad53a Add support for Data Digest 2024-05-04 19:34:06 -07:00
zhenwei pi
7bf8091013 Add iscsi_set_fd_dup_cb
libiscsi is widely used by poll driven, include libiscsi itself,
QEMU. Using poll works fine after iscsi reconnect, but it does not work
in epoll, because the epoll event has been removed during duplicating
file descriptor in kernel.

Add a new function iscsi_set_fd_dup_cb to set callback, then uplayer
gets notified after duplicating. The following codes reproduce this
issue, and test this patch by compiling flags -DISCSI_FD_DUP_CB.

static void iscsi_epoll_event(struct iscsi_context *iscsi, int epollfd, bool new)
{
	static int epoll_event;
	struct epoll_event ev = { 0 };
	int pevent = iscsi_which_events(iscsi);
	int event = 0;

	if (pevent & POLLIN)
		event |= EPOLLIN;

	if (pevent & POLLOUT)
		event |= EPOLLOUT;

	ev.events = event;
	ev.data.fd = iscsi_get_fd(iscsi);
	if (new)
		epoll_ctl(epollfd, EPOLL_CTL_ADD, ev.data.fd, &ev);
	else if (epoll_event != event) {
		epoll_ctl(epollfd, EPOLL_CTL_MOD, ev.data.fd, &ev);
	}
	epoll_event = event;
}

static void iscsi_tsk_cb(struct iscsi_context *iscsi, int status, void *command_data, void *private_data)
{
	printf("iscsi_tsk_cb status %d\n", status);
	exit(0);
}

static void iscsi_fd_dup_cb(struct iscsi_context *iscsi, void *opaque)
{
	int epollfd = *(int *)opaque;

	iscsi_epoll_event(iscsi, epollfd, true);
}

static void iscsi_on_pollout(struct iscsi_context *iscsi, struct iscsi_url *iscsi_url, int epollfd)
{
	static struct scsi_task *tsk = NULL;

	iscsi_service(iscsi, POLLOUT);
	if (!tsk) {
		tsk = iscsi_readcapacity16_task(iscsi, iscsi_url->lun, iscsi_tsk_cb, NULL);
		assert(tsk);
	}
}

int main(int argc, char *argv[])
{
	struct iscsi_context *iscsi;
	struct iscsi_url *iscsi_url;
	struct epoll_event ev, revent;
	int epollfd;

	iscsi = iscsi_create_context("dummy");
	assert(iscsi);

	iscsi_url = iscsi_parse_full_url(iscsi, argv[1]);
	assert(iscsi_url);

	iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL);
	iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);
	assert(!iscsi_full_connect_sync(iscsi, iscsi_url->portal, iscsi_url->lun));

	epollfd = epoll_create1(0);
	iscsi_epoll_event(iscsi, epollfd, true);

	iscsi_set_fd_dup_cb(iscsi, iscsi_fd_dup_cb, &epollfd);
	iscsi_reconnect(iscsi);

	while (epoll_wait(epollfd, &revent, 1, 100) >= 0) {
		if (revent.events & EPOLLIN)
			iscsi_service(iscsi, POLLIN);

		if (revent.events & EPOLLOUT)
			iscsi_on_pollout(iscsi, iscsi_url, epollfd);

		iscsi_epoll_event(iscsi, epollfd, false);
	}

	return 0;
}

Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
2023-06-06 13:29:52 +08:00
Bart Van Assche
70759869ff Port to MinGW
Compile-tested only.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
2021-05-23 13:23:52 -07:00
Vladimír Čunát
7f97ac0e4c init: fix Wformat on 32-bit platforms 2021-01-21 10:29:57 +01:00
wanghonghao
a03744c80a init: free iscsi->opaque before check mallocs/frees counter
Signed-off-by: wanghonghao <wanghonghao@bytedance.com>
2020-04-11 12:46:44 +08:00
Bart Van Assche
bac94c18b8 libiscsi: Reduce the size of struct iscsi_context
Reduce the size of struct iscsi_context by reordering the members of this
data structure. Additionally, change the rdma_ack_timeout value from
'unsigned char' into 'uint8_t' to make it clear that this variable
represents an integer.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
2020-03-07 12:37:51 -08:00
zhenwei pi
6ed1ffb7b2 iser: support rdma ack timeout optimization
Since 2c1619edef61a03cb516efaa81750784c3071d10 for linux kernel and
55843c4ab8f559679d28c559cc4d681836be769b for rdma-core, rdma cma
supports RDMA_OPTION_ID_ACK_TIMEOUT. It's useful for RDMA out of
sequence case. Because this feature is added recently, we have to
check this in autogen.sh before building source code.

Depend on production enviroument, tunning rdma ack timeout could get
the best performance. Suggested by Bart and Ronnie, instead of using
a fixed timeout value, add two methods to set rdma ack timeout value.
1, add URL variable 'LIBISCSI_RDMA_ACK_TIMEOUT'. This could works
for a specified connection.
2, add env argument 'LIBISCSI_RDMA_ACK_TIMEOUT'. This works as a
common setting for all the connection of a process.

Test under different packet loss rate and different ack timeout, run
fio (iodepth=1) in a guest os, I got this result:
latency under packet loss rate 0.00001:
	timeout 19: avg 170.22, pct99.9 215
	timeout 10: avg 160.08, pct99.9 215
	timeout 8 : avg 146.39, pct99.9 177
	timeout 7 : avg 148.37, pct99.9 211

latency under packet loss rate 0.0001:
	timeout 19: avg 949.23, pct99.9 306
	timeout 10: avg 818.53, pct99.9 378
	timeout 8 : avg 615.84, pct99.9 189
	timeout 7 : avg 618.89, pct99.9 310

Base on this test report, setting ack timeout to 8(1048.576 usec) is
a good choice in my test enviroument.

Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
2020-03-07 12:37:46 -08:00
zhenwei pi
e2a7fdfb36 socket: fix disconnect corner case for iser
iscsi->fd is never initialized in iser driver, so iscsi_disconnect
always does not work for iser context.

iscsi->fd is used as a member variable of TCP context, so let iscsi
TCP driver handle iscsi->fd, we just call iscsi_disconnect in
iscsi_destroy_context. Luckly, TCP driver has already handle invalid
iscsi->fd case in iscsi_tcp_disconnect.

And fix NULL pointer case for iscsi_disconnect.

Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
2020-02-27 10:02:02 +08:00
zhenwei pi
a391176a6d init: fix memory leak in iscsi_create_context
iscsi instance is allocated in iscsi_create_context, after we return
NULL, nobody could handle it anymore.

Currently we can't hit this logic, anyway we still fix this.

Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
2020-02-25 22:35:54 +08:00
Bart Van Assche
0ad5c2c648 libiscsi: Fix a format specifier
Use %lu to format unsigned long instead of %d.

This was detected by Coverity.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
2020-02-23 20:11:14 -08:00
Tim Crawford
9347cfebf2 Replace file variables with .dir-locals.el
Signed-off-by: Tim Crawford <tcrawford@datto.com>
2019-02-21 11:54:02 -05:00
Ronnie Sahlberg
04d6c326b8 Add some missing includes
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
2018-10-17 05:43:10 +10:00
Felipe Franciosi
41af44eba1 iscsi_create_context: call srand() only once
iscsi_create_context() calls srand() every time a new context is
generated. That practice is questionable, as the seed does not need to
change before each call to rand(). As a matter of fact, doing so defeats
the purpose of using rand() altogether. Furthermore, the current
implementation is not thread safe.

This improves ISID generation by using /dev/urandom (when available) as
a seed, and calling srand() only once. In case of errors, fallback to
using something similar to the previous implementation (albeit
thread-safe).

Signed-off-by: Felipe Franciosi <felipe@nutanix.com>
2018-10-05 18:10:07 +01:00
Felipe Franciosi
50fb64df91 iscsi_create_context: improve ISID randomness
The current random seed for determining a new context's ISID is
calculated by XOR'ing time(), getpid() and "iscsi". When invoked from
iscsi_reconnect(), all three inputs are likely to be identical,
resulting on identical ISIDs.

That happens because iscsi_reconnect() malloc()s a temporary "iscsi"
which is then free()d at the end of the call. Successive calls to
malloc() (from that function) are therefore likely to reuse the same
address for the context.

When multiple sessions are used for different LUNs of the same target,
and reconnects happen within the same second (the precision given by
time()), then multiple login attempts will happen with identical values,
violating the ISID RULE as described in Section 3.4.3 of RFC3270.

This fixes the issue by introducing a sequence number to the ISID seed
generation.

Signed-off-by: Felipe Franciosi <felipe@nutanix.com>
2018-09-30 19:32:06 +01:00
Felipe Franciosi
3c4925e8da pdu: Introduce iscsi_cancel_pdus()
Introduce a helper exported from lib/pdu.c which cancels all pdus for a
given context. This patch eliminates repeated code from various other
files which have the same purpose. The only functional difference is
that the cancellation done from iscsi-command.c was (incorrectly) not
checking for iscsi->is_loggedin before issuing callbacks.

Signed-off-by: Felipe Franciosi <felipe@nutanix.com>
2017-11-25 17:03:01 +00:00
Tim Crawford
aba0f7da1a Replace WIN32 with _WIN32
Using WIN32 depends on the build environment defining the variable.
_WIN32 is a predefined MSVC macro and is always available.

Signed-off-by: Tim Crawford <crawfxrd@gmail.com>
2017-11-29 10:07:44 -05:00
Tim Crawford
cdb437c545 Fix compilation with VS2017
The primary issue is that in MSVC 14.00 (VS2015) Microsoft added
snprintf as a function to the standard library and prevents users from
defining it to something else (typically, this was _snprintf). So, only
define it when using _MSC_VER < 1900.

Other changes are:
- Fix macro definition of dup2
- Add macro for getpid
- Add function definition for win32_dup
- Add missing EXTERNs

Signed-off-by: Tim Crawford <crawfxrd@gmail.com>
2017-11-29 10:07:44 -05:00
Ronnie Sahlberg
b1003dc75a Add URL arguments to enable/disable header digest
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
2017-02-17 17:58:19 -08:00
Ronnie Sahlberg
33d0b63717 Merge branch 'master' into read_batch_pdu2 2017-01-07 08:42:12 -08:00
Peter Lieven
eb7c1d9b0c socket: process PDUs directly after receiving them
this eliminated the need for an inqueue

Signed-off-by: Peter Lieven <pl@kamp.de>
2017-01-06 11:48:17 +01:00
Peter Lieven
c68d2c0ddb init: introduce iscsi_smalloc
Signed-off-by: Peter Lieven <pl@kamp.de>
2017-01-05 12:18:03 +01:00
Ronnie Sahlberg
e0fd6dc051 Allow iser:// style URLs
Let user specify iSER support by the protocol part of the URL.

I.e. support both
iser://127.0.0.1/iqn.ronnie.test/1

iscsi://127.0.0.1/iqn.ronnie.test/1?iser

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
2016-09-02 16:40:24 -07:00
Peter Lieven
fa123fc397 abstract transport to static driver functions and opaque driver specific information.
This splits a transport into static driver specific functions for the common
iscsi commands. Optionally, a driver specific opaque memory is introduced
which is currently only used by iSER transport.
Last a lot of functions changed to static.

Signed-off-by: Peter Lieven <pl@kamp.de>
2016-08-05 11:28:43 +02:00
Peter Lieven
1b3d3038bf init: do not leak transport struct on iscsi_destroy_context
Signed-off-by: Peter Lieven <pl@kamp.de>
2016-07-07 11:44:56 +02:00
Roy Shterman
a628264ef0 Libiscsi: iSER implementation
This commit includes all iSER implementation in libscsi
library and utilities.

Also, adding iser option in url.

Change-Id: I55ca8a9d4db802e72eb991061260dbb0bd0ef9ba
Signed-off-by: Roy Shterman <roysh@mellanox.com>
2016-06-03 18:59:01 -07:00
Roy Shterman
6c1bdb4808 Libiscsi: Adding free_pdu function to transport abstraction
Signed-off-by: Roy Shterman <roysh@mellanox.com>
2016-06-03 18:47:23 -07:00
Roy Shterman
9378a39ddc Libiscsi: Adding transport layer into all library utilities
lib/init: initializing connection transport

lib/socket: Adding function to initialize tcp transport.
            future commits will include adding iSER transport layer,
            so each transport option will has it's own template of functions.

all_utils: All utils stay the same, in future iSER commits in case of
	   iSER transport we will override tcp_transport in
	   iscsi_context.

connect: adding transport initialization when creating context

include/iscsi-private: Adding iscsi_transport attribute in iscsi_context

Signed-off-by: Roy Shterman <roysh@mellanox.com>

Make iscsi_init_tcp_transport private

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
2016-06-03 18:43:03 -07:00
Peter Lieven
cde2043891 pdu: drop ISCSI_PDU_NO_CALLBACK
we use the flag ISCSI_PDU_NO_CALLBACK and pdu->callback simultaneously, but
check only for one of them in various places. So drop ISCSI_PDU_NO_CALLBACK
and check for pdu->callback != NULL instead.

All PDUs that carried this flag have pdu->callback set to NULL.

Signed-off-by: Peter Lieven <pl@kamp.de>
2016-05-02 10:40:15 +02:00
Ronnie Sahlberg
99a5f99527 Add some emacs defaults. Tabs are 8 spaces.
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
2016-02-18 21:34:43 -08:00
Peter Lieven
a027931a2c init: simplify the case that the freelist is full in iscsi_sfree
if the freelist gets full we are likely in a low load situation so
we do not need to make all the work copying the pointers.

Signed-off-by: Peter Lieven <pl@kamp.de>
2015-05-05 14:14:26 +02:00
Peter Lieven
b4098c535e init: make LIBISCSI_CACHE_ALLOCATIONS a public environment variable
this variable was introduced for iscsi-test-cu only. This patch
makes it a generic environment variable that can be set per context.

Signed-off-by: Peter Lieven <pl@kamp.de>
2015-05-05 14:10:44 +02:00
Peter Lieven
52a6bdb774 Revert "lib: Make iscsi_realloc() update the freed pointer list"
iscsi_realloc MUST NOT be called with a pointer that is in the freelist
of small allocations. First they are free and secondly a realloc
will change the size of the small allocation to an unknown size.

This reverts commit d8de6531f8.
2015-04-23 14:12:57 +02:00
Bart Van Assche
cf4076dba9 test-tool: Make it possible to disable memory caching
Disable memory caching in libiscsi if the environment variable
LIBISCSI_CACHE_ALLOCATIONS has been set to zero. This makes
Valgrind reports more meaningful.

Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
2015-04-20 07:01:17 -07:00
Bart Van Assche
d8de6531f8 lib: Make iscsi_realloc() update the freed pointer list
This patch improves the stability of libiscsi by avoiding that
stale pointers are passed to free().

Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
2015-04-20 06:57:31 -07:00
Peter Lieven
e4a448b115 init: don't close fd of iscsi->old_iscsi
its already closed at this point

Signed-off-by: Peter Lieven <pl@kamp.de>
2015-04-16 11:58:39 +02:00
Peter Lieven
b152d26eb9 connect: make the reconnect async
Signed-off-by: Peter Lieven <pl@kamp.de>
2015-03-31 16:21:00 +02:00
Peter Lieven
2955b2c616 init: apply settings to context in iscsi_parse_url
if iscsi_context is not NULL we apply the parsed settings
to the context.

Signed-off-by: Peter Lieven <pl@kamp.de>
2015-03-26 10:37:39 +01:00
Peter Lieven
a45094b7a7 init: fix segfaul in iscsi_parse_url
We allowed iscsi to be NULL in iscsi_parse_url. Especially
qemu does this and currently segfaults at start. Change the
usage guidelines for target username/password to be the same
as for chap username/password.

Signed-off-by: Peter Lieven <pl@kamp.de>
2015-03-26 10:07:52 +01:00
Peter Lieven
ea2bcfd308 init: fix segfault in iscsi_destroy_context
observed when iscsi_destroy_context is called while a iscsi NOP out is in flight.

Signed-off-by: Peter Lieven <pl@kamp.de>
2015-03-19 12:40:37 +01:00
Ronnie Sahlberg
b1d0ac45f1 Add support for bidirectional CHAP
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
2015-03-14 10:43:03 -07:00
Peter Lieven
de7b38d9a0 use MIN and MAX macros at some places
Signed-off-by: Peter Lieven <pl@kamp.de>
2015-02-23 08:03:27 +01:00
Ronnie Sahlberg
717b95cb8a slist.h: rename SLIST_ to ISCSI_LIST_ to avoid clash on *BSD
Rename the macros for managing the linked lists from SLIST_* to ISCSI_LIST_*
to avoid a clash on *BSD which already have other macros SLIST_*

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
2014-05-07 06:44:19 -07:00
Michael Tokarev
120b308741 Spelling fixes: Dont => Don't
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2013-12-16 18:19:24 -08:00
Ronnie Sahlberg
1828481ba2 Portability fixes. Declare variables at the start of a scope only. 2013-10-05 13:48:00 -07:00
Sitsofe Wheeler
7692027d6c Fix compilation issues under clang
clang defaults to c99 so remove inline statements
(http://clang.llvm.org/compatibility.html#inline ) on functions shared
across different translation units.
clang's linker doesn't like major numbers over 255 so change how SOREL
is generated in Makefile.am.
2013-09-09 18:04:06 +01:00
Peter Lieven
d429276907 MEMORY introduce a small allocation pool
This patch finally introduces a small allocation pool
which recycles all the small portions of memory that
are used for headers and pdu structures. This was
the initial idea behind wrapping all memory functions
in libiscsi.

The results of booting are test system up to the login
prompt are quite impressive:

BEFORE:
libiscsi:5 memory is clean at iscsi_destroy_context() after 10712 mallocs, 18 realloc(s) and 10712 free(s)

AFTER:
libiscsi:5 memory is clean at iscsi_destroy_context() after 41 mallocs, 18 realloc(s), 41 free(s) and 10584 reused small allocations

Signed-off-by: Peter Lieven <pl@kamp.de>
2013-07-18 11:15:56 +02:00
Ronnie Sahlberg
e061cba1b9 URL encoded Targetnames
Assume target names are URL encoded with '%' as the special character.

Any sequence of '%' followed by two bytes in the target name will be replaced
with the byte that the second two bytes represent in hexadecimal.

Example
iqn.ronnie.test%3A1234
will be translated to iqn.ronnie.test:1234
2013-06-16 11:35:14 -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
Peter Lieven
ee83c7ce75 RECONNECT add option to limit the number of reconnect retries
In specific situation it might be useful to give up if a reconnect
is not successful or after a given number reconnect retries.
This patch adds the ability to change that. The default remains
the same: retry forever.

Signed-off-by: Peter Lieven <pl@kamp.de>
2012-12-04 13:38:50 +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