195 Commits

Author SHA1 Message Date
Duncan Overbruck
0873c22d55 use size_t printf format for iovector->offset 2026-02-04 20:07:24 +01:00
sahlberg
a8c3920ab8 Write the PDU directly to the socket if the socket is idle.
Signed-off-by: sahlberg <sahlberg@r10-0-1.rocky10.sahlberg>
2025-07-15 19:26:46 +10:00
Ronnie Sahlberg
914eb5d578 Fix compiler warning/error from the previous commit
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
2025-06-18 10:06:54 +10:00
lishiao
8ebfb20c55 Optimize the judgment conditions 2025-06-17 12:24:40 +08:00
lishiao
a81eacc0b1 iscsi: compute Data Digest for out_data segments 2025-06-17 11:57:38 +08:00
lishiao144
cbba36e150 fix ExpStatSN handling for Data-Out PDUs 2025-06-12 18:26:19 +08:00
lishiao144
484adf5017 Fix length check to exclude padding when comparing against initiator_max_recv_data_segment_length 2025-06-12 16:41:53 +08:00
Ronnie Sahlberg
eb19863f77 Fix race between queueing the pdu and update the task data
After we have called iscsi_queue_pdu from iscsi_scsi_command_async
the pdu might have already completed if we are using multithreading
so we should not dereference pdu at that point.

Move the assignment of task->cmdsn and task->itt we need for
task management into iscsi_pdu_set_cmdsn instead.

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
2025-04-26 11:55:47 +10:00
Ronnie Sahlberg
d5e3bf6175 Merge branch 'tst' 2025-04-26 11:30:58 +10:00
Ronnie Sahlberg
edd7d9b843 Remove the small allocations
This is not compatible with multithreading and would require a complete
re-design.

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
2025-04-26 08:56:16 +10:00
Ronnie Sahlberg
91cc1e4197 Protect outqueue and waitpdu with a spinlock
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
2025-04-26 08:56:16 +10:00
Ronnie Sahlberg
3fc5d2996b iscsi_queue_pdu() can never fail, make it void
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
2025-04-26 08:56:16 +10:00
Ronnie Sahlberg
37bc6fcd81 TCP: immediately trigger the service thread to write PDU
IF qe queue a new PDU to an empty outqueue then the mt service thread
will still be stuck in poll() until it timesout or the socket becomes
readable.

Fix this by sending SIGUSR1 to the service thread when we queue a PDU
to an empty queue. This will break out of poll() and we can immediately
go and write to the socket.

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
2025-04-26 08:56:16 +10:00
Peter Lieven
696c946a9b feat(socket): log resolved ip addresses if portal is a hostname
Signed-off-by: Peter Lieven <pl@dlhnet.de>
2025-03-25 22:06:21 +00:00
Peter Lieven
98f0f2f7f1 fix(socket): restore logging of local ip and port
commit a92b413 removed the logging of local ip and port.
For debugging puposes these information can be important.
Restore functionality by using the new thread safe replacement
for inet_ntoa called inet_ntop.

Signed-off-by: Peter Lieven <pl@dlhnet.de>
2025-03-25 22:06:19 +00:00
Ronnie Sahlberg
a92b41318c Don't use inet_ntoa, it is deprecated
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
2025-01-03 15:48:51 +10:00
Tianren Zhang
97ba4c34e2 lib: reserve the fd on reconnect
On reconnect case, the iscsi_tcp_connect tries to reuse
the fd number of old_iscsi. However, this fd could have been
already closed in previous iscsi_tcp_disconnect if
iscsi->fd == iscsi->old_iscsi->fd and the fd number
might have been allocated to some other caller, in this
case the fd reuse in iscsi_tcp_connect is not safe anymore.

Solve this by not closing the fd if iscsi and old_iscsi
share the same fd on reconnect to "really" reserve this
fd number.

Signed-off-by: Tianren Zhang <tianren@smartx.com>
2024-11-22 06:16:59 +00:00
Brian Meagher
882bcad53a Add support for Data Digest 2024-05-04 19:34:06 -07:00
zhenwei pi
3593362721 Log necessary message on internal reconnect
Once error occurs on socker read/write, libiscsi tries to reconnect
silently. Add necessary log message for this case.

Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
2023-11-14 15:39:33 +08: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
Bart Van Assche
2a5a0b3291 Enable -Wno-unused-parameter
Instead of adding __attribute__((unused)) to unused arguments, add the
-Wno-unused-parameter compiler flag.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
2021-05-23 13:23:41 -07:00
Xie Yongji
ee47dc7338 socket: Make the pdu timeout handling aware of old iscsi context
We should check the pdus in old iscsi context when
scanning timeout tasks during reconnecting.

Signed-off-by: Xie Yongji <xieyongji@bytedance.com>
2020-06-23 19:49:07 +08:00
wanghonghao
7e59b9bd23 socket: fix rewrite cmdsn of immediate pdus
Cmdsn of a data-out pdu struct is less than `expcmdsn` since it's from its
cmd pdu. A data-out pdu doesn't carray a cmdsn on the wire actually, so it
doesn't matter to itself, but if we rewrite the cmdsn of a immediate pdu with
it, it will cause an error.

Related error logs:
libiscsi: iscsi_write_to_socket: outqueue[0]->cmdsn < expcmdsn (3648bab5 < 3648bab9) opcode 00 [iqn.2003-01.org.linux-iscsi.tgt0]
libiscsi: reconnect initiated [iqn.2003-01.org.linux-iscsi.tgt0]
libiscsi: connecting to portal 127.0.0.1 [iqn.2003-01.org.linux-iscsi.tgt0]
libiscsi: connection established (127.0.0.1:62404 -> 127.0.0.1) [iqn.2003-01.org.linux-iscsi.tgt0]

