A new iscsi context is created as TCP transport type, but currently
missing iscsi_init_transport to change transport to iser in
reconnecting logic, then iser could never reconnect successfully.
Use orignal transport to initialize new iscsi context.
Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
If a thread is created without any attr, it works in attached mode.
It means that we need run pthread_join to relaim stack of thread.
Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
Hit segfault at iser_reg_mr during attaching disk with backtrace:
#0 0x000055ace9635b0f in iser_reg_mr (iser_conn=0x55aceca33820) at iser.c:1060
#1 iser_connected_handler (cma_id=<optimized out>) at iser.c:1300
#2 iser_cma_handler (event=0x7f29ef1f7950, cma_id=<optimized out>, iser_conn=0x55aceca33820) at iser.c:1326
#3 cm_thread (arg=0x55aceca33820) at iser.c:1380
#4 0x00007f2e2c31c4a4 in start_thread (arg=0x7f29ef1f8700) at pthread_create.c:456
#5 0x00007f2e2c05ed0f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:97
(gdb) p *iser_conn->tx_desc
Cannot access memory at address 0x20
This issue can be reproduced easily by attaching several disks of iser
protocol:
# virsh attach-device stretch iser0.xml
# virsh attach-device stretch iser1.xml
...
Initialize instances with zero to avoid random value pointer.
Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
libiscsi is usually linked by QEMU, and QEMU sets thread proc name
by function. But iser cm thread is created by libiscsi privately,
QEMU can't set this thread. After attaching a iser disk, we can find
a new thread 'qemu-system-x86' in QEMU process.
With this patch, iser cm thread works with thread name
'iscsi_cm_thread'.
Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
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>
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>
In logic.c, data segment parameters in the text segment are converted to
signed longs. Changing from strtol -> strtoul fixes compiler errors on
certain platforms that warn against comparing a signed long with
uint32_t using MIN.
A PDU is sent directly in iscsi_iser_queue_pdu even if the cmdsn of
it exceeds maxcmdsn, and it may be ignored by the target.
Signed-off-by: wanghonghao <wanghonghao@bytedance.com>
When ImmediateData=Yes, DataSegmentLength is set in iSCSI layer
but immediate data is not sent in the RCaP message.
Signed-off-by: wanghonghao <wanghonghao@bytedance.com>
This patch fixes the following linker error:
/usr/bin/ld: ../lib/.libs/libiscsipriv.a(libiscsipriv_la-iser.o): undefined reference to symbol 'sem_post@@GLIBC_2.2.5'
/usr/bin/ld: //lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from command line
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
The buffer is memcopied into the PDU. const makes it a little clearer
that the caller isn't handing over ownership.
Signed-off-by: David Disseldorp <ddiss@suse.de>
rfc3720 indicates that SendTargets on discovery *and* normal operational
sessions must be supported by targets:
A system that contains targets MUST support discovery sessions on
each of its iSCSI IP address-port pairs, and MUST support the
SendTargets command on the discovery session.
...
A target MUST support the SendTargets command on operational
sessions...
Signed-off-by: David Disseldorp <ddiss@suse.de>
Discovered this while running iSCSI.iSCSITMF AbortTaskSimpleAsync
test case. For Task Management command iser_pdu->iscsi_pdu.scsi_cbdata
is not set. When test case tries to send Task Management command
via common API iser_send_command() - it calls overflow_data_size
which tries to dereference scsi_cbdata leading to SEGFAULT.
Added a non-NULL check for scsi_cbdata before accessing it.
Added support for negotiating below keys:
RDMAExtensions, TargetRecvDataSegmentLength, and
InitiatorRecvDataSegmentLength.
These are required to support iSER. See RFC5046 Section 6.
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>
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>
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>
The old code is effectively always posting iser_conn->min_posted_rx
descriptors, since it is
if (outstanding + iser_conn->min_posted_rx <= iser_conn->qp_max_recv_dtos) {
if(iser_conn->qp_max_recv_dtos - outstanding > iser_conn->min_posted_rx)
count = iser_conn->min_posted_rx;
else
count = iser_conn->qp_max_recv_dtos - outstanding;
which is equivalent to
if(iser_conn->qp_max_recv_dtos - outstanding >= iser_conn->min_posted_rx)
if(iser_conn->qp_max_recv_dtos - outstanding > iser_conn->min_posted_rx)
count = iser_conn->min_posted_rx;
else
count = iser_conn->min_posted_rx;
So the "if" is redundant and the "min_posted_rx" is actually behaving more
like a _maximum_ number of posted descriptors in one iser_post_recvm.
Fix it with the (presumably) intended logic and remove a goto along
the way.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
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>
The current iscsi context in iscsi_reconnect() is called "old_iscsi",
whilst the temporary context is called "iscsi". That is rather
confusing, and this fixes that by calling the current context "iscsi"
and the temporary context "tmp_iscsi".
Signed-off-by: Felipe Franciosi <felipe@nutanix.com>
This fixes some identation in iscsi_reconnect_cb() where whitespaces
were used instead of hard tabs.
Signed-off-by: Felipe Franciosi <felipe@nutanix.com>
When unmarshalling a SCSI_PERSISTENT_RESERVE_READ_KEYS response,
scsi_persistentreservein_datain_unmarshall() assumes that the ADDITIONAL
LENGTH field represents the number of keys packed in the key array.
This is incorrect as key array data buffer may be truncated while
ADDITIONAL LENGTH is left in tact, as per SPC5r17 4.2.5.6:
If the information being transferred to the Data-In Buffer includes
fields containing counts ..., then the contents of these fields shall
not be altered to reflect the truncation, if any, that results from an
insufficient ALLOCATION LENGTH value, unless the standard that
describes the Data-In Buffer format states otherwise.
Determine the number of keys returned based on the minimum of the
data-in length and the ADDITIONAL LENGTH value.
Signed-off-by: David Disseldorp <ddiss@suse.de>
The code was implicitly dependent on container_of from
inifiniband/verbs.h, however that's been removed in rdma-core
latest release:
ce0274acff
Define container_of locally if it's not already defined
The set of sync connect calls use a stack variable to track the
connection status. This is ok because such calls block on event_poll()
until the connection is established. However, event_poll may return
early in case of errors (or timeout) while PDUs are still queued on the
context (and pointing to a local stack).
This cancels any pending PDUs before returning from sync connect calls.
Signed-off-by: Felipe Franciosi <felipe@nutanix.com>
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>
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>
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>