diff --git a/Makefile.am b/Makefile.am index 26b0653..623a948 100644 --- a/Makefile.am +++ b/Makefile.am @@ -134,6 +134,7 @@ bin_iscsi_test_SOURCES = test-tool/iscsi-test.c \ test-tool/0403_inquiry_supported_vpd.c \ test-tool/0404_inquiry_all_reported_vpd.c \ test-tool/0410_readtoc_basic.c \ + test-tool/0420_reserve6_simple.c \ \ test-tool/1000_cmdsn_invalid.c \ test-tool/1010_datasn_invalid.c \ diff --git a/test-tool/0420_reserve6_simple.c b/test-tool/0420_reserve6_simple.c new file mode 100644 index 0000000..68f27bd --- /dev/null +++ b/test-tool/0420_reserve6_simple.c @@ -0,0 +1,268 @@ +/* + Copyright (C) 2012 by Jon Grimm + + 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 "iscsi.h" +#include "scsi-lowlevel.h" +#include "iscsi-test.h" + +int T0420_reserve6_simple(const char *initiator, const char *url, int data_loss, int show_info) +{ + struct iscsi_context *iscsi, *iscsi2; + struct scsi_task *task; + int ret, lun; + + printf("0420_reserve6_simple:\n"); + printf("===================\n"); + if (show_info) { + printf("Test RESERVE6/RELEASE6 commands if supported.\n"); + printf(" If device does not support, just verify appropriate error returned\n"); + printf("1. Test simple RESERVE6 followed by RELEASE6\n"); + printf("2. Test Initator 1 can reserve if already reserved by Intiator 1.\n"); + printf("3. Test Initiator 2 can't reserve if already reserved by Initiator 1.\n"); + printf("4. Test Initiator 1 can testunitready if reserved by Initiator 1.\n"); + printf("5. Test Initiator 2 can't testunitready if reserved by Initiator 1.\n"); + printf("6. Test Initiator 2 can get reservation once Intiator 1 releases reservation.\n"); + + printf("\n"); + return 0; + } + + iscsi = iscsi_context_login(initiator, url, &lun); + if (iscsi == NULL) { + printf("Failed to login to target\n"); + return -1; + } + + iscsi2 = iscsi_context_login(initiator, url, &lun); + if (iscsi2 == NULL) { + printf("Failed to login to target\n"); + return -1; + } + + ret = 0; + + printf("Send RESERVE6...\n"); + task = iscsi_reserve6_sync(iscsi, lun); + if (task == NULL) { + printf("[FAILED]\n"); + printf("Failed to send RESERVE6 command : %s\n", + iscsi_get_error(iscsi)); + ret = -1; + goto finished; + } + if (task->status != SCSI_STATUS_GOOD) { + printf("[FAILED]\n"); + printf("RESERVE6 command failed : %s\n", + iscsi_get_error(iscsi)); + scsi_free_scsi_task(task); + ret = -1; + goto finished; + } + + printf("[OK]\n"); + printf("Send RELEASE6...\n"); + task = iscsi_release6_sync(iscsi, lun); + if (task == NULL) { + printf("[FAILED]\n"); + printf("Failed to send RELEASE6 command : %s\n", + iscsi_get_error(iscsi)); + ret = -1; + goto finished; + } + if (task->status != SCSI_STATUS_GOOD) { + printf("[FAILED]\n"); + printf("RELEASE6 command failed : %s\n", + iscsi_get_error(iscsi)); + scsi_free_scsi_task(task); + ret = -1; + goto finished; + } + + printf("[OK]\n"); + +test2: + printf("Test that reservation works.\n"); + printf("Send RESERVE6 from Initiator 1...\n"); + task = iscsi_reserve6_sync(iscsi, lun); + if (task == NULL) { + printf("[FAILED]\n"); + printf("Failed to send RESERVE6 command : %s\n", + iscsi_get_error(iscsi)); + ret = -1; + goto finished; + } + if (task->status != SCSI_STATUS_GOOD) { + printf("[FAILED]\n"); + printf("RESERVE6 command failed : %s\n", + iscsi_get_error(iscsi)); + scsi_free_scsi_task(task); + ret = -1; + goto finished; + } + + printf("[OK]\n"); + + printf("Send RESERVE6 from Initiator 1...\n"); + task = iscsi_reserve6_sync(iscsi, lun); + if (task == NULL) { + printf("[FAILED]\n"); + printf("Failed to send RESERVE6 command : %s\n", + iscsi_get_error(iscsi)); + ret = -1; + goto finished; + } + if (task->status != SCSI_STATUS_GOOD) { + printf("[FAILED]\n"); + printf("RESERVE6 command failed : %s\n", + iscsi_get_error(iscsi)); + scsi_free_scsi_task(task); + ret = -1; + goto finished; + } + + printf("[OK]\n"); +test3: + printf("Send RESERVE6 from Initiator 2...Expect conflict.\n"); + task = iscsi_reserve6_sync(iscsi2, lun); + if (task == NULL) { + printf("[FAILED]\n"); + printf("Failed to send RESERVE6 command : %s\n", + iscsi_get_error(iscsi)); + ret = -1; + goto finished; + } + /* We expect this command to fail for the test to pass. */ + if (task->status != SCSI_STATUS_RESERVATION_CONFLICT) { + printf("[FAILED]\n"); + printf("Expected RESERVATION CONFLICT\n"); + scsi_free_scsi_task(task); + ret = -1; + goto finished; + } + + printf("[OK]\n"); +test4: + printf("Send TESTUNITREADY from Initiator 1...\n"); + task = iscsi_testunitready_sync(iscsi, lun); + if (task == NULL) { + printf("[FAILED]\n"); + printf("Failed to send TEST UNIT READY command: %s\n", + iscsi_get_error(iscsi)); + ret = -1; + goto finished; + } + if (task->status != SCSI_STATUS_GOOD) { + printf("[FAILED]\n"); + printf("TEST UNIT READY command: failed with sense %s\n", + iscsi_get_error(iscsi)); + scsi_free_scsi_task(task); + ret = -1; + goto finished; + } + printf("[OK]\n"); + +test5: + + printf("Send TESTUNITREADY from Initiator 2...Expect conflict.\n"); + task = iscsi_testunitready_sync(iscsi2, lun); + if (task == NULL) { + printf("[FAILED]\n"); + printf("Failed to send TEST UNIT READY command: %s\n", + iscsi_get_error(iscsi2)); + ret = -1; + goto finished; + } + if (task->status != SCSI_STATUS_RESERVATION_CONFLICT) { + printf("[FAILED]\n"); + printf("Expected RESERVATION CONFLICT\n"); + scsi_free_scsi_task(task); + ret = -1; + goto finished; + } + printf("[OK]\n"); + +test6: + printf("Test that release actually works\n"); + printf("Send RELEASE6 from Initiator 1...\n"); + task = iscsi_release6_sync(iscsi, lun); + if (task == NULL) { + printf("[FAILED]\n"); + printf("Failed to send RELEASE6 command : %s\n", + iscsi_get_error(iscsi)); + ret = -1; + goto finished; + } + if (task->status != SCSI_STATUS_GOOD) { + printf("[FAILED]\n"); + printf("RELEASE6 command failed : %s\n", + iscsi_get_error(iscsi)); + scsi_free_scsi_task(task); + ret = -1; + goto finished; + } + + printf("[OK]\n"); + + printf("Send RESERVE6 Initiator 2...\n"); + task = iscsi_reserve6_sync(iscsi2, lun); + if (task == NULL) { + printf("[FAILED]\n"); + printf("Failed to send RESERVE6 command : %s\n", + iscsi_get_error(iscsi)); + ret = -1; + goto finished; + } + if (task->status != SCSI_STATUS_GOOD) { + printf("[FAILED]\n"); + printf("RESERVE6 command failed : %s\n", + iscsi_get_error(iscsi)); + scsi_free_scsi_task(task); + ret = -1; + goto finished; + } + printf("[OK]\n"); + + printf("Send RELEASE6 Initiator 2...\n"); + task = iscsi_reserve6_sync(iscsi2, lun); + if (task == NULL) { + printf("[FAILED]\n"); + printf("Failed to send RELEASE6 command : %s\n", + iscsi_get_error(iscsi)); + ret = -1; + goto finished; + } + if (task->status != SCSI_STATUS_GOOD) { + printf("[FAILED]\n"); + printf("RELEASE6 command failed : %s\n", + iscsi_get_error(iscsi)); + scsi_free_scsi_task(task); + ret = -1; + goto finished; + } + + printf("[OK]\n"); + + scsi_free_scsi_task(task); + +finished: + iscsi_logout_sync(iscsi); + iscsi_destroy_context(iscsi); + return ret; +} diff --git a/test-tool/iscsi-test.c b/test-tool/iscsi-test.c index 147d129..b70e440 100644 --- a/test-tool/iscsi-test.c +++ b/test-tool/iscsi-test.c @@ -214,6 +214,9 @@ struct scsi_test tests[] = { /* read TOC/PMA/ATIP */ { "T0410_readtoc_basic", T0410_readtoc_basic }, +/* reserve6/release6 */ +{ "T0420_reserve6_simple", T0420_reserve6_simple }, + /* iSCSI protocol tests */ /* invalid cmdsn from initiator */ diff --git a/test-tool/iscsi-test.h b/test-tool/iscsi-test.h index f45cca5..db25234 100644 --- a/test-tool/iscsi-test.h +++ b/test-tool/iscsi-test.h @@ -166,6 +166,8 @@ int T0404_inquiry_all_reported_vpd(const char *initiator, const char *url, int d int T0410_readtoc_basic(const char *initiator, const char *url, int data_loss, int show_info); +int T0420_reserve6_simple(const char *initiator, const char *url, int data_loss, int show_info); + int T1000_cmdsn_invalid(const char *initiator, const char *url, int data_loss, int show_info); int T1010_datasn_invalid(const char *initiator, const char *url, int data_loss, int show_info); int T1020_bufferoffset_invalid(const char *initiator, const char *url, int data_loss, int show_info);