aboutsummaryrefslogtreecommitdiff
path: root/testing/sg_mrq_dd.cpp
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 /testing/sg_mrq_dd.cpp
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
Diffstat (limited to 'testing/sg_mrq_dd.cpp')
-rw-r--r--testing/sg_mrq_dd.cpp601
1 files changed, 241 insertions, 360 deletions
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;