This is the basic support for doing i/o in a separate worker thread.
It is still not threads safe but a start.
Now we need to protect all variables such as outqueue, waitpdu
and friends.
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
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>
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>
Instead of adding __attribute__((unused)) to unused arguments, add the
-Wno-unused-parameter compiler flag.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Declare dynamically allocated strings as 'char *' instead of 'const char *'.
Remove the discard_const() macro. Do not test whether or not a pointer is
NULL before calling free() because it is allowed to pass NULL to free().
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
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>
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>
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>
all sync commands that return an integer value are
supposed to return a negative value on error.
However, state.status is positive non-zero on error.
Fix this by returning -1 if the state.status is
not SCSI_STATUS_GOOD.
Reported-by: Sitsofe Wheeler <sitsofe@yahoo.com>
Signed-off-by: Peter Lieven <pl@kamp.de>
Build on existing scsi_cdb_extended_copy() functionality. This operation
can be used to offload inter and intra LU copies to the target.
The API is rather primitive, in that the caller needs to construct the
parameter buffer, including CSCD and segment descriptor lists, etc.
Signed-off-by: David Disseldorp <ddiss@suse.de>
Build on existing scsi_cdb_receive_copy_results() functionality. This
request is most commonly used to determine target-side EXTENDED COPY
operational parameters.
Signed-off-by: David Disseldorp <ddiss@suse.de>
iscsi-command: Adding new functions for all write operations (WRITE10,
WRITE12, WRITE16, WRITEOR, etc') for cases where the user wants
to pass his own io vectors (prevent memcpy).
new functions are called iscsi_write*_iov_task and looks
very similar to the iscsi_write*_task, only they get
scsi_iovec pointer and number of scsi_iovec as
parameters.
Change-Id: I719552b4cbda4f937975b5df7e77b4844e48cd16
Signed-off-by: Roy Shterman <roysh@mellanox.com>
iscsi-command: Adding new functions for all write operations (READ6,
READ10, READ12, READ16, etc') for cases where the
user wants to pass his own io vectors (prevent memcpy).
new functions are called iscsi_read*_iov_task and looks
very similar to the iscsi_read*_task, only they get
scsi_iovec pointer and number of scsi_iovec as
parameters.
Change-Id: Ice6bdb9227d72b20f495927f17d6757c124e4c84
Signed-off-by: Roy Shterman <roysh@mellanox.com>
Currently the iscsi_task_mgmt_abort_task_[a]sync() functions cancel any
queued or dispatched (awaiting response) PDUs prior to transmitting the
ABORT TASK TMF request, which means that a TMF request may be sent which
references a PDU that the target never received.
Bug: https://github.com/sahlberg/libiscsi/issues/192
Signed-off-by: David Disseldorp <ddiss@suse.de>
Add a test to verify the pdu timeout handling.
Fix numerous bugs in the timeout handling. It was really broken.
Add test for non-SCSI task PDUs too and verify they works.
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
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.
If there is an error in iscsi_service or on poll we
exit the event_loop. But in this case scsi_sync_cb is
never reached and the status is 0. This will make
the caller think that the sync task has been completed
successfully.
If there is an error during reconnect we should not loop in event_loop
as this will cause a deadlock in case there is actually an error like
connection drop etc. If this reconnect fails the reconnect routine
will retry itself.