aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2021-05-15 21:17:40 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2021-05-15 21:17:40 +0000
commit46fc8659ec9bfc87e58008a5341393a86ca40c52 (patch)
treeb7b8af0a5107f2c53a9215c880d8e8e0863b2ac9
parenta5226c6f336ee819b21e5b27e971fa560502c844 (diff)
downloadsg3_utils-46fc8659ec9bfc87e58008a5341393a86ca40c52.tar.gz
sg_lib: add sg_scsi_status_is_bad(); testing/ work
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@901 6180dd3e-e324-4e3e-922d-17de1ae2f315
-rw-r--r--ChangeLog5
-rw-r--r--README4
-rw-r--r--debian/changelog2
-rw-r--r--include/sg_lib.h6
-rw-r--r--lib/sg_lib.c13
-rw-r--r--sg3_utils.spec2
-rw-r--r--src/sg_dd.c8
-rw-r--r--testing/sg_mrq_dd.cpp31
-rw-r--r--testing/sgh_dd.cpp34
9 files changed, 73 insertions, 32 deletions
diff --git a/ChangeLog b/ChangeLog
index 0b55a2de..c48fc583 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,11 +2,12 @@ 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.47 [20210503] [svn: r900]
+Changelog for pre-release sg3_utils-1.47 [20210515] [svn: r901]
- sg_raw: fix prints of NVMe NVM command names
- sg_ses: fix Windows problem "No command (cdb) given"
- sg_logs: additions to Volume statistics lpage [ssc5r05c]
- - sg_lib: add sg_scsi_status_is_good()
+ - sg_lib: add sg_scsi_status_is_good() and
+ sg_scsi_status_is_bad()
- pt_linux: fix verify(BytChk=0) which Linux SNTL translated
to write, other SNTL cleanups
- pt: check_pt_file_handle() add return value of 5 for
diff --git a/README b/README
index b5e9d3ca..541562c5 100644
--- a/README
+++ b/README
@@ -540,5 +540,5 @@ Other SCSI and storage tools
See https://sg.danny.cz/sg/tools.html
-Douglas Gilbert
-8th April 2021
+Douglas Gilbert dgilbert@interlog.com
+4th May 2021
diff --git a/debian/changelog b/debian/changelog
index 77670146..fda25bee 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,7 +2,7 @@ sg3-utils (1.47-0.1) unstable; urgency=low
* New upstream version
- -- Douglas Gilbert <dgilbert@interlog.com> Sat, 01 May 2021 21:00:00 -0400
+ -- Douglas Gilbert <dgilbert@interlog.com> Sat, 15 May 2021 17:00:00 -0400
sg3-utils (1.46-0.1) unstable; urgency=low
diff --git a/include/sg_lib.h b/include/sg_lib.h
index ae228bcc..108ab873 100644
--- a/include/sg_lib.h
+++ b/include/sg_lib.h
@@ -189,9 +189,11 @@ struct sg_scsi_sense_hdr {
uint8_t additional_length; /* zero for fixed format sense data */
};
-/* Returns true when status is SAM_STAT_GOOD or SAM_STAT_CONDITION_MET,
- * returns false otherwise. Ignores bit 0. */
+/* The '_is_good()' returns true when status is SAM_STAT_GOOD or
+ * SAM_STAT_CONDITION_MET, returns false otherwise. Ignores bit 0. The
+ * '_is_bad() variant is the logical inverse. */
bool sg_scsi_status_is_good(int sstatus);
+bool sg_scsi_status_is_bad(int sstatus);
/* Maps the salient data from a sense buffer which is in either fixed or
* descriptor format into a structure mimicking a descriptor format
diff --git a/lib/sg_lib.c b/lib/sg_lib.c
index 780a3a4d..3e66e13a 100644
--- a/lib/sg_lib.c
+++ b/lib/sg_lib.c
@@ -274,6 +274,19 @@ sg_scsi_status_is_good(int sstatus)
}
}
+bool
+sg_scsi_status_is_bad(int sstatus)
+{
+ sstatus &= 0xfe;
+ switch (sstatus) {
+ case SAM_STAT_GOOD:
+ case SAM_STAT_CONDITION_MET:
+ return false;
+ default:
+ return true;
+ }
+}
+
void
sg_get_scsi_status_str(int scsi_status, int buff_len, char * buff)
{
diff --git a/sg3_utils.spec b/sg3_utils.spec
index 0d3e9642..67790c66 100644
--- a/sg3_utils.spec
+++ b/sg3_utils.spec
@@ -84,7 +84,7 @@ fi
%{_libdir}/*.la
%changelog
-* Sat May 01 2021 - dgilbert at interlog dot com
+* Sat May 15 2021 - dgilbert at interlog dot com
- track t10 changes
* sg3_utils-1.47
diff --git a/src/sg_dd.c b/src/sg_dd.c
index be90b7a0..13cfd780 100644
--- a/src/sg_dd.c
+++ b/src/sg_dd.c
@@ -70,7 +70,7 @@
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-static const char * version_str = "6.25 20210326";
+static const char * version_str = "6.26 20210512";
#define ME "sg_dd: "
@@ -1243,9 +1243,9 @@ calc_duration_throughput(bool contin)
a = res_tm.tv_sec;
a += (0.000001 * res_tm.tv_usec);
b = (double)blk_sz * blks;
- pr2serr("time to transfer data%s: %d.%06d secs",
- (contin ? " so far" : ""), (int)res_tm.tv_sec,
- (int)res_tm.tv_usec);
+ pr2serr("time to %s data%s: %d.%06d secs",
+ (do_verify ? "verify" : "copy"), (contin ? " so far" : ""),
+ (int)res_tm.tv_sec, (int)res_tm.tv_usec);
if ((a > 0.00001) && (b > 511))
pr2serr(" at %.2f MB/sec\n", b / (a * 1000000.0));
else
diff --git a/testing/sg_mrq_dd.cpp b/testing/sg_mrq_dd.cpp
index 4a486d8b..00296025 100644
--- a/testing/sg_mrq_dd.cpp
+++ b/testing/sg_mrq_dd.cpp
@@ -30,7 +30,7 @@
*
*/
-static const char * version_str = "1.27 20210424";
+static const char * version_str = "1.29 20210515";
#define _XOPEN_SOURCE 600
#ifndef _GNU_SOURCE
@@ -189,8 +189,9 @@ struct flags_t {
bool fua;
bool hipri;
bool masync; /* more async sg v4 driver fd flag */
- bool no_dur;
bool nocreat;
+ bool no_dur;
+ bool no_thresh;
bool no_waitq; /* dummy, no longer supported, just warn */
bool order_wr;
bool qhead;
@@ -721,9 +722,9 @@ calc_duration_throughput(int contin)
a = res_tm.tv_sec;
a += (0.000001 * res_tm.tv_usec);
b = (double)gcoll.bs * (gcoll.dd_count - gcoll.out_rem_count.load());
- pr2serr("time to transfer data %s %d.%06d secs",
- (contin ? "so far" : "was"), (int)res_tm.tv_sec,
- (int)res_tm.tv_usec);
+ pr2serr("time to %s data %s %d.%06d secs",
+ (gcoll.verify ? "verify" : "copy"), (contin ? "so far" : "was"),
+ (int)res_tm.tv_sec, (int)res_tm.tv_usec);
if ((a > 0.00001) && (b > 511))
pr2serr(", %.2f MB/sec\n", b / (a * 1000000.0));
else
@@ -986,6 +987,7 @@ page3:
" mmap,mmap when used twice, doesn't call munmap()\n"
" nocreat will fail rather than create OFILE\n"
" nodur turns off command duration calculations\n"
+ " no_thresh skip checking per fd max data xfer size\n"
" order require write ordering on sg->sg copy; only "
"for oflag\n"
" qhead queue new request at head of block queue\n"
@@ -1771,7 +1773,7 @@ process_mrq_response(Rq_elem * rep, const struct sg_io_v4 * ctl_v4p,
int hole_count = 0;
int cat = 0;
int vb = clp->verbose;
- int k, j, f1, slen, sstatus;
+ int k, j, f1, slen;
char b[160];
good_inblks = 0;
@@ -1815,8 +1817,7 @@ process_mrq_response(Rq_elem * rep, const struct sg_io_v4 * ctl_v4p,
pr2serr_lk("[%d] a_v4[%d]: SG_INFO_CHECK set [%s]\n", id, k,
sg_info_str(a_v4p->info, sizeof(b), b));
}
- sstatus = a_v4p->device_status;
- if ((! sg_scsi_status_is_good(sstatus)) ||
+ if (sg_scsi_status_is_bad(a_v4p->device_status) ||
a_v4p->transport_status || a_v4p->driver_status) {
ok = false;
last_err_on_in = ! (a_v4p->flags & SGV4_FLAG_DO_ON_OTHER);
@@ -2876,6 +2877,8 @@ sg_prepare_resbuf(int fd, struct global_collection *clp, bool is_in,
bool no_dur = is_in ? clp->in_flags.no_dur : clp->out_flags.no_dur;
bool masync = is_in ? clp->in_flags.masync : clp->out_flags.masync;
bool wq_excl = is_in ? clp->in_flags.wq_excl : clp->out_flags.wq_excl;
+ bool skip_thresh = is_in ? clp->in_flags.no_thresh :
+ clp->out_flags.no_thresh;
int elem_sz = clp->elem_sz;
int res, t, num, err;
uint8_t *mmp;
@@ -2912,7 +2915,7 @@ sg_prepare_resbuf(int fd, struct global_collection *clp, bool is_in,
"wr error: %s\n", __func__, strerror(errno));
}
}
- if (no_dur || masync) {
+ if (no_dur || masync || skip_thresh) {
memset(seip, 0, sizeof(*seip));
seip->sei_wr_mask |= SG_SEIM_CTL_FLAGS;
if (no_dur) {
@@ -2927,6 +2930,10 @@ sg_prepare_resbuf(int fd, struct global_collection *clp, bool is_in,
seip->ctl_flags_wr_mask |= SG_CTL_FLAGM_EXCL_WAITQ;
seip->ctl_flags |= SG_CTL_FLAGM_EXCL_WAITQ;
}
+ if (skip_thresh) {
+ seip->tot_fd_thresh = 0;
+ sei.sei_wr_mask |= SG_SEIM_TOT_FD_THRESH;
+ }
res = ioctl(fd, SG_SET_GET_EXTENDED, seip);
if (res < 0)
pr2serr_lk("sg_mrq_dd: %s: SG_SET_GET_EXTENDED(NO_DURATION) "
@@ -3119,6 +3126,12 @@ process_flags(const char * arg, struct flags_t * fp)
fp->no_dur = true;
else if (0 == strcmp(cp, "no_dur"))
fp->no_dur = true;
+ else if (0 == strcmp(cp, "nothresh"))
+ fp->no_thresh = true;
+ else if (0 == strcmp(cp, "no_thresh"))
+ fp->no_thresh = true;
+ else if (0 == strcmp(cp, "no-thresh"))
+ fp->no_thresh = true;
else if (0 == strcmp(cp, "noxfer"))
; /* accept but ignore */
else if (0 == strcmp(cp, "null"))
diff --git a/testing/sgh_dd.cpp b/testing/sgh_dd.cpp
index af226958..62c6a3e0 100644
--- a/testing/sgh_dd.cpp
+++ b/testing/sgh_dd.cpp
@@ -36,7 +36,7 @@
* renamed [20181221]
*/
-static const char * version_str = "2.06 20210427";
+static const char * version_str = "2.08 20210515";
#define _XOPEN_SOURCE 600
#ifndef _GNU_SOURCE
@@ -189,6 +189,7 @@ struct flags_t {
bool no_dur;
bool nocreat;
bool noshare;
+ bool no_thresh;
bool no_unshare; /* leave it for driver close/release */
bool no_waitq; /* dummy, no longer supported, just warn */
bool noxfer;
@@ -751,9 +752,9 @@ calc_duration_throughput(int contin)
a = res_tm.tv_sec;
a += (0.000001 * res_tm.tv_usec);
b = (double)gcoll.bs * (dd_count - gcoll.out_rem_count.load());
- pr2serr("time to transfer data %s %d.%06d secs",
- (contin ? "so far" : "was"), (int)res_tm.tv_sec,
- (int)res_tm.tv_usec);
+ pr2serr("time to %s data %s %d.%06d secs",
+ (gcoll.verify ? "verify" : "copy"), (contin ? "so far" : "was"),
+ (int)res_tm.tv_sec, (int)res_tm.tv_usec);
if ((a > 0.00001) && (b > 511))
pr2serr(", %.2f MB/sec\n", b / (a * 1000000.0));
else
@@ -1057,6 +1058,7 @@ page3:
" nocreat will fail rather than create OFILE\n"
" nodur turns off command duration calculations\n"
" noxfer no transfer to/from the user space\n"
+ " no_thresh skip checking per fd max data xfer\n"
" null does nothing, placeholder\n"
" qhead queue new request at head of block queue\n"
" qtail queue new request at tail of block queue (def: "
@@ -2366,7 +2368,7 @@ process_mrq_response(Rq_elem * rep, const struct sg_io_v4 * ctl_v4p,
int n_good = 0;
int hole_count = 0;
int vb = clp->verbose;
- int k, j, f1, slen, sstatus, blen;
+ int k, j, f1, slen, blen;
char b[160];
blen = sizeof(b);
@@ -2411,8 +2413,7 @@ process_mrq_response(Rq_elem * rep, const struct sg_io_v4 * ctl_v4p,
pr2serr_lk("[%d] a_v4[%d]: SG_INFO_CHECK set [%s]\n", id, k,
sg_info_str(a_v4p->info, sizeof(b), b));
}
- sstatus = a_v4p->device_status;
- if ((! sg_scsi_status_is_good(sstatus)) ||
+ if (sg_scsi_status_is_bad(a_v4p->device_status) ||
a_v4p->transport_status || a_v4p->driver_status) {
ok = false;
if (SAM_STAT_CHECK_CONDITION != a_v4p->device_status) {
@@ -2488,7 +2489,7 @@ chk_mrq_response(Rq_elem * rep, const struct sg_io_v4 * ctl_v4p,
int n_cmpl = ctl_v4p->info;
int n_good = 0;
int vb = clp->verbose;
- int k, slen, sstatus, blen;
+ int k, slen, blen;
uint32_t good_inblks = 0;
uint32_t good_outblks = 0;
const struct sg_io_v4 * a_np = a_v4p;
@@ -2531,8 +2532,7 @@ chk_mrq_response(Rq_elem * rep, const struct sg_io_v4 * ctl_v4p,
pr2serr_lk("[%d] a_n[%d]: SG_INFO_CHECK set [%s]\n", id, k,
sg_info_str(a_np->info, sizeof(b), b));
}
- sstatus = a_np->device_status;
- if ((! sg_scsi_status_is_good(sstatus)) ||
+ if (sg_scsi_status_is_bad(a_np->device_status) ||
a_np->transport_status || a_np->driver_status) {
ok = false;
if (SAM_STAT_CHECK_CONDITION != a_np->device_status) {
@@ -3604,6 +3604,8 @@ sg_prepare_resbuf(int fd, bool is_in, struct global_collection *clp,
bool no_dur = is_in ? clp->in_flags.no_dur : clp->out_flags.no_dur;
bool masync = is_in ? clp->in_flags.masync : clp->out_flags.masync;
bool wq_excl = is_in ? clp->in_flags.wq_excl : clp->out_flags.wq_excl;
+ bool skip_thresh = is_in ? clp->in_flags.no_thresh :
+ clp->out_flags.no_thresh;
int res, t, num;
uint8_t *mmp;
struct sg_extended_info sei;
@@ -3643,7 +3645,7 @@ sg_prepare_resbuf(int fd, bool is_in, struct global_collection *clp,
"error: %s\n", my_name, __func__, strerror(errno));
}
}
- if (no_dur || masync) {
+ if (no_dur || masync || skip_thresh) {
memset(seip, 0, sizeof(*seip));
seip->sei_wr_mask |= SG_SEIM_CTL_FLAGS;
if (no_dur) {
@@ -3658,6 +3660,10 @@ sg_prepare_resbuf(int fd, bool is_in, struct global_collection *clp,
seip->ctl_flags_wr_mask |= SG_CTL_FLAGM_EXCL_WAITQ;
seip->ctl_flags |= SG_CTL_FLAGM_EXCL_WAITQ;
}
+ if (skip_thresh) {
+ seip->tot_fd_thresh = 0;
+ sei.sei_wr_mask |= SG_SEIM_TOT_FD_THRESH;
+ }
res = ioctl(fd, SG_SET_GET_EXTENDED, seip);
if (res < 0)
pr2serr_lk("%s%s: SG_SET_GET_EXTENDED(NO_DURATION) error: %s\n",
@@ -3781,6 +3787,12 @@ process_flags(const char * arg, struct flags_t * fp)
fp->noshare = true;
else if (0 == strcmp(cp, "no_share"))
fp->noshare = true;
+ else if (0 == strcmp(cp, "no_thresh"))
+ fp->no_thresh = true;
+ else if (0 == strcmp(cp, "no-thresh"))
+ fp->no_thresh = true;
+ else if (0 == strcmp(cp, "nothresh"))
+ fp->no_thresh = true;
else if (0 == strcmp(cp, "no_unshare"))
fp->no_unshare = true;
else if (0 == strcmp(cp, "no-unshare"))