From 7b165064d3d22cf8e699935bccef0e728857c4eb Mon Sep 17 00:00:00 2001 From: Douglas Gilbert Date: Mon, 10 Sep 2007 00:54:57 +0000 Subject: rearrange files into include, src, lib and doc directories git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@100 6180dd3e-e324-4e3e-922d-17de1ae2f315 --- src/sg_verify.c | 248 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 248 insertions(+) create mode 100644 src/sg_verify.c (limited to 'src/sg_verify.c') diff --git a/src/sg_verify.c b/src/sg_verify.c new file mode 100644 index 00000000..b5de97b0 --- /dev/null +++ b/src/sg_verify.c @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2004-2007 Douglas Gilbert. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include +#include +#define __STDC_FORMAT_MACROS 1 +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "sg_lib.h" +#include "sg_cmds_basic.h" +#include "sg_cmds_extra.h" + +/* A utility program for the Linux OS SCSI subsystem. + * + * This program issues the SCSI VERIFY command to the given SCSI block device. + */ + +static char * version_str = "1.09 20070714"; + +#define ME "sg_verify: " + + +static struct option long_options[] = { + {"bpc", 1, 0, 'b'}, + {"count", 1, 0, 'c'}, + {"dpo", 0, 0, 'd'}, + {"help", 0, 0, 'h'}, + {"lba", 1, 0, 'l'}, + {"verbose", 0, 0, 'v'}, + {"version", 0, 0, 'V'}, + {0, 0, 0, 0}, +}; + +static void usage() +{ + fprintf(stderr, "Usage: " + "sg_verify [--bpc=BPC] [--count=COUNT] [--dpo] [--help] " + "[--lba=LBA]\n" + " [--verbose] [--version] DEVICE\n" + " where:\n" + " --bpc=BPC|-b BPC max blocks per verify command " + "(def 128)\n" + " --count=COUNT|-c COUNT count of blocks to verify " + "(def 1)\n" + " --dpo|-d disable page out (cache retention " + "priority)\n" + " --help|-h print out usage message\n" + " --lba=LBA|-l LBA logical block address to start " + "verify (def 0)\n" + " --verbose|-v increase verbosity\n" + " --version|-V print version string and exit\n\n" + "Performs a SCSI VERIFY(10) command\n" + ); +} + +int main(int argc, char * argv[]) +{ + int sg_fd, res, c, num; + long long ll; + int dpo = 0; + int bytechk = 0; + long long count = 1; + long long orig_count; + int bpc = 128; + unsigned long long lba = 0; + unsigned long long orig_lba; + int verbose = 0; + char device_name[256]; + int ret = 0; + unsigned long info = 0; + + memset(device_name, 0, sizeof device_name); + while (1) { + int option_index = 0; + + c = getopt_long(argc, argv, "b:c:dhl:vV", long_options, + &option_index); + if (c == -1) + break; + + switch (c) { + case 'b': + bpc = sg_get_num(optarg); + if (bpc < 1) { + fprintf(stderr, "bad argument to '--bpc'\n"); + return SG_LIB_SYNTAX_ERROR; + } + break; + case 'c': + count = sg_get_llnum(optarg); + if (count < 0) { + fprintf(stderr, "bad argument to '--count'\n"); + return SG_LIB_SYNTAX_ERROR; + } + break; + case 'd': + dpo = 1; + break; + case 'h': + case '?': + usage(); + return 0; + case 'l': + ll = sg_get_llnum(optarg); + if (-1 == ll) { + fprintf(stderr, "bad argument to '--lba'\n"); + return SG_LIB_SYNTAX_ERROR; + } + lba = (unsigned long long)ll; + break; + case 'v': + ++verbose; + break; + case 'V': + fprintf(stderr, ME "version: %s\n", version_str); + return 0; + default: + fprintf(stderr, "unrecognised option code 0x%x ??\n", c); + usage(); + return SG_LIB_SYNTAX_ERROR; + } + } + if (optind < argc) { + if ('\0' == device_name[0]) { + strncpy(device_name, argv[optind], sizeof(device_name) - 1); + device_name[sizeof(device_name) - 1] = '\0'; + ++optind; + } + if (optind < argc) { + for (; optind < argc; ++optind) + fprintf(stderr, "Unexpected extra argument: %s\n", + argv[optind]); + usage(); + return SG_LIB_SYNTAX_ERROR; + } + } + if (bpc > 0xffff) { + fprintf(stderr, "'bpc' cannot exceed 65535\n"); + usage(); + return SG_LIB_SYNTAX_ERROR; + } + if (lba > 0xffffffffLLU) { + fprintf(stderr, "'lba' cannot exceed 32 bits\n"); + usage(); + return SG_LIB_SYNTAX_ERROR; + } + orig_count = count; + orig_lba = lba; + + if (0 == device_name[0]) { + fprintf(stderr, "missing device name!\n"); + usage(); + return SG_LIB_SYNTAX_ERROR; + } + sg_fd = sg_cmds_open_device(device_name, 0 /* rw */, verbose); + if (sg_fd < 0) { + fprintf(stderr, ME "open error: %s: %s\n", device_name, + safe_strerror(-sg_fd)); + return SG_LIB_FILE_ERROR; + } + + for (; count > 0; count -= bpc, lba +=bpc) { + num = (count > bpc) ? bpc : count; + res = sg_ll_verify10(sg_fd, dpo, bytechk, (unsigned long)lba, num, + NULL, 0, &info, 1, verbose); + if (0 != res) { + ret = res; + switch (res) { + case SG_LIB_CAT_NOT_READY: + fprintf(stderr, "Verify(10) failed, device not ready\n"); + break; + case SG_LIB_CAT_UNIT_ATTENTION: + fprintf(stderr, "Verify(10), unit attention\n"); + break; + case SG_LIB_CAT_ABORTED_COMMAND: + fprintf(stderr, "Verify(10), aborted command\n"); + break; + case SG_LIB_CAT_INVALID_OP: + fprintf(stderr, "Verify(10) command not supported\n"); + break; + case SG_LIB_CAT_ILLEGAL_REQ: + fprintf(stderr, "bad field in Verify(10) cdb, near " + "lba=0x%" PRIx64 "\n", lba); + break; + case SG_LIB_CAT_MEDIUM_HARD: + fprintf(stderr, "medium or hardware error near " + "lba=0x%" PRIx64 "\n", lba); + break; + case SG_LIB_CAT_MEDIUM_HARD_WITH_INFO: + fprintf(stderr, "medium or hardware error, reported " + "lba=0x%lx\n", info); + break; + default: + fprintf(stderr, "Verify(10) failed near lba=%" PRIu64 + " [0x%" PRIx64 "]\n", lba, lba); + break; + } + break; + } + } + + if (verbose && (0 == ret) && (orig_count > 1)) + fprintf(stderr, "Verified %" PRId64 " [0x%" PRIx64 "] blocks from " + "lba %" PRIu64 " [0x%" PRIx64 "]\n without error\n", + orig_count, (unsigned long long)orig_count, orig_lba, + orig_lba); + + res = sg_cmds_close_device(sg_fd); + if (res < 0) { + fprintf(stderr, "close error: %s\n", safe_strerror(-res)); + if (0 == ret) + return SG_LIB_FILE_ERROR; + } + return (ret >= 0) ? ret : SG_LIB_CAT_OTHER; +} -- cgit v1.2.3