aboutsummaryrefslogtreecommitdiff
path: root/testing
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2019-04-14 23:06:18 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2019-04-14 23:06:18 +0000
commitf55a523cb14c613b30b6d63fe78c892e8a414e3a (patch)
treed5a6a5f344ec7872137356aac114d2279185218b /testing
parentcc730c8de77b8f35d924cb4a01437f7166d85e12 (diff)
downloadsg3_utils-f55a523cb14c613b30b6d63fe78c892e8a414e3a.tar.gz
testing folder utilities for sg v4 driver
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@818 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'testing')
-rw-r--r--testing/sg_tst_async.cpp15
-rw-r--r--testing/sgh_dd.cpp98
-rw-r--r--testing/sgs_dd.c24
3 files changed, 84 insertions, 53 deletions
diff --git a/testing/sg_tst_async.cpp b/testing/sg_tst_async.cpp
index bdd024fb..e33d8ec0 100644
--- a/testing/sg_tst_async.cpp
+++ b/testing/sg_tst_async.cpp
@@ -89,7 +89,7 @@
#include "sg_pt.h"
#include "sg_cmds.h"
-static const char * version_str = "1.26 20190409";
+static const char * version_str = "1.28 20190414";
static const char * util_name = "sg_tst_async";
/* This is a test program for checking the async usage of the Linux sg
@@ -372,7 +372,8 @@ usage(void)
"Each thread queues up to NT commands.\nOne block is transferred "
"by each READ and WRITE; zeros are written. If a\nlogical block "
"range is given, a uniform distribution generates a pseudo\n"
- "random sequence of LBAs.\n");
+ "random sequence of LBAs. Set environment variable\n"
+ "SG3_UTILS_LINUX_NANO to get command timings in nanoseconds\n");
}
#ifdef __GNUC__
@@ -1001,7 +1002,9 @@ work_thread(int id, struct opts_t * op)
memset(seip, 0, sizeof(*seip));
seip->sei_wr_mask |= SG_SEIM_CTL_FLAGS;
seip->sei_rd_mask |= SG_SEIM_CTL_FLAGS;
+ 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 |= 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",
errno, strerror(errno));
@@ -1916,10 +1919,10 @@ main(int argc, char * argv[])
op->maxq_per_thread = 1;
}
if (! op->cmd_time && getenv("SG3_UTILS_LINUX_NANO")) {
- op->cmd_time = true;
- if (op->verbose)
- fprintf(stderr, "setting nanosecond timing due to environment "
- "variable: SG3_UTILS_LINUX_NANO\n");
+ op->cmd_time = true;
+ if (op->verbose)
+ fprintf(stderr, "setting nanosecond timing due to environment "
+ "variable: SG3_UTILS_LINUX_NANO\n");
}
if (0 == op->dev_names.size()) {
fprintf(stderr, "No sg_disk_device-s given\n\n");
diff --git a/testing/sgh_dd.cpp b/testing/sgh_dd.cpp
index b7608cfb..c982c868 100644
--- a/testing/sgh_dd.cpp
+++ b/testing/sgh_dd.cpp
@@ -103,7 +103,7 @@
using namespace std;
-static const char * version_str = "1.22 20190331";
+static const char * version_str = "1.25 20190413";
#ifdef __GNUC__
#ifndef __clang__
@@ -213,6 +213,7 @@ typedef struct global_collection
int dry_run;
bool ofile_given;
bool ofile2_given;
+ bool unit_nanosec; /* default duration unit is millisecond */
const char * infp;
const char * outfp;
const char * out2fp;
@@ -278,8 +279,9 @@ static void sg_out_wr_cmd(Gbl_coll * clp, Rq_elem * rep, mrq_arr_t & def_arr,
bool is_wr2);
static bool normal_in_rd(Gbl_coll * clp, Rq_elem * rep, int blocks);
static void normal_out_wr(Gbl_coll * clp, Rq_elem * rep, int blocks);
-static int sg_start_io(Rq_elem * rep, mrq_arr_t & def_arr, bool is_wr2);
-static int sg_finish_io(bool wr, Rq_elem * rep, bool is_wr2);
+static int sg_start_io(Rq_elem * rep, mrq_arr_t & def_arr, int & pack_id,
+ bool is_wr2);
+static int sg_finish_io(bool wr, Rq_elem * rep, int pack_id, bool is_wr2);
static int sg_in_open(Gbl_coll *clp, const char *inf, uint8_t **mmpp,
int *mmap_len);
static int sg_out_open(Gbl_coll *clp, const char *outf, uint8_t **mmpp,
@@ -669,7 +671,7 @@ page2:
" sync 0->no sync(def), 1->SYNCHRONIZE CACHE on OFILE "
"after copy\n"
" thr is number of threads, must be > 0, default 4, "
- "max 16\n"
+ "max 1024\n"
" time 0->no timing, 1->time plus calculate "
"throughput (def)\n"
" verbose same as 'deb=VERB': increase verbosity\n"
@@ -899,7 +901,7 @@ read_write_thread(void * v_tip)
memset(rep, 0, sizeof(Rq_elem));
/* Following clp members are constant during lifetime of thread */
rep->id = tip->id;
- if (vb > 0)
+ if (vb > 2)
pr2serr_lk("%d <-- Starting worker thread\n", rep->id);
if (! clp->in_flags.mmap) {
rep->buffp = sg_memalign(sz, 0 /* page align */, &rep->alloc_bp,
@@ -990,7 +992,7 @@ read_write_thread(void * v_tip)
rep->out2fd);
}
if (rep->in_flags.noshare || rep->out_flags.noshare) {
- if (vb)
+ if (vb > 4)
pr2serr_lk("thread=%d: Skipping share on both IFILE and OFILE\n",
rep->id);
} else if ((FT_SG == clp->in_type) && (FT_SG == clp->out_type))
@@ -1345,11 +1347,10 @@ sg_build_scsi_cdb(uint8_t * cdbp, int cdb_sz, unsigned int blocks,
static void
sg_in_rd_cmd(Gbl_coll * clp, Rq_elem * rep, mrq_arr_t & def_arr)
{
- int res;
- int status;
+ int res, status, pack_id;
while (1) {
- res = sg_start_io(rep, def_arr, false);
+ res = sg_start_io(rep, def_arr, pack_id, false);
if (1 == res)
err_exit(ENOMEM, "sg starting in command");
else if (res < 0) {
@@ -1364,7 +1365,7 @@ sg_in_rd_cmd(Gbl_coll * clp, Rq_elem * rep, mrq_arr_t & def_arr)
status = pthread_mutex_unlock(&clp->in_mutex);
if (0 != status) err_exit(status, "unlock in_mutex");
- res = sg_finish_io(rep->wr, rep, false);
+ res = sg_finish_io(rep->wr, rep, pack_id, false);
switch (res) {
case SG_LIB_CAT_ABORTED_COMMAND:
case SG_LIB_CAT_UNIT_ATTENTION:
@@ -1465,15 +1466,14 @@ sg_wr_swap_share(Rq_elem * rep, int to_fd, bool before)
static void
sg_out_wr_cmd(Gbl_coll * clp, Rq_elem * rep, mrq_arr_t & def_arr, bool is_wr2)
{
- int res;
- int status;
+ int res, status, pack_id;
pthread_mutex_t * mutexp = is_wr2 ? &clp->out2_mutex : &clp->out_mutex;
if (rep->has_share && is_wr2)
sg_wr_swap_share(rep, rep->out2fd, true);
while (1) {
- res = sg_start_io(rep, def_arr, is_wr2);
+ res = sg_start_io(rep, def_arr, pack_id, is_wr2);
if (1 == res)
err_exit(ENOMEM, "sg starting out command");
else if (res < 0) {
@@ -1488,7 +1488,7 @@ sg_out_wr_cmd(Gbl_coll * clp, Rq_elem * rep, mrq_arr_t & def_arr, bool is_wr2)
status = pthread_mutex_unlock(mutexp);
if (0 != status) err_exit(status, "unlock out_mutex");
- res = sg_finish_io(rep->wr, rep, is_wr2);
+ res = sg_finish_io(rep->wr, rep, pack_id, is_wr2);
switch (res) {
case SG_LIB_CAT_ABORTED_COMMAND:
case SG_LIB_CAT_UNIT_ATTENTION:
@@ -1611,7 +1611,8 @@ sgh_do_def(Rq_elem * rep, mrq_arr_t & def_arr)
/* Returns 0 on success, 1 if ENOMEM error else -1 for other errors. */
static int
-sg_start_io(Rq_elem * rep, mrq_arr_t & def_arr, bool is_wr2)
+sg_start_io(Rq_elem * rep, mrq_arr_t & def_arr, int & pack_id,
+ bool is_wr2)
{
bool wr = rep->wr;
bool fua = wr ? rep->out_flags.fua : rep->in_flags.fua;
@@ -1664,10 +1665,11 @@ sg_start_io(Rq_elem * rep, mrq_arr_t & def_arr, 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); /* fetch before */
+ pack_id = atomic_fetch_add(&mono_pack_id, 1); /* fetch before */
+ rep->rq_id = pack_id;
if (rep->debug > 3) {
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,
+ " num_blks=%d\n", __func__, rep->id, pack_id, crwp, cp,
c2p, c3p, blk, rep->num_blks);
lk_print_command(rep->cmd);
}
@@ -1685,7 +1687,7 @@ sg_start_io(Rq_elem * rep, mrq_arr_t & def_arr, bool is_wr2)
hp->sbp = rep->sb;
hp->timeout = DEF_TIMEOUT;
hp->usr_ptr = rep;
- hp->pack_id = rep->rq_id;
+ hp->pack_id = pack_id;
hp->flags = flags;
while (((res = write(fd, hp, sizeof(struct sg_io_hdr))) < 0) &&
@@ -1716,8 +1718,8 @@ do_v4:
h4p->response = (uint64_t)rep->sb;
h4p->timeout = DEF_TIMEOUT;
h4p->usr_ptr = (uint64_t)rep;
- h4p->request_extra = rep->rq_id; /* this is the pack_id */
- h4p->flags = flags;
+ h4p->request_extra = pack_id; /* this is the pack_id */
+ h4p->flags = flags | SGV4_FLAG_IMMED;
if (rep->nmrqs > 0) {
if (rep->both_sg && (rep->outfd == fd))
h4p->flags |= SGV4_FLAG_DO_ON_OTHER;
@@ -1760,7 +1762,7 @@ do_v4:
__func__, safe_strerror(errno), errno);
else if (rep->debug > 1)
pr2serr_lk("%s: sending ioctl(SG_IOABORT) on rq_id=%d\n",
- __func__, rep->rq_id);
+ __func__, pack_id);
} /* else got response, too late for timeout, so skip */
}
}
@@ -1771,7 +1773,7 @@ do_v4:
-> try again, SG_LIB_CAT_NOT_READY, SG_LIB_CAT_MEDIUM_HARD,
-1 other errors */
static int
-sg_finish_io(bool wr, Rq_elem * rep, bool is_wr2)
+sg_finish_io(bool wr, Rq_elem * rep, int pack_id, bool is_wr2)
{
bool v4 = wr ? rep->out_flags.v4 : rep->in_flags.v4;
int res, fd;
@@ -1797,7 +1799,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 = rep->rq_id;
+ io_hdr.pack_id = pack_id;
while (((res = read(fd, &io_hdr, sizeof(struct sg_io_hdr))) < 0) &&
((EINTR == errno) || (EAGAIN == errno)))
@@ -1852,6 +1854,7 @@ do_v4:
return 0;
}
h4p = &rep->io_hdr4;
+ h4p->request_extra = pack_id;
while (((res = ioctl(fd, SG_IORECEIVE, h4p)) < 0) &&
((EINTR == errno) || (EAGAIN == errno)))
sched_yield(); /* another thread may be able to progress */
@@ -1882,7 +1885,7 @@ do_v4:
char ebuff[EBUFF_SZ];
snprintf(ebuff, EBUFF_SZ, "%s rq_id=%d, blk=%" PRId64, cp,
- rep->rq_id, blk);
+ pack_id, blk);
lk_chk_n_print4(ebuff, h4p, false);
if ((rep->debug > 4) && h4p->info)
pr2serr_lk(" info=0x%x sg_info_check=%d direct=%d "
@@ -1905,7 +1908,7 @@ do_v4:
rep->resid = h4p->din_resid;
if (rep->debug > 3) {
pr2serr_lk("%s: tid,rq_id=%d,%d: completed %s\n", __func__, rep->id,
- rep->rq_id, cp);
+ pack_id, cp);
if ((rep->debug > 4) && h4p->info)
pr2serr_lk(" info=0x%x sg_info_check=%d direct=%d "
"detaching=%d aborted=%d\n", h4p->info,
@@ -1926,8 +1929,7 @@ sg_in_out_interleave(Gbl_coll *clp, Rq_elem * rep, mrq_arr_t & def_arr)
while (1) {
/* start READ */
- res = sg_start_io(rep, def_arr, false);
- pid_read = rep->rq_id;
+ res = sg_start_io(rep, def_arr, pid_read, false);
if (1 == res)
err_exit(ENOMEM, "sg interleave starting in command");
else if (res < 0) {
@@ -1941,8 +1943,7 @@ sg_in_out_interleave(Gbl_coll *clp, Rq_elem * rep, mrq_arr_t & def_arr)
/* start WRITE */
rep->wr = true;
- res = sg_start_io(rep, def_arr, false);
- pid_write = rep->rq_id;
+ res = sg_start_io(rep, def_arr, pid_write, false);
if (1 == res)
err_exit(ENOMEM, "sg interleave starting out command");
else if (res < 0) {
@@ -1964,9 +1965,8 @@ read_complet:
#endif
/* finish READ */
- rep->rq_id = pid_read;
rep->wr = false;
- res = sg_finish_io(rep->wr, rep, false);
+ res = sg_finish_io(rep->wr, rep, pid_read, false);
switch (res) {
case SG_LIB_CAT_ABORTED_COMMAND:
case SG_LIB_CAT_UNIT_ATTENTION:
@@ -2025,9 +2025,8 @@ read_complet:
write_complet:
#endif
/* finish WRITE, no lock held */
- rep->rq_id = pid_write;
rep->wr = true;
- res = sg_finish_io(rep->wr, rep, false);
+ res = sg_finish_io(rep->wr, rep, pid_write, false);
switch (res) {
case SG_LIB_CAT_ABORTED_COMMAND:
case SG_LIB_CAT_UNIT_ATTENTION:
@@ -2081,21 +2080,20 @@ write_complet:
/* Returns reserved_buffer_size/mmap_size if success, else 0 for failure */
static int
sg_prepare_resbuf(int fd, int bs, int bpt, bool def_res, int elem_sz,
- uint8_t **mmpp)
+ bool unit_nano, uint8_t **mmpp)
{
int res, t, num;
uint8_t *mmp;
+ struct sg_extended_info sei;
+ struct sg_extended_info * seip;
+ seip = &sei;
res = ioctl(fd, SG_GET_VERSION_NUM, &t);
if ((res < 0) || (t < 40000)) {
pr2serr_lk("%ssg driver prior to 4.0.00\n", my_name);
return 0;
}
if (elem_sz >= 4096) {
- struct sg_extended_info sei;
- struct sg_extended_info * seip;
-
- seip = &sei;
memset(seip, 0, sizeof(*seip));
seip->sei_rd_mask |= SG_SEIM_SGAT_ELEM_SZ;
res = ioctl(fd, SG_SET_GET_EXTENDED, seip);
@@ -2131,6 +2129,17 @@ sg_prepare_resbuf(int fd, int bs, int bpt, bool def_res, int elem_sz,
res = ioctl(fd, SG_SET_FORCE_PACK_ID, &t);
if (res < 0)
perror("sgh_dd: SG_SET_FORCE_PACK_ID error");
+ if (unit_nano) {
+ memset(seip, 0, sizeof(*seip));
+ 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(fd, SG_SET_GET_EXTENDED, seip) < 0) {
+ res = -1;
+ pr2serr_lk("ioctl(EXTENDED(TIME_IN_NS)) failed, errno=%d %s\n",
+ errno, strerror(errno));
+ }
+ }
return (res < 0) ? 0 : num;
}
@@ -2232,7 +2241,7 @@ sg_in_open(Gbl_coll *clp, const char *inf, uint8_t **mmpp, int * mmap_lenp)
return -sg_convert_errno(err);
}
n = sg_prepare_resbuf(fd, clp->bs, clp->bpt, clp->in_flags.defres,
- clp->elem_sz, mmpp);
+ clp->elem_sz, clp->unit_nanosec, mmpp);
if (n <= 0)
return -SG_LIB_FILE_ERROR;
if (mmap_lenp)
@@ -2262,7 +2271,7 @@ sg_out_open(Gbl_coll *clp, const char *outf, uint8_t **mmpp, int * mmap_lenp)
return -sg_convert_errno(err);
}
n = sg_prepare_resbuf(fd, clp->bs, clp->bpt, clp->out_flags.defres,
- clp->elem_sz, mmpp);
+ clp->elem_sz, clp->unit_nanosec, mmpp);
if (n <= 0)
return -SG_LIB_FILE_ERROR;
if (mmap_lenp)
@@ -2582,8 +2591,11 @@ main(int argc, char * argv[])
usage(1);
return SG_LIB_SYNTAX_ERROR;
}
- if (clp->in_flags.swait && (! clp->out_flags.swait))
- pr2serr("iflag=swait is ignored, it should be oflag=swait\n");
+ if (clp->in_flags.swait && (! clp->out_flags.swait)) {
+ pr2serr("iflag=swait is treated as oflag=swait\n");
+ clp->out_flags.swait = true;
+ }
+ clp->unit_nanosec = !!getenv("SG3_UTILS_LINUX_NANO");
if (clp->debug)
pr2serr("%sif=%s skip=%" PRId64 " of=%s seek=%" PRId64 " count=%"
PRId64 "\n", my_name, inf, skip, outf, seek, dd_count);
@@ -2995,7 +3007,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 > 0)
+ if (clp->debug > 2)
pr2serr_lk("%d <-- Worker thread terminated, vp=%s\n", k,
((vp == clp) ? "clp" : "NULL (or !clp)"));
}
diff --git a/testing/sgs_dd.c b/testing/sgs_dd.c
index 624c41b3..d4dabcab 100644
--- a/testing/sgs_dd.c
+++ b/testing/sgs_dd.c
@@ -78,7 +78,7 @@
#include "sg_unaligned.h"
-static const char * version_str = "4.04 20190324";
+static const char * version_str = "4.05 20190412";
static const char * my_name = "sgs_dd";
#define DEF_BLOCK_SIZE 512
@@ -170,7 +170,8 @@ typedef struct request_collection
Rq_elem elem[SGQ_NUM_ELEMS];
} Rq_coll;
-static bool sgs_old_sg_driver = false;
+static bool sgs_old_sg_driver = false; /* true if VERSION_NUM < 4.00.00 */
+static bool sgs_nanosec_unit = false;
static void
@@ -472,7 +473,10 @@ static int
sz_reserve(int fd, int bs, int bpt, bool rt_sig)
{
int res, t, flags;
+ struct sg_extended_info sei;
+ struct sg_extended_info * seip;
+ seip = &sei;
res = ioctl(fd, SG_GET_VERSION_NUM, &t);
if ((res < 0) || (t < 30000)) {
fprintf(stderr, "sgs_dd: sg driver prior to 3.0.00\n");
@@ -487,6 +491,18 @@ sz_reserve(int fd, int bs, int bpt, bool rt_sig)
res = ioctl(fd, SG_SET_RESERVED_SIZE, &t);
if (res < 0)
perror("sgs_dd: SG_SET_RESERVED_SIZE error");
+
+ if (sgs_nanosec_unit) {
+ memset(seip, 0, sizeof(*seip));
+ 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(fd, SG_SET_GET_EXTENDED, seip) < 0) {
+ pr2serr("ioctl(EXTENDED(TIME_IN_NS)) failed, errno=%d %s\n",
+ errno, strerror(errno));
+ return 1;
+ }
+ }
if (-1 == fcntl(fd, F_SETOWN, getpid())) {
perror("fcntl(F_SETOWN)");
return 1;
@@ -933,6 +949,7 @@ main(int argc, char * argv[])
usage();
return 1;
}
+ sgs_nanosec_unit = !!getenv("SG3_UTILS_LINUX_NANO");
for(k = 1; k < argc; k++) {
if (argv[k]) {
@@ -1045,8 +1062,7 @@ main(int argc, char * argv[])
return 1;
}
}
- }
- else { /* looks like sg device so close then re-open it RW */
+ } else { /* looks like sg device so close then re-open it RW */
close(clp->infd);
open_fl = clp->iflag.excl ? O_EXCL : 0;
open_fl |= (O_RDWR | O_NONBLOCK);