diff --git a/Makefile.am b/Makefile.am index 5913800..bda3dbe 100644 --- a/Makefile.am +++ b/Makefile.am @@ -258,7 +258,8 @@ bin_iscsi_test_cu_SOURCES = test-tool/iscsi-test-cu.c \ test-tool/test_writesame16_wrprotect.c \ test-tool/test_writesame16_unmap.c \ test-tool/test_writesame16_unmap_unaligned.c \ - test-tool/test_writesame16_unmap_until_end.c + test-tool/test_writesame16_unmap_until_end.c \ + test-tool/test_prin_read_keys_simple.c endif diff --git a/test-tool/iscsi-support.c b/test-tool/iscsi-support.c index fe9a83c..17a2d26 100644 --- a/test-tool/iscsi-support.c +++ b/test-tool/iscsi-support.c @@ -183,6 +183,57 @@ iscsi_queue_pdu(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) return real_iscsi_queue_pdu(iscsi, pdu); } +int +prin_read_keys(struct iscsi_context *iscsi, int lun, struct scsi_task **tp, + struct scsi_persistent_reserve_in_read_keys **rkp) +{ + const int buf_sz = 16384; + struct scsi_persistent_reserve_in_read_keys *rk = NULL; + struct scsi_task *task; + + + logging(LOG_VERBOSE, "Send PRIN/READ_KEYS"); + + task = iscsi_persistent_reserve_in_sync(iscsi, lun, + SCSI_PERSISTENT_RESERVE_READ_KEYS, buf_sz); + if (task == NULL) { + logging(LOG_NORMAL, + "[FAILED] Failed to send PRIN command: %s", + iscsi_get_error(iscsi)); + return -1; + } + if (tp != NULL) + *tp = task; + + if (task->status != SCSI_STATUS_GOOD) { + logging(LOG_NORMAL, + "[FAILED] PRIN command: failed with sense. %s", + iscsi_get_error(iscsi)); + if (tp == NULL) + scsi_free_scsi_task(task); + return -1; + } + + rk = scsi_datain_unmarshall(task); + if (rk == NULL) { + logging(LOG_NORMAL, + "[FAIL] failed to unmarshall PRIN/READ_KEYS data. %s", + iscsi_get_error(iscsi)); + if (tp == NULL) + scsi_free_scsi_task(task); + return -1; + } + if (rkp != NULL) + *rkp = rk; + + /* clean up if we are managing our own task */ + if (tp == NULL) + scsi_free_scsi_task(task); + + return 0; +} + + int register_and_ignore(struct iscsi_context *iscsi, int lun, unsigned long long sark) diff --git a/test-tool/iscsi-support.h b/test-tool/iscsi-support.h index fa79c03..520bf95 100644 --- a/test-tool/iscsi-support.h +++ b/test-tool/iscsi-support.h @@ -127,7 +127,6 @@ struct iscsi_pdu; int (*local_iscsi_queue_pdu)(struct iscsi_context *iscsi, struct iscsi_pdu *pdu); - /* * PGR support */ @@ -159,6 +158,9 @@ static inline int pr_type_is_all_registrants( } } +int prin_read_keys(struct iscsi_context *iscsi, int lun, struct scsi_task **tp, + struct scsi_persistent_reserve_in_read_keys **rkp); + int register_and_ignore(struct iscsi_context *iscsi, int lun, unsigned long long key); int register_key(struct iscsi_context *iscsi, int lun, diff --git a/test-tool/iscsi-test-cu.c b/test-tool/iscsi-test-cu.c index 4815ae3..10ca8f9 100644 --- a/test-tool/iscsi-test-cu.c +++ b/test-tool/iscsi-test-cu.c @@ -215,6 +215,11 @@ static CU_TestInfo tests_writesame16[] = { CU_TEST_INFO_NULL }; +static CU_TestInfo tests_prin_read_keys[] = { + { (char *)"testPrinReadKeysSimple", test_prin_read_keys_simple }, + CU_TEST_INFO_NULL +}; + static CU_SuiteInfo suites[] = { { (char *)"TestPrefetch10", test_setup, test_teardown, tests_prefetch10 }, @@ -252,6 +257,8 @@ static CU_SuiteInfo suites[] = { tests_writesame10 }, { (char *)"TestWriteSame16", test_setup, test_teardown, tests_writesame16 }, + { (char *)"TestPrinReadKeys", test_setup, test_teardown, + tests_prin_read_keys }, CU_SUITE_INFO_NULL }; diff --git a/test-tool/iscsi-test-cu.h b/test-tool/iscsi-test-cu.h index 425d985..a240f17 100644 --- a/test-tool/iscsi-test-cu.h +++ b/test-tool/iscsi-test-cu.h @@ -138,4 +138,6 @@ void test_writesame16_unmap(void); void test_writesame16_unmap_unaligned(void); void test_writesame16_unmap_until_end(void); +void test_prin_read_keys_simple(void); + #endif /* _ISCSI_TEST_CU_H_ */ diff --git a/test-tool/test_prin_read_keys_simple.c b/test-tool/test_prin_read_keys_simple.c new file mode 100644 index 0000000..75870ea --- /dev/null +++ b/test-tool/test_prin_read_keys_simple.c @@ -0,0 +1,57 @@ +/* + Copyright (C) 2013 by Lee Duncan + + 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-support.h" +#include "iscsi-test-cu.h" + + +void +test_prin_read_keys_simple(void) +{ + int ret = 0; + int al; + + + logging(LOG_VERBOSE, ""); + logging(LOG_VERBOSE, "Test Persistent Reserve IN READ_KEYS works."); + + ret = prin_read_keys(iscsic, tgt_lun, &task, NULL); + CU_ASSERT_EQUAL(ret, 0); + + logging(LOG_VERBOSE, "Test DATA-IN is at least 8 bytes."); + if (task->datain.size < 8) { + logging(LOG_NORMAL, + "[FAILED] DATA-IN returned less than 8 bytes"); + return; + } + + logging(LOG_VERBOSE, "Test ADDITIONAL_LENGTH matches DATA_IN size."); + al = ntohl(*(uint32_t *)&task->datain.data[4]); + if (al != task->datain.size - 8) { + logging(LOG_NORMAL, + "[FAILED] ADDITIONAL_LENGTH was %d bytes but %d was expected.", + al, task->datain.size - 8); + return; + } +}