Merge branch 'tst'
This commit is contained in:
109
lib/socket.c
109
lib/socket.c
@@ -62,6 +62,10 @@
|
||||
#include <sys/uio.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PTHREAD
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -88,7 +92,7 @@ union socket_address {
|
||||
void
|
||||
iscsi_add_to_outqueue(struct iscsi_context *iscsi, struct iscsi_pdu *pdu)
|
||||
{
|
||||
struct iscsi_pdu *current = iscsi->outqueue;
|
||||
struct iscsi_pdu *current;
|
||||
struct iscsi_pdu *last = NULL;
|
||||
|
||||
if (iscsi->scsi_timeout > 0) {
|
||||
@@ -97,12 +101,15 @@ iscsi_add_to_outqueue(struct iscsi_context *iscsi, struct iscsi_pdu *pdu)
|
||||
pdu->scsi_timeout = 0;
|
||||
}
|
||||
|
||||
if (iscsi->outqueue == NULL) {
|
||||
iscsi_mt_spin_lock(&iscsi->iscsi_lock);
|
||||
|
||||
current = iscsi->outqueue;
|
||||
if (iscsi->outqueue == NULL) {
|
||||
iscsi->outqueue = pdu;
|
||||
pdu->next = NULL;
|
||||
return;
|
||||
goto finished;
|
||||
}
|
||||
|
||||
|
||||
/* queue pdus in ascending order of CmdSN.
|
||||
* ensure that pakets with the same CmdSN are kept in FIFO order.
|
||||
* immediate PDUs are queued in front of queue with the CmdSN
|
||||
@@ -126,22 +133,37 @@ iscsi_add_to_outqueue(struct iscsi_context *iscsi, struct iscsi_pdu *pdu)
|
||||
(pdu->outdata.data[0] & ISCSI_PDU_IMMEDIATE && !(current->outdata.data[0] & ISCSI_PDU_IMMEDIATE))) {
|
||||
/* insert PDU before the current */
|
||||
if (last != NULL) {
|
||||
last->next=pdu;
|
||||
last->next = pdu;
|
||||
} else {
|
||||
iscsi->outqueue=pdu;
|
||||
iscsi->outqueue = pdu;
|
||||
}
|
||||
pdu->next = current;
|
||||
return;
|
||||
goto finished;
|
||||
}
|
||||
last=current;
|
||||
current=current->next;
|
||||
last = current;
|
||||
current = current->next;
|
||||
} while (current != NULL);
|
||||
|
||||
last->next = pdu;
|
||||
pdu->next = NULL;
|
||||
|
||||
finished:
|
||||
iscsi_mt_spin_unlock(&iscsi->iscsi_lock);
|
||||
|
||||
/* TODO QQQ need to immediately send for the non multithreading case too
|
||||
* and for the Windows API too */
|
||||
#if defined(HAVE_MULTITHREADING) && defined(HAVE_PTHREAD)
|
||||
if(iscsi->multithreading_enabled) {
|
||||
if (current == NULL && pdu == iscsi->outqueue) {
|
||||
pthread_kill(iscsi->service_thread, SIGUSR1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
void iscsi_decrement_iface_rr() {
|
||||
/* TODO QQQ use an atomic here */
|
||||
iface_rr--;
|
||||
}
|
||||
|
||||
@@ -484,14 +506,16 @@ iscsi_tcp_which_events(struct iscsi_context *iscsi)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (iscsi->outqueue_current != NULL ||
|
||||
(iscsi->outqueue != NULL && !iscsi->is_corked &&
|
||||
iscsi_mt_spin_lock(&iscsi->iscsi_lock);
|
||||
if (iscsi->outqueue_current ||
|
||||
(iscsi->outqueue && !iscsi->is_corked &&
|
||||
(iscsi_serial32_compare(iscsi->outqueue->cmdsn, iscsi->maxcmdsn) <= 0 ||
|
||||
iscsi->outqueue->outdata.data[0] & ISCSI_PDU_IMMEDIATE)
|
||||
)
|
||||
) {
|
||||
events |= POLLOUT;
|
||||
}
|
||||
iscsi_mt_spin_unlock(&iscsi->iscsi_lock);
|
||||
return events;
|
||||
}
|
||||
|
||||
@@ -507,6 +531,7 @@ iscsi_queue_length(struct iscsi_context *iscsi)
|
||||
int i = 0;
|
||||
struct iscsi_pdu *pdu;
|
||||
|
||||
iscsi_mt_spin_lock(&iscsi->iscsi_lock);
|
||||
for (pdu = iscsi->outqueue; pdu; pdu = pdu->next) {
|
||||
i++;
|
||||
}
|
||||
@@ -516,6 +541,7 @@ iscsi_queue_length(struct iscsi_context *iscsi)
|
||||
if (iscsi->is_connected == 0) {
|
||||
i++;
|
||||
}
|
||||
iscsi_mt_spin_unlock(&iscsi->iscsi_lock);
|
||||
|
||||
return i;
|
||||
}
|
||||
@@ -526,9 +552,11 @@ iscsi_out_queue_length(struct iscsi_context *iscsi)
|
||||
int i = 0;
|
||||
struct iscsi_pdu *pdu;
|
||||
|
||||
iscsi_mt_spin_lock(&iscsi->iscsi_lock);
|
||||
for (pdu = iscsi->outqueue; pdu; pdu = pdu->next) {
|
||||
i++;
|
||||
}
|
||||
iscsi_mt_spin_unlock(&iscsi->iscsi_lock);
|
||||
|
||||
return i;
|
||||
}
|
||||
@@ -653,20 +681,23 @@ iscsi_read_from_socket(struct iscsi_context *iscsi)
|
||||
struct iscsi_in_pdu *in;
|
||||
ssize_t hdr_size, data_size, count, padding_size;
|
||||
bool do_data_digest = (iscsi->data_digest != ISCSI_DATA_DIGEST_NONE);
|
||||
|
||||
int ret = -1;
|
||||
|
||||
do {
|
||||
hdr_size = ISCSI_HEADER_SIZE(iscsi->header_digest);
|
||||
if (iscsi->incoming == NULL) {
|
||||
iscsi->incoming = iscsi_szmalloc(iscsi, sizeof(struct iscsi_in_pdu));
|
||||
iscsi->incoming = iscsi_zmalloc(iscsi, sizeof(struct iscsi_in_pdu));
|
||||
if (iscsi->incoming == NULL) {
|
||||
iscsi_set_error(iscsi, "Out-of-memory: failed to malloc iscsi_in_pdu");
|
||||
return -1;
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
if (iscsi->incoming->hdr == NULL) {
|
||||
crc32c_init(&(iscsi->incoming->calculated_data_digest));
|
||||
iscsi->incoming->hdr = iscsi_smalloc(iscsi, hdr_size);
|
||||
iscsi->incoming->hdr = iscsi_malloc(iscsi, hdr_size);
|
||||
if (iscsi->incoming->hdr == NULL) {
|
||||
iscsi_set_error(iscsi, "Out-of-memory");
|
||||
return -1;
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
in = iscsi->incoming;
|
||||
@@ -681,7 +712,7 @@ iscsi_read_from_socket(struct iscsi_context *iscsi)
|
||||
count, 0);
|
||||
if (count == 0) {
|
||||
/* remote side has closed the socket. */
|
||||
return -1;
|
||||
goto finished;
|
||||
}
|
||||
if (count < 0) {
|
||||
if (errno == EINTR || errno == EAGAIN) {
|
||||
@@ -689,7 +720,7 @@ iscsi_read_from_socket(struct iscsi_context *iscsi)
|
||||
}
|
||||
iscsi_set_error(iscsi, "read from socket failed, "
|
||||
"errno:%d", errno);
|
||||
return -1;
|
||||
goto finished;
|
||||
}
|
||||
in->hdr_pos += count;
|
||||
}
|
||||
@@ -704,7 +735,7 @@ iscsi_read_from_socket(struct iscsi_context *iscsi)
|
||||
|
||||
if (data_size < 0 || data_size > (ssize_t)iscsi->initiator_max_recv_data_segment_length) {
|
||||
iscsi_set_error(iscsi, "Invalid data size received from target (%d)", (int)data_size);
|
||||
return -1;
|
||||
goto finished;
|
||||
}
|
||||
if (data_size != 0) {
|
||||
unsigned char padding_buf[3];
|
||||
@@ -724,7 +755,7 @@ iscsi_read_from_socket(struct iscsi_context *iscsi)
|
||||
in->data = iscsi_malloc(iscsi, data_size);
|
||||
if (in->data == NULL) {
|
||||
iscsi_set_error(iscsi, "Out-of-memory: failed to malloc iscsi_in_pdu->data(%d)", (int)data_size);
|
||||
return -1;
|
||||
goto finished;
|
||||
}
|
||||
}
|
||||
buf = &in->data[in->data_pos];
|
||||
@@ -735,13 +766,13 @@ iscsi_read_from_socket(struct iscsi_context *iscsi)
|
||||
}
|
||||
if (count == 0) {
|
||||
/* remote side has closed the socket. */
|
||||
return -1;
|
||||
goto finished;
|
||||
}
|
||||
if (count < 0) {
|
||||
if (errno == EINTR || errno == EAGAIN) {
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
goto finished;
|
||||
}
|
||||
in->data_pos += count;
|
||||
}
|
||||
@@ -757,13 +788,13 @@ iscsi_read_from_socket(struct iscsi_context *iscsi)
|
||||
count = recv(iscsi->fd, (void *)(in->data_digest_buf + in->received_data_digest_bytes), ISCSI_DIGEST_SIZE - in->received_data_digest_bytes, 0);
|
||||
if (count == 0) {
|
||||
/* remote side has closed the socket. */
|
||||
return -1;
|
||||
goto finished;
|
||||
}
|
||||
if (count < 0) {
|
||||
if (errno == EINTR || errno == EAGAIN) {
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
goto finished;
|
||||
}
|
||||
in->received_data_digest_bytes += count;
|
||||
|
||||
@@ -772,15 +803,17 @@ iscsi_read_from_socket(struct iscsi_context *iscsi)
|
||||
}
|
||||
}
|
||||
|
||||
iscsi->incoming = NULL;
|
||||
iscsi->incoming = NULL;
|
||||
if (iscsi_process_pdu(iscsi, in) != 0) {
|
||||
iscsi_free_iscsi_in_pdu(iscsi, in);
|
||||
return -1;
|
||||
goto finished;
|
||||
}
|
||||
iscsi_free_iscsi_in_pdu(iscsi, in);
|
||||
} while (iscsi->tcp_nonblocking && iscsi->waitpdu && iscsi->is_loggedin);
|
||||
} while (iscsi->tcp_nonblocking && iscsi->waitpdu && iscsi->is_loggedin); //QQQ break the loop
|
||||
|
||||
return 0;
|
||||
ret = 0;
|
||||
finished:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int iscsi_pdu_update_headerdigest(struct iscsi_context *iscsi, struct iscsi_pdu *pdu)
|
||||
@@ -823,7 +856,7 @@ iscsi_write_to_socket(struct iscsi_context *iscsi)
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (iscsi->outqueue != NULL || iscsi->outqueue_current != NULL) {
|
||||
while (iscsi->outqueue || iscsi->outqueue_current) {
|
||||
if (iscsi->outqueue_current == NULL) {
|
||||
if (iscsi->is_corked) {
|
||||
/* connection is corked we are not allowed to send
|
||||
@@ -848,6 +881,8 @@ iscsi_write_to_socket(struct iscsi_context *iscsi)
|
||||
iscsi->outqueue->cmdsn, iscsi->expcmdsn, iscsi->outqueue->outdata.data[0] & 0x3f);
|
||||
return -1;
|
||||
}
|
||||
|
||||
iscsi_mt_spin_lock(&iscsi->iscsi_lock);
|
||||
iscsi->outqueue_current = iscsi->outqueue;
|
||||
|
||||
/* set exp statsn */
|
||||
@@ -856,6 +891,7 @@ iscsi_write_to_socket(struct iscsi_context *iscsi)
|
||||
/* calculate header checksum */
|
||||
if (iscsi->header_digest != ISCSI_HEADER_DIGEST_NONE &&
|
||||
iscsi_pdu_update_headerdigest(iscsi, iscsi->outqueue_current) != 0) {
|
||||
iscsi_mt_spin_unlock(&iscsi->iscsi_lock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -867,6 +903,7 @@ iscsi_write_to_socket(struct iscsi_context *iscsi)
|
||||
cmd PDU the R2T might get lost otherwise. */
|
||||
ISCSI_LIST_ADD_END(&iscsi->waitpdu, iscsi->outqueue_current);
|
||||
}
|
||||
iscsi_mt_spin_unlock(&iscsi->iscsi_lock);
|
||||
}
|
||||
|
||||
pdu = iscsi->outqueue_current;
|
||||
@@ -1109,6 +1146,7 @@ iscsi_tcp_service(struct iscsi_context *iscsi, int revents)
|
||||
return iscsi_service_reconnect_if_loggedin(iscsi);
|
||||
}
|
||||
}
|
||||
|
||||
if (revents & POLLOUT) {
|
||||
if (iscsi_write_to_socket(iscsi) != 0) {
|
||||
ISCSI_LOG(iscsi, 1, "%s", iscsi_get_error(iscsi));
|
||||
@@ -1132,26 +1170,19 @@ iscsi_service(struct iscsi_context *iscsi, int revents)
|
||||
return iscsi->drv->service(iscsi, revents);
|
||||
}
|
||||
|
||||
static int iscsi_tcp_queue_pdu(struct iscsi_context *iscsi,
|
||||
static void iscsi_tcp_queue_pdu(struct iscsi_context *iscsi,
|
||||
struct iscsi_pdu *pdu)
|
||||
{
|
||||
if (pdu == NULL) {
|
||||
iscsi_set_error(iscsi, "trying to queue NULL pdu");
|
||||
return -1;
|
||||
}
|
||||
|
||||
iscsi_add_to_outqueue(iscsi, pdu);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
iscsi_free_iscsi_in_pdu(struct iscsi_context *iscsi, struct iscsi_in_pdu *in)
|
||||
{
|
||||
iscsi_sfree(iscsi, in->hdr);
|
||||
iscsi_free(iscsi, in->hdr);
|
||||
iscsi_free(iscsi, in->data);
|
||||
in->data=NULL;
|
||||
iscsi_sfree(iscsi, in);
|
||||
iscsi_free(iscsi, in);
|
||||
in=NULL;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user