@@ -391,6 +391,8 @@ void iscsi_tcp_free_pdu(struct iscsi_context *iscsi, struct iscsi_pdu *pdu);
|
|||||||
|
|
||||||
int iscsi_service_reconnect_if_loggedin(struct iscsi_context *iscsi);
|
int iscsi_service_reconnect_if_loggedin(struct iscsi_context *iscsi);
|
||||||
|
|
||||||
|
void iscsi_dump_pdu_header(struct iscsi_context *iscsi, unsigned char *data);
|
||||||
|
|
||||||
struct iscsi_transport {
|
struct iscsi_transport {
|
||||||
int (*connect)(struct iscsi_context *iscsi, union socket_address *sa, int ai_family);
|
int (*connect)(struct iscsi_context *iscsi, union socket_address *sa, int ai_family);
|
||||||
int (*queue_pdu)(struct iscsi_context *iscsi, struct iscsi_pdu *pdu);
|
int (*queue_pdu)(struct iscsi_context *iscsi, struct iscsi_pdu *pdu);
|
||||||
|
|||||||
@@ -378,6 +378,10 @@ void iscsi_reconnect_cb(struct iscsi_context *iscsi _U_, int status,
|
|||||||
iscsi->t->free_pdu(old_iscsi, old_iscsi->outqueue_current);
|
iscsi->t->free_pdu(old_iscsi, old_iscsi->outqueue_current);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (old_iscsi->t) {
|
||||||
|
iscsi_free(old_iscsi, old_iscsi->t);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < old_iscsi->smalloc_free; i++) {
|
for (i = 0; i < old_iscsi->smalloc_free; i++) {
|
||||||
iscsi_free(old_iscsi, old_iscsi->smalloc_ptrs[i]);
|
iscsi_free(old_iscsi, old_iscsi->smalloc_ptrs[i]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -413,6 +413,10 @@ iscsi_destroy_context(struct iscsi_context *iscsi)
|
|||||||
iscsi_destroy_context(iscsi->old_iscsi);
|
iscsi_destroy_context(iscsi->old_iscsi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (iscsi->t) {
|
||||||
|
iscsi_free(iscsi, iscsi->t);
|
||||||
|
}
|
||||||
|
|
||||||
memset(iscsi, 0, sizeof(struct iscsi_context));
|
memset(iscsi, 0, sizeof(struct iscsi_context));
|
||||||
free(iscsi);
|
free(iscsi);
|
||||||
|
|
||||||
|
|||||||
@@ -450,6 +450,9 @@ iscsi_process_scsi_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu,
|
|||||||
task->sense.key,
|
task->sense.key,
|
||||||
scsi_sense_ascq_str(task->sense.ascq),
|
scsi_sense_ascq_str(task->sense.ascq),
|
||||||
task->sense.ascq);
|
task->sense.ascq);
|
||||||
|
if (task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST) {
|
||||||
|
iscsi_dump_pdu_header(iscsi, pdu->outdata.data);
|
||||||
|
}
|
||||||
if (pdu->callback) {
|
if (pdu->callback) {
|
||||||
pdu->callback(iscsi, SCSI_STATUS_CHECK_CONDITION, task,
|
pdu->callback(iscsi, SCSI_STATUS_CHECK_CONDITION, task,
|
||||||
pdu->private_data);
|
pdu->private_data);
|
||||||
|
|||||||
@@ -3889,8 +3889,12 @@ scsi_inquiry_pagecode_to_str(int pagecode)
|
|||||||
return "UNIT_SERIAL_NUMBER";
|
return "UNIT_SERIAL_NUMBER";
|
||||||
case SCSI_INQUIRY_PAGECODE_DEVICE_IDENTIFICATION:
|
case SCSI_INQUIRY_PAGECODE_DEVICE_IDENTIFICATION:
|
||||||
return "DEVICE_IDENTIFICATION";
|
return "DEVICE_IDENTIFICATION";
|
||||||
|
case SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS:
|
||||||
|
return "BLOCK_LIMITS";
|
||||||
case SCSI_INQUIRY_PAGECODE_BLOCK_DEVICE_CHARACTERISTICS:
|
case SCSI_INQUIRY_PAGECODE_BLOCK_DEVICE_CHARACTERISTICS:
|
||||||
return "BLOCK_DEVICE_CHARACTERISTICS";
|
return "BLOCK_DEVICE_CHARACTERISTICS";
|
||||||
|
case SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING:
|
||||||
|
return "LOGICAL_BLOCK_PROVISIONING";
|
||||||
}
|
}
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -359,11 +359,13 @@ iscsi_connect_async(struct iscsi_context *iscsi, const char *portal,
|
|||||||
iscsi->socket_status_cb = cb;
|
iscsi->socket_status_cb = cb;
|
||||||
iscsi->connect_data = private_data;
|
iscsi->connect_data = private_data;
|
||||||
|
|
||||||
if(iscsi->t->connect(iscsi, &sa, ai->ai_family) < 0) {
|
if (iscsi->t->connect(iscsi, &sa, ai->ai_family) < 0) {
|
||||||
iscsi_set_error(iscsi, "Couldn't connect transport");
|
iscsi_set_error(iscsi, "Couldn't connect transport");
|
||||||
|
freeaddrinfo(ai);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
freeaddrinfo(ai);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
#include <inttypes.h>
|
||||||
#include "iscsi.h"
|
#include "iscsi.h"
|
||||||
#include "scsi-lowlevel.h"
|
#include "scsi-lowlevel.h"
|
||||||
|
|
||||||
@@ -40,34 +41,34 @@ const char *initiator = "iqn.2007-10.com.github:sahlberg:libiscsi:iscsi-inq";
|
|||||||
void inquiry_block_limits(struct scsi_inquiry_block_limits *inq)
|
void inquiry_block_limits(struct scsi_inquiry_block_limits *inq)
|
||||||
{
|
{
|
||||||
printf("wsnz:%d\n", inq->wsnz);
|
printf("wsnz:%d\n", inq->wsnz);
|
||||||
printf("maximum compare and write length:%d\n", inq->max_cmp);
|
printf("maximum compare and write length:%" PRIu8 "\n", inq->max_cmp);
|
||||||
printf("optimal transfer length granularity:%d\n", inq->opt_gran);
|
printf("optimal transfer length granularity:%" PRIu16 "\n", inq->opt_gran);
|
||||||
printf("maximum transfer length:%d\n", inq->max_xfer_len);
|
printf("maximum transfer length:%" PRIu32 "\n", inq->max_xfer_len);
|
||||||
printf("optimal transfer length:%d\n",inq->opt_xfer_len);
|
printf("optimal transfer length:%" PRIu32 "\n",inq->opt_xfer_len);
|
||||||
printf("maximum prefetch xdread xdwrite transfer length:%d\n", inq->max_prefetch);
|
printf("maximum prefetch xdread xdwrite transfer length:%" PRIu32 "\n", inq->max_prefetch);
|
||||||
printf("maximum unmap lba count:%d\n", inq->max_unmap);
|
printf("maximum unmap lba count:%" PRIu32 "\n", inq->max_unmap);
|
||||||
printf("maximum unmap block descriptor count:%d\n", inq->max_unmap_bdc);
|
printf("maximum unmap block descriptor count:%" PRIu32 "\n", inq->max_unmap_bdc);
|
||||||
printf("optimal unmap granularity:%d\n", inq->opt_unmap_gran);
|
printf("optimal unmap granularity:%" PRIu32 "\n", inq->opt_unmap_gran);
|
||||||
printf("ugavalid:%d\n", inq->ugavalid);
|
printf("ugavalid:%d\n", inq->ugavalid);
|
||||||
printf("unmap granularity alignment:%d\n", inq->unmap_gran_align);
|
printf("unmap granularity alignment:%" PRIu32 "\n", inq->unmap_gran_align);
|
||||||
printf("maximum write same length:%d\n", (int)inq->max_ws_len);
|
printf("maximum write same length:%" PRIu64 "\n", inq->max_ws_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void inquiry_logical_block_provisioning(struct scsi_inquiry_logical_block_provisioning *inq)
|
void inquiry_logical_block_provisioning(struct scsi_inquiry_logical_block_provisioning *inq)
|
||||||
{
|
{
|
||||||
printf("Threshold Exponent:%d\n", inq->threshold_exponent);
|
printf("Threshold Exponent:%d\n", inq->threshold_exponent);
|
||||||
printf("lbpu:%d\n", inq->lbpu);
|
printf("lbpu:%d\n", inq->lbpu);
|
||||||
printf("lbpws:%d\n", inq->lbpws);
|
printf("lbpws:%d\n", inq->lbpws);
|
||||||
printf("lbpws10:%d\n", inq->lbpws10);
|
printf("lbpws10:%d\n", inq->lbpws10);
|
||||||
printf("lbprz:%d\n", inq->lbprz);
|
printf("lbprz:%d\n", inq->lbprz);
|
||||||
printf("anc_sup:%d\n", inq->anc_sup);
|
printf("anc_sup:%d\n", inq->anc_sup);
|
||||||
printf("dp:%d\n", inq->dp);
|
printf("dp:%d\n", inq->dp);
|
||||||
printf("provisioning type:%d\n", inq->provisioning_type);
|
printf("provisioning type:%d\n", inq->provisioning_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void inquiry_block_device_characteristics(struct scsi_inquiry_block_device_characteristics *inq)
|
void inquiry_block_device_characteristics(struct scsi_inquiry_block_device_characteristics *inq)
|
||||||
{
|
{
|
||||||
printf("Medium Rotation Rate:%dRPM\n", inq->medium_rotation_rate);
|
printf("Medium Rotation Rate:%dRPM\n", inq->medium_rotation_rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
void inquiry_device_identification(struct scsi_inquiry_device_identification *inq)
|
void inquiry_device_identification(struct scsi_inquiry_device_identification *inq)
|
||||||
|
|||||||
@@ -263,6 +263,10 @@ void discovery_cb(struct iscsi_context *iscsi, int status, void *command_data, v
|
|||||||
|
|
||||||
while (portal != NULL) {
|
while (portal != NULL) {
|
||||||
if (useurls == 1 && showluns == 0) {
|
if (useurls == 1 && showluns == 0) {
|
||||||
|
char *str = strrchr(portal->portal, ',');
|
||||||
|
if (str != NULL) {
|
||||||
|
str[0] = 0;
|
||||||
|
}
|
||||||
printf("iscsi://%s/%s/0\n", portal->portal, addr->target_name);
|
printf("iscsi://%s/%s/0\n", portal->portal, addr->target_name);
|
||||||
} else {
|
} else {
|
||||||
printf("Target:%s Portal:%s\n", addr->target_name, portal->portal);
|
printf("Target:%s Portal:%s\n", addr->target_name, portal->portal);
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ int max_in_flight = 32;
|
|||||||
int blocks_per_io = 8;
|
int blocks_per_io = 8;
|
||||||
uint64_t runtime = 0;
|
uint64_t runtime = 0;
|
||||||
uint64_t finished = 0;
|
uint64_t finished = 0;
|
||||||
|
int logging = 0;
|
||||||
|
|
||||||
struct client {
|
struct client {
|
||||||
int finished;
|
int finished;
|
||||||
@@ -117,6 +118,9 @@ void progress(struct client *client) {
|
|||||||
printf ("lba %" PRIu64 ", iops current %" PRIu64 " (%" PRIu64 " MB/s), ", client->pos, iops, mbps >> 20);
|
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);
|
printf ("iops average %" PRIu64 " (%" PRIu64 " MB/s), in_flight %d, busy %d ", aiops, ambps >> 20, client->in_flight, client->busy_cnt);
|
||||||
}
|
}
|
||||||
|
if (logging) {
|
||||||
|
printf ("\n");
|
||||||
|
}
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
client->last_ns = now;
|
client->last_ns = now;
|
||||||
client->last_iops = client->iops;
|
client->last_iops = client->iops;
|
||||||
@@ -220,7 +224,7 @@ void fill_read_queue(struct client *client)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void usage(void) {
|
void usage(void) {
|
||||||
fprintf(stderr,"Usage: iscsi-perf [-i <initiator-name>] [-m <max_requests>] [-b blocks_per_request] [-t timeout] [-r|--random] [-n|--ignore-errors] [-x <max_reconnects>] <LUN>\n");
|
fprintf(stderr,"Usage: iscsi-perf [-i <initiator-name>] [-m <max_requests>] [-b blocks_per_request] [-t timeout] [-r|--random] [-l|--logging] [-n|--ignore-errors] [-x <max_reconnects>] <LUN>\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,6 +258,7 @@ int main(int argc, char *argv[])
|
|||||||
{"runtime", required_argument, NULL, 't'},
|
{"runtime", required_argument, NULL, 't'},
|
||||||
{"random", no_argument, NULL, 'r'},
|
{"random", no_argument, NULL, 'r'},
|
||||||
{"random-blocks", no_argument, NULL, 'R'},
|
{"random-blocks", no_argument, NULL, 'R'},
|
||||||
|
{"logging", no_argument, NULL, 'l'},
|
||||||
{"ignore-errors", no_argument, NULL, 'n'},
|
{"ignore-errors", no_argument, NULL, 'n'},
|
||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
@@ -266,7 +271,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
printf("iscsi-perf version %s - (c) 2014-2015 by Peter Lieven <pl@ĸamp.de>\n\n", PERF_VERSION);
|
printf("iscsi-perf version %s - (c) 2014-2015 by Peter Lieven <pl@ĸamp.de>\n\n", PERF_VERSION);
|
||||||
|
|
||||||
while ((c = getopt_long(argc, argv, "i:m:b:t:nrRx:", long_options,
|
while ((c = getopt_long(argc, argv, "i:m:b:t:lnrRx:", long_options,
|
||||||
&option_index)) != -1) {
|
&option_index)) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'i':
|
case 'i':
|
||||||
@@ -290,6 +295,9 @@ int main(int argc, char *argv[])
|
|||||||
case 'R':
|
case 'R':
|
||||||
client.random_blocks = 1;
|
client.random_blocks = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'l':
|
||||||
|
logging = 1;
|
||||||
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
client.max_reconnects = atoi(optarg);
|
client.max_reconnects = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user