Signed-off-by: wanghonghao <wanghonghao@bytedance.com>
2020-05-09 12:22:00 +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
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
David Disseldorp
9d31150e9d socket: improve ISCSI_HEADER_SIZE readability
The ISCSI_HEADER_SIZE macro accesses iscsi->header_size, so pass it in
as a parameter to make it easier to follow callers.

Signed-off-by: David Disseldorp <ddiss@suse.de>
2018-10-25 23:38:59 +02:00
David Disseldorp
009892b017 socket: calculate hdr_size once per PDU process loop
ISCSI_HEADER_SIZE is determined based on the iscsi->header_digest
setting, which may change via iscsi_process_pdu().

Signed-off-by: David Disseldorp <ddiss@suse.de>
2018-10-25 23:38:59 +02:00
David Disseldorp
96dc6e7ebd socket: check for malloc failure before dereference
Signed-off-by: David Disseldorp <ddiss@suse.de>
2018-10-25 23:38:59 +02: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
12222077cc Add project file for iscsi-ls and make it build under visual studio
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
2017-05-13 12:09:42 -07:00
Ronnie Sahlberg
f750101980 Add initial visual studio project files and fix the win32 build
Win32 has been rotting for a while. This patch adds vs17 build files
as well as fixing up all build errors that have accumulated.
There are still build warnings but those can be addressed in a followup
patch.

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
2017-05-11 21:19:14 -07:00
Ronnie Sahlberg
179f6b33d4 Fix IPV6
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
2017-01-08 12:57:12 -08:00
Ronnie Sahlberg
2eefdbb9e8 Lost patch when resolving conflicts
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
2017-01-07 09:06:59 -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
0225c662d0 socket: restore connected_portal info
this got lost in commit 0d6362f

Signed-off-by: Peter Lieven <pl@kamp.de>
2017-01-05 14:47:51 +01:00
Peter Lieven
443b104833 crc32c: use uint_t types
Signed-off-by: Peter Lieven <pl@kamp.de>
2017-01-05 14:39:15 +01:00
Peter Lieven
23738bf1c3 socket: calculate header checksum at the right place
we mangled the PDU header after calculating the checksum which
effectively broke CRC32C header digests completely.

Signed-off-by: Peter Lieven <pl@kamp.de>
2017-01-05 12:28:37 +01:00
Peter Lieven
ed1ed27dde socket: return in->hdr to smalloc pool
commit bc64420 introduced an extra smalloc for the in->hdr,
however it did use iscsi_free instead of iscsi_sfree to free it.

Signed-off-by: Peter Lieven <pl@kamp.de>
2017-01-05 12:19:20 +01:00
Peter Lieven
1a552a8afa socket: do not zero header of incoming PDU
we overwrite it anyway

Signed-off-by: Peter Lieven <pl@kamp.de>
2017-01-05 12:19:07 +01:00
Peter Lieven
e058e825bf socket: break receive loop if there are no more outstanding PDUs
If the length of iscsi->waitpdu and iscsi->inqueue are the same
then except for any target initiated NOPs or async messages
we should have received any and all possible pdus from this
socket and can abort early.

This avoids running the loop one more time just to fail with EAGAIN
at the recs/readv. Just avoiding that recv/readv syscall will shave
at least 10us off this function and thus the latency.

Suggested-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Signed-off-by: Peter Lieven <pl@kamp.de>
2017-01-03 11:13:06 +01:00
Peter Lieven
b81e9a28a6 Batch pdu read in function iscsi_read_from_socket()
iscsi_read_from_socket can currently only read one PDU in each iscsi_service invocation even
if there is more data available on the socket. This patch reads all PDUs until the socket
would block. It enqueues all complete read PDUs and then processes them in order of arrival.

Signed-off-by: Peter Lieven <pl@kamp.de>
2017-01-02 15:52:19 +01: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
9ecc8184fe socket: do not leak addrinfo in iscsi_connect_async
Signed-off-by: Peter Lieven <pl@kamp.de>
2016-07-07 11:53:01 +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
47b6881b97 Libiscsi: Adding abstraction to async functions
future iSER implementation will include different implementations
for all socket relative function. in iSER we get event only when
there is new entry in completion queue opposed to TCP that we get event
when we can write to the socket.

1. iscsi_get_fd -
	TCP - returns socket fd.
	ISER - returns completion queue channel fd.
2. iscsi_service -
	TCP -   processing the event type got from the socket
		and handles it.
	ISER -  rearming the event mechanism in the completion queue
		and polling all available completion queue entries for
		process.
3. iscsi_which_events -
	TCP -   returns which type of event the library is waiting for
		(Read, Write or both).
	ISER -  in iSER we are waiting only for POLLIN event, hence this
		function always returns POLLIN.

Signed-off-by: Roy Shterman <roysh@mellanox.com>
2016-06-03 18:54:02 -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
dff69584e0 Libiscsi: Adding disconnect function to transport abstraction
all library: change disconnect to iscsi->t->disconnect

1. In TCP we need only to put -1 in fd and we don't
have more transport resources. In future iSER we will need to
clean resources and destroy the rdma connection.

Signed-off-by: Roy Shterman <roysh@mellanox.com>
2016-06-03 18:46:50 -07:00