are in flight at the moment.
Aside from commands, we also consider the "has not yet connected completely" as being an i/o.
When this command returns 0 it means we are connected ant the iscsi connection is idle, with no commands in flight.
KVM needs a function to detect idleness like this for its block layer io_flush
function.
Add a new pdu flag : DELETE_WHEN_SENT. When this pdu has been
sent to the wire, the pdu will be deleted and not put on the waitpdu list.
This will be useful for sequences such as
-> WRITE10 cdb
-> DATAOUT the data to write
-< RESPONSE
Where we want to match WRITE10 and RESPONSE but where the plain DATAOUT pdu
will not be soliciting its own response.
We dont need to wait for the response to DATAOUT pdus, we are already waitin
for the response form the initial PDU in the sequence.
When non-blocking connect completes the error code can be read using
getsockopt(SO_ERROR). Doing this is important for identifying failure
to connect, especially if POLLERR and POLLHUP were not employed by the
user.
The QEMU iscsi block driver does not use POLLERR/POLLHUP and depends on
SO_ERROR to detect connection failure.
Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>
Non-blocking socket connect(2) involves waiting for the socket to become
writeable to detect that a connection has been made. POLLIN events
should not be requested until the socket is connected because they are
processed even if the iSCSI context is not yet connected.
For example, the QEMU iscsi block driver does something like this:
iscsi_full_connect_async(...)
/* Now wait until the socket becomes ready */
poll(POLLIN|POLLOUT) = POLLIN|POLLOUT
/* QEMU calls POLLIN and POLLOUT handlers individually and it happens to
* call the POLLIN handler *before* the POLLOUT handler.
*/
iscsi_service(POLLIN)
iscsi_service(POLLOUT)
POLLIN processing will read from the socket and consume the error code
if connect failed. As a result, the POLLOUT handler will write to a
disconnected socket and raise a SIGPIPE which kills the process.
Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>
Input processing used to keep all data in one single input buffer, which
makes it hard to handle nested events as well as reading directly from the
socket into the application buffer without an extra copy.
Create a new iscsi_in_pdu structure where we store the header, and any data
for the recevied pdu and store them in a proper input queue.
Change the signature for all processing functions to tahe a iscsi_in_pdu
structure for the received pdu instead of just a pointer to a buffer.