pdu: handle async target requests logout events

Signed-off-by: Peter Lieven <pl@kamp.de>
This commit is contained in:
Peter Lieven
2014-06-17 14:52:27 +02:00
parent 98bbeab664
commit 81921e3762
3 changed files with 34 additions and 1 deletions

View File

@@ -126,6 +126,7 @@ struct iscsi_context {
int no_auto_reconnect;
int reconnect_deferred;
int reconnect_max_retries;
int pending_reconnect;
int log_level;
iscsi_log_fn log_fn;
@@ -189,8 +190,9 @@ enum iscsi_opcode {
ISCSI_PDU_DATA_IN = 0x25,
ISCSI_PDU_LOGOUT_RESPONSE = 0x26,
ISCSI_PDU_R2T = 0x31,
ISCSI_PDU_ASYNC_MSG = 0x32,
ISCSI_PDU_REJECT = 0x3f,
ISCSI_PDU_NO_PDU = 0xff
ISCSI_PDU_NO_PDU = 0xff
};
struct iscsi_scsi_cbdata {

View File

@@ -359,6 +359,17 @@ int iscsi_process_reject(struct iscsi_context *iscsi,
}
static void iscsi_reconnect_after_logout(struct iscsi_context *iscsi, int status,
void *command_data _U_, void *opaque _U_)
{
if (status) {
ISCSI_LOG(iscsi, 1, "logout failed: %s", iscsi_get_error(iscsi));
} else {
ISCSI_LOG(iscsi, 2, "logout was successful");
}
iscsi->pending_reconnect = 1;
}
int
iscsi_process_pdu(struct iscsi_context *iscsi, struct iscsi_in_pdu *in)
{
@@ -376,6 +387,22 @@ iscsi_process_pdu(struct iscsi_context *iscsi, struct iscsi_in_pdu *in)
return -1;
}
if (opcode == ISCSI_PDU_ASYNC_MSG) {
uint8_t event = in->hdr[36];
uint16_t param1 = scsi_get_uint16(&in->hdr[38]);
uint16_t param2 = scsi_get_uint16(&in->hdr[40]);
uint16_t param3 = scsi_get_uint16(&in->hdr[42]);
switch (event) {
case 0x1:
ISCSI_LOG(iscsi, 2, "target requests logout within %u seconds", param3);
iscsi_logout_async_internal(iscsi, iscsi_reconnect_after_logout, NULL, ISCSI_PDU_DROP_ON_RECONNECT|ISCSI_PDU_URGENT_DELIVERY);
return 0;
default:
ISCSI_LOG(iscsi, 1, "unhandled async event %u: param1 %u param2 %u param3 %u", event, param1, param2, param3);
return -1;
}
}
if (opcode == ISCSI_PDU_REJECT) {
iscsi_set_error(iscsi, "Request was rejected with reason: 0x%02x (%s)", in->hdr[2], iscsi_reject_reason_str(in->hdr[2]));

View File

@@ -735,6 +735,10 @@ iscsi_service(struct iscsi_context *iscsi, int revents)
return 0;
}
if (iscsi->pending_reconnect) {
iscsi_reconnect(iscsi);
}
if (revents & POLLERR) {
int err = 0;
socklen_t err_size = sizeof(err);