diff --git a/Makefile.am b/Makefile.am index 61cfaba..cd09c2b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -277,6 +277,7 @@ bin_iscsi_test_cu_SOURCES = test-tool/iscsi-test-cu.c \ test-tool/test_sanitize_invalid_serviceaction.c \ test-tool/test_sanitize_overwrite.c \ test-tool/test_sanitize_overwrite_reserved.c \ + test-tool/test_sanitize_reservations.c \ test-tool/test_startstopunit_simple.c \ test-tool/test_startstopunit_pwrcnd.c \ test-tool/test_startstopunit_noloej.c \ diff --git a/test-tool/iscsi-support.c b/test-tool/iscsi-support.c index 498e481..a8a048a 100644 --- a/test-tool/iscsi-support.c +++ b/test-tool/iscsi-support.c @@ -1401,6 +1401,33 @@ int sanitize_invalidfieldincdb(struct iscsi_context *iscsi, int lun, int immed, return 0; } +int sanitize_conflict(struct iscsi_context *iscsi, int lun, int immed, int ause, int sa, int param_len, struct iscsi_data *data) +{ + struct scsi_task *task; + + logging(LOG_VERBOSE, "Send SANITIZE (Expecting RESERVATION_CONFLICT) " + "IMMED:%d AUSE:%d SA:%d " + "PARAM_LEN:%d", + immed, ause, sa, param_len); + + task = iscsi_sanitize_sync(iscsi, lun, immed, ause, sa, param_len, + data); + if (task == NULL) { + logging(LOG_NORMAL, + "[FAILED] Failed to send SANITIZE command: %s", + iscsi_get_error(iscsi)); + return -1; + } + if (task->status != SCSI_STATUS_RESERVATION_CONFLICT) { + logging(LOG_NORMAL, "[FAILED] Expected RESERVATION CONFLICT"); + return -1; + } + + scsi_free_scsi_task(task); + logging(LOG_VERBOSE, "[OK] SANITIZE returned RESERVATION_CONFLICT."); + return 0; +} + int startstopunit(struct iscsi_context *iscsi, int lun, int immed, int pcm, int pc, int no_flush, int loej, int start) { struct scsi_task *task; diff --git a/test-tool/iscsi-support.h b/test-tool/iscsi-support.h index 7922f2f..3472fc8 100644 --- a/test-tool/iscsi-support.h +++ b/test-tool/iscsi-support.h @@ -266,6 +266,7 @@ int release6(struct iscsi_context *iscsi, int lun); int reserve6(struct iscsi_context *iscsi, int lun); int reserve6_conflict(struct iscsi_context *iscsi, int lun); int sanitize(struct iscsi_context *iscsi, int lun, int immed, int ause, int sa, int param_len, struct iscsi_data *data); +int sanitize_conflict(struct iscsi_context *iscsi, int lun, int immed, int ause, int sa, int param_len, struct iscsi_data *data); int sanitize_invalidfieldincdb(struct iscsi_context *iscsi, int lun, int immed, int ause, int sa, int param_len, struct iscsi_data *data); int startstopunit(struct iscsi_context *iscsi, int lun, int immed, int pcm, int pc, int no_flush, int loej, int start); int startstopunit_preventremoval(struct iscsi_context *iscsi, int lun, int immed, int pcm, int pc, int no_flush, int loej, int start); diff --git a/test-tool/iscsi-test-cu.c b/test-tool/iscsi-test-cu.c index f2d2280..ac27582 100644 --- a/test-tool/iscsi-test-cu.c +++ b/test-tool/iscsi-test-cu.c @@ -235,6 +235,7 @@ static CU_TestInfo tests_sanitize[] = { { (char *)"InvalidServiceAction", test_sanitize_invalid_serviceaction }, { (char *)"Overwrite", test_sanitize_overwrite }, { (char *)"OverwriteReserved", test_sanitize_overwrite_reserved }, + { (char *)"Reservations", test_sanitize_reservations }, CU_TEST_INFO_NULL }; diff --git a/test-tool/iscsi-test-cu.h b/test-tool/iscsi-test-cu.h index e25c1ba..70e081c 100644 --- a/test-tool/iscsi-test-cu.h +++ b/test-tool/iscsi-test-cu.h @@ -161,6 +161,7 @@ void test_sanitize_exit_failure_mode(void); void test_sanitize_invalid_serviceaction(void); void test_sanitize_overwrite(void); void test_sanitize_overwrite_reserved(void); +void test_sanitize_reservations(void); void test_startstopunit_simple(void); void test_startstopunit_pwrcnd(void); diff --git a/test-tool/test_sanitize_block_erase.c b/test-tool/test_sanitize_block_erase.c index b4bfa82..8231fe3 100644 --- a/test-tool/test_sanitize_block_erase.c +++ b/test-tool/test_sanitize_block_erase.c @@ -255,7 +255,7 @@ test_sanitize_block_erase(void) CHECK_FOR_SANITIZE; CHECK_FOR_DATALOSS; - logging(LOG_NORMAL, "Check that SANITIZE BLOCK_ERASE is supported " + logging(LOG_VERBOSE, "Check that SANITIZE BLOCK_ERASE is supported " "in REPORT_SUPPORTED_OPCODES"); cd = get_command_descriptor(SCSI_OPCODE_SANITIZE, SCSI_SANITIZE_BLOCK_ERASE); diff --git a/test-tool/test_sanitize_crypto_erase.c b/test-tool/test_sanitize_crypto_erase.c index c7ad5a8..2547def 100644 --- a/test-tool/test_sanitize_crypto_erase.c +++ b/test-tool/test_sanitize_crypto_erase.c @@ -142,7 +142,7 @@ test_sanitize_crypto_erase(void) CHECK_FOR_SANITIZE; CHECK_FOR_DATALOSS; - logging(LOG_NORMAL, "Check that SANITIZE CRYPTO_ERASE is supported " + logging(LOG_VERBOSE, "Check that SANITIZE CRYPTO_ERASE is supported " "in REPORT_SUPPORTED_OPCODES"); cd = get_command_descriptor(SCSI_OPCODE_SANITIZE, SCSI_SANITIZE_CRYPTO_ERASE); diff --git a/test-tool/test_sanitize_exit_failure_mode.c b/test-tool/test_sanitize_exit_failure_mode.c index 511f847..e950958 100644 --- a/test-tool/test_sanitize_exit_failure_mode.c +++ b/test-tool/test_sanitize_exit_failure_mode.c @@ -39,7 +39,7 @@ test_sanitize_exit_failure_mode(void) CHECK_FOR_SANITIZE; CHECK_FOR_DATALOSS; - logging(LOG_NORMAL, "Check that SANITIZE EXIT FAILURE MODE is " + logging(LOG_VERBOSE, "Check that SANITIZE EXIT FAILURE MODE is " "supported in REPORT_SUPPORTED_OPCODES"); cd = get_command_descriptor(SCSI_OPCODE_SANITIZE, SCSI_SANITIZE_EXIT_FAILURE_MODE); diff --git a/test-tool/test_sanitize_overwrite.c b/test-tool/test_sanitize_overwrite.c index 2c6100d..9f41e87 100644 --- a/test-tool/test_sanitize_overwrite.c +++ b/test-tool/test_sanitize_overwrite.c @@ -75,7 +75,7 @@ test_sanitize_overwrite(void) CHECK_FOR_SANITIZE; CHECK_FOR_DATALOSS; - logging(LOG_NORMAL, "Check that SANITIZE OVERWRITE is supported " + logging(LOG_VERBOSE, "Check that SANITIZE OVERWRITE is supported " "in REPORT_SUPPORTED_OPCODES"); cd = get_command_descriptor(SCSI_OPCODE_SANITIZE, SCSI_SANITIZE_OVERWRITE); diff --git a/test-tool/test_sanitize_reservations.c b/test-tool/test_sanitize_reservations.c new file mode 100644 index 0000000..1fdfd0e --- /dev/null +++ b/test-tool/test_sanitize_reservations.c @@ -0,0 +1,113 @@ +/* + Copyright (C) 2013 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 +#include + +#include + +#include "iscsi.h" +#include "scsi-lowlevel.h" +#include "iscsi-test-cu.h" + +void +test_sanitize_reservations(void) +{ + int ret; + struct iscsi_data data; + struct scsi_command_descriptor *cd; + + logging(LOG_VERBOSE, LOG_BLANK_LINE); + logging(LOG_VERBOSE, "Test SANITIZE with RESERVATIONS"); + + CHECK_FOR_SANITIZE; + CHECK_FOR_DATALOSS; + + logging(LOG_VERBOSE, "Create a second connection to the target"); + iscsic2 = iscsi_context_login(initiatorname1, tgt_url, &tgt_lun); + if (iscsic2 == NULL) { + logging(LOG_VERBOSE, "Failed to login to target"); + return; + } + + logging(LOG_VERBOSE, "Take out a RESERVE6 from the second " + "initiator"); + ret = reserve6(iscsic2, tgt_lun); + CU_ASSERT_EQUAL(ret, 0); + + + logging(LOG_VERBOSE, "Check if SANITIZE OVERWRITE is supported " + "in REPORT_SUPPORTED_OPCODES"); + cd = get_command_descriptor(SCSI_OPCODE_SANITIZE, + SCSI_SANITIZE_OVERWRITE); + if (cd == NULL) { + logging(LOG_NORMAL, "[SKIPPED] SANITIZE OVERWRITE is not " + "implemented according to REPORT_SUPPORTED_OPCODES."); + return; + } else { + logging(LOG_VERBOSE, "Test SANITIZE OVERWRITE with " + "initialization pattern of one full block"); + data.size = block_size + 4; + data.data = alloca(data.size); + memset(&data.data[4], 0xaa, block_size); + + data.data[0] = 0x01; + data.data[1] = 0x00; + data.data[2] = block_size >> 8; + data.data[3] = block_size & 0xff; + ret = sanitize_conflict(iscsic, tgt_lun, + 0, 0, SCSI_SANITIZE_OVERWRITE, data.size, &data); + CU_ASSERT_EQUAL(ret, 0); + } + + + logging(LOG_VERBOSE, "Check if SANITIZE BLOCK_ERASE is supported " + "in REPORT_SUPPORTED_OPCODES"); + cd = get_command_descriptor(SCSI_OPCODE_SANITIZE, + SCSI_SANITIZE_BLOCK_ERASE); + if (cd == NULL) { + logging(LOG_NORMAL, "[SKIPPED] SANITIZE BLOCK_ERASE is not " + "implemented according to REPORT_SUPPORTED_OPCODES."); + return; + } else { + logging(LOG_VERBOSE, "Test SANITIZE BLOCK_ERASE"); + ret = sanitize_conflict(iscsic, tgt_lun, + 0, 0, SCSI_SANITIZE_BLOCK_ERASE, 0, NULL); + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Check if SANITIZE CRYPTO_ERASE is supported " + "in REPORT_SUPPORTED_OPCODES"); + cd = get_command_descriptor(SCSI_OPCODE_SANITIZE, + SCSI_SANITIZE_CRYPTO_ERASE); + if (cd == NULL) { + logging(LOG_NORMAL, "[SKIPPED] SANITIZE CRYPTO_ERASE is not " + "implemented according to REPORT_SUPPORTED_OPCODES."); + return; + } else { + logging(LOG_VERBOSE, "Test SANITIZE CRYPTO_ERASE"); + ret = sanitize_conflict(iscsic, tgt_lun, + 0, 0, SCSI_SANITIZE_CRYPTO_ERASE, 0, NULL); + CU_ASSERT_EQUAL(ret, 0); + } + + + iscsi_destroy_context(iscsic2); + iscsic2 = NULL; +}