version 1.1.1.2, 2012/10/09 09:13:23
|
version 1.1.1.3, 2013/07/21 23:49:22
|
Line 117 static void istgt_remove_conn(CONN_Ptr conn);
|
Line 117 static void istgt_remove_conn(CONN_Ptr conn);
|
static int istgt_iscsi_drop_all_conns(CONN_Ptr conn); |
static int istgt_iscsi_drop_all_conns(CONN_Ptr conn); |
static int istgt_iscsi_drop_old_conns(CONN_Ptr conn); |
static int istgt_iscsi_drop_old_conns(CONN_Ptr conn); |
|
|
|
/* Switch to use readv/writev (assume blocking) */ |
|
#define ISTGT_USE_IOVEC |
|
|
|
#if defined (ISTGT_USE_IOVEC) |
|
#include <sys/uio.h> |
|
#endif |
|
|
|
#if !defined (ISTGT_USE_IOVEC) |
#if 0 |
#if 0 |
#define ISTGT_USE_RECVBLOCK |
#define ISTGT_USE_RECVBLOCK |
#define ISTGT_USE_SENDBLOCK |
#define ISTGT_USE_SENDBLOCK |
Line 376 istgt_iscsi_write(CONN_Ptr conn, const void *buf, size
|
Line 384 istgt_iscsi_write(CONN_Ptr conn, const void *buf, size
|
#endif /* ISTGT_USE_SENDBLOCK */ |
#endif /* ISTGT_USE_SENDBLOCK */ |
return nbytes; |
return nbytes; |
} |
} |
|
#endif /* !defined (ISTGT_USE_IOVEC) */ |
|
|
#define MATCH_DIGEST_WORD(BUF, CRC32C) \ |
#define MATCH_DIGEST_WORD(BUF, CRC32C) \ |
( ((((uint32_t) *((uint8_t *)(BUF)+0)) << 0) \ |
( ((((uint32_t) *((uint8_t *)(BUF)+0)) << 0) \ |
Line 417 istgt_make_digest_word(uint8_t *buf, size_t len, uint3
|
Line 426 istgt_make_digest_word(uint8_t *buf, size_t len, uint3
|
} |
} |
#endif |
#endif |
|
|
|
#if !defined (ISTGT_USE_IOVEC) |
static int |
static int |
istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) |
istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) |
{ |
{ |
Line 447 istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 457 istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
conn->initiator_name); |
conn->initiator_name); |
conn->state = CONN_STATE_EXITING; |
conn->state = CONN_STATE_EXITING; |
} else { |
} else { |
ISTGT_ERRLOG("iscsi_read() failed (errno=%d)\n", | ISTGT_ERRLOG("iscsi_read() failed (errno=%d,%s)\n", |
errno); | errno, conn->initiator_name); |
} |
} |
return -1; |
return -1; |
} |
} |
if (rc == 0) { |
if (rc == 0) { |
ISTGT_TRACELOG(ISTGT_TRACE_NET, "iscsi_read() EOF\n"); | ISTGT_TRACELOG(ISTGT_TRACE_NET, "iscsi_read() EOF (%s)\n", |
| conn->initiator_name); |
conn->state = CONN_STATE_EXITING; |
conn->state = CONN_STATE_EXITING; |
return -1; |
return -1; |
} |
} |
Line 471 istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 482 istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
(4 * total_ahs_len)); |
(4 * total_ahs_len)); |
rc = istgt_iscsi_read(conn, pdu->ahs, (4 * total_ahs_len)); |
rc = istgt_iscsi_read(conn, pdu->ahs, (4 * total_ahs_len)); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("iscsi_read() failed\n"); | ISTGT_ERRLOG("iscsi_read() failed (errno=%d,%s)\n", |
| errno, conn->initiator_name); |
return -1; |
return -1; |
} |
} |
if (rc == 0) { |
if (rc == 0) { |
Line 497 istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 509 istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
rc = istgt_iscsi_read(conn, pdu->header_digest, |
rc = istgt_iscsi_read(conn, pdu->header_digest, |
ISCSI_DIGEST_LEN); |
ISCSI_DIGEST_LEN); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("iscsi_read() failed\n"); | ISTGT_ERRLOG("iscsi_read() failed (errno=%d,%s)\n", |
| errno, conn->initiator_name); |
{ |
{ |
int opcode = BGET8W(&pdu->bhs.opcode, 5, 6); |
int opcode = BGET8W(&pdu->bhs.opcode, 5, 6); |
ISTGT_ERRLOG("Header Digest read error (opcode = 0x%x)\n", |
ISTGT_ERRLOG("Header Digest read error (opcode = 0x%x)\n", |
Line 540 istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 553 istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
data_len); |
data_len); |
rc = istgt_iscsi_read(conn, pdu->data, data_len); |
rc = istgt_iscsi_read(conn, pdu->data, data_len); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("iscsi_read() failed (%d,errno=%d)\n", | ISTGT_ERRLOG("iscsi_read() failed (%d,errno=%d,%s)\n", |
rc, errno); | rc, errno, conn->initiator_name); |
return -1; |
return -1; |
} |
} |
if (rc == 0) { |
if (rc == 0) { |
Line 577 istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 590 istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
rc = istgt_iscsi_read(conn, pdu->data_digest, |
rc = istgt_iscsi_read(conn, pdu->data_digest, |
ISCSI_DIGEST_LEN); |
ISCSI_DIGEST_LEN); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("iscsi_read() failed\n"); | ISTGT_ERRLOG("iscsi_read() failed (errno=%d,%s)\n", |
| errno, conn->initiator_name); |
return -1; |
return -1; |
} |
} |
if (rc == 0) { |
if (rc == 0) { |
Line 611 istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 625 istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
} |
} |
rc = MATCH_DIGEST_WORD(pdu->header_digest, crc32c); |
rc = MATCH_DIGEST_WORD(pdu->header_digest, crc32c); |
if (rc == 0) { |
if (rc == 0) { |
ISTGT_ERRLOG("header digest error\n"); | ISTGT_ERRLOG("header digest error (%s)\n", conn->initiator_name); |
return -1; |
return -1; |
} |
} |
} |
} |
Line 619 istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 633 istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
crc32c = istgt_crc32c(pdu->data, data_len); |
crc32c = istgt_crc32c(pdu->data, data_len); |
rc = MATCH_DIGEST_WORD(pdu->data_digest, crc32c); |
rc = MATCH_DIGEST_WORD(pdu->data_digest, crc32c); |
if (rc == 0) { |
if (rc == 0) { |
ISTGT_ERRLOG("data digest error\n"); | ISTGT_ERRLOG("data digest error (%s)\n", conn->initiator_name); |
return -1; |
return -1; |
} |
} |
} |
} |
|
|
return total; |
return total; |
} |
} |
|
#else /* defined (ISTGT_USE_IOVEC) */ |
|
static int |
|
istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) |
|
{ |
|
struct iovec iovec[4]; /* AHS+HD+DATA+DD */ |
|
uint32_t crc32c; |
|
time_t start, now; |
|
int nbytes; |
|
int total_ahs_len; |
|
int data_len; |
|
int segment_len; |
|
int total; |
|
int rc; |
|
int i; |
|
|
|
pdu->ahs = NULL; |
|
pdu->total_ahs_len = 0; |
|
pdu->data = NULL; |
|
pdu->data_segment_len = 0; |
|
total = 0; |
|
|
|
/* BHS (require for all PDU) */ |
|
ISTGT_TRACELOG(ISTGT_TRACE_NET, "BHS read %d\n", |
|
ISCSI_BHS_LEN); |
|
errno = 0; |
|
start = time(NULL); |
|
rc = recv(conn->sock, &pdu->bhs, ISCSI_BHS_LEN, MSG_WAITALL); |
|
if (rc < 0) { |
|
now = time(NULL); |
|
if (errno == ECONNRESET) { |
|
ISTGT_WARNLOG("Connection reset by peer (%s,time=%d)\n", |
|
conn->initiator_name, (int)difftime(now, start)); |
|
conn->state = CONN_STATE_EXITING; |
|
} else if (errno == ETIMEDOUT) { |
|
ISTGT_WARNLOG("Operation timed out (%s,time=%d)\n", |
|
conn->initiator_name, (int)difftime(now, start)); |
|
conn->state = CONN_STATE_EXITING; |
|
} else { |
|
ISTGT_ERRLOG("iscsi_read() failed (errno=%d,%s,time=%d)\n", |
|
errno, conn->initiator_name, (int)difftime(now, start)); |
|
} |
|
return -1; |
|
} |
|
if (rc == 0) { |
|
ISTGT_TRACELOG(ISTGT_TRACE_NET, "recv() EOF (%s)\n", |
|
conn->initiator_name); |
|
conn->state = CONN_STATE_EXITING; |
|
return -1; |
|
} |
|
if (rc != ISCSI_BHS_LEN) { |
|
ISTGT_ERRLOG("invalid BHS length (%d,%s)\n", rc, conn->initiator_name); |
|
return -1; |
|
} |
|
total += ISCSI_BHS_LEN; |
|
|
|
/* AHS */ |
|
total_ahs_len = DGET8(&pdu->bhs.total_ahs_len); |
|
if (total_ahs_len != 0) { |
|
pdu->ahs = xmalloc(ISCSI_ALIGN((4 * total_ahs_len))); |
|
pdu->total_ahs_len = total_ahs_len; |
|
total += (4 * total_ahs_len); |
|
} else { |
|
pdu->ahs = NULL; |
|
pdu->total_ahs_len = 0; |
|
} |
|
iovec[0].iov_base = pdu->ahs; |
|
iovec[0].iov_len = 4 * pdu->total_ahs_len; |
|
|
|
/* Header Digest */ |
|
iovec[1].iov_base = pdu->header_digest; |
|
if (conn->header_digest) { |
|
iovec[1].iov_len = ISCSI_DIGEST_LEN; |
|
total += ISCSI_DIGEST_LEN; |
|
} else { |
|
iovec[1].iov_len = 0; |
|
} |
|
|
|
/* Data Segment */ |
|
data_len = DGET24(&pdu->bhs.data_segment_len[0]); |
|
if (data_len != 0) { |
|
if (conn->sess == NULL) { |
|
segment_len = DEFAULT_FIRSTBURSTLENGTH; |
|
} else { |
|
segment_len = conn->MaxRecvDataSegmentLength; |
|
} |
|
if (data_len > segment_len) { |
|
ISTGT_ERRLOG("Data(%d) > Segment(%d)\n", |
|
data_len, segment_len); |
|
return -1; |
|
} |
|
if (ISCSI_ALIGN(data_len) <= ISTGT_SHORTDATASIZE) { |
|
pdu->data = pdu->shortdata; |
|
} else { |
|
pdu->data = xmalloc(ISCSI_ALIGN(segment_len)); |
|
} |
|
pdu->data_segment_len = data_len; |
|
total += ISCSI_ALIGN(data_len); |
|
} else { |
|
pdu->data = NULL; |
|
pdu->data_segment_len = 0; |
|
} |
|
iovec[2].iov_base = pdu->data; |
|
iovec[2].iov_len = ISCSI_ALIGN(pdu->data_segment_len); |
|
|
|
/* Data Digest */ |
|
iovec[3].iov_base = pdu->data_digest; |
|
if (conn->data_digest && data_len != 0) { |
|
iovec[3].iov_len = ISCSI_DIGEST_LEN; |
|
total += ISCSI_DIGEST_LEN; |
|
} else { |
|
iovec[3].iov_len = 0; |
|
} |
|
|
|
/* read all bytes to iovec */ |
|
nbytes = total - ISCSI_BHS_LEN; |
|
ISTGT_TRACELOG(ISTGT_TRACE_NET, "PDU read %d\n", nbytes); |
|
errno = 0; |
|
start = time(NULL); |
|
while (nbytes > 0) { |
|
rc = readv(conn->sock, &iovec[0], 4); |
|
if (rc < 0) { |
|
now = time(NULL); |
|
ISTGT_ERRLOG("readv() failed (%d,errno=%d,%s,time=%d)\n", |
|
rc, errno, conn->initiator_name, (int)difftime(now, start)); |
|
return -1; |
|
} |
|
if (rc == 0) { |
|
ISTGT_TRACELOG(ISTGT_TRACE_NET, "readv() EOF (%s)\n", |
|
conn->initiator_name); |
|
conn->state = CONN_STATE_EXITING; |
|
return -1; |
|
} |
|
nbytes -= rc; |
|
if (nbytes == 0) |
|
break; |
|
/* adjust iovec length */ |
|
for (i = 0; i < 4; i++) { |
|
if (iovec[i].iov_len != 0 && iovec[i].iov_len > (size_t)rc) { |
|
iovec[i].iov_base |
|
= (void *) (((uintptr_t)iovec[i].iov_base) + rc); |
|
iovec[i].iov_len -= rc; |
|
break; |
|
} else { |
|
rc -= iovec[i].iov_len; |
|
iovec[i].iov_len = 0; |
|
} |
|
} |
|
} |
|
|
|
/* check digest */ |
|
if (conn->header_digest) { |
|
if (total_ahs_len == 0) { |
|
crc32c = istgt_crc32c((uint8_t *) &pdu->bhs, |
|
ISCSI_BHS_LEN); |
|
} else { |
|
int upd_total = 0; |
|
crc32c = ISTGT_CRC32C_INITIAL; |
|
crc32c = istgt_update_crc32c((uint8_t *) &pdu->bhs, |
|
ISCSI_BHS_LEN, crc32c); |
|
upd_total += ISCSI_BHS_LEN; |
|
crc32c = istgt_update_crc32c((uint8_t *) pdu->ahs, |
|
(4 * total_ahs_len), crc32c); |
|
upd_total += (4 * total_ahs_len); |
|
crc32c = istgt_fixup_crc32c(upd_total, crc32c); |
|
crc32c = crc32c ^ ISTGT_CRC32C_XOR; |
|
} |
|
rc = MATCH_DIGEST_WORD(pdu->header_digest, crc32c); |
|
if (rc == 0) { |
|
ISTGT_ERRLOG("header digest error (%s)\n", conn->initiator_name); |
|
return -1; |
|
} |
|
} |
|
if (conn->data_digest && data_len != 0) { |
|
crc32c = istgt_crc32c(pdu->data, ISCSI_ALIGN(data_len)); |
|
rc = MATCH_DIGEST_WORD(pdu->data_digest, crc32c); |
|
if (rc == 0) { |
|
ISTGT_ERRLOG("data digest error (%s)\n", conn->initiator_name); |
|
return -1; |
|
} |
|
} |
|
|
|
return total; |
|
} |
|
#endif /* defined (ISTGT_USE_IOVEC) */ |
|
|
static int istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PDU_Ptr pdu); |
static int istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PDU_Ptr pdu); |
static int istgt_iscsi_write_pdu_queue(CONN_Ptr conn, ISCSI_PDU_Ptr pdu, int req_type, int I_bit); |
static int istgt_iscsi_write_pdu_queue(CONN_Ptr conn, ISCSI_PDU_Ptr pdu, int req_type, int I_bit); |
|
|
Line 787 istgt_iscsi_write_pdu_queue(CONN_Ptr conn, ISCSI_PDU_P
|
Line 985 istgt_iscsi_write_pdu_queue(CONN_Ptr conn, ISCSI_PDU_P
|
return rc; |
return rc; |
} |
} |
|
|
|
#if !defined (ISTGT_USE_IOVEC) |
static int |
static int |
istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) |
istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) |
{ |
{ |
Line 843 istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PD
|
Line 1042 istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PD
|
total); |
total); |
rc = istgt_iscsi_write(conn, spp, total); |
rc = istgt_iscsi_write(conn, spp, total); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("iscsi_write() failed (errno=%d)\n", | ISTGT_ERRLOG("iscsi_write() failed (errno=%d,%s)\n", |
errno); | errno, conn->initiator_name); |
return -1; |
return -1; |
} |
} |
if (rc != total) { |
if (rc != total) { |
Line 860 istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PD
|
Line 1059 istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PD
|
ISCSI_BHS_LEN); |
ISCSI_BHS_LEN); |
rc = istgt_iscsi_write(conn, &pdu->bhs, ISCSI_BHS_LEN); |
rc = istgt_iscsi_write(conn, &pdu->bhs, ISCSI_BHS_LEN); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("iscsi_write() failed (errno=%d)\n", errno); | ISTGT_ERRLOG("iscsi_write() failed (errno=%d,%s)\n", errno, |
| conn->initiator_name); |
return -1; |
return -1; |
} |
} |
if (rc != ISCSI_BHS_LEN) { |
if (rc != ISCSI_BHS_LEN) { |
Line 875 istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PD
|
Line 1075 istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PD
|
(4 * total_ahs_len)); |
(4 * total_ahs_len)); |
rc = istgt_iscsi_write(conn, pdu->ahs, (4 * total_ahs_len)); |
rc = istgt_iscsi_write(conn, pdu->ahs, (4 * total_ahs_len)); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("iscsi_write() failed\n"); | ISTGT_ERRLOG("iscsi_write() failed (errno=%d,%s)\n", |
| errno, conn->initiator_name); |
return -1; |
return -1; |
} |
} |
if (rc != (4 * total_ahs_len)) { |
if (rc != (4 * total_ahs_len)) { |
Line 909 istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PD
|
Line 1110 istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PD
|
rc = istgt_iscsi_write(conn, pdu->header_digest, |
rc = istgt_iscsi_write(conn, pdu->header_digest, |
ISCSI_DIGEST_LEN); |
ISCSI_DIGEST_LEN); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("iscsi_write() failed\n"); | ISTGT_ERRLOG("iscsi_write() failed (errno=%d,%s)\n", |
| errno, conn->initiator_name); |
return -1; |
return -1; |
} |
} |
if (rc != ISCSI_DIGEST_LEN) { |
if (rc != ISCSI_DIGEST_LEN) { |
Line 926 istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PD
|
Line 1128 istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PD
|
data_len); |
data_len); |
rc = istgt_iscsi_write(conn, pdu->data, data_len); |
rc = istgt_iscsi_write(conn, pdu->data, data_len); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("iscsi_write() failed\n"); | ISTGT_ERRLOG("iscsi_write() failed (errno=%d,%s)\n", |
| errno, conn->initiator_name); |
return -1; |
return -1; |
} |
} |
if (rc != data_len) { |
if (rc != data_len) { |
Line 949 istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PD
|
Line 1152 istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PD
|
rc = istgt_iscsi_write(conn, pdu->data_digest, |
rc = istgt_iscsi_write(conn, pdu->data_digest, |
ISCSI_DIGEST_LEN); |
ISCSI_DIGEST_LEN); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("iscsi_write() failed\n"); | ISTGT_ERRLOG("iscsi_write() failed (errno=%d,%s)\n", |
| errno, conn->initiator_name); |
return -1; |
return -1; |
} |
} |
if (rc != ISCSI_DIGEST_LEN) { |
if (rc != ISCSI_DIGEST_LEN) { |
Line 962 istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PD
|
Line 1166 istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PD
|
|
|
return total; |
return total; |
} |
} |
|
#else /* defined (ISTGT_USE_IOVEC) */ |
|
static int |
|
istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) |
|
{ |
|
struct iovec iovec[5]; /* BHS+AHS+HD+DATA+DD */ |
|
uint8_t *cp; |
|
uint32_t crc32c; |
|
time_t start, now; |
|
int nbytes; |
|
int enable_digest; |
|
int opcode; |
|
int total_ahs_len; |
|
int data_len; |
|
int total; |
|
int rc; |
|
int i; |
|
|
|
cp = (uint8_t *) &pdu->bhs; |
|
total_ahs_len = DGET8(&cp[4]); |
|
data_len = DGET24(&cp[5]); |
|
total = 0; |
|
|
|
enable_digest = 1; |
|
opcode = BGET8W(&cp[0], 5, 6); |
|
if (opcode == ISCSI_OP_LOGIN_RSP) { |
|
/* this PDU should be sent without digest */ |
|
enable_digest = 0; |
|
} |
|
|
|
/* BHS */ |
|
iovec[0].iov_base = &pdu->bhs; |
|
iovec[0].iov_len = ISCSI_BHS_LEN; |
|
total += ISCSI_BHS_LEN; |
|
|
|
/* AHS */ |
|
iovec[1].iov_base = pdu->ahs; |
|
iovec[1].iov_len = 4 * total_ahs_len; |
|
total += (4 * total_ahs_len); |
|
|
|
/* Header Digest */ |
|
iovec[2].iov_base = pdu->header_digest; |
|
if (enable_digest && conn->header_digest) { |
|
if (total_ahs_len == 0) { |
|
crc32c = istgt_crc32c((uint8_t *) &pdu->bhs, |
|
ISCSI_BHS_LEN); |
|
} else { |
|
int upd_total = 0; |
|
crc32c = ISTGT_CRC32C_INITIAL; |
|
crc32c = istgt_update_crc32c((uint8_t *) &pdu->bhs, |
|
ISCSI_BHS_LEN, crc32c); |
|
upd_total += ISCSI_BHS_LEN; |
|
crc32c = istgt_update_crc32c((uint8_t *) pdu->ahs, |
|
(4 * total_ahs_len), crc32c); |
|
upd_total += (4 * total_ahs_len); |
|
crc32c = istgt_fixup_crc32c(upd_total, crc32c); |
|
crc32c = crc32c ^ ISTGT_CRC32C_XOR; |
|
} |
|
MAKE_DIGEST_WORD(pdu->header_digest, crc32c); |
|
|
|
iovec[2].iov_len = ISCSI_DIGEST_LEN; |
|
total += ISCSI_DIGEST_LEN; |
|
} else { |
|
iovec[2].iov_len = 0; |
|
} |
|
|
|
/* Data Segment */ |
|
iovec[3].iov_base = pdu->data; |
|
iovec[3].iov_len = ISCSI_ALIGN(data_len); |
|
total += ISCSI_ALIGN(data_len); |
|
|
|
/* Data Digest */ |
|
iovec[4].iov_base = pdu->data_digest; |
|
if (enable_digest && conn->data_digest && data_len != 0) { |
|
crc32c = istgt_crc32c(pdu->data, ISCSI_ALIGN(data_len)); |
|
MAKE_DIGEST_WORD(pdu->data_digest, crc32c); |
|
|
|
iovec[4].iov_len = ISCSI_DIGEST_LEN; |
|
total += ISCSI_DIGEST_LEN; |
|
} else { |
|
iovec[4].iov_len = 0; |
|
} |
|
|
|
/* write all bytes from iovec */ |
|
nbytes = total; |
|
ISTGT_TRACELOG(ISTGT_TRACE_NET, "PDU write %d\n", nbytes); |
|
errno = 0; |
|
start = time(NULL); |
|
while (nbytes > 0) { |
|
rc = writev(conn->sock, &iovec[0], 5); |
|
if (rc < 0) { |
|
now = time(NULL); |
|
ISTGT_ERRLOG("writev() failed (errno=%d,%s,time=%d)\n", |
|
errno, conn->initiator_name, (int)difftime(now, start)); |
|
return -1; |
|
} |
|
nbytes -= rc; |
|
if (nbytes == 0) |
|
break; |
|
/* adjust iovec length */ |
|
for (i = 0; i < 5; i++) { |
|
if (iovec[i].iov_len != 0 && iovec[i].iov_len > (size_t)rc) { |
|
iovec[i].iov_base |
|
= (void *) (((uintptr_t)iovec[i].iov_base) + rc); |
|
iovec[i].iov_len -= rc; |
|
break; |
|
} else { |
|
rc -= iovec[i].iov_len; |
|
iovec[i].iov_len = 0; |
|
} |
|
} |
|
} |
|
|
|
return total; |
|
} |
|
#endif /* defined (ISTGT_USE_IOVEC) */ |
|
|
int |
int |
istgt_iscsi_copy_pdu(ISCSI_PDU_Ptr dst_pdu, ISCSI_PDU_Ptr src_pdu) |
istgt_iscsi_copy_pdu(ISCSI_PDU_Ptr dst_pdu, ISCSI_PDU_Ptr src_pdu) |
{ |
{ |
Line 3239 istgt_iscsi_op_scsi(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 3558 istgt_iscsi_op_scsi(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
if (SN32_GT(CmdSN, conn->sess->ExpCmdSN)) { |
if (SN32_GT(CmdSN, conn->sess->ExpCmdSN)) { |
if (conn->sess->connections > 1) { |
if (conn->sess->connections > 1) { |
struct timespec abstime; |
struct timespec abstime; |
time_t now; | time_t start, now; |
|
|
SESS_MTX_UNLOCK(conn); |
SESS_MTX_UNLOCK(conn); |
now = time(NULL); | start = now = time(NULL); |
memset(&abstime, 0, sizeof abstime); |
memset(&abstime, 0, sizeof abstime); |
abstime.tv_sec = now + (MAX_MCSREVWAIT / 1000); |
abstime.tv_sec = now + (MAX_MCSREVWAIT / 1000); |
abstime.tv_nsec = (MAX_MCSREVWAIT % 1000) * 1000000; |
abstime.tv_nsec = (MAX_MCSREVWAIT % 1000) * 1000000; |
Line 3269 istgt_iscsi_op_scsi(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 3588 istgt_iscsi_op_scsi(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
} |
} |
} |
} |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("MCS: CmdSN(%u) error ExpCmdSN=%u\n", | now = time(NULL); |
CmdSN, conn->sess->ExpCmdSN); | ISTGT_ERRLOG("MCS: CmdSN(%u) error ExpCmdSN=%u " |
| "(time=%d)\n", |
| CmdSN, conn->sess->ExpCmdSN, |
| (int)difftime(now, start)); |
SESS_MTX_UNLOCK(conn); |
SESS_MTX_UNLOCK(conn); |
return -1; |
return -1; |
} |
} |
Line 5162 worker(void *arg)
|
Line 5484 worker(void *arg)
|
return NULL; |
return NULL; |
} |
} |
conn->kq = kq; |
conn->kq = kq; |
|
#if defined (ISTGT_USE_IOVEC) && defined (NOTE_LOWAT) |
|
ISTGT_EV_SET(&kev, conn->sock, EVFILT_READ, EV_ADD, NOTE_LOWAT, ISCSI_BHS_LEN, NULL); |
|
#else |
ISTGT_EV_SET(&kev, conn->sock, EVFILT_READ, EV_ADD, 0, 0, NULL); |
ISTGT_EV_SET(&kev, conn->sock, EVFILT_READ, EV_ADD, 0, 0, NULL); |
|
#endif |
rc = kevent(kq, &kev, 1, NULL, 0, NULL); |
rc = kevent(kq, &kev, 1, NULL, 0, NULL); |
if (rc == -1) { |
if (rc == -1) { |
ISTGT_ERRLOG("kevent() failed\n"); |
ISTGT_ERRLOG("kevent() failed\n"); |
Line 5351 worker(void *arg)
|
Line 5677 worker(void *arg)
|
conn->pdu.copy_pdu = 0; |
conn->pdu.copy_pdu = 0; |
rc = istgt_iscsi_read_pdu(conn, &conn->pdu); |
rc = istgt_iscsi_read_pdu(conn, &conn->pdu); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("conn->state = %d\n", conn->state); | if (conn->state != CONN_STATE_EXITING) { |
| ISTGT_ERRLOG("conn->state = %d\n", conn->state); |
| } |
if (conn->state != CONN_STATE_RUNNING) { |
if (conn->state != CONN_STATE_RUNNING) { |
if (errno == EINPROGRESS) { |
if (errno == EINPROGRESS) { |
sleep(1); |
sleep(1); |
Line 5788 istgt_create_conn(ISTGT_Ptr istgt, PORTAL_Ptr portal,
|
Line 6116 istgt_create_conn(ISTGT_Ptr istgt, PORTAL_Ptr portal,
|
ISTGT_ERRLOG("istgt_set_sendtimeo() failed\n"); |
ISTGT_ERRLOG("istgt_set_sendtimeo() failed\n"); |
goto error_return; |
goto error_return; |
} |
} |
|
#if defined (ISTGT_USE_IOVEC) |
|
/* set low water mark */ |
|
rc = istgt_set_recvlowat(conn->sock, ISCSI_BHS_LEN); |
|
if (rc != 0) { |
|
ISTGT_ERRLOG("istgt_set_recvlowat() failed\n"); |
|
goto error_return; |
|
} |
|
#endif |
|
|
rc = pipe(conn->task_pipe); |
rc = pipe(conn->task_pipe); |
if (rc != 0) { |
if (rc != 0) { |