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>
Add unidirectional chap support so we can authenticate to the target.
Make the login phase more "intelligent" so we can iterate over login
pdus until we have reached full feature phase
Add a new helper functions to parse a iscsi url and break it down
into elements in a structure
Update iscsi-inq to allow CHAP authentication
We pass header and data separately now so no need to check id size
is less than header size.
Add error reporting of login type and error string describing
the error when login status has failed.
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.
to take the URLs in the form
iscsi://<host>[:<port>]
and
iscsi://<host>[:<port>]/<target-iqn>/<lun>
instead of specifying the values as --portal/--target/--lun