aboutsummaryrefslogtreecommitdiff
path: root/testing
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2019-01-31 14:29:54 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2019-01-31 14:29:54 +0000
commit04adb7f5027fb9f8b4368e4eaa561e14591bb1a7 (patch)
tree7f3af533e28c692c020eabd152b49762f340f106 /testing
parenta918d1a30569c4d3f09cc87836ff19215db6d8b7 (diff)
downloadsg3_utils-04adb7f5027fb9f8b4368e4eaa561e14591bb1a7.tar.gz
linux: add nanosecond durations when SG3_UTILS_LINUX_NANO environment variable given
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@809 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'testing')
-rw-r--r--testing/sg_queue_tst.c6
-rw-r--r--testing/sg_tst_async.cpp10
-rw-r--r--testing/sg_tst_bidi.c10
-rw-r--r--testing/sg_tst_ioctl.c71
-rw-r--r--testing/sgh_dd.c193
-rw-r--r--testing/uapi_sg.h46
6 files changed, 201 insertions, 135 deletions
diff --git a/testing/sg_queue_tst.c b/testing/sg_queue_tst.c
index 064d3885..f7754fae 100644
--- a/testing/sg_queue_tst.c
+++ b/testing/sg_queue_tst.c
@@ -15,7 +15,7 @@
* Invocation: sg_queue_tst [-l=Q_LEN] [-t] <sg_device>
* -t queue at tail
*
- * Version 0.95 (20190111)
+ * Version 0.96 (20190128)
*/
#include <unistd.h>
@@ -84,8 +84,8 @@ set_nanosecs(int sg_fd)
seip = &sei;
memset(seip, 0, sizeof(*seip));
- seip->valid_wr_mask |= SG_SEIM_CTL_FLAGS;
- seip->valid_rd_mask |= SG_SEIM_CTL_FLAGS; /* this or previous optional */
+ seip->sei_wr_mask |= SG_SEIM_CTL_FLAGS;
+ seip->sei_rd_mask |= SG_SEIM_CTL_FLAGS; /* this or previous optional */
seip->ctl_flags_wr_mask |= SG_CTL_FLAGM_TIME_IN_NS;
seip->ctl_flags |= SG_CTL_FLAGM_TIME_IN_NS;
diff --git a/testing/sg_tst_async.cpp b/testing/sg_tst_async.cpp
index 9c34b7a3..ab133348 100644
--- a/testing/sg_tst_async.cpp
+++ b/testing/sg_tst_async.cpp
@@ -88,7 +88,7 @@
#include "sg_pt.h"
#include "sg_cmds.h"
-static const char * version_str = "1.24 20190104";
+static const char * version_str = "1.25 20190128";
static const char * util_name = "sg_tst_async";
/* This is a test program for checking the async usage of the Linux sg
@@ -935,8 +935,8 @@ work_thread(int id, struct opts_t * op)
seip = &sei;
memset(seip, 0, sizeof(*seip));
- seip->valid_wr_mask |= SG_SEIM_CTL_FLAGS;
- seip->valid_rd_mask |= SG_SEIM_CTL_FLAGS;
+ seip->sei_wr_mask |= SG_SEIM_CTL_FLAGS;
+ seip->sei_rd_mask |= SG_SEIM_CTL_FLAGS;
seip->ctl_flags_rd_mask |= SG_CTL_FLAGM_TIME_IN_NS;
if (ioctl(sg_fd, SG_SET_GET_EXTENDED, seip) < 0) {
pr2serr_lk("ioctl(EXTENDED(TIME_IN_NS)) failed, errno=%d %s\n",
@@ -944,8 +944,8 @@ work_thread(int id, struct opts_t * op)
}
if (! (SG_CTL_FLAGM_TIME_IN_NS & seip->ctl_flags)) {
memset(seip, 0, sizeof(*seip));
- seip->valid_rd_mask |= SG_SEIM_CTL_FLAGS;
- seip->valid_wr_mask |= SG_SEIM_CTL_FLAGS;
+ seip->sei_rd_mask |= SG_SEIM_CTL_FLAGS;
+ seip->sei_wr_mask |= SG_SEIM_CTL_FLAGS;
seip->ctl_flags_wr_mask |= SG_CTL_FLAGM_TIME_IN_NS;
seip->ctl_flags |= SG_CTL_FLAGM_TIME_IN_NS;
if (ioctl(sg_fd, SG_SET_GET_EXTENDED, seip) < 0)
diff --git a/testing/sg_tst_bidi.c b/testing/sg_tst_bidi.c
index fd5d00c0..624266cc 100644
--- a/testing/sg_tst_bidi.c
+++ b/testing/sg_tst_bidi.c
@@ -53,7 +53,7 @@
is implemented by the scsi_debug driver is used. */
-static const char * version_str = "Version: 1.03 20190122";
+static const char * version_str = "Version: 1.04 20190128";
#define INQ_REPLY_LEN 96
#define INQ_CMD_OP 0x12
@@ -130,11 +130,11 @@ ext_ioctl(int sg_fd, bool nanosecs)
seip = &sei;
memset(seip, 0, sizeof(*seip));
- seip->valid_wr_mask |= SG_SEIM_RESERVED_SIZE;
+ seip->sei_wr_mask |= SG_SEIM_RESERVED_SIZE;
seip->reserved_sz = reserve_buff_sz;
- seip->valid_rd_mask |= SG_SEIM_RESERVED_SIZE;
- seip->valid_wr_mask |= SG_SEIM_CTL_FLAGS;
- seip->valid_rd_mask |= SG_SEIM_CTL_FLAGS; /* this or previous optional */
+ seip->sei_rd_mask |= SG_SEIM_RESERVED_SIZE;
+ seip->sei_wr_mask |= SG_SEIM_CTL_FLAGS;
+ seip->sei_rd_mask |= SG_SEIM_CTL_FLAGS; /* this or previous optional */
seip->ctl_flags_wr_mask |= SG_CTL_FLAGM_TIME_IN_NS;
seip->ctl_flags_rd_mask |= SG_CTL_FLAGM_TIME_IN_NS;
if (nanosecs)
diff --git a/testing/sg_tst_ioctl.c b/testing/sg_tst_ioctl.c
index c030889e..cdca282c 100644
--- a/testing/sg_tst_ioctl.c
+++ b/testing/sg_tst_ioctl.c
@@ -53,7 +53,7 @@
* later of the Linux sg driver. */
-static const char * version_str = "Version: 1.03 20190123";
+static const char * version_str = "Version: 1.03 20190128";
#define INQ_REPLY_LEN 96
#define INQ_CMD_LEN 6
@@ -221,16 +221,15 @@ tst_ioctl(const char * fnp, int sg_fd, const char * fn2p, int sg_fd2,
seip = &sei;
memset(seip, 0, sizeof(*seip));
- seip->valid_wr_mask |= SG_SEIM_RESERVED_SIZE;
+ seip->sei_wr_mask |= SG_SEIM_RESERVED_SIZE;
seip->reserved_sz = reserve_buff_sz;
seip->sgat_elem_sz = 64 * 1024;
- seip->valid_rd_mask |= SG_SEIM_RESERVED_SIZE;
- seip->valid_rd_mask |= SG_SEIM_RQ_REM_THRESH;
- seip->valid_rd_mask |= SG_SEIM_TOT_FD_THRESH;
- seip->valid_wr_mask |= SG_SEIM_CTL_FLAGS;
- seip->valid_rd_mask |= SG_SEIM_CTL_FLAGS; /* this or previous optional */
- seip->valid_rd_mask |= SG_SEIM_MINOR_INDEX;
- seip->valid_wr_mask |= SG_SEIM_SGAT_ELEM_SZ;
+ seip->sei_rd_mask |= SG_SEIM_RESERVED_SIZE;
+ seip->sei_rd_mask |= SG_SEIM_TOT_FD_THRESH;
+ seip->sei_wr_mask |= SG_SEIM_CTL_FLAGS;
+ seip->sei_rd_mask |= SG_SEIM_CTL_FLAGS; /* this or previous optional */
+ seip->sei_rd_mask |= SG_SEIM_MINOR_INDEX;
+ seip->sei_wr_mask |= SG_SEIM_SGAT_ELEM_SZ;
seip->ctl_flags_wr_mask |= SG_CTL_FLAGM_TIME_IN_NS;
seip->ctl_flags_rd_mask |= SG_CTL_FLAGM_TIME_IN_NS;
seip->ctl_flags_rd_mask |= SG_CTL_FLAGM_OTHER_OPENS;
@@ -251,16 +250,14 @@ tst_ioctl(const char * fnp, int sg_fd, const char * fn2p, int sg_fd2,
}
#if 1
printf("%sSG_SET_GET_EXTENDED ioctl ok\n", cp);
- if (SG_SEIM_RESERVED_SIZE & seip->valid_rd_mask)
+ if (SG_SEIM_RESERVED_SIZE & seip->sei_rd_mask)
printf(" %sreserved size: %u\n", cp, seip->reserved_sz);
- if (SG_SEIM_MINOR_INDEX & seip->valid_rd_mask)
+ if (SG_SEIM_MINOR_INDEX & seip->sei_rd_mask)
printf(" %sminor index: %u\n", cp, seip->minor_index);
- if (SG_SEIM_RQ_REM_THRESH & seip->valid_rd_mask)
- printf(" %srq_rem_sgat_thresh: %u\n", cp, seip->rq_rem_sgat_thresh);
- if (SG_SEIM_TOT_FD_THRESH & seip->valid_rd_mask)
+ if (SG_SEIM_TOT_FD_THRESH & seip->sei_rd_mask)
printf(" %stot_fd_thresh: %u\n", cp, seip->tot_fd_thresh);
- if ((SG_SEIM_CTL_FLAGS & seip->valid_rd_mask) ||
- (SG_SEIM_CTL_FLAGS & seip->valid_wr_mask)) {
+ if ((SG_SEIM_CTL_FLAGS & seip->sei_rd_mask) ||
+ (SG_SEIM_CTL_FLAGS & seip->sei_wr_mask)) {
cflags = seip->ctl_flags;
if (SG_CTL_FLAGM_TIME_IN_NS & seip->ctl_flags_rd_mask)
printf(" %sTIME_IN_NS: %s\n", cp,
@@ -293,14 +290,14 @@ tst_ioctl(const char * fnp, int sg_fd, const char * fn2p, int sg_fd2,
printf(" %sCHECK_FOR_MORE: %s\n", cp,
(SG_CTL_FLAGM_CHECK_FOR_MORE & cflags) ? "true" : "false");
}
- if (SG_SEIM_MINOR_INDEX & seip->valid_rd_mask)
+ if (SG_SEIM_MINOR_INDEX & seip->sei_rd_mask)
printf(" %sminor_index: %u\n", cp, seip->minor_index);
printf("\n");
#endif
memset(seip, 0, sizeof(*seip));
- seip->valid_wr_mask |= SG_SEIM_READ_VAL;
- seip->valid_rd_mask |= SG_SEIM_READ_VAL;
+ seip->sei_wr_mask |= SG_SEIM_READ_VAL;
+ seip->sei_rd_mask |= SG_SEIM_READ_VAL;
seip->read_value = SG_SEIRV_INT_MASK;
if (ioctl(sg_fd, SG_SET_GET_EXTENDED, seip) < 0) {
pr2serr("ioctl(SG_SET_GET_EXTENDED) failed, errno=%d %s\n", errno,
@@ -310,8 +307,8 @@ tst_ioctl(const char * fnp, int sg_fd, const char * fn2p, int sg_fd2,
printf(" %sread_value[SG_SEIRV_INT_MASK]= %u\n", cp, seip->read_value);
memset(seip, 0, sizeof(*seip));
- seip->valid_wr_mask |= SG_SEIM_READ_VAL;
- seip->valid_rd_mask |= SG_SEIM_READ_VAL;
+ seip->sei_wr_mask |= SG_SEIM_READ_VAL;
+ seip->sei_rd_mask |= SG_SEIM_READ_VAL;
seip->read_value = SG_SEIRV_BOOL_MASK;
if (ioctl(sg_fd, SG_SET_GET_EXTENDED, seip) < 0) {
pr2serr("ioctl(SG_SET_GET_EXTENDED) failed, errno=%d %s\n", errno,
@@ -321,8 +318,8 @@ tst_ioctl(const char * fnp, int sg_fd, const char * fn2p, int sg_fd2,
printf(" %sread_value[SG_SEIRV_BOOL_MASK]= %u\n", cp, seip->read_value);
memset(seip, 0, sizeof(*seip));
- seip->valid_wr_mask |= SG_SEIM_READ_VAL;
- seip->valid_rd_mask |= SG_SEIM_READ_VAL;
+ seip->sei_wr_mask |= SG_SEIM_READ_VAL;
+ seip->sei_rd_mask |= SG_SEIM_READ_VAL;
seip->read_value = SG_SEIRV_VERS_NUM;
if (ioctl(sg_fd, SG_SET_GET_EXTENDED, seip) < 0) {
pr2serr("ioctl(SG_SET_GET_EXTENDED) failed, errno=%d %s\n", errno,
@@ -332,8 +329,8 @@ tst_ioctl(const char * fnp, int sg_fd, const char * fn2p, int sg_fd2,
printf(" %sread_value[SG_SEIRV_VERS_NUM]= %u\n", cp, seip->read_value);
memset(seip, 0, sizeof(*seip));
- seip->valid_wr_mask |= SG_SEIM_READ_VAL;
- seip->valid_rd_mask |= SG_SEIM_READ_VAL;
+ seip->sei_wr_mask |= SG_SEIM_READ_VAL;
+ seip->sei_rd_mask |= SG_SEIM_READ_VAL;
seip->read_value = SG_SEIRV_FL_RQS;
if (ioctl(sg_fd, SG_SET_GET_EXTENDED, seip) < 0) {
pr2serr("ioctl(SG_SET_GET_EXTENDED) failed, errno=%d %s\n", errno,
@@ -343,8 +340,8 @@ tst_ioctl(const char * fnp, int sg_fd, const char * fn2p, int sg_fd2,
printf(" %sread_value[SG_SEIRV_FL_RQS]= %u\n", cp, seip->read_value);
memset(seip, 0, sizeof(*seip));
- seip->valid_wr_mask |= SG_SEIM_READ_VAL;
- seip->valid_rd_mask |= SG_SEIM_READ_VAL;
+ seip->sei_wr_mask |= SG_SEIM_READ_VAL;
+ seip->sei_rd_mask |= SG_SEIM_READ_VAL;
seip->read_value = SG_SEIRV_DEV_FL_RQS;
if (ioctl(sg_fd, SG_SET_GET_EXTENDED, seip) < 0) {
pr2serr("ioctl(SG_SET_GET_EXTENDED) failed, errno=%d %s\n", errno,
@@ -354,8 +351,8 @@ tst_ioctl(const char * fnp, int sg_fd, const char * fn2p, int sg_fd2,
printf(" %sread_value[SG_SEIRV_DEV_FL_RQS]= %u\n", cp, seip->read_value);
memset(seip, 0, sizeof(*seip));
- seip->valid_wr_mask |= SG_SEIM_READ_VAL;
- seip->valid_rd_mask |= SG_SEIM_READ_VAL;
+ seip->sei_wr_mask |= SG_SEIM_READ_VAL;
+ seip->sei_rd_mask |= SG_SEIM_READ_VAL;
seip->read_value = SG_SEIRV_TRC_SZ;
if (ioctl(sg_fd, SG_SET_GET_EXTENDED, seip) < 0) {
pr2serr("ioctl(SG_SET_GET_EXTENDED) failed, errno=%d %s\n", errno,
@@ -365,8 +362,8 @@ tst_ioctl(const char * fnp, int sg_fd, const char * fn2p, int sg_fd2,
printf(" %sread_value[SG_SEIRV_TRC_SZ]= %u\n", cp, seip->read_value);
memset(seip, 0, sizeof(*seip));
- seip->valid_wr_mask |= SG_SEIM_READ_VAL;
- seip->valid_rd_mask |= SG_SEIM_READ_VAL;
+ seip->sei_wr_mask |= SG_SEIM_READ_VAL;
+ seip->sei_rd_mask |= SG_SEIM_READ_VAL;
seip->read_value = SG_SEIRV_TRC_MAX_SZ;
if (ioctl(sg_fd, SG_SET_GET_EXTENDED, seip) < 0) {
pr2serr("ioctl(SG_SET_GET_EXTENDED) failed, errno=%d %s\n", errno,
@@ -376,8 +373,8 @@ tst_ioctl(const char * fnp, int sg_fd, const char * fn2p, int sg_fd2,
printf(" %sread_value[SG_SEIRV_TRC_MAX_SZ]= %u\n", cp, seip->read_value);
memset(seip, 0, sizeof(*seip));
- seip->valid_wr_mask |= SG_SEIM_SHARE_FD;
- seip->valid_rd_mask |= SG_SEIM_SHARE_FD;
+ seip->sei_wr_mask |= SG_SEIM_SHARE_FD;
+ seip->sei_rd_mask |= SG_SEIM_SHARE_FD;
#if 1
seip->share_fd = sg_fd2;
#else
@@ -389,7 +386,7 @@ tst_ioctl(const char * fnp, int sg_fd, const char * fn2p, int sg_fd2,
pr2serr("%sioctl(SG_SET_GET_EXTENDED) shared_fd=%d, failed errno=%d "
"%s\n", cp, sg_fd2, errno, strerror(errno));
}
- printf(" %sshare successful, read back shared_fd= %d\n", cp,
+ printf(" %sshare successful, read back previous shared_fd= %d\n", cp,
(int)seip->share_fd);
bypass_share:
@@ -440,6 +437,8 @@ bypass_share:
return 0;
}
+#include <linux/fs.h>
+#include <linux/blktrace_api.h>
int
main(int argc, char * argv[])
@@ -462,6 +461,10 @@ main(int argc, char * argv[])
const char * cp;
struct sg_scsi_id ssi;
+
+ if (sizeof(struct sg_extended_info) != 96)
+ pr2serr("Warning <<<< sizeof(struct sg_extended_info)=%zu not 96\n",
+ sizeof(struct sg_extended_info));
for (k = 1; k < argc; ++k) {
if (0 == memcmp("-f", argv[k], 2))
do_fork = true;
diff --git a/testing/sgh_dd.c b/testing/sgh_dd.c
index 6d0ae7a7..1c78eba8 100644
--- a/testing/sgh_dd.c
+++ b/testing/sgh_dd.c
@@ -46,9 +46,11 @@
#include <stdlib.h>
#include <stdarg.h>
#include <stdbool.h>
+#include <stdatomic.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
+#include <poll.h>
#include <limits.h>
#include <pthread.h>
#include <signal.h>
@@ -87,7 +89,7 @@
#else
#define __user
-#endif /* end of: ifndef HAVE_LINUX_SG_V4_HDR */
+#endif /* end of: ifndef HAVE_LINUX_SG_V4_HDR */
#include "sg_lib.h"
#include "sg_cmds_basic.h"
@@ -96,7 +98,7 @@
#include "sg_pr2serr.h"
-static const char * version_str = "1.14 20190107";
+static const char * version_str = "1.17 20190130";
#ifdef __GNUC__
#ifndef __clang__
@@ -177,6 +179,7 @@ typedef struct global_collection
int out2fd;
int out2_type;
int cdbsz_out;
+ int aen; /* abort every nth command */
struct flags_t out_flags;
int64_t out_blk; /* -\ next block address to write */
int64_t out_count; /* | blocks remaining for next write */
@@ -223,6 +226,9 @@ typedef struct request_element
int resid;
int cdbsz_in;
int cdbsz_out;
+ int aen;
+ int rep_count;
+ int rq_id;
int mmap_len;
struct flags_t in_flags;
struct flags_t out_flags;
@@ -236,6 +242,8 @@ typedef struct thread_info
pthread_t a_pthr;
} Thread_info;
+static atomic_int mono_pack_id;
+
static sigset_t signal_set;
static pthread_t sig_listen_thread_id;
@@ -509,13 +517,13 @@ usage(int pg_num)
" [obs=BS] [of=OFILE] [oflag=FLAGS] "
"[seek=SEEK] [skip=SKIP]\n"
" [--help] [--version]\n\n");
- pr2serr(" [bpt=BPT] [cdbsz=6|10|12|16] [coe=0|1] "
- "[deb=VERB] [dio=0|1]\n"
- " [elemsz_kb=ESK] [fua=0|1|2|3] [of2=OFILE2] "
- "[ofreg=OFREG]\n"
- " [sync=0|1] [thr=THR] [time=0|1] [verbose=VERB] "
- "[--dry-run]\n"
- " [--verbose]\n\n"
+ pr2serr(" [ae=AEN] [bpt=BPT] [cdbsz=6|10|12|16] [coe=0|1] "
+ "[deb=VERB]\n"
+ " [dio=0|1] [elemsz_kb=ESK] [fua=0|1|2|3] "
+ "[of2=OFILE2]\n"
+ " [ofreg=OFREG] [sync=0|1] [thr=THR] [time=0|1] "
+ "[verbose=VERB]\n"
+ " [--dry-run] [--verbose]\n\n"
" where the main options (shown in first group above) are:\n"
" bs must be device logical block size (default "
"512)\n"
@@ -549,10 +557,12 @@ usage(int pg_num)
page2:
pr2serr("Syntax: sgh_dd [operands] [options]\n\n"
" where: operands have the form name=value and are pecular to "
- "'dd'\n style commands, and options start with one or two "
- "hyphens\n\n"
+ "'dd'\n style commands, and options start with one or "
+ "two hyphens\n\n"
" where the less used options (not shown on first help page) "
"are:\n"
+ " ae abort every n commands (def: 0 --> don't abort "
+ "any)\n"
" bpt is blocks_per_transfer (default is 128)\n"
" cdbsz size of SCSI READ or WRITE cdb (default is 10)\n"
" coe continue on error, 0->exit (def), "
@@ -734,8 +744,8 @@ sg_share_prepare(int slave_wr_fd, int master_rd_fd, int id, bool vb_b)
seip = &sei;
memset(seip, 0, sizeof(*seip));
- seip->valid_wr_mask |= SG_SEIM_SHARE_FD;
- seip->valid_rd_mask |= SG_SEIM_SHARE_FD;
+ seip->sei_wr_mask |= SG_SEIM_SHARE_FD;
+ seip->sei_rd_mask |= SG_SEIM_SHARE_FD;
seip->share_fd = master_rd_fd;
if (ioctl(slave_wr_fd, SG_SET_GET_EXTENDED, seip) < 0) {
pr2serr_lk("tid=%d: ioctl(EXTENDED(shared_fd=%d), failed "
@@ -815,6 +825,8 @@ read_write_thread(void * v_tip)
rep->cdbsz_out = clp->cdbsz_out;
rep->in_flags = clp->in_flags;
rep->out_flags = clp->out_flags;
+ rep->aen = clp->aen;
+ rep->rep_count = 0;
if (rep->in_flags.same_fds || rep->out_flags.same_fds)
; /* we are sharing a single pair of fd_s across all threads */
@@ -905,6 +917,7 @@ read_write_thread(void * v_tip)
if (0 != status) err_exit(status, "unlock in_mutex");
}
pthread_cleanup_pop(0);
+ ++rep->rep_count;
/* Start of WRITE part of a segment */
rep->wr = true;
@@ -968,11 +981,13 @@ skip_force_out_sequence:
clp->out_rem_count -= blocks;
status = pthread_mutex_unlock(&clp->out_mutex);
if (0 != status) err_exit(status, "unlock out_mutex");
+ --rep->rep_count;
} else {
normal_out_wr(clp, rep, blocks);
status = pthread_mutex_unlock(&clp->out_mutex);
if (0 != status) err_exit(status, "unlock out_mutex");
}
+ ++rep->rep_count;
pthread_cleanup_pop(0);
/* Output to OFILE2 if sg device */
@@ -990,6 +1005,14 @@ skip_force_out_sequence:
break;
} /* end of while loop which copies segments */
+ status = pthread_mutex_lock(&clp->in_mutex);
+ if (0 != status) err_exit(status, "lock in_mutex");
+ if (! clp->in_stop)
+ clp->in_stop = true; /* flag other workers to stop */
+ status = pthread_mutex_unlock(&clp->in_mutex);
+ if (0 != status) err_exit(status, "unlock in_mutex");
+
+fini:
if (rep->mmap_len > 0) {
if (munmap(rep->buffp, rep->mmap_len) < 0) {
int err = errno;
@@ -1001,18 +1024,11 @@ skip_force_out_sequence:
} else if (rep->alloc_bp)
free(rep->alloc_bp);
- status = pthread_mutex_lock(&clp->in_mutex);
- if (0 != status) err_exit(status, "lock in_mutex");
- if (! clp->in_stop)
- clp->in_stop = true; /* flag other workers to stop */
- status = pthread_mutex_unlock(&clp->in_mutex);
- if (0 != status) err_exit(status, "unlock in_mutex");
-fini:
- if (own_infd)
+ if (own_infd && (rep->infd >= 0))
close(rep->infd);
- if (own_outfd)
+ if (own_outfd && (rep->outfd >= 0))
close(rep->outfd);
- if (own_out2fd)
+ if (own_out2fd && (rep->out2fd >= 0))
close(rep->out2fd);
pthread_cond_broadcast(&clp->out_sync_cv);
return stop_after_write ? NULL : clp;
@@ -1257,13 +1273,13 @@ sg_wr_swap_share(Rq_elem * rep, int to_fd, bool before)
seip = &sei;
memset(seip, 0, sizeof(*seip));
- seip->valid_wr_mask |= SG_SEIM_CHG_SHARE_FD;
- seip->valid_rd_mask |= SG_SEIM_CHG_SHARE_FD;
+ 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->valid_wr_mask |= SG_SEIM_CTL_FLAGS;
- seip->valid_rd_mask |= SG_SEIM_CTL_FLAGS;
+ 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 */
}
@@ -1425,10 +1441,11 @@ sg_start_io(Rq_elem * rep, bool is_wr2)
cp = (wr ? " slave active" : " master active");
} else
cp = (wr ? " slave not sharing" : " master not sharing");
+ rep->rq_id = atomic_fetch_add(&mono_pack_id, 1);
if (rep->debug > 3) {
- pr2serr_lk("%s tid=%d: SCSI %s%s%s%s, blk=%" PRId64 " num_blks=%d\n",
- __func__, rep->id, crwp, cp, c2p, c3p, rep->blk,
- rep->num_blks);
+ pr2serr_lk("%s tid,rq_id=%d,%d: SCSI %s%s%s%s, blk=%" PRId64
+ " num_blks=%d\n", __func__, rep->id, rep->rq_id, crwp, cp,
+ c2p, c3p, rep->blk, rep->num_blks);
lk_print_command(rep->cmd);
}
if (v4)
@@ -1445,7 +1462,7 @@ sg_start_io(Rq_elem * rep, bool is_wr2)
hp->sbp = rep->sb;
hp->timeout = DEF_TIMEOUT;
hp->usr_ptr = rep;
- hp->pack_id = (int)rep->blk;
+ hp->pack_id = rep->rq_id;
hp->flags = flags;
while (((res = write(fd, hp, sizeof(struct sg_io_hdr))) < 0) &&
@@ -1476,7 +1493,7 @@ do_v4:
h4p->response = (uint64_t)rep->sb;
h4p->timeout = DEF_TIMEOUT;
h4p->usr_ptr = (uint64_t)rep;
- h4p->request_extra = rep->blk;/* N.B. blk --> pack_id --> request_extra */
+ h4p->request_extra = rep->rq_id; /* this is the pack_id */
h4p->flags = flags;
while (((res = ioctl(fd, SG_IOSUBMIT, h4p)) < 0) &&
((EINTR == errno) || (EAGAIN == errno)))
@@ -1489,6 +1506,28 @@ do_v4:
rep->id, cp, c2p, c3p, strerror(err));
return -1;
}
+ if ((rep->aen > 0) && (rep->rep_count > 0)) {
+ if (0 == (rep->rq_id % rep->aen)) {
+ struct pollfd a_poll;
+
+ a_poll.fd = fd;
+ a_poll.events = POLL_IN;
+ a_poll.revents = 0;
+ res = poll(&a_poll, 1 /* element */, 1 /* millisecond */);
+ if (res < 0)
+ pr2serr_lk("%s: poll() failed: %s [%d]\n",
+ __func__, safe_strerror(errno), errno);
+ else if (0 == res) { /* timeout, cmd still inflight, so abort */
+ res = ioctl(fd, SG_IOABORT, h4p);
+ if (res < 0)
+ pr2serr_lk("%s: ioctl(SG_IOABORT) failed: %s [%d]\n",
+ __func__, safe_strerror(errno), errno);
+ else if (rep->debug > 3)
+ pr2serr_lk("%s: sending ioctl(SG_IOABORT) on rq_id=%d\n",
+ __func__, rep->rq_id);
+ } /* else got response, too late for timeout, so skip */
+ }
+ }
return 0;
}
@@ -1521,7 +1560,7 @@ sg_finish_io(bool wr, Rq_elem * rep, bool is_wr2)
/* FORCE_PACK_ID active set only read packet with matching pack_id */
io_hdr.interface_id = 'S';
io_hdr.dxfer_direction = wr ? SG_DXFER_TO_DEV : SG_DXFER_FROM_DEV;
- io_hdr.pack_id = (int)rep->blk;
+ io_hdr.pack_id = rep->rq_id;
while (((res = read(fd, &io_hdr, sizeof(struct sg_io_hdr))) < 0) &&
((EINTR == errno) || (EAGAIN == errno)))
@@ -1601,8 +1640,17 @@ do_v4:
{
char ebuff[EBUFF_SZ];
- snprintf(ebuff, EBUFF_SZ, "%s blk=%" PRId64, cp, rep->blk);
+ snprintf(ebuff, EBUFF_SZ, "%s rq_id=%d, blk=%" PRId64, cp,
+ rep->rq_id, rep->blk);
lk_chk_n_print4(ebuff, h4p, false);
+ if ((rep->debug > 4) && h4p->info)
+ pr2serr_lk(" info=0x%x sg_info_check=%d another_waiting=%d "
+ "direct=%d detaching=%d aborted=%d\n", h4p->info,
+ !!(h4p->info & SG_INFO_CHECK),
+ !!(h4p->info & SG_INFO_ANOTHER_WAITING),
+ !!(h4p->info & SG_INFO_DIRECT_IO),
+ !!(h4p->info & SG_INFO_DEVICE_DETACHING),
+ !!(h4p->info & SG_INFO_ABORTED));
return res;
}
}
@@ -1616,14 +1664,16 @@ do_v4:
rep->dio_incomplete_count = 0;
rep->resid = h4p->din_resid;
if (rep->debug > 3) {
- pr2serr_lk("%s: tid=%d: completed %s\n", __func__, rep->id, cp);
- if (rep->debug > 4)
+ pr2serr_lk("%s: tid,rq_id=%d,%d: completed %s\n", __func__, rep->id,
+ rep->rq_id, cp);
+ if ((rep->debug > 4) && h4p->info)
pr2serr_lk(" info=0x%x sg_info_check=%d another_waiting=%d "
- "direct=%d detaching=%d\n", h4p->info,
+ "direct=%d detaching=%d aborted=%d\n", h4p->info,
!!(h4p->info & SG_INFO_CHECK),
!!(h4p->info & SG_INFO_ANOTHER_WAITING),
!!(h4p->info & SG_INFO_DIRECT_IO),
- !!(h4p->info & SG_INFO_DEVICE_DETACHING));
+ !!(h4p->info & SG_INFO_DEVICE_DETACHING),
+ !!(h4p->info & SG_INFO_ABORTED));
}
return 0;
}
@@ -1647,14 +1697,14 @@ sg_prepare_resbuf(int fd, int bs, int bpt, bool def_res, int elem_sz,
seip = &sei;
memset(seip, 0, sizeof(*seip));
- seip->valid_rd_mask |= SG_SEIM_SGAT_ELEM_SZ;
+ seip->sei_rd_mask |= SG_SEIM_SGAT_ELEM_SZ;
res = ioctl(fd, SG_SET_GET_EXTENDED, seip);
if (res < 0)
pr2serr_lk("sgh_dd: %s: SG_SET_GET_EXTENDED(SGAT_ELEM_SZ) rd "
"error: %s\n", __func__, strerror(errno));
if (elem_sz != (int)seip->sgat_elem_sz) {
memset(seip, 0, sizeof(*seip));
- seip->valid_wr_mask |= SG_SEIM_SGAT_ELEM_SZ;
+ seip->sei_wr_mask |= SG_SEIM_SGAT_ELEM_SZ;
seip->sgat_elem_sz = elem_sz;
res = ioctl(fd, SG_SET_GET_EXTENDED, seip);
if (res < 0)
@@ -1882,27 +1932,34 @@ main(int argc, char * argv[])
if (*buf)
*buf++ = '\0';
keylen = strlen(key);
- if (0 == strcmp(key,"bpt")) {
+ if (0 == strcmp(key, "ae")) {
+ clp->aen = sg_get_num(buf);
+ if (clp->aen < 0) {
+ pr2serr("%sbad argument to 'ae=', want 0 or higher\n",
+ my_name);
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ } else if (0 == strcmp(key, "bpt")) {
clp->bpt = sg_get_num(buf);
if (-1 == clp->bpt) {
pr2serr("%sbad argument to 'bpt='\n", my_name);
return SG_LIB_SYNTAX_ERROR;
}
bpt_given = true;
- } else if (0 == strcmp(key,"bs")) {
+ } else if (0 == strcmp(key, "bs")) {
clp->bs = sg_get_num(buf);
if (-1 == clp->bs) {
pr2serr("%sbad argument to 'bs='\n", my_name);
return SG_LIB_SYNTAX_ERROR;
}
- } else if (0 == strcmp(key,"cdbsz")) {
+ } else if (0 == strcmp(key, "cdbsz")) {
clp->cdbsz_in = sg_get_num(buf);
clp->cdbsz_out = clp->cdbsz_in;
cdbsz_given = true;
- } else if (0 == strcmp(key,"coe")) {
+ } 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")) {
+ } else if (0 == strcmp(key, "count")) {
if (0 != strcmp("-1", buf)) {
dd_count = sg_get_llnum(buf);
if (-1LL == dd_count) {
@@ -1910,32 +1967,32 @@ main(int argc, char * argv[])
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)))
+ } 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")) {
+ } else if (0 == strcmp(key, "elemsz_kb")) {
clp->elem_sz = sg_get_num(buf) * 1024;
if ((clp->elem_sz > 0) && (clp->elem_sz < 4096)) {
pr2serr("elemsz_kb cannot be less than 4 (4 KB = 4096 "
"bytes)\n");
return SG_LIB_SYNTAX_ERROR;
}
- } else if (0 == strcmp(key,"fua")) {
+ } else if (0 == strcmp(key, "fua")) {
n = sg_get_num(buf);
if (n & 1)
clp->out_flags.fua = true;
if (n & 2)
clp->in_flags.fua = true;
- } else if (0 == strcmp(key,"ibs")) {
+ } else if (0 == strcmp(key, "ibs")) {
ibs = sg_get_num(buf);
if (-1 == ibs) {
pr2serr("%sbad argument to 'ibs='\n", my_name);
return SG_LIB_SYNTAX_ERROR;
}
- } else if (strcmp(key,"if") == 0) {
+ } else if (0 == strcmp(key, "if")) {
if ('\0' != inf[0]) {
pr2serr("Second 'if=' argument??\n");
return SG_LIB_SYNTAX_ERROR;
@@ -1946,25 +2003,25 @@ main(int argc, char * argv[])
pr2serr("%sbad argument to 'iflag='\n", my_name);
return SG_LIB_SYNTAX_ERROR;
}
- } else if (0 == strcmp(key,"obs")) {
+ } else if (0 == strcmp(key, "obs")) {
obs = sg_get_num(buf);
if (-1 == obs) {
pr2serr("%sbad argument to 'obs='\n", my_name);
return SG_LIB_SYNTAX_ERROR;
}
- } else if (strcmp(key,"of2") == 0) {
+ } else if (strcmp(key, "of2") == 0) {
if ('\0' != out2f[0]) {
pr2serr("Second OFILE2 argument??\n");
return SG_LIB_CONTRADICT;
} else
strncpy(out2f, buf, INOUTF_SZ - 1);
- } else if (strcmp(key,"ofreg") == 0) {
+ } else if (strcmp(key, "ofreg") == 0) {
if ('\0' != outregf[0]) {
pr2serr("Second OFREG argument??\n");
return SG_LIB_CONTRADICT;
} else
strncpy(outregf, buf, INOUTF_SZ - 1);
- } else if (strcmp(key,"of") == 0) {
+ } else if (strcmp(key, "of") == 0) {
if ('\0' != outf[0]) {
pr2serr("Second 'of=' argument??\n");
return SG_LIB_SYNTAX_ERROR;
@@ -1975,23 +2032,23 @@ main(int argc, char * argv[])
pr2serr("%sbad argument to 'oflag='\n", my_name);
return SG_LIB_SYNTAX_ERROR;
}
- } else if (0 == strcmp(key,"seek")) {
+ } else if (0 == strcmp(key, "seek")) {
seek = sg_get_llnum(buf);
if (-1LL == seek) {
pr2serr("%sbad argument to 'seek='\n", my_name);
return SG_LIB_SYNTAX_ERROR;
}
- } else if (0 == strcmp(key,"skip")) {
+ } else if (0 == strcmp(key, "skip")) {
skip = sg_get_llnum(buf);
if (-1LL == skip) {
pr2serr("%sbad argument to 'skip='\n", my_name);
return SG_LIB_SYNTAX_ERROR;
}
- } else if (0 == strcmp(key,"sync"))
+ } else if (0 == strcmp(key, "sync"))
do_sync = !! sg_get_num(buf);
- else if (0 == strcmp(key,"thr"))
+ else if (0 == strcmp(key, "thr"))
num_threads = sg_get_num(buf);
- else if (0 == strcmp(key,"time"))
+ else if (0 == strcmp(key, "time"))
do_time = !! sg_get_num(buf);
else if ((keylen > 1) && ('-' == key[0]) && ('-' != key[1])) {
res = 0;
@@ -2342,7 +2399,8 @@ main(int argc, char * argv[])
clp->outregfd = -1;
if ((STDIN_FILENO == clp->infd) && (STDOUT_FILENO == clp->outfd)) {
- pr2serr("Won't default both IFILE to stdin _and_ OFILE to stdout\n");
+ pr2serr("Won't default both IFILE to stdin _and_ OFILE to "
+ "/dev/null\n");
pr2serr("For more information use '--help'\n");
return SG_LIB_SYNTAX_ERROR;
}
@@ -2560,13 +2618,16 @@ main(int argc, char * argv[])
fini:
- if (STDIN_FILENO != clp->infd)
+ if ((STDIN_FILENO != clp->infd) && (clp->infd >= 0))
close(clp->infd);
- if ((STDOUT_FILENO != clp->outfd) && (FT_DEV_NULL != clp->out_type))
+ if ((STDOUT_FILENO != clp->outfd) && (FT_DEV_NULL != clp->out_type) &&
+ (clp->outfd >= 0))
close(clp->outfd);
- if ((STDOUT_FILENO != clp->out2fd) && (FT_DEV_NULL != clp->out2_type))
+ if ((clp->out2fd >= 0) && (STDOUT_FILENO != clp->out2fd) &&
+ (FT_DEV_NULL != clp->out2_type))
close(clp->out2fd);
- if ((STDOUT_FILENO != clp->outregfd) && (FT_DEV_NULL != clp->outreg_type))
+ if ((clp->outregfd >= 0) && (STDOUT_FILENO != clp->outregfd) &&
+ (FT_DEV_NULL != clp->outreg_type))
close(clp->outregfd);
res = exit_status;
if ((0 != clp->out_count) && (0 == clp->dry_run)) {
diff --git a/testing/uapi_sg.h b/testing/uapi_sg.h
index d6f366af..cfb0044b 100644
--- a/testing/uapi_sg.h
+++ b/testing/uapi_sg.h
@@ -14,8 +14,8 @@
* Later extensions (versions 2, 3 and 4) to driver:
* Copyright (C) 1998 - 2018 Douglas Gilbert
*
- * Version 4.0.03 (20181227)
- * This version is for Linux 2.6, 3 and 4 series kernels.
+ * Version 4.0.05 (20190126)
+ * This version is for Linux 2.6, 3, 4 and 5 series kernels.
*
* Documentation
* =============
@@ -128,6 +128,7 @@ typedef struct sg_io_hdr {
#define SG_INFO_MIXED_IO 0x4 /* not used, always 0 */
#define SG_INFO_DEVICE_DETACHING 0x8 /* completed successfully but ... */
#define SG_INFO_ANOTHER_WAITING 0x10 /* needs SG_CTL_FLAGM_CHECK_FOR_MORE */
+#define SG_INFO_ABORTED 0x20 /* this command has been aborted */
typedef struct sg_scsi_id { /* used by SG_GET_SCSI_ID ioctl() */
@@ -164,25 +165,24 @@ typedef struct sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */
/*
* The following defines are for manipulating struct sg_extended_info which
* is abbreviated to "SEI". A following "M" (i.e. "_SEIM_") indicates a
- * mask. Most mask values correspond to a integer (usually a __u32) apart
+ * mask. Most mask values correspond to a integer (usually a uint32_t) apart
* from SG_SEIM_CTL_FLAGS which is for boolean values packed into an integer.
* The mask values for those booleans start with "SG_CTL_FLAGM_". The scope
* of these settings, like most other ioctls, is usually that of the file
* descriptor the ioctl is executed on. The "rd:" indication means read-only,
* attempts to write to them are ignored. "rd>" means action when reading.
*/
-#define SG_SEIM_RESERVED_SIZE 0x1 /* reserved_sz field valid */
-#define SG_SEIM_RQ_REM_THRESH 0x2 /* rq_rem_sgat_thresh field valid */
-#define SG_SEIM_TOT_FD_THRESH 0x4 /* tot_fd_thresh field valid */
-#define SG_SEIM_CTL_FLAGS 0x8 /* ctl_flags_mask bits in ctl_flags */
+#define SG_SEIM_CTL_FLAGS 0x1 /* ctl_flags_mask bits in ctl_flags */
+#define SG_SEIM_READ_VAL 0x2 /* write SG_SEIRV_*, read back value */
+#define SG_SEIM_RESERVED_SIZE 0x4 /* reserved_sz of reserve request */
+#define SG_SEIM_TOT_FD_THRESH 0x8 /* tot_fd_thresh of data buffers */
#define SG_SEIM_MINOR_INDEX 0x10 /* sg device minor index number */
-#define SG_SEIM_READ_VAL 0x20 /* write SG_SEIRV_*, read back value */
-#define SG_SEIM_SHARE_FD 0x40 /* slave gives fd of master, sharing */
+#define SG_SEIM_SHARE_FD 0x20 /* slave gives fd of master: sharing */
+#define SG_SEIM_CHG_SHARE_FD 0x40 /* master gives fd of new slave */
#define SG_SEIM_SGAT_ELEM_SZ 0x80 /* sgat element size (>= PAGE_SIZE) */
-#define SG_SEIM_CHG_SHARE_FD 0x100 /* master gives fd of new slave */
-#define SG_SEIM_ALL_BITS 0x1ff /* should be OR of previous items */
+#define SG_SEIM_ALL_BITS 0xff /* should be OR of previous items */
-/* flag and mask values for boolena fields follow */
+/* flag and mask values for boolean fields follow */
#define SG_CTL_FLAGM_TIME_IN_NS 0x1 /* time: nanosecs (def: millisecs) */
#define SG_CTL_FLAGM_TAG_FOR_PACK_ID 0x2 /* prefer tag over pack_id (def) */
#define SG_CTL_FLAGM_OTHER_OPENS 0x4 /* rd: other sg fd_s on this dev */
@@ -218,19 +218,21 @@ typedef struct sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */
* setting but no other operation will split the two. This structure is
* padded to 96 bytes to allow for new values to be added in the future.
*/
+
+/* If both sei_wr_mask and sei_rd_mask are 0, this ioctl does nothing */
struct sg_extended_info {
- __u32 valid_wr_mask; /* OR-ed SG_SEIM_* user->driver values */
- __u32 valid_rd_mask; /* OR-ed SG_SEIM_* driver->user values */
- __u32 reserved_sz; /* data/sgl size of pre-allocated request */
- __u32 rq_rem_sgat_thresh;/* request re-use: clear data/sgat if > */
- __u32 tot_fd_thresh; /* total data/sgat for this fd, 0: no limit */
+ __u32 sei_wr_mask; /* OR-ed SG_SEIM_* user->driver values */
+ __u32 sei_rd_mask; /* OR-ed SG_SEIM_* driver->user values */
__u32 ctl_flags_wr_mask; /* OR-ed SG_CTL_FLAGM_* values */
__u32 ctl_flags_rd_mask; /* OR-ed SG_CTL_FLAGM_* values */
__u32 ctl_flags; /* bit values OR-ed, see SG_CTL_FLAGM_* */
+ __u32 read_value; /* write SG_SEIRV_*, read back related */
+
+ __u32 reserved_sz; /* data/sgl size of pre-allocated request */
+ __u32 tot_fd_thresh; /* total data/sgat for this fd, 0: no limit */
__u32 minor_index; /* rd: kernel's sg device minor number */
- __u32 read_value; /* write known value, read back related */
- __u32 share_fd; /* slave provided fd of master */
- __u32 sgat_elem_sz; /* sgat element size (must be power of 2 */
+ __u32 share_fd; /* SHARE_FD and CHG_SHARE_FD use this */
+ __u32 sgat_elem_sz; /* sgat element size (must be power of 2) */
__u8 pad_to_96[52]; /* pad so struct is 96 bytes long */
};
@@ -283,10 +285,10 @@ struct sg_extended_info {
* file descriptor (default: use pack_id). If pack_id or tag is -1 then read
* oldest waiting and this is the same action as when FORCE_PACK_ID is
* clear on the parent file descriptor. In the v4 interface the pack_id is
- * placed in sg_io_v4::request_extra field .
+ * placed the in sg_io_v4::request_extra field .
*/
#define SG_SET_FORCE_PACK_ID 0x227b /* pack_id or in v4 can be tag */
-#define SG_GET_PACK_ID 0x227c /* Yields oldest readable pack_id (or -1) */
+#define SG_GET_PACK_ID 0x227c /* Yields oldest readable pack_id/tag, or -1 */
#define SG_GET_NUM_WAITING 0x227d /* Number of commands awaiting read() */