diff --git a/Makefile.am b/Makefile.am index 7f162bc..756544d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -153,7 +153,7 @@ bin_iscsi_test_SOURCES = test-tool/iscsi-test.c \ test-tool/1042_unsolicited_nonimmediate_data.c \ test-tool/1100_persistent_reserve_in_read_keys_simple.c \ test-tool/1110_persistent_reserve_in_serviceaction_range.c \ - test-tool/1120_persistent_reserve_out_clear_simple.c + test-tool/1120_persistent_register_simple.c endif diff --git a/include/scsi-lowlevel.h b/include/scsi-lowlevel.h index 8340746..2192d5a 100644 --- a/include/scsi-lowlevel.h +++ b/include/scsi-lowlevel.h @@ -718,7 +718,7 @@ struct scsi_persistent_reserve_in_read_keys { uint32_t prgeneration; uint32_t additional_length; - uint32_t num_keys; + int num_keys; uint64_t keys[0]; }; diff --git a/test-tool/1120_persistent_register_simple.c b/test-tool/1120_persistent_register_simple.c new file mode 100644 index 0000000..3689445 --- /dev/null +++ b/test-tool/1120_persistent_register_simple.c @@ -0,0 +1,226 @@ +/* + Copyright (C) 2012 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-test.h" + +int T1120_persistent_register_simple(const char *initiator, const char *url, int data_loss _U_, int show_info) +{ + struct iscsi_context *iscsi; + struct scsi_task *task; + struct scsi_persistent_reserve_out_basic poc; + struct scsi_persistent_reserve_in_read_keys *rk; + int ret, lun, i; + + printf("1120_persistent_register_simple:\n"); + printf("============================================\n"); + if (show_info) { + printf("Test basic PERSISTENT_RESERVE_OUT/REGISTER functionality.\n"); + printf("1, REGISTER with the target.\n"); + printf("2, Check READ_KEYS that the registration exists.\n"); + printf("3, Remove the registraion using REGISTER_AND_IGNORE_EXISTING_KEY\n"); + printf("4, Check READ_KEYS that the registration is gone.\n"); + printf("\n"); + return 0; + } + + iscsi = iscsi_context_login(initiator, url, &lun); + if (iscsi == NULL) { + printf("Failed to login to target\n"); + return -1; + } + + if (!data_loss) { + printf("--dataloss flag is not set. Skipping test\n"); + ret = -2; + goto finished; + } + + ret = 0; + + /* Register at the target */ + printf("Send PERSISTENT_RESERVE_OUT/REGISTER ... "); + poc.reservation_key = 0; + poc.service_action_reservation_key = 0x6C69626953435349LL; + poc.spec_i_pt = 0; + poc.all_tg_pt = 0; + poc.aptpl = 0; + task = iscsi_persistent_reserve_out_sync(iscsi, lun, + SCSI_PERSISTENT_RESERVE_REGISTER, + SCSI_PERSISTENT_RESERVE_SCOPE_LU, + SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE, + &poc); + if (task == NULL) { + printf("[FAILED]\n"); + printf("Failed to send PERSISTENT_RESERVE_OUT command: %s\n", iscsi_get_error(iscsi)); + ret = -1; + goto finished; + } + if (task->status == SCSI_STATUS_CHECK_CONDITION + && task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST + && task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE) { + printf("[SKIPPED]\n"); + printf("PERSISTENT_RESERVE_OUT Not Supported\n"); + ret = -2; + scsi_free_scsi_task(task); + goto finished; + } + if (task->status != SCSI_STATUS_GOOD) { + printf("[FAILED]\n"); + printf("PERSISTENT_RESERVE_OUT command: failed with sense. %s\n", iscsi_get_error(iscsi)); + ret = -1; + scsi_free_scsi_task(task); + goto finished; + } + scsi_free_scsi_task(task); + printf("[OK]\n"); + + + + /* Verify we can read the registration */ + printf("Check READ_KEYS that the registration exists ... "); + task = iscsi_persistent_reserve_in_sync(iscsi, lun, + SCSI_PERSISTENT_RESERVE_READ_KEYS, + 16384); + if (task == NULL) { + printf("[FAILED]\n"); + printf("Failed to send PERSISTENT_RESERVE_IN command: %s\n", iscsi_get_error(iscsi)); + ret = -1; + goto finished; + } + if (task->status != SCSI_STATUS_GOOD) { + printf("[FAILED]\n"); + printf("PERSISTENT_RESERVE_IN command: failed with sense. %s\n", iscsi_get_error(iscsi)); + ret = -1; + scsi_free_scsi_task(task); + goto finished; + } + rk = scsi_datain_unmarshall(task); + if (rk == NULL) { + printf("failed to unmarshall PERSISTENT_RESERVE_IN/READ_KEYS data. %s\n", iscsi_get_error(iscsi)); + ret = -1; + scsi_free_scsi_task(task); + goto finished; + } + /* verify we can see the key */ + for (i = 0; i < rk->num_keys; i++) { + if (rk->keys[i] == 0x6C69626953435349LL) { + break; + } + } + if (i == rk->num_keys) { + printf("[FAILED]\n"); + printf("Did not find registration in READ_KEYS data\n"); + ret = -1; + scsi_free_scsi_task(task); + goto finished; + } + scsi_free_scsi_task(task); + printf("[OK]\n"); + + + + /* Release from the target */ + printf("Remove the registration using REGISTER_AND_IGNORE_EXISTING_KEY ... "); + poc.reservation_key = 0; + poc.service_action_reservation_key = 0; + poc.spec_i_pt = 0; + poc.all_tg_pt = 0; + poc.aptpl = 0; + task = iscsi_persistent_reserve_out_sync(iscsi, lun, + SCSI_PERSISTENT_RESERVE_REGISTER_AND_IGNORE_EXISTING_KEY, + SCSI_PERSISTENT_RESERVE_SCOPE_LU, + SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE, + &poc); + if (task == NULL) { + printf("[FAILED]\n"); + printf("Failed to send PERSISTENT_RESERVE_OUT command: %s\n", iscsi_get_error(iscsi)); + ret = -1; + goto finished; + } + if (task->status == SCSI_STATUS_CHECK_CONDITION + && task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST + && task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE) { + printf("[SKIPPED]\n"); + printf("PERSISTENT_RESERVE_OUT Not Supported\n"); + ret = -2; + scsi_free_scsi_task(task); + goto finished; + } + if (task->status != SCSI_STATUS_GOOD) { + printf("[FAILED]\n"); + printf("PERSISTENT_RESERVE_OUT command: failed with sense. %s\n", iscsi_get_error(iscsi)); + ret = -1; + scsi_free_scsi_task(task); + goto finished; + } + scsi_free_scsi_task(task); + printf("[OK]\n"); + + + + /* Verify the registration is gone */ + printf("Check READ_KEYS that the registration is gone... "); + task = iscsi_persistent_reserve_in_sync(iscsi, lun, + SCSI_PERSISTENT_RESERVE_READ_KEYS, + 16384); + if (task == NULL) { + printf("[FAILED]\n"); + printf("Failed to send PERSISTENT_RESERVE_IN command: %s\n", iscsi_get_error(iscsi)); + ret = -1; + goto finished; + } + if (task->status != SCSI_STATUS_GOOD) { + printf("[FAILED]\n"); + printf("PERSISTENT_RESERVE_IN command: failed with sense. %s\n", iscsi_get_error(iscsi)); + ret = -1; + scsi_free_scsi_task(task); + goto finished; + } + rk = scsi_datain_unmarshall(task); + if (rk == NULL) { + printf("failed to unmarshall PERSISTENT_RESERVE_IN/READ_KEYS data. %s\n", iscsi_get_error(iscsi)); + ret = -1; + scsi_free_scsi_task(task); + goto finished; + } + /* verify we can see the key */ + for (i = 0; i < rk->num_keys; i++) { + if (rk->keys[i] == 0x6C69626953435349LL) { + break; + } + } + if (i != rk->num_keys) { + printf("[FAILED]\n"); + printf("Registration still remains in the READ_KEYS data\n"); + ret = -1; + scsi_free_scsi_task(task); + goto finished; + } + scsi_free_scsi_task(task); + printf("[OK]\n"); + + + +finished: + iscsi_logout_sync(iscsi); + iscsi_destroy_context(iscsi); + return ret; +} diff --git a/test-tool/1120_persistent_reserve_out_clear_simple.c b/test-tool/1120_persistent_reserve_out_clear_simple.c deleted file mode 100644 index a32297f..0000000 --- a/test-tool/1120_persistent_reserve_out_clear_simple.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - Copyright (C) 2012 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-test.h" - -int T1120_persistent_reserve_out_clear_simple(const char *initiator, const char *url, int data_loss _U_, int show_info) -{ - struct iscsi_context *iscsi; - struct scsi_task *task; - struct scsi_persistent_reserve_out_basic poc; - int ret, lun; - - printf("1120_persistent_reserve_out_clear_simple:\n"); - printf("============================================\n"); - if (show_info) { - printf("Test basic PERSISTENT_RESERVE_OUT/CLEAR functionality.\n"); - printf("1, Verify that CLEAR works.\n"), - printf("\n"); - return 0; - } - - iscsi = iscsi_context_login(initiator, url, &lun); - if (iscsi == NULL) { - printf("Failed to login to target\n"); - return -1; - } - - if (!data_loss) { - printf("--dataloss flag is not set. Skipping test\n"); - ret = -2; - goto finished; - } - - ret = 0; - - /* Verify that PERSISTENT_RESERVE_OUT/CLEAR works */ - printf("Send PERSISTENT_RESERVE_OUT/CLEAR ... "); - poc.reservation_key = 1L; - poc.service_action_reservation_key = 2L; - poc.spec_i_pt = 0; - poc.all_tg_pt = 1; - poc.aptpl = 1; - task = iscsi_persistent_reserve_out_sync(iscsi, lun, - SCSI_PERSISTENT_RESERVE_CLEAR, - SCSI_PERSISTENT_RESERVE_SCOPE_LU, - SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE, - &poc); - if (task == NULL) { - printf("[FAILED]\n"); - printf("Failed to send PERSISTENT_RESERVE_OUT command: %s\n", iscsi_get_error(iscsi)); - ret = -1; - goto finished; - } - if (task->status == SCSI_STATUS_CHECK_CONDITION - && task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST - && task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE) { - printf("[SKIPPED]\n"); - printf("PERSISTENT_RESERVE_OUT Not Supported\n"); - ret = -2; - scsi_free_scsi_task(task); - goto finished; - } - if (task->status != SCSI_STATUS_GOOD) { - printf("[FAILED]\n"); - printf("PERSISTENT_RESERVE_OUT command: failed with sense. %s\n", iscsi_get_error(iscsi)); - ret = -1; - scsi_free_scsi_task(task); - goto finished; - } - scsi_free_scsi_task(task); - printf("[OK]\n"); - - - -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 cb587bd..fb50bdc 100644 --- a/test-tool/iscsi-test.c +++ b/test-tool/iscsi-test.c @@ -256,7 +256,7 @@ struct scsi_test tests[] = { /* PERSISTENT_RESERVE_IN */ { "T1100_persistent_reserve_in_read_keys_simple", T1100_persistent_reserve_in_read_keys_simple }, { "T1110_persistent_reserve_in_serviceaction_range", T1110_persistent_reserve_in_serviceaction_range }, -{ "T1120_persistent_reserve_out_clear_simple", T1120_persistent_reserve_out_clear_simple }, +{ "T1120_persistent_register_simple", T1120_persistent_register_simple }, { NULL, NULL } }; diff --git a/test-tool/iscsi-test.h b/test-tool/iscsi-test.h index 33e3263..c7d4837 100644 --- a/test-tool/iscsi-test.h +++ b/test-tool/iscsi-test.h @@ -187,4 +187,4 @@ int T1041_unsolicited_immediate_data(const char *initiator, const char *url, int int T1042_unsolicited_nonimmediate_data(const char *initiator, const char *url, int data_loss, int show_info); int T1100_persistent_reserve_in_read_keys_simple(const char *initiator, const char *url, int data_loss, int show_info); int T1110_persistent_reserve_in_serviceaction_range(const char *initiator, const char *url, int data_loss, int show_info); -int T1120_persistent_reserve_out_clear_simple(const char *initiator, const char *url, int data_loss, int show_info); +int T1120_persistent_register_simple(const char *initiator, const char *url, int data_loss, int show_info);