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>
a process might have a connection to different LUNs on the same target.
To be able to distinguish the different connections add the LUN id to the target
to log messages.
Signed-off-by: Peter Lieven <pl@dlhnet.de>
In iSCSI synchronous operations, a struct iscsi_sync_state variable
(state) is allocated on the stack, and its address is assigned to
pdu->scsi_cbdata.private_data. This address is eventually used in
the PDU callback function.
However, if a reconnection occurs during a synchronous operation
(e.g., read or write), but the connect function fails (iscsi->fd
will be set to -1), the event_loop times out and exits. At this point,
unprocessed PDUs remain. If the PDU callback function is triggered
after the timeout (e.g., during iscsi_destroy_context), it may
access the pdu->scsi_cbdata.private_data address, which no longer
points to the original stack allocation. Writing to this invalid
address in the callback corrupts the current stack structure,
leading to process crash.
This patch addresses the issue by scanning PDUs before exiting the
event_loop due connect timedout, ensuring the unprocessed PDUs are
properly handled to prevent stack corruption and crash.
Signed-off-by: raywang <honglei.wang@smartx.com>
When iscsi->fd gets invalid, there is not point to
keep stuck in the event loop, instead could give an
accurate error about the invalid fd.
Signed-off-by: Tianren Zhang <tianren@smartx.com>
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>
The pdu indata alloc by iscsi_malloc with a undetermined size, but free
by iscsi_sfree. The iscsi_sfree can only be used to free memory which
size is equal to iscsi->smalloc_size.
Signed-off-by: IriKa Qiu <qiujie.jq@gmail.com>
When an iSCSI connection enters the reconnection phase, the backoff
time (next_reconnect) increases with reconnection retry_cnt. However,
if the client detects that the target has recovered before reaching
next_reconnect, calling iscsi_reconnect/iscsi_force_reconnect has no
any effect, making fast reconnection impossible.
This patch introduces an interface to reset next_reconnect, so that
the client can reset the backoff time upon detecting target recovery
and achieve faster reconnection.
Resolves: https://github.com/sahlberg/libiscsi/issues/428
Signed-off-by: raywang <honglei.wang@smartx.com>
Implement a more generic wrapper API for message digests, so
that it is easier to also include gnutls as an option.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Originally, we use this in scsi-lowlevel.c only, this works as static
function. It also could be used to dump ISCSI opcode, so move it into
common utils.h/utils.c.
Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
Describe the reason again:
A WRITE16 command[w] handles R2T, and queues DATAOUT PDU m,x,y,z:
outqueue->DATAOUT[x]->DATAOUT[y]->DATAOUT[z]...
outqueue_current->DATAOUT[m]
waitqueue->WRITE16[w]...
1, Once x, y, z gets released in initiator side, the target still expects the remaining
DATAOUT PDUs.
2, Once command w timeout and callback to uplayer, uplayers usually releases memory of
iscsi task(include memory referenced by iovec.iov_base). DATAOUT[m] would access
invalid memory iovce.iov_base.
So invoke WRITEx command callback until draining DATAOUT PDUs.
Co-developed-by: Rui Zhang <zhangrui.1203@bytedance.com>
Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
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>
Now we have more friendly opcode message once error occurs:
libiscsi:1 command timed out from waitqueue [...]
libiscsi:2 PDU header: 01 c1 ... e9 88[READ16] 00 00 00 ...
^(human readable opcode string)
Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
Distinguish command timeout from outqueue or waitqueue. For example,
A command sequence: ...NOP,READ,WRITE...
NOP OUT command has no dependence on backend media, it is expected to
response soon. Once NOP timeout in libiscsi:
a, the command is already sent to target, the target side does *not*
response.
b, the command is still pending in libiscsi.
Separate the two cases for trouble shooting.
Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
The existing implementation of iscsi_task_mgmt_lun_reset_async cancels
all tasks in ready-to-send and wait-for-completion queues.
If the ISCSI context has in-flight tasks for a different LUNs or
tasks that are not LUN-specific (such as NOPIN, NOPOUT), those tasks
are not supposed to be affected by the LUN reset.
Also, the tasks for the LUN being reset may have in-flight responses
not affected by a concurrent LUN reset; they have to be handled
accordingly.
This change cancels only the tasks for the LUN being reset if they are
in the ready-to-send queue ('outqueue'). The tasks in the wait-for-
completion queue should be cancelled on LUN reset completion.
For example:
iscsi_task_mgmt_lun_reset_async(iscsi, lun, lun_reset_cb, ctxt);
....
....
void lun_reset_cb(struct iscsi_context * iscsi, int status,
void * command_data, void * private_data)
{
// 'response' field per ISCSI spec rfc7143 section 11.6.1
uint8_t iscsi_response = *(uint8_t *)command_data;
if (iscsi_response == 0) {
// The LUN has been reset. No further replies are expected
// for in-flight tasks for that LUN. Explicitly cancelling
// the tasks in wait-for-completion queue.
for (.. scsi_task-s in flight ..) {
iscsi_scsi_cancel_task(iscsi, task);
}
} ...
}
Users need to check if a task is queued to send (not sent yet)
before invoking functions such as iscsi_task_mgmt_abort_task_async.
Otherwise, because task management requests are automatically
treated as "immediate", a request to abort a task is sent before
the task itself.
if (iscsi_scsi_is_task_in_outqueue(iscsi_, task_)) {
iscsi_scsi_cancel_task(iscsi_, task_);
} else {
iscsi_task_mgmt_abort_task_async(iscsi_, task_, AbortCb, context_);
}
When execute iscsi_task_mgmt_lun_reset_async function,
pdus are already removed from waitpdu list. In iscsi_service
function, this will call iscsi_process_pdu and release
pdu from waitpdu again, which cause segmentation fault.
Whether waitpud list is NULL should be checked here to avoid
the problem.
Signed-off-by: geruijun <geruijun@huawei.com>
If a test sets the use_immediate_data parameter to ISCSI_IMMEDIATE_DATA_NO
for the iSCSI context, then the test expects that a data associated with
the Write command to be sent in a separate PDU.
But if for execute the command it is necessary to login on a target then
the use_immediate_data was previously set, will be rewrite during
the processing of the Login Response packet.
This happen during the iSCSI.iSCSIdatasn.iSCSIDataSnInvalid
(test_iscsi_datasn_invalid.c) test:
--> iSCSI 114 SCSI: Write(10) LUN: 0x01 (LBA: 0x00000064, Len: 1)
<-- iSCSI 114 Ready To Transfer
--> iSCSI 578 SCSI: Data Out LUN: 0x01 (Write(10) Request Data)
--> iSCSI 550 Login Command
Here we lose use_immediate_data value for iSCSI session.
<-- iSCSI 426 Login Response (Success)
--> iSCSI 114 SCSI: Test Unit Ready LUN: 0x01
<-- iSCSI 114 SCSI: Response LUN: 0x01 (Test Unit Ready) (Good)
And this Write command includes payload into iSCSI PDU packet, but should not do it.
--> iSCSI 578 SCSI: Write(10) LUN: 0x01 (LBA: 0x00000064, Len: 1)SCSI: Data Out LUN: 0x01 (Write(10) Request Data)
<-- iSCSI 114 SCSI: Response LUN: 0x01 (Write(10)) (Good)
--> iSCSI 114 SCSI: Write(10) LUN: 0x01 (LBA: 0x00000064, Len: 2)
<-- iSCSI 114 Ready To Transfer
--> iSCSI 578 SCSI: Data Out LUN: 0x01 (Write(10) Request Data)
--> iSCSI 626 SCSI: Data Out LUN: 0x01 (Write(10) Request Data)
Signed-off-by: Sergey Samoylenko <s.samoylenko@yadro.com>
In iscsi_send_data_out() a PDU is allocated, but there is no error
handling logic to free it if the PDU cannot be queued.
iscsi_allocate_pdu() may allocate memory for the PDU. This memory may be
leaked if iscsi_queue_pdu() fails since there is no call to free it.
Orignally there was a free() call but it was removed as a part of a
cleanup adding checks for NULL pdu callbacks.
Fixes: 423b82efa4 ("pdu: check callback for NULL everywhere")
Signed-off-by: Raphael Norwitz <raphael.norwitz@nutanix.com>
If a connection attempt is hung, then iscsi_reconnect() won't do anything. This
makes sense if we'd just re-try to connect to the same target, but if (for
example) login redirect might point us to a different, healthy, target, it
should be possible to restart the full connection process on request.
Signed-off-by: John Levon <john.levon@nutanix.com>