Target initiated NOP:
Initial support to try to respond to target initiated NOPs.
This commit is contained in:
@@ -243,6 +243,7 @@ int iscsi_process_r2t(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
|||||||
struct iscsi_in_pdu *in);
|
struct iscsi_in_pdu *in);
|
||||||
int iscsi_process_reject(struct iscsi_context *iscsi,
|
int iscsi_process_reject(struct iscsi_context *iscsi,
|
||||||
struct iscsi_in_pdu *in);
|
struct iscsi_in_pdu *in);
|
||||||
|
int iscsi_send_target_nop_out(struct iscsi_context *iscsi, uint32_t ttt);
|
||||||
|
|
||||||
void iscsi_set_error(struct iscsi_context *iscsi, const char *error_string,
|
void iscsi_set_error(struct iscsi_context *iscsi, const char *error_string,
|
||||||
...);
|
...);
|
||||||
|
|||||||
45
lib/nop.c
45
lib/nop.c
@@ -47,12 +47,15 @@ iscsi_nop_out_async(struct iscsi_context *iscsi, iscsi_command_cb cb,
|
|||||||
iscsi_pdu_set_ttt(pdu, 0xffffffff);
|
iscsi_pdu_set_ttt(pdu, 0xffffffff);
|
||||||
|
|
||||||
/* lun */
|
/* lun */
|
||||||
iscsi_pdu_set_lun(pdu, 2);
|
iscsi_pdu_set_lun(pdu, 0);
|
||||||
|
|
||||||
/* cmdsn is not increased if Immediate delivery*/
|
/* cmdsn is not increased if Immediate delivery*/
|
||||||
iscsi_pdu_set_cmdsn(pdu, iscsi->cmdsn);
|
iscsi_pdu_set_cmdsn(pdu, iscsi->cmdsn);
|
||||||
pdu->cmdsn = iscsi->cmdsn;
|
pdu->cmdsn = iscsi->cmdsn;
|
||||||
|
|
||||||
|
/* exp statsn */
|
||||||
|
iscsi_pdu_set_expstatsn(pdu, iscsi->statsn+1);
|
||||||
|
|
||||||
pdu->callback = cb;
|
pdu->callback = cb;
|
||||||
pdu->private_data = private_data;
|
pdu->private_data = private_data;
|
||||||
|
|
||||||
@@ -71,6 +74,46 @@ iscsi_nop_out_async(struct iscsi_context *iscsi, iscsi_command_cb cb,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
iscsi_send_target_nop_out(struct iscsi_context *iscsi, uint32_t ttt)
|
||||||
|
{
|
||||||
|
struct iscsi_pdu *pdu;
|
||||||
|
|
||||||
|
pdu = iscsi_allocate_pdu_with_itt_flags(iscsi, ISCSI_PDU_NOP_OUT, ISCSI_PDU_NO_PDU,
|
||||||
|
0xffffffff,ISCSI_PDU_DELETE_WHEN_SENT|ISCSI_PDU_NO_CALLBACK);
|
||||||
|
if (pdu == NULL) {
|
||||||
|
iscsi_set_error(iscsi, "Failed to allocate nop-out pdu");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* immediate flag */
|
||||||
|
iscsi_pdu_set_immediate(pdu);
|
||||||
|
|
||||||
|
/* flags */
|
||||||
|
iscsi_pdu_set_pduflags(pdu, 0x80);
|
||||||
|
|
||||||
|
/* ttt */
|
||||||
|
iscsi_pdu_set_ttt(pdu, ttt);
|
||||||
|
|
||||||
|
/* lun */
|
||||||
|
iscsi_pdu_set_lun(pdu, 0);
|
||||||
|
|
||||||
|
/* cmdsn is not increased if Immediate delivery*/
|
||||||
|
iscsi_pdu_set_cmdsn(pdu, iscsi->cmdsn);
|
||||||
|
pdu->cmdsn = iscsi->cmdsn;
|
||||||
|
|
||||||
|
/* exp statsn */
|
||||||
|
iscsi_pdu_set_expstatsn(pdu, iscsi->statsn+1);
|
||||||
|
|
||||||
|
if (iscsi_queue_pdu(iscsi, pdu) != 0) {
|
||||||
|
iscsi_set_error(iscsi, "failed to queue iscsi nop-out pdu");
|
||||||
|
iscsi_free_pdu(iscsi, pdu);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
iscsi_process_nop_out_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
iscsi_process_nop_out_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
||||||
struct iscsi_in_pdu *in)
|
struct iscsi_in_pdu *in)
|
||||||
|
|||||||
35
lib/pdu.c
35
lib/pdu.c
@@ -178,7 +178,7 @@ iscsi_get_pdu_data_size(const unsigned char *hdr)
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum iscsi_reject_reason {
|
enum iscsi_reject_reason {
|
||||||
ISCSI_REJECT_RESERVED = 0x01,
|
ISCSI_REJECT_RESERVED = 0x01,
|
||||||
ISCSI_REJECT_DATA_DIGEST_ERROR = 0x02,
|
ISCSI_REJECT_DATA_DIGEST_ERROR = 0x02,
|
||||||
ISCSI_REJECT_SNACK_REJECT = 0x03,
|
ISCSI_REJECT_SNACK_REJECT = 0x03,
|
||||||
@@ -225,6 +225,32 @@ static const char *iscsi_reject_reason_str(enum iscsi_reject_reason reason)
|
|||||||
return "Unknown";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int iscsi_process_target_nop_in(struct iscsi_context *iscsi,
|
||||||
|
struct iscsi_in_pdu *in)
|
||||||
|
{
|
||||||
|
uint32_t itt, ttt;
|
||||||
|
uint32_t statsn;
|
||||||
|
|
||||||
|
itt = ntohl(*(uint32_t *)&in->hdr[16]);
|
||||||
|
|
||||||
|
ttt = ntohl(*(uint32_t *)&in->hdr[20]);
|
||||||
|
|
||||||
|
statsn = ntohl(*(uint32_t *)&in->hdr[24]);
|
||||||
|
if (statsn > iscsi->statsn) {
|
||||||
|
iscsi->statsn = statsn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if the server does not want a response */
|
||||||
|
if (ttt == 0xffffffff) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
iscsi_send_target_nop_out(iscsi, ttt);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int iscsi_process_reject(struct iscsi_context *iscsi,
|
int iscsi_process_reject(struct iscsi_context *iscsi,
|
||||||
struct iscsi_in_pdu *in)
|
struct iscsi_in_pdu *in)
|
||||||
{
|
{
|
||||||
@@ -289,6 +315,13 @@ iscsi_process_pdu(struct iscsi_context *iscsi, struct iscsi_in_pdu *in)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opcode == ISCSI_PDU_NOP_IN && itt == 0xffffffff) {
|
||||||
|
if (iscsi_process_target_nop_in(iscsi, in) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
for (pdu = iscsi->waitpdu; pdu; pdu = pdu->next) {
|
for (pdu = iscsi->waitpdu; pdu; pdu = pdu->next) {
|
||||||
enum iscsi_opcode expected_response = pdu->response_opcode;
|
enum iscsi_opcode expected_response = pdu->response_opcode;
|
||||||
int is_finished = 1;
|
int is_finished = 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user