diff --git a/include/iscsi-private.h b/include/iscsi-private.h index c836b0e..aa22a6f 100644 --- a/include/iscsi-private.h +++ b/include/iscsi-private.h @@ -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); +void iscsi_dump_pdu_header(struct iscsi_context *iscsi, unsigned char *data); + struct iscsi_transport { int (*connect)(struct iscsi_context *iscsi, union socket_address *sa, int ai_family); int (*queue_pdu)(struct iscsi_context *iscsi, struct iscsi_pdu *pdu); diff --git a/lib/connect.c b/lib/connect.c index f42ec8b..d09f12d 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -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); } + if (old_iscsi->t) { + iscsi_free(old_iscsi, old_iscsi->t); + } + for (i = 0; i < old_iscsi->smalloc_free; i++) { iscsi_free(old_iscsi, old_iscsi->smalloc_ptrs[i]); } diff --git a/lib/init.c b/lib/init.c index 19c2f7b..ca4ff20 100644 --- a/lib/init.c +++ b/lib/init.c @@ -413,6 +413,10 @@ iscsi_destroy_context(struct iscsi_context *iscsi) iscsi_destroy_context(iscsi->old_iscsi); } + if (iscsi->t) { + iscsi_free(iscsi, iscsi->t); + } + memset(iscsi, 0, sizeof(struct iscsi_context)); free(iscsi); diff --git a/lib/iscsi-command.c b/lib/iscsi-command.c index 2b33fe7..f5930b7 100644 --- a/lib/iscsi-command.c +++ b/lib/iscsi-command.c @@ -450,6 +450,9 @@ iscsi_process_scsi_reply(struct iscsi_context *iscsi, struct iscsi_pdu *pdu, task->sense.key, scsi_sense_ascq_str(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) { pdu->callback(iscsi, SCSI_STATUS_CHECK_CONDITION, task, pdu->private_data); diff --git a/lib/scsi-lowlevel.c b/lib/scsi-lowlevel.c index 0737d8d..1c91d2c 100644 --- a/lib/scsi-lowlevel.c +++ b/lib/scsi-lowlevel.c @@ -3889,8 +3889,12 @@ scsi_inquiry_pagecode_to_str(int pagecode) return "UNIT_SERIAL_NUMBER"; case SCSI_INQUIRY_PAGECODE_DEVICE_IDENTIFICATION: return "DEVICE_IDENTIFICATION"; + case SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS: + return "BLOCK_LIMITS"; case SCSI_INQUIRY_PAGECODE_BLOCK_DEVICE_CHARACTERISTICS: return "BLOCK_DEVICE_CHARACTERISTICS"; + case SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING: + return "LOGICAL_BLOCK_PROVISIONING"; } return "unknown"; } diff --git a/lib/socket.c b/lib/socket.c index 7429478..8b30912 100644 --- a/lib/socket.c +++ b/lib/socket.c @@ -359,11 +359,13 @@ iscsi_connect_async(struct iscsi_context *iscsi, const char *portal, iscsi->socket_status_cb = cb; 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"); + freeaddrinfo(ai); return -1; } + freeaddrinfo(ai); return 0; } diff --git a/utils/iscsi-inq.c b/utils/iscsi-inq.c index 96a9513..2702342 100644 --- a/utils/iscsi-inq.c +++ b/utils/iscsi-inq.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "iscsi.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) { printf("wsnz:%d\n", inq->wsnz); - printf("maximum compare and write length:%d\n", inq->max_cmp); - printf("optimal transfer length granularity:%d\n", inq->opt_gran); - printf("maximum transfer length:%d\n", inq->max_xfer_len); - printf("optimal transfer length:%d\n",inq->opt_xfer_len); - printf("maximum prefetch xdread xdwrite transfer length:%d\n", inq->max_prefetch); - printf("maximum unmap lba count:%d\n", inq->max_unmap); - printf("maximum unmap block descriptor count:%d\n", inq->max_unmap_bdc); - printf("optimal unmap granularity:%d\n", inq->opt_unmap_gran); + printf("maximum compare and write length:%" PRIu8 "\n", inq->max_cmp); + printf("optimal transfer length granularity:%" PRIu16 "\n", inq->opt_gran); + printf("maximum transfer length:%" PRIu32 "\n", inq->max_xfer_len); + printf("optimal transfer length:%" PRIu32 "\n",inq->opt_xfer_len); + printf("maximum prefetch xdread xdwrite transfer length:%" PRIu32 "\n", inq->max_prefetch); + printf("maximum unmap lba count:%" PRIu32 "\n", inq->max_unmap); + printf("maximum unmap block descriptor count:%" PRIu32 "\n", inq->max_unmap_bdc); + printf("optimal unmap granularity:%" PRIu32 "\n", inq->opt_unmap_gran); printf("ugavalid:%d\n", inq->ugavalid); - printf("unmap granularity alignment:%d\n", inq->unmap_gran_align); - printf("maximum write same length:%d\n", (int)inq->max_ws_len); + printf("unmap granularity alignment:%" PRIu32 "\n", inq->unmap_gran_align); + printf("maximum write same length:%" PRIu64 "\n", inq->max_ws_len); } void inquiry_logical_block_provisioning(struct scsi_inquiry_logical_block_provisioning *inq) { - printf("Threshold Exponent:%d\n", inq->threshold_exponent); - printf("lbpu:%d\n", inq->lbpu); - printf("lbpws:%d\n", inq->lbpws); - printf("lbpws10:%d\n", inq->lbpws10); - printf("lbprz:%d\n", inq->lbprz); - printf("anc_sup:%d\n", inq->anc_sup); - printf("dp:%d\n", inq->dp); - printf("provisioning type:%d\n", inq->provisioning_type); + printf("Threshold Exponent:%d\n", inq->threshold_exponent); + printf("lbpu:%d\n", inq->lbpu); + printf("lbpws:%d\n", inq->lbpws); + printf("lbpws10:%d\n", inq->lbpws10); + printf("lbprz:%d\n", inq->lbprz); + printf("anc_sup:%d\n", inq->anc_sup); + printf("dp:%d\n", inq->dp); + printf("provisioning type:%d\n", inq->provisioning_type); } 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) diff --git a/utils/iscsi-ls.c b/utils/iscsi-ls.c index 0a06224..fff014b 100644 --- a/utils/iscsi-ls.c +++ b/utils/iscsi-ls.c @@ -263,6 +263,10 @@ void discovery_cb(struct iscsi_context *iscsi, int status, void *command_data, v while (portal != NULL) { 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); } else { printf("Target:%s Portal:%s\n", addr->target_name, portal->portal); diff --git a/utils/iscsi-perf.c b/utils/iscsi-perf.c index 8098557..14c3f49 100644 --- a/utils/iscsi-perf.c +++ b/utils/iscsi-perf.c @@ -47,6 +47,7 @@ int max_in_flight = 32; int blocks_per_io = 8; uint64_t runtime = 0; uint64_t finished = 0; +int logging = 0; struct client { 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 ("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); client->last_ns = now; client->last_iops = client->iops; @@ -220,7 +224,7 @@ void fill_read_queue(struct client *client) } void usage(void) { - fprintf(stderr,"Usage: iscsi-perf [-i ] [-m ] [-b blocks_per_request] [-t timeout] [-r|--random] [-n|--ignore-errors] [-x ] \n"); + fprintf(stderr,"Usage: iscsi-perf [-i ] [-m ] [-b blocks_per_request] [-t timeout] [-r|--random] [-l|--logging] [-n|--ignore-errors] [-x ] \n"); exit(1); } @@ -254,6 +258,7 @@ int main(int argc, char *argv[]) {"runtime", required_argument, NULL, 't'}, {"random", no_argument, NULL, 'r'}, {"random-blocks", no_argument, NULL, 'R'}, + {"logging", no_argument, NULL, 'l'}, {"ignore-errors", no_argument, NULL, 'n'}, {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 \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) { switch (c) { case 'i': @@ -290,6 +295,9 @@ int main(int argc, char *argv[]) case 'R': client.random_blocks = 1; break; + case 'l': + logging = 1; + break; case 'x': client.max_reconnects = atoi(optarg); break;