From 53471e62159647ea07c88dad1d254dcbe96f322d Mon Sep 17 00:00:00 2001 From: David Disseldorp Date: Fri, 21 Feb 2020 11:54:26 +0100 Subject: [PATCH 1/2] examples/iscsi-dd: print basic usage information Add additional -h/--help parameters. Signed-off-by: David Disseldorp --- examples/iscsi-dd.c | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/examples/iscsi-dd.c b/examples/iscsi-dd.c index f02f22e..9a5e3d6 100644 --- a/examples/iscsi-dd.c +++ b/examples/iscsi-dd.c @@ -523,6 +523,23 @@ void readcap(struct iscsi_context *iscsi, int lun, int use_16, return; } +static void usage_exit(int status) +{ + fprintf(stderr, "Usage:\n" +"-s, --src source iSCSI URL (required)\n" +"-d, --dst destination iSCSI URL (required)\n" +"-i, --initiator-name iSCSI initiator name (default=%s)\n" +"-p, --progress show progress while copying\n" +"-6, --16 use READ16 & WRITE16 SCSI commands\n" +"-x, --xcopy offload I/O to the target via XCOPY\n" +"-m, --max maximum requests in flight (default=%u)\n" +"-b, --blocks blocks per I/O (default=%u)\n" +"-n, --ignore-errors ignore any I/O errors\n" +"-h, --help show this usage message\n", + initiator, max_in_flight, blocks_per_io); + exit(status); +} + int main(int argc, char *argv[]) { char *src_url = NULL; @@ -542,13 +559,14 @@ int main(int argc, char *argv[]) {"max", required_argument, NULL, 'm'}, {"blocks", required_argument, NULL, 'b'}, {"ignore-errors", no_argument, NULL, 'n'}, + {"help", no_argument, NULL, 'h'}, {0, 0, 0, 0} }; int option_index; memset(&client, 0, sizeof(client)); - while ((c = getopt_long(argc, argv, "d:s:i:m:b:p6nx", long_options, + while ((c = getopt_long(argc, argv, "d:s:i:m:b:p6nxh", long_options, &option_index)) != -1) { char *endptr; @@ -590,21 +608,24 @@ int main(int argc, char *argv[]) case 'n': client.ignore_errors = 1; break; + case 'h': + usage_exit(0); + break; default: fprintf(stderr, "Unrecognized option '%c'\n\n", c); - exit(1); + usage_exit(1); } } if (src_url == NULL) { - fprintf(stderr, "You must specify source url\n"); - fprintf(stderr, " --src iscsi://[:]//\n"); - exit(10); + fprintf(stderr, "You must specify source url\n" + " --src iscsi://[:]//\n"); + usage_exit(10); } if (dst_url == NULL) { - fprintf(stderr, "You must specify destination url\n"); - fprintf(stderr, " --dst iscsi://[:]//\n"); - exit(10); + fprintf(stderr, "You must specify destination url\n" + " --dst iscsi://[:]//\n"); + usage_exit(10); } client.src_iscsi = iscsi_create_context(initiator); From 829c6351ed651ab148d9459242268d1908021738 Mon Sep 17 00:00:00 2001 From: David Disseldorp Date: Fri, 21 Feb 2020 19:00:02 +0100 Subject: [PATCH 2/2] examples/iscsi-dd: measure throughput Measure the elapsed time across the copy loop and print the throughput [bKMGT]/second. Signed-off-by: David Disseldorp --- examples/iscsi-dd.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/examples/iscsi-dd.c b/examples/iscsi-dd.c index 9a5e3d6..6e60479 100644 --- a/examples/iscsi-dd.c +++ b/examples/iscsi-dd.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "iscsi.h" #include "scsi-lowlevel.h" @@ -540,6 +541,26 @@ static void usage_exit(int status) exit(status); } +static void show_perf(struct timespec *start_time, + struct timespec *end_time, + uint64_t num_blocks, + uint64_t block_size) +{ + const char u[] = { 'b', 'K', 'M', 'G', 'T'}; + double elapsed = (end_time->tv_sec + 1.0e-9 * end_time->tv_nsec) + - (start_time->tv_sec + 1.0e-9 * start_time->tv_nsec); + double ubytes_per_sec = num_blocks * block_size / elapsed; + unsigned int i = 0; + + while (ubytes_per_sec > 1024 && i < sizeof(u) - 1) { + ubytes_per_sec = ubytes_per_sec / 1024; + i++; + } + + printf("\r%"PRIu64" blocks (%"PRIu64" sized) copied in %g seconds," + " %g%c/s.\n", num_blocks, block_size, elapsed, ubytes_per_sec, u[i]); +} + int main(int argc, char *argv[]) { char *src_url = NULL; @@ -548,6 +569,8 @@ int main(int argc, char *argv[]) int c; struct pollfd pfd[2]; struct client client; + struct timespec start_time; + struct timespec end_time; static struct option long_options[] = { {"dst", required_argument, NULL, 'd'}, @@ -702,6 +725,8 @@ int main(int argc, char *argv[]) exit(10); } + clock_gettime(CLOCK_MONOTONIC, &start_time); + if (client.use_xcopy) { fill_xcopy_queue(&client); } else { @@ -733,6 +758,9 @@ int main(int argc, char *argv[]) } } + clock_gettime(CLOCK_MONOTONIC, &end_time); + show_perf(&start_time, &end_time, client.pos, client.src_blocksize); + iscsi_logout_sync(client.src_iscsi); iscsi_destroy_context(client.src_iscsi); iscsi_logout_sync(client.dst_iscsi);