between them makes compilers complain about aliasing.
Merge the two and use one single structure bot both iscsi and scsi sync
commands so that gcc stops crying about strict-aliasing
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.
"random" ISID randomly.
Dont assume that users will never create multiple contexts
concurrently, in which case the previous getpid()^time(NULL)
would create duplicates.
LBA is uint32_t for read/write10
Also store the lba/numblocks arguments in the task structure for read10/write10
This makes it much easier to implement a fully async "read lots/write lots"
applications.
A Portal URL is of the form
iscsi://[<username>[%<password>]@]<host>[:<port>]
and is used by command such as iscsi-ls during the discovery login phase.
During discovery we do not yet know the target iqn name, nor the lun of
any devices.
There is no point in setting the username if there is no password
and vice versa.
Also, if we only set username but not passwd this would lead to a segv.
so that the password will not be showing up in log where the application
logs the "filename/iscsi url" or in ps aux output.
LIBISCSI_CHAP_USERNAME and LIBISCSI_CHAP_PASSWORD environment variables are
available to set these outside of the url.
If hte username/password is ALSO set in the URL, the settings in the URL
will override the environment variables.
Update the "send scsi command" fucntion to honour
"FirstBurstLength" so that we only send this many bytes as unsolicited data.
The wait for a train of R2T from the target to clock out additional
busrts of data until the full task data has been sent to the Target.
We should now honour, and handle the case of
ImmediateData=No
InitialR2T=No
correctly for targets that are limited on receiveing data too fast.
Update the send pdu command to trap when we need to send data to the target
but we are not allowed to send using immediate data.
For this case, send the data as a separate DATAOUT pdu instead.
Twiddle the flags and other fields to now manage that we send the data
as two separate PDUs.
This function can allocate a new pdu using a specific itt value
and specific flags instead of using the defaults of, next iff, no flags set.
This can be used when we need to allocate additional PDUs in a chain,
for commands that span across multiple PDUs and where all need to keep
the same itt value.
For example
->WRITE10 cdb
->DATAOUT
-<RESPONSE
Here the DATAOUT PDU belongs to the same task that was started by write10
so it need to use the same itt value.
This flag is used when we dont want the CANCEL callback to be invoked if the
context is destroyed.
Thsi will be used for the sequence where we send multiple PDUs
to the target for one single scsi task, such as
-> WRITE10 cdb
-> DATAOUT
-< RESPONSE
Since if the context is destroyed when the command is in flight, we
already get the CANCEL callback for the WRITE10 PDU, so we dont need to invoke
it again for when we destroy the DATAOUT pdu, since they both refer to the same
task.
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.
We will use this later to decide when we should send unsolicited imemdiate
data to the target. Currently we always send unsolicited immediate data
but targets configured to not allow immediate data may refuce this and
turn an error.
and accept what Target responds.
Store the result of the negotiated setting in the iscsi context
so we can use it later to determine how to send solicited/unsolicited
data.
Always print the correct url syntax when parsing has failed.
Test if the user forgot to specify a <target-iqn> at all and log
this as a missing target-iqn error. Not as a missing <lun> error.
Remove \n from the error strings in init.c
Add these settings to the iscsi context structure and initialize them to
sane valued.
When sending login commands to the target, use these values instead
of hardcoded values.
Parse when the target sends a login reply back to us and update these variables
if the target asks us to.
This allows us to detect when our defaults are too big for the target
and adjust the settings we use so we match the target.
Some targets have a very small accepted default for some settings.
During login, we will initially send these keys with our dafult values.
These targets will then respond back by refusing to transition to the next
login phase, and by telling us back what the maximum of these values should be.
In this case we have to try the login again but use the smaller values we got
from the target.
Othervise, if we try again, ignoring the value from the target, and just repeat
using our defaults the target will abort the login with a "initiator error".
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>