From af6d1c9c13482265b76dc15c84ab055ba25dda41 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Sun, 21 Apr 2013 14:50:41 -0700 Subject: [PATCH] Add a test for mandatory opcodes for SBC devices. Note that Read16/Readcapacity16 are mandatory on SBC3 but not prior. Not all mandatory opcodes are tested for yet. --- Makefile.am | 1 + test-tool/iscsi-support.c | 17 +++++- test-tool/iscsi-support.h | 1 + test-tool/iscsi-test-cu.c | 16 +++++- test-tool/iscsi-test-cu.h | 2 + test-tool/test_mandatory_sbc.c | 68 ++++++++++++++++++++++++ test-tool/test_nomedia_sbc.c | 11 +++- test-tool/test_readcapacity16_alloclen.c | 6 ++- test-tool/test_readcapacity16_simple.c | 10 ++++ 9 files changed, 127 insertions(+), 5 deletions(-) create mode 100644 test-tool/test_mandatory_sbc.c diff --git a/Makefile.am b/Makefile.am index a53f1cd..3308d9f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -190,6 +190,7 @@ bin_iscsi_test_cu_SOURCES = test-tool/iscsi-test-cu.c \ test-tool/test_inquiry_evpd.c \ test-tool/test_inquiry_supported_vpd.c \ test-tool/test_inquiry_mandatory_vpd_sbc.c \ + test-tool/test_mandatory_sbc.c \ test-tool/test_nomedia_sbc.c \ test-tool/test_orwrite_simple.c \ test-tool/test_orwrite_beyond_eol.c \ diff --git a/test-tool/iscsi-support.c b/test-tool/iscsi-support.c index c74bd42..e40ee97 100644 --- a/test-tool/iscsi-support.c +++ b/test-tool/iscsi-support.c @@ -60,6 +60,7 @@ int lbpws10; int lbpws; int anc_sup; int readonly; +int sbc3_support; int (*real_iscsi_queue_pdu)(struct iscsi_context *iscsi, struct iscsi_pdu *pdu); @@ -2465,7 +2466,13 @@ readcapacity16(struct iscsi_context *iscsi, int lun, int alloc_len) iscsi_get_error(iscsi)); return -1; } - + if (task->status == SCSI_STATUS_CHECK_CONDITION + && task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST + && task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE) { + logging(LOG_NORMAL, "[SKIPPED] READCAPACITY16 is not implemented on target"); + scsi_free_scsi_task(task); + return -2; + } if (task->status != SCSI_STATUS_GOOD) { logging(LOG_NORMAL, "[FAILED] READCAPACITY16 command: " "failed with sense. %s", iscsi_get_error(iscsi)); @@ -2498,7 +2505,13 @@ readcapacity16_nomedium(struct iscsi_context *iscsi, int lun, int alloc_len) iscsi_get_error(iscsi)); return -1; } - + if (task->status == SCSI_STATUS_CHECK_CONDITION + && task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST + && task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE) { + logging(LOG_NORMAL, "[SKIPPED] READCAPACITY16 is not implemented on target"); + scsi_free_scsi_task(task); + return -2; + } if (task->status == SCSI_STATUS_GOOD) { logging(LOG_NORMAL, "[FAILED] READCAPACITY16 command successful. But should have failed with NOT_READY/MEDIUM_NOT_PRESENT*"); scsi_free_scsi_task(task); diff --git a/test-tool/iscsi-support.h b/test-tool/iscsi-support.h index b605a7a..ca5ae06 100644 --- a/test-tool/iscsi-support.h +++ b/test-tool/iscsi-support.h @@ -142,6 +142,7 @@ extern int lbpws10; extern int lbpws; extern int anc_sup; extern int readonly; +extern int sbc3_support; struct iscsi_context *iscsi_context_login(const char *initiatorname, const char *url, int *lun); diff --git a/test-tool/iscsi-test-cu.c b/test-tool/iscsi-test-cu.c index 8871010..6c5511d 100644 --- a/test-tool/iscsi-test-cu.c +++ b/test-tool/iscsi-test-cu.c @@ -75,6 +75,11 @@ static CU_TestInfo tests_inquiry[] = { CU_TEST_INFO_NULL }; +static CU_TestInfo tests_mandatory[] = { + { (char *)"testMandatorySBC", test_mandatory_sbc }, + CU_TEST_INFO_NULL +}; + static CU_TestInfo tests_nomedia[] = { { (char *)"testNoMediaSBC", test_nomedia_sbc }, CU_TEST_INFO_NULL @@ -366,6 +371,8 @@ static CU_SuiteInfo suites[] = { tests_get_lba_status }, { (char *)"TestInquiry", test_setup, test_teardown, tests_inquiry }, + { (char *)"TestMandatory", test_setup, test_teardown, + tests_mandatory }, { (char *)"TestNoMedia", test_setup, test_teardown, tests_nomedia }, { (char *)"TestOrWrite", test_setup, test_teardown, @@ -679,7 +686,7 @@ main(int argc, char *argv[]) { "Verbose-scsi", no_argument, 0, 'V' }, { NULL, 0, 0, 0 } }; - int c; + int i, c; int opt_idx = 0; while ((c = getopt_long(argc, argv, "?hli:I:t:sdgfAsnvV", long_opts, @@ -844,6 +851,13 @@ main(int argc, char *argv[]) encserv = inq->encserv; scsi_free_scsi_task(task); + sbc3_support = 0; + for (i = 0; i < 8; i++) { + if (inq->version_descriptor[i] == 0x04C0) { + sbc3_support = 1; + } + } + /* if thin provisioned we also need to read the VPD page for it */ if (lbpme != 0) { struct scsi_inquiry_logical_block_provisioning *inq_lbp; diff --git a/test-tool/iscsi-test-cu.h b/test-tool/iscsi-test-cu.h index 1d2dcc4..1ef1960 100644 --- a/test-tool/iscsi-test-cu.h +++ b/test-tool/iscsi-test-cu.h @@ -49,6 +49,8 @@ void test_inquiry_evpd(void); void test_inquiry_supported_vpd(void); void test_inquiry_mandatory_vpd_sbc(void); +void test_mandatory_sbc(void); + void test_nomedia_sbc(void); void test_orwrite_simple(void); diff --git a/test-tool/test_mandatory_sbc.c b/test-tool/test_mandatory_sbc.c new file mode 100644 index 0000000..6012955 --- /dev/null +++ b/test-tool/test_mandatory_sbc.c @@ -0,0 +1,68 @@ +/* + Copyright (C) 2013 by Ronnie Sahlberg + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . +*/ + +#include + +#include + +#include "iscsi.h" +#include "scsi-lowlevel.h" +#include "iscsi-support.h" +#include "iscsi-test-cu.h" + +void +test_mandatory_sbc(void) +{ + int ret; + //unsigned char buf[4096]; + //struct unmap_list list[1]; + + logging(LOG_VERBOSE, LOG_BLANK_LINE); + logging(LOG_VERBOSE, "Test support for all mandatory opcodes on SBC devices"); + + CHECK_FOR_SBC; + + logging(LOG_VERBOSE, "Test INQUIRY."); + ret = inquiry(iscsic, tgt_lun, 0, 0, 255, NULL); + CU_ASSERT_EQUAL(ret, 0); + + logging(LOG_VERBOSE, "Test READCAPACITY10."); + ret = readcapacity10(iscsic, tgt_lun, 0, 0); + CU_ASSERT_EQUAL(ret, 0); + + if (sbc3_support) { + logging(LOG_VERBOSE, "Test READCAPACITY16. The device claims SBC-3 support."); + ret = readcapacity16(iscsic, tgt_lun, 15); + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Test READ10."); + ret = read10(iscsic, tgt_lun, 0, block_size, block_size, + 0, 0, 0, 0, 0, NULL); + CU_ASSERT_EQUAL(ret, 0); + + if (sbc3_support) { + logging(LOG_VERBOSE, "Test READ16. the device claims SBC-3 support."); + ret = read16(iscsic, tgt_lun, 0, block_size, block_size, + 0, 0, 0, 0, 0, NULL); + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Test TESTUNITREADY."); + ret = testunitready(iscsic, tgt_lun); + CU_ASSERT_EQUAL(ret, 0); +} diff --git a/test-tool/test_nomedia_sbc.c b/test-tool/test_nomedia_sbc.c index ed460e7..42ac02a 100644 --- a/test-tool/test_nomedia_sbc.c +++ b/test-tool/test_nomedia_sbc.c @@ -89,7 +89,16 @@ test_nomedia_sbc(void) logging(LOG_VERBOSE, "Test READCAPACITY16 when medium is ejected."); ret = readcapacity16_nomedium(iscsic, tgt_lun, 15); - CU_ASSERT_EQUAL(ret, 0); + if (ret == -2) { + if (sbc3_support) { + logging(LOG_NORMAL, "[FAILED] READCAPACITY16 is not available but the device claims SBC-3 support."); + CU_FAIL("READCAPACITY16 failed but the device claims SBC-3 support."); + } else { + logging(LOG_NORMAL, "[SKIPPED] READCAPACITY16 is not implemented on this target and it does not claim SBC-3 support."); + } + } else { + CU_ASSERT_EQUAL(ret, 0); + } logging(LOG_VERBOSE, "Test GET_LBA_STATUS when medium is ejected."); ret = get_lba_status_nomedium(iscsic, tgt_lun, 0, 24); diff --git a/test-tool/test_readcapacity16_alloclen.c b/test-tool/test_readcapacity16_alloclen.c index 098bf40..ef57115 100644 --- a/test-tool/test_readcapacity16_alloclen.c +++ b/test-tool/test_readcapacity16_alloclen.c @@ -1,4 +1,3 @@ - /* Copyright (C) 2013 by Ronnie Sahlberg @@ -37,6 +36,11 @@ test_readcapacity16_alloclen(void) for (i = 0; i < 16; i++) { ret = readcapacity16(iscsic, tgt_lun, i); + if (sbc3_support && ret == -2) { + logging(LOG_NORMAL, "[FAILED] READCAPACITY16 is not available but the device claims SBC-3 support."); + CU_FAIL("READCAPACITY16 failed but the device claims SBC-3 support."); + return; + } CU_ASSERT_EQUAL(ret, 0); } } diff --git a/test-tool/test_readcapacity16_simple.c b/test-tool/test_readcapacity16_simple.c index 599d6f3..e9f7815 100644 --- a/test-tool/test_readcapacity16_simple.c +++ b/test-tool/test_readcapacity16_simple.c @@ -36,5 +36,15 @@ test_readcapacity16_simple(void) logging(LOG_VERBOSE, "Test that READCAPACITY16 works"); ret = readcapacity16(iscsic, tgt_lun, 16); + if (sbc3_support && ret == -2) { + logging(LOG_NORMAL, "[FAILED] READCAPACITY16 is not available but the device claims SBC-3 support."); + CU_FAIL("READCAPACITY16 failed but the device claims SBC-3 support."); + return; + } + if (!sbc3_support && ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] READCAPACITY16 is not implemented on this target and it does not claim SBC-3 support."); + CU_PASS("READCAPACITY16 is not implemented and no SBC-3 support claimed."); + return; + } CU_ASSERT_EQUAL(ret, 0); }