aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2020-07-13 01:43:10 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2020-07-13 01:43:10 +0000
commitb07ad28107659f532c54659f5ecd12eaf086ea0b (patch)
tree34ec5e3a6412e3535fe5f2ed3ee5fe3ba08daf34
parent2c59b7853f594c9b3fa7e3f259f7b45ab6d47903 (diff)
downloadsg3_utils-b07ad28107659f532c54659f5ecd12eaf086ea0b.tar.gz
sg_lib: asc/ascq match asc-num.txt @t10 20200708 [spc6r02]; work on testing/sg_mrq_dd.cpp
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@854 6180dd3e-e324-4e3e-922d-17de1ae2f315
-rw-r--r--ChangeLog4
-rw-r--r--lib/sg_lib_data.c9
-rw-r--r--lib/sg_pt_solaris.c25
-rw-r--r--src/sg_luns.c2
-rw-r--r--testing/sg_mrq_dd.cpp601
-rw-r--r--testing/sgh_dd.cpp390
6 files changed, 549 insertions, 482 deletions
diff --git a/ChangeLog b/ChangeLog
index 2371a8ac..6863eb30 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 sg3_utils-1.46 [20200701] [svn: r853]
+Changelog for sg3_utils-1.46 [20200712] [svn: r854]
- sg_rep_pip: report new provisioning initialization pattern cmd
- sg_dd: separate category for miscompare errors
- sg_get_elem_status: add ralwd bit sbc4r20a
@@ -16,7 +16,7 @@ Changelog for sg3_utils-1.46 [20200701] [svn: r853]
- add dummy start stop unit and test unit ready commands
- wire cache mpage's WCE to nvme 'volatile write cache'
- sg_lib: reprint cdb with illegal request sense key
- - asc/ascq match asc-num.txt @t10 20200624
+ - asc/ascq match asc-num.txt @t10 20200708 [spc6r02]
- testing/sg_mrq_testing: new, for blocking mrq usage
- testing/sgs_dd: add evfd flags and eventfd processing
- testing/sgh_dd: various fixes
diff --git a/lib/sg_lib_data.c b/lib/sg_lib_data.c
index b7417d03..e64c240d 100644
--- a/lib/sg_lib_data.c
+++ b/lib/sg_lib_data.c
@@ -19,8 +19,8 @@
#include "sg_lib_data.h"
-const char * sg_lib_version_str = "2.75 20200624";
-/* spc6r01, sbc4r20a, zbc2r04 */
+const char * sg_lib_version_str = "2.76 20200708";
+/* spc6r02, sbc4r20a, zbc2r04 */
/* indexed by pdt; those that map to own index do not decay */
@@ -726,6 +726,7 @@ struct sg_lib_asc_ascq_t sg_lib_asc_ascq[] =
{0x04,0x22,"Logical unit not ready, power cycle required"},
{0x04,0x23,"Logical unit not ready, affiliation required"},
{0x04,0x24,"Depopulation in progress"}, /* spc5r15 */
+ {0x04,0x25,"Depopulation restoration in progress"}, /* spc6r02 */
{0x05,0x00,"Logical unit does not respond to selection"},
{0x06,0x00,"No reference position found"},
{0x07,0x00,"Multiple peripheral devices selected"},
@@ -1004,6 +1005,7 @@ struct sg_lib_asc_ascq_t sg_lib_asc_ascq[] =
{0x2C,0x10,"Unwritten data in zone"},
{0x2C,0x11,"Descriptor format sense data required"},
{0x2C,0x12,"Zone is inactive"},
+ {0x2C,0x13,"Well known logical unit access required"}, /* spc6r02 */
{0x2D,0x00,"Overwrite error on update in place"},
{0x2E,0x00,"Insufficient time for operation"},
{0x2E,0x01,"Command timeout before processing"},
@@ -1035,7 +1037,8 @@ struct sg_lib_asc_ascq_t sg_lib_asc_ascq[] =
{0x31,0x01,"Format command failed"},
{0x31,0x02,"Zoned formatting failed due to spare linking"},
{0x31,0x03,"Sanitize command failed"},
- {0x31,0x04,"Depopulation failed"}, /* spc5r15 */
+ {0x31,0x04,"Depopulation failed"}, /* spc5r15 */
+ {0x31,0x05,"Depopulation restoration failed"}, /* spc6r02 */
{0x32,0x00,"No defect spare location available"},
{0x32,0x01,"Defect list update failure"},
{0x33,0x00,"Tape length error"},
diff --git a/lib/sg_pt_solaris.c b/lib/sg_pt_solaris.c
index 3d0cb228..fa68f8ba 100644
--- a/lib/sg_pt_solaris.c
+++ b/lib/sg_pt_solaris.c
@@ -7,7 +7,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
-/* sg_pt_solaris version 1.11 20190113 */
+/* sg_pt_solaris version 1.12 20200712 */
#include <stdio.h>
#include <stdlib.h>
@@ -103,8 +103,8 @@ construct_scsi_pt_obj_with_fd(int dev_fd, int verbose)
ptp->dev_fd = (dev_fd < 0) ? -1 : dev_fd;
ptp->is_nvme = false;
ptp->uscsi.uscsi_timeout = DEF_TIMEOUT;
- ptp->uscsi.uscsi_flags = USCSI_READ | USCSI_ISOLATE | USCSI_RQENABLE;
- ptp->uscsi.uscsi_timeout = DEF_TIMEOUT;
+// ptp->uscsi.uscsi_flags = USCSI_READ | USCSI_ISOLATE | USCSI_RQENABLE;
+ ptp->uscsi.uscsi_flags = USCSI_ISOLATE | USCSI_RQENABLE;
} else if (verbose)
fprintf(sg_warnings_strm ? sg_warnings_strm : stderr,
"%s: calloc() out of memory\n", __func__);
@@ -134,8 +134,8 @@ clear_scsi_pt_obj(struct sg_pt_base * vp)
if (ptp) {
memset(ptp, 0, sizeof(struct sg_pt_solaris_scsi));
ptp->uscsi.uscsi_timeout = DEF_TIMEOUT;
- ptp->uscsi.uscsi_flags = USCSI_READ | USCSI_ISOLATE | USCSI_RQENABLE;
- ptp->uscsi.uscsi_timeout = DEF_TIMEOUT;
+// ptp->uscsi.uscsi_flags = USCSI_READ | USCSI_ISOLATE | USCSI_RQENABLE;
+ ptp->uscsi.uscsi_flags = USCSI_ISOLATE | USCSI_RQENABLE;
}
}
@@ -284,6 +284,11 @@ do_scsi_pt(struct sg_pt_base * vp, int fd, int time_secs, int verbose)
if (time_secs > 0)
ptp->uscsi.uscsi_timeout = time_secs;
+// Test code: address rejection of TUR (no data xfer) with EINVAL
+if (NULL == ptp->uscsi.uscsi_bufaddr)
+ ptp->uscsi.uscsi_bufaddr = ptp->uscsi.uscsi_rqbuf; /* give it a buffer address even though not used */
+// End of Test code 20200712 dpg
+
if (ioctl(ptp->dev_fd, USCSICMD, &ptp->uscsi)) {
ptp->os_err = errno;
if ((EIO == ptp->os_err) && ptp->uscsi.uscsi_status) {
@@ -335,8 +340,8 @@ void
get_pt_req_lengths(const struct sg_pt_base * vp, int * req_dinp,
int * req_doutp)
{
- const struct sg_pt_freebsd_scsi * ptp = &vp->impl;
- int dxfer_len = ptp->uscsi.uscsi_buflen
+ const struct sg_pt_solaris_scsi * ptp = &vp->impl;
+ int dxfer_len = ptp->uscsi.uscsi_buflen;
int flags = ptp->uscsi.uscsi_flags;
if (req_dinp) {
@@ -357,8 +362,8 @@ void
get_pt_actual_lengths(const struct sg_pt_base * vp, int * act_dinp,
int * act_doutp)
{
- const struct sg_pt_freebsd_scsi * ptp = &vp->impl;
- int dxfer_len = ptp->uscsi.uscsi_buflen
+ const struct sg_pt_solaris_scsi * ptp = &vp->impl;
+ int dxfer_len = ptp->uscsi.uscsi_buflen;
int flags = ptp->uscsi.uscsi_flags;
if (act_dinp) {
@@ -415,7 +420,7 @@ get_scsi_pt_duration_ms(const struct sg_pt_base * vp)
/* If not available return 0 otherwise return number of nanoseconds that the
* lower layers (and hardware) took to execute the command just completed. */
-uint64_t
+uint64_t
get_pt_duration_ns(const struct sg_pt_base * vp __attribute__ ((unused)))
{
return 0;
diff --git a/src/sg_luns.c b/src/sg_luns.c
index 5217ea98..62a2e6ca 100644
--- a/src/sg_luns.c
+++ b/src/sg_luns.c
@@ -34,7 +34,7 @@
* and decodes the response.
*/
-static const char * version_str = "1.44 20200115";
+static const char * version_str = "1.45 20200708"; /* spc6r02 */
#define MAX_RLUNS_BUFF_LEN (1024 * 1024)
#define DEF_RLUNS_BUFF_LEN (1024 * 8)
diff --git a/testing/sg_mrq_dd.cpp b/testing/sg_mrq_dd.cpp
index a42cff74..846d381a 100644
--- a/testing/sg_mrq_dd.cpp
+++ b/testing/sg_mrq_dd.cpp
@@ -36,7 +36,7 @@
* renamed [20181221]
*/
-static const char * version_str = "1.01 20200701";
+static const char * version_str = "1.02 20200709";
#define _XOPEN_SOURCE 600
#ifndef _GNU_SOURCE
@@ -348,14 +348,10 @@ struct global_collection /* one instance visible to all threads */
int mrq_num; /* Number of multi-reqs for sg v4 */
int outfd;
int out_type;
- int out2fd;
- int out2_type;
- off_t out2_st_size; /* Only for FT_OTHER (regular) file */
int cdbsz_out;
struct flags_t out_flags;
atomic<int64_t> out_rem_count; /* | count of remaining out blocks */
atomic<int> out_partial; /* | */
- // pthread_mutex_t out2_mutex;
off_t out_st_size; /* Only for FT_OTHER (regular) file */
condition_variable infant_cv; /* after thread:0 does first segment */
mutex infant_mut;
@@ -367,20 +363,18 @@ struct global_collection /* one instance visible to all threads */
off_t outreg_st_size;
atomic<int> dio_incomplete_count;
atomic<int> sum_of_resids;
- int verbose; /* both -v and deb=VERB bump this field */
+ int verbose;
int dry_run;
bool cdbsz_given;
bool count_given;
bool flexible;
bool ofile_given;
- bool ofile2_given;
bool unit_nanosec; /* default duration unit is millisecond */
bool mrq_cmds; /* mrq=<NRQS>,C given */
bool verify; /* don't copy, verify like Unix: cmp */
bool prefetch; /* for verify: do PF(b),RD(a),V(b)_a_data */
const char * infp;
const char * outfp;
- const char * out2fp;
class scat_gath_list i_sgl;
class scat_gath_list o_sgl;
};
@@ -397,7 +391,6 @@ typedef struct request_element
int id;
int infd;
int outfd;
- int out2fd;
int outregfd;
uint8_t * buffp;
uint8_t * alloc_bp;
@@ -429,7 +422,6 @@ typedef struct request_element
/* Additional parameters for sg_start_io() and sg_finish_io() */
struct sg_io_extra {
- bool is_wr2;
bool prefetch;
bool dout_is_split;
int hpv4_ind;
@@ -464,7 +456,9 @@ static atomic<long int> pos_index(0);
static atomic<int> num_ebusy(0);
static atomic<int> num_start_eagain(0);
static atomic<int> num_fin_eagain(0);
+#if 0
static atomic<long> num_waiting_calls(0);
+#endif
static sigset_t signal_set;
@@ -703,8 +697,57 @@ fini:
return b;
}
+/* Info field decoded into abbreviations for those bits that are set,
+ * separated by '|' . */
+static char *
+sg_info_str(int info, int b_len, char * b)
+{
+ int n = 0;
+
+ if ((b_len < 1) || (! b))
+ return b;
+ b[0] = '\0';
+ if (SG_INFO_CHECK & info) { /* 0x1 */
+ n += sg_scnpr(b + n, b_len - n, "CHK|");
+ if (n >= b_len)
+ goto fini;
+ }
+ if (SG_INFO_DIRECT_IO & info) { /* 0x2 */
+ n += sg_scnpr(b + n, b_len - n, "DIO|");
+ if (n >= b_len)
+ goto fini;
+ }
+ if (SG_INFO_MIXED_IO & info) { /* 0x4 */
+ n += sg_scnpr(b + n, b_len - n, "MIO|");
+ if (n >= b_len)
+ goto fini;
+ }
+ if (SG_INFO_DEVICE_DETACHING & info) { /* 0x8 */
+ n += sg_scnpr(b + n, b_len - n, "DETA|");
+ if (n >= b_len)
+ goto fini;
+ }
+ if (SG_INFO_ABORTED & info) { /* 0x10 */
+ n += sg_scnpr(b + n, b_len - n, "ABRT|");
+ if (n >= b_len)
+ goto fini;
+ }
+ if (SG_INFO_MRQ_FINI & info) { /* 0x20 */
+ n += sg_scnpr(b + n, b_len - n, "MRQF|");
+ if (n >= b_len)
+ goto fini;
+ }
+fini:
+ if (n < b_len) { /* trim trailing '\' */
+ if ('|' == b[n - 1])
+ b[n - 1] = '\0';
+ } else if ('|' == b[b_len - 1])
+ b[b_len - 1] = '\0';
+ return b;
+}
+
static void
-v4hdr_out_lk(const char * leadin, const sg_io_v4 * h4p, int id)
+v4hdr_out_lk(const char * leadin, const sg_io_v4 * h4p, int id, bool chk_info)
{
lock_guard<mutex> lk(strerr_mut);
char b[80];
@@ -723,7 +766,7 @@ v4hdr_out_lk(const char * leadin, const sg_io_v4 * h4p, int id)
pr2serr(" flags=0x%x request_extra{pack_id}=%d\n",
h4p->flags, h4p->request_extra);
pr2serr(" flags set: %s\n", sg_flags_str(h4p->flags, sizeof(b), b));
- pr2serr(" OUT:\n");
+ pr2serr(" %s OUT:\n", leadin);
pr2serr(" response_len=%d driver/transport/device_status="
"0x%x/0x%x/0x%x\n", h4p->response_len, h4p->driver_status,
h4p->transport_status, h4p->device_status);
@@ -731,6 +774,8 @@ v4hdr_out_lk(const char * leadin, const sg_io_v4 * h4p, int id)
"dur=%u\n",
h4p->info, h4p->din_resid, h4p->dout_resid, h4p->spare_out,
h4p->duration);
+ if (chk_info && (SG_INFO_CHECK & h4p->info))
+ pr2serr(" >>>> info: %s\n", sg_info_str(h4p->info, sizeof(b), b));
}
static void
@@ -757,6 +802,8 @@ fetch_sg_version(void)
have_sg_version = !!sg_version;
}
}
+ if (NULL == fp)
+ pr2serr("The sg driver may not be loaded\n");
}
if (fp)
fclose(fp);
@@ -855,7 +902,7 @@ install_handler(int sig_num, void (*sig_handler) (int sig))
}
}
-#if 0 /* SG_LIB_ANDROID */
+#if 0 /* SG_LIB_ANDROID */
static void
thread_exit_handler(int sig)
{
@@ -930,16 +977,13 @@ usage(int pg_num)
" [obs=BS] [of=OFILE] [oflag=FLAGS] "
"[seek=SEEK]\n"
" [skip=SKIP] [--help] [--version]\n\n");
- pr2serr(" [bpt=BPT] [cdbsz=6|10|12|16] "
- "[coe=0|1]\n"
- " [deb=VERB] [dio=0|1]\n"
- " [fua=0|1|2|3] [mrq=MRQ[,C]] "
- "[of2=OFILE2]\n"
- " [ofreg=OFREG] [sync=0|1] [thr=THR] "
+ pr2serr(" [bpt=BPT] [cdbsz=6|10|12|16] [dio=0|1] "
+ "[fua=0|1|2|3]\n"
+ " [mrq=MRQ] [ofreg=OFREG] [sync=0|1] [thr=THR] "
"[time=0|1]\n"
- " [verbose=VERB] [--dry-run] "
- "\n"
- " [--verbose] [--verify] [--version]\n\n"
+ " [verbose=VERB] [--dry-run] [--verbose] "
+ "[--verify]\n"
+ " [--version]\n\n"
" where the main options (shown in first group above) are:\n"
" bs must be device logical block size (default "
"512)\n"
@@ -950,14 +994,11 @@ usage(int pg_num)
" dsync,excl,fua,masync,mmap,nodur,\n"
" null,order,qtail,serial,wq_excl]\n"
" mrq number of cmds placed in each sg call "
- "(def: 16);\n"
- " may have trailing ',C', to send bulk cdb_s\n"
+ "(def: 16)\n"
" of file or device to write to (def: /dev/null "
"N.B. different\n"
" from dd it defaults to stdout). If 'of=.' "
"uses /dev/null\n"
- " of2 second file or device to write to (def: "
- "/dev/null)\n"
" oflag comma separated list from: [append,<<list from "
"iflag>>]\n"
" seek block position to start writing to OFILE\n"
@@ -968,12 +1009,13 @@ usage(int pg_num)
"copy]\n"
" --version|-V output version string then exit\n\n"
"Copy IFILE to OFILE, similar to dd command. This utility is "
- "specialized for\nSCSI devices and uses multiple POSIX threads. "
- "It expects one or both IFILE\nand OFILE to be sg devices. With "
- "--verify option does a verify/compare\noperation instead of a "
- "copy. This utility is Linux specific and uses the\nv4 sg "
- "driver 'share' capability if available. Use '-hh', '-hhh' or "
- "'-hhhh'\nfor more information.\n"
+ "specialized for\nSCSI devices and uses the 'multiple requests' "
+ "(mrq) in a single invocation\nfacility in version 4 of the sg "
+ "driver. Usually one or both IFILE and\nOFILE will be sg "
+ "devices. With the --verify option it does a\n"
+ "verify/compare operation instead of a copy. This utility is "
+ "Linux\n specific. Use '-hh', '-hhh' or '-hhhh' for more "
+ "information.\n"
);
return;
page2:
@@ -986,10 +1028,6 @@ page2:
" bpt is blocks_per_transfer (default is 128)\n"
" cdbsz size of SCSI READ, WRITE or VERIFY cdb_s "
"(default is 10)\n"
- " coe continue on error, 0->exit (def), "
- "1->zero + continue\n"
- " deb for debug, 0->none (def), > 0->varying degrees "
- "of debug\n"
" dio is direct IO, 1->attempt, 0->indirect IO (def)\n"
" fua force unit access: 0->don't(def), 1->OFILE, "
"2->IFILE,\n"
@@ -1003,7 +1041,7 @@ page2:
"max 1024\n"
" time 0->no timing, 1->calc throughput(def), "
"2->nanosec precision\n"
- " verbose same as 'deb=VERB': increase verbosity\n"
+ " verbose increase verbosity (def: VERB=0)\n"
" --dry-run|-d prepare but bypass copy/read\n"
" --verbose|-v increase verbosity of utility\n\n"
"Use '-hhh' or '-hhhh' for more information about flags.\n"
@@ -1045,8 +1083,8 @@ page3:
" wq_excl set SG_CTL_FLAGM_EXCL_WAITQ on this sg fd\n"
"\n"
"Copies IFILE to OFILE (and to OFILE2 if given). If IFILE and "
- "OFILE are sg\ndevices 'shared' mode is selected. of2=OFILE2 "
- "uses 'oflag=FLAGS'. When sharing, the data stays in a\nsingle "
+ "OFILE are sg\ndevices 'shared' mode is selected. "
+ "When sharing, the data stays in a\nsingle "
"in-kernel buffer which is copied (or mmap-ed) to the user "
"space\nif the 'ofreg=OFREG' is given. Use '-hhhh' for more "
"information.\n"
@@ -2124,24 +2162,6 @@ global_collection::get_next(int desired_num_blks)
return make_pair(expected, desired - expected);
}
-#if 0
-/* Returns the number of times either 'ch1' or 'ch2' is found in
- * string 's' given the string's length. */
-static int
-num_either_ch_in_str(const char * s, int slen, int ch1, int ch2)
-{
- int k;
- int res = 0;
-
- while (--slen >= 0) {
- k = s[slen];
- if ((ch1 == k) || (ch2 == k))
- ++res;
- }
- return res;
-}
-#endif
-
/* Return of 0 -> success, see sg_ll_read_capacity*() otherwise */
static int
scsi_read_capacity(int sg_fd, int64_t * num_sect, int * sect_sz)
@@ -2287,7 +2307,6 @@ read_write_thread(struct global_collection * clp, int id, bool singleton)
bool own_infd = false;
bool in_is_sg, in_mmap, out_is_sg, out_mmap;
bool own_outfd = false;
- bool own_out2fd = false;
bool only_one_sg = false;
// bool share_and_ofreg;
class scat_gath_iter i_sg_it(clp->i_sgl);
@@ -2326,7 +2345,6 @@ read_write_thread(struct global_collection * clp, int id, bool singleton)
}
rep->infd = clp->infd;
rep->outfd = clp->outfd;
- rep->out2fd = clp->out2fd;
rep->outregfd = clp->outregfd;
rep->rep_count = 0;
rep->in_follow_on = -1;
@@ -2377,25 +2395,11 @@ read_write_thread(struct global_collection * clp, int id, bool singleton)
if (vb > 2)
pr2serr_lk("[%d]: opened local sg OFILE\n", id);
}
- if ((FT_SG == clp->out2_type) && clp->out2fp) {
- fd = sg_out_open(clp, clp->out2fp,
- (out_mmap ? &rep->buffp : NULL),
- (out_mmap ? &rep->mmap_len : NULL));
- if (fd < 0)
- goto fini;
- rep->out2fd = fd;
- own_out2fd = true;
- if (vb > 2)
- pr2serr_lk("[%d]: opened local sg OFILE2\n", id);
- }
if (vb > 2) {
if (in_is_sg && (! own_infd))
pr2serr_lk("[%d]: using global sg IFILE, fd=%d\n", id, rep->infd);
if (out_is_sg && (! own_outfd))
pr2serr_lk("[%d]: using global sg OFILE, fd=%d\n", id, rep->outfd);
- if ((FT_SG == clp->out2_type) && (! own_out2fd))
- pr2serr_lk("[%d]: using global sg OFILE2, fd=%d\n", id,
- rep->out2fd);
}
if (rep->both_sg)
rep->has_share = sg_share_prepare(rep->outfd, rep->infd, id, vb > 9);
@@ -2501,7 +2505,9 @@ fini:
if (own_infd && (rep->infd >= 0)) {
if (vb && in_is_sg) {
+#if 0
++num_waiting_calls;
+#endif
if (ioctl(rep->infd, SG_GET_NUM_WAITING, &n) >= 0) {
if (n > 0)
pr2serr_lk("%s: tid=%d: num_waiting=%d prior close(in)\n",
@@ -2516,7 +2522,9 @@ fini:
}
if (own_outfd && (rep->outfd >= 0)) {
if (vb && out_is_sg) {
+#if 0
++num_waiting_calls;
+#endif
if (ioctl(rep->outfd, SG_GET_NUM_WAITING, &n) >= 0) {
if (n > 0)
pr2serr_lk("%s: tid=%d: num_waiting=%d prior "
@@ -2529,8 +2537,6 @@ fini:
}
close(rep->outfd);
}
- if (own_out2fd && (rep->out2fd >= 0))
- close(rep->out2fd);
/* pass stats back to master */
clp->in_rem_count -= rep->in_local_count;
clp->out_rem_count -= rep->out_local_count;
@@ -2785,177 +2791,140 @@ sg_build_scsi_cdb(uint8_t * cdbp, int cdb_sz, unsigned int blocks,
return 0;
}
-#if 0
-
-static bool
-sg_wr_swap_share(Rq_elem * rep, int to_fd, bool before)
-{
- bool not_first = false;
- int err = 0;
- int k;
- int master_fd = rep->infd; /* in (READ) side is master */
- struct global_collection * clp = rep->clp;
- struct sg_extended_info sei;
- struct sg_extended_info * seip = &sei;
-
- if (rep->clp->verbose > 2)
- pr2serr_lk("%s: tid=%d: to_fd=%d, before=%d\n", __func__, rep->id,
- to_fd, (int)before);
- memset(seip, 0, sizeof(*seip));
- seip->sei_wr_mask |= SG_SEIM_CHG_SHARE_FD;
- seip->sei_rd_mask |= SG_SEIM_CHG_SHARE_FD;
- seip->share_fd = to_fd;
- if (before) {
- /* clear MASTER_FINI bit to put master in SG_RQ_SHR_SWAP state */
- seip->sei_wr_mask |= SG_SEIM_CTL_FLAGS;
- seip->sei_rd_mask |= SG_SEIM_CTL_FLAGS;
- seip->ctl_flags_wr_mask |= SG_CTL_FLAGM_MASTER_FINI;
- seip->ctl_flags &= SG_CTL_FLAGM_MASTER_FINI;/* would be 0 anyway */
- }
- for (k = 0; (ioctl(master_fd, SG_SET_GET_EXTENDED, seip) < 0) &&
- (EBUSY == errno); ++k) {
- err = errno;
- if (k > 10000)
- break;
- if (! not_first) {
- if (clp->verbose > 3)
- pr2serr_lk("tid=%d: ioctl(EXTENDED(change_shared_fd=%d), "
- "failed errno=%d %s\n", rep->id, master_fd, err,
- strerror(err));
- not_first = true;
- }
- err = 0;
- std::this_thread::yield();/* another thread may be able to progress */
- }
- if (err) {
- pr2serr_lk("tid=%d: ioctl(EXTENDED(change_shared_fd=%d), failed "
- "errno=%d %s\n", rep->id, master_fd, err, strerror(err));
- return false;
- }
- if (clp->verbose > 15)
- pr2serr_lk("%s: tid=%d: ioctl(EXTENDED(change_shared_fd)) ok, "
- "master_fd=%d, to_slave_fd=%d\n", __func__, rep->id,
- master_fd, to_fd);
- return true;
-}
-
-#endif
-
static int
process_mrq_response(Rq_elem * rep, const struct sg_io_v4 * ctl_v4p,
const struct sg_io_v4 * a_v4p, int num_mrq,
- uint32_t & good_inblks, uint32_t & good_outblks)
+ uint32_t & good_inblks, uint32_t & good_outblks,
+ bool & last_err_on_in)
{
struct global_collection * clp = rep->clp;
- bool ok;
+ bool ok, all_good;
+ bool sb_in_co = !!(ctl_v4p->response);
int id = rep->id;
int resid = ctl_v4p->din_resid;
int sres = ctl_v4p->spare_out;
int n_subm = num_mrq - ctl_v4p->dout_resid;
int n_cmpl = ctl_v4p->info;
int n_good = 0;
+ int hole_count = 0;
int vb = clp->verbose;
- int k, slen, sstatus;
- const struct sg_io_v4 * a_np = a_v4p;
+ int k, j, f1, slen, sstatus, blen;
+ char b[80];
+ blen = sizeof(b);
good_inblks = 0;
good_outblks = 0;
+ if (vb > 2)
+ pr2serr_lk("[thread_id=%d] %s: num_mrq=%d, n_subm=%d, n_cmpl=%d\n",
+ id, __func__, num_mrq, n_subm, n_cmpl);
if (n_subm < 0) {
- pr2serr_lk("[%d] %s: co.dout_resid(%d) > num_mrq(%d)\n", id, __func__,
+ pr2serr_lk("[%d] co.dout_resid(%d) > num_mrq(%d)\n", id,
ctl_v4p->dout_resid, num_mrq);
return -1;
}
if (n_cmpl != (num_mrq - resid))
- pr2serr_lk("[%d] %s: co.info(%d) != (num_mrq(%d) - co.din_resid(%d))\n"
- "will use co.info\n", id, __func__, n_cmpl, num_mrq, resid);
+ pr2serr_lk("[%d] co.info(%d) != (num_mrq(%d) - co.din_resid(%d))\n"
+ "will use co.info\n", id, n_cmpl, num_mrq, resid);
if (n_cmpl > n_subm) {
- pr2serr_lk("[%d] %s: n_cmpl(%d) > n_subm(%d), use n_subm for both\n",
- id, __func__, n_cmpl, n_subm);
+ pr2serr_lk("[%d] n_cmpl(%d) > n_subm(%d), use n_subm for both\n",
+ id, n_cmpl, n_subm);
n_cmpl = n_subm;
}
if (sres) {
- pr2serr_lk("[%d] %s: secondary error: %s [%d], info=0x%x\n", id,
- __func__, strerror(sres), sres, ctl_v4p->info);
+ pr2serr_lk("[%d] secondary error: %s [%d], info=0x%x\n", id,
+ strerror(sres), sres, ctl_v4p->info);
if (E2BIG == sres) {
sg_take_snap(rep->infd, id, true);
sg_take_snap(rep->outfd, id, true);
}
}
- /* Check if those submitted have finished or not */
- for (k = 0; k < n_subm; ++k, ++a_np) {
- slen = a_np->response_len;
- if (! (SG_INFO_MRQ_FINI & a_np->info)) {
- pr2serr_lk("[%d] %s, a_n[%d]: missing SG_INFO_MRQ_FINI ? ?\n",
- id, __func__, k);
- v4hdr_out_lk("a_np", a_np, id);
- v4hdr_out_lk("cop", ctl_v4p, id);
- }
+ /* Check if those submitted have finished or not. N.B. If there has been
+ * an error then there may be "holes" (i.e. info=0x0) in the array due
+ * to completions being out-of-order. */
+ for (k = 0, j = 0; ((k < num_mrq) && (j < n_subm));
+ ++k, j += f1, ++a_v4p) {
+ slen = a_v4p->response_len;
+ if (! (SG_INFO_MRQ_FINI & a_v4p->info))
+ ++hole_count;
ok = true;
- sstatus = a_np->device_status;
+ f1 = !!(a_v4p->info); /* want to skip n_subm count if info is 0x0 */
+ if (SG_INFO_CHECK & a_v4p->info) {
+ ok = false;
+ 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 ((sstatus && (SAM_STAT_CONDITION_MET != sstatus)) ||
- a_np->transport_status || a_np->driver_status) {
+ a_v4p->transport_status || a_v4p->driver_status) {
ok = false;
- if (SAM_STAT_CHECK_CONDITION != a_np->device_status) {
- pr2serr_lk("[%d] %s, a_n[%d]:\n", id, __func__, k);
+ last_err_on_in = ! (a_v4p->flags & SGV4_FLAG_DO_ON_OTHER);
+ if (SAM_STAT_CHECK_CONDITION != a_v4p->device_status) {
+ pr2serr_lk("[%d] a_v4[%d]:\n", id, k);
if (vb)
- lk_chk_n_print4(" >>", a_np, false);
+ lk_chk_n_print4(" >>", a_v4p, vb > 4);
}
}
if (slen > 0) {
struct sg_scsi_sense_hdr ssh;
- const uint8_t *sbp = (const uint8_t *)a_np->response;
+ const uint8_t *sbp = (const uint8_t *)
+ (sb_in_co ? ctl_v4p->response : a_v4p->response);
if (sg_scsi_normalize_sense(sbp, slen, &ssh) &&
(ssh.response_code >= 0x70)) {
char b[256];
- if (ssh.response_code & 0x1)
+ if (ssh.response_code & 0x1) {
ok = true;
+ last_err_on_in = false;
+ }
if (vb) {
- sg_get_sense_str(" ", sbp, slen, false, sizeof(b), b);
- pr2serr_lk("[%d] %s, a_n[%d]:\n%s\n", id, __func__, k, b);
+ sg_get_sense_str(" ", sbp, slen, false, blen, b);
+ pr2serr_lk("[%d] a_v4[%d]:\n%s\n", id, k, b);
}
}
}
- if (ok) {
+ if (ok && f1) {
++n_good;
- if (a_np->dout_xfer_len >= (uint32_t)clp->bs) {
- if (a_np->dout_resid)
- good_outblks += (a_np->dout_xfer_len - a_np->dout_resid) /
- clp->bs;
+ if (a_v4p->dout_xfer_len >= (uint32_t)clp->bs) {
+ if (a_v4p->dout_resid)
+ good_outblks +=
+ (a_v4p->dout_xfer_len - a_v4p->dout_resid) / clp->bs;
else /* avoid division in common case of resid==0 */
- good_outblks += (uint32_t)a_np->usr_ptr;
+ good_outblks += (uint32_t)a_v4p->usr_ptr;
}
- if (a_np->din_xfer_len >= (uint32_t)clp->bs) {
- if (a_np->din_resid)
- good_inblks += (a_np->din_xfer_len - a_np->din_resid) /
+ if (a_v4p->din_xfer_len >= (uint32_t)clp->bs) {
+ if (a_v4p->din_resid)
+ good_inblks += (a_v4p->din_xfer_len - a_v4p->din_resid) /
clp->bs;
else
- good_inblks += (uint32_t)a_np->usr_ptr;
+ good_inblks += (uint32_t)a_v4p->usr_ptr;
}
}
- }
+ } /* end of request array scan loop */
if ((n_subm == num_mrq) || (vb < 3))
goto fini;
- pr2serr_lk("[%d] %s: checking response array beyond number of "
- "submissions:\n", id, __func__);
- for (k = n_subm; k < num_mrq; ++k, ++a_np) {
- if (SG_INFO_MRQ_FINI & a_np->info)
- pr2serr_lk("[%d] %s, a_n[%d]: unexpected SG_INFO_MRQ_FINI set\n",
- id, __func__, k);
- if (a_np->device_status || a_np->transport_status ||
- a_np->driver_status) {
- pr2serr_lk("[%d] %s, a_n[%d]:\n", id, __func__, k);
- lk_chk_n_print4(" ", a_np, false);
+ if (vb)
+ pr2serr_lk("[%d] checking response array _beyond_ number of "
+ "submissions [%d] to num_mrq:\n", id, k);
+ for (all_good = true; k < num_mrq; ++k, ++a_v4p) {
+ if (SG_INFO_MRQ_FINI & a_v4p->info) {
+ pr2serr_lk("[%d] a_v4[%d]: unexpected SG_INFO_MRQ_FINI set [%s]\n",
+ id, k, sg_info_str(a_v4p->info, sizeof(b), b));
+ all_good = false;
+ }
+ if (a_v4p->device_status || a_v4p->transport_status ||
+ a_v4p->driver_status) {
+ pr2serr_lk("[%d] a_v4[%d]:\n", id, k);
+ lk_chk_n_print4(" ", a_v4p, vb > 4);
+ all_good = false;
}
}
+ if (all_good)
+ pr2serr_lk(" ... all good\n");
fini:
return n_good;
}
-
-// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< zzzzzzzzz
-
/* Returns number of blocks successfully processed or a negative error
* number. */
static int
@@ -2982,6 +2951,8 @@ sg_half_segment(Rq_elem * rep, scat_gath_iter & sg_it, bool is_wr,
struct sg_io_v4 * t_v4p = &t_v4;
struct flags_t * flagsp = is_wr ? &clp->out_flags : &clp->in_flags;
bool serial = flagsp->serial;
+ bool err_on_in = false;
+ int vb = clp->verbose;
id = rep->id;
b_len = sizeof(b);
@@ -3019,7 +2990,7 @@ sg_half_segment(Rq_elem * rep, scat_gath_iter & sg_it, bool is_wr,
if (res) {
pr2serr_lk("[%d] %s: sg_build_scsi_cdb() failed\n", id, __func__);
break;
- } else if (clp->verbose > 3)
+ } else if (vb > 3)
lk_print_command_len("cdb: ", t_cdb.data(), cdbsz, true);
a_cdb.push_back(t_cdb);
@@ -3060,7 +3031,9 @@ sg_half_segment(Rq_elem * rep, scat_gath_iter & sg_it, bool is_wr,
ctl_v4.request = (uint64_t)a_cdb.data();
ctl_v4.max_response_len = sizeof(rep->sb);
ctl_v4.response = (uint64_t)rep->sb;
- ctl_v4.flags = SGV4_FLAG_MULTIPLE_REQS | SGV4_FLAG_STOP_IF;
+ ctl_v4.flags = SGV4_FLAG_MULTIPLE_REQS;
+ if (! flagsp->coe)
+ ctl_v4.flags |= SGV4_FLAG_STOP_IF;
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 */
@@ -3068,16 +3041,16 @@ sg_half_segment(Rq_elem * rep, scat_gath_iter & sg_it, bool is_wr,
if (false /* allow_mrq_abort */)
ctl_v4.request_extra = mrq_pack_id_base + ++rep->mrq_pack_id_off;
- if (clp->verbose > 4) {
- pr2serr_lk("[%d] %s: Controlling object _before_ ioctl(SG_IO%s):\n",
+ if (vb > 4) {
+ pr2serr_lk("[%d] %s: >> Control object _before_ ioctl(SG_IO%s):\n",
id, __func__, iosub_str);
- if (clp->verbose > 5)
+ if (vb > 5)
hex2stderr_lk((const uint8_t *)&ctl_v4, sizeof(ctl_v4), 1);
- v4hdr_out_lk("Controlling object before", &ctl_v4, id);
+ v4hdr_out_lk(">> Control object before", &ctl_v4, id, false);
}
try_again:
- if (!after1 && (clp->verbose > 1)) {
+ if (!after1 && (vb > 1)) {
after1 = true;
pr2serr_lk("%s: %s\n", __func__, serial ? mrq_ob_s : mrq_vb_s);
}
@@ -3100,28 +3073,28 @@ try_again:
res, err, strerror(err));
return -err;
}
- if (clp->verbose > 4) {
- pr2serr_lk("%s: Controlling object output by ioctl(%s):\n", __func__,
- iosub_str);
- if (clp->verbose > 5)
+ if (vb > 4) {
+ pr2serr_lk("%s: >> Control object after ioctl(%s) seg_blks=%d:\n",
+ __func__, iosub_str, o_seg_blks);
+ if (vb > 5)
hex2stderr_lk((const uint8_t *)&ctl_v4, sizeof(ctl_v4), 1);
- v4hdr_out_lk("Controlling object after", &ctl_v4, id);
- if (clp->verbose > 5) {
+ v4hdr_out_lk(">> Control object after", &ctl_v4, id, false);
+ if (vb > 5) {
for (k = 0; k < num_mrq; ++k) {
- pr2serr_lk("AFTER: def_arr[%d]:\n", k);
- v4hdr_out_lk("normal v4 object", (a_v4p + k), id);
- // hex2stderr_lk((const uint8_t *)(a_v4p + k), sizeof(*a_v4p),
- // 1);
+ if ((vb > 6) || a_v4p[k].info) {
+ snprintf(b, b_len, "a_v4[%d/%d]", k, num_mrq);
+ v4hdr_out_lk(b, (a_v4p + k), id, true);
+ }
}
}
}
num_good = process_mrq_response(rep, &ctl_v4, a_v4p, num_mrq, in_fin_blks,
- out_fin_blks);
+ out_fin_blks, err_on_in);
if (is_wr)
out_mrq_q_blks = mrq_q_blks;
else
in_mrq_q_blks = mrq_q_blks;
- if (clp->verbose > 2)
+ if (vb > 2)
pr2serr_lk("%s: >>> seg_blks=%d, num_good=%d, in_q/fin blks=%u/%u; "
"out_q/fin blks=%u/%u\n", __func__, o_seg_blks, num_good,
in_mrq_q_blks, in_fin_blks, out_mrq_q_blks, out_fin_blks);
@@ -3132,13 +3105,16 @@ try_again:
if (num_good < num_mrq) {
int resid_blks = in_mrq_q_blks - in_fin_blks;
- if (resid_blks > 0)
+ if (resid_blks > 0) {
rep->in_rem_count += resid_blks;
+ rep->stop_after_write = ! (err_on_in && clp->in_flags.coe);
+ }
resid_blks = out_mrq_q_blks - out_fin_blks;
- if (resid_blks > 0)
+ if (resid_blks > 0) {
rep->out_rem_count += resid_blks;
- rep->stop_after_write = true;
+ rep->stop_after_write = ! (! err_on_in && clp->out_flags.coe);
+ }
}
}
return is_wr ? out_fin_blks : in_fin_blks;
@@ -3349,6 +3325,7 @@ do_both_sg_segment(Rq_elem * rep, scat_gath_iter & i_sg_it,
vector<cdb_arr_t> & a_cdb,
vector<struct sg_io_v4> & a_v4)
{
+ bool err_on_in = false;
int num_mrq, k, res, fd, mrq_pack_id_base, id, b_len, iflags, oflags;
int num, kk, i_lin_blks, o_lin_blks, cdbsz, num_good;
int o_seg_blks = seg_blks;
@@ -3366,6 +3343,7 @@ do_both_sg_segment(Rq_elem * rep, scat_gath_iter & i_sg_it,
struct sg_io_v4 * t_v4p = &t_v4;
struct flags_t * iflagsp = &clp->in_flags;
struct flags_t * oflagsp = &clp->out_flags;
+ int vb = clp->verbose;
id = rep->id;
b_len = sizeof(b);
@@ -3415,7 +3393,7 @@ do_both_sg_segment(Rq_elem * rep, scat_gath_iter & i_sg_it,
pr2serr_lk("%s: t=%d: input sg_build_scsi_cdb() failed\n",
__func__, id);
break;
- } else if (clp->verbose > 3)
+ } else if (vb > 3)
lk_print_command_len("input cdb: ", t_cdb.data(), cdbsz, true);
a_cdb.push_back(t_cdb);
@@ -3439,7 +3417,7 @@ do_both_sg_segment(Rq_elem * rep, scat_gath_iter & i_sg_it,
pr2serr_lk("%s: t=%d: output sg_build_scsi_cdb() failed\n",
__func__, id);
break;
- } else if (clp->verbose > 3)
+ } else if (vb > 3)
lk_print_command_len("output cdb: ", t_cdb.data(), cdbsz, true);
a_cdb.push_back(t_cdb);
memset(t_v4p, 0, sizeof(*t_v4p));
@@ -3453,15 +3431,15 @@ do_both_sg_segment(Rq_elem * rep, scat_gath_iter & i_sg_it,
t_v4p->request_extra = mrq_pack_id_base + ++rep->mrq_pack_id_off;
a_v4.push_back(t_v4);
- if (clp->verbose > 5) {
- pr2serr_lk("%s: t=%d: a_v4 array contents:\n", __func__, id);
- hex2stderr_lk((const uint8_t *)a_v4.data(),
- a_v4.size() * sizeof(struct sg_io_v4), 1);
- }
i_sg_it.add_blks(num);
o_sg_it.add_blks(num);
}
+ if (vb > 6) {
+ pr2serr_lk("%s: t=%d: a_v4 array contents:\n", __func__, id);
+ hex2stderr_lk((const uint8_t *)a_v4.data(),
+ a_v4.size() * sizeof(struct sg_io_v4), 1);
+ }
if (rep->both_sg || rep->same_sg)
fd = rep->infd; /* assume share to rep->outfd */
else if (rep->only_in_sg)
@@ -3482,8 +3460,9 @@ do_both_sg_segment(Rq_elem * rep, scat_gath_iter & i_sg_it,
ctl_v4.request = (uint64_t)a_cdb.data();
ctl_v4.max_response_len = sizeof(rep->sb);
ctl_v4.response = (uint64_t)rep->sb;
- ctl_v4.flags = SGV4_FLAG_MULTIPLE_REQS | SGV4_FLAG_STOP_IF |
- SGV4_FLAG_SHARE;
+ ctl_v4.flags = SGV4_FLAG_MULTIPLE_REQS | SGV4_FLAG_SHARE;
+ if (! (iflagsp->coe || oflagsp->coe))
+ ctl_v4.flags |= SGV4_FLAG_STOP_IF;
if ((! clp->verify) && clp->out_flags.order)
ctl_v4.flags |= SGV4_FLAG_ORDERED_SLV;
ctl_v4.dout_xferp = (uint64_t)a_v4.data(); /* request array */
@@ -3493,16 +3472,16 @@ do_both_sg_segment(Rq_elem * rep, scat_gath_iter & i_sg_it,
if (false /* allow_mrq_abort */)
ctl_v4.request_extra = mrq_pack_id_base + ++rep->mrq_pack_id_off;
- if (clp->verbose > 4) {
- pr2serr_lk("%s: Controlling object _before_ ioctl(SG_IO%s):\n",
+ if (vb > 4) {
+ pr2serr_lk("%s: >> Control object _before_ ioctl(SG_IO%s):\n",
__func__, iosub_str);
- if (clp->verbose > 5)
+ if (vb > 5)
hex2stderr_lk((const uint8_t *)&ctl_v4, sizeof(ctl_v4), 1);
- v4hdr_out_lk("Controlling object before", &ctl_v4, id);
+ v4hdr_out_lk(">> Control object before", &ctl_v4, id, false);
}
try_again:
- if (!after1 && (clp->verbose > 1)) {
+ if (!after1 && (vb > 1)) {
after1 = true;
pr2serr_lk("%s: %s\n", __func__, mrq_svb_s);
}
@@ -3523,24 +3502,24 @@ try_again:
res = -err;
goto fini;
}
- if (clp->verbose > 4) {
- pr2serr_lk("%s: Controlling object output by ioctl(%s):\n", __func__,
- iosub_str);
- if (clp->verbose > 5)
+ if (vb > 4) {
+ pr2serr_lk("%s: >> Control object after ioctl(%s) seg_blks=%d:\n",
+ __func__, iosub_str, o_seg_blks);
+ if (vb > 5)
hex2stderr_lk((const uint8_t *)&ctl_v4, sizeof(ctl_v4), 1);
- v4hdr_out_lk("Controlling object after", &ctl_v4, id);
- if (clp->verbose > 5) {
+ v4hdr_out_lk(">> Control object after", &ctl_v4, id, false);
+ if (vb > 5) {
for (k = 0; k < num_mrq; ++k) {
- pr2serr_lk("AFTER: def_arr[%d]:\n", k);
- v4hdr_out_lk("normal v4 object", (a_v4p + k), id);
- // hex2stderr_lk((const uint8_t *)(a_v4p + k), sizeof(*a_v4p),
- // 1);
+ if ((vb > 6) || a_v4p[k].info) {
+ snprintf(b, b_len, "a_v4[%d/%d]", k, num_mrq);
+ v4hdr_out_lk(b, (a_v4p + k), id, true);
+ }
}
}
}
num_good = process_mrq_response(rep, &ctl_v4, a_v4p, num_mrq, in_fin_blks,
- out_fin_blks);
- if (clp->verbose > 2)
+ out_fin_blks, err_on_in);
+ if (vb > 2)
pr2serr_lk("%s: >>> seg_blks=%d, num_good=%d, in_q/fin blks=%u/%u; "
"out_q/fin blks=%u/%u\n", __func__, o_seg_blks, num_good,
in_mrq_q_blks, in_fin_blks, out_mrq_q_blks, out_fin_blks);
@@ -3551,15 +3530,19 @@ try_again:
rep->in_local_count += in_fin_blks;
rep->out_local_count += out_fin_blks;
- if (num_good < num_mrq) {
+ if (num_good < num_mrq) { /* reduced number completed */
int resid_blks = in_mrq_q_blks - in_fin_blks;
- if (resid_blks > 0)
+ if (resid_blks > 0) {
rep->in_rem_count += resid_blks;
+ rep->stop_after_write = ! (err_on_in && clp->in_flags.coe);
+ }
+
resid_blks = out_mrq_q_blks - out_fin_blks;
- if (resid_blks > 0)
+ if (resid_blks > 0) {
rep->out_rem_count += resid_blks;
- rep->stop_after_write = true;
+ rep->stop_after_write = ! (! err_on_in && clp->out_flags.coe);
+ }
}
}
fini:
@@ -3658,10 +3641,12 @@ bypass:
errno, strerror(errno));
}
}
+#if 0
t = 1;
res = ioctl(fd, SG_SET_DEBUG, &t); /* more info in /proc/scsi/sg/debug */
if (res < 0)
perror("sgh_dd: SG_SET_DEBUG error");
+#endif
return (res < 0) ? 0 : num;
}
@@ -3896,7 +3881,7 @@ sg_out_open(struct global_collection *clp, const char *outf, uint8_t **mmpp,
static int
parse_cmdline_sanity(int argc, char * argv[], struct global_collection * clp,
- char * inf, char * outf, char * out2f, char * outregf)
+ char * inf, char * outf, char * outregf)
{
bool contra = false;
bool verbose_given = false;
@@ -3942,9 +3927,6 @@ parse_cmdline_sanity(int argc, char * argv[], struct global_collection * clp,
clp->cdbsz_in = sg_get_num(buf);
clp->cdbsz_out = clp->cdbsz_in;
clp->cdbsz_given = true;
- } else if (0 == strcmp(key, "coe")) {
- clp->in_flags.coe = !! sg_get_num(buf);
- clp->out_flags.coe = clp->in_flags.coe;
} else if (0 == strcmp(key, "count")) {
if (clp->count_given) {
pr2serr("second 'count=' argument detected, only one "
@@ -3960,10 +3942,7 @@ parse_cmdline_sanity(int argc, char * argv[], struct global_collection * clp,
}
} /* treat 'count=-1' as calculate count (same as not given) */
clp->count_given = true;
- } else if ((0 == strncmp(key, "deb", 3)) ||
- (0 == strncmp(key, "verb", 4)))
- clp->verbose = sg_get_num(buf);
- else if (0 == strcmp(key, "dio")) {
+ } else if (0 == strcmp(key, "dio")) {
clp->in_flags.dio = !! sg_get_num(buf);
clp->out_flags.dio = clp->in_flags.dio;
} else if (0 == strcmp(key, "fua")) {
@@ -4010,15 +3989,6 @@ parse_cmdline_sanity(int argc, char * argv[], struct global_collection * clp,
pr2serr("%sbad argument to 'obs='\n", my_name);
goto syn_err;
}
- } else if (strcmp(key, "of2") == 0) {
- if ('\0' != out2f[0]) {
- pr2serr("Second OFILE2 argument??\n");
- contra = true;
- goto syn_err;
- } else {
- memcpy(out2f, buf, INOUTF_SZ);
- out2f[INOUTF_SZ - 1] = '\0'; /* noisy compiler */
- }
} else if (strcmp(key, "ofreg") == 0) {
if ('\0' != outregf[0]) {
pr2serr("Second OFREG argument??\n");
@@ -4063,6 +4033,8 @@ parse_cmdline_sanity(int argc, char * argv[], struct global_collection * clp,
num_threads = sg_get_num(buf);
else if (0 == strcmp(key, "time"))
do_time = sg_get_num(buf);
+ else if (0 == strncmp(key, "verb", 4))
+ clp->verbose = sg_get_num(buf);
else if ((keylen > 1) && ('-' == key[0]) && ('-' != key[1])) {
res = 0;
n = num_chs_in_str(key + 1, keylen - 1, 'd');
@@ -4201,8 +4173,8 @@ parse_cmdline_sanity(int argc, char * argv[], struct global_collection * clp,
}
#endif
/* defaulting transfer size to 128*2048 for CD/DVDs is too large
- for the block layer in lk 2.6 and results in an EIO on the
- SG_IO ioctl. So reduce it in that case. */
+ * for the block layer in lk 2.6 and results in an EIO on the
+ * SG_IO ioctl. So reduce it in that case. */
if ((clp->bs >= 2048) && (! bpt_given))
clp->bpt = DEF_BLOCKS_PER_2048TRANSFER;
if (clp->in_flags.order)
@@ -4448,9 +4420,9 @@ fini:
int
main(int argc, char * argv[])
{
+ bool fail_after_cli = false;
char inf[INOUTF_SZ];
char outf[INOUTF_SZ];
- char out2f[INOUTF_SZ];
char outregf[INOUTF_SZ];
int res, k, err, flags;
int64_t in_num_sect = -1;
@@ -4462,7 +4434,7 @@ main(int argc, char * argv[])
vector<thread> work_thr;
vector<thread> listen_thr;
char ebuff[EBUFF_SZ];
-#if 0 /* SG_LIB_ANDROID */
+#if 0 /* SG_LIB_ANDROID */
struct sigaction actions;
memset(&actions, 0, sizeof(actions));
@@ -4478,28 +4450,31 @@ main(int argc, char * argv[])
clp->in_type = FT_FIFO;
/* change dd's default: if of=OFILE not given, assume /dev/null */
clp->out_type = FT_DEV_NULL;
- clp->out2_type = FT_DEV_NULL;
clp->cdbsz_in = DEF_SCSI_CDB_SZ;
clp->cdbsz_out = DEF_SCSI_CDB_SZ;
clp->mrq_num = DEF_MRQ_NUM;
inf[0] = '\0';
outf[0] = '\0';
- out2f[0] = '\0';
outregf[0] = '\0';
fetch_sg_version();
if (sg_version >= 40030)
sg_version_ge_40030 = true;
else {
- pr2serr("%srequires an sg driver version of 4.0.30 or later\n",
+ pr2serr(">>> %srequires an sg driver version of 4.0.30 or later\n\n",
my_name);
- return SG_LIB_SYNTAX_ERROR;
+ fail_after_cli = true;
}
- res = parse_cmdline_sanity(argc, argv, clp, inf, outf, out2f, outregf);
+ res = parse_cmdline_sanity(argc, argv, clp, inf, outf, outregf);
if (SG_LIB_OK_FALSE == res)
return 0;
if (res)
return res;
+ if (fail_after_cli) {
+ pr2serr("%scommand line parsing was okay but sg driver is too old\n",
+ my_name);
+ return SG_LIB_SYNTAX_ERROR;
+ }
install_handler(SIGINT, interrupt_handler);
install_handler(SIGQUIT, interrupt_handler);
@@ -4614,66 +4589,6 @@ main(int argc, char * argv[])
clp->outfp = outf;
}
- if (out2f[0])
- clp->ofile2_given = true;
- if (out2f[0] && ('-' != out2f[0])) {
- clp->out2_type = dd_filetype(out2f, clp->out2_st_size);
-
- if (FT_ST == clp->out2_type) {
- pr2serr("%sunable to use scsi tape device %s\n", my_name, out2f);
- return SG_LIB_FILE_ERROR;
- }
- else if (FT_SG == clp->out2_type) {
- clp->out2fd = sg_out_open(clp, out2f, NULL, NULL);
- if (clp->out2fd < 0)
- return -clp->out2fd;
- }
- else if (FT_DEV_NULL == clp->out2_type)
- clp->out2fd = -1; /* don't bother opening */
- else {
- if (FT_RAW != clp->out2_type) {
- flags = O_WRONLY | O_CREAT;
- if (clp->out_flags.direct)
- flags |= O_DIRECT;
- if (clp->out_flags.excl)
- flags |= O_EXCL;
- if (clp->out_flags.dsync)
- flags |= O_SYNC;
- if (clp->out_flags.append)
- flags |= O_APPEND;
-
- if ((clp->out2fd = open(out2f, flags, 0666)) < 0) {
- err = errno;
- snprintf(ebuff, EBUFF_SZ, "%scould not open %s for "
- "writing", my_name, out2f);
- perror(ebuff);
- return sg_convert_errno(err);
- }
- }
- else { /* raw output file */
- if ((clp->out2fd = open(out2f, O_WRONLY)) < 0) {
- err = errno;
- snprintf(ebuff, EBUFF_SZ, "%scould not open %s for raw "
- "writing", my_name, out2f);
- perror(ebuff);
- return sg_convert_errno(err);
- }
- }
- if (clp->o_sgl.lowest_lba > 0) {
- off64_t offset = clp->o_sgl.lowest_lba;
-
- offset *= clp->bs; /* could exceed 32 bits here! */
- if (lseek64(clp->out2fd, offset, SEEK_SET) < 0) {
- err = errno;
- snprintf(ebuff, EBUFF_SZ, "%scouldn't seek to required "
- "position on %s", my_name, out2f);
- perror(ebuff);
- return sg_convert_errno(err);
- }
- }
- }
- clp->out2fp = out2f;
- }
if ((FT_SG == clp->in_type ) && (FT_SG == clp->out_type)) {
;
} else if (clp->in_flags.order)
@@ -4746,10 +4661,6 @@ main(int argc, char * argv[])
clp->in_rem_count = clp->dd_count;
clp->out_rem_count = clp->dd_count;
-#if 0
- status = pthread_mutex_init(&clp->out2_mutex, NULL);
- if (0 != status) err_exit(status, "init out2_mutex");
-#endif
if (clp->dry_run > 0) {
pr2serr("Due to --dry-run option, bypass copy/read\n");
@@ -4761,23 +4672,13 @@ main(int argc, char * argv[])
sigemptyset(&signal_set);
sigaddset(&signal_set, SIGINT);
-#if 0
- status = pthread_sigmask(SIG_BLOCK, &signal_set, NULL);
- if (0 != status) err_exit(status, "pthread_sigmask");
-#endif
res = sigprocmask(SIG_BLOCK, &signal_set, NULL);
if (res < 0) {
- pr2serr("sigprocmask failed: %s\n", safe_strerror(errno));
- goto fini;
+ pr2serr("sigprocmask failed: %s\n", safe_strerror(errno));
+ goto fini;
}
-#if 0
- status = pthread_create(&sig_listen_thread_id, NULL,
- sig_listen_thread, (void *)clp);
- if (0 != status) err_exit(status, "pthread_create, sig...");
-#endif
-
listen_thr.emplace_back(sig_listen_thread, clp);
if (do_time) {
@@ -4829,17 +4730,6 @@ jump:
if (0 != res)
pr2serr_lk("Unable to synchronize cache\n");
}
- if (FT_SG == clp->out2_type) {
- pr2serr_lk(">> Synchronizing cache on %s\n", out2f);
- res = sg_ll_sync_cache_10(clp->out2fd, 0, 0, 0, 0, 0, false, 0);
- if (SG_LIB_CAT_UNIT_ATTENTION == res) {
- pr2serr_lk("Unit attention(out2), continuing\n");
- res = sg_ll_sync_cache_10(clp->out2fd, 0, 0, 0, 0, 0, false,
- 0);
- }
- if (0 != res)
- pr2serr_lk("Unable to synchronize cache (of2)\n");
- }
}
shutting_down = true;
@@ -4857,21 +4747,10 @@ fini:
if ((STDOUT_FILENO != clp->outfd) && (FT_DEV_NULL != clp->out_type) &&
(clp->outfd >= 0))
close(clp->outfd);
- if ((clp->out2fd >= 0) && (STDOUT_FILENO != clp->out2fd) &&
- (FT_DEV_NULL != clp->out2_type))
- close(clp->out2fd);
if ((clp->outregfd >= 0) && (STDOUT_FILENO != clp->outregfd) &&
(FT_DEV_NULL != clp->outreg_type))
close(clp->outregfd);
res = exit_status;
-#if 0
- if ((0 != clp->out_count.load()) && (0 == clp->dry_run)) {
- pr2serr(">>>> Some error occurred, remaining blocks=%" PRId64 "\n",
- clp->out_count.load());
- if (0 == res)
- res = SG_LIB_CAT_OTHER;
- }
-#endif
print_stats("");
if (clp->dio_incomplete_count.load()) {
int fd;
@@ -4897,10 +4776,12 @@ fini:
pr2serr("Number of finish EAGAINs: %d\n", num_fin_eagain.load());
if (clp->verbose && (num_ebusy > 0))
pr2serr("Number of EBUSYs: %d\n", num_ebusy.load());
+#if 0
if (clp->verbose > 1) {
pr2serr("Number of SG_GET_NUM_WAITING calls=%ld\n",
num_waiting_calls.load());
}
+#endif
if (clp->verify && (SG_LIB_CAT_MISCOMPARE == res))
pr2serr("Verify/compare failed due to miscompare\n");
return (res >= 0) ? res : SG_LIB_CAT_OTHER;
diff --git a/testing/sgh_dd.cpp b/testing/sgh_dd.cpp
index 7abcb455..a9cc85d3 100644
--- a/testing/sgh_dd.cpp
+++ b/testing/sgh_dd.cpp
@@ -36,7 +36,7 @@
* renamed [20181221]
*/
-static const char * version_str = "1.82 20200629";
+static const char * version_str = "1.83 20200709";
#define _XOPEN_SOURCE 600
#ifndef _GNU_SOURCE
@@ -238,8 +238,9 @@ struct global_collection
int ofsplit;
atomic<int> dio_incomplete_count;
atomic<int> sum_of_resids;
- int debug; /* both -v and deb=VERB bump this field */
+ int vebose;
int fail_mask;
+ int verbose;
int dry_run;
bool aen_given;
bool cdbsz_given;
@@ -615,6 +616,55 @@ fini:
return b;
}
+/* Info field decoded into abbreviations for those bits that are set,
+ * separated by '|' . */
+static char *
+sg_info_str(int info, int b_len, char * b)
+{
+ int n = 0;
+
+ if ((b_len < 1) || (! b))
+ return b;
+ b[0] = '\0';
+ if (SG_INFO_CHECK & info) { /* 0x1 */
+ n += sg_scnpr(b + n, b_len - n, "CHK|");
+ if (n >= b_len)
+ goto fini;
+ }
+ if (SG_INFO_DIRECT_IO & info) { /* 0x2 */
+ n += sg_scnpr(b + n, b_len - n, "DIO|");
+ if (n >= b_len)
+ goto fini;
+ }
+ if (SG_INFO_MIXED_IO & info) { /* 0x4 */
+ n += sg_scnpr(b + n, b_len - n, "MIO|");
+ if (n >= b_len)
+ goto fini;
+ }
+ if (SG_INFO_DEVICE_DETACHING & info) { /* 0x8 */
+ n += sg_scnpr(b + n, b_len - n, "DETA|");
+ if (n >= b_len)
+ goto fini;
+ }
+ if (SG_INFO_ABORTED & info) { /* 0x10 */
+ n += sg_scnpr(b + n, b_len - n, "ABRT|");
+ if (n >= b_len)
+ goto fini;
+ }
+ if (SG_INFO_MRQ_FINI & info) { /* 0x20 */
+ n += sg_scnpr(b + n, b_len - n, "MRQF|");
+ if (n >= b_len)
+ goto fini;
+ }
+fini:
+ if (n < b_len) { /* trim trailing '\' */
+ if ('|' == b[n - 1])
+ b[n - 1] = '\0';
+ } else if ('|' == b[b_len - 1])
+ b[b_len - 1] = '\0';
+ return b;
+}
+
static void
v4hdr_out_lk(const char * leadin, const sg_io_v4 * h4p, int id)
{
@@ -635,7 +685,7 @@ v4hdr_out_lk(const char * leadin, const sg_io_v4 * h4p, int id)
pr2serr(" flags=0x%x request_extra{pack_id}=%d\n",
h4p->flags, h4p->request_extra);
pr2serr(" flags set: %s\n", sg_flags_str(h4p->flags, sizeof(b), b));
- pr2serr(" OUT:\n");
+ pr2serr(" %s OUT fields:\n", leadin);
pr2serr(" response_len=%d driver/transport/device_status="
"0x%x/0x%x/0x%x\n", h4p->response_len, h4p->driver_status,
h4p->transport_status, h4p->device_status);
@@ -849,10 +899,10 @@ usage(int pg_num)
" [--help] [--version]\n\n");
pr2serr(" [ae=AEN[,MAEN]] [bpt=BPT] [cdbsz=6|10|12|16] "
"[coe=0|1]\n"
- " [deb=VERB] [dio=0|1] [elemsz_kb=ESK] "
- "[fail_mask=FM]\n"
- " [fua=0|1|2|3] [mrq=[I|O,]NRQS[,C]] [noshare=0|1] "
- "[of2=OFILE2]\n"
+ " [dio=0|1] [elemsz_kb=ESK] [fail_mask=FM] "
+ "[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]\n"
" [unshare=1|0] [verbose=VERB] [--dry-run] "
@@ -914,8 +964,6 @@ page2:
"(default is 10)\n"
" coe continue on error, 0->exit (def), "
"1->zero + continue\n"
- " deb for debug, 0->none (def), > 0->varying degrees "
- "of debug\n"
" dio is direct IO, 1->attempt, 0->indirect IO (def)\n"
" elemsz_kb scatter gather list element size in kilobytes "
"(def: 32[KB])\n"
@@ -944,7 +992,7 @@ page2:
" unshare 0->don't explicitly unshare after share; 1->let "
"close do\n"
" file unshare (default)\n"
- " verbose same as 'deb=VERB': increase verbosity\n"
+ " verbose increase verbosity\n"
" --dry-run|-d prepare but bypass copy/read\n"
" --verbose|-v increase verbosity of utility\n\n"
"Use '-hhh' or '-hhhh' for more information about flags.\n"
@@ -1360,7 +1408,7 @@ read_write_thread(void * v_tip)
tip = (Thread_info *)v_tip;
clp = tip->gcp;
- vb = clp->debug;
+ vb = clp->verbose;
sz = clp->bpt * clp->bs;
in_is_sg = (FT_SG == clp->in_type);
in_mmap = (in_is_sg && (clp->in_flags.mmap > 0));
@@ -1724,7 +1772,7 @@ normal_in_rd(Rq_elem * rep, int blocks)
int res;
char strerr_buff[STRERR_BUFF_LEN];
- if (clp->debug > 4)
+ if (clp->verbose > 4)
pr2serr_lk("%s: tid=%d: iblk=%" PRIu64 ", blocks=%d\n", __func__,
rep->id, rep->iblk, blocks);
if (FT_RANDOM_0_FF == clp->in_type) {
@@ -1807,7 +1855,7 @@ normal_out_wr(Rq_elem * rep, int blocks)
char strerr_buff[STRERR_BUFF_LEN];
/* enters holding out_mutex */
- if (clp->debug > 4)
+ if (clp->verbose > 4)
pr2serr_lk("%s: tid=%d: oblk=%" PRIu64 ", blocks=%d\n", __func__,
rep->id, rep->oblk, blocks);
while (((res = write(clp->outfd, rep->buffp, blocks * clp->bs))
@@ -2008,7 +2056,7 @@ sg_wr_swap_share(Rq_elem * rep, int to_fd, bool before)
struct sg_extended_info sei;
struct sg_extended_info * seip = &sei;
- if (rep->clp->debug > 2)
+ if (rep->clp->verbose > 2)
pr2serr_lk("%s: tid=%d: to_fd=%d, before=%d\n", __func__, rep->id,
to_fd, (int)before);
memset(seip, 0, sizeof(*seip));
@@ -2028,7 +2076,7 @@ sg_wr_swap_share(Rq_elem * rep, int to_fd, bool before)
if (k > 10000)
break;
if (! not_first) {
- if (clp->debug > 3)
+ if (clp->verbose > 3)
pr2serr_lk("tid=%d: ioctl(EXTENDED(change_shared_fd=%d), "
"failed errno=%d %s\n", rep->id, master_fd, err,
strerror(err));
@@ -2042,7 +2090,7 @@ sg_wr_swap_share(Rq_elem * rep, int to_fd, bool before)
"errno=%d %s\n", rep->id, master_fd, err, strerror(err));
return false;
}
- if (clp->debug > 15)
+ if (clp->verbose > 15)
pr2serr_lk("%s: tid=%d: ioctl(EXTENDED(change_shared_fd)) ok, "
"master_fd=%d, to_slave_fd=%d\n", __func__, rep->id,
master_fd, to_fd);
@@ -2201,6 +2249,138 @@ fini:
}
static int
+process_mrq_response(Rq_elem * rep, const struct sg_io_v4 * ctl_v4p,
+ const struct sg_io_v4 * a_v4p, int num_mrq,
+ uint32_t & good_inblks, uint32_t & good_outblks)
+{
+ struct global_collection * clp = rep->clp;
+ bool ok, all_good;
+ bool sb_in_co = !!(ctl_v4p->response);
+ int id = rep->id;
+ int resid = ctl_v4p->din_resid;
+ int sres = ctl_v4p->spare_out;
+ int n_subm = num_mrq - ctl_v4p->dout_resid;
+ int n_cmpl = ctl_v4p->info;
+ int n_good = 0;
+ int hole_count = 0;
+ int vb = clp->verbose;
+ int k, j, f1, slen, sstatus, blen;
+ char b[80];
+
+ blen = sizeof(b);
+ good_inblks = 0;
+ good_outblks = 0;
+ if (vb > 2)
+ pr2serr_lk("[thread_id=%d] %s: num_mrq=%d, n_subm=%d, n_cmpl=%d\n",
+ id, __func__, num_mrq, n_subm, n_cmpl);
+ if (n_subm < 0) {
+ pr2serr_lk("[%d] co.dout_resid(%d) > num_mrq(%d)\n", id,
+ ctl_v4p->dout_resid, num_mrq);
+ return -1;
+ }
+ if (n_cmpl != (num_mrq - resid))
+ pr2serr_lk("[%d] co.info(%d) != (num_mrq(%d) - co.din_resid(%d))\n"
+ "will use co.info\n", id, n_cmpl, num_mrq, resid);
+ if (n_cmpl > n_subm) {
+ pr2serr_lk("[%d] n_cmpl(%d) > n_subm(%d), use n_subm for both\n",
+ id, n_cmpl, n_subm);
+ n_cmpl = n_subm;
+ }
+ if (sres) {
+ pr2serr_lk("[%d] secondary error: %s [%d], info=0x%x\n", id,
+ strerror(sres), sres, ctl_v4p->info);
+ if (E2BIG == sres) {
+ sg_take_snap(rep->infd, id, true);
+ sg_take_snap(rep->outfd, id, true);
+ }
+ }
+ /* Check if those submitted have finished or not. N.B. If there has been
+ * an error then there may be "holes" (i.e. info=0x0) in the array due
+ * to completions being out-of-order. */
+ for (k = 0, j = 0; ((k < num_mrq) && (j < n_subm));
+ ++k, j += f1, ++a_v4p) {
+ slen = a_v4p->response_len;
+ if (! (SG_INFO_MRQ_FINI & a_v4p->info))
+ ++hole_count;
+ ok = true;
+ f1 = !!(a_v4p->info); /* want to skip n_subm count if info is 0x0 */
+ if (SG_INFO_CHECK & a_v4p->info) {
+ ok = false;
+ 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 ((sstatus && (SAM_STAT_CONDITION_MET != sstatus)) ||
+ a_v4p->transport_status || a_v4p->driver_status) {
+ ok = false;
+ if (SAM_STAT_CHECK_CONDITION != a_v4p->device_status) {
+ pr2serr_lk("[%d] a_v4[%d]:\n", id, k);
+ if (vb)
+ lk_chk_n_print4(" >>", a_v4p, vb > 4);
+ }
+ }
+ if (slen > 0) {
+ struct sg_scsi_sense_hdr ssh;
+ const uint8_t *sbp = (const uint8_t *)
+ (sb_in_co ? ctl_v4p->response : a_v4p->response);
+
+ if (sg_scsi_normalize_sense(sbp, slen, &ssh) &&
+ (ssh.response_code >= 0x70)) {
+ char b[256];
+
+ if (ssh.response_code & 0x1) {
+ ok = true;
+ }
+ if (vb) {
+ sg_get_sense_str(" ", sbp, slen, false, blen, b);
+ pr2serr_lk("[%d] a_v4[%d]:\n%s\n", id, k, b);
+ }
+ }
+ }
+ if (ok && f1) {
+ ++n_good;
+ if (a_v4p->dout_xfer_len >= (uint32_t)clp->bs) {
+ if (a_v4p->dout_resid)
+ good_outblks +=
+ (a_v4p->dout_xfer_len - a_v4p->dout_resid) / clp->bs;
+ else /* avoid division in common case of resid==0 */
+ good_outblks += (uint32_t)a_v4p->usr_ptr;
+ }
+ if (a_v4p->din_xfer_len >= (uint32_t)clp->bs) {
+ if (a_v4p->din_resid)
+ good_inblks += (a_v4p->din_xfer_len - a_v4p->din_resid) /
+ clp->bs;
+ else
+ good_inblks += (uint32_t)a_v4p->usr_ptr;
+ }
+ }
+ } /* end of request array scan loop */
+ if ((n_subm == num_mrq) || (vb < 3))
+ goto fini;
+ if (vb)
+ pr2serr_lk("[%d] checking response array _beyond_ number of "
+ "submissions [%d] to num_mrq:\n", id, k);
+ for (all_good = true; k < num_mrq; ++k, ++a_v4p) {
+ if (SG_INFO_MRQ_FINI & a_v4p->info) {
+ pr2serr_lk("[%d] a_v4[%d]: unexpected SG_INFO_MRQ_FINI set [%s]\n",
+ id, k, sg_info_str(a_v4p->info, sizeof(b), b));
+ all_good = false;
+ }
+ if (a_v4p->device_status || a_v4p->transport_status ||
+ a_v4p->driver_status) {
+ pr2serr_lk("[%d] a_v4[%d]:\n", id, k);
+ lk_chk_n_print4(" ", a_v4p, vb > 4);
+ all_good = false;
+ }
+ }
+ if (all_good)
+ pr2serr_lk(" ... all good\n");
+fini:
+ return n_good;
+}
+
+#if 0
+static int
chk_mrq_response(Rq_elem * rep, const struct sg_io_v4 * ctl_v4p,
const struct sg_io_v4 * a_v4p, int nrq,
uint32_t * good_inblksp, uint32_t * good_outblksp)
@@ -2213,12 +2393,14 @@ chk_mrq_response(Rq_elem * rep, const struct sg_io_v4 * ctl_v4p,
int n_subm = nrq - ctl_v4p->dout_resid;
int n_cmpl = ctl_v4p->info;
int n_good = 0;
- int vb = clp->debug;
- int k, slen, sstatus;
+ int vb = clp->verbose;
+ int k, slen, sstatus, blen;
uint32_t good_inblks = 0;
uint32_t good_outblks = 0;
const struct sg_io_v4 * a_np = a_v4p;
+ char b[80];
+ blen = sizeof(b);
if (n_subm < 0) {
pr2serr_lk("[%d] %s: co.dout_resid(%d) > nrq(%d)\n", id, __func__,
ctl_v4p->dout_resid, nrq);
@@ -2244,12 +2426,17 @@ chk_mrq_response(Rq_elem * rep, const struct sg_io_v4 * ctl_v4p,
for (k = 0; k < n_subm; ++k, ++a_np) {
slen = a_np->response_len;
if (! (SG_INFO_MRQ_FINI & a_np->info)) {
- pr2serr_lk("[%d] %s, a_n[%d]: missing SG_INFO_MRQ_FINI ? ?\n",
- id, __func__, k);
+ pr2serr_lk("[%d] %s, a_n[%d]: missing SG_INFO_MRQ_FINI [%s]\n",
+ id, __func__, k, sg_info_str(a_np->info, blen, b));
v4hdr_out_lk("a_np", a_np, id);
v4hdr_out_lk("cop", ctl_v4p, id);
}
ok = true;
+ if (SG_INFO_CHECK & a_np->info) {
+ ok = false;
+ 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 ((sstatus && (SAM_STAT_CONDITION_MET != sstatus)) ||
a_np->transport_status || a_np->driver_status) {
@@ -2297,7 +2484,7 @@ chk_mrq_response(Rq_elem * rep, const struct sg_io_v4 * ctl_v4p,
if (a_np->device_status || a_np->transport_status ||
a_np->driver_status) {
pr2serr_lk("[%d] %s, a_n[%d]:\n", id, __func__, k);
- lk_chk_n_print4(" ", a_np, false);
+ lk_chk_n_print4(" ", a_np, vb > 4);
}
}
fini:
@@ -2307,6 +2494,7 @@ fini:
*good_outblksp = good_outblks;
return n_good;
}
+#endif
/* do mrq 'submit (waitless) non-blocking' call. These are restricted to
* a single file descriptor (i.e. the 'fd' argument). */
@@ -2329,21 +2517,21 @@ sgh_do_async_mrq(Rq_elem * rep, mrq_arr_t & def_arr, int fd,
ctlop->flags = SGV4_FLAG_MULTIPLE_REQS;
if (clp->in_flags.no_waitq || clp->out_flags.no_waitq) {
ctlop->flags |= SGV4_FLAG_NO_WAITQ; /* waitless non-blocking */
- if (!after1 && (clp->debug > 1)) {
+ if (!after1 && (clp->verbose > 1)) {
after1 = true;
pr2serr_lk("%s: %s\n", __func__, mrq_nw_nb_s);
}
} else {
ctlop->flags |= SGV4_FLAG_IMMED; /* submit non-blocking */
- if (!after1 && (clp->debug > 1)) {
+ if (!after1 && (clp->verbose > 1)) {
after1 = true;
pr2serr_lk("%s: %s\n", __func__, mrq_s_nb_s);
}
}
- if (clp->debug > 4) {
+ if (clp->verbose > 4) {
pr2serr_lk("%s: Controlling object _before_ ioctl(SG_IOSUBMIT):\n",
__func__);
- if (clp->debug > 5)
+ if (clp->verbose > 5)
hex2stderr_lk((const uint8_t *)ctlop, sizeof(*ctlop), 1);
v4hdr_out_lk("Controlling object before", ctlop, rep->id);
}
@@ -2384,13 +2572,13 @@ sgh_do_async_mrq(Rq_elem * rep, mrq_arr_t & def_arr, int fd,
half_num = 0;
} else
half_num = ctlop->info;
- if (clp->debug > 4) {
+ if (clp->verbose > 4) {
pr2serr_lk("%s: Controlling object output by ioctl(SG_IORECEIVE),1: "
"num_received=%d\n", __func__, half_num);
- if (clp->debug > 5)
+ if (clp->verbose > 5)
hex2stderr_lk((const uint8_t *)ctlop, sizeof(*ctlop), 1);
v4hdr_out_lk("Controlling object after", ctlop, rep->id);
- if (clp->debug > 5) {
+ if (clp->verbose > 5) {
for (k = 0; k < half_num; ++k) {
pr2serr_lk("AFTER: def_arr[%d]:\n", k);
v4hdr_out_lk("normal v4 object", (a_v4p + k), rep->id);
@@ -2401,9 +2589,9 @@ sgh_do_async_mrq(Rq_elem * rep, mrq_arr_t & def_arr, int fd,
}
in_fin_blks = 0;
out_fin_blks = 0;
- num_good = chk_mrq_response(rep, ctlop, a_v4p, half_num, &in_fin_blks,
- &out_fin_blks);
- if (clp->debug > 2)
+ num_good = process_mrq_response(rep, ctlop, a_v4p, half_num, in_fin_blks,
+ out_fin_blks);
+ if (clp->verbose > 2)
pr2serr_lk("%s: >>>1 num_good=%d, in_q/fin blks=%u/%u; out_q/fin "
"blks=%u/%u\n", __func__, num_good, rep->in_mrq_q_blks,
in_fin_blks, rep->out_mrq_q_blks, out_fin_blks);
@@ -2456,13 +2644,13 @@ sgh_do_async_mrq(Rq_elem * rep, mrq_arr_t & def_arr, int fd,
half_num = 0;
} else
half_num = ctlop->info;
- if (clp->debug > 4) {
+ if (clp->verbose > 4) {
pr2serr_lk("%s: Controlling object output by ioctl(SG_IORECEIVE),2: "
"num_received=%d\n", __func__, half_num);
- if (clp->debug > 5)
+ if (clp->verbose > 5)
hex2stderr_lk((const uint8_t *)ctlop, sizeof(*ctlop), 1);
v4hdr_out_lk("Controlling object after", ctlop, rep->id);
- if (clp->debug > 5) {
+ if (clp->verbose > 5) {
for (k = 0; k < half_num; ++k) {
pr2serr_lk("AFTER: def_arr[%d]:\n", k);
v4hdr_out_lk("normal v4 object", (a_v4p + k), rep->id);
@@ -2473,9 +2661,9 @@ sgh_do_async_mrq(Rq_elem * rep, mrq_arr_t & def_arr, int fd,
}
in_fin_blks = 0;
out_fin_blks = 0;
- num_good = chk_mrq_response(rep, ctlop, a_v4p, half_num, &in_fin_blks,
- &out_fin_blks);
- if (clp->debug > 2)
+ num_good = process_mrq_response(rep, ctlop, a_v4p, half_num, in_fin_blks,
+ out_fin_blks);
+ if (clp->verbose > 2)
pr2serr_lk("%s: >>>2 num_good=%d, in_q/fin blks=%u/%u; out_q/fin "
"blks=%u/%u\n", __func__, num_good, rep->in_mrq_q_blks,
in_fin_blks, rep->out_mrq_q_blks, out_fin_blks);
@@ -2575,7 +2763,7 @@ sgh_do_deferred_mrq(Rq_elem * rep, mrq_arr_t & def_arr)
h4p->request = 0;
} else
h4p->request = (uint64_t)cmdp;
- if (clp->debug > 5) {
+ if (clp->verbose > 5) {
pr2serr_lk("%s%s[%d] def_arr[%d]", ((0 == k) ? __func__ : ""),
((0 == k) ? ": " : ""), id, k);
if (h4p->din_xferp)
@@ -2617,14 +2805,14 @@ sgh_do_deferred_mrq(Rq_elem * rep, mrq_arr_t & def_arr)
if ((clp->m_aen > 0) && (MONO_MRQ_ID_INIT != mrq_pack_id) &&
(0 == ((mrq_pack_id - MONO_MRQ_ID_INIT) % clp->m_aen))) {
launch_mrq_abort = true;
- if (clp->debug > 2)
+ if (clp->verbose > 2)
pr2serr_lk("[%d] %s: Decide to launch MRQ abort thread, "
"mrq_id=%d\n", id, __func__, mrq_pack_id);
memset(&rep->mai, 0, sizeof(rep->mai));
rep->mai.from_tid = id;
rep->mai.mrq_id = mrq_pack_id;
rep->mai.fd = fd;
- rep->mai.debug = clp->debug;
+ rep->mai.debug = clp->verbose;
status = pthread_create(&rep->mrq_abort_thread_id, NULL,
mrq_abort_thread, (void *)&rep->mai);
@@ -2632,12 +2820,12 @@ sgh_do_deferred_mrq(Rq_elem * rep, mrq_arr_t & def_arr)
}
ctl_v4.request_extra = launch_mrq_abort ? mrq_pack_id : 0;
rep->mrq_id = mrq_pack_id;
- if (clp->debug > 4) {
+ if (clp->verbose > 4) {
if (rep->both_sg && clp->mrq_async)
iosub_str = "SUBMIT(variable)";
pr2serr_lk("%s: Controlling object _before_ ioctl(SG_IO%s):\n",
__func__, iosub_str);
- if (clp->debug > 5)
+ if (clp->verbose > 5)
hex2stderr_lk((const uint8_t *)&ctl_v4, sizeof(ctl_v4), 1);
v4hdr_out_lk("Controlling object before", &ctl_v4, id);
}
@@ -2664,7 +2852,7 @@ sgh_do_deferred_mrq(Rq_elem * rep, mrq_arr_t & def_arr)
h4p->request = 0;
} else
h4p->request = (uint64_t)cmdp;
- if (clp->debug > 5) {
+ if (clp->verbose > 5) {
pr2serr_lk("[%d] df_def_arr[%d]:\n", id, k);
hex2stderr_lk((const uint8_t *)(aa_v4p + k),
sizeof(*aa_v4p), 1);
@@ -2694,7 +2882,7 @@ sgh_do_deferred_mrq(Rq_elem * rep, mrq_arr_t & def_arr)
h4p->request = 0;
} else
h4p->request = (uint64_t)cmdp;
- if (clp->debug > 5) {
+ if (clp->verbose > 5) {
pr2serr_lk("[%d] o_fd_def_arr[%d]:\n", id, k);
hex2stderr_lk((const uint8_t *)(aa_v4p + k),
sizeof(*aa_v4p), 1);
@@ -2715,7 +2903,7 @@ sgh_do_deferred_mrq(Rq_elem * rep, mrq_arr_t & def_arr)
try_again:
if (clp->unbalanced_mrq) {
- if (!after1 && (clp->debug > 1)) {
+ if (!after1 && (clp->verbose > 1)) {
after1 = true;
pr2serr_lk("%s: unbalanced %s\n", __func__, mrq_vb_s);
}
@@ -2723,21 +2911,21 @@ try_again:
} else {
if (clp->mrq_async) {
iosub_str = "SUBMIT(variable_blocking)";
- if (!after1 && (clp->debug > 1)) {
+ if (!after1 && (clp->verbose > 1)) {
after1 = true;
pr2serr_lk("%s: %s\n", __func__, mrq_vb_s);
}
res = ioctl(fd, SG_IOSUBMIT, &ctl_v4);
} else if (clp->in_flags.mrq_svb || clp->in_flags.mrq_svb) {
iosub_str = "SUBMIT(shared_variable_blocking)";
- if (!after1 && (clp->debug > 1)) {
+ if (!after1 && (clp->verbose > 1)) {
after1 = true;
pr2serr_lk("%s: %s\n", __func__, mrq_svb_s);
}
res = ioctl(fd, SG_IOSUBMIT, &ctl_v4);
} else {
iosub_str = "SG_IO(ordered_blocking)";
- if (!after1 && (clp->debug > 1)) {
+ if (!after1 && (clp->verbose > 1)) {
after1 = true;
pr2serr_lk("%s: %s\n", __func__, mrq_blk_s);
}
@@ -2760,13 +2948,13 @@ try_again:
res = -1;
goto fini;
}
- if (clp->debug > 4) {
+ if (clp->verbose > 4) {
pr2serr_lk("%s: Controlling object output by ioctl(%s):\n",
__func__, iosub_str);
- if (clp->debug > 5)
+ if (clp->verbose > 5)
hex2stderr_lk((const uint8_t *)&ctl_v4, sizeof(ctl_v4), 1);
v4hdr_out_lk("Controlling object after", &ctl_v4, id);
- if (clp->debug > 5) {
+ if (clp->verbose > 5) {
for (k = 0; k < nrq; ++k) {
pr2serr_lk("AFTER: def_arr[%d]:\n", k);
v4hdr_out_lk("normal v4 object", (a_v4p + k), id);
@@ -2777,9 +2965,9 @@ try_again:
}
in_fin_blks = 0;
out_fin_blks = 0;
- num_good = chk_mrq_response(rep, &ctl_v4, a_v4p, nrq, &in_fin_blks,
- &out_fin_blks);
- if (clp->debug > 2)
+ num_good = process_mrq_response(rep, &ctl_v4, a_v4p, nrq, in_fin_blks,
+ out_fin_blks);
+ if (clp->verbose > 2)
pr2serr_lk("%s: >>> num_good=%d, in_q/fin blks=%u/%u; out_q/fin "
"blks=%u/%u\n", __func__, num_good, rep->in_mrq_q_blks,
in_fin_blks, rep->out_mrq_q_blks, out_fin_blks);
@@ -2805,7 +2993,7 @@ fini:
if (cmd_ap)
free(cmd_ap);
if (launch_mrq_abort) {
- if (clp->debug > 1)
+ if (clp->verbose > 1)
pr2serr_lk("[%d] %s: About to join MRQ abort thread, "
"mrq_id=%d\n", id, __func__, mrq_pack_id);
@@ -2940,11 +3128,11 @@ sg_start_io(Rq_elem * rep, mrq_arr_t & def_arr, int & pack_id,
flags |= SGV4_FLAG_KEEP_SHARE; /* troublemaking .... */
} else
memset(hp, 0, sizeof(struct sg_io_hdr));
- if (clp->debug > 3) {
+ if (clp->verbose > 3) {
bool lock = true;
char prefix[128];
- if (4 == clp->debug) {
+ if (4 == clp->verbose) {
snprintf(prefix, sizeof(prefix), "tid,rq_id=%d,%d: ", rep->id,
pack_id);
lock = false;
@@ -2985,13 +3173,13 @@ sg_start_io(Rq_elem * rep, mrq_arr_t & def_arr, int & pack_id,
++num_start_eagain;
#ifdef SGH_DD_SNAP_DEV
if (0 == (num_ebusy % 1000))
- sg_take_snap(fd, rep->id, (clp->debug > 2));
+ sg_take_snap(fd, rep->id, (clp->verbose > 2));
#endif
} else if (EBUSY == errno) {
++num_ebusy;
#ifdef SGH_DD_SNAP_DEV
if (0 == (num_ebusy % 1000))
- sg_take_snap(fd, rep->id, (clp->debug > 2));
+ sg_take_snap(fd, rep->id, (clp->verbose > 2));
#endif
}
std::this_thread::yield();/* another thread may be able to progress */
@@ -3051,13 +3239,13 @@ do_v4:
++num_start_eagain;
#ifdef SGH_DD_SNAP_DEV
if (0 == (num_ebusy % 1000))
- sg_take_snap(fd, rep->id, (clp->debug > 2));
+ sg_take_snap(fd, rep->id, (clp->verbose > 2));
#endif
} else if (EBUSY == errno) {
++num_ebusy;
#ifdef SGH_DD_SNAP_DEV
if (0 == (num_ebusy % 1000))
- sg_take_snap(fd, rep->id, (clp->debug > 2));
+ sg_take_snap(fd, rep->id, (clp->verbose > 2));
#endif
}
std::this_thread::yield();/* another thread may be able to progress */
@@ -3097,7 +3285,7 @@ do_v4:
if (res < 0) {
err = errno;
if (ENODATA == err) {
- if (clp->debug > 2)
+ if (clp->verbose > 2)
pr2serr_lk("%s: ioctl(SG_IOABORT) no match on "
"pack_id=%d\n", __func__, pack_id);
} else
@@ -3105,7 +3293,7 @@ do_v4:
__func__, safe_strerror(err), err);
} else {
++num_abort_req_success;
- if (clp->debug > 2)
+ if (clp->verbose > 2)
pr2serr_lk("%s: sent ioctl(SG_IOABORT) on rq_id=%d, "
"success\n", __func__, pack_id);
}
@@ -3130,9 +3318,6 @@ sg_finish_io(bool wr, Rq_elem * rep, int pack_id, struct sg_io_extra *xtrp)
struct sg_io_hdr * hp;
struct sg_io_v4 * h4p;
const char *cp;
-#if 0
- static int testing = 0; /* thread dubious! */
-#endif
if (wr) {
fd = is_wr2 ? rep->out2fd : rep->outfd;
@@ -3160,13 +3345,13 @@ sg_finish_io(bool wr, Rq_elem * rep, int pack_id, struct sg_io_extra *xtrp)
++num_fin_eagain;
#ifdef SGH_DD_SNAP_DEV
if (0 == (num_ebusy % 1000))
- sg_take_snap(fd, rep->id, (clp->debug > 2));
+ sg_take_snap(fd, rep->id, (clp->verbose > 2));
#endif
} else if (EBUSY == errno) {
++num_ebusy;
#ifdef SGH_DD_SNAP_DEV
if (0 == (num_ebusy % 1000))
- sg_take_snap(fd, rep->id, (clp->debug > 2));
+ sg_take_snap(fd, rep->id, (clp->verbose > 2));
#endif
}
std::this_thread::yield();/* another thread may be able to progress */
@@ -3190,7 +3375,7 @@ sg_finish_io(bool wr, Rq_elem * rep, int pack_id, struct sg_io_extra *xtrp)
break;
case SG_LIB_CAT_ABORTED_COMMAND:
case SG_LIB_CAT_UNIT_ATTENTION:
- if (clp->debug > 3)
+ if (clp->verbose > 3)
lk_chk_n_print3(cp, hp, false);
return res;
case SG_LIB_CAT_NOT_READY:
@@ -3203,16 +3388,13 @@ sg_finish_io(bool wr, Rq_elem * rep, int pack_id, struct sg_io_extra *xtrp)
return res;
}
}
-#if 0
- if (0 == (++testing % 100)) return -1;
-#endif
if ((wr ? clp->out_flags.dio : clp->in_flags.dio) &&
(! (hp->info & SG_INFO_DIRECT_IO_MASK)))
rep->dio_incomplete_count = 1; /* count dios done as indirect IO */
else
rep->dio_incomplete_count = 0;
rep->resid = hp->resid;
- if (clp->debug > 3)
+ if (clp->verbose > 3)
pr2serr_lk("%s: tid=%d: completed %s\n", __func__, rep->id, cp);
return 0;
@@ -3229,13 +3411,13 @@ do_v4:
++num_fin_eagain;
#ifdef SGH_DD_SNAP_DEV
if (0 == (num_ebusy % 1000))
- sg_take_snap(fd, rep->id, (clp->debug > 2));
+ sg_take_snap(fd, rep->id, (clp->verbose > 2));
#endif
} else if (EBUSY == errno) {
++num_ebusy;
#ifdef SGH_DD_SNAP_DEV
if (0 == (num_ebusy % 1000))
- sg_take_snap(fd, rep->id, (clp->debug > 2));
+ sg_take_snap(fd, rep->id, (clp->verbose > 2));
#endif
}
std::this_thread::yield();/* another thread may be able to progress */
@@ -3259,7 +3441,7 @@ do_v4:
break;
case SG_LIB_CAT_ABORTED_COMMAND:
case SG_LIB_CAT_UNIT_ATTENTION:
- if (clp->debug > 3)
+ if (clp->verbose > 3)
lk_chk_n_print4(cp, h4p, false);
return res;
case SG_LIB_CAT_NOT_READY:
@@ -3270,7 +3452,7 @@ do_v4:
snprintf(ebuff, EBUFF_SZ, "%s rq_id=%d, blk=%" PRId64, cp,
pack_id, blk);
lk_chk_n_print4(ebuff, h4p, false);
- if ((clp->debug > 4) && h4p->info)
+ if ((clp->verbose > 4) && h4p->info)
pr2serr_lk(" info=0x%x sg_info_check=%d direct=%d "
"detaching=%d aborted=%d\n", h4p->info,
!!(h4p->info & SG_INFO_CHECK),
@@ -3280,19 +3462,16 @@ do_v4:
return res;
}
}
-#if 0
- if (0 == (++testing % 100)) return -1;
-#endif
if ((wr ? clp->out_flags.dio : clp->in_flags.dio) &&
! (h4p->info & SG_INFO_DIRECT_IO))
rep->dio_incomplete_count = 1; /* count dios done as indirect IO */
else
rep->dio_incomplete_count = 0;
rep->resid = h4p->din_resid;
- if (clp->debug > 4) {
+ if (clp->verbose > 4) {
pr2serr_lk("%s: tid,rq_id=%d,%d: completed %s\n", __func__, rep->id,
pack_id, cp);
- if ((clp->debug > 4) && h4p->info)
+ if ((clp->verbose > 4) && h4p->info)
pr2serr_lk(" info=0x%x sg_info_check=%d direct=%d "
"detaching=%d aborted=%d\n", h4p->info,
!!(h4p->info & SG_INFO_CHECK),
@@ -3730,7 +3909,7 @@ sg_in_open(struct global_collection *clp, const char *inf, uint8_t **mmpp,
if (n <= 0)
return -SG_LIB_FILE_ERROR;
if (clp->noshare)
- sg_noshare_enlarge(fd, clp->debug > 3);
+ sg_noshare_enlarge(fd, clp->verbose > 3);
if (mmap_lenp)
*mmap_lenp = n;
return fd;
@@ -3765,7 +3944,7 @@ sg_out_open(struct global_collection *clp, const char *outf, uint8_t **mmpp,
if (n <= 0)
return -SG_LIB_FILE_ERROR;
if (clp->noshare)
- sg_noshare_enlarge(fd, clp->debug > 3);
+ sg_noshare_enlarge(fd, clp->verbose > 3);
if (mmap_lenp)
*mmap_lenp = n;
return fd;
@@ -3848,10 +4027,7 @@ parse_cmdline_sanity(int argc, char * argv[], struct global_collection * clp,
return SG_LIB_SYNTAX_ERROR;
}
} /* treat 'count=-1' as calculate count (same as not given) */
- } else if ((0 == strncmp(key, "deb", 3)) ||
- (0 == strncmp(key, "verb", 4)))
- clp->debug = sg_get_num(buf);
- else if (0 == strcmp(key, "dio")) {
+ } else if (0 == strcmp(key, "dio")) {
clp->in_flags.dio = !! sg_get_num(buf);
clp->out_flags.dio = clp->in_flags.dio;
} else if (0 == strcmp(key, "elemsz_kb")) {
@@ -3980,6 +4156,8 @@ parse_cmdline_sanity(int argc, char * argv[], struct global_collection * clp,
do_time = sg_get_num(buf);
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);
else if ((keylen > 1) && ('-' == key[0]) && ('-' != key[1])) {
res = 0;
n = num_chs_in_str(key + 1, keylen - 1, 'd');
@@ -3995,7 +4173,7 @@ parse_cmdline_sanity(int argc, char * argv[], struct global_collection * clp,
n = num_chs_in_str(key + 1, keylen - 1, 'v');
if (n > 0)
verbose_given = true;
- clp->debug += n; /* -v ---> --verbose */
+ clp->verbose += n; /* -v ---> --verbose */
res += n;
n = num_chs_in_str(key + 1, keylen - 1, 'V');
if (n > 0)
@@ -4022,7 +4200,7 @@ parse_cmdline_sanity(int argc, char * argv[], struct global_collection * clp,
clp->prefetch = true;
else if (0 == strncmp(key, "--verb", 6)) {
verbose_given = true;
- ++clp->debug; /* --verbose */
+ ++clp->verbose; /* --verbose */
} else if (0 == strncmp(key, "--veri", 6))
verify_given = true;
else if (0 == strncmp(key, "--vers", 6))
@@ -4040,12 +4218,12 @@ parse_cmdline_sanity(int argc, char * argv[], struct global_collection * clp,
pr2serr("but override: '-vV' given, zero verbose and continue\n");
verbose_given = false;
version_given = false;
- clp->debug = 0;
+ clp->verbose = 0;
} else if (! verbose_given) {
pr2serr("set '-vv'\n");
- clp->debug = 2;
+ clp->verbose = 2;
} else
- pr2serr("keep verbose=%d\n", clp->debug);
+ pr2serr("keep verbose=%d\n", clp->verbose);
#else
if (verbose_given && version_given)
pr2serr("Not in DEBUG mode, so '-vV' has no special action\n");
@@ -4141,7 +4319,7 @@ parse_cmdline_sanity(int argc, char * argv[], struct global_collection * clp,
}
clp->unit_nanosec = (do_time > 1) || !!getenv("SG3_UTILS_LINUX_NANO");
#if 0
- if (clp->debug) {
+ if (clp->verbose) {
pr2serr("%sif=%s skip=%" PRId64 " of=%s seek=%" PRId64 " count=%"
PRId64, my_name, inf, clp->skip, outf, clp->seek, dd_count);
if (clp->nmrqs > 0)
@@ -4441,7 +4619,7 @@ main(int argc, char * argv[])
if (clp->in_flags.v4_given && (! clp->out_flags.v3)) {
if (! clp->out_flags.v4_given) {
clp->out_flags.v4 = true;
- if (clp->debug)
+ if (clp->verbose)
pr2serr("Changing OFILE from v3 to v4, use oflag=v3 to "
"force v3\n");
}
@@ -4449,7 +4627,7 @@ main(int argc, char * argv[])
if (clp->out_flags.v4_given && (! clp->in_flags.v3)) {
if (! clp->in_flags.v4_given) {
clp->in_flags.v4 = true;
- if (clp->debug)
+ if (clp->verbose)
pr2serr("Changing IFILE from v3 to v4, use iflag=v3 to "
"force v3\n");
}
@@ -4481,7 +4659,7 @@ main(int argc, char * argv[])
perror(ebuff);
return sg_convert_errno(err);
}
- if (clp->debug > 1)
+ if (clp->verbose > 1)
pr2serr("ofreg=%s opened okay, fd=%d\n", outregf, clp->outregfd);
if (FT_ERROR == ftyp)
clp->outreg_type = FT_OTHER; /* regular file created */
@@ -4580,7 +4758,7 @@ main(int argc, char * argv[])
else
dd_count = out_num_sect;
}
- if (clp->debug > 2)
+ if (clp->verbose > 2)
pr2serr("Start of loop, count=%" PRId64 ", in_num_sect=%" PRId64
", out_num_sect=%" PRId64 "\n", dd_count, in_num_sect,
out_num_sect);
@@ -4675,7 +4853,7 @@ main(int argc, char * argv[])
tip = thread_arr + k;
status = pthread_join(tip->a_pthr, &vp);
if (0 != status) err_exit(status, "pthread_join");
- if (clp->debug > 2)
+ if (clp->verbose > 2)
pr2serr_lk("%d <-- Worker thread terminated, vp=%s\n", k,
((vp == clp) ? "clp" : "NULL (or !clp)"));
}
@@ -4754,24 +4932,24 @@ fini:
if (clp->sum_of_resids.load())
pr2serr(">> Non-zero sum of residual counts=%d\n",
clp->sum_of_resids.load());
- if (clp->debug && (num_start_eagain > 0))
+ if (clp->verbose && (num_start_eagain > 0))
pr2serr("Number of start EAGAINs: %d\n", num_start_eagain.load());
- if (clp->debug && (num_fin_eagain > 0))
+ if (clp->verbose && (num_fin_eagain > 0))
pr2serr("Number of finish EAGAINs: %d\n", num_fin_eagain.load());
- if (clp->debug && (num_ebusy > 0))
+ if (clp->verbose && (num_ebusy > 0))
pr2serr("Number of EBUSYs: %d\n", num_ebusy.load());
- if (clp->debug && clp->aen_given && (num_abort_req > 0)) {
+ if (clp->verbose && clp->aen_given && (num_abort_req > 0)) {
pr2serr("Number of Aborts: %d\n", num_abort_req.load());
pr2serr("Number of successful Aborts: %d\n",
num_abort_req_success.load());
}
- if (clp->debug && clp->m_aen_given && (num_mrq_abort_req > 0)) {
+ if (clp->verbose && clp->m_aen_given && (num_mrq_abort_req > 0)) {
pr2serr("Number of MRQ Aborts: %d\n", num_mrq_abort_req.load());
pr2serr("Number of successful MRQ Aborts: %d\n",
num_mrq_abort_req_success.load());
}
- if (clp->debug > 1) {
- if (clp->debug > 3)
+ if (clp->verbose > 1) {
+ if (clp->verbose > 3)
pr2serr("Final pack_id=%d, mrq_id=%d\n", mono_pack_id.load(),
mono_mrq_id.load());
pr2serr("Number of SG_GET_NUM_WAITING calls=%ld\n",