aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2021-02-09 01:22:53 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2021-02-09 01:22:53 +0000
commit28d27daf0d8ff9ab8ee957a3f9917e2c2a23d232 (patch)
treecbbdd7eefff01b0d647a09cd56ac8baa9f8a659b
parent245e8d347a48c70d5a2e047bf85b98609b64b900 (diff)
downloadsg3_utils-28d27daf0d8ff9ab8ee957a3f9917e2c2a23d232.tar.gz
sg_dd: add command timeout after comma in time= operand; testing/sg_mrq_dd+sgh_dd work
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@875 6180dd3e-e324-4e3e-922d-17de1ae2f315
-rw-r--r--ChangeLog3
-rw-r--r--debian/changelog2
-rw-r--r--doc/sg3_utils.82
-rw-r--r--doc/sg_dd.816
-rw-r--r--lib/Makefile.am3
-rw-r--r--sg3_utils.spec2
-rw-r--r--src/Makefile.am1
-rw-r--r--src/sg_dd.c33
-rw-r--r--testing/Makefile7
-rw-r--r--testing/sg_mrq_dd.cpp81
-rw-r--r--testing/sgh_dd.cpp40
11 files changed, 132 insertions, 58 deletions
diff --git a/ChangeLog b/ChangeLog
index 3199fc60..1ad6872e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,7 +2,7 @@ Each utility has its own version number, date of last change and
some description at the top of its ".c" file. All utilities in the main
directory have their own "man" pages. There is also a sg3_utils man page.
-Changelog for pre-release sg3_utils-1.46 [20210131] [svn: r874]
+Changelog for pre-release sg3_utils-1.46 [20210208] [svn: r875]
- sg_rep_pip: report new provisioning initialization pattern cmd
- sg_turs: estimated time-to-ready [20-061r2]
- add --delay=MS option
@@ -14,6 +14,7 @@ Changelog for pre-release sg3_utils-1.46 [20210131] [svn: r874]
- --verify : oflag=coe continue on miscompares, counts them
- add oflag=nocreat and conv=nocreat : OFILE must exist
- add iflag=00, ff, random flags
+ - add command timeout after comma in time= operand
- sg_get_elem_status: add ralwd bit sbc4r20a
- sg_write_x: add dld bits to write(32) [sbc4r19a]
- sg_rep_zones: print invalid write pointer LBA as -1 rather
diff --git a/debian/changelog b/debian/changelog
index 895de16a..0779e80d 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,7 +2,7 @@ sg3-utils (1.46-0.1) unstable; urgency=low
* New upstream version
- -- Douglas Gilbert <dgilbert@interlog.com> Sun, 03 Jan 2021 21:00:00 -0500
+ -- Douglas Gilbert <dgilbert@interlog.com> Fri, 05 Feb 2021 15:00:00 -0500
sg3-utils (1.45-0.1) unstable; urgency=low
diff --git a/doc/sg3_utils.8 b/doc/sg3_utils.8
index 467043b1..738391bc 100644
--- a/doc/sg3_utils.8
+++ b/doc/sg3_utils.8
@@ -1,4 +1,4 @@
-.TH SG3_UTILS "8" "January 2021" "sg3_utils\-1.46" SG3_UTILS
+.TH SG3_UTILS "8" "February 2021" "sg3_utils\-1.46" SG3_UTILS
.SH NAME
sg3_utils \- a package of utilities for sending SCSI commands
.SH SYNOPSIS
diff --git a/doc/sg_dd.8 b/doc/sg_dd.8
index b2d45874..48d16047 100644
--- a/doc/sg_dd.8
+++ b/doc/sg_dd.8
@@ -1,4 +1,4 @@
-.TH SG_DD "8" "October 2020" "sg3_utils\-1.46" SG3_UTILS
+.TH SG_DD "8" "February 2021" "sg3_utils\-1.46" SG3_UTILS
.SH NAME
sg_dd \- copy data to and from files and devices, especially SCSI
devices
@@ -11,9 +11,9 @@ devices
.PP
[\fIblk_sgio=\fR{0|1}] [\fIbpt=BPT\fR] [\fIcdbsz=\fR{6|10|12|16}]
[\fIcoe=\fR{0|1|2|3}] [\fIcoe_limit=CL\fR] [\fIdio=\fR{0|1}]
-[\fIodir=\fR{0|1}] [\fIof2=OFILE2\fR] [\fIretries=RETR\fR] [\fIsync=\fR{0|1}]
-[\fItime=\fR{0|1}] [\fIverbose=VERB\fR] [\fI\-\-dry\-run\fR]
-[\fI\-\-progress\fR] [\fI\-\-verify\fR]
+[\fIodir=\fR{0|1}] [\fIof2=OFILE2\fR] [\fIretries=RETR\fR]
+[\fIsync=\fR{0|1}] [\fItime=\fR{0|1}[,TO]] [\fIverbose=VERB\fR]
+[\fI\-\-dry\-run\fR] [\fI\-\-progress\fR] [\fI\-\-verify\fR]
.SH DESCRIPTION
.\" Add any additional description here
.PP
@@ -189,9 +189,13 @@ when 1, does SYNCHRONIZE CACHE command on \fIOFILE\fR at the end of the
transfer. Only active when \fIOFILE\fR is a sg device file name or a block
device and 'blk_sgio=1' is given.
.TP
-\fBtime\fR={0|1}
+\fBtime\fR={0|1}[,\fITO\fR]
when 1, times transfer and does throughput calculation, outputting the
results (to stderr) at completion. When 0 (default) doesn't perform timing.
+.br
+If that value is followed by a comma, then \fITO\fR is the command timeout
+in seconds for SCSI READ, WRITE or VERIFY commands issued by this utility.
+The default is 60 seconds.
.TP
\fBverbose\fR=\fIVERB\fR
as \fIVERB\fR increases so does the amount of debug output sent to stderr.
@@ -550,7 +554,7 @@ Written by Douglas Gilbert and Peter Allworth.
.SH "REPORTING BUGS"
Report bugs to <dgilbert at interlog dot com>.
.SH COPYRIGHT
-Copyright \(co 2000\-2020 Douglas Gilbert
+Copyright \(co 2000\-2021 Douglas Gilbert
.br
This software is distributed under the GPL version 2. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
diff --git a/lib/Makefile.am b/lib/Makefile.am
index aef8384f..9f39d4a5 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -46,8 +46,9 @@ endif
# For C++/clang testing
## CC = gcc-9
-## CC = g++
+## CXX = g++
## CC = clang
+## CXX = clang++
## CC = clang++
## CC = powerpc64-linux-gnu-gcc
diff --git a/sg3_utils.spec b/sg3_utils.spec
index 8a0a9dbf..58f32d85 100644
--- a/sg3_utils.spec
+++ b/sg3_utils.spec
@@ -84,7 +84,7 @@ fi
%{_libdir}/*.la
%changelog
-* Sun Jan 03 2021 - dgilbert at interlog dot com
+* Fri Feb 05 2021 - dgilbert at interlog dot com
- track t10 changes
* sg3_utils-1.46
diff --git a/src/Makefile.am b/src/Makefile.am
index 46d34665..47293fe5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -47,6 +47,7 @@ endif
## CC = gcc-9
## CC = g++
## CC = clang
+## CXX = clang++
## CC = clang++
## CC = powerpc64-linux-gnu-gcc
diff --git a/src/sg_dd.c b/src/sg_dd.c
index fb88ac7e..e7b4f108 100644
--- a/src/sg_dd.c
+++ b/src/sg_dd.c
@@ -1,7 +1,7 @@
/* A utility program for copying files. Specialised for "files" that
* represent devices that understand the SCSI command set.
*
- * Copyright (C) 1999 - 2020 D. Gilbert and P. Allworth
+ * Copyright (C) 1999 - 2021 D. Gilbert and P. Allworth
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
@@ -67,7 +67,7 @@
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-static const char * version_str = "6.22 20201031";
+static const char * version_str = "6.23 20210208";
#define ME "sg_dd: "
@@ -164,6 +164,7 @@ static int max_uas = MAX_UNIT_ATTENTIONS;
static int max_aborted = MAX_ABORTED_CMDS;
static int coe_limit = 0;
static int coe_count = 0;
+static int cmd_timeout = DEF_TIMEOUT; /* in milliseconds */
static uint32_t glob_pack_id = 0; /* pre-increment */
static struct timeval start_tm;
@@ -436,8 +437,9 @@ usage()
"[coe=0|1|2|3]\n"
" [coe_limit=CL] [dio=0|1] [odir=0|1] "
"[of2=OFILE2] [retries=RETR]\n"
- " [sync=0|1] [time=0|1] [verbose=VERB] "
- "[--progress] [--verify]\n"
+ " [sync=0|1] [time=0|1[,TO]] [verbose=VERB] "
+ "[--progress]\n"
+ " [--verify]\n"
" where:\n"
" blk_sgio 0->block device use normal I/O(def), 1->use "
"SG_IO\n"
@@ -486,7 +488,8 @@ usage()
" sync 0->no sync(def), 1->SYNCHRONIZE CACHE on "
"OFILE after copy\n"
" time 0->no timing(def), 1->time plus calculate "
- "throughput\n"
+ "throughput;\n"
+ " TO is command timeout in seconds (def: 60)\n"
" verbose 0->quiet(def), 1->some noise, 2->more noise, "
"etc\n"
" --dry-run do preparation but bypass copy (or read)\n"
@@ -717,7 +720,7 @@ sg_read_low(int sg_fd, uint8_t * buff, int blocks, int64_t from_block,
io_hdr.dxferp = buff;
io_hdr.mx_sb_len = SENSE_BUFF_LEN;
io_hdr.sbp = senseBuff;
- io_hdr.timeout = DEF_TIMEOUT;
+ io_hdr.timeout = cmd_timeout;
io_hdr.pack_id = (int)++glob_pack_id;
if (diop && *diop)
io_hdr.flags |= SG_FLAG_DIRECT_IO;
@@ -1126,7 +1129,7 @@ sg_write(int sg_fd, uint8_t * buff, int blocks, int64_t to_block,
io_hdr.dxferp = buff;
io_hdr.mx_sb_len = SENSE_BUFF_LEN;
io_hdr.sbp = senseBuff;
- io_hdr.timeout = DEF_TIMEOUT;
+ io_hdr.timeout = cmd_timeout;
io_hdr.pack_id = (int)++glob_pack_id;
if (diop && *diop)
io_hdr.flags |= SG_FLAG_DIRECT_IO;
@@ -1932,9 +1935,19 @@ main(int argc, char * argv[])
}
} else if (0 == strcmp(key, "sync"))
do_sync = !! sg_get_num(buf);
- else if (0 == strcmp(key, "time"))
+ else if (0 == strcmp(key, "time")) {
+ const char * cp = strchr(buf, ',');
+
do_time = !! sg_get_num(buf);
- else if (0 == strncmp(key, "verb", 4))
+ if (cp) {
+ n = sg_get_num(cp + 1);
+ if (n < 0) {
+ pr2serr(ME "bad argument to 'time=0|1,TO'\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ cmd_timeout = n ? (n * 1000) : DEF_TIMEOUT;
+ }
+ } else if (0 == strncmp(key, "verb", 4))
verbose = sg_get_num(buf);
else if ((keylen > 1) && ('-' == key[0]) && ('-' != key[1])) {
res = 0;
@@ -2440,7 +2453,7 @@ main(int argc, char * argv[])
while (1) {
ret = sg_write(outfd, wrkPos, blocks, seek, blk_sz, &oflag,
&dio_tmp);
- if ((0 == ret) || (SG_DD_BYPASS))
+ if ((0 == ret) || (SG_DD_BYPASS == ret))
break;
if ((SG_LIB_CAT_NOT_READY == ret) ||
(SG_LIB_SYNTAX_ERROR == ret))
diff --git a/testing/Makefile b/testing/Makefile
index 8383cc5b..ac152d8d 100644
--- a/testing/Makefile
+++ b/testing/Makefile
@@ -29,9 +29,11 @@ LD = $(CXX)
CXXLD = $(CXX)
CPPFLAGS = -iquote ../include -iquote .. -D_REENTRANT $(LARGE_FILE_FLAGS) -DHAVE_CONFIG_H -DHAVE_NVME
-CXXFLAGS = -std=c++17 -pthread -ggdb -O2 -W -Wall -iquote ../include -D_REENTRANT $(LARGE_FILE_FLAGS)
+CXXFLAGS = -std=c++11 -pthread -ggdb -O2 -W -Wall -iquote ../include -D_REENTRANT $(LARGE_FILE_FLAGS)
+## CXXFLAGS = -std=c++14 -pthread -ggdb -O2 -W -Wall -iquote ../include -D_REENTRANT $(LARGE_FILE_FLAGS)
+## CXXFLAGS = -std=c++17 -pthread -ggdb -O2 -W -Wall -iquote ../include -D_REENTRANT $(LARGE_FILE_FLAGS)
+## CXXFLAGS = -std=c++20 -pthread -ggdb -O2 -W -Wall -iquote ../include -D_REENTRANT $(LARGE_FILE_FLAGS)
# CXXFLAGS = -std=c++2a -pthread -ggdb -O2 -W -Wall -iquote ../include -D_REENTRANT $(LARGE_FILE_FLAGS)
-# CXXFLAGS = -std=c++11 -pthread -ggdb -O2 -W -Wall -iquote ../include -D_REENTRANT $(LARGE_FILE_FLAGS)
# CPPFLAGS = -iquote ../include -iquote .. -D_REENTRANT $(LARGE_FILE_FLAGS) -DHAVE_CONFIG_H -DHAVE_NVME -DDEBUG
CFLAGS = -g -O2 -W -Wall
# CFLAGS = -ggdb -O2 -W -Wall -DDEBUG
@@ -39,6 +41,7 @@ CFLAGS = -g -O2 -W -Wall
# CFLAGS = -g -O2 -Wall -pedantic
# CFLAGS = -Wall -W -pedantic -std=c11 --analyze
# CFLAGS = -Wall -W -pedantic -std=c++14 -fPIC
+# CFLAGS = -Wall -W -pedantic -std=c++20
LDFLAGS =
diff --git a/testing/sg_mrq_dd.cpp b/testing/sg_mrq_dd.cpp
index 32f0f4d6..5beb9b31 100644
--- a/testing/sg_mrq_dd.cpp
+++ b/testing/sg_mrq_dd.cpp
@@ -30,7 +30,7 @@
*
*/
-static const char * version_str = "1.18 20210130";
+static const char * version_str = "1.19 20210208";
#define _XOPEN_SOURCE 600
#ifndef _GNU_SOURCE
@@ -237,6 +237,7 @@ struct global_collection /* one instance visible to all threads */
mutex infant_mut;
int bs;
int bpt;
+ int cmd_timeout; /* in milliseconds */
int elem_sz;
int outregfd;
int outreg_type;
@@ -252,6 +253,7 @@ struct global_collection /* one instance visible to all threads */
bool cdbsz_given;
bool count_given;
bool flexible;
+ bool mrq_hipri;
bool ofile_given;
bool unit_nanosec; /* default duration unit is millisecond */
bool no_waitq; /* if set use polling for response instead */
@@ -838,12 +840,13 @@ usage(int pg_num)
"[--version]\n\n");
pr2serr(" [bpt=BPT] [cdbsz=6|10|12|16] [dio=0|1] "
"[elemsz_kb=EKB]\n"
- " [fua=0|1|2|3] [mrq=MRQ] [no_waitq=0|1] "
- "[ofreg=OFREG]\n"
- " [sync=0|1] [thr=THR] [time=0|1|2] "
- "[verbose=VERB]\n"
- " [--dry-run] [--pre-fetch] [--verbose] "
- "[--version]\n\n"
+ " [fua=0|1|2|3] [hipri=NRQS] [mrq=NRQS] "
+ "[no_waitq=0|1]\n"
+ " [ofreg=OFREG] [sync=0|1] [thr=THR] "
+ "[time=0|1|2[,TO]]\n"
+ " [verbose=VERB] [--dry-run] [--pre-fetch] "
+ "[--verbose]\n"
+ " [--version]\n\n"
" where: operands have the form name=value and are pecular to "
"'dd'\n"
" style commands, and options start with one or "
@@ -899,8 +902,11 @@ page2:
" 3->OFILE+IFILE\n"
" ibs IFILE logical block size, cannot differ from "
"obs or bs\n"
- " mrq number of cmds placed in each sg call "
- "(def: 16)\n"
+ " hipri similar to mrq=NRQS operand but does set mrq "
+ "hipri flag\n"
+ " mrq NRQS is number of cmds placed in each sg "
+ "ioctl\n"
+ " (def: 16). Does not set mrq hipri flag.\n"
" if mrq=0 does one-by-one, blocking "
"ioctl(SG_IO)s\n"
" no_waitq=0|1 poll for completion when 1; def: 0 (use "
@@ -915,7 +921,8 @@ page2:
" thr is number of threads, must be > 0, default 4, "
"max 1024\n"
" time 0->no timing; 1/2->millisec/nanosec precision "
- "(def: 1)\n"
+ "(def: 1);\n"
+ " TO is command timeout in seconds (def: 60)\n"
" verbose increase verbosity (def: VERB=0)\n"
" --dry-run|-d prepare but bypass copy/read\n"
" --prefetch|-p with verify: do pre-fetch first\n"
@@ -1904,7 +1911,7 @@ sg_half_segment_mrq0(Rq_elem * rep, scat_gath_iter & sg_it, bool is_wr,
t_v4p->din_xfer_len = num * clp->bs;
t_v4p->din_xferp = (uint64_t)(dp + (q_blks * clp->bs));
}
- t_v4p->timeout = DEF_TIMEOUT;
+ t_v4p->timeout = clp->cmd_timeout;
t_v4p->request_extra = pack_id_base + ++rep->mrq_pack_id_off;
clp->most_recent_pack_id.store(t_v4p->request_extra);
mrq0_again:
@@ -2013,6 +2020,9 @@ sg_half_segment(Rq_elem * rep, scat_gath_iter & sg_it, bool is_wr,
t_v4p->guard = 'Q';
t_v4p->flags = rflags;
t_v4p->request_len = cdbsz;
+ t_v4p->response = (uint64_t)rep->sb;
+ t_v4p->max_response_len = sizeof(rep->sb);
+ t_v4p->flags = rflags;
t_v4p->usr_ptr = (uint64_t)&a_cdb[a_cdb.size() - 1];
if (is_wr) {
t_v4p->dout_xfer_len = num * clp->bs;
@@ -2021,7 +2031,7 @@ sg_half_segment(Rq_elem * rep, scat_gath_iter & sg_it, bool is_wr,
t_v4p->din_xfer_len = num * clp->bs;
t_v4p->din_xferp = (uint64_t)(dp + (mrq_q_blks * clp->bs));
}
- t_v4p->timeout = DEF_TIMEOUT;
+ t_v4p->timeout = clp->cmd_timeout;
mrq_q_blks += num;
t_v4p->request_extra = mrq_pack_id_base + ++rep->mrq_pack_id_off;
clp->most_recent_pack_id.store(t_v4p->request_extra);
@@ -2050,8 +2060,8 @@ sg_half_segment(Rq_elem * rep, scat_gath_iter & sg_it, bool is_wr,
ctl_v4.flags = SGV4_FLAG_MULTIPLE_REQS;
if (! flagsp->coe)
ctl_v4.flags |= SGV4_FLAG_STOP_IF;
- if (flagsp->hipri)
- rflags |= SGV4_FLAG_HIPRI;
+ if (clp->mrq_hipri)
+ ctl_v4.flags |= SGV4_FLAG_HIPRI;
ctl_v4.dout_xferp = (uint64_t)a_v4.data(); /* request array */
ctl_v4.dout_xfer_len = a_v4.size() * sizeof(struct sg_io_v4);
ctl_v4.din_xferp = (uint64_t)a_v4.data(); /* response array */
@@ -2434,7 +2444,7 @@ do_both_sg_segment_mrq0(Rq_elem * rep, scat_gath_iter & i_sg_it,
t_v4p->flags = iflags;
t_v4p->request_len = cdbsz;
t_v4p->din_xfer_len = num * clp->bs;
- t_v4p->timeout = DEF_TIMEOUT;
+ t_v4p->timeout = clp->cmd_timeout;
t_v4p->request_extra = pack_id_base + ++rep->mrq_pack_id_off;
clp->most_recent_pack_id.store(t_v4p->request_extra);
mrq0_again:
@@ -2481,10 +2491,11 @@ mrq0_again:
t_v4p->request = (uint64_t)t_cdb.data();
t_v4p->usr_ptr = t_v4p->request;
t_v4p->response = (uint64_t)rep->sb;
+ t_v4p->max_response_len = sizeof(rep->sb);
t_v4p->flags = oflags;
t_v4p->request_len = cdbsz;
t_v4p->dout_xfer_len = num * clp->bs;
- t_v4p->timeout = DEF_TIMEOUT;
+ t_v4p->timeout = clp->cmd_timeout;
t_v4p->request_extra = pack_id_base + ++rep->mrq_pack_id_off;
clp->most_recent_pack_id.store(t_v4p->request_extra);
mrq0_again2:
@@ -2614,9 +2625,11 @@ do_both_sg_segment(Rq_elem * rep, scat_gath_iter & i_sg_it,
t_v4p->guard = 'Q';
t_v4p->flags = iflags;
t_v4p->request_len = cdbsz;
+ t_v4p->response = (uint64_t)rep->sb;
+ t_v4p->max_response_len = sizeof(rep->sb);
t_v4p->usr_ptr = (uint64_t)&a_cdb[a_cdb.size() - 1];
t_v4p->din_xfer_len = num * clp->bs;
- t_v4p->timeout = DEF_TIMEOUT;
+ t_v4p->timeout = clp->cmd_timeout;
in_mrq_q_blks += num;
t_v4p->request_extra = mrq_pack_id_base + ++rep->mrq_pack_id_off;
clp->most_recent_pack_id.store(t_v4p->request_extra);
@@ -2638,9 +2651,11 @@ do_both_sg_segment(Rq_elem * rep, scat_gath_iter & i_sg_it,
t_v4p->guard = 'Q';
t_v4p->flags = oflags;
t_v4p->request_len = cdbsz;
+ t_v4p->response = (uint64_t)rep->sb;
+ t_v4p->max_response_len = sizeof(rep->sb);
t_v4p->usr_ptr = (uint64_t)&a_cdb[a_cdb.size() - 1];
t_v4p->dout_xfer_len = num * clp->bs;
- t_v4p->timeout = DEF_TIMEOUT;
+ t_v4p->timeout = clp->cmd_timeout;
out_mrq_q_blks += num;
t_v4p->request_extra = mrq_pack_id_base + ++rep->mrq_pack_id_off;
clp->most_recent_pack_id.store(t_v4p->request_extra);
@@ -2677,7 +2692,7 @@ do_both_sg_segment(Rq_elem * rep, scat_gath_iter & i_sg_it,
ctl_v4.flags |= SGV4_FLAG_STOP_IF;
if ((! clp->verify) && clp->out_flags.order)
ctl_v4.flags |= SGV4_FLAG_ORDERED_WR;
- if (! (iflagsp->hipri || oflagsp->hipri))
+ if (clp->mrq_hipri)
ctl_v4.flags |= SGV4_FLAG_HIPRI;
ctl_v4.dout_xferp = (uint64_t)a_v4.data(); /* request array */
ctl_v4.dout_xfer_len = a_v4.size() * sizeof(struct sg_io_v4);
@@ -3309,12 +3324,13 @@ parse_cmdline_sanity(int argc, char * argv[], struct global_collection * clp,
pr2serr("%sbad argument to 'iflag='\n", my_name);
goto syn_err;
}
- } else if (0 == strcmp(key, "mrq")) {
+ } else if ((0 == strcmp(key, "hipri")) ||
+ (0 == strcmp(key, "mrq"))) {
if (isdigit(buf[0]))
cp = buf;
else {
- pr2serr("%sonly mrq=NRQS which is a number allowed here\n",
- my_name);
+ pr2serr("%sonly mrq=NRQS or hipri=NRQS which is a number "
+ "allowed here\n", my_name);
goto syn_err;
}
clp->mrq_num = sg_get_num(cp);
@@ -3327,6 +3343,8 @@ parse_cmdline_sanity(int argc, char * argv[], struct global_collection * clp,
clp->mrq_num = 1;
pr2serr("note: send single, non-mrq commands\n");
}
+ if ('h' == key[0])
+ clp->mrq_hipri = true;
} else if ((0 == strcmp(key, "no_waitq")) ||
(0 == strcmp(key, "no-waitq"))) {
n = sg_get_num(buf);
@@ -3384,9 +3402,23 @@ parse_cmdline_sanity(int argc, char * argv[], struct global_collection * clp,
do_sync = !! sg_get_num(buf);
else if (0 == strcmp(key, "thr"))
num_threads = sg_get_num(buf);
- else if (0 == strcmp(key, "time"))
+ else if (0 == strcmp(key, "time")) {
+ const char * ccp = strchr(buf, ',');
+
do_time = sg_get_num(buf);
- else if (0 == strncmp(key, "verb", 4))
+ if (do_time < 0) {
+ pr2serr("%sbad argument to 'time=0|1|2'\n", my_name);
+ goto syn_err;
+ }
+ if (ccp) {
+ n = sg_get_num(ccp + 1);
+ if (n < 0) {
+ pr2serr("%sbad argument to 'time=0|1|2,TO'\n", my_name);
+ goto syn_err;
+ }
+ clp->cmd_timeout = n ? (n * 1000) : DEF_TIMEOUT;
+ }
+ } else if (0 == strncmp(key, "verb", 4))
clp->verbose = sg_get_num(buf);
else if ((keylen > 1) && ('-' == key[0]) && ('-' != key[1])) {
res = 0;
@@ -3794,6 +3826,7 @@ main(int argc, char * argv[])
/* memset(clp, 0, sizeof(*clp)); */
clp->dd_count = SG_COUNT_INDEFINITE;
clp->bpt = DEF_BLOCKS_PER_TRANSFER;
+ clp->cmd_timeout = DEF_TIMEOUT;
clp->in_type = FT_FIFO;
/* change dd's default: if of=OFILE not given, assume /dev/null */
clp->out_type = FT_DEV_NULL;
diff --git a/testing/sgh_dd.cpp b/testing/sgh_dd.cpp
index f0b145f8..35358352 100644
--- a/testing/sgh_dd.cpp
+++ b/testing/sgh_dd.cpp
@@ -36,7 +36,7 @@
* renamed [20181221]
*/
-static const char * version_str = "1.98 20210106";
+static const char * version_str = "1.98 20210108";
#define _XOPEN_SOURCE 600
#ifndef _GNU_SOURCE
@@ -231,6 +231,7 @@ struct global_collection
pthread_mutex_t out2_mutex;
int bs;
int bpt;
+ int cmd_timeout; /* in milliseconds */
int outregfd;
int outreg_type;
int ofsplit;
@@ -912,11 +913,12 @@ usage(int pg_num)
"[fua=0|1|2|3]\n"
" [mrq=[I|O,]NRQS[,C]] [noshare=0|1] "
"[of2=OFILE2]\n"
- " [ofreg=OFREG] [ofsplit=OSP] [sync=0|1] [thr=THR] "
- "[time=0|1|2]\n"
- " [unshare=1|0] [verbose=VERB] [--dry-run] "
- "[--prefetch]\n"
- " [--verbose] [--verify] [--version]\n\n"
+ " [ofreg=OFREG] [ofsplit=OSP] [sync=0|1] "
+ "[thr=THR]\n"
+ " [time=0|1|2[,TO]] [unshare=1|0] [verbose=VERB] "
+ "[--dry-run]\n"
+ " [--prefetch] [--verbose] [--verify] "
+ "[--version]\n\n"
" where the main options (shown in first group above) are:\n"
" bs must be device logical block size (default "
"512)\n"
@@ -996,7 +998,9 @@ page2:
" thr is number of threads, must be > 0, default 4, "
"max 1024\n"
" time 0->no timing, 1->calc throughput(def), "
- "2->nanosec precision\n"
+ "2->nanosec\n"
+ " precision; TO is command timeout in seconds "
+ "(def: 60)\n"
" unshare 0->don't explicitly unshare after share; 1->let "
"close do\n"
" file unshare (default)\n"
@@ -3164,7 +3168,7 @@ sg_start_io(Rq_elem * rep, mrq_arr_t & def_arr, int & pack_id,
hp->dxfer_direction = SG_DXFER_TO_DEV;
hp->mx_sb_len = sizeof(rep->sb);
hp->sbp = rep->sb;
- hp->timeout = DEF_TIMEOUT;
+ hp->timeout = clp->cmd_timeout;
hp->usr_ptr = rep;
hp->pack_id = pack_id;
hp->flags = flags;
@@ -3215,7 +3219,7 @@ do_v4:
}
h4p->max_response_len = sizeof(rep->sb);
h4p->response = (uint64_t)rep->sb;
- h4p->timeout = DEF_TIMEOUT;
+ h4p->timeout = clp->cmd_timeout;
h4p->usr_ptr = (uint64_t)rep;
h4p->request_extra = pack_id; /* this is the pack_id */
h4p->flags = flags;
@@ -4060,9 +4064,22 @@ parse_cmdline_sanity(int argc, char * argv[], struct global_collection * clp,
do_sync = !! sg_get_num(buf);
else if (0 == strcmp(key, "thr"))
num_threads = sg_get_num(buf);
- else if (0 == strcmp(key, "time"))
+ else if (0 == strcmp(key, "time")) {
do_time = sg_get_num(buf);
- else if (0 == strcmp(key, "unshare"))
+ if (do_time < 0) {
+ pr2serr("%sbad argument to 'time=0|1|2'\n", my_name);
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ cp = strchr(buf, ',');
+ if (cp) {
+ n = sg_get_num(cp + 1);
+ if (n < 0) {
+ pr2serr("%sbad argument to 'time=0|1|2,TO'\n", my_name);
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ clp->cmd_timeout = n ? (n * 1000) : DEF_TIMEOUT;
+ }
+ } else if (0 == strcmp(key, "unshare"))
clp->unshare = !! sg_get_num(buf); /* default: true */
else if (0 == strncmp(key, "verb", 4))
clp->verbose = sg_get_num(buf);
@@ -4273,6 +4290,7 @@ main(int argc, char * argv[])
/* memset(clp, 0, sizeof(*clp)); */
memset(thread_arr, 0, sizeof(thread_arr));
clp->bpt = DEF_BLOCKS_PER_TRANSFER;
+ clp->cmd_timeout = DEF_TIMEOUT;
clp->in_type = FT_OTHER;
/* change dd's default: if of=OFILE not given, assume /dev/null */
clp->out_type = FT_DEV_NULL;