@@ -229,11 +229,6 @@ struct iscsi_pdu {
|
||||
#define ISCSI_PDU_DROP_ON_RECONNECT 0x00000004
|
||||
/* stop sending after this PDU has been sent */
|
||||
#define ISCSI_PDU_CORK_WHEN_SENT 0x00000008
|
||||
/* put this immediate delivery PDU in front of outqueue.
|
||||
* This is currently only used for immediate logout requests
|
||||
* as answer to an async logout event. */
|
||||
#define ISCSI_PDU_URGENT_DELIVERY 0x00000010
|
||||
|
||||
|
||||
uint32_t flags;
|
||||
|
||||
@@ -371,10 +366,6 @@ uint32_t iscsi_itt_post_increment(struct iscsi_context *iscsi);
|
||||
|
||||
void iscsi_timeout_scan(struct iscsi_context *iscsi);
|
||||
|
||||
int
|
||||
iscsi_logout_async_internal(struct iscsi_context *iscsi, iscsi_command_cb cb,
|
||||
void *private_data, uint32_t flags);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -115,9 +115,6 @@ iscsi_send_data_out(struct iscsi_context *iscsi, struct iscsi_pdu *cmd_pdu,
|
||||
/* ttt */
|
||||
iscsi_pdu_set_ttt(pdu, ttt);
|
||||
|
||||
/* exp statsn */
|
||||
iscsi_pdu_set_expstatsn(pdu, iscsi->statsn+1);
|
||||
|
||||
/* data sn */
|
||||
iscsi_pdu_set_datasn(pdu, cmd_pdu->datasn++);
|
||||
|
||||
@@ -305,13 +302,8 @@ iscsi_scsi_command_async(struct iscsi_context *iscsi, int lun,
|
||||
iscsi_pdu_set_expxferlen(pdu, task->expxferlen);
|
||||
|
||||
/* cmdsn */
|
||||
iscsi_pdu_set_cmdsn(pdu, iscsi->cmdsn);
|
||||
pdu->cmdsn = iscsi->cmdsn;
|
||||
iscsi->cmdsn++;
|
||||
iscsi_pdu_set_cmdsn(pdu, iscsi->cmdsn++);
|
||||
|
||||
/* exp statsn */
|
||||
iscsi_pdu_set_expstatsn(pdu, iscsi->statsn+1);
|
||||
|
||||
/* cdb */
|
||||
iscsi_pdu_set_cdb(pdu, task);
|
||||
|
||||
|
||||
35
lib/login.c
35
lib/login.c
@@ -790,6 +790,13 @@ iscsi_login_async(struct iscsi_context *iscsi, iscsi_command_cb cb,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* randomize cmdsn and itt */
|
||||
if (!iscsi->current_phase && !iscsi->secneg_phase) {
|
||||
iscsi->itt = (u_int32_t) rand();
|
||||
iscsi->cmdsn = (u_int32_t) rand();
|
||||
iscsi->expcmdsn = iscsi->maxcmdsn = iscsi->cmdsn;
|
||||
}
|
||||
|
||||
pdu = iscsi_allocate_pdu(iscsi,
|
||||
ISCSI_PDU_LOGIN_REQUEST,
|
||||
ISCSI_PDU_LOGIN_RESPONSE,
|
||||
@@ -804,6 +811,9 @@ iscsi_login_async(struct iscsi_context *iscsi, iscsi_command_cb cb,
|
||||
/* login request */
|
||||
iscsi_pdu_set_immediate(pdu);
|
||||
|
||||
/* cmdsn is not increased if Immediate delivery*/
|
||||
iscsi_pdu_set_cmdsn(pdu, iscsi->cmdsn);
|
||||
|
||||
if (!iscsi->user[0]) {
|
||||
iscsi->current_phase = ISCSI_PDU_LOGIN_CSG_OPNEG;
|
||||
}
|
||||
@@ -1034,7 +1044,13 @@ iscsi_process_login_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
||||
|
||||
status = scsi_get_uint16(&in->hdr[36]);
|
||||
|
||||
iscsi_adjust_statsn(iscsi, in);
|
||||
// Status-Class is 0
|
||||
if (!(status >> 8)) {
|
||||
if (!iscsi->current_phase && !iscsi->secneg_phase) {
|
||||
iscsi->statsn = scsi_get_uint32(&in->hdr[24]);
|
||||
}
|
||||
iscsi_adjust_statsn(iscsi, in);
|
||||
}
|
||||
iscsi_adjust_maxexpcmdsn(iscsi, in);
|
||||
|
||||
/* Using bidirectional CHAP? Then we must see a chap_n and chap_r
|
||||
@@ -1236,8 +1252,8 @@ iscsi_process_login_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
||||
}
|
||||
|
||||
int
|
||||
iscsi_logout_async_internal(struct iscsi_context *iscsi, iscsi_command_cb cb,
|
||||
void *private_data, uint32_t flags)
|
||||
iscsi_logout_async(struct iscsi_context *iscsi, iscsi_command_cb cb,
|
||||
void *private_data)
|
||||
{
|
||||
struct iscsi_pdu *pdu;
|
||||
|
||||
@@ -1252,7 +1268,7 @@ iscsi_logout_async_internal(struct iscsi_context *iscsi, iscsi_command_cb cb,
|
||||
ISCSI_PDU_LOGOUT_REQUEST,
|
||||
ISCSI_PDU_LOGOUT_RESPONSE,
|
||||
iscsi_itt_post_increment(iscsi),
|
||||
ISCSI_PDU_DROP_ON_RECONNECT|ISCSI_PDU_CORK_WHEN_SENT|flags);
|
||||
ISCSI_PDU_DROP_ON_RECONNECT|ISCSI_PDU_CORK_WHEN_SENT);
|
||||
if (pdu == NULL) {
|
||||
iscsi_set_error(iscsi, "Out-of-memory: Failed to allocate "
|
||||
"logout pdu.");
|
||||
@@ -1267,10 +1283,6 @@ iscsi_logout_async_internal(struct iscsi_context *iscsi, iscsi_command_cb cb,
|
||||
|
||||
/* 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);
|
||||
|
||||
pdu->callback = cb;
|
||||
pdu->private_data = private_data;
|
||||
@@ -1285,13 +1297,6 @@ iscsi_logout_async_internal(struct iscsi_context *iscsi, iscsi_command_cb cb,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
iscsi_logout_async(struct iscsi_context *iscsi, iscsi_command_cb cb,
|
||||
void *private_data)
|
||||
{
|
||||
return iscsi_logout_async_internal(iscsi, cb, private_data, 0);
|
||||
}
|
||||
|
||||
int
|
||||
iscsi_process_logout_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
||||
struct iscsi_in_pdu *in)
|
||||
|
||||
32
lib/nop.c
32
lib/nop.c
@@ -46,9 +46,6 @@ iscsi_nop_out_async(struct iscsi_context *iscsi, iscsi_command_cb cb,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* immediate flag */
|
||||
iscsi_pdu_set_immediate(pdu);
|
||||
|
||||
/* flags */
|
||||
iscsi_pdu_set_pduflags(pdu, 0x80);
|
||||
|
||||
@@ -58,12 +55,8 @@ iscsi_nop_out_async(struct iscsi_context *iscsi, iscsi_command_cb cb,
|
||||
/* 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);
|
||||
/* cmdsn */
|
||||
iscsi_pdu_set_cmdsn(pdu, iscsi->cmdsn++);
|
||||
|
||||
pdu->callback = cb;
|
||||
pdu->private_data = private_data;
|
||||
@@ -83,7 +76,9 @@ iscsi_nop_out_async(struct iscsi_context *iscsi, iscsi_command_cb cb,
|
||||
}
|
||||
|
||||
iscsi->nops_in_flight++;
|
||||
ISCSI_LOG(iscsi, 6, "NOP Out Send (nops_in_flight: %d)", iscsi->nops_in_flight);
|
||||
ISCSI_LOG(iscsi, (iscsi->nops_in_flight > 1) ? 1 : 6,
|
||||
"NOP Out Send (nops_in_flight: %d, pdu->cmdsn %08x, pdu->itt %08x, pdu->ttt %08x, iscsi->maxcmdsn %08x, iscsi->expcmdsn %08x)",
|
||||
iscsi->nops_in_flight, pdu->cmdsn, pdu->itt, 0xffffffff, iscsi->maxcmdsn, iscsi->expcmdsn);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -117,10 +112,6 @@ iscsi_send_target_nop_out(struct iscsi_context *iscsi, uint32_t ttt)
|
||||
|
||||
/* 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");
|
||||
@@ -128,6 +119,10 @@ iscsi_send_target_nop_out(struct iscsi_context *iscsi, uint32_t ttt)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ISCSI_LOG(iscsi, (iscsi->nops_in_flight > 1) ? 1 : 6,
|
||||
"NOP Out Send (nops_in_flight: %d, pdu->cmdsn %08x, pdu->itt %08x, pdu->ttt %08x, iscsi->maxcmdsn %08x, iscsi->expcmdsn %08x)",
|
||||
iscsi->nops_in_flight, pdu->cmdsn, 0xffffffff, ttt, iscsi->maxcmdsn, iscsi->expcmdsn);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -137,9 +132,14 @@ iscsi_process_nop_out_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
||||
{
|
||||
struct iscsi_data data;
|
||||
|
||||
iscsi->nops_in_flight = 0;
|
||||
iscsi_adjust_maxexpcmdsn(iscsi, in);
|
||||
iscsi_adjust_statsn(iscsi, in);
|
||||
|
||||
ISCSI_LOG(iscsi, 6, "NOP Out Reply received");
|
||||
ISCSI_LOG(iscsi, (iscsi->nops_in_flight > 1) ? 1 : 6,
|
||||
"NOP-In received (pdu->itt %08x, pdu->ttt %08x, iscsi->maxcmdsn %08x, iscsi->expcmdsn %08x, iscsi->statsn %08x)",
|
||||
pdu->itt, 0xffffffff, iscsi->maxcmdsn, iscsi->expcmdsn, iscsi->statsn);
|
||||
|
||||
iscsi->nops_in_flight = 0;
|
||||
|
||||
if (pdu->callback == NULL) {
|
||||
return 0;
|
||||
|
||||
17
lib/pdu.c
17
lib/pdu.c
@@ -319,11 +319,15 @@ static const char *iscsi_reject_reason_str(enum iscsi_reject_reason reason)
|
||||
int iscsi_process_target_nop_in(struct iscsi_context *iscsi,
|
||||
struct iscsi_in_pdu *in)
|
||||
{
|
||||
uint32_t ttt;
|
||||
|
||||
ttt = scsi_get_uint32(&in->hdr[20]);
|
||||
uint32_t ttt = scsi_get_uint32(&in->hdr[20]);
|
||||
uint32_t itt = scsi_get_uint32(&in->hdr[16]);
|
||||
|
||||
iscsi_adjust_statsn(iscsi, in);
|
||||
iscsi_adjust_maxexpcmdsn(iscsi, in);
|
||||
|
||||
ISCSI_LOG(iscsi, (iscsi->nops_in_flight > 1) ? 1 : 6,
|
||||
"NOP-In received (pdu->itt %08x, pdu->ttt %08x, iscsi->maxcmdsn %08x, iscsi->expcmdsn %08x, iscsi->statsn %08x)",
|
||||
itt, ttt, iscsi->maxcmdsn, iscsi->expcmdsn, iscsi->statsn);
|
||||
|
||||
/* if the server does not want a response */
|
||||
if (ttt == 0xffffffff) {
|
||||
@@ -365,7 +369,7 @@ int iscsi_process_reject(struct iscsi_context *iscsi,
|
||||
|
||||
if (reason == ISCSI_REJECT_WAITING_FOR_LOGOUT) {
|
||||
ISCSI_LOG(iscsi, 1, "target rejects request with reason: %s", iscsi_reject_reason_str(reason));
|
||||
iscsi_logout_async_internal(iscsi, iscsi_reconnect_after_logout, NULL, ISCSI_PDU_URGENT_DELIVERY);
|
||||
iscsi_logout_async(iscsi, iscsi_reconnect_after_logout, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -435,7 +439,7 @@ iscsi_process_pdu(struct iscsi_context *iscsi, struct iscsi_in_pdu *in)
|
||||
ISCSI_LOG(iscsi, 2, "dropping connection to fix errors with broken DELL Equallogic firmware 7.x");
|
||||
return -1;
|
||||
}
|
||||
iscsi_logout_async_internal(iscsi, iscsi_reconnect_after_logout, NULL, ISCSI_PDU_URGENT_DELIVERY);
|
||||
iscsi_logout_async(iscsi, iscsi_reconnect_after_logout, NULL);
|
||||
return 0;
|
||||
case 0x2:
|
||||
ISCSI_LOG(iscsi, 2, "target will drop this connection. Time2Wait is %u seconds", param2);
|
||||
@@ -447,7 +451,7 @@ iscsi_process_pdu(struct iscsi_context *iscsi, struct iscsi_in_pdu *in)
|
||||
return 0;
|
||||
case 0x4:
|
||||
ISCSI_LOG(iscsi, 2, "target requests parameter renogitiation.");
|
||||
iscsi_logout_async_internal(iscsi, iscsi_reconnect_after_logout, NULL, ISCSI_PDU_DROP_ON_RECONNECT);
|
||||
iscsi_logout_async(iscsi, iscsi_reconnect_after_logout, NULL);
|
||||
return 0;
|
||||
default:
|
||||
ISCSI_LOG(iscsi, 1, "unhandled async event %u: param1 %u param2 %u param3 %u", event, param1, param2, param3);
|
||||
@@ -621,6 +625,7 @@ void
|
||||
iscsi_pdu_set_cmdsn(struct iscsi_pdu *pdu, uint32_t cmdsn)
|
||||
{
|
||||
scsi_set_uint32(&pdu->outdata.data[24], cmdsn);
|
||||
pdu->cmdsn = cmdsn;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
26
lib/socket.c
26
lib/socket.c
@@ -92,10 +92,17 @@ iscsi_add_to_outqueue(struct iscsi_context *iscsi, struct iscsi_pdu *pdu)
|
||||
|
||||
/* 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
|
||||
* of the first element in the outqueue.
|
||||
*/
|
||||
|
||||
if (pdu->outdata.data[0] & ISCSI_PDU_IMMEDIATE) {
|
||||
iscsi_pdu_set_cmdsn(pdu, current->cmdsn);
|
||||
}
|
||||
|
||||
do {
|
||||
if (iscsi_serial32_compare(pdu->cmdsn, current->cmdsn) < 0 ||
|
||||
pdu->flags & ISCSI_PDU_URGENT_DELIVERY) {
|
||||
(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;
|
||||
@@ -386,7 +393,10 @@ iscsi_which_events(struct iscsi_context *iscsi)
|
||||
|
||||
if (iscsi->outqueue_current != NULL ||
|
||||
(iscsi->outqueue != NULL && !iscsi->is_corked &&
|
||||
iscsi_serial32_compare(iscsi->outqueue->cmdsn, iscsi->maxcmdsn) <= 0)) {
|
||||
(iscsi_serial32_compare(iscsi->outqueue->cmdsn, iscsi->maxcmdsn) <= 0 ||
|
||||
iscsi->outqueue->outdata.data[0] & ISCSI_PDU_IMMEDIATE)
|
||||
)
|
||||
) {
|
||||
events |= POLLOUT;
|
||||
}
|
||||
return events;
|
||||
@@ -639,13 +649,19 @@ iscsi_write_to_socket(struct iscsi_context *iscsi)
|
||||
iscsi->outqueue->cmdsn, iscsi->maxcmdsn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* pop first element of the outqueue */
|
||||
if (iscsi_serial32_compare(iscsi->outqueue->cmdsn, iscsi->expcmdsn) < 0) {
|
||||
iscsi_set_error(iscsi, "iscsi_write_to_scoket: outqueue[0]->cmdsn < expcmdsn (%08x < %08x)",
|
||||
iscsi->outqueue->cmdsn, iscsi->expcmdsn);
|
||||
if (iscsi_serial32_compare(iscsi->outqueue->cmdsn, iscsi->expcmdsn) < 0 &&
|
||||
(iscsi->outqueue->outdata.data[0] & 0x3f) != ISCSI_PDU_DATA_OUT) {
|
||||
iscsi_set_error(iscsi, "iscsi_write_to_scoket: outqueue[0]->cmdsn < expcmdsn (%08x < %08x) opcode %02x",
|
||||
iscsi->outqueue->cmdsn, iscsi->expcmdsn, iscsi->outqueue->outdata.data[0] & 0x3f);
|
||||
return -1;
|
||||
}
|
||||
iscsi->outqueue_current = iscsi->outqueue;
|
||||
|
||||
/* set exp statsn */
|
||||
iscsi_pdu_set_expstatsn(iscsi->outqueue_current, iscsi->statsn + 1);
|
||||
|
||||
ISCSI_LIST_REMOVE(&iscsi->outqueue, iscsi->outqueue_current);
|
||||
if (!(iscsi->outqueue_current->flags & ISCSI_PDU_DELETE_WHEN_SENT)) {
|
||||
/* we have to add the pdu to the waitqueue already here
|
||||
|
||||
@@ -73,7 +73,6 @@ iscsi_task_mgmt_async(struct iscsi_context *iscsi,
|
||||
|
||||
/* cmdsn is not increased if Immediate delivery*/
|
||||
iscsi_pdu_set_cmdsn(pdu, iscsi->cmdsn);
|
||||
pdu->cmdsn = iscsi->cmdsn;
|
||||
|
||||
/* rcmdsn */
|
||||
iscsi_pdu_set_rcmdsn(pdu, rcmdsn);
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <getopt.h>
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include "iscsi.h"
|
||||
#include "scsi-lowlevel.h"
|
||||
|
||||
@@ -33,7 +34,11 @@
|
||||
|
||||
#define VERSION "0.1"
|
||||
|
||||
#define NOP_INTERVAL 5
|
||||
#define MAX_NOP_FAILURES 3
|
||||
|
||||
const char *initiator = "iqn.2010-11.libiscsi:iscsi-perf";
|
||||
int proc_alarm = 0;
|
||||
int max_in_flight = 32;
|
||||
int blocks_per_io = 8;
|
||||
uint64_t runtime = 0;
|
||||
@@ -43,6 +48,7 @@ struct client {
|
||||
int finished;
|
||||
int in_flight;
|
||||
int random;
|
||||
int random_blocks;
|
||||
|
||||
struct iscsi_context *iscsi;
|
||||
struct scsi_iovec perf_iov;
|
||||
@@ -55,6 +61,8 @@ struct client {
|
||||
uint64_t first_ns;
|
||||
uint64_t iops;
|
||||
uint64_t last_iops;
|
||||
uint64_t bytes;
|
||||
uint64_t last_bytes;
|
||||
|
||||
int ignore_errors;
|
||||
int busy_cnt;
|
||||
@@ -92,40 +100,44 @@ void progress(struct client *client) {
|
||||
if (runtime) _runtime = runtime - _runtime;
|
||||
|
||||
printf ("\r");
|
||||
uint64_t aiops = 1000000000UL * (client->iops) / (now - client->first_ns);
|
||||
uint64_t aiops = 1000000000.0 * (client->iops) / (now - client->first_ns);
|
||||
uint64_t ambps = 1000000000.0 * (client->bytes) / (now - client->first_ns);
|
||||
if (!_runtime) {
|
||||
finished = 1;
|
||||
printf ("iops average %" PRIu64 " (%" PRIu64 " MB/s) ", aiops, (aiops * blocks_per_io * client->blocksize) >> 20);
|
||||
} else {
|
||||
uint64_t iops = 1000000000UL * (client->iops - client->last_iops) / (now - client->last_ns);
|
||||
uint64_t mbps = 1000000000UL * (client->bytes - client->last_bytes) / (now - client->last_ns);
|
||||
printf ("%02" PRIu64 ":%02" PRIu64 ":%02" PRIu64 " - ", _runtime / 3600, (_runtime % 3600) / 60, _runtime % 60);
|
||||
printf ("lba %" PRIu64 ", iops current %" PRIu64 " (%" PRIu64 " MB/s), ", client->pos, iops, (iops * blocks_per_io * client->blocksize) >> 20);
|
||||
printf ("iops average %" PRIu64 " (%" PRIu64 " MB/s), in_flight %d, busy %d ", aiops, (aiops * blocks_per_io * client->blocksize) >> 20, client->in_flight, client->busy_cnt);
|
||||
printf ("lba %" PRIu64 ", iops current %" PRIu64 " (%" PRIu64 " MB/s), ", client->pos, iops, mbps >> 20);
|
||||
printf ("iops average %" PRIu64 " (%" PRIu64 " MB/s), in_flight %d, busy %d ", aiops, ambps >> 20, client->in_flight, client->busy_cnt);
|
||||
}
|
||||
fflush(stdout);
|
||||
client->last_ns = now;
|
||||
client->last_iops = client->iops;
|
||||
client->last_bytes = client->bytes;
|
||||
}
|
||||
|
||||
void cb(struct iscsi_context *iscsi _U_, int status, void *command_data, void *private_data)
|
||||
{
|
||||
struct client *client = (struct client *)private_data;
|
||||
struct scsi_task *task = command_data, *task2 = NULL;
|
||||
struct scsi_read16_cdb *read16_cdb = NULL;
|
||||
|
||||
read16_cdb = scsi_cdb_unmarshall(task, SCSI_OPCODE_READ16);
|
||||
if (read16_cdb == NULL) {
|
||||
fprintf(stderr, "Failed to unmarshall READ16 CDB.\n");
|
||||
client->err_cnt++;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (status == SCSI_STATUS_BUSY ||
|
||||
(status == SCSI_STATUS_CHECK_CONDITION && task->sense.key == SCSI_SENSE_UNIT_ATTENTION)) {
|
||||
struct scsi_read16_cdb *read16_cdb = NULL;
|
||||
if (client->retry_cnt++ > 4 * max_in_flight) {
|
||||
fprintf(stderr, "maxium number of command retries reached...\n");
|
||||
client->err_cnt++;
|
||||
goto out;
|
||||
}
|
||||
read16_cdb = scsi_cdb_unmarshall(task, SCSI_OPCODE_READ16);
|
||||
if (read16_cdb == NULL) {
|
||||
fprintf(stderr, "Failed to unmarshall READ16 CDB.\n");
|
||||
client->err_cnt++;
|
||||
goto out;
|
||||
}
|
||||
task2 = iscsi_read16_task(client->iscsi,
|
||||
client->lun, read16_cdb->lba,
|
||||
read16_cdb->transfer_length * client->blocksize,
|
||||
@@ -143,6 +155,7 @@ void cb(struct iscsi_context *iscsi _U_, int status, void *command_data, void *p
|
||||
client->err_cnt++;
|
||||
} else if (status == SCSI_STATUS_GOOD) {
|
||||
client->retry_cnt = 0;
|
||||
client->bytes += read16_cdb->transfer_length * client->blocksize;
|
||||
} else {
|
||||
fprintf(stderr, "Read16 failed with %s\n", iscsi_get_error(iscsi));
|
||||
if (!client->ignore_errors) {
|
||||
@@ -181,6 +194,10 @@ void fill_read_queue(struct client *client)
|
||||
if (num_blocks > blocks_per_io) {
|
||||
num_blocks = blocks_per_io;
|
||||
}
|
||||
|
||||
if (client->random_blocks) {
|
||||
num_blocks = rand() % num_blocks + 1;
|
||||
}
|
||||
|
||||
task = iscsi_read16_task(client->iscsi,
|
||||
client->lun, client->pos,
|
||||
@@ -202,8 +219,17 @@ void usage(void) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void sig_handler (int signum _U_) {
|
||||
finished = 1;
|
||||
void sig_handler (int signum ) {
|
||||
if (signum == SIGALRM) {
|
||||
if (proc_alarm) {
|
||||
fprintf(stderr, "\n\nABORT: Last alarm was not processed.\n");
|
||||
exit(10);
|
||||
}
|
||||
proc_alarm = 1;
|
||||
alarm(NOP_INTERVAL);
|
||||
} else {
|
||||
finished = 1;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
@@ -222,6 +248,7 @@ int main(int argc, char *argv[])
|
||||
{"blocks", required_argument, NULL, 'b'},
|
||||
{"runtime", required_argument, NULL, 't'},
|
||||
{"random", no_argument, NULL, 'r'},
|
||||
{"random-blocks", no_argument, NULL, 'R'},
|
||||
{"ignore-errors", no_argument, NULL, 'n'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
@@ -233,7 +260,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
printf("iscsi-perf version %s - (c) 2014-2015 by Peter Lieven <pl@ĸamp.de>\n\n", VERSION);
|
||||
|
||||
while ((c = getopt_long(argc, argv, "i:m:b:t:nr", long_options,
|
||||
while ((c = getopt_long(argc, argv, "i:m:b:t:nrR", long_options,
|
||||
&option_index)) != -1) {
|
||||
switch (c) {
|
||||
case 'i':
|
||||
@@ -254,6 +281,9 @@ int main(int argc, char *argv[])
|
||||
case 'r':
|
||||
client.random = 1;
|
||||
break;
|
||||
case 'R':
|
||||
client.random_blocks = 1;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unrecognized option '%c'\n\n", c);
|
||||
usage();
|
||||
@@ -324,8 +354,13 @@ int main(int argc, char *argv[])
|
||||
printf("capacity is %" PRIu64 " blocks or %" PRIu64 " byte (%" PRIu64 " MB)\n", client.num_blocks, client.num_blocks * client.blocksize,
|
||||
(client.num_blocks * client.blocksize) >> 20);
|
||||
|
||||
printf("performing %s READ with %d parallel requests\nfixed transfer size of %d blocks (%d byte)\n",
|
||||
client.random ? "random" : "sequential", max_in_flight, blocks_per_io, blocks_per_io * client.blocksize);
|
||||
printf("performing %s READ with %d parallel requests\n", client.random ? "RANDOM" : "SEQUENTIAL", max_in_flight);
|
||||
|
||||
if (client.random_blocks) {
|
||||
printf("RANDOM transfer size of 1 - %d blocks (%d - %d byte)\n", blocks_per_io, client.blocksize, blocks_per_io * client.blocksize);
|
||||
} else {
|
||||
printf("FIXED transfer size of %d blocks (%d byte)\n", blocks_per_io, blocks_per_io * client.blocksize);
|
||||
}
|
||||
|
||||
if (runtime) {
|
||||
printf("will run for %" PRIu64 " seconds.\n", runtime);
|
||||
@@ -340,6 +375,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
sigaction(SIGINT, &sa, NULL);
|
||||
sigaction(SIGTERM, &sa, NULL);
|
||||
sigaction(SIGALRM, &sa, NULL);
|
||||
|
||||
printf("\n");
|
||||
|
||||
@@ -347,10 +383,21 @@ int main(int argc, char *argv[])
|
||||
|
||||
fill_read_queue(&client);
|
||||
|
||||
alarm(NOP_INTERVAL);
|
||||
|
||||
while (client.in_flight && !client.err_cnt) {
|
||||
pfd[0].fd = iscsi_get_fd(client.iscsi);
|
||||
pfd[0].events = iscsi_which_events(client.iscsi);
|
||||
|
||||
if (proc_alarm) {
|
||||
if (iscsi_get_nops_in_flight(client.iscsi) > MAX_NOP_FAILURES) {
|
||||
fprintf(stderr, "\n\nABORT: NOP timeout.\n");
|
||||
exit(10);
|
||||
}
|
||||
iscsi_nop_out_async(client.iscsi, NULL, NULL, 0, NULL);
|
||||
proc_alarm = 0;
|
||||
}
|
||||
|
||||
if (poll(&pfd[0], 1, -1) < 0) {
|
||||
continue;
|
||||
}
|
||||
@@ -359,6 +406,8 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
alarm(0);
|
||||
|
||||
progress(&client);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user