aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--examples/sg_tst_excl.cpp110
-rw-r--r--examples/sg_tst_excl2.cpp43
-rw-r--r--examples/sg_tst_excl3.cpp64
-rw-r--r--src/sg_luns.c11
5 files changed, 152 insertions, 80 deletions
diff --git a/ChangeLog b/ChangeLog
index a6c7d871..36aa84de 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,10 +2,12 @@ Each utility has its own version number, date of last change and
some description at the top of its ".c" file. All utilities in the main
directory have their own "man" pages. There is also a sg3_utils man page.
-Changelog for sg3_utils-1.38 [20131026] [svn: r524]
+Changelog for sg3_utils-1.38 [20131029] [svn: r525]
- sg_inq: add --block=0|1 option to control opens
+ - sg_luns: guard against garbage response
- sg_lib_data: sync asc/ascq codes with T10 dated 20131008
- examples: add sg_tst_excl3 for testing O_EXCL
+ - improve sg_tst_excl and sg_tst_excl2
Changelog for sg3_utils-1.37 [20131014] [svn: r522]
- sg_compare_and_write: fix wrprotect setting
diff --git a/examples/sg_tst_excl.cpp b/examples/sg_tst_excl.cpp
index fbd38550..ebcb5197 100644
--- a/examples/sg_tst_excl.cpp
+++ b/examples/sg_tst_excl.cpp
@@ -46,7 +46,7 @@
#include "sg_lib.h"
#include "sg_io_linux.h"
-static const char * version_str = "1.04 20130829";
+static const char * version_str = "1.05 20131028";
static const char * util_name = "sg_tst_excl";
/* This is a test program for checking O_EXCL on open() works. It uses
@@ -98,7 +98,8 @@ using namespace std::chrono;
static mutex odd_count_mutex;
static mutex console_mutex;
static unsigned int odd_count;
-static unsigned int bounce_count;
+static unsigned int ebusy_count;
+static unsigned int eagain_count;
static void
@@ -128,7 +129,7 @@ usage(void)
printf(" -x don't use O_EXCL on first thread "
"(def: use\n"
" O_EXCL on all threads)\n\n");
- printf("Test O_EXCL open flag with sg driver. Each open/close "
+ printf("Test O_EXCL open flag with Linux sg driver. Each open/close "
"cycle with the\nO_EXCL flag does a double increment on "
"lba (using its first 4 bytes).\n");
}
@@ -141,18 +142,19 @@ usage(void)
/* Opens dev_name and spins if busy (i.e. gets EBUSY), sleeping for
* wait_ms milliseconds if wait_ms is positive.
- * Reads lba and treats the first 4 bytes as an int (SCSI endian),
+ * Reads lba (twice) and treats the first 4 bytes as an int (SCSI endian),
* increments it and writes it back. Repeats so that happens twice. Then
* closes dev_name. If an error occurs returns -1 else returns 0 if
* first int read from lba is even otherwise returns 1. */
static int
do_rd_inc_wr_twice(const char * dev_name, unsigned int lba, int block,
- int excl, int wait_ms, unsigned int & bounces)
+ int excl, int wait_ms, int id, unsigned int & ebusy,
+ unsigned int & eagains)
{
- int k, sg_fd, ok;
+ int k, sg_fd, ok, res;
int odd = 0;
unsigned int u = 0;
- struct sg_io_hdr pt;
+ struct sg_io_hdr pt, pt2;
unsigned char r16CmdBlk [READ16_CMD_LEN] =
{0x88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0};
unsigned char w16CmdBlk [WRITE16_CMD_LEN] =
@@ -173,7 +175,7 @@ do_rd_inc_wr_twice(const char * dev_name, unsigned int lba, int block,
while (((sg_fd = open(dev_name, open_flags)) < 0) &&
(EBUSY == errno)) {
- ++bounces;
+ ++ebusy;
if (wait_ms > 0)
this_thread::sleep_for(milliseconds{wait_ms});
else if (0 == wait_ms)
@@ -200,9 +202,33 @@ do_rd_inc_wr_twice(const char * dev_name, unsigned int lba, int block,
pt.cmdp = r16CmdBlk;
pt.sbp = sense_buffer;
pt.timeout = 20000; /* 20000 millisecs == 20 seconds */
+ pt.pack_id = id;
- if (ioctl(sg_fd, SG_IO, &pt) < 0) {
- perror("do_rd_inc_wr_twice: READ_16 SG_IO ioctl error");
+ // queue up two READ_16s to same LBA
+ if (write(sg_fd, &pt, sizeof(pt)) < 0) {
+ perror("do_rd_inc_wr_twice: write(sg, READ_16)");
+ close(sg_fd);
+ return -1;
+ }
+ pt2 = pt;
+ if (write(sg_fd, &pt2, sizeof(pt2)) < 0) {
+ perror("do_rd_inc_wr_twice: write(sg, READ_16) 2");
+ close(sg_fd);
+ return -1;
+ }
+
+ while (((res = read(sg_fd, &pt, sizeof(pt))) < 0) &&
+ (EAGAIN == errno)) {
+ ++eagains;
+ if (wait_ms > 0)
+ this_thread::sleep_for(milliseconds{wait_ms});
+ else if (0 == wait_ms)
+ this_thread::yield();
+ else if (-2 == wait_ms)
+ sleep(0); // process yield ??
+ }
+ if (res < 0) {
+ perror("do_rd_inc_wr_twice: read(sg, READ_16)");
close(sg_fd);
return -1;
}
@@ -220,6 +246,38 @@ do_rd_inc_wr_twice(const char * dev_name, unsigned int lba, int block,
sg_chk_n_print3("READ_16 command error", &pt, 1);
break;
}
+ if (ok) {
+ while (((res = read(sg_fd, &pt2, sizeof(pt2))) < 0) &&
+ (EAGAIN == errno)) {
+ ++eagains;
+ if (wait_ms > 0)
+ this_thread::sleep_for(milliseconds{wait_ms});
+ else if (0 == wait_ms)
+ this_thread::yield();
+ else if (-2 == wait_ms)
+ sleep(0); // process yield ??
+ }
+ if (res < 0) {
+ perror("do_rd_inc_wr_twice: read(sg, READ_16) 2");
+ close(sg_fd);
+ return -1;
+ }
+ pt = pt2;
+ /* now for the error processing */
+ ok = 0;
+ switch (sg_err_category3(&pt)) {
+ case SG_LIB_CAT_CLEAN:
+ ok = 1;
+ break;
+ case SG_LIB_CAT_RECOVERED:
+ printf("Recovered error on READ_16, continuing 2\n");
+ ok = 1;
+ break;
+ default: /* won't bother decoding other categories */
+ sg_chk_n_print3("READ_16 command error 2", &pt, 1);
+ break;
+ }
+ }
if (! ok) {
close(sg_fd);
return -1;
@@ -252,6 +310,7 @@ do_rd_inc_wr_twice(const char * dev_name, unsigned int lba, int block,
pt.cmdp = w16CmdBlk;
pt.sbp = sense_buffer;
pt.timeout = 20000; /* 20000 millisecs == 20 seconds */
+ pt.pack_id = id;
if (ioctl(sg_fd, SG_IO, &pt) < 0) {
perror("do_rd_inc_wr_twice: WRITE_16 SG_IO ioctl error");
@@ -287,10 +346,11 @@ do_rd_inc_wr_twice(const char * dev_name, unsigned int lba, int block,
#define INQ_CMD_LEN 6
/* Send INQUIRY and fetches response. If okay puts PRODUCT ID field
- * in b (up to m_blen bytes). Returns 0 on success, else -1 . */
+ * in b (up to m_blen bytes). Does not use O_EXCL flag. Returns 0 on success,
+ * else -1 . */
static int
-do_inquiry_prod_id(const char * dev_name, int block, int excl, int wait_ms,
- unsigned int & bounces, char * b, int b_mlen)
+do_inquiry_prod_id(const char * dev_name, int block, int wait_ms,
+ unsigned int & ebusys, char * b, int b_mlen)
{
int sg_fd, ok, ret;
struct sg_io_hdr pt;
@@ -303,11 +363,9 @@ do_inquiry_prod_id(const char * dev_name, int block, int excl, int wait_ms,
if (! block)
open_flags |= O_NONBLOCK;
- if (excl)
- open_flags |= O_EXCL;
while (((sg_fd = open(dev_name, open_flags)) < 0) &&
(EBUSY == errno)) {
- ++bounces;
+ ++ebusys;
if (wait_ms > 0)
this_thread::sleep_for(milliseconds{wait_ms});
else if (0 == wait_ms)
@@ -380,15 +438,17 @@ work_thread(const char * dev_name, unsigned int lba, int id, int block,
int excl, int num, int wait_ms)
{
unsigned int thr_odd_count = 0;
- unsigned int thr_bounce_count = 0;
+ unsigned int thr_ebusy_count = 0;
+ unsigned int thr_eagain_count = 0;
int k, res;
console_mutex.lock();
- cerr << "Enter work_thread id=" << id << " excl=" << excl << endl;
+ cerr << "Enter work_thread id=" << id << " excl=" << excl << " block="
+ << block << endl;
console_mutex.unlock();
for (k = 0; k < num; ++k) {
- res = do_rd_inc_wr_twice(dev_name, lba, block, excl, wait_ms,
- thr_bounce_count);
+ res = do_rd_inc_wr_twice(dev_name, lba, block, excl, wait_ms, k,
+ thr_ebusy_count, thr_eagain_count);
if (res < 0)
break;
if (res)
@@ -402,7 +462,8 @@ work_thread(const char * dev_name, unsigned int lba, int id, int block,
odd_count_mutex.lock();
odd_count += thr_odd_count;
- bounce_count += thr_bounce_count;
+ ebusy_count += thr_ebusy_count;
+ eagain_count += thr_eagain_count;
odd_count_mutex.unlock();
}
@@ -481,8 +542,8 @@ main(int argc, char * argv[])
try {
if (! force) {
- res = do_inquiry_prod_id(dev_name, block, ! exclude_o_excl,
- wait_ms, bounce_count, b, sizeof(b));
+ res = do_inquiry_prod_id(dev_name, block, wait_ms, ebusy_count,
+ b, sizeof(b));
if (res) {
fprintf(stderr, "INQUIRY failed on %s\n", dev_name);
return 1;
@@ -515,7 +576,8 @@ main(int argc, char * argv[])
delete vt[k];
cout << "Expecting odd count of 0, got " << odd_count << endl;
- cout << "Number of EBUSYs: bounce_count=" << bounce_count << endl;
+ cout << "Number of EBUSYs: " << ebusy_count << endl;
+ cout << "Number of EAGAINs: " << eagain_count << endl;
}
catch(system_error& e) {
diff --git a/examples/sg_tst_excl2.cpp b/examples/sg_tst_excl2.cpp
index 6cefb628..435836f5 100644
--- a/examples/sg_tst_excl2.cpp
+++ b/examples/sg_tst_excl2.cpp
@@ -46,7 +46,7 @@
#include "sg_lib.h"
#include "sg_pt.h"
-static const char * version_str = "1.05 20131026";
+static const char * version_str = "1.05 20131029";
static const char * util_name = "sg_tst_excl2";
/* This is a test program for checking O_EXCL on open() works. It uses
@@ -99,7 +99,7 @@ using namespace std::chrono;
static mutex odd_count_mutex;
static mutex console_mutex;
static unsigned int odd_count;
-static unsigned int bounce_count;
+static unsigned int ebusy_count;
static void
@@ -129,9 +129,9 @@ usage(void)
printf(" -x don't use O_EXCL on first thread "
"(def: use\n"
" O_EXCL on all threads)\n\n");
- printf("Test O_EXCL open flag with sg driver. Each open/close "
- "cycle with the\nO_EXCL flag does a double increment on "
- "lba (using its first 4 bytes).\n");
+ printf("Test O_EXCL open flag with pass-through drivers. Each "
+ "open/close cycle with\nthe O_EXCL flag does a double increment "
+ "on lba (using its first 4 bytes).\n");
}
static int
@@ -193,7 +193,7 @@ pt_cat_no_good(int cat, struct sg_pt_base * ptp, const unsigned char * sbp)
* returns -1 else returns 0 if first int read is even otherwise returns 1. */
static int
do_rd_inc_wr_twice(const char * dev_name, unsigned int lba, int block,
- int excl, int wait_ms, unsigned int & bounces)
+ int excl, int wait_ms, unsigned int & ebusys)
{
int k, sg_fd, res, cat;
int odd = 0;
@@ -219,7 +219,7 @@ do_rd_inc_wr_twice(const char * dev_name, unsigned int lba, int block,
while (((sg_fd = scsi_pt_open_flags(dev_name, open_flags, 0)) < 0) &&
(-EBUSY == sg_fd)) {
- ++bounces;
+ ++ebusys;
if (wait_ms > 0)
this_thread::sleep_for(milliseconds{wait_ms});
else if (0 == wait_ms)
@@ -243,7 +243,7 @@ do_rd_inc_wr_twice(const char * dev_name, unsigned int lba, int block,
set_scsi_pt_data_in(ptp, lb, READ16_REPLY_LEN);
res = do_scsi_pt(ptp, sg_fd, 20 /* secs timeout */, 1);
if (res) {
- fprintf(stderr, "READ_16 do_scsi_pt() error\n");
+ fprintf(stderr, "READ_16 do_scsi_pt() submission error\n");
res = pt_err(res);
goto err;
}
@@ -278,7 +278,7 @@ do_rd_inc_wr_twice(const char * dev_name, unsigned int lba, int block,
set_scsi_pt_data_out(ptp, lb, WRITE16_REPLY_LEN);
res = do_scsi_pt(ptp, sg_fd, 20 /* secs timeout */, 1);
if (res) {
- fprintf(stderr, "WRITE_16 do_scsi_pt() error\n");
+ fprintf(stderr, "WRITE_16 do_scsi_pt() submission error\n");
res = pt_err(res);
goto err;
}
@@ -302,10 +302,11 @@ err:
#define INQ_CMD_LEN 6
/* Send INQUIRY and fetches response. If okay puts PRODUCT ID field
- * in b (up to m_blen bytes). Returns 0 on success, else -1 . */
+ * in b (up to m_blen bytes). Does not use O_EXCL flag. Returns 0 on success,
+ * else -1 . */
static int
-do_inquiry_prod_id(const char * dev_name, int block, int excl, int wait_ms,
- unsigned int & bounces, char * b, int b_mlen)
+do_inquiry_prod_id(const char * dev_name, int block, int wait_ms,
+ unsigned int & ebusys, char * b, int b_mlen)
{
int sg_fd, res, cat;
struct sg_pt_base * ptp = NULL;
@@ -318,11 +319,9 @@ do_inquiry_prod_id(const char * dev_name, int block, int excl, int wait_ms,
if (! block)
open_flags |= O_NONBLOCK;
- if (excl)
- open_flags |= O_EXCL;
while (((sg_fd = scsi_pt_open_flags(dev_name, open_flags, 0)) < 0) &&
(-EBUSY == sg_fd)) {
- ++bounces;
+ ++ebusys;
if (wait_ms > 0)
this_thread::sleep_for(milliseconds{wait_ms});
else if (0 == wait_ms)
@@ -344,7 +343,7 @@ do_inquiry_prod_id(const char * dev_name, int block, int excl, int wait_ms,
set_scsi_pt_data_in(ptp, inqBuff, INQ_REPLY_LEN);
res = do_scsi_pt(ptp, sg_fd, 20 /* secs timeout */, 1);
if (res) {
- fprintf(stderr, "INQUIRY do_scsi_pt() error\n");
+ fprintf(stderr, "INQUIRY do_scsi_pt() submission error\n");
res = pt_err(res);
goto err;
}
@@ -377,7 +376,7 @@ work_thread(const char * dev_name, unsigned int lba, int id, int block,
int excl, int num, int wait_ms)
{
unsigned int thr_odd_count = 0;
- unsigned int thr_bounce_count = 0;
+ unsigned int thr_ebusy_count = 0;
int k, res;
console_mutex.lock();
@@ -386,7 +385,7 @@ work_thread(const char * dev_name, unsigned int lba, int id, int block,
console_mutex.unlock();
for (k = 0; k < num; ++k) {
res = do_rd_inc_wr_twice(dev_name, lba, block, excl, wait_ms,
- thr_bounce_count);
+ thr_ebusy_count);
if (res < 0)
break;
if (res)
@@ -400,7 +399,7 @@ work_thread(const char * dev_name, unsigned int lba, int id, int block,
odd_count_mutex.lock();
odd_count += thr_odd_count;
- bounce_count += thr_bounce_count;
+ ebusy_count += thr_ebusy_count;
odd_count_mutex.unlock();
}
@@ -479,8 +478,8 @@ main(int argc, char * argv[])
try {
if (! force) {
- res = do_inquiry_prod_id(dev_name, block, ! exclude_o_excl,
- wait_ms, bounce_count, b, sizeof(b));
+ res = do_inquiry_prod_id(dev_name, block, wait_ms, ebusy_count,
+ b, sizeof(b));
if (res) {
fprintf(stderr, "INQUIRY failed on %s\n", dev_name);
return 1;
@@ -512,7 +511,7 @@ main(int argc, char * argv[])
delete vt[k];
cout << "Expecting odd count of 0, got " << odd_count << endl;
- cout << "Number of EBUSYs: bounce_count=" << bounce_count << endl;
+ cout << "Number of EBUSYs: " << ebusy_count << endl;
}
catch(system_error& e) {
diff --git a/examples/sg_tst_excl3.cpp b/examples/sg_tst_excl3.cpp
index 9ca59c99..58fdae75 100644
--- a/examples/sg_tst_excl3.cpp
+++ b/examples/sg_tst_excl3.cpp
@@ -46,7 +46,7 @@
#include "sg_lib.h"
#include "sg_pt.h"
-static const char * version_str = "1.02 20131026";
+static const char * version_str = "1.03 20131029";
static const char * util_name = "sg_tst_excl3";
/* This is a test program for checking O_EXCL on open() works. It uses
@@ -101,14 +101,15 @@ using namespace std::chrono;
static mutex odd_count_mutex;
static mutex console_mutex;
static unsigned int odd_count;
-static unsigned int bounce_count;
+static unsigned int ebusy_count;
static void
usage(void)
{
printf("Usage: %s [-b] [-f] [-h] [-l <lba>] [-n <n_per_thr>]\n"
- " [-t <num_thrs>] [-V] [-w <wait_ms>] [-x]\n"
+ " [-R] [-t <num_thrs>] [-V] [-w <wait_ms>] "
+ "[-x]\n"
" <disk_device>\n", util_name);
printf(" where\n");
printf(" -b block on open (def: O_NONBLOCK)\n");
@@ -120,6 +121,8 @@ usage(void)
DEF_LBA);
printf(" -n <n_per_thr> number of loops per thread "
"(def: %d)\n", DEF_NUM_PER_THREAD);
+ printf(" -R all readers; so first thread (id=0) "
+ "just reads\n");
printf(" -t <num_thrs> number of threads (def: %d)\n",
DEF_NUM_THREADS);
printf(" -V print version number then exit\n");
@@ -130,9 +133,9 @@ usage(void)
printf(" -x don't use O_EXCL on first thread "
"(def: use\n"
" O_EXCL on first thread)\n\n");
- printf("Test O_EXCL open flag with sg driver. First thread (id=0) "
- "does\nopen/close cycle with the O_EXCL flag then does a double "
- "increment on\nlba (using its first 4 bytes). Remaining "
+ printf("Test O_EXCL open flag with pass-through drivers. First thread "
+ "(id=0) does\nopen/close cycle with the O_EXCL flag then does a "
+ "double increment on\nlba (using its first 4 bytes). Remaining "
"theads read (without\nO_EXCL flag on open) and check the "
"value is even.\n");
}
@@ -196,7 +199,7 @@ pt_cat_no_good(int cat, struct sg_pt_base * ptp, const unsigned char * sbp)
* returns -1 else returns 0 if first int read is even otherwise returns 1. */
static int
do_rd_inc_wr_twice(const char * dev_name, int read_only, unsigned int lba,
- int block, int excl, int wait_ms, unsigned int & bounces)
+ int block, int excl, int wait_ms, unsigned int & ebusys)
{
int k, sg_fd, res, cat;
int odd = 0;
@@ -222,7 +225,7 @@ do_rd_inc_wr_twice(const char * dev_name, int read_only, unsigned int lba,
while (((sg_fd = scsi_pt_open_flags(dev_name, open_flags, 0)) < 0) &&
(-EBUSY == sg_fd)) {
- ++bounces;
+ ++ebusys;
if (wait_ms > 0)
this_thread::sleep_for(milliseconds{wait_ms});
else if (0 == wait_ms)
@@ -246,7 +249,7 @@ do_rd_inc_wr_twice(const char * dev_name, int read_only, unsigned int lba,
set_scsi_pt_data_in(ptp, lb, READ16_REPLY_LEN);
res = do_scsi_pt(ptp, sg_fd, 20 /* secs timeout */, 1);
if (res) {
- fprintf(stderr, "READ_16 do_scsi_pt() error\n");
+ fprintf(stderr, "READ_16 do_scsi_pt() submission error\n");
res = pt_err(res);
goto err;
}
@@ -284,7 +287,7 @@ do_rd_inc_wr_twice(const char * dev_name, int read_only, unsigned int lba,
set_scsi_pt_data_out(ptp, lb, WRITE16_REPLY_LEN);
res = do_scsi_pt(ptp, sg_fd, 20 /* secs timeout */, 1);
if (res) {
- fprintf(stderr, "WRITE_16 do_scsi_pt() error\n");
+ fprintf(stderr, "WRITE_16 do_scsi_pt() submission error\n");
res = pt_err(res);
goto err;
}
@@ -303,15 +306,15 @@ err:
}
-
#define INQ_REPLY_LEN 96
#define INQ_CMD_LEN 6
/* Send INQUIRY and fetches response. If okay puts PRODUCT ID field
- * in b (up to m_blen bytes). Returns 0 on success, else -1 . */
+ * in b (up to m_blen bytes). Does not use O_EXCL flag. Returns 0 on success,
+ * else -1 . */
static int
-do_inquiry_prod_id(const char * dev_name, int block, int excl, int wait_ms,
- unsigned int & bounces, char * b, int b_mlen)
+do_inquiry_prod_id(const char * dev_name, int block, int wait_ms,
+ unsigned int & ebusys, char * b, int b_mlen)
{
int sg_fd, res, cat;
struct sg_pt_base * ptp = NULL;
@@ -324,11 +327,9 @@ do_inquiry_prod_id(const char * dev_name, int block, int excl, int wait_ms,
if (! block)
open_flags |= O_NONBLOCK;
- if (excl)
- open_flags |= O_EXCL;
while (((sg_fd = scsi_pt_open_flags(dev_name, open_flags, 0)) < 0) &&
(-EBUSY == sg_fd)) {
- ++bounces;
+ ++ebusys;
if (wait_ms > 0)
this_thread::sleep_for(milliseconds{wait_ms});
else if (0 == wait_ms)
@@ -350,7 +351,7 @@ do_inquiry_prod_id(const char * dev_name, int block, int excl, int wait_ms,
set_scsi_pt_data_in(ptp, inqBuff, INQ_REPLY_LEN);
res = do_scsi_pt(ptp, sg_fd, 20 /* secs timeout */, 1);
if (res) {
- fprintf(stderr, "INQUIRY do_scsi_pt() error\n");
+ fprintf(stderr, "INQUIRY do_scsi_pt() submission error\n");
res = pt_err(res);
goto err;
}
@@ -380,19 +381,20 @@ err:
static void
work_thread(const char * dev_name, unsigned int lba, int id, int block,
- int excl, int num, int wait_ms)
+ int excl, bool all_readers, int num, int wait_ms)
{
unsigned int thr_odd_count = 0;
- unsigned int thr_bounce_count = 0;
+ unsigned int thr_ebusy_count = 0;
int k, res;
+ int reader = ((id > 0) || (all_readers));
console_mutex.lock();
cerr << "Enter work_thread id=" << id << " excl=" << excl << " block="
- << block << " ro=" << (id > 0) << endl;
+ << block << " reader=" << reader << endl;
console_mutex.unlock();
for (k = 0; k < num; ++k) {
- res = do_rd_inc_wr_twice(dev_name, (id > 0), lba, block, excl,
- wait_ms, thr_bounce_count);
+ res = do_rd_inc_wr_twice(dev_name, reader, lba, block, excl,
+ wait_ms, thr_ebusy_count);
if (res < 0)
break;
if (res)
@@ -406,7 +408,7 @@ work_thread(const char * dev_name, unsigned int lba, int id, int block,
odd_count_mutex.lock();
odd_count += thr_odd_count;
- bounce_count += thr_bounce_count;
+ ebusy_count += thr_ebusy_count;
odd_count_mutex.unlock();
}
@@ -419,6 +421,7 @@ main(int argc, char * argv[])
int force = 0;
unsigned int lba = DEF_LBA;
int num_per_thread = DEF_NUM_PER_THREAD;
+ bool all_readers = false;
int num_threads = DEF_NUM_THREADS;
int wait_ms = DEF_WAIT_MS;
int exclude_o_excl = 0;
@@ -451,7 +454,9 @@ main(int argc, char * argv[])
num_threads = atoi(argv[k]);
else
break;
- } else if (0 == memcmp("-V", argv[k], 2)) {
+ } else if (0 == memcmp("-R", argv[k], 2))
+ all_readers = true;
+ else if (0 == memcmp("-V", argv[k], 2)) {
printf("%s version: %s\n", util_name, version_str);
return 0;
} else if (0 == memcmp("-w", argv[k], 2)) {
@@ -485,8 +490,8 @@ main(int argc, char * argv[])
try {
if (! force) {
- res = do_inquiry_prod_id(dev_name, block, ! exclude_o_excl,
- wait_ms, bounce_count, b, sizeof(b));
+ res = do_inquiry_prod_id(dev_name, block, wait_ms, ebusy_count,
+ b, sizeof(b));
if (res) {
fprintf(stderr, "INQUIRY failed on %s\n", dev_name);
return 1;
@@ -507,7 +512,8 @@ main(int argc, char * argv[])
int excl = ((0 == k) && (! exclude_o_excl)) ? 1 : 0;
thread * tp = new thread {work_thread, dev_name, lba, k, block,
- excl, num_per_thread, wait_ms};
+ excl, all_readers, num_per_thread,
+ wait_ms};
vt.push_back(tp);
}
@@ -518,7 +524,7 @@ main(int argc, char * argv[])
delete vt[k];
cout << "Expecting odd count of 0, got " << odd_count << endl;
- cout << "Number of EBUSYs: bounce_count=" << bounce_count << endl;
+ cout << "Number of EBUSYs: " << ebusy_count << endl;
}
catch(system_error& e) {
diff --git a/src/sg_luns.c b/src/sg_luns.c
index 33e4f222..497b2c51 100644
--- a/src/sg_luns.c
+++ b/src/sg_luns.c
@@ -28,7 +28,7 @@
* and decodes the response.
*/
-static const char * version_str = "1.23 20130730";
+static const char * version_str = "1.24 20131029";
#define MAX_RLUNS_BUFF_LEN (1024 * 1024)
#define DEF_RLUNS_BUFF_LEN (1024 * 8)
@@ -332,7 +332,7 @@ dStrRaw(const char* str, int len)
int
main(int argc, char * argv[])
{
- int sg_fd, k, m, off, res, c, list_len, luns, trunc;
+ int sg_fd, k, m, off, res, c, list_len, len_cap, luns, trunc;
int decode = 0;
int do_hex = 0;
#ifdef SG_LIB_LINUX
@@ -555,12 +555,15 @@ main(int argc, char * argv[])
if (0 == res) {
list_len = (reportLunsBuff[0] << 24) + (reportLunsBuff[1] << 16) +
(reportLunsBuff[2] << 8) + reportLunsBuff[3];
+ len_cap = list_len + 8;
+ if (len_cap > maxlen)
+ len_cap = maxlen;
if (do_raw) {
- dStrRaw((const char *)reportLunsBuff, list_len + 8);
+ dStrRaw((const char *)reportLunsBuff, len_cap);
goto the_end;
}
if (1 == do_hex) {
- dStrHex((const char *)reportLunsBuff, list_len + 8, 1);
+ dStrHex((const char *)reportLunsBuff, len_cap, 1);
goto the_end;
}
luns = (list_len / 8);