aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2013-08-08 14:45:41 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2013-08-08 14:45:41 +0000
commit81c585f852c09f67e6aabb36cccd0eec0c7768b0 (patch)
tree5fb06c502db25a254d1ca76f1da2790564e134bb
parent070138c9d60d9b70dc809e1a200af6e7d15d8a4a (diff)
downloadsg3_utils-81c585f852c09f67e6aabb36cccd0eec0c7768b0.tar.gz
sg_compare_and_write: solaris fix; and -b to sg_tst_excl+sg_tst_excl2
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@505 6180dd3e-e324-4e3e-922d-17de1ae2f315
-rw-r--r--ChangeLog4
-rw-r--r--examples/sg_tst_excl.cpp52
-rw-r--r--examples/sg_tst_excl2.cpp61
-rw-r--r--src/sg_compare_and_write.c4
4 files changed, 71 insertions, 50 deletions
diff --git a/ChangeLog b/ChangeLog
index 4307c119..3953a884 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,7 +2,7 @@ Each utility has its own version number, date of last change and
some description at the top of its ".c" file. All utilities in the main
directory have their own "man" pages. There is also a sg3_utils man page.
-Changelog for sg3_utils-1.37 [20130805] [svn: r504]
+Changelog for sg3_utils-1.37 [20130807] [svn: r505]
- sg_compare_and_write: fix wrprotect setting
- sg_inq: fix referrals VPD page
- dev_id VPD: T10 vendor id designator clean up
@@ -15,7 +15,7 @@ Changelog for sg3_utils-1.37 [20130805] [svn: r504]
- add sg_ll_3party_copy_out()
- add dStrHexErr(): ascii hex to stderr
- add dStrHexStr(): ascii hex to string
- - scripts/rescan-scsi-bus.sh KR's v1.57 + HR patch
+ - scripts/rescan-scsi-bus.sh KG's v1.57 + HR patch
- Makefile.am cleanup
- examples: add sg_tst_excl and sg_tst_excl2
diff --git a/examples/sg_tst_excl.cpp b/examples/sg_tst_excl.cpp
index 77bdfe3f..384a3566 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.03 20130803";
+static const char * version_str = "1.04 20130806";
static const char * util_name = "sg_tst_excl";
/* This is a test program for checking O_EXCL on open() works. It uses
@@ -104,10 +104,11 @@ static unsigned int bounce_count;
static void
usage(void)
{
- printf("Usage: %s [-l <lba>] [-n <n_per_thr>] [-t <num_thrs>]\n"
+ printf("Usage: %s [-b] [-l <lba>] [-n <n_per_thr>] [-t <num_thrs>]\n"
" [-V] [-w <wait_ms>] [-x] "
"<disk_device>\n", util_name);
printf(" where\n");
+ printf(" -b block on open (def: O_NONBLOCK)\n");
printf(" -l <lba> logical block to increment (def: %u)\n",
DEF_LBA);
printf(" -n <n_per_thr> number of loops per thread "
@@ -133,15 +134,15 @@ usage(void)
#define WRITE16_REPLY_LEN 512
#define WRITE16_CMD_LEN 16
-/* Opens dev_name O_EXCL | O_NONBLOCK and spins if busy, sleeping for
- * wait_ms milliseconds if wait_ms is non-negative (else tight spin).
+/* 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),
* 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 excl,
- int wait_ms, unsigned int & bounces)
+do_rd_inc_wr_twice(const char * dev_name, unsigned int lba, int block,
+ int excl, int wait_ms, unsigned int & bounces)
{
int k, sg_fd, ok;
int odd = 0;
@@ -154,12 +155,14 @@ do_rd_inc_wr_twice(const char * dev_name, unsigned int lba, int excl,
unsigned char sense_buffer[64];
unsigned char lb[READ16_REPLY_LEN];
char ebuff[EBUFF_SZ];
- int open_flags = O_RDWR | O_NONBLOCK;
+ int open_flags = O_RDWR;
r16CmdBlk[6] = w16CmdBlk[6] = (lba >> 24) & 0xff;
r16CmdBlk[7] = w16CmdBlk[7] = (lba >> 16) & 0xff;
r16CmdBlk[8] = w16CmdBlk[8] = (lba >> 8) & 0xff;
r16CmdBlk[9] = w16CmdBlk[9] = lba & 0xff;
+ if (! block)
+ open_flags |= O_NONBLOCK;
if (excl)
open_flags |= O_EXCL;
@@ -281,7 +284,7 @@ do_rd_inc_wr_twice(const char * dev_name, unsigned int lba, int excl,
/* Send INQUIRY and fetches response. If okay puts PRODUCT ID field
* in b (up to m_blen bytes). Returns 0 on success, else -1 . */
static int
-do_inquiry_prod_id(const char * dev_name, int wait_ms,
+do_inquiry_prod_id(const char * dev_name, int block, int excl, int wait_ms,
unsigned int & bounces, char * b, int b_mlen)
{
int sg_fd, ok, ret;
@@ -291,9 +294,13 @@ do_inquiry_prod_id(const char * dev_name, int wait_ms,
unsigned char inqBuff[INQ_REPLY_LEN];
unsigned char sense_buffer[64];
char ebuff[EBUFF_SZ];
+ int open_flags = O_RDWR; /* O_EXCL | O_RDONLY fails with EPERM */
- /* O_RDONLY | O_EXCL leads to EPERM (undocumented, historic) */
- while (((sg_fd = open(dev_name, O_RDWR | O_EXCL | O_NONBLOCK)) < 0) &&
+ if (! block)
+ open_flags |= O_NONBLOCK;
+ if (excl)
+ open_flags |= O_EXCL;
+ while (((sg_fd = open(dev_name, open_flags)) < 0) &&
(EBUSY == errno)) {
++bounces;
if (wait_ms > 0)
@@ -364,8 +371,8 @@ do_inquiry_prod_id(const char * dev_name, int wait_ms,
}
static void
-work_thread(const char * dev_name, unsigned int lba, int id, int excl,
- int num, int wait_ms)
+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;
@@ -375,7 +382,7 @@ work_thread(const char * dev_name, unsigned int lba, int id, int excl,
cerr << "Enter work_thread id=" << id << " excl=" << excl << endl;
console_mutex.unlock();
for (k = 0; k < num; ++k) {
- res = do_rd_inc_wr_twice(dev_name, lba, excl, wait_ms,
+ res = do_rd_inc_wr_twice(dev_name, lba, block, excl, wait_ms,
thr_bounce_count);
if (res < 0)
break;
@@ -399,16 +406,19 @@ int
main(int argc, char * argv[])
{
int k, res;
+ int block = 0;
unsigned int lba = DEF_LBA;
int num_per_thread = DEF_NUM_PER_THREAD;
int num_threads = DEF_NUM_THREADS;
int wait_ms = DEF_WAIT_MS;
- int exclude_excl1 = 0;
+ int exclude_o_excl = 0;
char * dev_name = NULL;
char b[64];
for (k = 1; k < argc; ++k) {
- if (0 == memcmp("-l", argv[k], 2)) {
+ if (0 == memcmp("-b", argv[k], 2))
+ ++block;
+ else if (0 == memcmp("-l", argv[k], 2)) {
++k;
if ((k < argc) && isdigit(*argv[k]))
lba = (unsigned int)atoi(argv[k]);
@@ -439,7 +449,7 @@ main(int argc, char * argv[])
} else
break;
} else if (0 == memcmp("-x", argv[k], 2))
- ++exclude_excl1;
+ ++exclude_o_excl;
else if (*argv[k] == '-') {
printf("Unrecognized switch: %s\n", argv[k]);
dev_name = NULL;
@@ -459,8 +469,8 @@ main(int argc, char * argv[])
}
try {
- res = do_inquiry_prod_id(dev_name, wait_ms, bounce_count, b,
- sizeof(b));
+ res = do_inquiry_prod_id(dev_name, block, ! exclude_o_excl, wait_ms,
+ bounce_count, b, sizeof(b));
if (res) {
fprintf(stderr, "INQUIRY failed on %s\n", dev_name);
return 1;
@@ -477,10 +487,10 @@ main(int argc, char * argv[])
vector<thread *> vt;
for (k = 0; k < num_threads; ++k) {
- int excl = ((0 == k) && exclude_excl1) ? 0 : 1;
+ int excl = ((0 == k) && exclude_o_excl) ? 0 : 1;
- thread * tp = new thread {work_thread, dev_name, lba, k, excl,
- num_per_thread, wait_ms};
+ thread * tp = new thread {work_thread, dev_name, lba, k, block,
+ excl, num_per_thread, wait_ms};
vt.push_back(tp);
}
diff --git a/examples/sg_tst_excl2.cpp b/examples/sg_tst_excl2.cpp
index 10677bc8..8f88a25f 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.03 20130803";
+static const char * version_str = "1.04 20130806";
static const char * util_name = "sg_tst_excl2";
/* This is a test program for checking O_EXCL on open() works. It uses
@@ -105,10 +105,11 @@ static unsigned int bounce_count;
static void
usage(void)
{
- printf("Usage: %s [-l <lba>] [-n <n_per_thr>] [-t <num_thrs>]\n"
+ printf("Usage: %s [-b] [-l <lba>] [-n <n_per_thr>] [-t <num_thrs>]\n"
" [-V] [-w <wait_ms>] [-x] "
"<disk_device>\n", util_name);
printf(" where\n");
+ printf(" -b block on open (def: O_NONBLOCK)\n");
printf(" -l <lba> logical block to increment (def: %u)\n",
DEF_LBA);
printf(" -n <n_per_thr> number of loops per thread "
@@ -187,15 +188,14 @@ pt_cat_no_good(int cat, int sg_fd, struct sg_pt_base * ptp,
#define WRITE16_REPLY_LEN 512
#define WRITE16_CMD_LEN 16
-/* Opens dev_name either O_EXCL | O_NONBLOCK, if excl is 1; or O_NONBLOCK
- * if excl is 0. Spins if busy, sleeping for wait_ms milliseconds if wait_ms
- * is non-negative (else tight spin). Reads lba 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 is even otherwise returns 1. */
+/* 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), 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 is even otherwise returns 1. */
static int
-do_rd_inc_wr_twice(const char * dev_name, unsigned int lba, int excl,
- int wait_ms, unsigned int & bounces)
+do_rd_inc_wr_twice(const char * dev_name, unsigned int lba, int block,
+ int excl, int wait_ms, unsigned int & bounces)
{
int k, sg_fd, res, cat;
int odd = 0;
@@ -208,12 +208,14 @@ do_rd_inc_wr_twice(const char * dev_name, unsigned int lba, int excl,
unsigned char sense_buffer[64];
unsigned char lb[READ16_REPLY_LEN];
char ebuff[EBUFF_SZ];
- int open_flags = O_RDWR | O_NONBLOCK;
+ int open_flags = O_RDWR;
r16CmdBlk[6] = w16CmdBlk[6] = (lba >> 24) & 0xff;
r16CmdBlk[7] = w16CmdBlk[7] = (lba >> 16) & 0xff;
r16CmdBlk[8] = w16CmdBlk[8] = (lba >> 8) & 0xff;
r16CmdBlk[9] = w16CmdBlk[9] = lba & 0xff;
+ if (! block)
+ open_flags |= O_NONBLOCK;
if (excl)
open_flags |= O_EXCL;
@@ -300,7 +302,7 @@ do_rd_inc_wr_twice(const char * dev_name, unsigned int lba, int excl,
/* Send INQUIRY and fetches response. If okay puts PRODUCT ID field
* in b (up to m_blen bytes). Returns 0 on success, else -1 . */
static int
-do_inquiry_prod_id(const char * dev_name, int wait_ms,
+do_inquiry_prod_id(const char * dev_name, int block, int excl, int wait_ms,
unsigned int & bounces, char * b, int b_mlen)
{
int sg_fd, res, cat;
@@ -310,9 +312,12 @@ do_inquiry_prod_id(const char * dev_name, int wait_ms,
unsigned char inqBuff[INQ_REPLY_LEN];
unsigned char sense_buffer[64];
char ebuff[EBUFF_SZ];
- const int open_flags = O_RDWR | O_EXCL | O_NONBLOCK;
+ int open_flags = O_RDWR; /* since O_EXCL | O_RDONLY gives EPERM */
- /* O_RDONLY | O_EXCL leads to EPERM (undocumented, historic) */
+ 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;
@@ -363,18 +368,19 @@ do_inquiry_prod_id(const char * dev_name, int wait_ms,
}
static void
-work_thread(const char * dev_name, unsigned int lba, int id, int excl,
- int num, int wait_ms)
+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;
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, excl, wait_ms,
+ res = do_rd_inc_wr_twice(dev_name, lba, block, excl, wait_ms,
thr_bounce_count);
if (res < 0)
break;
@@ -398,16 +404,19 @@ int
main(int argc, char * argv[])
{
int k, res;
+ int block = 0;
unsigned int lba = DEF_LBA;
int num_per_thread = DEF_NUM_PER_THREAD;
int num_threads = DEF_NUM_THREADS;
int wait_ms = DEF_WAIT_MS;
- int exclude_excl1 = 0;
+ int exclude_o_excl = 0;
char * dev_name = NULL;
char b[64];
for (k = 1; k < argc; ++k) {
- if (0 == memcmp("-l", argv[k], 2)) {
+ if (0 == memcmp("-b", argv[k], 2))
+ ++block;
+ else if (0 == memcmp("-l", argv[k], 2)) {
++k;
if ((k < argc) && isdigit(*argv[k]))
lba = (unsigned int)atoi(argv[k]);
@@ -438,7 +447,7 @@ main(int argc, char * argv[])
} else
break;
} else if (0 == memcmp("-x", argv[k], 2))
- ++exclude_excl1;
+ ++exclude_o_excl;
else if (*argv[k] == '-') {
printf("Unrecognized switch: %s\n", argv[k]);
dev_name = NULL;
@@ -458,8 +467,8 @@ main(int argc, char * argv[])
}
try {
- res = do_inquiry_prod_id(dev_name, wait_ms, bounce_count, b,
- sizeof(b));
+ res = do_inquiry_prod_id(dev_name, block, ! exclude_o_excl, wait_ms,
+ bounce_count, b, sizeof(b));
if (res) {
fprintf(stderr, "INQUIRY failed on %s\n", dev_name);
return 1;
@@ -476,10 +485,10 @@ main(int argc, char * argv[])
vector<thread *> vt;
for (k = 0; k < num_threads; ++k) {
- int excl = ((0 == k) && exclude_excl1) ? 0 : 1;
+ int excl = ((0 == k) && exclude_o_excl) ? 0 : 1;
- thread * tp = new thread {work_thread, dev_name, lba, k, excl,
- num_per_thread, wait_ms};
+ thread * tp = new thread {work_thread, dev_name, lba, k, block,
+ excl, num_per_thread, wait_ms};
vt.push_back(tp);
}
diff --git a/src/sg_compare_and_write.c b/src/sg_compare_and_write.c
index f97ca4bf..a91fe661 100644
--- a/src/sg_compare_and_write.c
+++ b/src/sg_compare_and_write.c
@@ -28,10 +28,12 @@
*
*/
+#ifndef __sun
#define _XOPEN_SOURCE 500
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
+#endif
#include <unistd.h>
#include <fcntl.h>
@@ -48,7 +50,7 @@
#include "sg_cmds_basic.h"
#include "sg_pt.h"
-static const char * version_str = "1.06 20130604";
+static const char * version_str = "1.07 20130807";
#define DEF_BLOCK_SIZE 512
#define DEF_NUM_BLOCKS (1)