Tests: convert tabs to 8 spaces

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
This commit is contained in:
Ronnie Sahlberg
2016-02-21 16:17:18 -08:00
parent 5a80c7b581
commit b4320bd76c
215 changed files with 13344 additions and 13344 deletions

View File

@@ -54,338 +54,338 @@ struct scsi_device *mp_sds[MPATH_MAX_DEVS];
static void static void
mpath_des_free(struct scsi_inquiry_device_designator *des) mpath_des_free(struct scsi_inquiry_device_designator *des)
{ {
if (!des) { if (!des) {
return; return;
} }
free(des->designator); free(des->designator);
free(des); free(des);
} }
static int static int
mpath_des_copy(struct scsi_inquiry_device_designator *des, mpath_des_copy(struct scsi_inquiry_device_designator *des,
struct scsi_inquiry_device_designator **_des_cp) struct scsi_inquiry_device_designator **_des_cp)
{ {
struct scsi_inquiry_device_designator *des_cp; struct scsi_inquiry_device_designator *des_cp;
if (!_des_cp) { if (!_des_cp) {
return -1; return -1;
} }
des_cp = malloc(sizeof(*des_cp)); des_cp = malloc(sizeof(*des_cp));
if (des_cp == NULL) { if (des_cp == NULL) {
return -1; return -1;
} }
des_cp->protocol_identifier = des->protocol_identifier; des_cp->protocol_identifier = des->protocol_identifier;
des_cp->code_set = des->code_set; des_cp->code_set = des->code_set;
des_cp->piv = des->piv; des_cp->piv = des->piv;
des_cp->association = des->association; des_cp->association = des->association;
des_cp->designator_type = des->designator_type; des_cp->designator_type = des->designator_type;
des_cp->designator_length = des->designator_length; des_cp->designator_length = des->designator_length;
des_cp->designator = malloc(des->designator_length); des_cp->designator = malloc(des->designator_length);
if (des_cp->designator == NULL) { if (des_cp->designator == NULL) {
free(des_cp); free(des_cp);
return -1; return -1;
} }
memcpy(des_cp->designator, des->designator, des->designator_length); memcpy(des_cp->designator, des->designator, des->designator_length);
*_des_cp = des_cp; *_des_cp = des_cp;
return 0; return 0;
} }
static int static int
mpath_des_cmp(struct scsi_inquiry_device_designator *des1, mpath_des_cmp(struct scsi_inquiry_device_designator *des1,
struct scsi_inquiry_device_designator *des2) struct scsi_inquiry_device_designator *des2)
{ {
if (des1->protocol_identifier != des2->protocol_identifier) { if (des1->protocol_identifier != des2->protocol_identifier) {
return -1; return -1;
} }
if (des1->code_set != des2->code_set) { if (des1->code_set != des2->code_set) {
return -1; return -1;
} }
if (des1->piv != des2->piv) { if (des1->piv != des2->piv) {
return -1; return -1;
} }
if (des1->association != des2->association) { if (des1->association != des2->association) {
return -1; return -1;
} }
if (des1->designator_type != des2->designator_type) { if (des1->designator_type != des2->designator_type) {
return -1; return -1;
} }
if (des1->designator_length != des2->designator_length) { if (des1->designator_length != des2->designator_length) {
return -1; return -1;
} }
return memcmp(des1->designator, des2->designator, return memcmp(des1->designator, des2->designator,
des1->designator_length); des1->designator_length);
} }
static int static int
mpath_check_matching_ids_devid_vpd(int num_sds, mpath_check_matching_ids_devid_vpd(int num_sds,
struct scsi_device **sds) struct scsi_device **sds)
{ {
int i; int i;
int num_sds_with_valid_id = 0; int num_sds_with_valid_id = 0;
struct scsi_task *inq_task = NULL; struct scsi_task *inq_task = NULL;
struct scsi_inquiry_device_designator *des_saved = NULL; struct scsi_inquiry_device_designator *des_saved = NULL;
for (i = 0; i < num_sds; i++) { for (i = 0; i < num_sds; i++) {
int ret; int ret;
int full_size; int full_size;
struct scsi_inquiry_device_identification *inq_id_data; struct scsi_inquiry_device_identification *inq_id_data;
struct scsi_inquiry_device_designator *des; struct scsi_inquiry_device_designator *des;
/* /*
* dev ID inquiry to confirm that all multipath devices carry * dev ID inquiry to confirm that all multipath devices carry
* an identical logical unit identifier. * an identical logical unit identifier.
*/ */
inquiry(sds[i], &inq_task, 1, inquiry(sds[i], &inq_task, 1,
SCSI_INQUIRY_PAGECODE_DEVICE_IDENTIFICATION, SCSI_INQUIRY_PAGECODE_DEVICE_IDENTIFICATION,
64, 64,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
if (inq_task == NULL || inq_task->status != SCSI_STATUS_GOOD) { if (inq_task == NULL || inq_task->status != SCSI_STATUS_GOOD) {
printf("Inquiry command failed : %s\n", printf("Inquiry command failed : %s\n",
sds[i]->error_str); sds[i]->error_str);
goto err_cleanup; goto err_cleanup;
} }
full_size = scsi_datain_getfullsize(inq_task); full_size = scsi_datain_getfullsize(inq_task);
if (full_size > inq_task->datain.size) { if (full_size > inq_task->datain.size) {
/* we need more data */ /* we need more data */
scsi_free_scsi_task(inq_task); scsi_free_scsi_task(inq_task);
inq_task = NULL; inq_task = NULL;
inquiry(sds[i], &inq_task, 1, inquiry(sds[i], &inq_task, 1,
SCSI_INQUIRY_PAGECODE_DEVICE_IDENTIFICATION, SCSI_INQUIRY_PAGECODE_DEVICE_IDENTIFICATION,
full_size, full_size,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
if (inq_task == NULL) { if (inq_task == NULL) {
printf("Inquiry command failed : %s\n", printf("Inquiry command failed : %s\n",
sds[i]->error_str); sds[i]->error_str);
goto err_cleanup; goto err_cleanup;
} }
} }
inq_id_data = scsi_datain_unmarshall(inq_task); inq_id_data = scsi_datain_unmarshall(inq_task);
if (inq_id_data == NULL) { if (inq_id_data == NULL) {
printf("failed to unmarshall inquiry ID datain blob\n"); printf("failed to unmarshall inquiry ID datain blob\n");
goto err_cleanup; goto err_cleanup;
} }
if (inq_id_data->qualifier if (inq_id_data->qualifier
!= SCSI_INQUIRY_PERIPHERAL_QUALIFIER_CONNECTED) { != SCSI_INQUIRY_PERIPHERAL_QUALIFIER_CONNECTED) {
printf("error: multipath device not connected\n"); printf("error: multipath device not connected\n");
goto err_cleanup; goto err_cleanup;
} }
if (inq_id_data->device_type if (inq_id_data->device_type
!= SCSI_INQUIRY_PERIPHERAL_DEVICE_TYPE_DIRECT_ACCESS) { != SCSI_INQUIRY_PERIPHERAL_DEVICE_TYPE_DIRECT_ACCESS) {
printf("error: multipath devices must be SBC\n"); printf("error: multipath devices must be SBC\n");
goto err_cleanup; goto err_cleanup;
} }
/* walk the list of IDs, and find a suitable LU candidate */ /* walk the list of IDs, and find a suitable LU candidate */
for (des = inq_id_data->designators; for (des = inq_id_data->designators;
des != NULL; des != NULL;
des = des->next) { des = des->next) {
if (des->association != SCSI_ASSOCIATION_LOGICAL_UNIT) { if (des->association != SCSI_ASSOCIATION_LOGICAL_UNIT) {
printf("skipping non-LU designator: %d\n", printf("skipping non-LU designator: %d\n",
des->association); des->association);
continue; continue;
} }
if ((des->designator_type != SCSI_DESIGNATOR_TYPE_EUI_64) if ((des->designator_type != SCSI_DESIGNATOR_TYPE_EUI_64)
&& (des->designator_type != SCSI_DESIGNATOR_TYPE_NAA) && (des->designator_type != SCSI_DESIGNATOR_TYPE_NAA)
&& (des->designator_type != SCSI_DESIGNATOR_TYPE_MD5_LOGICAL_UNIT_IDENTIFIER) && (des->designator_type != SCSI_DESIGNATOR_TYPE_MD5_LOGICAL_UNIT_IDENTIFIER)
&& (des->designator_type != SCSI_DESIGNATOR_TYPE_SCSI_NAME_STRING)) { && (des->designator_type != SCSI_DESIGNATOR_TYPE_SCSI_NAME_STRING)) {
printf("skipping unsupported des type: %d\n", printf("skipping unsupported des type: %d\n",
des->designator_type); des->designator_type);
continue; continue;
} }
if (des->designator_length <= 0) { if (des->designator_length <= 0) {
printf("skipping designator with bad len: %d\n", printf("skipping designator with bad len: %d\n",
des->designator_length); des->designator_length);
continue; continue;
} }
if (des_saved == NULL) { if (des_saved == NULL) {
ret = mpath_des_copy(des, &des_saved); ret = mpath_des_copy(des, &des_saved);
if (ret < 0) { if (ret < 0) {
goto err_cleanup; goto err_cleanup;
} }
/* /*
* we now have a reference to look for in all * we now have a reference to look for in all
* subsequent paths. * subsequent paths.
*/ */
num_sds_with_valid_id++; num_sds_with_valid_id++;
break; break;
} else if (mpath_des_cmp(des, des_saved) == 0) { } else if (mpath_des_cmp(des, des_saved) == 0) {
/* found match for previous path designator */ /* found match for previous path designator */
num_sds_with_valid_id++; num_sds_with_valid_id++;
break; break;
} }
/* no match yet, keep checking other designators */ /* no match yet, keep checking other designators */
} }
scsi_free_scsi_task(inq_task); scsi_free_scsi_task(inq_task);
inq_task = NULL; inq_task = NULL;
} }
mpath_des_free(des_saved); mpath_des_free(des_saved);
if (num_sds_with_valid_id != num_sds) { if (num_sds_with_valid_id != num_sds) {
printf("failed to find matching LU device ID for all paths\n"); printf("failed to find matching LU device ID for all paths\n");
return -1; return -1;
} }
printf("found matching LU device identifier for all (%d) paths\n", printf("found matching LU device identifier for all (%d) paths\n",
num_sds); num_sds);
return 0; return 0;
err_cleanup: err_cleanup:
mpath_des_free(des_saved); mpath_des_free(des_saved);
scsi_free_scsi_task(inq_task); scsi_free_scsi_task(inq_task);
return -1; return -1;
} }
static int static int
mpath_check_matching_ids_serial_vpd(int num_sds, mpath_check_matching_ids_serial_vpd(int num_sds,
struct scsi_device **sds) struct scsi_device **sds)
{ {
int i; int i;
int num_sds_with_valid_id = 0; int num_sds_with_valid_id = 0;
struct scsi_task *inq_task = NULL; struct scsi_task *inq_task = NULL;
char *usn_saved = NULL; char *usn_saved = NULL;
for (i = 0; i < num_sds; i++) { for (i = 0; i < num_sds; i++) {
int full_size; int full_size;
struct scsi_inquiry_unit_serial_number *inq_serial; struct scsi_inquiry_unit_serial_number *inq_serial;
/* /*
* inquiry to confirm that all multipath devices carry an * inquiry to confirm that all multipath devices carry an
* identical unit serial number. * identical unit serial number.
*/ */
inq_task = NULL; inq_task = NULL;
inquiry(sds[i], &inq_task, 1, inquiry(sds[i], &inq_task, 1,
SCSI_INQUIRY_PAGECODE_UNIT_SERIAL_NUMBER, 64, SCSI_INQUIRY_PAGECODE_UNIT_SERIAL_NUMBER, 64,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
if (inq_task == NULL || inq_task->status != SCSI_STATUS_GOOD) { if (inq_task == NULL || inq_task->status != SCSI_STATUS_GOOD) {
printf("Inquiry command failed : %s\n", printf("Inquiry command failed : %s\n",
sds[i]->error_str); sds[i]->error_str);
goto err_cleanup; goto err_cleanup;
} }
full_size = scsi_datain_getfullsize(inq_task); full_size = scsi_datain_getfullsize(inq_task);
if (full_size > inq_task->datain.size) { if (full_size > inq_task->datain.size) {
scsi_free_scsi_task(inq_task); scsi_free_scsi_task(inq_task);
/* we need more data */ /* we need more data */
inq_task = NULL; inq_task = NULL;
inquiry(sds[i], &inq_task, 1, inquiry(sds[i], &inq_task, 1,
SCSI_INQUIRY_PAGECODE_UNIT_SERIAL_NUMBER, SCSI_INQUIRY_PAGECODE_UNIT_SERIAL_NUMBER,
full_size, full_size,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
if (inq_task == NULL) { if (inq_task == NULL) {
printf("Inquiry command failed : %s\n", printf("Inquiry command failed : %s\n",
sds[i]->error_str); sds[i]->error_str);
goto err_cleanup; goto err_cleanup;
} }
} }
inq_serial = scsi_datain_unmarshall(inq_task); inq_serial = scsi_datain_unmarshall(inq_task);
if (inq_serial == NULL) { if (inq_serial == NULL) {
printf("failed to unmarshall inquiry datain blob\n"); printf("failed to unmarshall inquiry datain blob\n");
goto err_cleanup; goto err_cleanup;
} }
if (inq_serial->qualifier if (inq_serial->qualifier
!= SCSI_INQUIRY_PERIPHERAL_QUALIFIER_CONNECTED) { != SCSI_INQUIRY_PERIPHERAL_QUALIFIER_CONNECTED) {
printf("error: multipath device not connected\n"); printf("error: multipath device not connected\n");
goto err_cleanup; goto err_cleanup;
} }
if (inq_serial->device_type if (inq_serial->device_type
!= SCSI_INQUIRY_PERIPHERAL_DEVICE_TYPE_DIRECT_ACCESS) { != SCSI_INQUIRY_PERIPHERAL_DEVICE_TYPE_DIRECT_ACCESS) {
printf("error: multipath devices must be SBC\n"); printf("error: multipath devices must be SBC\n");
goto err_cleanup; goto err_cleanup;
} }
if (inq_serial->usn == NULL) { if (inq_serial->usn == NULL) {
printf("error: empty usn for multipath device\n"); printf("error: empty usn for multipath device\n");
goto err_cleanup; goto err_cleanup;
} }
if (usn_saved == NULL) { if (usn_saved == NULL) {
usn_saved = strdup(inq_serial->usn); usn_saved = strdup(inq_serial->usn);
if (usn_saved == NULL) { if (usn_saved == NULL) {
goto err_cleanup; goto err_cleanup;
} }
num_sds_with_valid_id++; num_sds_with_valid_id++;
} else if (strcmp(usn_saved, inq_serial->usn) == 0) { } else if (strcmp(usn_saved, inq_serial->usn) == 0) {
num_sds_with_valid_id++; num_sds_with_valid_id++;
} else { } else {
printf("multipath unit serial mismatch: %s != %s\n", printf("multipath unit serial mismatch: %s != %s\n",
usn_saved, inq_serial->usn); usn_saved, inq_serial->usn);
} }
scsi_free_scsi_task(inq_task); scsi_free_scsi_task(inq_task);
inq_task = NULL; inq_task = NULL;
} }
if (num_sds_with_valid_id != num_sds) { if (num_sds_with_valid_id != num_sds) {
printf("failed to find matching serial number for all paths\n"); printf("failed to find matching serial number for all paths\n");
goto err_cleanup; goto err_cleanup;
} }
printf("found matching serial number for all (%d) paths: %s\n", printf("found matching serial number for all (%d) paths: %s\n",
num_sds, usn_saved); num_sds, usn_saved);
free(usn_saved); free(usn_saved);
return 0; return 0;
err_cleanup: err_cleanup:
free(usn_saved); free(usn_saved);
scsi_free_scsi_task(inq_task); scsi_free_scsi_task(inq_task);
return -1; return -1;
} }
int int
mpath_check_matching_ids(int num_sds, mpath_check_matching_ids(int num_sds,
struct scsi_device **sds) struct scsi_device **sds)
{ {
int ret; int ret;
/* /*
* first check all devices for a matching LU identifier in the device * first check all devices for a matching LU identifier in the device
* identification INQUIRY VPD page. * identification INQUIRY VPD page.
*/ */
ret = mpath_check_matching_ids_devid_vpd(num_sds, sds); ret = mpath_check_matching_ids_devid_vpd(num_sds, sds);
if (ret == 0) { if (ret == 0) {
return 0; /* found matching */ return 0; /* found matching */
} }
/* fall back to a unit serial number check */ /* fall back to a unit serial number check */
ret = mpath_check_matching_ids_serial_vpd(num_sds, sds); ret = mpath_check_matching_ids_serial_vpd(num_sds, sds);
return ret; return ret;
} }
int int
mpath_count_iscsi(int num_sds, mpath_count_iscsi(int num_sds,
struct scsi_device **sds) struct scsi_device **sds)
{ {
int i; int i;
int found = 0; int found = 0;
for (i = 0; i < num_sds; i++) { for (i = 0; i < num_sds; i++) {
if (sds[i]->iscsi_ctx != NULL) { if (sds[i]->iscsi_ctx != NULL) {
found++; found++;
} }
} }
return found; return found;
} }
/* /*
@@ -394,52 +394,52 @@ mpath_count_iscsi(int num_sds,
int int
mpath_sd2_get_or_clone(struct scsi_device *sd1, struct scsi_device **_sd2) mpath_sd2_get_or_clone(struct scsi_device *sd1, struct scsi_device **_sd2)
{ {
struct scsi_device *sd2; struct scsi_device *sd2;
if (mp_num_sds > 1) { if (mp_num_sds > 1) {
logging(LOG_VERBOSE, "using multipath dev for second session"); logging(LOG_VERBOSE, "using multipath dev for second session");
*_sd2 = mp_sds[1]; *_sd2 = mp_sds[1];
return 0; return 0;
} }
if (sd1->iscsi_ctx == NULL) { if (sd1->iscsi_ctx == NULL) {
logging(LOG_NORMAL, "can't clone non-iscsi device"); logging(LOG_NORMAL, "can't clone non-iscsi device");
return -EINVAL; return -EINVAL;
} }
logging(LOG_VERBOSE, "cloning sd1 for second session"); logging(LOG_VERBOSE, "cloning sd1 for second session");
sd2 = malloc(sizeof(*sd2)); sd2 = malloc(sizeof(*sd2));
if (sd2 == NULL) { if (sd2 == NULL) {
return -ENOMEM; return -ENOMEM;
} }
memset(sd2, 0, sizeof(*sd2)); memset(sd2, 0, sizeof(*sd2));
sd2->iscsi_url = sd1->iscsi_url; sd2->iscsi_url = sd1->iscsi_url;
sd2->iscsi_lun = sd1->iscsi_lun; sd2->iscsi_lun = sd1->iscsi_lun;
sd2->iscsi_ctx = iscsi_context_login(initiatorname2, sd2->iscsi_url, sd2->iscsi_ctx = iscsi_context_login(initiatorname2, sd2->iscsi_url,
&sd2->iscsi_lun); &sd2->iscsi_lun);
if (sd2->iscsi_ctx == NULL) { if (sd2->iscsi_ctx == NULL) {
logging(LOG_VERBOSE, "Failed to login to target"); logging(LOG_VERBOSE, "Failed to login to target");
free(sd2); free(sd2);
return -ENOMEM; return -ENOMEM;
} }
*_sd2 = sd2; *_sd2 = sd2;
return 0; return 0;
} }
void void
mpath_sd2_put(struct scsi_device *sd2) mpath_sd2_put(struct scsi_device *sd2)
{ {
if (mp_num_sds > 1) { if (mp_num_sds > 1) {
if (sd2 != mp_sds[1]) { if (sd2 != mp_sds[1]) {
logging(LOG_NORMAL, "Invalid sd2!"); logging(LOG_NORMAL, "Invalid sd2!");
} }
return; return;
} }
/* sd2 was allocated by mp_get - cleanup */ /* sd2 was allocated by mp_get - cleanup */
iscsi_logout_sync(sd2->iscsi_ctx); iscsi_logout_sync(sd2->iscsi_ctx);
iscsi_destroy_context(sd2->iscsi_ctx); iscsi_destroy_context(sd2->iscsi_ctx);
free(sd2); free(sd2);
} }

View File

@@ -17,8 +17,8 @@
along with this program; if not, see <http://www.gnu.org/licenses/>. along with this program; if not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef _ISCSI_MULTIPATH_H_ #ifndef _ISCSI_MULTIPATH_H_
#define _ISCSI_MULTIPATH_H_ #define _ISCSI_MULTIPATH_H_
#define MPATH_MAX_DEVS 2 #define MPATH_MAX_DEVS 2
extern int mp_num_sds; extern int mp_num_sds;
@@ -26,35 +26,35 @@ extern struct scsi_device *mp_sds[MPATH_MAX_DEVS];
int int
mpath_check_matching_ids(int num_sds, mpath_check_matching_ids(int num_sds,
struct scsi_device **sds); struct scsi_device **sds);
int int
mpath_count_iscsi(int num_sds, mpath_count_iscsi(int num_sds,
struct scsi_device **sds); struct scsi_device **sds);
int int
mpath_sd2_get_or_clone(struct scsi_device *sd1, struct scsi_device **_sd2); mpath_sd2_get_or_clone(struct scsi_device *sd1, struct scsi_device **_sd2);
void void
mpath_sd2_put(struct scsi_device *sd2); mpath_sd2_put(struct scsi_device *sd2);
#define MPATH_SKIP_IF_UNAVAILABLE(_sds, _num_sds) \ #define MPATH_SKIP_IF_UNAVAILABLE(_sds, _num_sds) \
do { \ do { \
if (_num_sds <= 1) { \ if (_num_sds <= 1) { \
logging(LOG_NORMAL, "[SKIPPED] Multipath unavailable." \ logging(LOG_NORMAL, "[SKIPPED] Multipath unavailable." \
" Skipping test"); \ " Skipping test"); \
CU_PASS("[SKIPPED] Multipath unavailable." \ CU_PASS("[SKIPPED] Multipath unavailable." \
" Skipping test"); \ " Skipping test"); \
return; \ return; \
} \ } \
} while (0); } while (0);
#define MPATH_SKIP_UNLESS_ISCSI(_sds, _num_sds) \ #define MPATH_SKIP_UNLESS_ISCSI(_sds, _num_sds) \
do { \ do { \
if (mpath_count_iscsi(_num_sds, _sds) != _num_sds) { \ if (mpath_count_iscsi(_num_sds, _sds) != _num_sds) { \
logging(LOG_NORMAL, "[SKIPPED] Non-iSCSI multipath." \ logging(LOG_NORMAL, "[SKIPPED] Non-iSCSI multipath." \
" Skipping test"); \ " Skipping test"); \
CU_PASS("[SKIPPED] Non-iSCSI multipath." \ CU_PASS("[SKIPPED] Non-iSCSI multipath." \
" Skipping test"); \ " Skipping test"); \
return; \ return; \
} \ } \
} while (0); } while (0);
#endif /* _ISCSI_MULTIPATH_H_ */ #endif /* _ISCSI_MULTIPATH_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -18,8 +18,8 @@
along with this program; if not, see <http://www.gnu.org/licenses/>. along with this program; if not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef _ISCSI_SUPPORT_H_ #ifndef _ISCSI_SUPPORT_H_
#define _ISCSI_SUPPORT_H_ #define _ISCSI_SUPPORT_H_
#include <time.h> #include <time.h>
#include <sys/types.h> #include <sys/types.h>
@@ -70,115 +70,115 @@ void logging(int level, const char *format, ...) _R_(2,3);
* define special flags for logging a blank line, so compiler * define special flags for logging a blank line, so compiler
* does not commplain when logging a "" * does not commplain when logging a ""
*/ */
#define LOG_BLANK_LINE " " #define LOG_BLANK_LINE " "
#define LOG_BLANK_LINE_CMP_LEN 2 #define LOG_BLANK_LINE_CMP_LEN 2
#define CHECK_FOR_DATALOSS \ #define CHECK_FOR_DATALOSS \
do { \ do { \
if (!data_loss) { \ if (!data_loss) { \
logging(LOG_NORMAL, "[SKIPPED] --dataloss flag is not " \ logging(LOG_NORMAL, "[SKIPPED] --dataloss flag is not " \
"set. Skipping test."); \ "set. Skipping test."); \
CU_PASS("[SKIPPED] --dataloss flag is not set." \ CU_PASS("[SKIPPED] --dataloss flag is not set." \
" Skipping test"); \ " Skipping test"); \
return; \ return; \
} \ } \
} while (0); } while (0);
#define CHECK_FOR_SANITIZE \ #define CHECK_FOR_SANITIZE \
do { \ do { \
if (!allow_sanitize) { \ if (!allow_sanitize) { \
logging(LOG_NORMAL, "[SKIPPED] --allow-sanitize flag " \ logging(LOG_NORMAL, "[SKIPPED] --allow-sanitize flag " \
"is not set. Skipping test."); \ "is not set. Skipping test."); \
CU_PASS("[SKIPPED] --allow-sanitize flag is not set." \ CU_PASS("[SKIPPED] --allow-sanitize flag is not set." \
" Skipping test"); \ " Skipping test"); \
return; \ return; \
} \ } \
} while (0); } while (0);
#define CHECK_FOR_READONLY \ #define CHECK_FOR_READONLY \
do { \ do { \
if (!readonly) { \ if (!readonly) { \
logging(LOG_NORMAL, "[SKIPPED] Logical unit is not " \ logging(LOG_NORMAL, "[SKIPPED] Logical unit is not " \
"write-protected. Skipping test."); \ "write-protected. Skipping test."); \
CU_PASS("[SKIPPED] Logical unit is not write-" \ CU_PASS("[SKIPPED] Logical unit is not write-" \
"protected. Skipping test"); \ "protected. Skipping test"); \
return; \ return; \
} \ } \
} while (0); } while (0);
#define CHECK_FOR_REMOVABLE \ #define CHECK_FOR_REMOVABLE \
do { \ do { \
if (!inq->rmb) { \ if (!inq->rmb) { \
logging(LOG_NORMAL, "[SKIPPED] Logical unit is not " \ logging(LOG_NORMAL, "[SKIPPED] Logical unit is not " \
"removable. Skipping test."); \ "removable. Skipping test."); \
CU_PASS("[SKIPPED] Logical unit is not removable" \ CU_PASS("[SKIPPED] Logical unit is not removable" \
" Skipping test"); \ " Skipping test"); \
return; \ return; \
} \ } \
} while (0); } while (0);
#define CHECK_FOR_THIN_PROVISIONING \ #define CHECK_FOR_THIN_PROVISIONING \
do { \ do { \
if (rc16 == NULL || rc16->lbpme == 0) { \ if (rc16 == NULL || rc16->lbpme == 0) { \
logging(LOG_NORMAL, "[SKIPPED] Logical unit is fully" \ logging(LOG_NORMAL, "[SKIPPED] Logical unit is fully" \
" provisioned. Skipping test"); \ " provisioned. Skipping test"); \
CU_PASS("[SKIPPED] Logical unit is fully provisioned." \ CU_PASS("[SKIPPED] Logical unit is fully provisioned." \
" Skipping test"); \ " Skipping test"); \
return; \ return; \
} \ } \
} while (0); } while (0);
#define CHECK_FOR_LBPWS10 \ #define CHECK_FOR_LBPWS10 \
do { \ do { \
if (inq_lbp->lbpws10 == 0) { \ if (inq_lbp->lbpws10 == 0) { \
logging(LOG_NORMAL, "[SKIPPED] Logical unit does not" \ logging(LOG_NORMAL, "[SKIPPED] Logical unit does not" \
" have LBPWS10. Skipping test"); \ " have LBPWS10. Skipping test"); \
CU_PASS("[SKIPPED] Logical unit does not have LBPWS10." \ CU_PASS("[SKIPPED] Logical unit does not have LBPWS10." \
" Skipping test"); \ " Skipping test"); \
return; \ return; \
} \ } \
} while (0); } while (0);
#define CHECK_FOR_LBPWS \ #define CHECK_FOR_LBPWS \
do { \ do { \
if (inq_lbp->lbpws == 0) { \ if (inq_lbp->lbpws == 0) { \
logging(LOG_NORMAL, "[SKIPPED] Logical unit does not" \ logging(LOG_NORMAL, "[SKIPPED] Logical unit does not" \
" have LBPWS. Skipping test"); \ " have LBPWS. Skipping test"); \
CU_PASS("[SKIPPED] Logical unit does not have LBPWS." \ CU_PASS("[SKIPPED] Logical unit does not have LBPWS." \
" Skipping test"); \ " Skipping test"); \
return; \ return; \
} \ } \
} while (0); } while (0);
#define CHECK_FOR_LBPU \ #define CHECK_FOR_LBPU \
do { \ do { \
if (inq_lbp->lbpu == 0) { \ if (inq_lbp->lbpu == 0) { \
logging(LOG_NORMAL, "[SKIPPED] Logical unit does not" \ logging(LOG_NORMAL, "[SKIPPED] Logical unit does not" \
" have LBPU. Skipping test"); \ " have LBPU. Skipping test"); \
CU_PASS("[SKIPPED] Logical unit does not have LBPU." \ CU_PASS("[SKIPPED] Logical unit does not have LBPU." \
" Skipping test"); \ " Skipping test"); \
return; \ return; \
} \ } \
} while (0); } while (0);
#define CHECK_FOR_LBPPB_GT_1 \ #define CHECK_FOR_LBPPB_GT_1 \
do { \ do { \
if (lbppb < 2) { \ if (lbppb < 2) { \
logging(LOG_NORMAL, "[SKIPPED] LBPPB < 2. Skipping test"); \ logging(LOG_NORMAL, "[SKIPPED] LBPPB < 2. Skipping test"); \
CU_PASS("[SKIPPED] LBPPB < 2. Skipping test"); \ CU_PASS("[SKIPPED] LBPPB < 2. Skipping test"); \
return; \ return; \
} \ } \
} while (0); } while (0);
#define CHECK_FOR_SBC \ #define CHECK_FOR_SBC \
do { \ do { \
if (inq->device_type != SCSI_INQUIRY_PERIPHERAL_DEVICE_TYPE_DIRECT_ACCESS) {\ if (inq->device_type != SCSI_INQUIRY_PERIPHERAL_DEVICE_TYPE_DIRECT_ACCESS) {\
logging(LOG_NORMAL, "[SKIPPED] Not SBC device." \ logging(LOG_NORMAL, "[SKIPPED] Not SBC device." \
" Skipping test"); \ " Skipping test"); \
CU_PASS("[SKIPPED] Not SBC device." \ CU_PASS("[SKIPPED] Not SBC device." \
" Skipping test"); \ " Skipping test"); \
return; \ return; \
} \ } \
} while (0); } while (0);
#define COMPAREANDWRITE(...) \ #define COMPAREANDWRITE(...) \
@@ -704,23 +704,23 @@ extern int sbc3_support;
extern int maximum_transfer_length; extern int maximum_transfer_length;
struct scsi_device { struct scsi_device {
char *error_str; char *error_str;
struct iscsi_context *iscsi_ctx; struct iscsi_context *iscsi_ctx;
int iscsi_lun; int iscsi_lun;
char *iscsi_url; char *iscsi_url;
char *sgio_dev; char *sgio_dev;
int sgio_fd; int sgio_fd;
}; };
extern struct scsi_device *sd; extern struct scsi_device *sd;
struct iscsi_context *iscsi_context_login(const char *initiatorname, const char *url, int *lun); struct iscsi_context *iscsi_context_login(const char *initiatorname, const char *url, int *lun);
struct iscsi_async_state { struct iscsi_async_state {
struct scsi_task *task; struct scsi_task *task;
int status; int status;
int finished; int finished;
}; };
void wait_until_test_finished(struct iscsi_context *iscsi, struct iscsi_async_state *test_state); void wait_until_test_finished(struct iscsi_context *iscsi, struct iscsi_async_state *test_state);
@@ -735,32 +735,32 @@ struct scsi_command_descriptor *get_command_descriptor(int opcode, int sa);
static inline long rand_key(void) static inline long rand_key(void)
{ {
static int seed = 0; static int seed = 0;
if (!seed) { if (!seed) {
struct timeval tv; struct timeval tv;
pid_t p; pid_t p;
unsigned int s; unsigned int s;
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
p = getpid(); p = getpid();
s = p ^ tv.tv_sec ^ tv.tv_usec; s = p ^ tv.tv_sec ^ tv.tv_usec;
srandom(s); srandom(s);
} }
seed = 1; seed = 1;
return random(); return random();
} }
static inline int pr_type_is_all_registrants( static inline int pr_type_is_all_registrants(
enum scsi_persistent_out_type pr_type) enum scsi_persistent_out_type pr_type)
{ {
switch (pr_type) { switch (pr_type) {
case SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE_ALL_REGISTRANTS: case SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE_ALL_REGISTRANTS:
case SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS_ALL_REGISTRANTS: case SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS_ALL_REGISTRANTS:
return 1; return 1;
default: default:
return 0; return 0;
} }
} }
int all_zeroes(const unsigned char *buf, unsigned size); int all_zeroes(const unsigned char *buf, unsigned size);
@@ -783,13 +783,13 @@ int prout_release(struct scsi_device *sdev,
unsigned long long key, enum scsi_persistent_out_type pr_type); unsigned long long key, enum scsi_persistent_out_type pr_type);
int prout_clear(struct scsi_device *sdev, unsigned long long key); int prout_clear(struct scsi_device *sdev, unsigned long long key);
int prout_preempt(struct scsi_device *sdev, int prout_preempt(struct scsi_device *sdev,
unsigned long long sark, unsigned long long rk, unsigned long long sark, unsigned long long rk,
enum scsi_persistent_out_type pr_type); enum scsi_persistent_out_type pr_type);
int prin_verify_not_reserved(struct scsi_device *sdev); int prin_verify_not_reserved(struct scsi_device *sdev);
int prin_verify_reserved_as(struct scsi_device *sdev, int prin_verify_reserved_as(struct scsi_device *sdev,
unsigned long long key, enum scsi_persistent_out_type pr_type); unsigned long long key, enum scsi_persistent_out_type pr_type);
int prin_report_caps(struct scsi_device *sdev, struct scsi_task **tp, int prin_report_caps(struct scsi_device *sdev, struct scsi_task **tp,
struct scsi_persistent_reserve_in_report_capabilities **_rcaps); struct scsi_persistent_reserve_in_report_capabilities **_rcaps);
int verify_read_works(struct scsi_device *sdev, unsigned char *buf); int verify_read_works(struct scsi_device *sdev, unsigned char *buf);
int verify_write_works(struct scsi_device *sdev, unsigned char *buf); int verify_write_works(struct scsi_device *sdev, unsigned char *buf);
int verify_read_fails(struct scsi_device *sdev, unsigned char *buf); int verify_read_fails(struct scsi_device *sdev, unsigned char *buf);
@@ -844,8 +844,8 @@ int populate_seg_desc_hdr(unsigned char *hdr, enum ec_descr_type_code desc_type,
int populate_seg_desc_b2b(unsigned char *desc, int dc, int cat, int src_index, int dst_index, int num_blks, uint64_t src_lba, uint64_t dst_lba); int populate_seg_desc_b2b(unsigned char *desc, int dc, int cat, int src_index, int dst_index, int num_blks, uint64_t src_lba, uint64_t dst_lba);
void populate_param_header(unsigned char *buf, int list_id, int str, int list_id_usage, int prio, int tgt_desc_len, int seg_desc_len, int inline_data_len); void populate_param_header(unsigned char *buf, int list_id, int str, int list_id_usage, int prio, int tgt_desc_len, int seg_desc_len, int inline_data_len);
int receive_copy_results(struct scsi_task **task, struct scsi_device *sdev, int receive_copy_results(struct scsi_task **task, struct scsi_device *sdev,
enum scsi_copy_results_sa sa, int list_id, enum scsi_copy_results_sa sa, int list_id,
void **datap, int status, enum scsi_sense_key key, void **datap, int status, enum scsi_sense_key key,
int *ascq, int num_ascq); int *ascq, int num_ascq);
int test_iscsi_tur_until_good(struct scsi_device *iscsi_sd, int *num_uas); int test_iscsi_tur_until_good(struct scsi_device *iscsi_sd, int *num_uas);
#endif /* _ISCSI_SUPPORT_H_ */ #endif /* _ISCSI_SUPPORT_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -17,8 +17,8 @@
along with this program; if not, see <http://www.gnu.org/licenses/>. along with this program; if not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef _ISCSI_TEST_CU_H_ #ifndef _ISCSI_TEST_CU_H_
#define _ISCSI_TEST_CU_H_ #define _ISCSI_TEST_CU_H_
#include <time.h> #include <time.h>
#include <sys/types.h> #include <sys/types.h>
@@ -308,4 +308,4 @@ void test_multipathio_simple(void);
void test_multipathio_reset(void); void test_multipathio_reset(void);
void test_multipathio_compareandwrite(void); void test_multipathio_compareandwrite(void);
#endif /* _ISCSI_TEST_CU_H_ */ #endif /* _ISCSI_TEST_CU_H_ */

View File

@@ -29,90 +29,90 @@
void void
test_compareandwrite_dpofua(void) test_compareandwrite_dpofua(void)
{ {
int ret, dpofua, usage_data_dpofua; int ret, dpofua, usage_data_dpofua;
struct scsi_task *ms_task = NULL; struct scsi_task *ms_task = NULL;
struct scsi_mode_sense *ms; struct scsi_mode_sense *ms;
struct scsi_task *rso_task = NULL; struct scsi_task *rso_task = NULL;
struct scsi_report_supported_op_codes_one_command *rsoc; struct scsi_report_supported_op_codes_one_command *rsoc;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test COMPAREANDWRITE DPO/FUA flags"); logging(LOG_VERBOSE, "Test COMPAREANDWRITE DPO/FUA flags");
CHECK_FOR_SBC; CHECK_FOR_SBC;
CHECK_FOR_DATALOSS; CHECK_FOR_DATALOSS;
logging(LOG_VERBOSE, "Read the DPOFUA flag from mode sense data"); logging(LOG_VERBOSE, "Read the DPOFUA flag from mode sense data");
MODESENSE6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT, MODESENSE6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT,
SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255, SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "[SUCCESS] Mode sense returned status GOOD"); logging(LOG_VERBOSE, "[SUCCESS] Mode sense returned status GOOD");
ms = scsi_datain_unmarshall(ms_task); ms = scsi_datain_unmarshall(ms_task);
dpofua = ms && (ms->device_specific_parameter & 0x10); dpofua = ms && (ms->device_specific_parameter & 0x10);
scsi_free_scsi_task(ms_task); scsi_free_scsi_task(ms_task);
logging(LOG_VERBOSE, "Read the first block"); logging(LOG_VERBOSE, "Read the first block");
ret = read10(sd, NULL, 0, block_size, ret = read10(sd, NULL, 0, block_size,
block_size, 0, 0, 0, 0, 0, scratch, block_size, 0, 0, 0, 0, 0, scratch,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
if (ret == 0) if (ret == 0)
memcpy(scratch + block_size, scratch, block_size); memcpy(scratch + block_size, scratch, block_size);
else else
memset(scratch, 0xa6, 2 * block_size); memset(scratch, 0xa6, 2 * block_size);
if (dpofua) { if (dpofua) {
logging(LOG_VERBOSE, "DPOFUA flag is set. Device should allow " logging(LOG_VERBOSE, "DPOFUA flag is set. Device should allow "
"DPO/FUA flags in CDBs"); "DPO/FUA flags in CDBs");
} else { } else {
logging(LOG_VERBOSE, "DPOFUA flag is clear. Device should fail " logging(LOG_VERBOSE, "DPOFUA flag is clear. Device should fail "
"CDBs with DPO/FUA set"); "CDBs with DPO/FUA set");
} }
logging(LOG_VERBOSE, "Test COMPAREANDWRITE with DPO==1"); logging(LOG_VERBOSE, "Test COMPAREANDWRITE with DPO==1");
if (dpofua) { if (dpofua) {
COMPAREANDWRITE(sd, 0, scratch, 2 * block_size, COMPAREANDWRITE(sd, 0, scratch, 2 * block_size,
block_size, 0, 1, 0, 0, block_size, 0, 1, 0, 0,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} else { } else {
COMPAREANDWRITE(sd, 0, scratch, 2 * block_size, COMPAREANDWRITE(sd, 0, scratch, 2 * block_size,
block_size, 0, 1, 0, 0, block_size, 0, 1, 0, 0,
EXPECT_INVALID_FIELD_IN_CDB); EXPECT_INVALID_FIELD_IN_CDB);
} }
logging(LOG_VERBOSE, "Test COMPAREANDWRITE with FUA==1"); logging(LOG_VERBOSE, "Test COMPAREANDWRITE with FUA==1");
if (dpofua) { if (dpofua) {
COMPAREANDWRITE(sd, 0, scratch, 2 * block_size, COMPAREANDWRITE(sd, 0, scratch, 2 * block_size,
block_size, 0, 0, 1, 0, block_size, 0, 0, 1, 0,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} else { } else {
COMPAREANDWRITE(sd, 0, scratch, 2 * block_size, COMPAREANDWRITE(sd, 0, scratch, 2 * block_size,
block_size, 0, 0, 1, 0, block_size, 0, 0, 1, 0,
EXPECT_INVALID_FIELD_IN_CDB); EXPECT_INVALID_FIELD_IN_CDB);
} }
logging(LOG_VERBOSE, "Test COMPAREANDWRITE with DPO==1 FUA==1"); logging(LOG_VERBOSE, "Test COMPAREANDWRITE with DPO==1 FUA==1");
if (dpofua) { if (dpofua) {
COMPAREANDWRITE(sd, 0, scratch, 2 * block_size, COMPAREANDWRITE(sd, 0, scratch, 2 * block_size,
block_size, 0, 1, 1, 0, block_size, 0, 1, 1, 0,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} else { } else {
COMPAREANDWRITE(sd, 0, scratch, 2 * block_size, COMPAREANDWRITE(sd, 0, scratch, 2 * block_size,
block_size, 0, 1, 1, 0, block_size, 0, 1, 1, 0,
EXPECT_INVALID_FIELD_IN_CDB); EXPECT_INVALID_FIELD_IN_CDB);
} }
logging(LOG_VERBOSE, "Try fetching REPORT_SUPPORTED_OPCODES " logging(LOG_VERBOSE, "Try fetching REPORT_SUPPORTED_OPCODES "
"for COMPAREANDWRITE"); "for COMPAREANDWRITE");
REPORT_SUPPORTED_OPCODES(sd, &rso_task, REPORT_SUPPORTED_OPCODES(sd, &rso_task,
0, SCSI_REPORT_SUPPORTING_OPCODE, 0, SCSI_REPORT_SUPPORTING_OPCODE,
SCSI_OPCODE_COMPARE_AND_WRITE, SCSI_OPCODE_COMPARE_AND_WRITE,
0, 0,
65535, 65535,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer"); logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer");
rsoc = scsi_datain_unmarshall(rso_task); rsoc = scsi_datain_unmarshall(rso_task);
CU_ASSERT_PTR_NOT_NULL_FATAL(rsoc); CU_ASSERT_PTR_NOT_NULL_FATAL(rsoc);
usage_data_dpofua = rsoc->cdb_usage_data[1] & 0x18; usage_data_dpofua = rsoc->cdb_usage_data[1] & 0x18;
if (dpofua) { if (dpofua) {
@@ -133,5 +133,5 @@ test_compareandwrite_dpofua(void)
} }
} }
scsi_free_scsi_task(rso_task); scsi_free_scsi_task(rso_task);
} }

View File

@@ -31,125 +31,125 @@
void void
test_compareandwrite_miscompare(void) test_compareandwrite_miscompare(void)
{ {
int i; int i;
unsigned j; unsigned j;
int maxbl; int maxbl;
CHECK_FOR_DATALOSS; CHECK_FOR_DATALOSS;
CHECK_FOR_SBC; CHECK_FOR_SBC;
if (inq_bl && inq_bl->max_cmp) { if (inq_bl && inq_bl->max_cmp) {
maxbl = inq_bl->max_cmp; maxbl = inq_bl->max_cmp;
} else { } else {
/* Assume we are not limited */ /* Assume we are not limited */
maxbl = 256; maxbl = 256;
} }
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test COMPARE_AND_WRITE of 1-256 blocks at the " logging(LOG_VERBOSE, "Test COMPARE_AND_WRITE of 1-256 blocks at the "
"start of the LUN. One Byte miscompare in the final block."); "start of the LUN. One Byte miscompare in the final block.");
for (i = 1; i < 256; i++) { for (i = 1; i < 256; i++) {
logging(LOG_VERBOSE, "Write %d blocks of 'A' at LBA:0", i); logging(LOG_VERBOSE, "Write %d blocks of 'A' at LBA:0", i);
memset(scratch, 'A', 2 * i * block_size); memset(scratch, 'A', 2 * i * block_size);
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
WRITE16(sd, 0, i * block_size, WRITE16(sd, 0, i * block_size,
block_size, 0, 0, 0, 0, 0, scratch, block_size, 0, 0, 0, 0, 0, scratch,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Change byte 27 from the end to 'C' so that it does not match."); logging(LOG_VERBOSE, "Change byte 27 from the end to 'C' so that it does not match.");
scratch[i * block_size - 27] = 'C'; scratch[i * block_size - 27] = 'C';
if (i > maxbl) { if (i > maxbl) {
logging(LOG_VERBOSE, "Number of blocks %d is greater than " logging(LOG_VERBOSE, "Number of blocks %d is greater than "
"BlockLimits.MaximumCompareAndWriteLength(%d). " "BlockLimits.MaximumCompareAndWriteLength(%d). "
"Command should fail with INVALID_FIELD_IN_CDB", "Command should fail with INVALID_FIELD_IN_CDB",
i, maxbl); i, maxbl);
COMPAREANDWRITE(sd, 0, COMPAREANDWRITE(sd, 0,
scratch, 2 * i * block_size, scratch, 2 * i * block_size,
block_size, 0, 0, 0, 0, block_size, 0, 0, 0, 0,
EXPECT_INVALID_FIELD_IN_CDB); EXPECT_INVALID_FIELD_IN_CDB);
continue; continue;
} }
memset(scratch + i * block_size, 'B', i * block_size); memset(scratch + i * block_size, 'B', i * block_size);
logging(LOG_VERBOSE, "Overwrite %d blocks with 'B' " logging(LOG_VERBOSE, "Overwrite %d blocks with 'B' "
"at LBA:0 (if they all contain 'A')", i); "at LBA:0 (if they all contain 'A')", i);
COMPAREANDWRITE(sd, 0, COMPAREANDWRITE(sd, 0,
scratch, 2 * i * block_size, block_size, scratch, 2 * i * block_size, block_size,
0, 0, 0, 0, 0, 0, 0, 0,
EXPECT_MISCOMPARE); EXPECT_MISCOMPARE);
logging(LOG_VERBOSE, "Read %d blocks at LBA:0 and verify " logging(LOG_VERBOSE, "Read %d blocks at LBA:0 and verify "
"they are still unchanged as 'A'", i); "they are still unchanged as 'A'", i);
READ16(sd, NULL, 0, i * block_size, READ16(sd, NULL, 0, i * block_size,
block_size, 0, 0, 0, 0, 0, scratch, block_size, 0, 0, 0, 0, 0, scratch,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
for (j = 0; j < i * block_size; j++) { for (j = 0; j < i * block_size; j++) {
if (scratch[j] != 'A') { if (scratch[j] != 'A') {
logging(LOG_VERBOSE, "[FAILED] Data changed " logging(LOG_VERBOSE, "[FAILED] Data changed "
"eventhough there was a miscompare"); "eventhough there was a miscompare");
CU_FAIL("Block was written to"); CU_FAIL("Block was written to");
return; return;
} }
} }
} }
logging(LOG_VERBOSE, "Test COMPARE_AND_WRITE of 1-256 blocks at the " logging(LOG_VERBOSE, "Test COMPARE_AND_WRITE of 1-256 blocks at the "
"end of the LUN"); "end of the LUN");
for (i = 1; i < 256; i++) { for (i = 1; i < 256; i++) {
logging(LOG_VERBOSE, "Write %d blocks of 'A' at LBA:%" PRIu64, logging(LOG_VERBOSE, "Write %d blocks of 'A' at LBA:%" PRIu64,
i, num_blocks - i); i, num_blocks - i);
memset(scratch, 'A', 2 * i * block_size); memset(scratch, 'A', 2 * i * block_size);
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
WRITE16(sd, num_blocks - i, i * block_size, WRITE16(sd, num_blocks - i, i * block_size,
block_size, 0, 0, 0, 0, 0, scratch, block_size, 0, 0, 0, 0, 0, scratch,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Change byte 27 from the end to 'C' so that it does not match."); logging(LOG_VERBOSE, "Change byte 27 from the end to 'C' so that it does not match.");
scratch[i * block_size - 27] = 'C'; scratch[i * block_size - 27] = 'C';
if (i > maxbl) { if (i > maxbl) {
logging(LOG_VERBOSE, "Number of blocks %d is greater than " logging(LOG_VERBOSE, "Number of blocks %d is greater than "
"BlockLimits.MaximumCompareAndWriteLength(%d). " "BlockLimits.MaximumCompareAndWriteLength(%d). "
"Command should fail with INVALID_FIELD_IN_CDB", "Command should fail with INVALID_FIELD_IN_CDB",
i, maxbl); i, maxbl);
COMPAREANDWRITE(sd, 0, COMPAREANDWRITE(sd, 0,
scratch, 2 * i * block_size, scratch, 2 * i * block_size,
block_size, 0, 0, 0, 0, block_size, 0, 0, 0, 0,
EXPECT_INVALID_FIELD_IN_CDB); EXPECT_INVALID_FIELD_IN_CDB);
continue; continue;
} }
memset(scratch + i * block_size, 'B', i * block_size); memset(scratch + i * block_size, 'B', i * block_size);
logging(LOG_VERBOSE, "Overwrite %d blocks with 'B' " logging(LOG_VERBOSE, "Overwrite %d blocks with 'B' "
"at LBA:%" PRIu64 " (if they all contain 'A')", "at LBA:%" PRIu64 " (if they all contain 'A')",
i, num_blocks - i); i, num_blocks - i);
COMPAREANDWRITE(sd, num_blocks - i, COMPAREANDWRITE(sd, num_blocks - i,
scratch, 2 * i * block_size, block_size, scratch, 2 * i * block_size, block_size,
0, 0, 0, 0, 0, 0, 0, 0,
EXPECT_MISCOMPARE); EXPECT_MISCOMPARE);
logging(LOG_VERBOSE, "Read %d blocks at LBA:%" PRIu64 logging(LOG_VERBOSE, "Read %d blocks at LBA:%" PRIu64
"they are still unchanged as 'A'", "they are still unchanged as 'A'",
i, num_blocks - i); i, num_blocks - i);
READ16(sd, NULL, num_blocks - i, i * block_size, READ16(sd, NULL, num_blocks - i, i * block_size,
block_size, 0, 0, 0, 0, 0, scratch, block_size, 0, 0, 0, 0, 0, scratch,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
for (j = 0; j < i * block_size; j++) { for (j = 0; j < i * block_size; j++) {
if (scratch[j] != 'A') { if (scratch[j] != 'A') {
logging(LOG_VERBOSE, "[FAILED] Data changed " logging(LOG_VERBOSE, "[FAILED] Data changed "
"eventhough there was a miscompare"); "eventhough there was a miscompare");
CU_FAIL("Block was written to"); CU_FAIL("Block was written to");
return; return;
} }
} }
} }
} }

View File

@@ -31,121 +31,121 @@
void void
test_compareandwrite_simple(void) test_compareandwrite_simple(void)
{ {
int i; int i;
unsigned j; unsigned j;
int maxbl; int maxbl;
CHECK_FOR_DATALOSS; CHECK_FOR_DATALOSS;
CHECK_FOR_SBC; CHECK_FOR_SBC;
if (inq_bl && inq_bl->max_cmp) { if (inq_bl && inq_bl->max_cmp) {
maxbl = inq_bl->max_cmp; maxbl = inq_bl->max_cmp;
} else { } else {
/* Assume we are not limited */ /* Assume we are not limited */
maxbl = 256; maxbl = 256;
} }
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test COMPARE_AND_WRITE of 1-256 blocks at the " logging(LOG_VERBOSE, "Test COMPARE_AND_WRITE of 1-256 blocks at the "
"start of the LUN"); "start of the LUN");
for (i = 1; i < 256; i++) { for (i = 1; i < 256; i++) {
logging(LOG_VERBOSE, "Write %d blocks of 'A' at LBA:0", i); logging(LOG_VERBOSE, "Write %d blocks of 'A' at LBA:0", i);
memset(scratch, 'A', 2 * i * block_size); memset(scratch, 'A', 2 * i * block_size);
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
WRITE16(sd, 0, i * block_size, WRITE16(sd, 0, i * block_size,
block_size, 0, 0, 0, 0, 0, scratch, block_size, 0, 0, 0, 0, 0, scratch,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
if (i > maxbl) { if (i > maxbl) {
logging(LOG_VERBOSE, "Number of blocks %d is greater than " logging(LOG_VERBOSE, "Number of blocks %d is greater than "
"BlockLimits.MaximumCompareAndWriteLength(%d). " "BlockLimits.MaximumCompareAndWriteLength(%d). "
"Command should fail with INVALID_FIELD_IN_CDB", "Command should fail with INVALID_FIELD_IN_CDB",
i, maxbl); i, maxbl);
COMPAREANDWRITE(sd, 0, COMPAREANDWRITE(sd, 0,
scratch, 2 * i * block_size, scratch, 2 * i * block_size,
block_size, 0, 0, 0, 0, block_size, 0, 0, 0, 0,
EXPECT_INVALID_FIELD_IN_CDB); EXPECT_INVALID_FIELD_IN_CDB);
continue; continue;
} }
memset(scratch + i * block_size, 'B', i * block_size); memset(scratch + i * block_size, 'B', i * block_size);
logging(LOG_VERBOSE, "Overwrite %d blocks with 'B' " logging(LOG_VERBOSE, "Overwrite %d blocks with 'B' "
"at LBA:0 (if they all contain 'A')", i); "at LBA:0 (if they all contain 'A')", i);
COMPAREANDWRITE(sd, 0, COMPAREANDWRITE(sd, 0,
scratch, 2 * i * block_size, block_size, scratch, 2 * i * block_size, block_size,
0, 0, 0, 0, 0, 0, 0, 0,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Read %d blocks at LBA:0 and verify " logging(LOG_VERBOSE, "Read %d blocks at LBA:0 and verify "
"they are all 'B'", i); "they are all 'B'", i);
READ16(sd, NULL, 0, i * block_size, READ16(sd, NULL, 0, i * block_size,
block_size, 0, 0, 0, 0, 0, scratch, block_size, 0, 0, 0, 0, 0, scratch,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
for (j = 0; j < i * block_size; j++) { for (j = 0; j < i * block_size; j++) {
if (scratch[j] != 'B') { if (scratch[j] != 'B') {
logging(LOG_VERBOSE, "[FAILED] Data did not " logging(LOG_VERBOSE, "[FAILED] Data did not "
"read back as 'B' (scratch[%d] = %#02x)", "read back as 'B' (scratch[%d] = %#02x)",
j, scratch[j]); j, scratch[j]);
CU_FAIL("Block was not written correctly"); CU_FAIL("Block was not written correctly");
return; return;
} }
} }
} }
logging(LOG_VERBOSE, "Test COMPARE_AND_WRITE of 1-256 blocks at the " logging(LOG_VERBOSE, "Test COMPARE_AND_WRITE of 1-256 blocks at the "
"end of the LUN"); "end of the LUN");
for (i = 1; i < 256; i++) { for (i = 1; i < 256; i++) {
logging(LOG_VERBOSE, "Write %d blocks of 'A' at LBA:%" PRIu64, logging(LOG_VERBOSE, "Write %d blocks of 'A' at LBA:%" PRIu64,
i, num_blocks - i); i, num_blocks - i);
memset(scratch, 'A', 2 * i * block_size); memset(scratch, 'A', 2 * i * block_size);
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
WRITE16(sd, num_blocks - i, i * block_size, WRITE16(sd, num_blocks - i, i * block_size,
block_size, 0, 0, 0, 0, 0, scratch, block_size, 0, 0, 0, 0, 0, scratch,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
if (i > maxbl) { if (i > maxbl) {
logging(LOG_VERBOSE, "Number of blocks %d is greater than " logging(LOG_VERBOSE, "Number of blocks %d is greater than "
"BlockLimits.MaximumCompareAndWriteLength(%d). " "BlockLimits.MaximumCompareAndWriteLength(%d). "
"Command should fail with INVALID_FIELD_IN_CDB", "Command should fail with INVALID_FIELD_IN_CDB",
i, maxbl); i, maxbl);
COMPAREANDWRITE(sd, 0, COMPAREANDWRITE(sd, 0,
scratch, 2 * i * block_size, scratch, 2 * i * block_size,
block_size, 0, 0, 0, 0, block_size, 0, 0, 0, 0,
EXPECT_INVALID_FIELD_IN_CDB); EXPECT_INVALID_FIELD_IN_CDB);
continue; continue;
} }
memset(scratch + i * block_size, 'B', i * block_size); memset(scratch + i * block_size, 'B', i * block_size);
logging(LOG_VERBOSE, "Overwrite %d blocks with 'B' " logging(LOG_VERBOSE, "Overwrite %d blocks with 'B' "
"at LBA:%" PRIu64 " (if they all contain 'A')", "at LBA:%" PRIu64 " (if they all contain 'A')",
i, num_blocks - i); i, num_blocks - i);
COMPAREANDWRITE(sd, num_blocks - i, COMPAREANDWRITE(sd, num_blocks - i,
scratch, 2 * i * block_size, block_size, scratch, 2 * i * block_size, block_size,
0, 0, 0, 0, 0, 0, 0, 0,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Read %d blocks at LBA:%" PRIu64 logging(LOG_VERBOSE, "Read %d blocks at LBA:%" PRIu64
" and verify they are all 'B'", " and verify they are all 'B'",
i, num_blocks - i); i, num_blocks - i);
READ16(sd, NULL, num_blocks - i, i * block_size, READ16(sd, NULL, num_blocks - i, i * block_size,
block_size, 0, 0, 0, 0, 0, scratch, block_size, 0, 0, 0, 0, 0, scratch,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
for (j = 0; j < i * block_size; j++) { for (j = 0; j < i * block_size; j++) {
if (scratch[j] != 'B') { if (scratch[j] != 'B') {
logging(LOG_VERBOSE, "[FAILED] Data did not " logging(LOG_VERBOSE, "[FAILED] Data did not "
"read back as 'B' (scratch[%d] = %#02x)", "read back as 'B' (scratch[%d] = %#02x)",
j, scratch[j]); j, scratch[j]);
CU_FAIL("Block was not written correctly"); CU_FAIL("Block was not written correctly");
return; return;
} }
} }
} }
} }

View File

@@ -28,88 +28,88 @@
#include "iscsi-test-cu.h" #include "iscsi-test-cu.h"
int init_xcopy_descr(unsigned char *buf, int offset, int num_tgt_desc, int init_xcopy_descr(unsigned char *buf, int offset, int num_tgt_desc,
int num_seg_desc, int *tgt_desc_len, int *seg_desc_len) int num_seg_desc, int *tgt_desc_len, int *seg_desc_len)
{ {
int i; int i;
/* Initialize target descriptor list with num_tgt_desc /* Initialize target descriptor list with num_tgt_desc
* target descriptor */ * target descriptor */
for (i = 0; i < num_tgt_desc; i++) for (i = 0; i < num_tgt_desc; i++)
offset += populate_tgt_desc(buf+offset, IDENT_DESCR_TGT_DESCR, offset += populate_tgt_desc(buf+offset, IDENT_DESCR_TGT_DESCR,
LU_ID_TYPE_LUN, 0, 0, 0, 0, sd); LU_ID_TYPE_LUN, 0, 0, 0, 0, sd);
*tgt_desc_len = offset - XCOPY_DESC_OFFSET; *tgt_desc_len = offset - XCOPY_DESC_OFFSET;
/* Iniitialize segment descriptor list with num_seg_desc /* Iniitialize segment descriptor list with num_seg_desc
* segment descriptor */ * segment descriptor */
for (i = 0; i < num_seg_desc; i++) for (i = 0; i < num_seg_desc; i++)
offset += populate_seg_desc_b2b(buf+offset, 0, 0, 0, 0, offset += populate_seg_desc_b2b(buf+offset, 0, 0, 0, 0,
2048, 0, num_blocks - 2048); 2048, 0, num_blocks - 2048);
*seg_desc_len = offset - XCOPY_DESC_OFFSET - *tgt_desc_len; *seg_desc_len = offset - XCOPY_DESC_OFFSET - *tgt_desc_len;
return offset; return offset;
} }
void void
test_extendedcopy_descr_limits(void) test_extendedcopy_descr_limits(void)
{ {
struct scsi_task *edl_task; struct scsi_task *edl_task;
struct iscsi_data data; struct iscsi_data data;
unsigned char *xcopybuf; unsigned char *xcopybuf;
struct scsi_copy_results_op_params *opp = NULL; struct scsi_copy_results_op_params *opp = NULL;
int tgt_desc_len = 0, seg_desc_len = 0; int tgt_desc_len = 0, seg_desc_len = 0;
unsigned int alloc_len; unsigned int alloc_len;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test EXTENDED COPY descriptor limits"); logging(LOG_VERBOSE, "Test EXTENDED COPY descriptor limits");
CHECK_FOR_DATALOSS; CHECK_FOR_DATALOSS;
logging(LOG_VERBOSE, "Issue RECEIVE COPY RESULTS (OPERATING PARAMS)"); logging(LOG_VERBOSE, "Issue RECEIVE COPY RESULTS (OPERATING PARAMS)");
RECEIVE_COPY_RESULTS(&edl_task, sd, SCSI_COPY_RESULTS_OP_PARAMS, 0, RECEIVE_COPY_RESULTS(&edl_task, sd, SCSI_COPY_RESULTS_OP_PARAMS, 0,
(void **)&opp, EXPECT_STATUS_GOOD); (void **)&opp, EXPECT_STATUS_GOOD);
/* Allocate buffer to accommodate (MAX+1) target and /* Allocate buffer to accommodate (MAX+1) target and
* segment descriptors */ * segment descriptors */
alloc_len = XCOPY_DESC_OFFSET + alloc_len = XCOPY_DESC_OFFSET +
(opp->max_target_desc_count+1) * (opp->max_target_desc_count+1) *
get_desc_len(IDENT_DESCR_TGT_DESCR) + get_desc_len(IDENT_DESCR_TGT_DESCR) +
(opp->max_segment_desc_count+1) * (opp->max_segment_desc_count+1) *
get_desc_len(BLK_TO_BLK_SEG_DESCR); get_desc_len(BLK_TO_BLK_SEG_DESCR);
data.data = alloca(alloc_len); data.data = alloca(alloc_len);
xcopybuf = data.data; xcopybuf = data.data;
memset(xcopybuf, 0, alloc_len); memset(xcopybuf, 0, alloc_len);
logging(LOG_VERBOSE, logging(LOG_VERBOSE,
"Test sending more than supported target descriptors"); "Test sending more than supported target descriptors");
data.size = init_xcopy_descr(xcopybuf, XCOPY_DESC_OFFSET, data.size = init_xcopy_descr(xcopybuf, XCOPY_DESC_OFFSET,
(opp->max_target_desc_count+1), 1, (opp->max_target_desc_count+1), 1,
&tgt_desc_len, &seg_desc_len); &tgt_desc_len, &seg_desc_len);
populate_param_header(xcopybuf, 1, 0, 0, 0, populate_param_header(xcopybuf, 1, 0, 0, 0,
tgt_desc_len, seg_desc_len, 0); tgt_desc_len, seg_desc_len, 0);
EXTENDEDCOPY(sd, &data, EXPECT_TOO_MANY_DESCR); EXTENDEDCOPY(sd, &data, EXPECT_TOO_MANY_DESCR);
logging(LOG_VERBOSE, logging(LOG_VERBOSE,
"Test sending more than supported segment descriptors"); "Test sending more than supported segment descriptors");
memset(xcopybuf, 0, alloc_len); memset(xcopybuf, 0, alloc_len);
data.size = init_xcopy_descr(xcopybuf, XCOPY_DESC_OFFSET, 1, data.size = init_xcopy_descr(xcopybuf, XCOPY_DESC_OFFSET, 1,
(opp->max_segment_desc_count+1), (opp->max_segment_desc_count+1),
&tgt_desc_len, &seg_desc_len); &tgt_desc_len, &seg_desc_len);
populate_param_header(xcopybuf, 2, 0, 0, 0, populate_param_header(xcopybuf, 2, 0, 0, 0,
tgt_desc_len, seg_desc_len, 0); tgt_desc_len, seg_desc_len, 0);
EXTENDEDCOPY(sd, &data, EXPECT_TOO_MANY_DESCR); EXTENDEDCOPY(sd, &data, EXPECT_TOO_MANY_DESCR);
logging(LOG_VERBOSE, logging(LOG_VERBOSE,
"Test sending descriptors > Maximum Descriptor List Length"); "Test sending descriptors > Maximum Descriptor List Length");
memset(xcopybuf, 0, alloc_len); memset(xcopybuf, 0, alloc_len);
if (opp->max_desc_list_length < alloc_len) { if (opp->max_desc_list_length < alloc_len) {
data.size = init_xcopy_descr(xcopybuf, XCOPY_DESC_OFFSET, data.size = init_xcopy_descr(xcopybuf, XCOPY_DESC_OFFSET,
(opp->max_target_desc_count+1), (opp->max_target_desc_count+1),
(opp->max_segment_desc_count+1), (opp->max_segment_desc_count+1),
&tgt_desc_len, &seg_desc_len); &tgt_desc_len, &seg_desc_len);
populate_param_header(xcopybuf, 3, 0, 0, 0, populate_param_header(xcopybuf, 3, 0, 0, 0,
tgt_desc_len, seg_desc_len, 0); tgt_desc_len, seg_desc_len, 0);
EXTENDEDCOPY(sd, &data, EXPECT_PARAM_LIST_LEN_ERR); EXTENDEDCOPY(sd, &data, EXPECT_PARAM_LIST_LEN_ERR);
} }
scsi_free_scsi_task(edl_task); scsi_free_scsi_task(edl_task);
} }

View File

@@ -28,60 +28,60 @@
#include "iscsi-test-cu.h" #include "iscsi-test-cu.h"
int init_xcopybuf(unsigned char *buf, int tgt_desc_type, int seg_desc_type, int init_xcopybuf(unsigned char *buf, int tgt_desc_type, int seg_desc_type,
int *tgt_desc_len, int *seg_desc_len) int *tgt_desc_len, int *seg_desc_len)
{ {
int offset = XCOPY_DESC_OFFSET; int offset = XCOPY_DESC_OFFSET;
offset += populate_tgt_desc(buf+offset, tgt_desc_type, LU_ID_TYPE_LUN, offset += populate_tgt_desc(buf+offset, tgt_desc_type, LU_ID_TYPE_LUN,
0, 0, 0, 0, sd); 0, 0, 0, 0, sd);
*tgt_desc_len = offset - XCOPY_DESC_OFFSET; *tgt_desc_len = offset - XCOPY_DESC_OFFSET;
if (seg_desc_type == BLK_TO_BLK_SEG_DESCR) if (seg_desc_type == BLK_TO_BLK_SEG_DESCR)
offset += populate_seg_desc_b2b(buf+offset, 0, 0, 0, 0, 2048, 0, offset += populate_seg_desc_b2b(buf+offset, 0, 0, 0, 0, 2048, 0,
num_blocks - 2048); num_blocks - 2048);
else else
offset += populate_seg_desc_hdr(buf+offset, seg_desc_type, offset += populate_seg_desc_hdr(buf+offset, seg_desc_type,
0, 0, 0, 0); 0, 0, 0, 0);
*seg_desc_len = offset - XCOPY_DESC_OFFSET - *tgt_desc_len; *seg_desc_len = offset - XCOPY_DESC_OFFSET - *tgt_desc_len;
return offset; return offset;
} }
void void
test_extendedcopy_descr_type(void) test_extendedcopy_descr_type(void)
{ {
int tgt_desc_len = 0, seg_desc_len = 0, alloc_len; int tgt_desc_len = 0, seg_desc_len = 0, alloc_len;
struct iscsi_data data; struct iscsi_data data;
unsigned char *xcopybuf; unsigned char *xcopybuf;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, logging(LOG_VERBOSE,
"Test EXTENDED COPY unsupported descriptor types"); "Test EXTENDED COPY unsupported descriptor types");
CHECK_FOR_DATALOSS; CHECK_FOR_DATALOSS;
alloc_len = XCOPY_DESC_OFFSET + alloc_len = XCOPY_DESC_OFFSET +
get_desc_len(IDENT_DESCR_TGT_DESCR) + get_desc_len(IDENT_DESCR_TGT_DESCR) +
get_desc_len(BLK_TO_BLK_SEG_DESCR); get_desc_len(BLK_TO_BLK_SEG_DESCR);
data.data = alloca(alloc_len); data.data = alloca(alloc_len);
xcopybuf = data.data; xcopybuf = data.data;
memset(xcopybuf, 0, alloc_len); memset(xcopybuf, 0, alloc_len);
logging(LOG_VERBOSE, logging(LOG_VERBOSE,
"Send Fibre Channel N_Port_Name target descriptor"); "Send Fibre Channel N_Port_Name target descriptor");
data.size = init_xcopybuf(xcopybuf, 0xE0, BLK_TO_BLK_SEG_DESCR, data.size = init_xcopybuf(xcopybuf, 0xE0, BLK_TO_BLK_SEG_DESCR,
&tgt_desc_len, &seg_desc_len); &tgt_desc_len, &seg_desc_len);
populate_param_header(xcopybuf, 1, 0, 0, 0, populate_param_header(xcopybuf, 1, 0, 0, 0,
tgt_desc_len, seg_desc_len, 0); tgt_desc_len, seg_desc_len, 0);
EXTENDEDCOPY(sd, &data, EXPECT_UNSUPP_DESCR_CODE); EXTENDEDCOPY(sd, &data, EXPECT_UNSUPP_DESCR_CODE);
logging(LOG_VERBOSE, "Send Stream-to-Stream Copy segment descriptor"); logging(LOG_VERBOSE, "Send Stream-to-Stream Copy segment descriptor");
memset(xcopybuf, 0, alloc_len); memset(xcopybuf, 0, alloc_len);
data.size = init_xcopybuf(xcopybuf, IDENT_DESCR_TGT_DESCR, data.size = init_xcopybuf(xcopybuf, IDENT_DESCR_TGT_DESCR,
STRM_TO_STRM_SEG_DESCR, STRM_TO_STRM_SEG_DESCR,
&tgt_desc_len, &seg_desc_len); &tgt_desc_len, &seg_desc_len);
populate_param_header(xcopybuf, 1, 0, 0, 0, populate_param_header(xcopybuf, 1, 0, 0, 0,
tgt_desc_len, seg_desc_len, 0); tgt_desc_len, seg_desc_len, 0);
EXTENDEDCOPY(sd, &data, EXPECT_UNSUPP_DESCR_CODE); EXTENDEDCOPY(sd, &data, EXPECT_UNSUPP_DESCR_CODE);
} }

View File

@@ -30,47 +30,47 @@
void void
test_extendedcopy_param(void) test_extendedcopy_param(void)
{ {
int tgt_desc_len = 0, seg_desc_len = 0, offset = XCOPY_DESC_OFFSET; int tgt_desc_len = 0, seg_desc_len = 0, offset = XCOPY_DESC_OFFSET;
struct iscsi_data data; struct iscsi_data data;
unsigned char *xcopybuf; unsigned char *xcopybuf;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test EXTENDED COPY parameter list length"); logging(LOG_VERBOSE, "Test EXTENDED COPY parameter list length");
CHECK_FOR_DATALOSS; CHECK_FOR_DATALOSS;
data.size = XCOPY_DESC_OFFSET + data.size = XCOPY_DESC_OFFSET +
get_desc_len(IDENT_DESCR_TGT_DESCR) + get_desc_len(IDENT_DESCR_TGT_DESCR) +
get_desc_len(BLK_TO_BLK_SEG_DESCR); get_desc_len(BLK_TO_BLK_SEG_DESCR);
data.data = alloca(data.size); data.data = alloca(data.size);
xcopybuf = data.data; xcopybuf = data.data;
memset(xcopybuf, 0, data.size); memset(xcopybuf, 0, data.size);
offset += populate_tgt_desc(xcopybuf+offset, IDENT_DESCR_TGT_DESCR, offset += populate_tgt_desc(xcopybuf+offset, IDENT_DESCR_TGT_DESCR,
LU_ID_TYPE_LUN, 0, 0, 0, 0, sd); LU_ID_TYPE_LUN, 0, 0, 0, 0, sd);
tgt_desc_len = offset - XCOPY_DESC_OFFSET; tgt_desc_len = offset - XCOPY_DESC_OFFSET;
offset += populate_seg_desc_b2b(xcopybuf+offset, 0, 0, 0, 0, offset += populate_seg_desc_b2b(xcopybuf+offset, 0, 0, 0, 0,
2048, 0, num_blocks - 2048); 2048, 0, num_blocks - 2048);
seg_desc_len = offset - XCOPY_DESC_OFFSET - tgt_desc_len; seg_desc_len = offset - XCOPY_DESC_OFFSET - tgt_desc_len;
populate_param_header(xcopybuf, 1, 0, 0, 0, populate_param_header(xcopybuf, 1, 0, 0, 0,
tgt_desc_len, seg_desc_len, 0); tgt_desc_len, seg_desc_len, 0);
logging(LOG_VERBOSE, logging(LOG_VERBOSE,
"Test parameter list length truncating target descriptor"); "Test parameter list length truncating target descriptor");
data.size = XCOPY_DESC_OFFSET + data.size = XCOPY_DESC_OFFSET +
get_desc_len(IDENT_DESCR_TGT_DESCR) - 1; get_desc_len(IDENT_DESCR_TGT_DESCR) - 1;
EXTENDEDCOPY(sd, &data, EXPECT_PARAM_LIST_LEN_ERR); EXTENDEDCOPY(sd, &data, EXPECT_PARAM_LIST_LEN_ERR);
logging(LOG_VERBOSE, logging(LOG_VERBOSE,
"Test parameter list length truncating segment descriptor"); "Test parameter list length truncating segment descriptor");
data.size = XCOPY_DESC_OFFSET + data.size = XCOPY_DESC_OFFSET +
get_desc_len(IDENT_DESCR_TGT_DESCR) + get_desc_len(IDENT_DESCR_TGT_DESCR) +
get_desc_len(BLK_TO_BLK_SEG_DESCR) - 1; get_desc_len(BLK_TO_BLK_SEG_DESCR) - 1;
EXTENDEDCOPY(sd, &data, EXPECT_PARAM_LIST_LEN_ERR); EXTENDEDCOPY(sd, &data, EXPECT_PARAM_LIST_LEN_ERR);
logging(LOG_VERBOSE, "Test parameter list length = 0"); logging(LOG_VERBOSE, "Test parameter list length = 0");
data.size = 0; data.size = 0;
EXTENDEDCOPY(sd, &data, EXPECT_STATUS_GOOD); EXTENDEDCOPY(sd, &data, EXPECT_STATUS_GOOD);
} }

View File

@@ -30,55 +30,55 @@
void void
test_extendedcopy_simple(void) test_extendedcopy_simple(void)
{ {
int tgt_desc_len = 0, seg_desc_len = 0, offset = XCOPY_DESC_OFFSET; int tgt_desc_len = 0, seg_desc_len = 0, offset = XCOPY_DESC_OFFSET;
struct iscsi_data data; struct iscsi_data data;
unsigned char *xcopybuf; unsigned char *xcopybuf;
unsigned char *buf1 = malloc(2048*block_size); unsigned char *buf1 = malloc(2048*block_size);
unsigned char *buf2 = malloc(2048*block_size); unsigned char *buf2 = malloc(2048*block_size);
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, logging(LOG_VERBOSE,
"Test EXTENDED COPY of 2048 blocks from start of LUN to end of LUN"); "Test EXTENDED COPY of 2048 blocks from start of LUN to end of LUN");
CHECK_FOR_DATALOSS; CHECK_FOR_DATALOSS;
logging(LOG_VERBOSE, "Write 2048 blocks of 'A' at LBA:0"); logging(LOG_VERBOSE, "Write 2048 blocks of 'A' at LBA:0");
memset(buf1, 'A', 2048*block_size); memset(buf1, 'A', 2048*block_size);
WRITE16(sd, 0, 2048*block_size, block_size, 0, 0, 0, 0, 0, WRITE16(sd, 0, 2048*block_size, block_size, 0, 0, 0, 0, 0,
buf1, EXPECT_STATUS_GOOD); buf1, EXPECT_STATUS_GOOD);
data.size = XCOPY_DESC_OFFSET + data.size = XCOPY_DESC_OFFSET +
get_desc_len(IDENT_DESCR_TGT_DESCR) + get_desc_len(IDENT_DESCR_TGT_DESCR) +
get_desc_len(BLK_TO_BLK_SEG_DESCR); get_desc_len(BLK_TO_BLK_SEG_DESCR);
data.data = alloca(data.size); data.data = alloca(data.size);
xcopybuf = data.data; xcopybuf = data.data;
memset(xcopybuf, 0, data.size); memset(xcopybuf, 0, data.size);
/* Initialize target descriptor list with one target descriptor */ /* Initialize target descriptor list with one target descriptor */
offset += populate_tgt_desc(xcopybuf+offset, IDENT_DESCR_TGT_DESCR, offset += populate_tgt_desc(xcopybuf+offset, IDENT_DESCR_TGT_DESCR,
LU_ID_TYPE_LUN, 0, 0, 0, 0, sd); LU_ID_TYPE_LUN, 0, 0, 0, 0, sd);
tgt_desc_len = offset - XCOPY_DESC_OFFSET; tgt_desc_len = offset - XCOPY_DESC_OFFSET;
/* Iniitialize segment descriptor list with one segment descriptor */ /* Iniitialize segment descriptor list with one segment descriptor */
offset += populate_seg_desc_b2b(xcopybuf+offset, 0, 0, 0, 0, offset += populate_seg_desc_b2b(xcopybuf+offset, 0, 0, 0, 0,
2048, 0, num_blocks - 2048); 2048, 0, num_blocks - 2048);
seg_desc_len = offset - XCOPY_DESC_OFFSET - tgt_desc_len; seg_desc_len = offset - XCOPY_DESC_OFFSET - tgt_desc_len;
/* Initialize the parameter list header */ /* Initialize the parameter list header */
populate_param_header(xcopybuf, 1, 0, LIST_ID_USAGE_DISCARD, 0, populate_param_header(xcopybuf, 1, 0, LIST_ID_USAGE_DISCARD, 0,
tgt_desc_len, seg_desc_len, 0); tgt_desc_len, seg_desc_len, 0);
EXTENDEDCOPY(sd, &data, EXPECT_STATUS_GOOD); EXTENDEDCOPY(sd, &data, EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Read 2048 blocks from end of the LUN"); logging(LOG_VERBOSE, "Read 2048 blocks from end of the LUN");
READ16(sd, NULL, num_blocks - 2048, 2048*block_size, READ16(sd, NULL, num_blocks - 2048, 2048*block_size,
block_size, 0, 0, 0, 0, 0, buf2, block_size, 0, 0, 0, 0, 0, buf2,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
if (memcmp(buf1, buf2, 2048)) { if (memcmp(buf1, buf2, 2048)) {
CU_FAIL("Blocks were not copied correctly"); CU_FAIL("Blocks were not copied correctly");
} }
free(buf1); free(buf1);
free(buf2); free(buf2);
} }

View File

@@ -30,48 +30,48 @@
void void
test_extendedcopy_validate_seg_descr(void) test_extendedcopy_validate_seg_descr(void)
{ {
int tgt_desc_len = 0, seg_desc_len = 0, offset = XCOPY_DESC_OFFSET; int tgt_desc_len = 0, seg_desc_len = 0, offset = XCOPY_DESC_OFFSET;
struct iscsi_data data; struct iscsi_data data;
unsigned char *xcopybuf; unsigned char *xcopybuf;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test EXTENDED COPY segment descriptor fields"); logging(LOG_VERBOSE, "Test EXTENDED COPY segment descriptor fields");
CHECK_FOR_DATALOSS; CHECK_FOR_DATALOSS;
data.size = XCOPY_DESC_OFFSET + data.size = XCOPY_DESC_OFFSET +
get_desc_len(IDENT_DESCR_TGT_DESCR) + get_desc_len(IDENT_DESCR_TGT_DESCR) +
get_desc_len(BLK_TO_BLK_SEG_DESCR); get_desc_len(BLK_TO_BLK_SEG_DESCR);
data.data = alloca(data.size); data.data = alloca(data.size);
xcopybuf = data.data; xcopybuf = data.data;
memset(xcopybuf, 0, data.size); memset(xcopybuf, 0, data.size);
logging(LOG_VERBOSE, "Send invalid target descriptor index"); logging(LOG_VERBOSE, "Send invalid target descriptor index");
offset += populate_tgt_desc(xcopybuf+offset, IDENT_DESCR_TGT_DESCR, offset += populate_tgt_desc(xcopybuf+offset, IDENT_DESCR_TGT_DESCR,
LU_ID_TYPE_LUN, 0, 0, 0, 0, sd); LU_ID_TYPE_LUN, 0, 0, 0, 0, sd);
tgt_desc_len = offset - XCOPY_DESC_OFFSET; tgt_desc_len = offset - XCOPY_DESC_OFFSET;
/* Inaccessible DESTINATION TARGET DESCRIPTOR INDEX */ /* Inaccessible DESTINATION TARGET DESCRIPTOR INDEX */
offset += populate_seg_desc_b2b(xcopybuf+offset, 0, 0, 0, 1, offset += populate_seg_desc_b2b(xcopybuf+offset, 0, 0, 0, 1,
2048, 0, num_blocks - 2048); 2048, 0, num_blocks - 2048);
seg_desc_len = offset - XCOPY_DESC_OFFSET - tgt_desc_len; seg_desc_len = offset - XCOPY_DESC_OFFSET - tgt_desc_len;
populate_param_header(xcopybuf, 1, 0, 0, 0, populate_param_header(xcopybuf, 1, 0, 0, 0,
tgt_desc_len, seg_desc_len, 0); tgt_desc_len, seg_desc_len, 0);
EXTENDEDCOPY(sd, &data, EXPECT_COPY_ABORTED); EXTENDEDCOPY(sd, &data, EXPECT_COPY_ABORTED);
logging(LOG_VERBOSE, logging(LOG_VERBOSE,
"Number of copy blocks beyond destination block device capacity"); "Number of copy blocks beyond destination block device capacity");
memset(xcopybuf, 0, data.size); memset(xcopybuf, 0, data.size);
offset = XCOPY_DESC_OFFSET; offset = XCOPY_DESC_OFFSET;
offset += populate_tgt_desc(xcopybuf+offset, IDENT_DESCR_TGT_DESCR, offset += populate_tgt_desc(xcopybuf+offset, IDENT_DESCR_TGT_DESCR,
LU_ID_TYPE_LUN, 0, 0, 0, 0, sd); LU_ID_TYPE_LUN, 0, 0, 0, 0, sd);
tgt_desc_len = offset - XCOPY_DESC_OFFSET; tgt_desc_len = offset - XCOPY_DESC_OFFSET;
/* Beyond EOL */ /* Beyond EOL */
offset += populate_seg_desc_b2b(xcopybuf+offset, 0, 0, 0, 0, offset += populate_seg_desc_b2b(xcopybuf+offset, 0, 0, 0, 0,
2048, 0, num_blocks - 1); 2048, 0, num_blocks - 1);
seg_desc_len = offset - XCOPY_DESC_OFFSET - tgt_desc_len; seg_desc_len = offset - XCOPY_DESC_OFFSET - tgt_desc_len;
populate_param_header(xcopybuf, 1, 0, 0, 0, populate_param_header(xcopybuf, 1, 0, 0, 0,
tgt_desc_len, seg_desc_len, 0); tgt_desc_len, seg_desc_len, 0);
EXTENDEDCOPY(sd, &data, EXPECT_COPY_ABORTED); EXTENDEDCOPY(sd, &data, EXPECT_COPY_ABORTED);
} }

View File

@@ -30,47 +30,47 @@
void void
test_extendedcopy_validate_tgt_descr(void) test_extendedcopy_validate_tgt_descr(void)
{ {
int tgt_desc_len = 0, seg_desc_len = 0, offset = XCOPY_DESC_OFFSET; int tgt_desc_len = 0, seg_desc_len = 0, offset = XCOPY_DESC_OFFSET;
struct iscsi_data data; struct iscsi_data data;
unsigned char *xcopybuf; unsigned char *xcopybuf;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test EXTENDED COPY target descriptor fields"); logging(LOG_VERBOSE, "Test EXTENDED COPY target descriptor fields");
CHECK_FOR_DATALOSS; CHECK_FOR_DATALOSS;
data.size = XCOPY_DESC_OFFSET + data.size = XCOPY_DESC_OFFSET +
get_desc_len(IDENT_DESCR_TGT_DESCR) + get_desc_len(IDENT_DESCR_TGT_DESCR) +
get_desc_len(BLK_TO_BLK_SEG_DESCR); get_desc_len(BLK_TO_BLK_SEG_DESCR);
data.data = alloca(data.size); data.data = alloca(data.size);
xcopybuf = data.data; xcopybuf = data.data;
memset(xcopybuf, 0, data.size); memset(xcopybuf, 0, data.size);
logging(LOG_VERBOSE, "Unsupported LU_ID TYPE"); logging(LOG_VERBOSE, "Unsupported LU_ID TYPE");
/* Unsupported LU ID TYPE */ /* Unsupported LU ID TYPE */
offset += populate_tgt_desc(xcopybuf+offset, IDENT_DESCR_TGT_DESCR, offset += populate_tgt_desc(xcopybuf+offset, IDENT_DESCR_TGT_DESCR,
LU_ID_TYPE_RSVD, 0, 0, 0, 0, sd); LU_ID_TYPE_RSVD, 0, 0, 0, 0, sd);
tgt_desc_len = offset - XCOPY_DESC_OFFSET; tgt_desc_len = offset - XCOPY_DESC_OFFSET;
offset += populate_seg_desc_b2b(xcopybuf+offset, 0, 0, 0, 0, offset += populate_seg_desc_b2b(xcopybuf+offset, 0, 0, 0, 0,
2048, 0, num_blocks - 2048); 2048, 0, num_blocks - 2048);
seg_desc_len = offset - XCOPY_DESC_OFFSET - tgt_desc_len; seg_desc_len = offset - XCOPY_DESC_OFFSET - tgt_desc_len;
populate_param_header(xcopybuf, 1, 0, 0, 0, populate_param_header(xcopybuf, 1, 0, 0, 0,
tgt_desc_len, seg_desc_len, 0); tgt_desc_len, seg_desc_len, 0);
EXTENDEDCOPY(sd, &data, EXPECT_INVALID_FIELD_IN_CDB); EXTENDEDCOPY(sd, &data, EXPECT_INVALID_FIELD_IN_CDB);
logging(LOG_VERBOSE, "Test NUL bit in target descriptor"); logging(LOG_VERBOSE, "Test NUL bit in target descriptor");
/* NUL bit */ /* NUL bit */
memset(xcopybuf, 0, data.size); memset(xcopybuf, 0, data.size);
offset = XCOPY_DESC_OFFSET; offset = XCOPY_DESC_OFFSET;
offset += populate_tgt_desc(xcopybuf+offset, IDENT_DESCR_TGT_DESCR, offset += populate_tgt_desc(xcopybuf+offset, IDENT_DESCR_TGT_DESCR,
LU_ID_TYPE_LUN, 1, 0, 0, 0, sd); LU_ID_TYPE_LUN, 1, 0, 0, 0, sd);
tgt_desc_len = offset - XCOPY_DESC_OFFSET; tgt_desc_len = offset - XCOPY_DESC_OFFSET;
offset += populate_seg_desc_b2b(xcopybuf+offset, 0, 0, 0, 0, offset += populate_seg_desc_b2b(xcopybuf+offset, 0, 0, 0, 0,
2048, 0, num_blocks - 2048); 2048, 0, num_blocks - 2048);
seg_desc_len = offset - XCOPY_DESC_OFFSET - tgt_desc_len; seg_desc_len = offset - XCOPY_DESC_OFFSET - tgt_desc_len;
populate_param_header(xcopybuf, 1, 0, 0, 0, populate_param_header(xcopybuf, 1, 0, 0, 0,
tgt_desc_len, seg_desc_len, 0); tgt_desc_len, seg_desc_len, 0);
EXTENDEDCOPY(sd, &data, EXPECT_COPY_ABORTED); EXTENDEDCOPY(sd, &data, EXPECT_COPY_ABORTED);
} }

View File

@@ -29,17 +29,17 @@
void void
test_get_lba_status_beyond_eol(void) test_get_lba_status_beyond_eol(void)
{ {
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test GETLBASTATUS one block beyond the end of the LUN"); logging(LOG_VERBOSE, "Test GETLBASTATUS one block beyond the end of the LUN");
GETLBASTATUS(sd, NULL, num_blocks + 1, 24, GETLBASTATUS(sd, NULL, num_blocks + 1, 24,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
logging(LOG_VERBOSE, "Test GETLBASTATUS at LBA 2^63"); logging(LOG_VERBOSE, "Test GETLBASTATUS at LBA 2^63");
GETLBASTATUS(sd, NULL, 0x8000000000000000ULL, 24, GETLBASTATUS(sd, NULL, 0x8000000000000000ULL, 24,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
logging(LOG_VERBOSE, "Test GETLBASTATUS at LBA -1"); logging(LOG_VERBOSE, "Test GETLBASTATUS at LBA -1");
GETLBASTATUS(sd, NULL, 0xffffffffffffffffULL, 24, GETLBASTATUS(sd, NULL, 0xffffffffffffffffULL, 24,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }

View File

@@ -29,18 +29,18 @@
void void
test_get_lba_status_simple(void) test_get_lba_status_simple(void)
{ {
int i; int i;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test GETLBASTATUS of 1-256 blocks at the start of the LUN"); logging(LOG_VERBOSE, "Test GETLBASTATUS of 1-256 blocks at the start of the LUN");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
GETLBASTATUS(sd, NULL, i, 24, GETLBASTATUS(sd, NULL, i, 24,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }
logging(LOG_VERBOSE, "Test GETLBASTATUS of 1-256 blocks at the end of the LUN"); logging(LOG_VERBOSE, "Test GETLBASTATUS of 1-256 blocks at the end of the LUN");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
GETLBASTATUS(sd, NULL, num_blocks - i, 24, GETLBASTATUS(sd, NULL, num_blocks - i, 24,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }
} }

View File

@@ -29,120 +29,120 @@
void void
test_get_lba_status_unmap_single(void) test_get_lba_status_unmap_single(void)
{ {
uint64_t i; uint64_t i;
struct unmap_list list[1]; struct unmap_list list[1];
struct scsi_task *t = NULL; struct scsi_task *t = NULL;
struct scsi_get_lba_status *lbas = NULL; struct scsi_get_lba_status *lbas = NULL;
struct scsi_lba_status_descriptor *lbasd = NULL; struct scsi_lba_status_descriptor *lbasd = NULL;
CHECK_FOR_DATALOSS; CHECK_FOR_DATALOSS;
CHECK_FOR_THIN_PROVISIONING; CHECK_FOR_THIN_PROVISIONING;
CHECK_FOR_LBPU; CHECK_FOR_LBPU;
memset(scratch, 'A', (256 + lbppb + 1) * block_size); memset(scratch, 'A', (256 + lbppb + 1) * block_size);
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test GETLBASTATUS for a single unmapped block " logging(LOG_VERBOSE, "Test GETLBASTATUS for a single unmapped block "
"at offset 0-255"); "at offset 0-255");
logging(LOG_VERBOSE, "We have %d logical blocks per physical block", logging(LOG_VERBOSE, "We have %d logical blocks per physical block",
lbppb); lbppb);
logging(LOG_VERBOSE, "Write the first %i blocks with a known " logging(LOG_VERBOSE, "Write the first %i blocks with a known "
"pattern and thus map the blocks", 256 + lbppb); "pattern and thus map the blocks", 256 + lbppb);
WRITE10(sd, 0, (256 + lbppb) * block_size, WRITE10(sd, 0, (256 + lbppb) * block_size,
block_size, 0, 0, 0, 0, 0, scratch, block_size, 0, 0, 0, 0, 0, scratch,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
for (i = 0; i + lbppb <= 256; i += lbppb) { for (i = 0; i + lbppb <= 256; i += lbppb) {
logging(LOG_VERBOSE, "Unmap a single physical block at LBA:%" logging(LOG_VERBOSE, "Unmap a single physical block at LBA:%"
PRIu64 " (number of logical blocks: %d)", i, lbppb); PRIu64 " (number of logical blocks: %d)", i, lbppb);
list[0].lba = i; list[0].lba = i;
list[0].num = lbppb; list[0].num = lbppb;
UNMAP(sd, 0, list, 1, UNMAP(sd, 0, list, 1,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Read the status of the block at LBA:%" logging(LOG_VERBOSE, "Read the status of the block at LBA:%"
PRIu64, i); PRIu64, i);
GETLBASTATUS(sd, NULL, i, 24, GETLBASTATUS(sd, NULL, i, 24,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Read the status of the block at LBA:%" logging(LOG_VERBOSE, "Read the status of the block at LBA:%"
PRIu64, i + lbppb); PRIu64, i + lbppb);
GETLBASTATUS(sd, &t, i + lbppb, 24, GETLBASTATUS(sd, &t, i + lbppb, 24,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
if (t == NULL) { if (t == NULL) {
CU_FAIL("[FAILED] GETLBASTATUS task is NULL"); CU_FAIL("[FAILED] GETLBASTATUS task is NULL");
return; return;
} }
lbas = scsi_datain_unmarshall(t); lbas = scsi_datain_unmarshall(t);
if (lbas == NULL) { if (lbas == NULL) {
CU_FAIL("[FAILED] GETLBASTATUS command: failed " CU_FAIL("[FAILED] GETLBASTATUS command: failed "
"to unmarshall data."); "to unmarshall data.");
scsi_free_scsi_task(t); scsi_free_scsi_task(t);
return; return;
} }
lbasd = &lbas->descriptors[0]; lbasd = &lbas->descriptors[0];
if (lbasd->lba != i + lbppb) { if (lbasd->lba != i + lbppb) {
CU_FAIL("[FAILED] GETLBASTATUS command: " CU_FAIL("[FAILED] GETLBASTATUS command: "
"lba offset in first descriptor does not " "lba offset in first descriptor does not "
"match request."); "match request.");
scsi_free_scsi_task(t); scsi_free_scsi_task(t);
return; return;
} }
if (lbasd->provisioning != SCSI_PROVISIONING_TYPE_MAPPED) { if (lbasd->provisioning != SCSI_PROVISIONING_TYPE_MAPPED) {
CU_FAIL("[FAILED] LBA should be mapped but isn't"); CU_FAIL("[FAILED] LBA should be mapped but isn't");
return; return;
} }
scsi_free_scsi_task(t); scsi_free_scsi_task(t);
} }
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test GETLBASTATUS for a single range of 1-255 " logging(LOG_VERBOSE, "Test GETLBASTATUS for a single range of 1-255 "
"blocks at offset 0"); "blocks at offset 0");
for (i = lbppb; i + lbppb <= 256; i += lbppb) { for (i = lbppb; i + lbppb <= 256; i += lbppb) {
logging(LOG_VERBOSE, "Write the first %i blocks with a known " logging(LOG_VERBOSE, "Write the first %i blocks with a known "
"pattern and thus map the blocks", (256 + lbppb)); "pattern and thus map the blocks", (256 + lbppb));
WRITE10(sd, 0, (256 + lbppb) * block_size, WRITE10(sd, 0, (256 + lbppb) * block_size,
block_size, 0, 0, 0, 0, 0, scratch, block_size, 0, 0, 0, 0, 0, scratch,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Unmap %" PRIu64 " blocks at LBA 0", i); logging(LOG_VERBOSE, "Unmap %" PRIu64 " blocks at LBA 0", i);
list[0].lba = 0; list[0].lba = 0;
list[0].num = i; list[0].num = i;
UNMAP(sd, 0, list, 1, UNMAP(sd, 0, list, 1,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Read the status of the block at LBA:0"); logging(LOG_VERBOSE, "Read the status of the block at LBA:0");
GETLBASTATUS(sd, NULL, 0, 24, GETLBASTATUS(sd, NULL, 0, 24,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Read the status of the block at LBA:%" PRIu64, i + 1); logging(LOG_VERBOSE, "Read the status of the block at LBA:%" PRIu64, i + 1);
GETLBASTATUS(sd, &t, i + 1, 24, GETLBASTATUS(sd, &t, i + 1, 24,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
if (t == NULL) { if (t == NULL) {
CU_FAIL("[FAILED] GETLBASTATUS task is NULL"); CU_FAIL("[FAILED] GETLBASTATUS task is NULL");
return; return;
} }
lbas = scsi_datain_unmarshall(t); lbas = scsi_datain_unmarshall(t);
if (lbas == NULL) { if (lbas == NULL) {
CU_FAIL("[FAILED] GETLBASTATUS command: failed " CU_FAIL("[FAILED] GETLBASTATUS command: failed "
"to unmarshall data."); "to unmarshall data.");
scsi_free_scsi_task(t); scsi_free_scsi_task(t);
return; return;
} }
lbasd = &lbas->descriptors[0]; lbasd = &lbas->descriptors[0];
if (lbasd->lba != i + lbppb) { if (lbasd->lba != i + lbppb) {
CU_FAIL("[FAILED] GETLBASTATUS command: " CU_FAIL("[FAILED] GETLBASTATUS command: "
"lba offset in first descriptor does not " "lba offset in first descriptor does not "
"match request."); "match request.");
scsi_free_scsi_task(t); scsi_free_scsi_task(t);
return; return;
} }
if (lbasd->provisioning != SCSI_PROVISIONING_TYPE_MAPPED) { if (lbasd->provisioning != SCSI_PROVISIONING_TYPE_MAPPED) {
CU_FAIL("[FAILED] LBA should be mapped but isn't"); CU_FAIL("[FAILED] LBA should be mapped but isn't");
return; return;
} }
scsi_free_scsi_task(t); scsi_free_scsi_task(t);
} }
} }

View File

@@ -28,85 +28,85 @@
void void
test_inquiry_alloc_length(void) test_inquiry_alloc_length(void)
{ {
int ret, i; int ret, i;
struct scsi_inquiry_standard *std_inq; struct scsi_inquiry_standard *std_inq;
struct scsi_task *task2 = NULL; struct scsi_task *task2 = NULL;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test of the INQUIRY allocation length"); logging(LOG_VERBOSE, "Test of the INQUIRY allocation length");
logging(LOG_VERBOSE, "Verify we can read standard INQUIRY page with alloc length from 5-255"); logging(LOG_VERBOSE, "Verify we can read standard INQUIRY page with alloc length from 5-255");
for (i = 5; i < 256 ; i++) { for (i = 5; i < 256 ; i++) {
if (task != NULL) { if (task != NULL) {
scsi_free_scsi_task(task); scsi_free_scsi_task(task);
task = NULL; task = NULL;
} }
ret = inquiry(sd, &task, 0, 0, i, ret = inquiry(sd, &task, 0, 0, i,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
} }
logging(LOG_VERBOSE, "Verify we got at least 36 bytes of data when reading with alloc length 255"); logging(LOG_VERBOSE, "Verify we got at least 36 bytes of data when reading with alloc length 255");
CU_ASSERT(task->datain.size >= 36); CU_ASSERT(task->datain.size >= 36);
logging(LOG_VERBOSE, "Verify we can unmarshall the DATA-IN buffer"); logging(LOG_VERBOSE, "Verify we can unmarshall the DATA-IN buffer");
std_inq = scsi_datain_unmarshall(task); std_inq = scsi_datain_unmarshall(task);
CU_ASSERT_NOT_EQUAL(std_inq, NULL); CU_ASSERT_NOT_EQUAL(std_inq, NULL);
if (std_inq == NULL) { if (std_inq == NULL) {
logging(LOG_NORMAL, "[FAILED] Failed to unmarshall DATA-IN " logging(LOG_NORMAL, "[FAILED] Failed to unmarshall DATA-IN "
"buffer"); "buffer");
return; return;
} }
logging(LOG_VERBOSE, "Verify peripheral-qualifier is 0"); logging(LOG_VERBOSE, "Verify peripheral-qualifier is 0");
CU_ASSERT_EQUAL(std_inq->qualifier, 0); CU_ASSERT_EQUAL(std_inq->qualifier, 0);
/* Final test. IF this claims SPC-3 or later then the target /* Final test. IF this claims SPC-3 or later then the target
supports 16-bit allocation lengths. Try reading INQ data supports 16-bit allocation lengths. Try reading INQ data
specifying 256 bytes as allocation length and make sure the specifying 256 bytes as allocation length and make sure the
target responds properly. target responds properly.
*/ */
logging(LOG_VERBOSE, "If version is SPC-3 or later INQUIRY supports 16-bit allocation lengths"); logging(LOG_VERBOSE, "If version is SPC-3 or later INQUIRY supports 16-bit allocation lengths");
switch (std_inq->version) { switch (std_inq->version) {
case 0x5: case 0x5:
case 0x6: case 0x6:
break; break;
default: default:
logging(LOG_NORMAL, "[SKIPPED] This device does not claim " logging(LOG_NORMAL, "[SKIPPED] This device does not claim "
"SPC-3 or later"); "SPC-3 or later");
CU_PASS("[SKIPPED] Not SPC-3 or later"); CU_PASS("[SKIPPED] Not SPC-3 or later");
goto finished; goto finished;
} }
scsi_free_scsi_task(task); scsi_free_scsi_task(task);
task = NULL; task = NULL;
logging(LOG_VERBOSE, "Version is SPC-3 or later. Read INQUIRY data using 16-bit allocation length"); logging(LOG_VERBOSE, "Version is SPC-3 or later. Read INQUIRY data using 16-bit allocation length");
logging(LOG_VERBOSE, "Read INQUIRY data with allocation length 511 (low order byte is 0xff)"); logging(LOG_VERBOSE, "Read INQUIRY data with allocation length 511 (low order byte is 0xff)");
ret = inquiry(sd, &task, 0, 0, 511, ret = inquiry(sd, &task, 0, 0, 511,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
logging(LOG_VERBOSE, "Read INQUIRY data with allocation length 512 (low order byte is 0x00)"); logging(LOG_VERBOSE, "Read INQUIRY data with allocation length 512 (low order byte is 0x00)");
ret = inquiry(sd, &task2, 0, 0, 512, ret = inquiry(sd, &task2, 0, 0, 512,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
logging(LOG_VERBOSE, "INQUIRY data should be the same when allocation length is 511 and 512 bytes"); logging(LOG_VERBOSE, "INQUIRY data should be the same when allocation length is 511 and 512 bytes");
ret = task->datain.size != task2->datain.size; ret = task->datain.size != task2->datain.size;
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
ret = memcmp(task->datain.data, task2->datain.data, task->datain.size); ret = memcmp(task->datain.data, task2->datain.data, task->datain.size);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
finished: finished:
if (task != NULL) { if (task != NULL) {
scsi_free_scsi_task(task); scsi_free_scsi_task(task);
task = NULL; task = NULL;
} }
if (task2 != NULL) { if (task2 != NULL) {
scsi_free_scsi_task(task2); scsi_free_scsi_task(task2);
task2 = NULL; task2 = NULL;
} }
} }

View File

@@ -27,158 +27,158 @@
static void check_lbp(int *supports_lbp) static void check_lbp(int *supports_lbp)
{ {
*supports_lbp = 0; *supports_lbp = 0;
CHECK_FOR_THIN_PROVISIONING; CHECK_FOR_THIN_PROVISIONING;
*supports_lbp = 1; *supports_lbp = 1;
} }
void void
test_inquiry_block_limits(void) test_inquiry_block_limits(void)
{ {
int supports_lbp, ret; int supports_lbp, ret;
struct scsi_inquiry_block_limits *bl; struct scsi_inquiry_block_limits *bl;
struct scsi_task *bl_task = NULL; struct scsi_task *bl_task = NULL;
struct scsi_inquiry_logical_block_provisioning *lbp = NULL; struct scsi_inquiry_logical_block_provisioning *lbp = NULL;
struct scsi_task *lbp_task = NULL; struct scsi_task *lbp_task = NULL;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test of the INQUIRY Block Limits"); logging(LOG_VERBOSE, "Test of the INQUIRY Block Limits");
CHECK_FOR_SBC; CHECK_FOR_SBC;
logging(LOG_VERBOSE, "Block device. Verify that we can read Block " logging(LOG_VERBOSE, "Block device. Verify that we can read Block "
"Limits VPD"); "Limits VPD");
ret = inquiry(sd, &bl_task, ret = inquiry(sd, &bl_task,
1, SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS, 255, 1, SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS, 255,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
if (ret != 0) { if (ret != 0) {
logging(LOG_NORMAL, "[FAILURE] failed to send inquiry."); logging(LOG_NORMAL, "[FAILURE] failed to send inquiry.");
goto finished; goto finished;
} }
bl = scsi_datain_unmarshall(bl_task); bl = scsi_datain_unmarshall(bl_task);
if (bl == NULL) { if (bl == NULL) {
logging(LOG_NORMAL, "[FAILURE] failed to unmarshall inquiry " logging(LOG_NORMAL, "[FAILURE] failed to unmarshall inquiry "
"datain blob."); "datain blob.");
CU_FAIL("[FAILURE] failed to unmarshall inquiry " CU_FAIL("[FAILURE] failed to unmarshall inquiry "
"datain blob."); "datain blob.");
goto finished; goto finished;
} }
logging(LOG_VERBOSE, "Verify that the PageLength matches up with the " logging(LOG_VERBOSE, "Verify that the PageLength matches up with the "
"size of the DATA-IN buffer."); "size of the DATA-IN buffer.");
CU_ASSERT_EQUAL(bl_task->datain.size, bl_task->datain.data[3] + 4); CU_ASSERT_EQUAL(bl_task->datain.size, bl_task->datain.data[3] + 4);
if (bl_task->datain.size != bl_task->datain.data[3] + 4) { if (bl_task->datain.size != bl_task->datain.data[3] + 4) {
logging(LOG_NORMAL, "[FAILURE] Invalid PageLength returned. " logging(LOG_NORMAL, "[FAILURE] Invalid PageLength returned. "
"Was %d but expected %d", "Was %d but expected %d",
bl_task->datain.data[3], bl_task->datain.size - 4); bl_task->datain.data[3], bl_task->datain.size - 4);
} else { } else {
logging(LOG_VERBOSE, "[SUCCESS] PageLength matches DataIn " logging(LOG_VERBOSE, "[SUCCESS] PageLength matches DataIn "
"buffer size"); "buffer size");
} }
logging(LOG_VERBOSE, "Verify that the PageLength matches SCSI-level."); logging(LOG_VERBOSE, "Verify that the PageLength matches SCSI-level.");
/* if it is not SBC3 then we assume it must be SBC2 */ /* if it is not SBC3 then we assume it must be SBC2 */
if (sbc3_support) { if (sbc3_support) {
logging(LOG_VERBOSE, "Device claims SBC-3. Verify that " "page size is >= 60"); logging(LOG_VERBOSE, "Device claims SBC-3. Verify that " "page size is >= 60");
} else { } else {
logging(LOG_VERBOSE, "Device is not SBC-3. Verify that " logging(LOG_VERBOSE, "Device is not SBC-3. Verify that "
"PageLength == 8 (but allow >= 60 too. Some SBC-2 " "PageLength == 8 (but allow >= 60 too. Some SBC-2 "
"devices support some SBC-3 features."); "devices support some SBC-3 features.");
} }
if (bl_task->datain.data[3] == 8) { if (bl_task->datain.data[3] == 8) {
if (sbc3_support) { if (sbc3_support) {
logging(LOG_NORMAL, "[FAILURE] Invalid PageLength " logging(LOG_NORMAL, "[FAILURE] Invalid PageLength "
"returned. SBC3 claimed but page length " "returned. SBC3 claimed but page length "
"is 8."); "is 8.");
CU_FAIL("[FAILED] Invalid pagelength returned. " CU_FAIL("[FAILED] Invalid pagelength returned. "
"SBC3 claimed but page length is 8."); "SBC3 claimed but page length is 8.");
} }
} else if (bl_task->datain.size >= 60) { } else if (bl_task->datain.size >= 60) {
if (!sbc3_support) { if (!sbc3_support) {
logging(LOG_NORMAL, "[WARNING] SBC-3 pagelength " logging(LOG_NORMAL, "[WARNING] SBC-3 pagelength "
"(>=60) returned but SBC-3 support was not " "(>=60) returned but SBC-3 support was not "
"claimed in the standard inquiry page."); "claimed in the standard inquiry page.");
CU_FAIL("[WARNING] SBC-3 pagelength " CU_FAIL("[WARNING] SBC-3 pagelength "
"(>=60) returned but SBC-3 support was not " "(>=60) returned but SBC-3 support was not "
"claimed in the standard inquiry page."); "claimed in the standard inquiry page.");
} }
} }
if (bl_task->datain.data[3] != 0x3c) { if (bl_task->datain.data[3] != 0x3c) {
goto finished; goto finished;
} }
check_lbp(&supports_lbp); check_lbp(&supports_lbp);
if (!supports_lbp) if (!supports_lbp)
goto finished; goto finished;
/* /*
* MAXIMUM UNMAP LBA COUNT * MAXIMUM UNMAP LBA COUNT
* MAXIMUM UNMAP BLOCK DESCRIPTOR COUNT * MAXIMUM UNMAP BLOCK DESCRIPTOR COUNT
*/ */
logging(LOG_VERBOSE, "Try reading the logical block provisioning VPD"); logging(LOG_VERBOSE, "Try reading the logical block provisioning VPD");
ret = inquiry(sd, &lbp_task, ret = inquiry(sd, &lbp_task,
1, SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING, 255, 1, SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING, 255,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
if (ret == 0) { if (ret == 0) {
lbp = scsi_datain_unmarshall(lbp_task); lbp = scsi_datain_unmarshall(lbp_task);
if (lbp == NULL) { if (lbp == NULL) {
logging(LOG_NORMAL, "[FAILURE] failed to unmarshall " logging(LOG_NORMAL, "[FAILURE] failed to unmarshall "
"inquiry datain blob."); "inquiry datain blob.");
} }
} }
if (lbp && lbp->lbpu) { if (lbp && lbp->lbpu) {
/* We support UNMAP so MAXIMUM UNMAP LBA COUNT and /* We support UNMAP so MAXIMUM UNMAP LBA COUNT and
* MAXIMUM UNMAP BLOCK DESCRIPTOR COUNT. * MAXIMUM UNMAP BLOCK DESCRIPTOR COUNT.
* They must be > 0. * They must be > 0.
* It can be 0xffffffff which means no limit, but if there is * It can be 0xffffffff which means no limit, but if there is
* an explicit limit set, then we check that it looks sane. * an explicit limit set, then we check that it looks sane.
* Sane here means < 1M. * Sane here means < 1M.
*/ */
logging(LOG_VERBOSE, "Device claims UNMAP support via LBPU"); logging(LOG_VERBOSE, "Device claims UNMAP support via LBPU");
logging(LOG_VERBOSE, "Verify that MAXIMUM UNMAP LBA COUNT is " logging(LOG_VERBOSE, "Verify that MAXIMUM UNMAP LBA COUNT is "
"not 0"); "not 0");
CU_ASSERT_NOT_EQUAL(bl->max_unmap, 0); CU_ASSERT_NOT_EQUAL(bl->max_unmap, 0);
logging(LOG_VERBOSE, "Verify that MAXIMUM UNMAP LBA COUNT is " logging(LOG_VERBOSE, "Verify that MAXIMUM UNMAP LBA COUNT is "
"at least 2^LBPPBE"); "at least 2^LBPPBE");
CU_ASSERT_EQUAL(bl->max_unmap >= (1U << rc16->lbppbe), 1); CU_ASSERT_EQUAL(bl->max_unmap >= (1U << rc16->lbppbe), 1);
if (bl->max_unmap != 0xffffffff) { if (bl->max_unmap != 0xffffffff) {
logging(LOG_VERBOSE, "Verify that MAXIMUM UNMAP LBA " logging(LOG_VERBOSE, "Verify that MAXIMUM UNMAP LBA "
"COUNT is not insanely big"); "COUNT is not insanely big");
CU_ASSERT_TRUE(bl->max_unmap <= 1024*1024); CU_ASSERT_TRUE(bl->max_unmap <= 1024*1024);
} }
logging(LOG_VERBOSE, "Verify that MAXIMUM UNMAP BLOCK " logging(LOG_VERBOSE, "Verify that MAXIMUM UNMAP BLOCK "
"DESCRIPTOR COUNT is not 0"); "DESCRIPTOR COUNT is not 0");
CU_ASSERT_NOT_EQUAL(bl->max_unmap_bdc, 0); CU_ASSERT_NOT_EQUAL(bl->max_unmap_bdc, 0);
if (bl->max_unmap_bdc != 0xffffffff) { if (bl->max_unmap_bdc != 0xffffffff) {
logging(LOG_VERBOSE, "Verify that MAXIMUM UNMAP " logging(LOG_VERBOSE, "Verify that MAXIMUM UNMAP "
"BLOCK DESCRIPTOR COUNT is not insanely big"); "BLOCK DESCRIPTOR COUNT is not insanely big");
CU_ASSERT_TRUE(bl->max_unmap_bdc <= 1024*1024); CU_ASSERT_TRUE(bl->max_unmap_bdc <= 1024*1024);
} }
} else { } else {
logging(LOG_VERBOSE, "Device does not claim UNMAP support via " logging(LOG_VERBOSE, "Device does not claim UNMAP support via "
"LBPU"); "LBPU");
logging(LOG_VERBOSE, "Verify that MAXIMUM UNMAP LBA COUNT is " logging(LOG_VERBOSE, "Verify that MAXIMUM UNMAP LBA COUNT is "
"0"); "0");
CU_ASSERT_EQUAL(bl->max_unmap, 0); CU_ASSERT_EQUAL(bl->max_unmap, 0);
logging(LOG_VERBOSE, "Verify that MAXIMUM UNMAP BLOCK " logging(LOG_VERBOSE, "Verify that MAXIMUM UNMAP BLOCK "
"DESCRIPTOR COUNT is 0"); "DESCRIPTOR COUNT is 0");
CU_ASSERT_EQUAL(bl->max_unmap_bdc, 0); CU_ASSERT_EQUAL(bl->max_unmap_bdc, 0);
} }
finished: finished:
scsi_free_scsi_task(bl_task); scsi_free_scsi_task(bl_task);
scsi_free_scsi_task(lbp_task); scsi_free_scsi_task(lbp_task);
} }

View File

@@ -28,13 +28,13 @@
void void
test_inquiry_evpd(void) test_inquiry_evpd(void)
{ {
int ret; int ret;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test of the INQUIRY EVPD bit"); logging(LOG_VERBOSE, "Test of the INQUIRY EVPD bit");
logging(LOG_VERBOSE, "Verify that INQUIRY with EVPD==0 and PC!=0 is an error"); logging(LOG_VERBOSE, "Verify that INQUIRY with EVPD==0 and PC!=0 is an error");
ret = inquiry(sd, NULL, 0, 1, 256, ret = inquiry(sd, NULL, 0, 1, 256,
EXPECT_INVALID_FIELD_IN_CDB); EXPECT_INVALID_FIELD_IN_CDB);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
} }

View File

@@ -28,23 +28,23 @@
void void
test_inquiry_mandatory_vpd_sbc(void) test_inquiry_mandatory_vpd_sbc(void)
{ {
int ret; int ret;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test INQUIRY support for mandatory SBC VPD"); logging(LOG_VERBOSE, "Test INQUIRY support for mandatory SBC VPD");
CHECK_FOR_SBC; CHECK_FOR_SBC;
logging(LOG_VERBOSE, "SUPPORTED_VPD_PAGES is mandatory for SBC devices. Verify we can read it."); logging(LOG_VERBOSE, "SUPPORTED_VPD_PAGES is mandatory for SBC devices. Verify we can read it.");
ret = inquiry(sd, NULL, ret = inquiry(sd, NULL,
1, SCSI_INQUIRY_PAGECODE_SUPPORTED_VPD_PAGES, 255, 1, SCSI_INQUIRY_PAGECODE_SUPPORTED_VPD_PAGES, 255,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
logging(LOG_VERBOSE, "DEVICE_IDENTIFICATION is mandatory for SBC devices. Verify we can read it."); logging(LOG_VERBOSE, "DEVICE_IDENTIFICATION is mandatory for SBC devices. Verify we can read it.");
ret = inquiry(sd, NULL, ret = inquiry(sd, NULL,
1, SCSI_INQUIRY_PAGECODE_DEVICE_IDENTIFICATION, 255, 1, SCSI_INQUIRY_PAGECODE_DEVICE_IDENTIFICATION, 255,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
} }

View File

@@ -28,150 +28,150 @@
void void
test_inquiry_standard(void) test_inquiry_standard(void)
{ {
int ret, i; int ret, i;
struct scsi_inquiry_standard *std_inq; struct scsi_inquiry_standard *std_inq;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test of the standard INQUIRY page"); logging(LOG_VERBOSE, "Test of the standard INQUIRY page");
logging(LOG_VERBOSE, "Verify we can read standard INQUIRY page"); logging(LOG_VERBOSE, "Verify we can read standard INQUIRY page");
/* 260 bytes is the maximum possible size of the standard vpd */ /* 260 bytes is the maximum possible size of the standard vpd */
ret = inquiry(sd, &task, 0, 0, 260, ret = inquiry(sd, &task, 0, 0, 260,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
logging(LOG_VERBOSE, "Verify we got at least 36 bytes of data"); logging(LOG_VERBOSE, "Verify we got at least 36 bytes of data");
CU_ASSERT(task->datain.size >= 36); CU_ASSERT(task->datain.size >= 36);
logging(LOG_VERBOSE, "Verify we can unmarshall the DATA-IN buffer"); logging(LOG_VERBOSE, "Verify we can unmarshall the DATA-IN buffer");
std_inq = scsi_datain_unmarshall(task); std_inq = scsi_datain_unmarshall(task);
CU_ASSERT_NOT_EQUAL(std_inq, NULL); CU_ASSERT_NOT_EQUAL(std_inq, NULL);
if (std_inq == NULL) { if (std_inq == NULL) {
logging(LOG_NORMAL, "[FAILED] Failed to unmarshall DATA-IN " logging(LOG_NORMAL, "[FAILED] Failed to unmarshall DATA-IN "
"buffer"); "buffer");
return; return;
} }
logging(LOG_VERBOSE, "Verify peripheral-qualifier is 0"); logging(LOG_VERBOSE, "Verify peripheral-qualifier is 0");
CU_ASSERT_EQUAL(std_inq->qualifier, 0); CU_ASSERT_EQUAL(std_inq->qualifier, 0);
logging(LOG_VERBOSE, "Verify version field is either 0x4, 0x5 or 0x6"); logging(LOG_VERBOSE, "Verify version field is either 0x4, 0x5 or 0x6");
switch (std_inq->version) { switch (std_inq->version) {
case 0x0: case 0x0:
logging(LOG_NORMAL, "[WARNING] Standard INQUIRY data claims " logging(LOG_NORMAL, "[WARNING] Standard INQUIRY data claims "
"conformance to no standard. Version==0. " "conformance to no standard. Version==0. "
"Bad sport."); "Bad sport.");
break; break;
case 0x4: case 0x4:
case 0x5: case 0x5:
case 0x6: case 0x6:
break; break;
default: default:
logging(LOG_NORMAL, "[FAILED] Invalid version in standard " logging(LOG_NORMAL, "[FAILED] Invalid version in standard "
"INQUIRY data. Version %d found but only versions " "INQUIRY data. Version %d found but only versions "
"0x4,0x4,0x6 are valid.", std_inq->version); "0x4,0x4,0x6 are valid.", std_inq->version);
CU_FAIL("Invalid version in INQUIRY data"); CU_FAIL("Invalid version in INQUIRY data");
} }
logging(LOG_VERBOSE, "Verify response-data-format is 2 " logging(LOG_VERBOSE, "Verify response-data-format is 2 "
"(SPC-2 or later)"); "(SPC-2 or later)");
if (std_inq->response_data_format != 2) { if (std_inq->response_data_format != 2) {
logging(LOG_NORMAL, "[FAILED] Response data format is " logging(LOG_NORMAL, "[FAILED] Response data format is "
"invalid. Must be 2 but device returned %d", "invalid. Must be 2 but device returned %d",
std_inq->response_data_format); std_inq->response_data_format);
} }
CU_ASSERT_EQUAL(std_inq->response_data_format, 2); CU_ASSERT_EQUAL(std_inq->response_data_format, 2);
logging(LOG_VERBOSE, "Verify additional-length is correct"); logging(LOG_VERBOSE, "Verify additional-length is correct");
if (std_inq->additional_length > task->datain.size - 5) { if (std_inq->additional_length > task->datain.size - 5) {
logging(LOG_NORMAL, "[FAILED] Bad additional length " logging(LOG_NORMAL, "[FAILED] Bad additional length "
"returned. Should be %d but device returned %d.", "returned. Should be %d but device returned %d.",
task->datain.size - 5, task->datain.size - 5,
std_inq->additional_length); std_inq->additional_length);
logging(LOG_NORMAL, "[FAILED] Additional length points " logging(LOG_NORMAL, "[FAILED] Additional length points "
"beyond end of data"); "beyond end of data");
CU_FAIL("Additional length points beyond end of data"); CU_FAIL("Additional length points beyond end of data");
} }
if (std_inq->additional_length < task->datain.size - 5) { if (std_inq->additional_length < task->datain.size - 5) {
logging(LOG_NORMAL, "[WARNING] Bad additional length " logging(LOG_NORMAL, "[WARNING] Bad additional length "
"returned. Should be %d but device returned %d. ", "returned. Should be %d but device returned %d. ",
task->datain.size - 5, task->datain.size - 5,
std_inq->additional_length); std_inq->additional_length);
logging(LOG_VERBOSE, "Verify that all padding data is 0"); logging(LOG_VERBOSE, "Verify that all padding data is 0");
for (i = std_inq->additional_length + 6; i < task->datain.size; i++) { for (i = std_inq->additional_length + 6; i < task->datain.size; i++) {
if (!task->datain.data[i]) if (!task->datain.data[i])
continue; continue;
logging(LOG_NORMAL, "[FAILED] Padding data is not zero." logging(LOG_NORMAL, "[FAILED] Padding data is not zero."
" Are we leaking data?"); " Are we leaking data?");
CU_FAIL("Padding data is not zero. Leaking data?"); CU_FAIL("Padding data is not zero. Leaking data?");
} }
} }
logging(LOG_VERBOSE, "Verify VENDOR_IDENTIFICATION is in ASCII"); logging(LOG_VERBOSE, "Verify VENDOR_IDENTIFICATION is in ASCII");
for (i = 8; i < 16; i++) { for (i = 8; i < 16; i++) {
/* SPC-4 4.4.1 only characters 0x00 and 0x20-0x7E allowed */ /* SPC-4 4.4.1 only characters 0x00 and 0x20-0x7E allowed */
if (task->datain.data[i] == 0) { if (task->datain.data[i] == 0) {
continue; continue;
} }
if (task->datain.data[i] >= 0x20 && task->datain.data[i] <= 0x7e) { if (task->datain.data[i] >= 0x20 && task->datain.data[i] <= 0x7e) {
continue; continue;
} }
logging(LOG_NORMAL, "[FAILED] VENDOR_IDENTIFICATION contains " logging(LOG_NORMAL, "[FAILED] VENDOR_IDENTIFICATION contains "
"non-ASCII characters"); "non-ASCII characters");
CU_FAIL("Invalid characters in VENDOR_IDENTIFICATION"); CU_FAIL("Invalid characters in VENDOR_IDENTIFICATION");
break; break;
} }
logging(LOG_VERBOSE, "Verify PRODUCT_IDENTIFICATION is in ASCII"); logging(LOG_VERBOSE, "Verify PRODUCT_IDENTIFICATION is in ASCII");
for (i = 16; i < 32; i++) { for (i = 16; i < 32; i++) {
/* SPC-4 4.4.1 only characters 0x00 and 0x20-0x7E allowed */ /* SPC-4 4.4.1 only characters 0x00 and 0x20-0x7E allowed */
if (task->datain.data[i] == 0) { if (task->datain.data[i] == 0) {
continue; continue;
} }
if (task->datain.data[i] >= 0x20 && task->datain.data[i] <= 0x7e) { if (task->datain.data[i] >= 0x20 && task->datain.data[i] <= 0x7e) {
continue; continue;
} }
logging(LOG_NORMAL, "[FAILED] PRODUCT_IDENTIFICATION contains " logging(LOG_NORMAL, "[FAILED] PRODUCT_IDENTIFICATION contains "
"non-ASCII characters"); "non-ASCII characters");
CU_FAIL("Invalid characters in PRODUCT_IDENTIFICATION"); CU_FAIL("Invalid characters in PRODUCT_IDENTIFICATION");
break; break;
} }
logging(LOG_VERBOSE, "Verify PRODUCT_REVISION_LEVEL is in ASCII"); logging(LOG_VERBOSE, "Verify PRODUCT_REVISION_LEVEL is in ASCII");
for (i = 32; i < 36; i++) { for (i = 32; i < 36; i++) {
/* SPC-4 4.4.1 only characters 0x00 and 0x20-0x7E allowed */ /* SPC-4 4.4.1 only characters 0x00 and 0x20-0x7E allowed */
if (task->datain.data[i] == 0) { if (task->datain.data[i] == 0) {
continue; continue;
} }
if (task->datain.data[i] >= 0x20 && task->datain.data[i] <= 0x7e) { if (task->datain.data[i] >= 0x20 && task->datain.data[i] <= 0x7e) {
continue; continue;
} }
logging(LOG_NORMAL, "[FAILED] PRODUCT_REVISON_LEVEL contains " logging(LOG_NORMAL, "[FAILED] PRODUCT_REVISON_LEVEL contains "
"non-ASCII characters"); "non-ASCII characters");
CU_FAIL("Invalid characters in PRODUCT_REVISON_LEVEL"); CU_FAIL("Invalid characters in PRODUCT_REVISON_LEVEL");
break; break;
} }
logging(LOG_VERBOSE, "Verify AERC is clear in SPC-3 and later"); logging(LOG_VERBOSE, "Verify AERC is clear in SPC-3 and later");
if (task->datain.data[3] & 0x80 && std_inq->version >= 5) { if (task->datain.data[3] & 0x80 && std_inq->version >= 5) {
logging(LOG_NORMAL, "[FAILED] AERC is set but this device " logging(LOG_NORMAL, "[FAILED] AERC is set but this device "
"reports SPC-3 or later."); "reports SPC-3 or later.");
CU_FAIL("AERC is set but SPC-3+ is claimed"); CU_FAIL("AERC is set but SPC-3+ is claimed");
} }
logging(LOG_VERBOSE, "Verify TRMTSK is clear in SPC-2 and later"); logging(LOG_VERBOSE, "Verify TRMTSK is clear in SPC-2 and later");
if (task->datain.data[3] & 0x40 && std_inq->version >= 4) { if (task->datain.data[3] & 0x40 && std_inq->version >= 4) {
logging(LOG_NORMAL, "[FAILED] TRMTSK is set but this device " logging(LOG_NORMAL, "[FAILED] TRMTSK is set but this device "
"reports SPC-2 or later."); "reports SPC-2 or later.");
CU_FAIL("TRMTSK is set but SPC-2+ is claimed"); CU_FAIL("TRMTSK is set but SPC-2+ is claimed");
} }
if (task != NULL) { if (task != NULL) {
scsi_free_scsi_task(task); scsi_free_scsi_task(task);
task = NULL; task = NULL;
} }
} }

View File

@@ -28,42 +28,42 @@
void void
test_inquiry_supported_vpd(void) test_inquiry_supported_vpd(void)
{ {
int ret, i; int ret, i;
struct scsi_inquiry_supported_pages *sup_inq; struct scsi_inquiry_supported_pages *sup_inq;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test INQUIRY supported VPD pages"); logging(LOG_VERBOSE, "Test INQUIRY supported VPD pages");
logging(LOG_VERBOSE, "Verify we can read the SUPPORTED VPD page"); logging(LOG_VERBOSE, "Verify we can read the SUPPORTED VPD page");
ret = inquiry(sd, &task, ret = inquiry(sd, &task,
1, SCSI_INQUIRY_PAGECODE_SUPPORTED_VPD_PAGES, 255, 1, SCSI_INQUIRY_PAGECODE_SUPPORTED_VPD_PAGES, 255,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
logging(LOG_VERBOSE, "Verify we got at least 4 bytes of data"); logging(LOG_VERBOSE, "Verify we got at least 4 bytes of data");
CU_ASSERT(task->datain.size >= 4); CU_ASSERT(task->datain.size >= 4);
logging(LOG_VERBOSE, "Verify we can unmarshall the DATA-IN buffer"); logging(LOG_VERBOSE, "Verify we can unmarshall the DATA-IN buffer");
sup_inq = scsi_datain_unmarshall(task); sup_inq = scsi_datain_unmarshall(task);
CU_ASSERT_NOT_EQUAL(sup_inq, NULL); CU_ASSERT_NOT_EQUAL(sup_inq, NULL);
if (sup_inq == NULL) { if (sup_inq == NULL) {
logging(LOG_NORMAL, "[FAILED] Failed to unmarshall DATA-IN " logging(LOG_NORMAL, "[FAILED] Failed to unmarshall DATA-IN "
"buffer"); "buffer");
return; return;
} }
logging(LOG_VERBOSE, "Verify we read all the supported pages"); logging(LOG_VERBOSE, "Verify we read all the supported pages");
for (i = 0; i < sup_inq->num_pages; i++) { for (i = 0; i < sup_inq->num_pages; i++) {
logging(LOG_VERBOSE, "Verify we can read page 0x%02x", logging(LOG_VERBOSE, "Verify we can read page 0x%02x",
sup_inq->pages[i]); sup_inq->pages[i]);
ret = inquiry(sd, NULL, 1, sup_inq->pages[i], 255, ret = inquiry(sd, NULL, 1, sup_inq->pages[i], 255,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
} }
if (task != NULL) { if (task != NULL) {
scsi_free_scsi_task(task); scsi_free_scsi_task(task);
task = NULL; task = NULL;
} }
} }

View File

@@ -28,80 +28,80 @@
void void
test_inquiry_version_descriptors(void) test_inquiry_version_descriptors(void)
{ {
int i, claimed_ok; int i, claimed_ok;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test of the INQUIRY version descriptors"); logging(LOG_VERBOSE, "Test of the INQUIRY version descriptors");
switch (inq->device_type) { switch (inq->device_type) {
case SCSI_INQUIRY_PERIPHERAL_DEVICE_TYPE_DIRECT_ACCESS: case SCSI_INQUIRY_PERIPHERAL_DEVICE_TYPE_DIRECT_ACCESS:
logging(LOG_VERBOSE, "Device is a block device"); logging(LOG_VERBOSE, "Device is a block device");
logging(LOG_VERBOSE, "Verify it claim some version of SPC"); logging(LOG_VERBOSE, "Verify it claim some version of SPC");
claimed_ok = 0; claimed_ok = 0;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
switch(inq->version_descriptor[i]) { switch(inq->version_descriptor[i]) {
case SCSI_VERSION_DESCRIPTOR_SPC: case SCSI_VERSION_DESCRIPTOR_SPC:
case SCSI_VERSION_DESCRIPTOR_SPC_ANSI_INCITS_301_1997: case SCSI_VERSION_DESCRIPTOR_SPC_ANSI_INCITS_301_1997:
case SCSI_VERSION_DESCRIPTOR_SPC_T10_0995_D_R11A: case SCSI_VERSION_DESCRIPTOR_SPC_T10_0995_D_R11A:
case SCSI_VERSION_DESCRIPTOR_SPC_2: case SCSI_VERSION_DESCRIPTOR_SPC_2:
case SCSI_VERSION_DESCRIPTOR_SPC_2_ISO_IEC_14776_452: case SCSI_VERSION_DESCRIPTOR_SPC_2_ISO_IEC_14776_452:
case SCSI_VERSION_DESCRIPTOR_SPC_2_ANSI_INCITS_351_2001: case SCSI_VERSION_DESCRIPTOR_SPC_2_ANSI_INCITS_351_2001:
case SCSI_VERSION_DESCRIPTOR_SPC_2_T10_1236_D_R20: case SCSI_VERSION_DESCRIPTOR_SPC_2_T10_1236_D_R20:
case SCSI_VERSION_DESCRIPTOR_SPC_2_T10_1236_D_R12: case SCSI_VERSION_DESCRIPTOR_SPC_2_T10_1236_D_R12:
case SCSI_VERSION_DESCRIPTOR_SPC_2_T10_1236_D_R18: case SCSI_VERSION_DESCRIPTOR_SPC_2_T10_1236_D_R18:
case SCSI_VERSION_DESCRIPTOR_SPC_2_T10_1236_D_R19: case SCSI_VERSION_DESCRIPTOR_SPC_2_T10_1236_D_R19:
case SCSI_VERSION_DESCRIPTOR_SPC_3: case SCSI_VERSION_DESCRIPTOR_SPC_3:
case SCSI_VERSION_DESCRIPTOR_SPC_3_ISO_IEC_14776_453: case SCSI_VERSION_DESCRIPTOR_SPC_3_ISO_IEC_14776_453:
case SCSI_VERSION_DESCRIPTOR_SPC_3_ANSI_INCITS_408_2005: case SCSI_VERSION_DESCRIPTOR_SPC_3_ANSI_INCITS_408_2005:
case SCSI_VERSION_DESCRIPTOR_SPC_3_T10_1416_D_R7: case SCSI_VERSION_DESCRIPTOR_SPC_3_T10_1416_D_R7:
case SCSI_VERSION_DESCRIPTOR_SPC_3_T10_1416_D_R21: case SCSI_VERSION_DESCRIPTOR_SPC_3_T10_1416_D_R21:
case SCSI_VERSION_DESCRIPTOR_SPC_3_T10_1416_D_R22: case SCSI_VERSION_DESCRIPTOR_SPC_3_T10_1416_D_R22:
case SCSI_VERSION_DESCRIPTOR_SPC_3_T10_1416_D_R23: case SCSI_VERSION_DESCRIPTOR_SPC_3_T10_1416_D_R23:
case SCSI_VERSION_DESCRIPTOR_SPC_4: case SCSI_VERSION_DESCRIPTOR_SPC_4:
case SCSI_VERSION_DESCRIPTOR_SPC_4_T10_1731_D_R16: case SCSI_VERSION_DESCRIPTOR_SPC_4_T10_1731_D_R16:
case SCSI_VERSION_DESCRIPTOR_SPC_4_T10_1731_D_R18: case SCSI_VERSION_DESCRIPTOR_SPC_4_T10_1731_D_R18:
case SCSI_VERSION_DESCRIPTOR_SPC_4_T10_1731_D_R23: case SCSI_VERSION_DESCRIPTOR_SPC_4_T10_1731_D_R23:
claimed_ok = 1; claimed_ok = 1;
break; break;
} }
} }
if (claimed_ok == 0) { if (claimed_ok == 0) {
logging(LOG_NORMAL, "[WARNING] Block device " logging(LOG_NORMAL, "[WARNING] Block device "
"did not claim any version of SPC"); "did not claim any version of SPC");
} else { } else {
logging(LOG_VERBOSE, "[SUCCESS] Block device " logging(LOG_VERBOSE, "[SUCCESS] Block device "
"claimed a version of SPC"); "claimed a version of SPC");
} }
logging(LOG_VERBOSE, "Verify it claim some version of SBC"); logging(LOG_VERBOSE, "Verify it claim some version of SBC");
claimed_ok = 0; claimed_ok = 0;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
switch(inq->version_descriptor[i]) { switch(inq->version_descriptor[i]) {
case SCSI_VERSION_DESCRIPTOR_SBC: case SCSI_VERSION_DESCRIPTOR_SBC:
case SCSI_VERSION_DESCRIPTOR_SBC_ANSI_INCITS_306_1998: case SCSI_VERSION_DESCRIPTOR_SBC_ANSI_INCITS_306_1998:
case SCSI_VERSION_DESCRIPTOR_SBC_T10_0996_D_R08C: case SCSI_VERSION_DESCRIPTOR_SBC_T10_0996_D_R08C:
case SCSI_VERSION_DESCRIPTOR_SBC_2: case SCSI_VERSION_DESCRIPTOR_SBC_2:
case SCSI_VERSION_DESCRIPTOR_SBC_2_ISO_IEC_14776_322: case SCSI_VERSION_DESCRIPTOR_SBC_2_ISO_IEC_14776_322:
case SCSI_VERSION_DESCRIPTOR_SBC_2_ANSI_INCITS_405_2005: case SCSI_VERSION_DESCRIPTOR_SBC_2_ANSI_INCITS_405_2005:
case SCSI_VERSION_DESCRIPTOR_SBC_2_T10_1417_D_R16: case SCSI_VERSION_DESCRIPTOR_SBC_2_T10_1417_D_R16:
case SCSI_VERSION_DESCRIPTOR_SBC_2_T10_1417_D_R5A: case SCSI_VERSION_DESCRIPTOR_SBC_2_T10_1417_D_R5A:
case SCSI_VERSION_DESCRIPTOR_SBC_2_T10_1417_D_R15: case SCSI_VERSION_DESCRIPTOR_SBC_2_T10_1417_D_R15:
case SCSI_VERSION_DESCRIPTOR_SBC_3: case SCSI_VERSION_DESCRIPTOR_SBC_3:
claimed_ok = 1; claimed_ok = 1;
break; break;
} }
} }
if (claimed_ok == 0) { if (claimed_ok == 0) {
logging(LOG_NORMAL, "[WARNING] Block device " logging(LOG_NORMAL, "[WARNING] Block device "
"did not claim any version of SBC"); "did not claim any version of SBC");
} else { } else {
logging(LOG_VERBOSE, "[SUCCESS] Block device " logging(LOG_VERBOSE, "[SUCCESS] Block device "
"claimed a version of SBC"); "claimed a version of SBC");
} }
break; break;
default: default:
logging(LOG_VERBOSE, "No version descriptor tests for device" logging(LOG_VERBOSE, "No version descriptor tests for device"
" type %d yet.", inq->device_type); " type %d yet.", inq->device_type);
} }
} }

View File

@@ -29,62 +29,62 @@ static int change_cmdsn;
static int my_iscsi_queue_pdu(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) static int my_iscsi_queue_pdu(struct iscsi_context *iscsi, struct iscsi_pdu *pdu)
{ {
switch (change_cmdsn) { switch (change_cmdsn) {
case 1: case 1:
/* change the cmdsn so it becomes too big */ /* change the cmdsn so it becomes too big */
scsi_set_uint32(&pdu->outdata.data[24], iscsi->maxcmdsn + 1); scsi_set_uint32(&pdu->outdata.data[24], iscsi->maxcmdsn + 1);
/* fudge the cmdsn value back to where it should be if this /* fudge the cmdsn value back to where it should be if this
* pdu is ignored. * pdu is ignored.
*/ */
iscsi->cmdsn = iscsi->expcmdsn; iscsi->cmdsn = iscsi->expcmdsn;
break; break;
} }
change_cmdsn = 0; change_cmdsn = 0;
return 0; return 0;
} }
void test_iscsi_cmdsn_toohigh(void) void test_iscsi_cmdsn_toohigh(void)
{ {
int ret; int ret;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test sending invalid iSCSI CMDSN"); logging(LOG_VERBOSE, "Test sending invalid iSCSI CMDSN");
logging(LOG_VERBOSE, "CMDSN MUST be in the range EXPCMDSN and MAXCMDSN"); logging(LOG_VERBOSE, "CMDSN MUST be in the range EXPCMDSN and MAXCMDSN");
if (sd->iscsi_ctx == NULL) { if (sd->iscsi_ctx == NULL) {
const char *err = "[SKIPPED] This test is " const char *err = "[SKIPPED] This test is "
"only supported for iSCSI backends"; "only supported for iSCSI backends";
logging(LOG_NORMAL, "%s", err); logging(LOG_NORMAL, "%s", err);
CU_PASS(err); CU_PASS(err);
return; return;
} }
logging(LOG_VERBOSE, "RFC3720:3.2.2.1 CMDSN > MAXCMDSN must be silently ignored by the target"); logging(LOG_VERBOSE, "RFC3720:3.2.2.1 CMDSN > MAXCMDSN must be silently ignored by the target");
logging(LOG_VERBOSE, "Send a TESTUNITREADY with CMDSN == MAXCMDSN+1. Should be ignored by the target."); logging(LOG_VERBOSE, "Send a TESTUNITREADY with CMDSN == MAXCMDSN+1. Should be ignored by the target.");
sd->iscsi_ctx->use_immediate_data = ISCSI_IMMEDIATE_DATA_NO; sd->iscsi_ctx->use_immediate_data = ISCSI_IMMEDIATE_DATA_NO;
sd->iscsi_ctx->target_max_recv_data_segment_length = block_size; sd->iscsi_ctx->target_max_recv_data_segment_length = block_size;
local_iscsi_queue_pdu = my_iscsi_queue_pdu; local_iscsi_queue_pdu = my_iscsi_queue_pdu;
change_cmdsn = 1; change_cmdsn = 1;
/* we don't want autoreconnect since some targets will incorrectly /* we don't want autoreconnect since some targets will incorrectly
* drop the connection on this condition. * drop the connection on this condition.
*/ */
iscsi_set_noautoreconnect(sd->iscsi_ctx, 1); iscsi_set_noautoreconnect(sd->iscsi_ctx, 1);
iscsi_set_timeout(sd->iscsi_ctx, 3); iscsi_set_timeout(sd->iscsi_ctx, 3);
ret = testunitready(sd, ret = testunitready(sd,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
CU_ASSERT_EQUAL(ret, -1); CU_ASSERT_EQUAL(ret, -1);
if (ret == -1) { if (ret == -1) {
logging(LOG_VERBOSE, "[SUCCESS] We did not receive a reply"); logging(LOG_VERBOSE, "[SUCCESS] We did not receive a reply");
} else { } else {
logging(LOG_VERBOSE, "[FAILURE] We got a response from the target but SMDSN was outside of the window."); logging(LOG_VERBOSE, "[FAILURE] We got a response from the target but SMDSN was outside of the window.");
} }
iscsi_set_noautoreconnect(sd->iscsi_ctx, 0); iscsi_set_noautoreconnect(sd->iscsi_ctx, 0);
logging(LOG_VERBOSE, "Send a TESTUNITREADY with CMDSN == EXPCMDSN. should work again"); logging(LOG_VERBOSE, "Send a TESTUNITREADY with CMDSN == EXPCMDSN. should work again");
TESTUNITREADY(sd, TESTUNITREADY(sd,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }

View File

@@ -29,63 +29,63 @@ static int change_cmdsn;
static int my_iscsi_queue_pdu(struct iscsi_context *iscsi, struct iscsi_pdu *pdu) static int my_iscsi_queue_pdu(struct iscsi_context *iscsi, struct iscsi_pdu *pdu)
{ {
switch (change_cmdsn) { switch (change_cmdsn) {
case 1: case 1:
/* change the cmdsn so it becomes too big */ /* change the cmdsn so it becomes too big */
scsi_set_uint32(&pdu->outdata.data[24], iscsi->expcmdsn - 1); scsi_set_uint32(&pdu->outdata.data[24], iscsi->expcmdsn - 1);
/* fudge the cmdsn value back to where it should be if this /* fudge the cmdsn value back to where it should be if this
* pdu is ignored. * pdu is ignored.
*/ */
iscsi->cmdsn = iscsi->expcmdsn; iscsi->cmdsn = iscsi->expcmdsn;
break; break;
} }
change_cmdsn = 0; change_cmdsn = 0;
return 0; return 0;
} }
void test_iscsi_cmdsn_toolow(void) void test_iscsi_cmdsn_toolow(void)
{ {
int ret; int ret;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test sending invalid iSCSI CMDSN"); logging(LOG_VERBOSE, "Test sending invalid iSCSI CMDSN");
logging(LOG_VERBOSE, "CMDSN MUST be in the range EXPCMDSN and MAXCMDSN"); logging(LOG_VERBOSE, "CMDSN MUST be in the range EXPCMDSN and MAXCMDSN");
if (sd->iscsi_ctx == NULL) { if (sd->iscsi_ctx == NULL) {
const char *err = "[SKIPPED] This test is " const char *err = "[SKIPPED] This test is "
"only supported for iSCSI backends"; "only supported for iSCSI backends";
logging(LOG_NORMAL, "%s", err); logging(LOG_NORMAL, "%s", err);
CU_PASS(err); CU_PASS(err);
return; return;
} }
logging(LOG_VERBOSE, "RFC3720:3.2.2.1 CMDSN < EXPCMDSN must be silently ignored by the target"); logging(LOG_VERBOSE, "RFC3720:3.2.2.1 CMDSN < EXPCMDSN must be silently ignored by the target");
logging(LOG_VERBOSE, "Send a TESTUNITREADY with CMDSN == EXPCMDSN-1. Should be ignored by the target."); logging(LOG_VERBOSE, "Send a TESTUNITREADY with CMDSN == EXPCMDSN-1. Should be ignored by the target.");
sd->iscsi_ctx->use_immediate_data = ISCSI_IMMEDIATE_DATA_NO; sd->iscsi_ctx->use_immediate_data = ISCSI_IMMEDIATE_DATA_NO;
sd->iscsi_ctx->target_max_recv_data_segment_length = block_size; sd->iscsi_ctx->target_max_recv_data_segment_length = block_size;
local_iscsi_queue_pdu = my_iscsi_queue_pdu; local_iscsi_queue_pdu = my_iscsi_queue_pdu;
change_cmdsn = 1; change_cmdsn = 1;
/* we don't want autoreconnect since some targets will incorrectly /* we don't want autoreconnect since some targets will incorrectly
* drop the connection on this condition. * drop the connection on this condition.
*/ */
iscsi_set_noautoreconnect(sd->iscsi_ctx, 1); iscsi_set_noautoreconnect(sd->iscsi_ctx, 1);
iscsi_set_timeout(sd->iscsi_ctx, 3); iscsi_set_timeout(sd->iscsi_ctx, 3);
ret = testunitready(sd, ret = testunitready(sd,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
CU_ASSERT_EQUAL(ret, -1); CU_ASSERT_EQUAL(ret, -1);
if (ret == -1) { if (ret == -1) {
logging(LOG_VERBOSE, "[SUCCESS] We did not receive a reply"); logging(LOG_VERBOSE, "[SUCCESS] We did not receive a reply");
} else { } else {
logging(LOG_VERBOSE, "[FAILURE] We got a response from the target but SMDSN was outside of the window."); logging(LOG_VERBOSE, "[FAILURE] We got a response from the target but SMDSN was outside of the window.");
} }
iscsi_set_noautoreconnect(sd->iscsi_ctx, 0); iscsi_set_noautoreconnect(sd->iscsi_ctx, 0);
logging(LOG_VERBOSE, "Send a TESTUNITREADY with CMDSN == EXPCMDSN. should work again"); logging(LOG_VERBOSE, "Send a TESTUNITREADY with CMDSN == EXPCMDSN. should work again");
TESTUNITREADY(sd, TESTUNITREADY(sd,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }

View File

@@ -29,142 +29,142 @@ static int change_datasn;
static int my_iscsi_queue_pdu(struct iscsi_context *iscsi _U_, struct iscsi_pdu *pdu _U_) static int my_iscsi_queue_pdu(struct iscsi_context *iscsi _U_, struct iscsi_pdu *pdu _U_)
{ {
uint32_t datasn; uint32_t datasn;
if (pdu->outdata.data[0] != ISCSI_PDU_DATA_OUT) { if (pdu->outdata.data[0] != ISCSI_PDU_DATA_OUT) {
return 0; return 0;
} }
switch (change_datasn) { switch (change_datasn) {
case 1: case 1:
/* change DataSN to 0 */ /* change DataSN to 0 */
scsi_set_uint32(&pdu->outdata.data[36], 0); scsi_set_uint32(&pdu->outdata.data[36], 0);
break; break;
case 2: case 2:
/* change DataSN to 27 */ /* change DataSN to 27 */
scsi_set_uint32(&pdu->outdata.data[36], 27); scsi_set_uint32(&pdu->outdata.data[36], 27);
break; break;
case 3: case 3:
/* change DataSN to -1 */ /* change DataSN to -1 */
scsi_set_uint32(&pdu->outdata.data[36], -1); scsi_set_uint32(&pdu->outdata.data[36], -1);
break; break;
case 4: case 4:
/* change DataSN from (0,1) to (1,0) */ /* change DataSN from (0,1) to (1,0) */
datasn = scsi_get_uint32(&pdu->outdata.data[36]); datasn = scsi_get_uint32(&pdu->outdata.data[36]);
scsi_set_uint32(&pdu->outdata.data[36], 1 - datasn); scsi_set_uint32(&pdu->outdata.data[36], 1 - datasn);
break; break;
} }
return 0; return 0;
} }
void test_iscsi_datasn_invalid(void) void test_iscsi_datasn_invalid(void)
{ {
int ret; int ret;
CHECK_FOR_DATALOSS; CHECK_FOR_DATALOSS;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test sending invalid iSCSI DataSN"); logging(LOG_VERBOSE, "Test sending invalid iSCSI DataSN");
if (sd->iscsi_ctx == NULL) { if (sd->iscsi_ctx == NULL) {
const char *err = "[SKIPPED] This test is " const char *err = "[SKIPPED] This test is "
"only supported for iSCSI backends"; "only supported for iSCSI backends";
logging(LOG_NORMAL, "%s", err); logging(LOG_NORMAL, "%s", err);
CU_PASS(err); CU_PASS(err);
return; return;
} }
logging(LOG_VERBOSE, "Send two Data-Out PDU's with DataSN==0. Should fail."); logging(LOG_VERBOSE, "Send two Data-Out PDU's with DataSN==0. Should fail.");
change_datasn = 1; change_datasn = 1;
sd->iscsi_ctx->use_immediate_data = ISCSI_IMMEDIATE_DATA_NO; sd->iscsi_ctx->use_immediate_data = ISCSI_IMMEDIATE_DATA_NO;
sd->iscsi_ctx->target_max_recv_data_segment_length = block_size; sd->iscsi_ctx->target_max_recv_data_segment_length = block_size;
local_iscsi_queue_pdu = my_iscsi_queue_pdu; local_iscsi_queue_pdu = my_iscsi_queue_pdu;
iscsi_set_noautoreconnect(sd->iscsi_ctx, 1); iscsi_set_noautoreconnect(sd->iscsi_ctx, 1);
iscsi_set_timeout(sd->iscsi_ctx, 3); iscsi_set_timeout(sd->iscsi_ctx, 3);
memset(scratch, 0xa6, 2 * block_size); memset(scratch, 0xa6, 2 * block_size);
ret = write10(sd, 100, 2 * block_size, ret = write10(sd, 100, 2 * block_size,
block_size, 0, 0, 0, 0, 0, scratch, block_size, 0, 0, 0, 0, 0, scratch,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
if (ret == -2) { if (ret == -2) {
logging(LOG_NORMAL, "[SKIPPED] WRITE10 is not implemented."); logging(LOG_NORMAL, "[SKIPPED] WRITE10 is not implemented.");
CU_PASS("WRITE10 is not implemented."); CU_PASS("WRITE10 is not implemented.");
local_iscsi_queue_pdu = NULL; local_iscsi_queue_pdu = NULL;
return; return;
} }
CU_ASSERT_NOT_EQUAL(ret, 0); CU_ASSERT_NOT_EQUAL(ret, 0);
iscsi_set_noautoreconnect(sd->iscsi_ctx, 0); iscsi_set_noautoreconnect(sd->iscsi_ctx, 0);
logging(LOG_VERBOSE, "Send Data-Out PDU with DataSN==27. Should fail"); logging(LOG_VERBOSE, "Send Data-Out PDU with DataSN==27. Should fail");
change_datasn = 2; change_datasn = 2;
sd->iscsi_ctx->use_immediate_data = ISCSI_IMMEDIATE_DATA_NO; sd->iscsi_ctx->use_immediate_data = ISCSI_IMMEDIATE_DATA_NO;
sd->iscsi_ctx->target_max_recv_data_segment_length = block_size; sd->iscsi_ctx->target_max_recv_data_segment_length = block_size;
local_iscsi_queue_pdu = my_iscsi_queue_pdu; local_iscsi_queue_pdu = my_iscsi_queue_pdu;
iscsi_set_noautoreconnect(sd->iscsi_ctx, 1); iscsi_set_noautoreconnect(sd->iscsi_ctx, 1);
iscsi_set_timeout(sd->iscsi_ctx, 3); iscsi_set_timeout(sd->iscsi_ctx, 3);
ret = write10(sd, 100, block_size, ret = write10(sd, 100, block_size,
block_size, 0, 0, 0, 0, 0, scratch, block_size, 0, 0, 0, 0, 0, scratch,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
if (ret == -2) { if (ret == -2) {
logging(LOG_NORMAL, "[SKIPPED] WRITE10 is not implemented."); logging(LOG_NORMAL, "[SKIPPED] WRITE10 is not implemented.");
CU_PASS("WRITE10 is not implemented."); CU_PASS("WRITE10 is not implemented.");
local_iscsi_queue_pdu = NULL; local_iscsi_queue_pdu = NULL;
return; return;
} }
CU_ASSERT_NOT_EQUAL(ret, 0); CU_ASSERT_NOT_EQUAL(ret, 0);
iscsi_set_noautoreconnect(sd->iscsi_ctx, 0); iscsi_set_noautoreconnect(sd->iscsi_ctx, 0);
logging(LOG_VERBOSE, "Send Data-Out PDU with DataSN==-1. Should fail"); logging(LOG_VERBOSE, "Send Data-Out PDU with DataSN==-1. Should fail");
change_datasn = 3; change_datasn = 3;
sd->iscsi_ctx->use_immediate_data = ISCSI_IMMEDIATE_DATA_NO; sd->iscsi_ctx->use_immediate_data = ISCSI_IMMEDIATE_DATA_NO;
sd->iscsi_ctx->target_max_recv_data_segment_length = block_size; sd->iscsi_ctx->target_max_recv_data_segment_length = block_size;
local_iscsi_queue_pdu = my_iscsi_queue_pdu; local_iscsi_queue_pdu = my_iscsi_queue_pdu;
iscsi_set_noautoreconnect(sd->iscsi_ctx, 1); iscsi_set_noautoreconnect(sd->iscsi_ctx, 1);
iscsi_set_timeout(sd->iscsi_ctx, 3); iscsi_set_timeout(sd->iscsi_ctx, 3);
ret = write10(sd, 100, block_size, ret = write10(sd, 100, block_size,
block_size, 0, 0, 0, 0, 0, scratch, block_size, 0, 0, 0, 0, 0, scratch,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
if (ret == -2) { if (ret == -2) {
logging(LOG_NORMAL, "[SKIPPED] WRITE10 is not implemented."); logging(LOG_NORMAL, "[SKIPPED] WRITE10 is not implemented.");
CU_PASS("WRITE10 is not implemented."); CU_PASS("WRITE10 is not implemented.");
local_iscsi_queue_pdu = NULL; local_iscsi_queue_pdu = NULL;
return; return;
} }
CU_ASSERT_NOT_EQUAL(ret, 0); CU_ASSERT_NOT_EQUAL(ret, 0);
iscsi_set_noautoreconnect(sd->iscsi_ctx, 0); iscsi_set_noautoreconnect(sd->iscsi_ctx, 0);
logging(LOG_VERBOSE, "Send Data-Out PDU's in reverse order (DataSN == 1,0). Should fail"); logging(LOG_VERBOSE, "Send Data-Out PDU's in reverse order (DataSN == 1,0). Should fail");
change_datasn = 4; change_datasn = 4;
sd->iscsi_ctx->use_immediate_data = ISCSI_IMMEDIATE_DATA_NO; sd->iscsi_ctx->use_immediate_data = ISCSI_IMMEDIATE_DATA_NO;
sd->iscsi_ctx->target_max_recv_data_segment_length = block_size; sd->iscsi_ctx->target_max_recv_data_segment_length = block_size;
local_iscsi_queue_pdu = my_iscsi_queue_pdu; local_iscsi_queue_pdu = my_iscsi_queue_pdu;
iscsi_set_noautoreconnect(sd->iscsi_ctx, 1); iscsi_set_noautoreconnect(sd->iscsi_ctx, 1);
iscsi_set_timeout(sd->iscsi_ctx, 3); iscsi_set_timeout(sd->iscsi_ctx, 3);
ret = write10(sd, 100, 2 * block_size, ret = write10(sd, 100, 2 * block_size,
block_size, 0, 0, 0, 0, 0, scratch, block_size, 0, 0, 0, 0, 0, scratch,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
if (ret == -2) { if (ret == -2) {
logging(LOG_NORMAL, "[SKIPPED] WRITE10 is not implemented."); logging(LOG_NORMAL, "[SKIPPED] WRITE10 is not implemented.");
CU_PASS("WRITE10 is not implemented."); CU_PASS("WRITE10 is not implemented.");
local_iscsi_queue_pdu = NULL; local_iscsi_queue_pdu = NULL;
return; return;
} }
CU_ASSERT_NOT_EQUAL(ret, 0); CU_ASSERT_NOT_EQUAL(ret, 0);
local_iscsi_queue_pdu = NULL; local_iscsi_queue_pdu = NULL;
iscsi_set_noautoreconnect(sd->iscsi_ctx, 0); iscsi_set_noautoreconnect(sd->iscsi_ctx, 0);
} }

View File

@@ -28,48 +28,48 @@
void void
test_mandatory_sbc(void) test_mandatory_sbc(void)
{ {
int ret; int ret;
//unsigned char buf[4096]; //unsigned char buf[4096];
//struct unmap_list list[1]; //struct unmap_list list[1];
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test support for all mandatory opcodes on SBC devices"); logging(LOG_VERBOSE, "Test support for all mandatory opcodes on SBC devices");
CHECK_FOR_SBC; CHECK_FOR_SBC;
logging(LOG_VERBOSE, "Test INQUIRY."); logging(LOG_VERBOSE, "Test INQUIRY.");
ret = inquiry(sd, NULL, 0, 0, 255, ret = inquiry(sd, NULL, 0, 0, 255,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
logging(LOG_VERBOSE, "Test READCAPACITY10."); logging(LOG_VERBOSE, "Test READCAPACITY10.");
ret = readcapacity10(sd, NULL, 0, 0, ret = readcapacity10(sd, NULL, 0, 0,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
if (sbc3_support) { if (sbc3_support) {
logging(LOG_VERBOSE, "Test READCAPACITY16. The device claims SBC-3 support."); logging(LOG_VERBOSE, "Test READCAPACITY16. The device claims SBC-3 support.");
ret = readcapacity16(sd, NULL, 15, ret = readcapacity16(sd, NULL, 15,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
} }
logging(LOG_VERBOSE, "Test READ10."); logging(LOG_VERBOSE, "Test READ10.");
ret = read10(sd, NULL, 0, block_size, block_size, ret = read10(sd, NULL, 0, block_size, block_size,
0, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 0, NULL,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
if (sbc3_support) { if (sbc3_support) {
logging(LOG_VERBOSE, "Test READ16. the device claims SBC-3 support."); logging(LOG_VERBOSE, "Test READ16. the device claims SBC-3 support.");
ret = read16(sd, NULL, 0, block_size, block_size, ret = read16(sd, NULL, 0, block_size, block_size,
0, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 0, NULL,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
} }
logging(LOG_VERBOSE, "Test TESTUNITREADY."); logging(LOG_VERBOSE, "Test TESTUNITREADY.");
ret = testunitready(sd, ret = testunitready(sd,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
} }

View File

@@ -28,39 +28,39 @@
void void
test_modesense6_all_pages(void) test_modesense6_all_pages(void)
{ {
struct scsi_mode_sense *ms; struct scsi_mode_sense *ms;
struct scsi_task *ms_task = NULL; struct scsi_task *ms_task = NULL;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test of MODESENSE6 AllPages"); logging(LOG_VERBOSE, "Test of MODESENSE6 AllPages");
logging(LOG_VERBOSE, "Send MODESENSE6 command to fetch AllPages"); logging(LOG_VERBOSE, "Send MODESENSE6 command to fetch AllPages");
MODESENSE6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT, MODESENSE6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT,
SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255, SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "[SUCCESS] All Pages fetched."); logging(LOG_VERBOSE, "[SUCCESS] All Pages fetched.");
logging(LOG_VERBOSE, "Try to unmarshall the DATA-IN buffer."); logging(LOG_VERBOSE, "Try to unmarshall the DATA-IN buffer.");
ms = scsi_datain_unmarshall(ms_task); ms = scsi_datain_unmarshall(ms_task);
if (ms == NULL) { if (ms == NULL) {
logging(LOG_VERBOSE, "[FAILED] failed to unmarshall mode sense " logging(LOG_VERBOSE, "[FAILED] failed to unmarshall mode sense "
"datain buffer"); "datain buffer");
CU_FAIL("[FAILED] Failed to unmarshall the data-in buffer."); CU_FAIL("[FAILED] Failed to unmarshall the data-in buffer.");
scsi_free_scsi_task(ms_task); scsi_free_scsi_task(ms_task);
return; return;
} }
logging(LOG_VERBOSE, "[SUCCESS] Unmarshalling successful."); logging(LOG_VERBOSE, "[SUCCESS] Unmarshalling successful.");
logging(LOG_VERBOSE, "Verify that mode data length is >= 3"); logging(LOG_VERBOSE, "Verify that mode data length is >= 3");
if (ms->mode_data_length >= 3) { if (ms->mode_data_length >= 3) {
logging(LOG_VERBOSE, "[SUCCESS] Mode data length is >= 3"); logging(LOG_VERBOSE, "[SUCCESS] Mode data length is >= 3");
} else { } else {
logging(LOG_VERBOSE, "[FAILED] Mode data length is < 3"); logging(LOG_VERBOSE, "[FAILED] Mode data length is < 3");
} }
CU_ASSERT_TRUE(ms->mode_data_length >= 3); CU_ASSERT_TRUE(ms->mode_data_length >= 3);
scsi_free_scsi_task(ms_task); scsi_free_scsi_task(ms_task);
} }

View File

@@ -28,213 +28,213 @@
void void
test_modesense6_control(void) test_modesense6_control(void)
{ {
struct scsi_mode_sense *ms; struct scsi_mode_sense *ms;
struct scsi_mode_page *ap_page; struct scsi_mode_page *ap_page;
struct scsi_mode_page *ct_page; struct scsi_mode_page *ct_page;
struct scsi_task *ap_task = NULL; struct scsi_task *ap_task = NULL;
struct scsi_task *ct_task = NULL; struct scsi_task *ct_task = NULL;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test of MODESENSE6 CONTROL page"); logging(LOG_VERBOSE, "Test of MODESENSE6 CONTROL page");
logging(LOG_VERBOSE, "Fetch the CONTROL page via AllPages"); logging(LOG_VERBOSE, "Fetch the CONTROL page via AllPages");
logging(LOG_VERBOSE, "Send MODESENSE6 command to fetch AllPages"); logging(LOG_VERBOSE, "Send MODESENSE6 command to fetch AllPages");
MODESENSE6(sd, &ap_task, 0, SCSI_MODESENSE_PC_CURRENT, MODESENSE6(sd, &ap_task, 0, SCSI_MODESENSE_PC_CURRENT,
SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255, SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "[SUCCESS] All Pages fetched."); logging(LOG_VERBOSE, "[SUCCESS] All Pages fetched.");
logging(LOG_VERBOSE, "Try to unmarshall the DATA-IN buffer."); logging(LOG_VERBOSE, "Try to unmarshall the DATA-IN buffer.");
ms = scsi_datain_unmarshall(ap_task); ms = scsi_datain_unmarshall(ap_task);
if (ms == NULL) { if (ms == NULL) {
logging(LOG_NORMAL, "[FAILED] failed to unmarshall mode sense " logging(LOG_NORMAL, "[FAILED] failed to unmarshall mode sense "
"datain buffer"); "datain buffer");
CU_FAIL("[FAILED] Failed to unmarshall the data-in buffer."); CU_FAIL("[FAILED] Failed to unmarshall the data-in buffer.");
goto finished; goto finished;
} }
logging(LOG_VERBOSE, "[SUCCESS] Unmarshalling successful."); logging(LOG_VERBOSE, "[SUCCESS] Unmarshalling successful.");
logging(LOG_VERBOSE, "Verify that mode data length is >= 3"); logging(LOG_VERBOSE, "Verify that mode data length is >= 3");
if (ms->mode_data_length >= 3) { if (ms->mode_data_length >= 3) {
logging(LOG_VERBOSE, "[SUCCESS] Mode data length is >= 3"); logging(LOG_VERBOSE, "[SUCCESS] Mode data length is >= 3");
} else { } else {
logging(LOG_NORMAL, "[FAILED] Mode data length is < 3"); logging(LOG_NORMAL, "[FAILED] Mode data length is < 3");
} }
CU_ASSERT_TRUE(ms->mode_data_length >= 3); CU_ASSERT_TRUE(ms->mode_data_length >= 3);
for (ap_page = ms->pages; ap_page; ap_page = ap_page->next) { for (ap_page = ms->pages; ap_page; ap_page = ap_page->next) {
if (ap_page->page_code == SCSI_MODEPAGE_CONTROL && if (ap_page->page_code == SCSI_MODEPAGE_CONTROL &&
ap_page->spf == 0) { ap_page->spf == 0) {
break; break;
} }
} }
if(ap_page == NULL) { if(ap_page == NULL) {
logging(LOG_NORMAL, "[WARNING] CONTROL page was not returned " logging(LOG_NORMAL, "[WARNING] CONTROL page was not returned "
"from AllPages. All devices SHOULD implement this " "from AllPages. All devices SHOULD implement this "
"page."); "page.");
} }
logging(LOG_VERBOSE, "Fetch the CONTROL page directly"); logging(LOG_VERBOSE, "Fetch the CONTROL page directly");
logging(LOG_VERBOSE, "Send MODESENSE6 command to fetch CONTROL"); logging(LOG_VERBOSE, "Send MODESENSE6 command to fetch CONTROL");
MODESENSE6(sd, &ct_task, 0, SCSI_MODESENSE_PC_CURRENT, MODESENSE6(sd, &ct_task, 0, SCSI_MODESENSE_PC_CURRENT,
SCSI_MODEPAGE_CONTROL, 0, 255, SCSI_MODEPAGE_CONTROL, 0, 255,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "[SUCCESS] CONTROL page fetched."); logging(LOG_VERBOSE, "[SUCCESS] CONTROL page fetched.");
logging(LOG_VERBOSE, "Try to unmarshall the DATA-IN buffer."); logging(LOG_VERBOSE, "Try to unmarshall the DATA-IN buffer.");
ms = scsi_datain_unmarshall(ct_task); ms = scsi_datain_unmarshall(ct_task);
if (ms == NULL) { if (ms == NULL) {
logging(LOG_NORMAL, "[FAILED] failed to unmarshall mode sense " logging(LOG_NORMAL, "[FAILED] failed to unmarshall mode sense "
"datain buffer"); "datain buffer");
CU_FAIL("[FAILED] Failed to unmarshall the data-in buffer."); CU_FAIL("[FAILED] Failed to unmarshall the data-in buffer.");
goto finished; goto finished;
} }
logging(LOG_VERBOSE, "[SUCCESS] Unmarshalling successful."); logging(LOG_VERBOSE, "[SUCCESS] Unmarshalling successful.");
logging(LOG_VERBOSE, "Verify that mode data length is >= 3"); logging(LOG_VERBOSE, "Verify that mode data length is >= 3");
if (ms->mode_data_length >= 3) { if (ms->mode_data_length >= 3) {
logging(LOG_VERBOSE, "[SUCCESS] Mode data length is >= 3"); logging(LOG_VERBOSE, "[SUCCESS] Mode data length is >= 3");
} else { } else {
logging(LOG_NORMAL, "[FAILED] Mode data length is < 3"); logging(LOG_NORMAL, "[FAILED] Mode data length is < 3");
} }
CU_ASSERT_TRUE(ms->mode_data_length >= 3); CU_ASSERT_TRUE(ms->mode_data_length >= 3);
for (ct_page = ms->pages; ct_page; ct_page = ct_page->next) { for (ct_page = ms->pages; ct_page; ct_page = ct_page->next) {
if (ct_page->page_code == SCSI_MODEPAGE_CONTROL) { if (ct_page->page_code == SCSI_MODEPAGE_CONTROL) {
break; break;
} }
} }
if(ct_page == NULL) { if(ct_page == NULL) {
logging(LOG_NORMAL, "[WARNING] CONTROL page was not returned." logging(LOG_NORMAL, "[WARNING] CONTROL page was not returned."
"All devices SHOULD implement this page."); "All devices SHOULD implement this page.");
} }
if (ap_page == NULL && ct_page != NULL) { if (ap_page == NULL && ct_page != NULL) {
logging(LOG_NORMAL, "[FAILED] CONTROL page was not returned " logging(LOG_NORMAL, "[FAILED] CONTROL page was not returned "
"from AllPages."); "from AllPages.");
CU_FAIL("[FAILED] CONTROL page is missing from AllPages"); CU_FAIL("[FAILED] CONTROL page is missing from AllPages");
goto finished; goto finished;
} }
if (ap_page != NULL && ct_page == NULL) { if (ap_page != NULL && ct_page == NULL) {
logging(LOG_NORMAL, "[FAILED] CONTROL page is only available " logging(LOG_NORMAL, "[FAILED] CONTROL page is only available "
"from AllPages but not directly."); "from AllPages but not directly.");
CU_FAIL("[FAILED] CONTROL page is missing"); CU_FAIL("[FAILED] CONTROL page is missing");
goto finished; goto finished;
} }
if (ct_page == NULL) { if (ct_page == NULL) {
logging(LOG_NORMAL, "[SKIPPED] CONTROL page is not " logging(LOG_NORMAL, "[SKIPPED] CONTROL page is not "
"implemented."); "implemented.");
CU_PASS("CONTROL page is not implemented."); CU_PASS("CONTROL page is not implemented.");
goto finished; goto finished;
} }
logging(LOG_VERBOSE, "Verify that the two pages are identical."); logging(LOG_VERBOSE, "Verify that the two pages are identical.");
logging(LOG_VERBOSE, "Check TST field"); logging(LOG_VERBOSE, "Check TST field");
CU_ASSERT_EQUAL(ct_page->control.tst, ap_page->control.tst); CU_ASSERT_EQUAL(ct_page->control.tst, ap_page->control.tst);
logging(LOG_VERBOSE, "Check TMF_ONLY field"); logging(LOG_VERBOSE, "Check TMF_ONLY field");
CU_ASSERT_EQUAL(ct_page->control.tmf_only, ap_page->control.tmf_only); CU_ASSERT_EQUAL(ct_page->control.tmf_only, ap_page->control.tmf_only);
logging(LOG_VERBOSE, "Check dpicz field"); logging(LOG_VERBOSE, "Check dpicz field");
CU_ASSERT_EQUAL(ct_page->control.dpicz, ap_page->control.dpicz); CU_ASSERT_EQUAL(ct_page->control.dpicz, ap_page->control.dpicz);
logging(LOG_VERBOSE, "Check d_sense field"); logging(LOG_VERBOSE, "Check d_sense field");
CU_ASSERT_EQUAL(ct_page->control.d_sense, ap_page->control.d_sense); CU_ASSERT_EQUAL(ct_page->control.d_sense, ap_page->control.d_sense);
logging(LOG_VERBOSE, "Check gltsd field"); logging(LOG_VERBOSE, "Check gltsd field");
CU_ASSERT_EQUAL(ct_page->control.gltsd, ap_page->control.gltsd); CU_ASSERT_EQUAL(ct_page->control.gltsd, ap_page->control.gltsd);
logging(LOG_VERBOSE, "Check rlec field"); logging(LOG_VERBOSE, "Check rlec field");
CU_ASSERT_EQUAL(ct_page->control.rlec, ap_page->control.rlec); CU_ASSERT_EQUAL(ct_page->control.rlec, ap_page->control.rlec);
logging(LOG_VERBOSE, "Check queue_algorithm_modifier field"); logging(LOG_VERBOSE, "Check queue_algorithm_modifier field");
CU_ASSERT_EQUAL(ct_page->control.queue_algorithm_modifier, CU_ASSERT_EQUAL(ct_page->control.queue_algorithm_modifier,
ap_page->control.queue_algorithm_modifier); ap_page->control.queue_algorithm_modifier);
logging(LOG_VERBOSE, "Check nuar field"); logging(LOG_VERBOSE, "Check nuar field");
CU_ASSERT_EQUAL(ct_page->control.nuar, ap_page->control.nuar); CU_ASSERT_EQUAL(ct_page->control.nuar, ap_page->control.nuar);
logging(LOG_VERBOSE, "Check qerr field"); logging(LOG_VERBOSE, "Check qerr field");
CU_ASSERT_EQUAL(ct_page->control.qerr, ap_page->control.qerr); CU_ASSERT_EQUAL(ct_page->control.qerr, ap_page->control.qerr);
logging(LOG_VERBOSE, "Check vs field"); logging(LOG_VERBOSE, "Check vs field");
CU_ASSERT_EQUAL(ct_page->control.vs, ap_page->control.vs); CU_ASSERT_EQUAL(ct_page->control.vs, ap_page->control.vs);
logging(LOG_VERBOSE, "Check rac field"); logging(LOG_VERBOSE, "Check rac field");
CU_ASSERT_EQUAL(ct_page->control.rac, ap_page->control.rac); CU_ASSERT_EQUAL(ct_page->control.rac, ap_page->control.rac);
logging(LOG_VERBOSE, "Check ua_intlck_ctrl field"); logging(LOG_VERBOSE, "Check ua_intlck_ctrl field");
CU_ASSERT_EQUAL(ct_page->control.ua_intlck_ctrl, CU_ASSERT_EQUAL(ct_page->control.ua_intlck_ctrl,
ap_page->control.ua_intlck_ctrl); ap_page->control.ua_intlck_ctrl);
logging(LOG_VERBOSE, "Check swp field"); logging(LOG_VERBOSE, "Check swp field");
CU_ASSERT_EQUAL(ct_page->control.swp, ap_page->control.swp); CU_ASSERT_EQUAL(ct_page->control.swp, ap_page->control.swp);
logging(LOG_VERBOSE, "Check ato field"); logging(LOG_VERBOSE, "Check ato field");
CU_ASSERT_EQUAL(ct_page->control.ato, ap_page->control.ato); CU_ASSERT_EQUAL(ct_page->control.ato, ap_page->control.ato);
logging(LOG_VERBOSE, "Check tas field"); logging(LOG_VERBOSE, "Check tas field");
CU_ASSERT_EQUAL(ct_page->control.tas, ap_page->control.tas); CU_ASSERT_EQUAL(ct_page->control.tas, ap_page->control.tas);
logging(LOG_VERBOSE, "Check atmpe field"); logging(LOG_VERBOSE, "Check atmpe field");
CU_ASSERT_EQUAL(ct_page->control.atmpe, ap_page->control.atmpe); CU_ASSERT_EQUAL(ct_page->control.atmpe, ap_page->control.atmpe);
logging(LOG_VERBOSE, "Check rwwp field"); logging(LOG_VERBOSE, "Check rwwp field");
CU_ASSERT_EQUAL(ct_page->control.rwwp, ap_page->control.rwwp); CU_ASSERT_EQUAL(ct_page->control.rwwp, ap_page->control.rwwp);
logging(LOG_VERBOSE, "Check autoload_mode field"); logging(LOG_VERBOSE, "Check autoload_mode field");
CU_ASSERT_EQUAL(ct_page->control.autoload_mode, CU_ASSERT_EQUAL(ct_page->control.autoload_mode,
ap_page->control.autoload_mode); ap_page->control.autoload_mode);
logging(LOG_VERBOSE, "Check busy_timeout_period field"); logging(LOG_VERBOSE, "Check busy_timeout_period field");
CU_ASSERT_EQUAL(ct_page->control.busy_timeout_period, CU_ASSERT_EQUAL(ct_page->control.busy_timeout_period,
ap_page->control.busy_timeout_period); ap_page->control.busy_timeout_period);
logging(LOG_VERBOSE, "Check extended_selftest_completion_time field"); logging(LOG_VERBOSE, "Check extended_selftest_completion_time field");
CU_ASSERT_EQUAL(ct_page->control.extended_selftest_completion_time, CU_ASSERT_EQUAL(ct_page->control.extended_selftest_completion_time,
ap_page->control.extended_selftest_completion_time); ap_page->control.extended_selftest_completion_time);
logging(LOG_VERBOSE, "Verify that the values are sane."); logging(LOG_VERBOSE, "Verify that the values are sane.");
logging(LOG_VERBOSE, "Check that TST is 0 or 1."); logging(LOG_VERBOSE, "Check that TST is 0 or 1.");
if (ct_page->control.tst > 1) { if (ct_page->control.tst > 1) {
logging(LOG_NORMAL, "[FAILED] TST value is invalid. Must be " logging(LOG_NORMAL, "[FAILED] TST value is invalid. Must be "
"0, 1 but was %d", ct_page->control.tst); "0, 1 but was %d", ct_page->control.tst);
CU_FAIL("[FAILED] TST is invalid."); CU_FAIL("[FAILED] TST is invalid.");
} }
logging(LOG_VERBOSE, "Check that QUEUE_ALGORITHM_MODIFIER is " logging(LOG_VERBOSE, "Check that QUEUE_ALGORITHM_MODIFIER is "
"0, 1 or >7"); "0, 1 or >7");
if (ct_page->control.queue_algorithm_modifier > 1 && if (ct_page->control.queue_algorithm_modifier > 1 &&
ct_page->control.queue_algorithm_modifier < 8) { ct_page->control.queue_algorithm_modifier < 8) {
logging(LOG_NORMAL, "[FAILED] QUEUE_ALGORITHM_MODIFIER value " logging(LOG_NORMAL, "[FAILED] QUEUE_ALGORITHM_MODIFIER value "
"is invalid. Must be 0, 1 or >7 but was %d", "is invalid. Must be 0, 1 or >7 but was %d",
ct_page->control.queue_algorithm_modifier); ct_page->control.queue_algorithm_modifier);
CU_FAIL("[FAILED] QUEUE_ALGORITHM_MODIFIER is invalid."); CU_FAIL("[FAILED] QUEUE_ALGORITHM_MODIFIER is invalid.");
} }
logging(LOG_VERBOSE, "Check that QERR is not 2"); logging(LOG_VERBOSE, "Check that QERR is not 2");
if (ct_page->control.qerr == 2) { if (ct_page->control.qerr == 2) {
logging(LOG_NORMAL, "[FAILED] QERR value " logging(LOG_NORMAL, "[FAILED] QERR value "
"is invalid. Can not be 2"); "is invalid. Can not be 2");
CU_FAIL("[FAILED] QERR is invalid."); CU_FAIL("[FAILED] QERR is invalid.");
} }
logging(LOG_VERBOSE, "Check that UA_INTLCK_CTRL is not 1"); logging(LOG_VERBOSE, "Check that UA_INTLCK_CTRL is not 1");
if (ct_page->control.ua_intlck_ctrl == 1) { if (ct_page->control.ua_intlck_ctrl == 1) {
logging(LOG_NORMAL, "[FAILED] UA_INTLCK_CTRL value " logging(LOG_NORMAL, "[FAILED] UA_INTLCK_CTRL value "
"is invalid. Can not be 1"); "is invalid. Can not be 1");
CU_FAIL("[FAILED] UA_INTLCK_CTRL is invalid."); CU_FAIL("[FAILED] UA_INTLCK_CTRL is invalid.");
} }
logging(LOG_VERBOSE, "Check that AUTOLOAD is 0, 1 or 2"); logging(LOG_VERBOSE, "Check that AUTOLOAD is 0, 1 or 2");
if (ct_page->control.autoload_mode > 2) { if (ct_page->control.autoload_mode > 2) {
logging(LOG_NORMAL, "[FAILED] AUTOLOAD value " logging(LOG_NORMAL, "[FAILED] AUTOLOAD value "
"is invalid. Must be 0, 1 or 2 but was %d", "is invalid. Must be 0, 1 or 2 but was %d",
ct_page->control.autoload_mode); ct_page->control.autoload_mode);
CU_FAIL("[FAILED] AUTOLOAD is invalid."); CU_FAIL("[FAILED] AUTOLOAD is invalid.");
} }
logging(LOG_VERBOSE, "Check that BUSY_TIMEOUT_PERIOD is specified"); logging(LOG_VERBOSE, "Check that BUSY_TIMEOUT_PERIOD is specified");
if (ct_page->control.busy_timeout_period == 0) { if (ct_page->control.busy_timeout_period == 0) {
logging(LOG_NORMAL, "[WARNING] BUSY_TIMEOUT_PERIOD is " logging(LOG_NORMAL, "[WARNING] BUSY_TIMEOUT_PERIOD is "
"undefined."); "undefined.");
} }
finished: finished:
if (ap_task != NULL) { if (ap_task != NULL) {
scsi_free_scsi_task(ap_task); scsi_free_scsi_task(ap_task);
} }
if (ct_task != NULL) { if (ct_task != NULL) {
scsi_free_scsi_task(ct_task); scsi_free_scsi_task(ct_task);
} }
} }

View File

@@ -29,86 +29,86 @@
void void
test_modesense6_control_d_sense(void) test_modesense6_control_d_sense(void)
{ {
struct scsi_task *ms_task = NULL; struct scsi_task *ms_task = NULL;
struct scsi_task *r16_task = NULL; struct scsi_task *r16_task = NULL;
struct scsi_mode_sense *ms; struct scsi_mode_sense *ms;
struct scsi_mode_page *page; struct scsi_mode_page *page;
int ret; int ret;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test of MODESENSE6 CONTROL D_SENSE flag"); logging(LOG_VERBOSE, "Test of MODESENSE6 CONTROL D_SENSE flag");
logging(LOG_VERBOSE, "Read the CONTROL page from the device"); logging(LOG_VERBOSE, "Read the CONTROL page from the device");
ret = modesense6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT, ret = modesense6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT,
SCSI_MODEPAGE_CONTROL, 0, 255, SCSI_MODEPAGE_CONTROL, 0, 255,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
if (ret != 0) { if (ret != 0) {
logging(LOG_NORMAL,"[WARNING] Could not read " logging(LOG_NORMAL,"[WARNING] Could not read "
"BlockDeviceCharacteristics."); "BlockDeviceCharacteristics.");
goto finished; goto finished;
} }
logging(LOG_VERBOSE, "[SUCCESS] CONTROL page fetched."); logging(LOG_VERBOSE, "[SUCCESS] CONTROL page fetched.");
logging(LOG_VERBOSE, "Try to unmarshall the DATA-IN buffer."); logging(LOG_VERBOSE, "Try to unmarshall the DATA-IN buffer.");
ms = scsi_datain_unmarshall(ms_task); ms = scsi_datain_unmarshall(ms_task);
if (ms == NULL) { if (ms == NULL) {
logging(LOG_NORMAL, "[FAILED] failed to unmarshall mode sense " logging(LOG_NORMAL, "[FAILED] failed to unmarshall mode sense "
"datain buffer"); "datain buffer");
CU_FAIL("[FAILED] Failed to unmarshall the data-in buffer."); CU_FAIL("[FAILED] Failed to unmarshall the data-in buffer.");
goto finished; goto finished;
} }
logging(LOG_VERBOSE, "[SUCCESS] Unmarshalling successful."); logging(LOG_VERBOSE, "[SUCCESS] Unmarshalling successful.");
for (page = ms->pages; page; page = page->next) { for (page = ms->pages; page; page = page->next) {
if (page->page_code == SCSI_MODEPAGE_CONTROL) { if (page->page_code == SCSI_MODEPAGE_CONTROL) {
break; break;
} }
} }
if(page == NULL) { if(page == NULL) {
logging(LOG_NORMAL, "[WARNING] CONTROL page was not returned." logging(LOG_NORMAL, "[WARNING] CONTROL page was not returned."
"All devices SHOULD implement this page."); "All devices SHOULD implement this page.");
CU_PASS("[SKIPPED] CONTROL page not reported"); CU_PASS("[SKIPPED] CONTROL page not reported");
goto finished; goto finished;
} }
logging(LOG_VERBOSE, "Send a READ16 that will fail so we can check " logging(LOG_VERBOSE, "Send a READ16 that will fail so we can check "
"the type of sense data returned"); "the type of sense data returned");
READ16(sd, &r16_task, 0xffffffffffffffffLL, block_size, block_size, 0, READ16(sd, &r16_task, 0xffffffffffffffffLL, block_size, block_size, 0,
0, 0, 0, 0, NULL, 0, 0, 0, 0, NULL,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
if (page->control.d_sense) { if (page->control.d_sense) {
logging(LOG_VERBOSE, "D_SENSE is set, verify that sense format " logging(LOG_VERBOSE, "D_SENSE is set, verify that sense format "
"is descriptor format"); "is descriptor format");
} else { } else {
logging(LOG_VERBOSE, "D_SENSE is clear, verify that sense format " logging(LOG_VERBOSE, "D_SENSE is clear, verify that sense format "
"is fixed format"); "is fixed format");
} }
switch (r16_task->sense.error_type) { switch (r16_task->sense.error_type) {
case SCSI_SENSE_DESCRIPTOR_CURRENT: case SCSI_SENSE_DESCRIPTOR_CURRENT:
case SCSI_SENSE_DESCRIPTOR_DEFERRED_ERRORS: case SCSI_SENSE_DESCRIPTOR_DEFERRED_ERRORS:
if (!page->control.d_sense) { if (!page->control.d_sense) {
logging(LOG_NORMAL, "[FAILED] D_SENSE is set but " logging(LOG_NORMAL, "[FAILED] D_SENSE is set but "
"returned sense is not descriptor format"); "returned sense is not descriptor format");
CU_FAIL("[FAILED] Wrong type of sense format returned"); CU_FAIL("[FAILED] Wrong type of sense format returned");
goto finished; goto finished;
} }
break; break;
case SCSI_SENSE_FIXED_CURRENT: case SCSI_SENSE_FIXED_CURRENT:
case SCSI_SENSE_FIXED_DEFERRED_ERRORS: case SCSI_SENSE_FIXED_DEFERRED_ERRORS:
if (page->control.d_sense) { if (page->control.d_sense) {
logging(LOG_NORMAL, "[FAILED] D_SENSE is cleat but " logging(LOG_NORMAL, "[FAILED] D_SENSE is cleat but "
"returned sense is not fixed format"); "returned sense is not fixed format");
CU_FAIL("[FAILED] Wrong type of sense format returned"); CU_FAIL("[FAILED] Wrong type of sense format returned");
goto finished; goto finished;
} }
break; break;
} }
finished: finished:
if (ms_task != NULL) { if (ms_task != NULL) {
scsi_free_scsi_task(ms_task); scsi_free_scsi_task(ms_task);
} }
if (r16_task != NULL) { if (r16_task != NULL) {
scsi_free_scsi_task(r16_task); scsi_free_scsi_task(r16_task);
} }
} }

View File

@@ -29,74 +29,74 @@
void void
test_modesense6_control_swp(void) test_modesense6_control_swp(void)
{ {
struct scsi_task *ms_task = NULL; struct scsi_task *ms_task = NULL;
struct scsi_mode_sense *ms; struct scsi_mode_sense *ms;
struct scsi_mode_page *page; struct scsi_mode_page *page;
int ret; int ret;
CHECK_FOR_DATALOSS; CHECK_FOR_DATALOSS;
CHECK_FOR_SBC; CHECK_FOR_SBC;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test of MODESENSE6 CONTROL SWP flag"); logging(LOG_VERBOSE, "Test of MODESENSE6 CONTROL SWP flag");
logging(LOG_VERBOSE, "Set SWP to enable write protect"); logging(LOG_VERBOSE, "Set SWP to enable write protect");
ret = set_swp(sd); ret = set_swp(sd);
if (ret == -2) { if (ret == -2) {
CU_PASS("[SKIPPED] Target does not support changing SWP"); CU_PASS("[SKIPPED] Target does not support changing SWP");
return; return;
} }
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
if (ret) { if (ret) {
goto finished; goto finished;
} }
logging(LOG_VERBOSE, "Read the CONTROL page back from the device"); logging(LOG_VERBOSE, "Read the CONTROL page back from the device");
MODESENSE6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT, MODESENSE6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT,
SCSI_MODEPAGE_CONTROL, 0, 255, SCSI_MODEPAGE_CONTROL, 0, 255,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "[SUCCESS] CONTROL page fetched."); logging(LOG_VERBOSE, "[SUCCESS] CONTROL page fetched.");
logging(LOG_VERBOSE, "Try to unmarshall the DATA-IN buffer."); logging(LOG_VERBOSE, "Try to unmarshall the DATA-IN buffer.");
ms = scsi_datain_unmarshall(ms_task); ms = scsi_datain_unmarshall(ms_task);
if (ms == NULL) { if (ms == NULL) {
logging(LOG_NORMAL, "[FAILED] failed to unmarshall mode sense " logging(LOG_NORMAL, "[FAILED] failed to unmarshall mode sense "
"datain buffer"); "datain buffer");
CU_FAIL("[FAILED] Failed to unmarshall the data-in buffer."); CU_FAIL("[FAILED] Failed to unmarshall the data-in buffer.");
goto finished; goto finished;
} }
logging(LOG_VERBOSE, "[SUCCESS] Unmarshalling successful."); logging(LOG_VERBOSE, "[SUCCESS] Unmarshalling successful.");
for (page = ms->pages; page; page = page->next) { for (page = ms->pages; page; page = page->next) {
if (page->page_code == SCSI_MODEPAGE_CONTROL) { if (page->page_code == SCSI_MODEPAGE_CONTROL) {
break; break;
} }
} }
if(page == NULL) { if(page == NULL) {
logging(LOG_NORMAL, "[WARNING] CONTROL page was not returned." logging(LOG_NORMAL, "[WARNING] CONTROL page was not returned."
"All devices SHOULD implement this page."); "All devices SHOULD implement this page.");
} }
logging(LOG_VERBOSE, "Verify that the SWP bit is set"); logging(LOG_VERBOSE, "Verify that the SWP bit is set");
if (page->control.swp == 0) { if (page->control.swp == 0) {
logging(LOG_NORMAL, "[FAILED] SWP bit is not set"); logging(LOG_NORMAL, "[FAILED] SWP bit is not set");
CU_FAIL("[FAILED] SWP is not set"); CU_FAIL("[FAILED] SWP is not set");
goto finished; goto finished;
} }
logging(LOG_VERBOSE, "[SUCCESS] SWP was set successfully"); logging(LOG_VERBOSE, "[SUCCESS] SWP was set successfully");
logging(LOG_VERBOSE, "Read a block from the now Read-Only device"); logging(LOG_VERBOSE, "Read a block from the now Read-Only device");
READ10(sd, NULL, 0, block_size, block_size, 0, 0, 0, 0, 0, scratch, READ10(sd, NULL, 0, block_size, block_size, 0, 0, 0, 0, 0, scratch,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Try to write a block to the Read-Only device"); logging(LOG_VERBOSE, "Try to write a block to the Read-Only device");
WRITE10(sd, 0, block_size, block_size, 0, 0, 0, 0, 0, scratch, WRITE10(sd, 0, block_size, block_size, 0, 0, 0, 0, 0, scratch,
EXPECT_WRITE_PROTECTED); EXPECT_WRITE_PROTECTED);
finished: finished:
if (ms_task != NULL) { if (ms_task != NULL) {
scsi_free_scsi_task(ms_task); scsi_free_scsi_task(ms_task);
} }
logging(LOG_VERBOSE, "Clear SWP to disable write protect"); logging(LOG_VERBOSE, "Clear SWP to disable write protect");
clear_swp(sd); clear_swp(sd);
} }

View File

@@ -28,78 +28,78 @@
void void
test_modesense6_residuals(void) test_modesense6_residuals(void)
{ {
struct scsi_task *ms_task = NULL; struct scsi_task *ms_task = NULL;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test of MODESENSE6 Residuals"); logging(LOG_VERBOSE, "Test of MODESENSE6 Residuals");
logging(LOG_VERBOSE, "MODESENSE6 command should not result in any " logging(LOG_VERBOSE, "MODESENSE6 command should not result in any "
"residuals"); "residuals");
logging(LOG_VERBOSE, "Try a MODESENSE6 command with 4 bytes of " logging(LOG_VERBOSE, "Try a MODESENSE6 command with 4 bytes of "
"transfer length and verify that we don't get residuals."); "transfer length and verify that we don't get residuals.");
MODESENSE6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT, MODESENSE6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT,
SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 4, SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 4,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "[SUCCESS] All Pages fetched."); logging(LOG_VERBOSE, "[SUCCESS] All Pages fetched.");
logging(LOG_VERBOSE, "Verify that we got at most 4 bytes of DATA-IN"); logging(LOG_VERBOSE, "Verify that we got at most 4 bytes of DATA-IN");
if (ms_task->datain.size > 4) { if (ms_task->datain.size > 4) {
logging(LOG_NORMAL, "[FAILED] got more than 4 bytes of " logging(LOG_NORMAL, "[FAILED] got more than 4 bytes of "
"DATA-IN."); "DATA-IN.");
} else { } else {
logging(LOG_VERBOSE, "[SUCCESS] <= 4 bytes of DATA-IN " logging(LOG_VERBOSE, "[SUCCESS] <= 4 bytes of DATA-IN "
"received."); "received.");
} }
CU_ASSERT_TRUE(ms_task->datain.size <= 4); CU_ASSERT_TRUE(ms_task->datain.size <= 4);
logging(LOG_VERBOSE, "Verify residual overflow flag not set"); logging(LOG_VERBOSE, "Verify residual overflow flag not set");
if (ms_task->residual_status == SCSI_RESIDUAL_OVERFLOW) { if (ms_task->residual_status == SCSI_RESIDUAL_OVERFLOW) {
logging(LOG_VERBOSE, "[FAILED] Target set residual " logging(LOG_VERBOSE, "[FAILED] Target set residual "
"overflow flag"); "overflow flag");
} }
CU_ASSERT_NOT_EQUAL(ms_task->residual_status, SCSI_RESIDUAL_OVERFLOW); CU_ASSERT_NOT_EQUAL(ms_task->residual_status, SCSI_RESIDUAL_OVERFLOW);
logging(LOG_VERBOSE, "Try a MODESENSE6 command with 255 bytes of " logging(LOG_VERBOSE, "Try a MODESENSE6 command with 255 bytes of "
"transfer length and verify that we get residuals if the target returns less than the requested amount of data."); "transfer length and verify that we get residuals if the target returns less than the requested amount of data.");
scsi_free_scsi_task(ms_task); scsi_free_scsi_task(ms_task);
MODESENSE6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT, MODESENSE6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT,
SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255, SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "[SUCCESS] All Pages fetched."); logging(LOG_VERBOSE, "[SUCCESS] All Pages fetched.");
if (ms_task->datain.size == 255) { if (ms_task->datain.size == 255) {
logging(LOG_VERBOSE, "We got all 255 bytes of data back " logging(LOG_VERBOSE, "We got all 255 bytes of data back "
"from the target. Verify that underflow is not set."); "from the target. Verify that underflow is not set.");
if (ms_task->residual_status == SCSI_RESIDUAL_UNDERFLOW) { if (ms_task->residual_status == SCSI_RESIDUAL_UNDERFLOW) {
logging(LOG_VERBOSE, "[FAILED] Target set residual " logging(LOG_VERBOSE, "[FAILED] Target set residual "
"underflow flag"); "underflow flag");
} else { } else {
logging(LOG_VERBOSE, "[SUCCESS] Residual underflow " logging(LOG_VERBOSE, "[SUCCESS] Residual underflow "
"is not set"); "is not set");
} }
CU_ASSERT_NOT_EQUAL(ms_task->residual_status, CU_ASSERT_NOT_EQUAL(ms_task->residual_status,
SCSI_RESIDUAL_UNDERFLOW); SCSI_RESIDUAL_UNDERFLOW);
} else { } else {
logging(LOG_VERBOSE, "We got less than the requested 255 bytes " logging(LOG_VERBOSE, "We got less than the requested 255 bytes "
"from the target. Verify that underflow is set."); "from the target. Verify that underflow is set.");
if (ms_task->residual_status != SCSI_RESIDUAL_UNDERFLOW) { if (ms_task->residual_status != SCSI_RESIDUAL_UNDERFLOW) {
logging(LOG_VERBOSE, "[FAILED] Target did not set " logging(LOG_VERBOSE, "[FAILED] Target did not set "
"residual underflow flag"); "residual underflow flag");
} else { } else {
logging(LOG_VERBOSE, "[SUCCESS] Residual underflow " logging(LOG_VERBOSE, "[SUCCESS] Residual underflow "
"is set"); "is set");
} }
CU_ASSERT_EQUAL(ms_task->residual_status, CU_ASSERT_EQUAL(ms_task->residual_status,
SCSI_RESIDUAL_UNDERFLOW); SCSI_RESIDUAL_UNDERFLOW);
} }
scsi_free_scsi_task(ms_task); scsi_free_scsi_task(ms_task);
} }

View File

@@ -32,65 +32,65 @@
void void
test_multipathio_compareandwrite(void) test_multipathio_compareandwrite(void)
{ {
int io_bl = 1; /* 1 block CAW IOs */ int io_bl = 1; /* 1 block CAW IOs */
int path; int path;
int i, ret; int i, ret;
int maxbl; int maxbl;
CHECK_FOR_DATALOSS; CHECK_FOR_DATALOSS;
CHECK_FOR_SBC; CHECK_FOR_SBC;
MPATH_SKIP_IF_UNAVAILABLE(mp_sds, mp_num_sds); MPATH_SKIP_IF_UNAVAILABLE(mp_sds, mp_num_sds);
if (inq_bl) { if (inq_bl) {
maxbl = inq_bl->max_cmp; maxbl = inq_bl->max_cmp;
} else { } else {
/* Assume we are not limited */ /* Assume we are not limited */
maxbl = 256; maxbl = 256;
} }
if (maxbl < io_bl) { if (maxbl < io_bl) {
CU_PASS("[SKIPPED] MAXIMUM_COMPARE_AND_WRITE_LENGTH too small"); CU_PASS("[SKIPPED] MAXIMUM_COMPARE_AND_WRITE_LENGTH too small");
return; return;
} }
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Initialising data prior to COMPARE_AND_WRITE"); logging(LOG_VERBOSE, "Initialising data prior to COMPARE_AND_WRITE");
memset(scratch, 0, io_bl * block_size); memset(scratch, 0, io_bl * block_size);
ret = writesame10(mp_sds[0], 0, ret = writesame10(mp_sds[0], 0,
block_size, 256, 0, 0, 0, 0, scratch, block_size, 256, 0, 0, 0, 0, scratch,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
if (ret == -2) { if (ret == -2) {
CU_PASS("[SKIPPED] Target does not support WRITESAME10. Skipping test"); CU_PASS("[SKIPPED] Target does not support WRITESAME10. Skipping test");
return; return;
} }
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
logging(LOG_VERBOSE, "Test multipath COMPARE_AND_WRITE"); logging(LOG_VERBOSE, "Test multipath COMPARE_AND_WRITE");
for (i = 0; i < 256; i++) { for (i = 0; i < 256; i++) {
for (path = 0; path < mp_num_sds; path++) { for (path = 0; path < mp_num_sds; path++) {
logging(LOG_VERBOSE, logging(LOG_VERBOSE,
"Test COMPARE_AND_WRITE(%d->%d) using path %d", "Test COMPARE_AND_WRITE(%d->%d) using path %d",
path, path + 1, path); path, path + 1, path);
/* compare data is first half */ /* compare data is first half */
memset(scratch, path, io_bl * block_size); memset(scratch, path, io_bl * block_size);
/* write data is the second half, wrap around */ /* write data is the second half, wrap around */
memset(scratch + io_bl * block_size, path + 1, memset(scratch + io_bl * block_size, path + 1,
io_bl * block_size); io_bl * block_size);
COMPAREANDWRITE(mp_sds[path], i, COMPAREANDWRITE(mp_sds[path], i,
scratch, 2 * io_bl * block_size, scratch, 2 * io_bl * block_size,
block_size, 0, 0, 0, 0, block_size, 0, 0, 0, 0,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, logging(LOG_VERBOSE,
"Test bad COMPARE_AND_WRITE(%d->%d)", "Test bad COMPARE_AND_WRITE(%d->%d)",
path, path + 1); path, path + 1);
COMPAREANDWRITE(mp_sds[path], i, COMPAREANDWRITE(mp_sds[path], i,
scratch, 2 * io_bl * block_size, scratch, 2 * io_bl * block_size,
block_size, 0, 0, 0, 0, block_size, 0, 0, 0, 0,
EXPECT_MISCOMPARE); EXPECT_MISCOMPARE);
} }
} }
} }

View File

@@ -31,43 +31,43 @@
void void
test_multipathio_reset(void) test_multipathio_reset(void)
{ {
int reset_path; int reset_path;
CHECK_FOR_DATALOSS; CHECK_FOR_DATALOSS;
CHECK_FOR_SBC; CHECK_FOR_SBC;
MPATH_SKIP_IF_UNAVAILABLE(mp_sds, mp_num_sds); MPATH_SKIP_IF_UNAVAILABLE(mp_sds, mp_num_sds);
MPATH_SKIP_UNLESS_ISCSI(mp_sds, mp_num_sds); MPATH_SKIP_UNLESS_ISCSI(mp_sds, mp_num_sds);
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
for (reset_path = 0; reset_path < mp_num_sds; reset_path++) { for (reset_path = 0; reset_path < mp_num_sds; reset_path++) {
int num_uas; int num_uas;
int ret; int ret;
int tur_path; int tur_path;
struct scsi_device *reset_sd = mp_sds[reset_path]; struct scsi_device *reset_sd = mp_sds[reset_path];
logging(LOG_VERBOSE, "Awaiting good TUR"); logging(LOG_VERBOSE, "Awaiting good TUR");
ret = test_iscsi_tur_until_good(reset_sd, &num_uas); ret = test_iscsi_tur_until_good(reset_sd, &num_uas);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
logging(LOG_VERBOSE, logging(LOG_VERBOSE,
"Test multipath LUN Reset using path %d", reset_path); "Test multipath LUN Reset using path %d", reset_path);
ret = iscsi_task_mgmt_lun_reset_sync(reset_sd->iscsi_ctx, ret = iscsi_task_mgmt_lun_reset_sync(reset_sd->iscsi_ctx,
reset_sd->iscsi_lun); reset_sd->iscsi_lun);
if (ret != 0) { if (ret != 0) {
logging(LOG_NORMAL, "LUN reset failed. %s", logging(LOG_NORMAL, "LUN reset failed. %s",
iscsi_get_error(reset_sd->iscsi_ctx)); iscsi_get_error(reset_sd->iscsi_ctx));
} }
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
/* check for and clear LU reset UA on all paths */ /* check for and clear LU reset UA on all paths */
for (tur_path = 0; tur_path < mp_num_sds; tur_path++) { for (tur_path = 0; tur_path < mp_num_sds; tur_path++) {
logging(LOG_VERBOSE, "check for LU reset unit " logging(LOG_VERBOSE, "check for LU reset unit "
"attention via TUR on path %d", tur_path); "attention via TUR on path %d", tur_path);
ret = test_iscsi_tur_until_good(mp_sds[tur_path], &num_uas); ret = test_iscsi_tur_until_good(mp_sds[tur_path], &num_uas);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
CU_ASSERT_NOT_EQUAL(num_uas, 0); CU_ASSERT_NOT_EQUAL(num_uas, 0);
} }
} }
} }

View File

@@ -31,44 +31,44 @@
void void
test_multipathio_simple(void) test_multipathio_simple(void)
{ {
int write_path; int write_path;
unsigned char *write_buf = alloca(256 * block_size); unsigned char *write_buf = alloca(256 * block_size);
unsigned char *read_buf = alloca(256 * block_size); unsigned char *read_buf = alloca(256 * block_size);
CHECK_FOR_DATALOSS; CHECK_FOR_DATALOSS;
CHECK_FOR_SBC; CHECK_FOR_SBC;
MPATH_SKIP_IF_UNAVAILABLE(mp_sds, mp_num_sds); MPATH_SKIP_IF_UNAVAILABLE(mp_sds, mp_num_sds);
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
memset(write_buf, 0xa6, 256 * block_size); memset(write_buf, 0xa6, 256 * block_size);
for (write_path = 0; write_path < mp_num_sds; write_path++) { for (write_path = 0; write_path < mp_num_sds; write_path++) {
int i; int i;
int read_path; int read_path;
/* read back written data using a different path */ /* read back written data using a different path */
read_path = (write_path + 1) % mp_num_sds; read_path = (write_path + 1) % mp_num_sds;
logging(LOG_VERBOSE, logging(LOG_VERBOSE,
"Test multipath WRITE10/READ10 of 1-256 blocks using " "Test multipath WRITE10/READ10 of 1-256 blocks using "
"path %d", write_path); "path %d", write_path);
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
if (maximum_transfer_length if (maximum_transfer_length
&& maximum_transfer_length < i) { && maximum_transfer_length < i) {
break; break;
} }
WRITE10(mp_sds[write_path], 0, i * block_size, WRITE10(mp_sds[write_path], 0, i * block_size,
block_size, 0, 0, 0, 0, 0, write_buf, block_size, 0, 0, 0, 0, 0, write_buf,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
READ10(mp_sds[read_path], NULL, 0, i * block_size, READ10(mp_sds[read_path], NULL, 0, i * block_size,
block_size, 0, 0, 0, 0, 0, read_buf, block_size, 0, 0, 0, 0, 0, read_buf,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
/* compare written and read data */ /* compare written and read data */
CU_ASSERT_EQUAL(0, CU_ASSERT_EQUAL(0,
memcmp(write_buf, read_buf, i * block_size)); memcmp(write_buf, read_buf, i * block_size));
} }
} }
} }

View File

@@ -28,64 +28,64 @@
static void static void
test_synchronizecache10(void) test_synchronizecache10(void)
{ {
logging(LOG_VERBOSE, "Test SYNCHRONIZECACHE10 when medium is ejected."); logging(LOG_VERBOSE, "Test SYNCHRONIZECACHE10 when medium is ejected.");
SYNCHRONIZECACHE10(sd, 0, 1, 1, 1, SYNCHRONIZECACHE10(sd, 0, 1, 1, 1,
EXPECT_NO_MEDIUM); EXPECT_NO_MEDIUM);
} }
static void static void
test_synchronizecache16(void) test_synchronizecache16(void)
{ {
logging(LOG_VERBOSE, "Test SYNCHRONIZECACHE16 when medium is ejected."); logging(LOG_VERBOSE, "Test SYNCHRONIZECACHE16 when medium is ejected.");
SYNCHRONIZECACHE16(sd, 0, 1, 1, 1, SYNCHRONIZECACHE16(sd, 0, 1, 1, 1,
EXPECT_NO_MEDIUM); EXPECT_NO_MEDIUM);
} }
static void static void
test_read10(void) test_read10(void)
{ {
logging(LOG_VERBOSE, "Test READ10 when medium is ejected."); logging(LOG_VERBOSE, "Test READ10 when medium is ejected.");
READ10(sd, NULL, 0, block_size, block_size, 0, 0, 0, 0, 0, NULL, READ10(sd, NULL, 0, block_size, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_NO_MEDIUM); EXPECT_NO_MEDIUM);
} }
static void static void
test_read12(void) test_read12(void)
{ {
logging(LOG_VERBOSE, "Test READ12 when medium is ejected."); logging(LOG_VERBOSE, "Test READ12 when medium is ejected.");
READ12(sd, NULL, 0, block_size, block_size, 0, 0, 0, 0, 0, NULL, READ12(sd, NULL, 0, block_size, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_NO_MEDIUM); EXPECT_NO_MEDIUM);
} }
static void static void
test_read16(void) test_read16(void)
{ {
logging(LOG_VERBOSE, "Test READ16 when medium is ejected."); logging(LOG_VERBOSE, "Test READ16 when medium is ejected.");
READ16(sd, NULL, 0, block_size, block_size, 0, 0, 0, 0, 0, NULL, READ16(sd, NULL, 0, block_size, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_NO_MEDIUM); EXPECT_NO_MEDIUM);
} }
static void static void
test_write10(void) test_write10(void)
{ {
logging(LOG_VERBOSE, "Test WRITE10 when medium is ejected."); logging(LOG_VERBOSE, "Test WRITE10 when medium is ejected.");
WRITE10(sd, 0, block_size, block_size, 0, 0, 0, 0, 0, scratch, WRITE10(sd, 0, block_size, block_size, 0, 0, 0, 0, 0, scratch,
EXPECT_NO_MEDIUM); EXPECT_NO_MEDIUM);
} }
static void static void
test_write12(void) test_write12(void)
{ {
logging(LOG_VERBOSE, "Test WRITE12 when medium is ejected."); logging(LOG_VERBOSE, "Test WRITE12 when medium is ejected.");
WRITE12(sd, 0, block_size, block_size, 0, 0, 0, 0, 0, scratch, WRITE12(sd, 0, block_size, block_size, 0, 0, 0, 0, 0, scratch,
EXPECT_NO_MEDIUM); EXPECT_NO_MEDIUM);
} }
static void static void
test_write16(void) test_write16(void)
{ {
logging(LOG_VERBOSE, "Test WRITE16 when medium is ejected."); logging(LOG_VERBOSE, "Test WRITE16 when medium is ejected.");
WRITE16(sd, 0, block_size, block_size, 0, 0, 0, 0, 0, scratch, WRITE16(sd, 0, block_size, block_size, 0, 0, 0, 0, 0, scratch,
EXPECT_NO_MEDIUM); EXPECT_NO_MEDIUM);
} }
@@ -93,7 +93,7 @@ static void
test_writeverify10(void) test_writeverify10(void)
{ {
logging(LOG_VERBOSE, "Test WRITEVERIFY10 when medium is ejected."); logging(LOG_VERBOSE, "Test WRITEVERIFY10 when medium is ejected.");
WRITEVERIFY10(sd, 0, block_size, block_size, 0, 0, 0, 0, scratch, WRITEVERIFY10(sd, 0, block_size, block_size, 0, 0, 0, 0, scratch,
EXPECT_NO_MEDIUM); EXPECT_NO_MEDIUM);
} }
@@ -101,7 +101,7 @@ static void
test_writeverify12(void) test_writeverify12(void)
{ {
logging(LOG_VERBOSE, "Test WRITEVERIFY12 when medium is ejected."); logging(LOG_VERBOSE, "Test WRITEVERIFY12 when medium is ejected.");
WRITEVERIFY12(sd, 0, block_size, block_size, 0, 0, 0, 0, scratch, WRITEVERIFY12(sd, 0, block_size, block_size, 0, 0, 0, 0, scratch,
EXPECT_NO_MEDIUM); EXPECT_NO_MEDIUM);
} }
@@ -109,68 +109,68 @@ static void
test_writeverify16(void) test_writeverify16(void)
{ {
logging(LOG_VERBOSE, "Test WRITEVERIFY16 when medium is ejected."); logging(LOG_VERBOSE, "Test WRITEVERIFY16 when medium is ejected.");
WRITEVERIFY16(sd, 0, block_size, block_size, 0, 0, 0, 0, scratch, WRITEVERIFY16(sd, 0, block_size, block_size, 0, 0, 0, 0, scratch,
EXPECT_NO_MEDIUM); EXPECT_NO_MEDIUM);
} }
static void static void
test_verify10(void) test_verify10(void)
{ {
logging(LOG_VERBOSE, "Test VERIFY10 when medium is ejected."); logging(LOG_VERBOSE, "Test VERIFY10 when medium is ejected.");
VERIFY10(sd, 0, block_size, block_size, 0, 0, 1, scratch, VERIFY10(sd, 0, block_size, block_size, 0, 0, 1, scratch,
EXPECT_NO_MEDIUM); EXPECT_NO_MEDIUM);
} }
static void static void
test_verify12(void) test_verify12(void)
{ {
logging(LOG_VERBOSE, "Test VERIFY12 when medium is ejected."); logging(LOG_VERBOSE, "Test VERIFY12 when medium is ejected.");
VERIFY12(sd, 0, block_size, block_size, 0, 0, 1, scratch, VERIFY12(sd, 0, block_size, block_size, 0, 0, 1, scratch,
EXPECT_NO_MEDIUM); EXPECT_NO_MEDIUM);
} }
static void static void
test_verify16(void) test_verify16(void)
{ {
logging(LOG_VERBOSE, "Test VERIFY16 when medium is ejected."); logging(LOG_VERBOSE, "Test VERIFY16 when medium is ejected.");
VERIFY16(sd, 0, block_size, block_size, 0, 0, 1, scratch, VERIFY16(sd, 0, block_size, block_size, 0, 0, 1, scratch,
EXPECT_NO_MEDIUM); EXPECT_NO_MEDIUM);
} }
static void static void
test_getlbastatus(void) test_getlbastatus(void)
{ {
logging(LOG_VERBOSE, "Test GET_LBA_STATUS when medium is ejected."); logging(LOG_VERBOSE, "Test GET_LBA_STATUS when medium is ejected.");
GETLBASTATUS(sd, NULL, 0, 24, GETLBASTATUS(sd, NULL, 0, 24,
EXPECT_NO_MEDIUM); EXPECT_NO_MEDIUM);
} }
static void static void
test_prefetch10(void) test_prefetch10(void)
{ {
logging(LOG_VERBOSE, "Test PREFETCH10 when medium is ejected."); logging(LOG_VERBOSE, "Test PREFETCH10 when medium is ejected.");
PREFETCH10(sd, 0, 1, 1, 0, PREFETCH10(sd, 0, 1, 1, 0,
EXPECT_NO_MEDIUM); EXPECT_NO_MEDIUM);
} }
static void static void
test_prefetch16(void) test_prefetch16(void)
{ {
logging(LOG_VERBOSE, "Test PREFETCH16 when medium is ejected."); logging(LOG_VERBOSE, "Test PREFETCH16 when medium is ejected.");
PREFETCH16(sd, 0, 1, 1, 0, PREFETCH16(sd, 0, 1, 1, 0,
EXPECT_NO_MEDIUM); EXPECT_NO_MEDIUM);
} }
static void static void
test_orwrite(void) test_orwrite(void)
{ {
logging(LOG_VERBOSE, "Test ORWRITE when medium is ejected."); logging(LOG_VERBOSE, "Test ORWRITE when medium is ejected.");
ORWRITE(sd, 0, block_size, block_size, 0, 0, 0, 0, 0, scratch, ORWRITE(sd, 0, block_size, block_size, 0, 0, 0, 0, 0, scratch,
EXPECT_NO_MEDIUM); EXPECT_NO_MEDIUM);
} }
static void static void
test_compareandwrite(void) test_compareandwrite(void)
{ {
logging(LOG_VERBOSE, "Test COMPAREANDWRITE when medium is ejected."); logging(LOG_VERBOSE, "Test COMPAREANDWRITE when medium is ejected.");
COMPAREANDWRITE(sd, 0, scratch, 2 * block_size, block_size, 0, 0, 0, 0, COMPAREANDWRITE(sd, 0, scratch, 2 * block_size, block_size, 0, 0, 0, 0,
EXPECT_NO_MEDIUM); EXPECT_NO_MEDIUM);
} }
@@ -178,36 +178,36 @@ test_compareandwrite(void)
static void static void
test_writesame10(void) test_writesame10(void)
{ {
logging(LOG_VERBOSE, "Test WRITESAME10 when medium is ejected."); logging(LOG_VERBOSE, "Test WRITESAME10 when medium is ejected.");
WRITESAME10(sd, 0, block_size, 1, 0, 0, 0, 0, scratch, WRITESAME10(sd, 0, block_size, 1, 0, 0, 0, 0, scratch,
EXPECT_NO_MEDIUM); EXPECT_NO_MEDIUM);
} }
static void static void
test_writesame16(void) test_writesame16(void)
{ {
logging(LOG_VERBOSE, "Test WRITESAME16 when medium is ejected."); logging(LOG_VERBOSE, "Test WRITESAME16 when medium is ejected.");
WRITESAME16(sd, 0, block_size, 1, 0, 0, 0, 0, scratch, WRITESAME16(sd, 0, block_size, 1, 0, 0, 0, 0, scratch,
EXPECT_NO_MEDIUM); EXPECT_NO_MEDIUM);
} }
static void static void
test_unmap(void) test_unmap(void)
{ {
struct unmap_list list[1]; struct unmap_list list[1];
logging(LOG_VERBOSE, "Test UNMAP when medium is ejected."); logging(LOG_VERBOSE, "Test UNMAP when medium is ejected.");
list[0].lba = 0; list[0].lba = 0;
list[0].num = lbppb; list[0].num = lbppb;
UNMAP(sd, 0, list, 1, UNMAP(sd, 0, list, 1,
EXPECT_NO_MEDIUM); EXPECT_NO_MEDIUM);
} }
static void static void
test_readcapacity10(void) test_readcapacity10(void)
{ {
logging(LOG_VERBOSE, "Test READCAPACITY10 when medium is ejected."); logging(LOG_VERBOSE, "Test READCAPACITY10 when medium is ejected.");
READCAPACITY10(sd, NULL, 0, 0, READCAPACITY10(sd, NULL, 0, 0,
EXPECT_NO_MEDIUM); EXPECT_NO_MEDIUM);
} }
@@ -215,30 +215,30 @@ static void
test_readcapacity16(void) test_readcapacity16(void)
{ {
logging(LOG_VERBOSE, "Test READCAPACITY16 when medium is ejected."); logging(LOG_VERBOSE, "Test READCAPACITY16 when medium is ejected.");
READCAPACITY16(sd, NULL, 15, READCAPACITY16(sd, NULL, 15,
EXPECT_NO_MEDIUM); EXPECT_NO_MEDIUM);
} }
void void
test_nomedia_sbc(void) test_nomedia_sbc(void)
{ {
CHECK_FOR_SBC; CHECK_FOR_SBC;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test that Medium commands fail when medium is ejected on SBC devices"); logging(LOG_VERBOSE, "Test that Medium commands fail when medium is ejected on SBC devices");
if (!inq->rmb) { if (!inq->rmb) {
logging(LOG_VERBOSE, "[SKIPPED] LUN is not removable. " logging(LOG_VERBOSE, "[SKIPPED] LUN is not removable. "
"Skipping test."); "Skipping test.");
return; return;
} }
logging(LOG_VERBOSE, "Eject the medium."); logging(LOG_VERBOSE, "Eject the medium.");
STARTSTOPUNIT(sd, 1, 0, 0, 0, 1, 0, STARTSTOPUNIT(sd, 1, 0, 0, 0, 1, 0,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Test TESTUNITREADY when medium is ejected."); logging(LOG_VERBOSE, "Test TESTUNITREADY when medium is ejected.");
TESTUNITREADY(sd, TESTUNITREADY(sd,
EXPECT_NO_MEDIUM); EXPECT_NO_MEDIUM);
test_synchronizecache10(); test_synchronizecache10();
@@ -255,10 +255,10 @@ test_nomedia_sbc(void)
test_prefetch10(); test_prefetch10();
test_prefetch16(); test_prefetch16();
if (!data_loss) { if (!data_loss) {
logging(LOG_VERBOSE, "[SKIPPING] Dataloss flag not set. Skipping test for WRITE commands"); logging(LOG_VERBOSE, "[SKIPPING] Dataloss flag not set. Skipping test for WRITE commands");
goto finished; goto finished;
} }
test_compareandwrite(); test_compareandwrite();
test_orwrite(); test_orwrite();
@@ -273,7 +273,7 @@ test_nomedia_sbc(void)
test_writeverify16(); test_writeverify16();
finished: finished:
logging(LOG_VERBOSE, "Load the medium again."); logging(LOG_VERBOSE, "Load the medium again.");
STARTSTOPUNIT(sd, 1, 0, 0, 0, 1, 1, STARTSTOPUNIT(sd, 1, 0, 0, 0, 1, 1,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }

View File

@@ -27,23 +27,23 @@
void void
test_orwrite_0blocks(void) test_orwrite_0blocks(void)
{ {
CHECK_FOR_DATALOSS; CHECK_FOR_DATALOSS;
CHECK_FOR_SBC; CHECK_FOR_SBC;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test ORWRITE 0-blocks at LBA==0"); logging(LOG_VERBOSE, "Test ORWRITE 0-blocks at LBA==0");
ORWRITE(sd, 0, 0, block_size, 0, 0, 0, 0, 0, NULL, ORWRITE(sd, 0, 0, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Test ORWRITE 0-blocks one block past end-of-LUN"); logging(LOG_VERBOSE, "Test ORWRITE 0-blocks one block past end-of-LUN");
ORWRITE(sd, num_blocks + 1, 0, block_size, 0, 0, 0, 0, 0, NULL, ORWRITE(sd, num_blocks + 1, 0, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
logging(LOG_VERBOSE, "Test ORWRITE 0-blocks at LBA==2^63"); logging(LOG_VERBOSE, "Test ORWRITE 0-blocks at LBA==2^63");
ORWRITE(sd, 0x8000000000000000ULL, 0, block_size, 0, 0, 0, 0, 0, NULL, ORWRITE(sd, 0x8000000000000000ULL, 0, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
logging(LOG_VERBOSE, "Test ORWRITE 0-blocks at LBA==-1"); logging(LOG_VERBOSE, "Test ORWRITE 0-blocks at LBA==-1");
ORWRITE(sd, -1, 0, block_size, 0, 0, 0, 0, 0, NULL, ORWRITE(sd, -1, 0, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }

View File

@@ -29,53 +29,53 @@
void void
test_orwrite_beyond_eol(void) test_orwrite_beyond_eol(void)
{ {
int i; int i;
CHECK_FOR_DATALOSS; CHECK_FOR_DATALOSS;
CHECK_FOR_SBC; CHECK_FOR_SBC;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test ORWRITE 1-256 blocks one block beyond the end"); logging(LOG_VERBOSE, "Test ORWRITE 1-256 blocks one block beyond the end");
memset(scratch, 0xa6, 256 * block_size); memset(scratch, 0xa6, 256 * block_size);
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
ORWRITE(sd, num_blocks + 1 - i, ORWRITE(sd, num_blocks + 1 - i,
i * block_size, block_size, 0, 0, 0, 0, 0, scratch, i * block_size, block_size, 0, 0, 0, 0, 0, scratch,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }
logging(LOG_VERBOSE, "Test ORWRITE 1-256 blocks at LBA==2^63"); logging(LOG_VERBOSE, "Test ORWRITE 1-256 blocks at LBA==2^63");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
ORWRITE(sd, 0x8000000000000000ULL, i * block_size, block_size, ORWRITE(sd, 0x8000000000000000ULL, i * block_size, block_size,
0, 0, 0, 0, 0, scratch, 0, 0, 0, 0, 0, scratch,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }
logging(LOG_VERBOSE, "Test ORWRITE 1-256 blocks at LBA==-1"); logging(LOG_VERBOSE, "Test ORWRITE 1-256 blocks at LBA==-1");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
ORWRITE(sd, -1, i * block_size, block_size, ORWRITE(sd, -1, i * block_size, block_size,
0, 0, 0, 0, 0, scratch, 0, 0, 0, 0, 0, scratch,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }
logging(LOG_VERBOSE, "Test ORWRITE 2-256 blocks all but one block beyond the end"); logging(LOG_VERBOSE, "Test ORWRITE 2-256 blocks all but one block beyond the end");
for (i = 2; i <= 256; i++) { for (i = 2; i <= 256; i++) {
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
ORWRITE(sd, num_blocks - 1, i * block_size, block_size, ORWRITE(sd, num_blocks - 1, i * block_size, block_size,
0, 0, 0, 0, 0, scratch, 0, 0, 0, 0, 0, scratch,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }
} }

View File

@@ -29,75 +29,75 @@
void void
test_orwrite_dpofua(void) test_orwrite_dpofua(void)
{ {
int dpofua, usage_data_dpofua; int dpofua, usage_data_dpofua;
struct scsi_task *ms_task = NULL; struct scsi_task *ms_task = NULL;
struct scsi_mode_sense *ms; struct scsi_mode_sense *ms;
struct scsi_task *rso_task = NULL; struct scsi_task *rso_task = NULL;
struct scsi_report_supported_op_codes_one_command *rsoc; struct scsi_report_supported_op_codes_one_command *rsoc;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test ORWRITE DPO/FUA flags"); logging(LOG_VERBOSE, "Test ORWRITE DPO/FUA flags");
CHECK_FOR_SBC; CHECK_FOR_SBC;
CHECK_FOR_DATALOSS; CHECK_FOR_DATALOSS;
logging(LOG_VERBOSE, "Read the DPOFUA flag from mode sense data"); logging(LOG_VERBOSE, "Read the DPOFUA flag from mode sense data");
MODESENSE6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT, MODESENSE6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT,
SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255, SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "[SUCCESS] Mode sense returned status GOOD"); logging(LOG_VERBOSE, "[SUCCESS] Mode sense returned status GOOD");
ms = scsi_datain_unmarshall(ms_task); ms = scsi_datain_unmarshall(ms_task);
dpofua = ms && (ms->device_specific_parameter & 0x10); dpofua = ms && (ms->device_specific_parameter & 0x10);
scsi_free_scsi_task(ms_task); scsi_free_scsi_task(ms_task);
if (dpofua) { if (dpofua) {
logging(LOG_VERBOSE, "DPOFUA flag is set. Device should allow " logging(LOG_VERBOSE, "DPOFUA flag is set. Device should allow "
"DPO/FUA flags in CDBs"); "DPO/FUA flags in CDBs");
} else { } else {
logging(LOG_VERBOSE, "DPOFUA flag is clear. Device should fail " logging(LOG_VERBOSE, "DPOFUA flag is clear. Device should fail "
"CDBs with DPO/FUA set"); "CDBs with DPO/FUA set");
} }
logging(LOG_VERBOSE, "Test ORWRITE with DPO==1"); logging(LOG_VERBOSE, "Test ORWRITE with DPO==1");
memset(scratch, 0xa6, block_size); memset(scratch, 0xa6, block_size);
if (dpofua) { if (dpofua) {
ORWRITE(sd, 0, block_size, block_size, 0, 1, 0, 0, 0, scratch, ORWRITE(sd, 0, block_size, block_size, 0, 1, 0, 0, 0, scratch,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} else { } else {
ORWRITE(sd, 0, block_size, block_size, 0, 1, 0, 0, 0, scratch, ORWRITE(sd, 0, block_size, block_size, 0, 1, 0, 0, 0, scratch,
EXPECT_INVALID_FIELD_IN_CDB); EXPECT_INVALID_FIELD_IN_CDB);
} }
logging(LOG_VERBOSE, "Test ORWRITE with FUA==1"); logging(LOG_VERBOSE, "Test ORWRITE with FUA==1");
if (dpofua) { if (dpofua) {
ORWRITE(sd, 0, block_size, block_size, 0, 0, 1, 0, 0, scratch, ORWRITE(sd, 0, block_size, block_size, 0, 0, 1, 0, 0, scratch,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} else { } else {
ORWRITE(sd, 0, block_size, block_size, 0, 0, 1, 0, 0, scratch, ORWRITE(sd, 0, block_size, block_size, 0, 0, 1, 0, 0, scratch,
EXPECT_INVALID_FIELD_IN_CDB); EXPECT_INVALID_FIELD_IN_CDB);
} }
logging(LOG_VERBOSE, "Test ORWRITE with DPO==1 FUA==1"); logging(LOG_VERBOSE, "Test ORWRITE with DPO==1 FUA==1");
if (dpofua) { if (dpofua) {
ORWRITE(sd, 0, block_size, block_size, 0, 1, 1, 0, 0, scratch, ORWRITE(sd, 0, block_size, block_size, 0, 1, 1, 0, 0, scratch,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} else { } else {
ORWRITE(sd, 0, block_size, block_size, 0, 1, 1, 0, 0, scratch, ORWRITE(sd, 0, block_size, block_size, 0, 1, 1, 0, 0, scratch,
EXPECT_INVALID_FIELD_IN_CDB); EXPECT_INVALID_FIELD_IN_CDB);
} }
logging(LOG_VERBOSE, "Try fetching REPORT_SUPPORTED_OPCODES " logging(LOG_VERBOSE, "Try fetching REPORT_SUPPORTED_OPCODES "
"for ORWRITE"); "for ORWRITE");
REPORT_SUPPORTED_OPCODES(sd, &rso_task, REPORT_SUPPORTED_OPCODES(sd, &rso_task,
0, SCSI_REPORT_SUPPORTING_OPCODE, 0, SCSI_REPORT_SUPPORTING_OPCODE,
SCSI_OPCODE_ORWRITE, SCSI_OPCODE_ORWRITE,
0, 0,
65535, 65535,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer"); logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer");
rsoc = scsi_datain_unmarshall(rso_task); rsoc = scsi_datain_unmarshall(rso_task);
CU_ASSERT_PTR_NOT_NULL_FATAL(rsoc); CU_ASSERT_PTR_NOT_NULL_FATAL(rsoc);
usage_data_dpofua = rsoc->cdb_usage_data[1] & 0x18; usage_data_dpofua = rsoc->cdb_usage_data[1] & 0x18;
if (dpofua) { if (dpofua) {
@@ -118,5 +118,5 @@ test_orwrite_dpofua(void)
} }
} }
scsi_free_scsi_task(rso_task); scsi_free_scsi_task(rso_task);
} }

View File

@@ -30,30 +30,30 @@
void void
test_orwrite_simple(void) test_orwrite_simple(void)
{ {
int i; int i;
CHECK_FOR_DATALOSS; CHECK_FOR_DATALOSS;
CHECK_FOR_SBC; CHECK_FOR_SBC;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test ORWRITE of 1-256 blocks at the start of the LUN"); logging(LOG_VERBOSE, "Test ORWRITE of 1-256 blocks at the start of the LUN");
memset(scratch, 0xa6, 256 * block_size); memset(scratch, 0xa6, 256 * block_size);
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
ORWRITE(sd, 0, i * block_size, ORWRITE(sd, 0, i * block_size,
block_size, 0, 0, 0, 0, 0, scratch, block_size, 0, 0, 0, 0, 0, scratch,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }
logging(LOG_VERBOSE, "Test ORWRITE of 1-256 blocks at the end of the LUN"); logging(LOG_VERBOSE, "Test ORWRITE of 1-256 blocks at the end of the LUN");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
ORWRITE(sd, num_blocks - i, i * block_size, block_size, ORWRITE(sd, num_blocks - i, i * block_size, block_size,
0, 0, 0, 0, 0, scratch, 0, 0, 0, 0, 0, scratch,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }
} }

View File

@@ -31,101 +31,101 @@
void void
test_orwrite_verify(void) test_orwrite_verify(void)
{ {
int i, ret; int i, ret;
unsigned char *buf = &scratch[0]; unsigned char *buf = &scratch[0];
unsigned char *readbuf = &scratch[256 * block_size]; unsigned char *readbuf = &scratch[256 * block_size];
CHECK_FOR_DATALOSS; CHECK_FOR_DATALOSS;
CHECK_FOR_SBC; CHECK_FOR_SBC;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test ORWRITE of 1-256 blocks at the start of the LUN"); logging(LOG_VERBOSE, "Test ORWRITE of 1-256 blocks at the start of the LUN");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
logging(LOG_VERBOSE, "Write %d blocks of all-zero", i); logging(LOG_VERBOSE, "Write %d blocks of all-zero", i);
memset(buf, 0, block_size * i); memset(buf, 0, block_size * i);
ret = write10(sd, 0, i * block_size, ret = write10(sd, 0, i * block_size,
block_size, 0, 0, 0, 0, 0, buf, block_size, 0, 0, 0, 0, 0, buf,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
logging(LOG_VERBOSE, "OrWrite %d blocks with 0xa5", i); logging(LOG_VERBOSE, "OrWrite %d blocks with 0xa5", i);
memset(buf, 0xa5, block_size * i); memset(buf, 0xa5, block_size * i);
ORWRITE(sd, 0, i * block_size, ORWRITE(sd, 0, i * block_size,
block_size, 0, 0, 0, 0, 0, buf, block_size, 0, 0, 0, 0, 0, buf,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Read %d blocks back", i); logging(LOG_VERBOSE, "Read %d blocks back", i);
READ10(sd, NULL, 0, i * block_size, READ10(sd, NULL, 0, i * block_size,
block_size, 0, 0, 0, 0, 0, readbuf, block_size, 0, 0, 0, 0, 0, readbuf,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Verify that the blocks are all 0xa5"); logging(LOG_VERBOSE, "Verify that the blocks are all 0xa5");
ret = memcmp(buf, readbuf, block_size * i); ret = memcmp(buf, readbuf, block_size * i);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
logging(LOG_VERBOSE, "OrWrite %d blocks with 0x5a", i); logging(LOG_VERBOSE, "OrWrite %d blocks with 0x5a", i);
memset(buf, 0x5a, block_size * i); memset(buf, 0x5a, block_size * i);
ORWRITE(sd, 0, i * block_size, ORWRITE(sd, 0, i * block_size,
block_size, 0, 0, 0, 0, 0, buf, block_size, 0, 0, 0, 0, 0, buf,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Read %d blocks back", i); logging(LOG_VERBOSE, "Read %d blocks back", i);
READ10(sd, NULL, 0, i * block_size, READ10(sd, NULL, 0, i * block_size,
block_size, 0, 0, 0, 0, 0, readbuf, block_size, 0, 0, 0, 0, 0, readbuf,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Verify that the blocks are all 0xff"); logging(LOG_VERBOSE, "Verify that the blocks are all 0xff");
memset(buf, 0xff, block_size * i); memset(buf, 0xff, block_size * i);
ret = memcmp(buf, readbuf, block_size * i); ret = memcmp(buf, readbuf, block_size * i);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
} }
logging(LOG_VERBOSE, "Test ORWRITE of 1-256 blocks at the end of the LUN"); logging(LOG_VERBOSE, "Test ORWRITE of 1-256 blocks at the end of the LUN");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
logging(LOG_VERBOSE, "Write %d blocks of all-zero", i); logging(LOG_VERBOSE, "Write %d blocks of all-zero", i);
memset(buf, 0, block_size * i); memset(buf, 0, block_size * i);
WRITE16(sd, num_blocks - i, i * block_size, WRITE16(sd, num_blocks - i, i * block_size,
block_size, 0, 0, 0, 0, 0, buf, block_size, 0, 0, 0, 0, 0, buf,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "OrWrite %d blocks with 0xa5", i); logging(LOG_VERBOSE, "OrWrite %d blocks with 0xa5", i);
memset(buf, 0xa5, block_size * i); memset(buf, 0xa5, block_size * i);
ORWRITE(sd, num_blocks - i, i * block_size, ORWRITE(sd, num_blocks - i, i * block_size,
block_size, 0, 0, 0, 0, 0, buf, block_size, 0, 0, 0, 0, 0, buf,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Read %d blocks back", i); logging(LOG_VERBOSE, "Read %d blocks back", i);
READ16(sd, NULL, num_blocks - i, i * block_size, READ16(sd, NULL, num_blocks - i, i * block_size,
block_size, 0, 0, 0, 0, 0, readbuf, block_size, 0, 0, 0, 0, 0, readbuf,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Verify that the blocks are all 0xa5"); logging(LOG_VERBOSE, "Verify that the blocks are all 0xa5");
ret = memcmp(buf, readbuf, block_size * i); ret = memcmp(buf, readbuf, block_size * i);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
logging(LOG_VERBOSE, "OrWrite %d blocks with 0x5a", i); logging(LOG_VERBOSE, "OrWrite %d blocks with 0x5a", i);
memset(buf, 0x5a, block_size * i); memset(buf, 0x5a, block_size * i);
ORWRITE(sd, num_blocks - i, i * block_size, ORWRITE(sd, num_blocks - i, i * block_size,
block_size, 0, 0, 0, 0, 0, buf, block_size, 0, 0, 0, 0, 0, buf,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Read %d blocks back", i); logging(LOG_VERBOSE, "Read %d blocks back", i);
READ16(sd, NULL, num_blocks - i, i * block_size, READ16(sd, NULL, num_blocks - i, i * block_size,
block_size, 0, 0, 0, 0, 0, readbuf, block_size, 0, 0, 0, 0, 0, readbuf,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Verify that the blocks are all 0xff"); logging(LOG_VERBOSE, "Verify that the blocks are all 0xff");
memset(buf, 0xff, block_size * i); memset(buf, 0xff, block_size * i);
ret = memcmp(buf, readbuf, block_size * i); ret = memcmp(buf, readbuf, block_size * i);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
} }
} }

View File

@@ -30,27 +30,27 @@
void void
test_orwrite_wrprotect(void) test_orwrite_wrprotect(void)
{ {
int i; int i;
/* /*
* Try out different non-zero values for WRPROTECT. * Try out different non-zero values for WRPROTECT.
*/ */
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test ORWRITE with non-zero WRPROTECT"); logging(LOG_VERBOSE, "Test ORWRITE with non-zero WRPROTECT");
CHECK_FOR_DATALOSS; CHECK_FOR_DATALOSS;
CHECK_FOR_SBC; CHECK_FOR_SBC;
memset(scratch, 0xa6, block_size); memset(scratch, 0xa6, block_size);
if (!inq->protect || (rc16 != NULL && !rc16->prot_en)) { if (!inq->protect || (rc16 != NULL && !rc16->prot_en)) {
logging(LOG_VERBOSE, "Device does not support/use protection information. All commands should fail."); logging(LOG_VERBOSE, "Device does not support/use protection information. All commands should fail.");
for (i = 1; i < 8; i++) { for (i = 1; i < 8; i++) {
ORWRITE(sd, 0, block_size, ORWRITE(sd, 0, block_size,
block_size, i, 0, 0, 0, 0, scratch, block_size, i, 0, 0, 0, 0, scratch,
EXPECT_INVALID_FIELD_IN_CDB); EXPECT_INVALID_FIELD_IN_CDB);
} }
return; return;
} }
logging(LOG_NORMAL, "No tests for devices that support protection information yet."); logging(LOG_NORMAL, "No tests for devices that support protection information yet.");
} }

View File

@@ -27,26 +27,26 @@
void void
test_prefetch10_0blocks(void) test_prefetch10_0blocks(void)
{ {
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test PREFETCH10 0-blocks at LBA==0"); logging(LOG_VERBOSE, "Test PREFETCH10 0-blocks at LBA==0");
PREFETCH10(sd, 0, 0, 0, 0, PREFETCH10(sd, 0, 0, 0, 0,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
if (num_blocks > 0x80000000) { if (num_blocks > 0x80000000) {
CU_PASS("[SKIPPED] LUN is too big"); CU_PASS("[SKIPPED] LUN is too big");
return; return;
} }
logging(LOG_VERBOSE, "Test PREFETCH10 0-blocks one block past end-of-LUN"); logging(LOG_VERBOSE, "Test PREFETCH10 0-blocks one block past end-of-LUN");
PREFETCH10(sd, num_blocks + 1, 0, 0, 0, PREFETCH10(sd, num_blocks + 1, 0, 0, 0,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
logging(LOG_VERBOSE, "Test PREFETCH10 0-blocks at LBA==2^31"); logging(LOG_VERBOSE, "Test PREFETCH10 0-blocks at LBA==2^31");
PREFETCH10(sd, 0x80000000, 0, 0, 0, PREFETCH10(sd, 0x80000000, 0, 0, 0,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
logging(LOG_VERBOSE, "Test PREFETCH10 0-blocks at LBA==-1"); logging(LOG_VERBOSE, "Test PREFETCH10 0-blocks at LBA==-1");
PREFETCH10(sd, -1, 0, 0, 0, PREFETCH10(sd, -1, 0, 0, 0,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }

View File

@@ -28,35 +28,35 @@
void void
test_prefetch10_beyond_eol(void) test_prefetch10_beyond_eol(void)
{ {
int i; int i;
if (num_blocks >= 0x80000000) { if (num_blocks >= 0x80000000) {
CU_PASS("LUN is too big for read-beyond-eol tests with PREFETCH10. Skipping test.\n"); CU_PASS("LUN is too big for read-beyond-eol tests with PREFETCH10. Skipping test.\n");
return; return;
} }
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test PREFETCH10 1-256 blocks one block beyond the end"); logging(LOG_VERBOSE, "Test PREFETCH10 1-256 blocks one block beyond the end");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
PREFETCH10(sd, num_blocks + 1 - i, i, 0, 0, PREFETCH10(sd, num_blocks + 1 - i, i, 0, 0,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }
logging(LOG_VERBOSE, "Test PREFETCH10 1-256 blocks at LBA==2^31"); logging(LOG_VERBOSE, "Test PREFETCH10 1-256 blocks at LBA==2^31");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
PREFETCH10(sd, 0x80000000, i, 0, 0, PREFETCH10(sd, 0x80000000, i, 0, 0,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }
logging(LOG_VERBOSE, "Test PREFETCH10 1-256 blocks at LBA==-1"); logging(LOG_VERBOSE, "Test PREFETCH10 1-256 blocks at LBA==-1");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
PREFETCH10(sd, -1, i, 0, 0, PREFETCH10(sd, -1, i, 0, 0,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }
logging(LOG_VERBOSE, "Test PREFETCH10 2-256 blocks all but one block beyond the end"); logging(LOG_VERBOSE, "Test PREFETCH10 2-256 blocks all but one block beyond the end");
for (i = 2; i <= 256; i++) { for (i = 2; i <= 256; i++) {
PREFETCH10(sd, num_blocks - 1, i, 0, 0, PREFETCH10(sd, num_blocks - 1, i, 0, 0,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }
} }

View File

@@ -29,18 +29,18 @@
void void
test_prefetch10_flags(void) test_prefetch10_flags(void)
{ {
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test PREFETCH10 flags"); logging(LOG_VERBOSE, "Test PREFETCH10 flags");
logging(LOG_VERBOSE, "Test PREFETCH10 with IMMED==1"); logging(LOG_VERBOSE, "Test PREFETCH10 with IMMED==1");
PREFETCH10(sd, 0, 1, 1, 0, PREFETCH10(sd, 0, 1, 1, 0,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Test PREFETCH10 with GROUP==3"); logging(LOG_VERBOSE, "Test PREFETCH10 with GROUP==3");
PREFETCH10(sd, 0, 1, 0, 3, PREFETCH10(sd, 0, 1, 0, 3,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Test PREFETCH10 with IMMED=1 and GROUP==3"); logging(LOG_VERBOSE, "Test PREFETCH10 with IMMED=1 and GROUP==3");
PREFETCH10(sd, 0, 1, 1, 3, PREFETCH10(sd, 0, 1, 1, 3,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }

View File

@@ -29,19 +29,19 @@
void void
test_prefetch10_simple(void) test_prefetch10_simple(void)
{ {
int i; int i;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test PREFETCH10 of 1-256 blocks at the start of the LUN"); logging(LOG_VERBOSE, "Test PREFETCH10 of 1-256 blocks at the start of the LUN");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
PREFETCH10(sd, 0, i, 0, 0, PREFETCH10(sd, 0, i, 0, 0,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }
logging(LOG_VERBOSE, "Test PREFETCH10 of 1-256 blocks at the end of the LUN"); logging(LOG_VERBOSE, "Test PREFETCH10 of 1-256 blocks at the end of the LUN");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
PREFETCH10(sd, num_blocks - i, i, 0, 0, PREFETCH10(sd, num_blocks - i, i, 0, 0,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }
} }

View File

@@ -27,21 +27,21 @@
void void
test_prefetch16_0blocks(void) test_prefetch16_0blocks(void)
{ {
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test PREFETCH16 0-blocks at LBA==0"); logging(LOG_VERBOSE, "Test PREFETCH16 0-blocks at LBA==0");
PREFETCH16(sd, 0, 0, 0, 0, PREFETCH16(sd, 0, 0, 0, 0,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Test PREFETCH16 0-blocks one block past end-of-LUN"); logging(LOG_VERBOSE, "Test PREFETCH16 0-blocks one block past end-of-LUN");
PREFETCH16(sd, num_blocks + 1, 0, 0, 0, PREFETCH16(sd, num_blocks + 1, 0, 0, 0,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
logging(LOG_VERBOSE, "Test PREFETCH16 0-blocks at LBA==2^63"); logging(LOG_VERBOSE, "Test PREFETCH16 0-blocks at LBA==2^63");
PREFETCH16(sd, 0x8000000000000000ULL, 0, 0, 0, PREFETCH16(sd, 0x8000000000000000ULL, 0, 0, 0,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
logging(LOG_VERBOSE, "Test PREFETCH16 0-blocks at LBA==-1"); logging(LOG_VERBOSE, "Test PREFETCH16 0-blocks at LBA==-1");
PREFETCH16(sd, -1, 0, 0, 0, PREFETCH16(sd, -1, 0, 0, 0,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }

View File

@@ -28,30 +28,30 @@
void void
test_prefetch16_beyond_eol(void) test_prefetch16_beyond_eol(void)
{ {
int i; int i;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test PREFETCH16 1-256 blocks one block beyond the end"); logging(LOG_VERBOSE, "Test PREFETCH16 1-256 blocks one block beyond the end");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
PREFETCH16(sd, num_blocks + 1 - i, i, 0, 0, PREFETCH16(sd, num_blocks + 1 - i, i, 0, 0,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }
logging(LOG_VERBOSE, "Test PREFETCH16 1-256 blocks at LBA==2^63"); logging(LOG_VERBOSE, "Test PREFETCH16 1-256 blocks at LBA==2^63");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
PREFETCH16(sd, 0x8000000000000000ULL, i, 0, 0, PREFETCH16(sd, 0x8000000000000000ULL, i, 0, 0,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }
logging(LOG_VERBOSE, "Test PREFETCH16 1-256 blocks at LBA==-1"); logging(LOG_VERBOSE, "Test PREFETCH16 1-256 blocks at LBA==-1");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
PREFETCH16(sd, -1, i, 0, 0, PREFETCH16(sd, -1, i, 0, 0,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }
logging(LOG_VERBOSE, "Test PREFETCH16 2-256 blocks all but one block beyond the end"); logging(LOG_VERBOSE, "Test PREFETCH16 2-256 blocks all but one block beyond the end");
for (i = 2; i <= 256; i++) { for (i = 2; i <= 256; i++) {
PREFETCH16(sd, num_blocks - 1, i, 0, 0, PREFETCH16(sd, num_blocks - 1, i, 0, 0,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }
} }

View File

@@ -29,18 +29,18 @@
void void
test_prefetch16_flags(void) test_prefetch16_flags(void)
{ {
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test PREFETCH16 flags"); logging(LOG_VERBOSE, "Test PREFETCH16 flags");
logging(LOG_VERBOSE, "Test PREFETCH16 with IMMED==1"); logging(LOG_VERBOSE, "Test PREFETCH16 with IMMED==1");
PREFETCH16(sd, 0, 1, 1, 0, PREFETCH16(sd, 0, 1, 1, 0,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Test PREFETCH16 with GROUP==3"); logging(LOG_VERBOSE, "Test PREFETCH16 with GROUP==3");
PREFETCH16(sd, 0, 1, 0, 3, PREFETCH16(sd, 0, 1, 0, 3,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Test PREFETCH16 with IMMED=1 and GROUP==3"); logging(LOG_VERBOSE, "Test PREFETCH16 with IMMED=1 and GROUP==3");
PREFETCH16(sd, 0, 1, 1, 3, PREFETCH16(sd, 0, 1, 1, 3,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }

View File

@@ -29,19 +29,19 @@
void void
test_prefetch16_simple(void) test_prefetch16_simple(void)
{ {
int i; int i;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test PREFETCH16 of 1-256 blocks at the start of the LUN"); logging(LOG_VERBOSE, "Test PREFETCH16 of 1-256 blocks at the start of the LUN");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
PREFETCH16(sd, 0, i, 0, 0, PREFETCH16(sd, 0, i, 0, 0,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }
logging(LOG_VERBOSE, "Test PREFETCH16 of 1-256 blocks at the end of the LUN"); logging(LOG_VERBOSE, "Test PREFETCH16 of 1-256 blocks at the end of the LUN");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
PREFETCH16(sd, num_blocks - i, i, 0, 0, PREFETCH16(sd, num_blocks - i, i, 0, 0,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }
} }

View File

@@ -29,52 +29,52 @@
void void
test_preventallow_2_itnexuses(void) test_preventallow_2_itnexuses(void)
{ {
int ret; int ret;
struct scsi_device *sd2; struct scsi_device *sd2;
CHECK_FOR_SBC; CHECK_FOR_SBC;
CHECK_FOR_REMOVABLE; CHECK_FOR_REMOVABLE;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test that PREVENT MEDIUM REMOVAL are seen on other nexuses as well"); logging(LOG_VERBOSE, "Test that PREVENT MEDIUM REMOVAL are seen on other nexuses as well");
if (sd->iscsi_ctx == NULL) { if (sd->iscsi_ctx == NULL) {
const char *err = "[SKIPPED] This PREVENTALLOW test is " const char *err = "[SKIPPED] This PREVENTALLOW test is "
"only supported for iSCSI backends"; "only supported for iSCSI backends";
logging(LOG_NORMAL, "%s", err); logging(LOG_NORMAL, "%s", err);
CU_PASS(err); CU_PASS(err);
return; return;
} }
logging(LOG_VERBOSE, "Set the PREVENT flag"); logging(LOG_VERBOSE, "Set the PREVENT flag");
PREVENTALLOW(sd, 1); PREVENTALLOW(sd, 1);
logging(LOG_VERBOSE, "Try to eject the medium"); logging(LOG_VERBOSE, "Try to eject the medium");
STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0, STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0,
EXPECT_REMOVAL_PREVENTED); EXPECT_REMOVAL_PREVENTED);
logging(LOG_VERBOSE, "Verify we can still access the media."); logging(LOG_VERBOSE, "Verify we can still access the media.");
TESTUNITREADY(sd, TESTUNITREADY(sd,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Create a second connection to the target"); logging(LOG_VERBOSE, "Create a second connection to the target");
ret = mpath_sd2_get_or_clone(sd, &sd2); ret = mpath_sd2_get_or_clone(sd, &sd2);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
if (ret < 0) if (ret < 0)
return; return;
logging(LOG_VERBOSE, "Try to eject the medium on the second connection"); logging(LOG_VERBOSE, "Try to eject the medium on the second connection");
STARTSTOPUNIT(sd2, 0, 0, 0, 0, 1, 0, STARTSTOPUNIT(sd2, 0, 0, 0, 0, 1, 0,
EXPECT_REMOVAL_PREVENTED); EXPECT_REMOVAL_PREVENTED);
logging(LOG_VERBOSE, "Logout the second connection from target"); logging(LOG_VERBOSE, "Logout the second connection from target");
mpath_sd2_put(sd2); mpath_sd2_put(sd2);
logging(LOG_VERBOSE, "Clear PREVENT and load medium in case target failed"); logging(LOG_VERBOSE, "Clear PREVENT and load medium in case target failed");
logging(LOG_VERBOSE, "Test we can clear PREVENT flag"); logging(LOG_VERBOSE, "Test we can clear PREVENT flag");
PREVENTALLOW(sd, 0); PREVENTALLOW(sd, 0);
logging(LOG_VERBOSE, "Load the medium"); logging(LOG_VERBOSE, "Load the medium");
STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 1, STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 1,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }

View File

@@ -30,56 +30,56 @@ test_preventallow_cold_reset(void)
{ {
int ret; int ret;
CHECK_FOR_SBC; CHECK_FOR_SBC;
CHECK_FOR_REMOVABLE; CHECK_FOR_REMOVABLE;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test that Target Warm Reset clears PREVENT MEDIUM REMOVAL"); logging(LOG_VERBOSE, "Test that Target Warm Reset clears PREVENT MEDIUM REMOVAL");
if (sd->iscsi_ctx == NULL) { if (sd->iscsi_ctx == NULL) {
const char *err = "[SKIPPED] This PREVENTALLOW test is " const char *err = "[SKIPPED] This PREVENTALLOW test is "
"only supported for iSCSI backends"; "only supported for iSCSI backends";
logging(LOG_NORMAL, "%s", err); logging(LOG_NORMAL, "%s", err);
CU_PASS(err); CU_PASS(err);
return; return;
} }
logging(LOG_VERBOSE, "Set the PREVENT flag"); logging(LOG_VERBOSE, "Set the PREVENT flag");
PREVENTALLOW(sd, 1); PREVENTALLOW(sd, 1);
logging(LOG_VERBOSE, "Try to eject the medium"); logging(LOG_VERBOSE, "Try to eject the medium");
STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0, STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0,
EXPECT_REMOVAL_PREVENTED); EXPECT_REMOVAL_PREVENTED);
logging(LOG_VERBOSE, "Verify we can still access the media."); logging(LOG_VERBOSE, "Verify we can still access the media.");
TESTUNITREADY(sd, TESTUNITREADY(sd,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Perform cold reset on target"); logging(LOG_VERBOSE, "Perform cold reset on target");
ret = iscsi_task_mgmt_target_cold_reset_sync(sd->iscsi_ctx); ret = iscsi_task_mgmt_target_cold_reset_sync(sd->iscsi_ctx);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
logging(LOG_VERBOSE, "Wait until all unit attentions clear"); logging(LOG_VERBOSE, "Wait until all unit attentions clear");
while (testunitready(sd, EXPECT_STATUS_GOOD) != 0) while (testunitready(sd, EXPECT_STATUS_GOOD) != 0)
; ;
logging(LOG_VERBOSE, "Try to eject the medium"); logging(LOG_VERBOSE, "Try to eject the medium");
STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0, STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Verify we can not access the media."); logging(LOG_VERBOSE, "Verify we can not access the media.");
TESTUNITREADY(sd, TESTUNITREADY(sd,
EXPECT_NO_MEDIUM); EXPECT_NO_MEDIUM);
logging(LOG_VERBOSE, "Load the medium"); logging(LOG_VERBOSE, "Load the medium");
STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0, STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Clear PREVENT and load medium in case target failed"); logging(LOG_VERBOSE, "Clear PREVENT and load medium in case target failed");
logging(LOG_VERBOSE, "Test we can clear PREVENT flag"); logging(LOG_VERBOSE, "Test we can clear PREVENT flag");
PREVENTALLOW(sd, 0); PREVENTALLOW(sd, 0);
logging(LOG_VERBOSE, "Load the medium"); logging(LOG_VERBOSE, "Load the medium");
STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 1, STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 1,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }

View File

@@ -28,45 +28,45 @@
void void
test_preventallow_eject(void) test_preventallow_eject(void)
{ {
CHECK_FOR_SBC; CHECK_FOR_SBC;
CHECK_FOR_REMOVABLE; CHECK_FOR_REMOVABLE;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test that we can not eject medium when PREVENT is active"); logging(LOG_VERBOSE, "Test that we can not eject medium when PREVENT is active");
logging(LOG_VERBOSE, "Set the PREVENT flag"); logging(LOG_VERBOSE, "Set the PREVENT flag");
PREVENTALLOW(sd, 1); PREVENTALLOW(sd, 1);
logging(LOG_VERBOSE, "Try to eject the medium"); logging(LOG_VERBOSE, "Try to eject the medium");
STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0, STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0,
EXPECT_REMOVAL_PREVENTED); EXPECT_REMOVAL_PREVENTED);
logging(LOG_VERBOSE, "Verify we can still access the media."); logging(LOG_VERBOSE, "Verify we can still access the media.");
TESTUNITREADY(sd, TESTUNITREADY(sd,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Test we can clear PREVENT flag"); logging(LOG_VERBOSE, "Test we can clear PREVENT flag");
PREVENTALLOW(sd, 0); PREVENTALLOW(sd, 0);
logging(LOG_VERBOSE, "Try to eject the medium"); logging(LOG_VERBOSE, "Try to eject the medium");
STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0, STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Verify we can not access the media."); logging(LOG_VERBOSE, "Verify we can not access the media.");
TESTUNITREADY(sd, TESTUNITREADY(sd,
EXPECT_NO_MEDIUM); EXPECT_NO_MEDIUM);
logging(LOG_VERBOSE, "Set the PREVENT flag"); logging(LOG_VERBOSE, "Set the PREVENT flag");
PREVENTALLOW(sd, 1); PREVENTALLOW(sd, 1);
logging(LOG_VERBOSE, "Try to load the medium"); logging(LOG_VERBOSE, "Try to load the medium");
STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 1, STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 1,
EXPECT_REMOVAL_PREVENTED); EXPECT_REMOVAL_PREVENTED);
logging(LOG_VERBOSE, "Clear PREVENT flag"); logging(LOG_VERBOSE, "Clear PREVENT flag");
PREVENTALLOW(sd, 0); PREVENTALLOW(sd, 0);
logging(LOG_VERBOSE, "Load the medium again"); logging(LOG_VERBOSE, "Load the medium again");
STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 1, STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 1,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }

View File

@@ -28,58 +28,58 @@
void void
test_preventallow_itnexus_loss(void) test_preventallow_itnexus_loss(void)
{ {
CHECK_FOR_SBC; CHECK_FOR_SBC;
CHECK_FOR_REMOVABLE; CHECK_FOR_REMOVABLE;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test that IT-Nexus loss clears PREVENT MEDIUM REMOVAL"); logging(LOG_VERBOSE, "Test that IT-Nexus loss clears PREVENT MEDIUM REMOVAL");
if (sd->iscsi_ctx == NULL) { if (sd->iscsi_ctx == NULL) {
const char *err = "[SKIPPED] This PREVENTALLOW test is " const char *err = "[SKIPPED] This PREVENTALLOW test is "
"only supported for iSCSI backends"; "only supported for iSCSI backends";
logging(LOG_NORMAL, "%s", err); logging(LOG_NORMAL, "%s", err);
CU_PASS(err); CU_PASS(err);
return; return;
} }
logging(LOG_VERBOSE, "Set the PREVENT flag"); logging(LOG_VERBOSE, "Set the PREVENT flag");
PREVENTALLOW(sd, 1); PREVENTALLOW(sd, 1);
logging(LOG_VERBOSE, "Try to eject the medium"); logging(LOG_VERBOSE, "Try to eject the medium");
STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0, STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0,
EXPECT_REMOVAL_PREVENTED); EXPECT_REMOVAL_PREVENTED);
logging(LOG_VERBOSE, "Verify we can still access the media."); logging(LOG_VERBOSE, "Verify we can still access the media.");
TESTUNITREADY(sd, TESTUNITREADY(sd,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Disconnect from the target."); logging(LOG_VERBOSE, "Disconnect from the target.");
iscsi_destroy_context(sd->iscsi_ctx); iscsi_destroy_context(sd->iscsi_ctx);
logging(LOG_VERBOSE, "Reconnect to target"); logging(LOG_VERBOSE, "Reconnect to target");
sd->iscsi_ctx = iscsi_context_login(initiatorname1, sd->iscsi_url, &sd->iscsi_lun); sd->iscsi_ctx = iscsi_context_login(initiatorname1, sd->iscsi_url, &sd->iscsi_lun);
if (sd->iscsi_ctx == NULL) { if (sd->iscsi_ctx == NULL) {
logging(LOG_VERBOSE, "Failed to login to target"); logging(LOG_VERBOSE, "Failed to login to target");
return; return;
} }
logging(LOG_VERBOSE, "Try to eject the medium"); logging(LOG_VERBOSE, "Try to eject the medium");
STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0, STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Verify we can not access the media."); logging(LOG_VERBOSE, "Verify we can not access the media.");
TESTUNITREADY(sd, TESTUNITREADY(sd,
EXPECT_NO_MEDIUM); EXPECT_NO_MEDIUM);
logging(LOG_VERBOSE, "Load the medium"); logging(LOG_VERBOSE, "Load the medium");
STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0, STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Clear PREVENT and load medium in case target failed"); logging(LOG_VERBOSE, "Clear PREVENT and load medium in case target failed");
logging(LOG_VERBOSE, "Test we can clear PREVENT flag"); logging(LOG_VERBOSE, "Test we can clear PREVENT flag");
PREVENTALLOW(sd, 0); PREVENTALLOW(sd, 0);
logging(LOG_VERBOSE, "Load the medium"); logging(LOG_VERBOSE, "Load the medium");
STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 1, STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 1,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }

View File

@@ -28,59 +28,59 @@
void void
test_preventallow_logout(void) test_preventallow_logout(void)
{ {
CHECK_FOR_SBC; CHECK_FOR_SBC;
CHECK_FOR_REMOVABLE; CHECK_FOR_REMOVABLE;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test that Logout loss clears PREVENT MEDIUM REMOVAL"); logging(LOG_VERBOSE, "Test that Logout loss clears PREVENT MEDIUM REMOVAL");
if (sd->iscsi_ctx == NULL) { if (sd->iscsi_ctx == NULL) {
const char *err = "[SKIPPED] This PREVENTALLOW test is " const char *err = "[SKIPPED] This PREVENTALLOW test is "
"only supported for iSCSI backends"; "only supported for iSCSI backends";
logging(LOG_NORMAL, "%s", err); logging(LOG_NORMAL, "%s", err);
CU_PASS(err); CU_PASS(err);
return; return;
} }
logging(LOG_VERBOSE, "Set the PREVENT flag"); logging(LOG_VERBOSE, "Set the PREVENT flag");
PREVENTALLOW(sd, 1); PREVENTALLOW(sd, 1);
logging(LOG_VERBOSE, "Try to eject the medium"); logging(LOG_VERBOSE, "Try to eject the medium");
STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0, STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0,
EXPECT_REMOVAL_PREVENTED); EXPECT_REMOVAL_PREVENTED);
logging(LOG_VERBOSE, "Verify we can still access the media."); logging(LOG_VERBOSE, "Verify we can still access the media.");
TESTUNITREADY(sd, TESTUNITREADY(sd,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Logout from target"); logging(LOG_VERBOSE, "Logout from target");
iscsi_logout_sync(sd->iscsi_ctx); iscsi_logout_sync(sd->iscsi_ctx);
iscsi_destroy_context(sd->iscsi_ctx); iscsi_destroy_context(sd->iscsi_ctx);
logging(LOG_VERBOSE, "Relogin to target"); logging(LOG_VERBOSE, "Relogin to target");
sd->iscsi_ctx = iscsi_context_login(initiatorname1, sd->iscsi_url, &sd->iscsi_lun); sd->iscsi_ctx = iscsi_context_login(initiatorname1, sd->iscsi_url, &sd->iscsi_lun);
if (sd->iscsi_ctx == NULL) { if (sd->iscsi_ctx == NULL) {
logging(LOG_VERBOSE, "Failed to login to target"); logging(LOG_VERBOSE, "Failed to login to target");
return; return;
} }
logging(LOG_VERBOSE, "Try to eject the medium"); logging(LOG_VERBOSE, "Try to eject the medium");
STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0, STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Verify we can not access the media."); logging(LOG_VERBOSE, "Verify we can not access the media.");
TESTUNITREADY(sd, TESTUNITREADY(sd,
EXPECT_NO_MEDIUM); EXPECT_NO_MEDIUM);
logging(LOG_VERBOSE, "Load the medium"); logging(LOG_VERBOSE, "Load the medium");
STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0, STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Clear PREVENT and load medium in case target failed"); logging(LOG_VERBOSE, "Clear PREVENT and load medium in case target failed");
logging(LOG_VERBOSE, "Test we can clear PREVENT flag"); logging(LOG_VERBOSE, "Test we can clear PREVENT flag");
PREVENTALLOW(sd, 0); PREVENTALLOW(sd, 0);
logging(LOG_VERBOSE, "Load the medium"); logging(LOG_VERBOSE, "Load the medium");
STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 1, STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 1,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }

View File

@@ -28,58 +28,58 @@
void void
test_preventallow_lun_reset(void) test_preventallow_lun_reset(void)
{ {
int ret; int ret;
CHECK_FOR_SBC; CHECK_FOR_SBC;
CHECK_FOR_REMOVABLE; CHECK_FOR_REMOVABLE;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test that Target Warm Reset clears PREVENT MEDIUM REMOVAL"); logging(LOG_VERBOSE, "Test that Target Warm Reset clears PREVENT MEDIUM REMOVAL");
if (sd->iscsi_ctx == NULL) { if (sd->iscsi_ctx == NULL) {
const char *err = "[SKIPPED] This PREVENTALLOW test is " const char *err = "[SKIPPED] This PREVENTALLOW test is "
"only supported for iSCSI backends"; "only supported for iSCSI backends";
logging(LOG_NORMAL, "%s", err); logging(LOG_NORMAL, "%s", err);
CU_PASS(err); CU_PASS(err);
return; return;
} }
logging(LOG_VERBOSE, "Set the PREVENT flag"); logging(LOG_VERBOSE, "Set the PREVENT flag");
PREVENTALLOW(sd, 1); PREVENTALLOW(sd, 1);
logging(LOG_VERBOSE, "Try to eject the medium"); logging(LOG_VERBOSE, "Try to eject the medium");
STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0, STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0,
EXPECT_REMOVAL_PREVENTED); EXPECT_REMOVAL_PREVENTED);
logging(LOG_VERBOSE, "Verify we can still access the media."); logging(LOG_VERBOSE, "Verify we can still access the media.");
TESTUNITREADY(sd, TESTUNITREADY(sd,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Perform LUN reset on target"); logging(LOG_VERBOSE, "Perform LUN reset on target");
ret = iscsi_task_mgmt_lun_reset_sync(sd->iscsi_ctx, sd->iscsi_lun); ret = iscsi_task_mgmt_lun_reset_sync(sd->iscsi_ctx, sd->iscsi_lun);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
logging(LOG_VERBOSE, "Wait until all unit attentions clear"); logging(LOG_VERBOSE, "Wait until all unit attentions clear");
while (testunitready(sd, EXPECT_STATUS_GOOD) != 0) while (testunitready(sd, EXPECT_STATUS_GOOD) != 0)
; ;
logging(LOG_VERBOSE, "Try to eject the medium"); logging(LOG_VERBOSE, "Try to eject the medium");
STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0, STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Verify we can not access the media."); logging(LOG_VERBOSE, "Verify we can not access the media.");
TESTUNITREADY(sd, TESTUNITREADY(sd,
EXPECT_NO_MEDIUM); EXPECT_NO_MEDIUM);
logging(LOG_VERBOSE, "Load the medium"); logging(LOG_VERBOSE, "Load the medium");
STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0, STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Clear PREVENT and load medium in case target failed"); logging(LOG_VERBOSE, "Clear PREVENT and load medium in case target failed");
logging(LOG_VERBOSE, "Test we can clear PREVENT flag"); logging(LOG_VERBOSE, "Test we can clear PREVENT flag");
PREVENTALLOW(sd, 0); PREVENTALLOW(sd, 0);
logging(LOG_VERBOSE, "Load the medium"); logging(LOG_VERBOSE, "Load the medium");
STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 1, STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 1,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }

View File

@@ -28,15 +28,15 @@
void void
test_preventallow_simple(void) test_preventallow_simple(void)
{ {
CHECK_FOR_SBC; CHECK_FOR_SBC;
CHECK_FOR_REMOVABLE; CHECK_FOR_REMOVABLE;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test PREVENTALLOW basics"); logging(LOG_VERBOSE, "Test PREVENTALLOW basics");
logging(LOG_VERBOSE, "Test we can set PREVENT flag"); logging(LOG_VERBOSE, "Test we can set PREVENT flag");
PREVENTALLOW(sd, 1); PREVENTALLOW(sd, 1);
logging(LOG_VERBOSE, "Test we can clear PREVENT flag"); logging(LOG_VERBOSE, "Test we can clear PREVENT flag");
PREVENTALLOW(sd, 0); PREVENTALLOW(sd, 0);
} }

View File

@@ -28,58 +28,58 @@
void void
test_preventallow_warm_reset(void) test_preventallow_warm_reset(void)
{ {
int ret; int ret;
CHECK_FOR_SBC; CHECK_FOR_SBC;
CHECK_FOR_REMOVABLE; CHECK_FOR_REMOVABLE;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test that Target Warm Reset clears PREVENT MEDIUM REMOVAL"); logging(LOG_VERBOSE, "Test that Target Warm Reset clears PREVENT MEDIUM REMOVAL");
if (sd->iscsi_ctx == NULL) { if (sd->iscsi_ctx == NULL) {
const char *err = "[SKIPPED] This PREVENTALLOW test is " const char *err = "[SKIPPED] This PREVENTALLOW test is "
"only supported for iSCSI backends"; "only supported for iSCSI backends";
logging(LOG_NORMAL, "%s", err); logging(LOG_NORMAL, "%s", err);
CU_PASS(err); CU_PASS(err);
return; return;
} }
logging(LOG_VERBOSE, "Set the PREVENT flag"); logging(LOG_VERBOSE, "Set the PREVENT flag");
PREVENTALLOW(sd, 1); PREVENTALLOW(sd, 1);
logging(LOG_VERBOSE, "Try to eject the medium"); logging(LOG_VERBOSE, "Try to eject the medium");
STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0, STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0,
EXPECT_REMOVAL_PREVENTED); EXPECT_REMOVAL_PREVENTED);
logging(LOG_VERBOSE, "Verify we can still access the media."); logging(LOG_VERBOSE, "Verify we can still access the media.");
TESTUNITREADY(sd, TESTUNITREADY(sd,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Perform warm reset on target"); logging(LOG_VERBOSE, "Perform warm reset on target");
ret = iscsi_task_mgmt_target_warm_reset_sync(sd->iscsi_ctx); ret = iscsi_task_mgmt_target_warm_reset_sync(sd->iscsi_ctx);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
logging(LOG_VERBOSE, "Wait until all unit attentions clear"); logging(LOG_VERBOSE, "Wait until all unit attentions clear");
while (testunitready(sd, EXPECT_STATUS_GOOD) != 0) while (testunitready(sd, EXPECT_STATUS_GOOD) != 0)
; ;
logging(LOG_VERBOSE, "Try to eject the medium"); logging(LOG_VERBOSE, "Try to eject the medium");
STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0, STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Verify we can not access the media."); logging(LOG_VERBOSE, "Verify we can not access the media.");
TESTUNITREADY(sd, TESTUNITREADY(sd,
EXPECT_NO_MEDIUM); EXPECT_NO_MEDIUM);
logging(LOG_VERBOSE, "Load the medium"); logging(LOG_VERBOSE, "Load the medium");
STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0, STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Clear PREVENT and load medium in case target failed"); logging(LOG_VERBOSE, "Clear PREVENT and load medium in case target failed");
logging(LOG_VERBOSE, "Test we can clear PREVENT flag"); logging(LOG_VERBOSE, "Test we can clear PREVENT flag");
PREVENTALLOW(sd, 0); PREVENTALLOW(sd, 0);
logging(LOG_VERBOSE, "Load the medium"); logging(LOG_VERBOSE, "Load the medium");
STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 1, STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 1,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }

View File

@@ -30,34 +30,34 @@
void void
test_prin_read_keys_simple(void) test_prin_read_keys_simple(void)
{ {
int ret = 0; int ret = 0;
int al; int al;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test Persistent Reserve IN READ_KEYS works."); logging(LOG_VERBOSE, "Test Persistent Reserve IN READ_KEYS works.");
ret = prin_read_keys(sd, &task, NULL); ret = prin_read_keys(sd, &task, NULL);
if (ret == -2) { if (ret == -2) {
logging(LOG_NORMAL, "[SKIPPED] PERSISTEN RESERVE IN is not implemented."); logging(LOG_NORMAL, "[SKIPPED] PERSISTEN RESERVE IN is not implemented.");
CU_PASS("PERSISTENT RESERVE IN is not implemented."); CU_PASS("PERSISTENT RESERVE IN is not implemented.");
return; return;
} }
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
logging(LOG_VERBOSE, "Test DATA-IN is at least 8 bytes."); logging(LOG_VERBOSE, "Test DATA-IN is at least 8 bytes.");
if (task->datain.size < 8) { if (task->datain.size < 8) {
logging(LOG_NORMAL, logging(LOG_NORMAL,
"[FAILED] DATA-IN returned less than 8 bytes"); "[FAILED] DATA-IN returned less than 8 bytes");
return; return;
} }
logging(LOG_VERBOSE, "Test ADDITIONAL_LENGTH matches DATA_IN size."); logging(LOG_VERBOSE, "Test ADDITIONAL_LENGTH matches DATA_IN size.");
al = scsi_get_uint32(&task->datain.data[4]); al = scsi_get_uint32(&task->datain.data[4]);
if (al != task->datain.size - 8) { if (al != task->datain.size - 8) {
logging(LOG_NORMAL, logging(LOG_NORMAL,
"[FAILED] ADDITIONAL_LENGTH was %d bytes but %d was expected.", "[FAILED] ADDITIONAL_LENGTH was %d bytes but %d was expected.",
al, task->datain.size - 8); al, task->datain.size - 8);
return; return;
} }
} }

View File

@@ -27,89 +27,89 @@
#include "iscsi-test-cu.h" #include "iscsi-test-cu.h"
static struct test_prin_report_caps_types { static struct test_prin_report_caps_types {
enum scsi_persistent_reservation_type_mask mask; enum scsi_persistent_reservation_type_mask mask;
enum scsi_persistent_out_type op; enum scsi_persistent_out_type op;
} report_caps_types_array[] = { } report_caps_types_array[] = {
{ SCSI_PR_TYPE_MASK_WR_EX_AR, { SCSI_PR_TYPE_MASK_WR_EX_AR,
SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE_ALL_REGISTRANTS }, SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE_ALL_REGISTRANTS },
{ SCSI_PR_TYPE_MASK_EX_AC_RO, { SCSI_PR_TYPE_MASK_EX_AC_RO,
SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS_REGISTRANTS_ONLY }, SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS_REGISTRANTS_ONLY },
{ SCSI_PR_TYPE_MASK_WR_EX_RO, { SCSI_PR_TYPE_MASK_WR_EX_RO,
SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE_REGISTRANTS_ONLY }, SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE_REGISTRANTS_ONLY },
{ SCSI_PR_TYPE_MASK_EX_AC, { SCSI_PR_TYPE_MASK_EX_AC,
SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS }, SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS },
{ SCSI_PR_TYPE_MASK_WR_EX, { SCSI_PR_TYPE_MASK_WR_EX,
SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE }, SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE },
{ SCSI_PR_TYPE_MASK_EX_AC_AR, { SCSI_PR_TYPE_MASK_EX_AC_AR,
SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS_ALL_REGISTRANTS }, SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS_ALL_REGISTRANTS },
{ 0, 0 } { 0, 0 }
}; };
void void
test_prin_report_caps_simple(void) test_prin_report_caps_simple(void)
{ {
int ret = 0; int ret = 0;
const unsigned long long key = rand_key(); const unsigned long long key = rand_key();
struct scsi_task *tsk; struct scsi_task *tsk;
struct scsi_persistent_reserve_in_report_capabilities *rcaps; struct scsi_persistent_reserve_in_report_capabilities *rcaps;
struct test_prin_report_caps_types *type; struct test_prin_report_caps_types *type;
CHECK_FOR_DATALOSS; CHECK_FOR_DATALOSS;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, logging(LOG_VERBOSE,
"Test Persistent Reserve In REPORT CAPABILITIES works."); "Test Persistent Reserve In REPORT CAPABILITIES works.");
/* register our reservation key with the target */ /* register our reservation key with the target */
ret = prout_register_and_ignore(sd, key); ret = prout_register_and_ignore(sd, key);
if (ret == -2) { if (ret == -2) {
logging(LOG_NORMAL, "[SKIPPED] PERSISTENT RESERVE OUT is not implemented."); logging(LOG_NORMAL, "[SKIPPED] PERSISTENT RESERVE OUT is not implemented.");
CU_PASS("PERSISTENT RESERVE OUT is not implemented."); CU_PASS("PERSISTENT RESERVE OUT is not implemented.");
return; return;
} }
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
ret = prin_report_caps(sd, &tsk, &rcaps); ret = prin_report_caps(sd, &tsk, &rcaps);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
logging(LOG_VERBOSE, logging(LOG_VERBOSE,
"Checking PERSISTENT RESERVE IN REPORT CAPABILITIES fields."); "Checking PERSISTENT RESERVE IN REPORT CAPABILITIES fields.");
CU_ASSERT_EQUAL(rcaps->length, 8); CU_ASSERT_EQUAL(rcaps->length, 8);
CU_ASSERT_TRUE(rcaps->allow_commands <= 5); CU_ASSERT_TRUE(rcaps->allow_commands <= 5);
CU_ASSERT_EQUAL(rcaps->persistent_reservation_type_mask CU_ASSERT_EQUAL(rcaps->persistent_reservation_type_mask
& ~SCSI_PR_TYPE_MASK_ALL, 0); & ~SCSI_PR_TYPE_MASK_ALL, 0);
for (type = &report_caps_types_array[0]; type->mask != 0; type++) { for (type = &report_caps_types_array[0]; type->mask != 0; type++) {
if (!(rcaps->persistent_reservation_type_mask & type->mask)) { if (!(rcaps->persistent_reservation_type_mask & type->mask)) {
logging(LOG_NORMAL, logging(LOG_NORMAL,
"PERSISTENT RESERVE op 0x%x not supported", "PERSISTENT RESERVE op 0x%x not supported",
type->op); type->op);
continue; continue;
} }
logging(LOG_VERBOSE, logging(LOG_VERBOSE,
"PERSISTENT RESERVE OUT op 0x%x supported, testing", "PERSISTENT RESERVE OUT op 0x%x supported, testing",
type->op); type->op);
/* reserve the target */ /* reserve the target */
ret = prout_reserve(sd, key, type->op); ret = prout_reserve(sd, key, type->op);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
/* verify target reservation */ /* verify target reservation */
ret = prin_verify_reserved_as(sd, ret = prin_verify_reserved_as(sd,
pr_type_is_all_registrants(type->op) ? 0 : key, pr_type_is_all_registrants(type->op) ? 0 : key,
type->op); type->op);
CU_ASSERT_EQUAL(0, ret); CU_ASSERT_EQUAL(0, ret);
/* release the target */ /* release the target */
ret = prout_release(sd, key, type->op); ret = prout_release(sd, key, type->op);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
} }
scsi_free_scsi_task(tsk); scsi_free_scsi_task(tsk);
rcaps = NULL; /* freed with tsk */ rcaps = NULL; /* freed with tsk */
/* drop registration */ /* drop registration */
ret = prout_register_key(sd, 0, key); ret = prout_register_key(sd, 0, key);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
} }

View File

@@ -30,31 +30,31 @@
void void
test_prin_serviceaction_range(void) test_prin_serviceaction_range(void)
{ {
int ret = 0; int ret = 0;
int i; int i;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test Persistent Reserve IN Serviceaction range."); logging(LOG_VERBOSE, "Test Persistent Reserve IN Serviceaction range.");
/* verify PRIN/READ_KEYS works -- XXX redundant -- remove this? */ /* verify PRIN/READ_KEYS works -- XXX redundant -- remove this? */
ret = prin_read_keys(sd, &task, NULL); ret = prin_read_keys(sd, &task, NULL);
if (ret == -2) { if (ret == -2) {
logging(LOG_NORMAL, "[SKIPPED] PERSISTEN RESERVE IN is not implemented."); logging(LOG_NORMAL, "[SKIPPED] PERSISTEN RESERVE IN is not implemented.");
CU_PASS("PERSISTENT RESERVE IN is not implemented."); CU_PASS("PERSISTENT RESERVE IN is not implemented.");
return; return;
} }
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
/* verify that PRIN/SA={0,1,2,3} works ... */ /* verify that PRIN/SA={0,1,2,3} works ... */
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
ret = prin_task(sd, i, 1); ret = prin_task(sd, i, 1);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
} }
/* verify that PRIN/SA={4..0x20} fails ... */ /* verify that PRIN/SA={4..0x20} fails ... */
for (i = 4; i < 0x20; i++) { for (i = 4; i < 0x20; i++) {
ret = prin_task(sd, i, 0); ret = prin_task(sd, i, 0);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
} }
} }

View File

@@ -29,60 +29,60 @@
void void
test_prout_clear_simple(void) test_prout_clear_simple(void)
{ {
int ret = 0; int ret = 0;
uint32_t old_gen; uint32_t old_gen;
const unsigned long long key = rand_key(); const unsigned long long key = rand_key();
struct scsi_task *tsk; struct scsi_task *tsk;
struct scsi_persistent_reserve_in_read_keys *rk; struct scsi_persistent_reserve_in_read_keys *rk;
CHECK_FOR_DATALOSS; CHECK_FOR_DATALOSS;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test Persistent Reserve OUT CLEAR works."); logging(LOG_VERBOSE, "Test Persistent Reserve OUT CLEAR works.");
/* register our reservation key with the target */ /* register our reservation key with the target */
ret = prout_register_and_ignore(sd, key); ret = prout_register_and_ignore(sd, key);
if (ret == -2) { if (ret == -2) {
logging(LOG_NORMAL, "[SKIPPED] PERSISTENT RESERVE OUT is not implemented."); logging(LOG_NORMAL, "[SKIPPED] PERSISTENT RESERVE OUT is not implemented.");
CU_PASS("PERSISTENT RESERVE OUT is not implemented."); CU_PASS("PERSISTENT RESERVE OUT is not implemented.");
return; return;
} }
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
ret = prin_read_keys(sd, &tsk, &rk); ret = prin_read_keys(sd, &tsk, &rk);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
CU_ASSERT_NOT_EQUAL(rk->num_keys, 0); CU_ASSERT_NOT_EQUAL(rk->num_keys, 0);
/* retain PR generation number to check for increments */ /* retain PR generation number to check for increments */
old_gen = rk->prgeneration; old_gen = rk->prgeneration;
scsi_free_scsi_task(tsk); scsi_free_scsi_task(tsk);
rk = NULL; /* freed with tsk */ rk = NULL; /* freed with tsk */
/* reserve the target */ /* reserve the target */
ret = prout_reserve(sd, key, ret = prout_reserve(sd, key,
SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS); SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
/* verify target reservation */ /* verify target reservation */
ret = prin_verify_reserved_as(sd, key, ret = prin_verify_reserved_as(sd, key,
SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS); SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
/* clear reservation and registration */ /* clear reservation and registration */
ret = prout_clear(sd, key); ret = prout_clear(sd, key);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
ret = prin_verify_not_reserved(sd); ret = prin_verify_not_reserved(sd);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
ret = prin_read_keys(sd, &tsk, &rk); ret = prin_read_keys(sd, &tsk, &rk);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
CU_ASSERT_EQUAL(rk->num_keys, 0); CU_ASSERT_EQUAL(rk->num_keys, 0);
/* generation incremented once for CLEAR (not for RESERVE) */ /* generation incremented once for CLEAR (not for RESERVE) */
CU_ASSERT_EQUAL(rk->prgeneration, old_gen + 1); CU_ASSERT_EQUAL(rk->prgeneration, old_gen + 1);
scsi_free_scsi_task(tsk); scsi_free_scsi_task(tsk);
rk = NULL; /* freed with tsk */ rk = NULL; /* freed with tsk */
} }

View File

@@ -30,86 +30,86 @@
void void
test_prout_preempt_rm_reg(void) test_prout_preempt_rm_reg(void)
{ {
int ret = 0; int ret = 0;
const unsigned long long k1 = rand_key(); const unsigned long long k1 = rand_key();
const unsigned long long k2 = rand_key(); const unsigned long long k2 = rand_key();
struct scsi_device *sd2; struct scsi_device *sd2;
struct scsi_task *tsk; struct scsi_task *tsk;
uint32_t old_gen; uint32_t old_gen;
int num_uas; int num_uas;
struct scsi_persistent_reserve_in_read_keys *rk; struct scsi_persistent_reserve_in_read_keys *rk;
CHECK_FOR_DATALOSS; CHECK_FOR_DATALOSS;
if (sd->iscsi_ctx == NULL) { if (sd->iscsi_ctx == NULL) {
const char *err = "[SKIPPED] This PERSISTENT RESERVE test is " const char *err = "[SKIPPED] This PERSISTENT RESERVE test is "
"only supported for iSCSI backends"; "only supported for iSCSI backends";
logging(LOG_NORMAL, "%s", err); logging(LOG_NORMAL, "%s", err);
CU_PASS(err); CU_PASS(err);
return; return;
} }
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test Persistent Reserve IN PREEMPT works."); logging(LOG_VERBOSE, "Test Persistent Reserve IN PREEMPT works.");
ret = prout_register_and_ignore(sd, k1); ret = prout_register_and_ignore(sd, k1);
if (ret == -2) { if (ret == -2) {
logging(LOG_NORMAL, "[SKIPPED] PERSISTEN RESERVE OUT is not implemented."); logging(LOG_NORMAL, "[SKIPPED] PERSISTEN RESERVE OUT is not implemented.");
CU_PASS("PERSISTENT RESERVE OUT is not implemented."); CU_PASS("PERSISTENT RESERVE OUT is not implemented.");
return; return;
} }
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
/* clear all PR state */ /* clear all PR state */
ret = prout_clear(sd, k1); ret = prout_clear(sd, k1);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
/* need to reregister cleared key */ /* need to reregister cleared key */
ret = prout_register_and_ignore(sd, k1); ret = prout_register_and_ignore(sd, k1);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
ret = mpath_sd2_get_or_clone(sd, &sd2); ret = mpath_sd2_get_or_clone(sd, &sd2);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
if (ret < 0) if (ret < 0)
return; return;
/* register secondary key */ /* register secondary key */
ret = prout_register_and_ignore(sd2, k2); ret = prout_register_and_ignore(sd2, k2);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
/* confirm that k1 and k2 are registered */ /* confirm that k1 and k2 are registered */
ret = prin_read_keys(sd, &tsk, &rk); ret = prin_read_keys(sd, &tsk, &rk);
CU_ASSERT_EQUAL_FATAL(ret, 0); CU_ASSERT_EQUAL_FATAL(ret, 0);
CU_ASSERT_EQUAL(rk->num_keys, 2); CU_ASSERT_EQUAL(rk->num_keys, 2);
/* retain PR generation number to check for increments */ /* retain PR generation number to check for increments */
old_gen = rk->prgeneration; old_gen = rk->prgeneration;
scsi_free_scsi_task(tsk); scsi_free_scsi_task(tsk);
rk = NULL; /* freed with tsk */ rk = NULL; /* freed with tsk */
/* use second connection to clear k1 registration */ /* use second connection to clear k1 registration */
ret = prout_preempt(sd2, k1, k2, ret = prout_preempt(sd2, k1, k2,
SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS); SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
/* clear any UAs generated by preempt */ /* clear any UAs generated by preempt */
ret = test_iscsi_tur_until_good(sd, &num_uas); ret = test_iscsi_tur_until_good(sd, &num_uas);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
ret = test_iscsi_tur_until_good(sd2, &num_uas); ret = test_iscsi_tur_until_good(sd2, &num_uas);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
ret = prin_read_keys(sd, &tsk, &rk); ret = prin_read_keys(sd, &tsk, &rk);
CU_ASSERT_EQUAL_FATAL(ret, 0); CU_ASSERT_EQUAL_FATAL(ret, 0);
CU_ASSERT_EQUAL(rk->num_keys, 1); CU_ASSERT_EQUAL(rk->num_keys, 1);
/* ensure preempt bumped generation number */ /* ensure preempt bumped generation number */
CU_ASSERT_EQUAL(rk->prgeneration, old_gen + 1); CU_ASSERT_EQUAL(rk->prgeneration, old_gen + 1);
/* ensure k2 is retained */ /* ensure k2 is retained */
CU_ASSERT_EQUAL(rk->keys[0], k2); CU_ASSERT_EQUAL(rk->keys[0], k2);
/* unregister k2 */ /* unregister k2 */
ret = prout_register_key(sd2, 0, k2); ret = prout_register_key(sd2, 0, k2);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
} }

View File

@@ -30,35 +30,35 @@
void void
test_prout_register_simple(void) test_prout_register_simple(void)
{ {
const unsigned long long key = rand_key(); const unsigned long long key = rand_key();
int ret = 0; int ret = 0;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test Persistent Reserve IN REGISTER works."); logging(LOG_VERBOSE, "Test Persistent Reserve IN REGISTER works.");
/* register our reservation key with the target */ /* register our reservation key with the target */
ret = prout_register_and_ignore(sd, key); ret = prout_register_and_ignore(sd, key);
if (ret == -2) { if (ret == -2) {
logging(LOG_NORMAL, "[SKIPPED] PERSISTEN RESERVE OUT is not implemented."); logging(LOG_NORMAL, "[SKIPPED] PERSISTEN RESERVE OUT is not implemented.");
CU_PASS("PERSISTENT RESERVE OUT is not implemented."); CU_PASS("PERSISTENT RESERVE OUT is not implemented.");
return; return;
} }
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
/* verify we can read the registration */ /* verify we can read the registration */
ret = prin_verify_key_presence(sd, key, 1); ret = prin_verify_key_presence(sd, key, 1);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
/* try to reregister, which should fail */ /* try to reregister, which should fail */
ret = prout_reregister_key_fails(sd, key+1); ret = prout_reregister_key_fails(sd, key+1);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
/* release from the target */ /* release from the target */
ret = prout_register_key(sd, 0, key); ret = prout_register_key(sd, 0, key);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
/* Verify the registration is gone */ /* Verify the registration is gone */
ret = prin_verify_key_presence(sd, key, 0); ret = prin_verify_key_presence(sd, key, 0);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
} }

View File

@@ -33,232 +33,232 @@ verify_persistent_reserve_access(struct scsi_device *sd1, struct scsi_device *sd
int unreg_i2_can_read, int unreg_i2_can_read,
int unreg_i2_can_write) int unreg_i2_can_write)
{ {
int ret; int ret;
const unsigned long long key = rand_key(); const unsigned long long key = rand_key();
const unsigned long long key2 = rand_key(); const unsigned long long key2 = rand_key();
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, logging(LOG_VERBOSE,
"Verify access for reservation type: %s", "Verify access for reservation type: %s",
scsi_pr_type_str(pr_type)); scsi_pr_type_str(pr_type));
/* send TURs to clear possible check conditions */ /* send TURs to clear possible check conditions */
(void) testunitready_clear_ua(sd1); (void) testunitready_clear_ua(sd1);
(void) testunitready_clear_ua(sd2); (void) testunitready_clear_ua(sd2);
/* register our reservation key with the target */ /* register our reservation key with the target */
ret = prout_register_and_ignore(sd1, key); ret = prout_register_and_ignore(sd1, key);
if (ret == -2) { if (ret == -2) {
logging(LOG_NORMAL, "[SKIPPED] PERSISTEN RESERVE OUT is not implemented."); logging(LOG_NORMAL, "[SKIPPED] PERSISTEN RESERVE OUT is not implemented.");
CU_PASS("PERSISTENT RESERVE OUT is not implemented."); CU_PASS("PERSISTENT RESERVE OUT is not implemented.");
return; return;
} }
CU_ASSERT_EQUAL(0, ret); CU_ASSERT_EQUAL(0, ret);
ret = prout_register_and_ignore(sd2, key2); ret = prout_register_and_ignore(sd2, key2);
CU_ASSERT_EQUAL(0, ret); CU_ASSERT_EQUAL(0, ret);
/* reserve the target through initiator 1 */ /* reserve the target through initiator 1 */
ret = prout_reserve(sd1, key, pr_type); ret = prout_reserve(sd1, key, pr_type);
CU_ASSERT_EQUAL(0, ret); CU_ASSERT_EQUAL(0, ret);
/* verify target reservation */ /* verify target reservation */
ret = prin_verify_reserved_as(sd1, ret = prin_verify_reserved_as(sd1,
pr_type_is_all_registrants(pr_type) ? 0 : key, pr_type_is_all_registrants(pr_type) ? 0 : key,
pr_type); pr_type);
CU_ASSERT_EQUAL(0, ret); CU_ASSERT_EQUAL(0, ret);
CU_ASSERT_PTR_NOT_NULL_FATAL(scratch); CU_ASSERT_PTR_NOT_NULL_FATAL(scratch);
/* make sure init1 can read */ /* make sure init1 can read */
ret = verify_read_works(sd1, scratch); ret = verify_read_works(sd1, scratch);
CU_ASSERT_EQUAL(0, ret); CU_ASSERT_EQUAL(0, ret);
/* make sure init1 can write */ /* make sure init1 can write */
ret = verify_write_works(sd1, scratch); ret = verify_write_works(sd1, scratch);
CU_ASSERT_EQUAL(0, ret); CU_ASSERT_EQUAL(0, ret);
/* verify registered init2 read access */ /* verify registered init2 read access */
if (reg_i2_can_read) if (reg_i2_can_read)
ret = verify_read_works(sd2, scratch); ret = verify_read_works(sd2, scratch);
else else
ret = verify_read_fails(sd2, scratch); ret = verify_read_fails(sd2, scratch);
CU_ASSERT_EQUAL(0, ret); CU_ASSERT_EQUAL(0, ret);
/* verify registered init2 write access */ /* verify registered init2 write access */
if (reg_i2_can_write) if (reg_i2_can_write)
ret = verify_write_works(sd2, scratch); ret = verify_write_works(sd2, scratch);
else else
ret = verify_write_fails(sd2, scratch); ret = verify_write_fails(sd2, scratch);
CU_ASSERT_EQUAL(0, ret); CU_ASSERT_EQUAL(0, ret);
/* unregister init2 */ /* unregister init2 */
ret = prout_register_key(sd2, 0, key2); ret = prout_register_key(sd2, 0, key2);
CU_ASSERT_EQUAL(0, ret); CU_ASSERT_EQUAL(0, ret);
/* verify unregistered init2 read access */ /* verify unregistered init2 read access */
if (unreg_i2_can_read) if (unreg_i2_can_read)
ret = verify_read_works(sd2, scratch); ret = verify_read_works(sd2, scratch);
else else
ret = verify_read_fails(sd2, scratch); ret = verify_read_fails(sd2, scratch);
CU_ASSERT_EQUAL(0, ret); CU_ASSERT_EQUAL(0, ret);
/* verify unregistered init2 write access */ /* verify unregistered init2 write access */
if (unreg_i2_can_write) if (unreg_i2_can_write)
ret = verify_write_works(sd2, scratch); ret = verify_write_works(sd2, scratch);
else else
ret = verify_write_fails(sd2, scratch); ret = verify_write_fails(sd2, scratch);
CU_ASSERT_EQUAL(0, ret); CU_ASSERT_EQUAL(0, ret);
/* release our reservation */ /* release our reservation */
ret = prout_release(sd1, key, pr_type); ret = prout_release(sd1, key, pr_type);
CU_ASSERT_EQUAL(0, ret); CU_ASSERT_EQUAL(0, ret);
/* remove our key from the target */ /* remove our key from the target */
ret = prout_register_key(sd1, 0, key); ret = prout_register_key(sd1, 0, key);
CU_ASSERT_EQUAL(0, ret); CU_ASSERT_EQUAL(0, ret);
} }
void void
test_prout_reserve_access_ea(void) test_prout_reserve_access_ea(void)
{ {
struct scsi_device *sd2; struct scsi_device *sd2;
int ret; int ret;
if (sd->iscsi_ctx == NULL) { if (sd->iscsi_ctx == NULL) {
const char *err = "[SKIPPED] This PERSISTENT RESERVE test is " const char *err = "[SKIPPED] This PERSISTENT RESERVE test is "
"only supported for iSCSI backends"; "only supported for iSCSI backends";
logging(LOG_NORMAL, "%s", err); logging(LOG_NORMAL, "%s", err);
CU_PASS(err); CU_PASS(err);
return; return;
} }
ret = mpath_sd2_get_or_clone(sd, &sd2); ret = mpath_sd2_get_or_clone(sd, &sd2);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
if (ret < 0) if (ret < 0)
return; return;
verify_persistent_reserve_access(sd, sd2, verify_persistent_reserve_access(sd, sd2,
SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS, SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS,
0, 0, 0, 0); 0, 0, 0, 0);
mpath_sd2_put(sd2); mpath_sd2_put(sd2);
} }
void void
test_prout_reserve_access_we(void) test_prout_reserve_access_we(void)
{ {
struct scsi_device *sd2; struct scsi_device *sd2;
int ret; int ret;
if (sd->iscsi_ctx == NULL) { if (sd->iscsi_ctx == NULL) {
const char *err = "[SKIPPED] This PERSISTENT RESERVE test is " const char *err = "[SKIPPED] This PERSISTENT RESERVE test is "
"only supported for iSCSI backends"; "only supported for iSCSI backends";
logging(LOG_NORMAL, "%s", err); logging(LOG_NORMAL, "%s", err);
CU_PASS(err); CU_PASS(err);
return; return;
} }
ret = mpath_sd2_get_or_clone(sd, &sd2); ret = mpath_sd2_get_or_clone(sd, &sd2);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
if (ret < 0) if (ret < 0)
return; return;
verify_persistent_reserve_access(sd, sd2, verify_persistent_reserve_access(sd, sd2,
SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE, SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE,
1, 0, 1, 0); 1, 0, 1, 0);
mpath_sd2_put(sd2); mpath_sd2_put(sd2);
} }
void void
test_prout_reserve_access_earo(void) test_prout_reserve_access_earo(void)
{ {
struct scsi_device *sd2; struct scsi_device *sd2;
int ret; int ret;
if (sd->iscsi_ctx == NULL) { if (sd->iscsi_ctx == NULL) {
const char *err = "[SKIPPED] This PERSISTENT RESERVE test is " const char *err = "[SKIPPED] This PERSISTENT RESERVE test is "
"only supported for iSCSI backends"; "only supported for iSCSI backends";
logging(LOG_NORMAL, "%s", err); logging(LOG_NORMAL, "%s", err);
CU_PASS(err); CU_PASS(err);
return; return;
} }
ret = mpath_sd2_get_or_clone(sd, &sd2); ret = mpath_sd2_get_or_clone(sd, &sd2);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
if (ret < 0) if (ret < 0)
return; return;
verify_persistent_reserve_access(sd, sd2, verify_persistent_reserve_access(sd, sd2,
SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS_REGISTRANTS_ONLY, SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS_REGISTRANTS_ONLY,
1, 1, 0, 0); 1, 1, 0, 0);
mpath_sd2_put(sd2); mpath_sd2_put(sd2);
} }
void void
test_prout_reserve_access_wero(void) test_prout_reserve_access_wero(void)
{ {
struct scsi_device *sd2; struct scsi_device *sd2;
int ret; int ret;
if (sd->iscsi_ctx == NULL) { if (sd->iscsi_ctx == NULL) {
const char *err = "[SKIPPED] This PERSISTENT RESERVE test is " const char *err = "[SKIPPED] This PERSISTENT RESERVE test is "
"only supported for iSCSI backends"; "only supported for iSCSI backends";
logging(LOG_NORMAL, "%s", err); logging(LOG_NORMAL, "%s", err);
CU_PASS(err); CU_PASS(err);
return; return;
} }
ret = mpath_sd2_get_or_clone(sd, &sd2); ret = mpath_sd2_get_or_clone(sd, &sd2);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
if (ret < 0) if (ret < 0)
return; return;
verify_persistent_reserve_access(sd, sd2, verify_persistent_reserve_access(sd, sd2,
SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE_REGISTRANTS_ONLY, SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE_REGISTRANTS_ONLY,
1, 1, 1, 0); 1, 1, 1, 0);
mpath_sd2_put(sd2); mpath_sd2_put(sd2);
} }
void void
test_prout_reserve_access_eaar(void) test_prout_reserve_access_eaar(void)
{ {
struct scsi_device *sd2; struct scsi_device *sd2;
int ret; int ret;
if (sd->iscsi_ctx == NULL) { if (sd->iscsi_ctx == NULL) {
const char *err = "[SKIPPED] This PERSISTENT RESERVE test is " const char *err = "[SKIPPED] This PERSISTENT RESERVE test is "
"only supported for iSCSI backends"; "only supported for iSCSI backends";
logging(LOG_NORMAL, "%s", err); logging(LOG_NORMAL, "%s", err);
CU_PASS(err); CU_PASS(err);
return; return;
} }
ret = mpath_sd2_get_or_clone(sd, &sd2); ret = mpath_sd2_get_or_clone(sd, &sd2);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
if (ret < 0) if (ret < 0)
return; return;
verify_persistent_reserve_access(sd, sd2, verify_persistent_reserve_access(sd, sd2,
SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS_ALL_REGISTRANTS, SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS_ALL_REGISTRANTS,
1, 1, 0, 0); 1, 1, 0, 0);
mpath_sd2_put(sd2); mpath_sd2_put(sd2);
} }
void void
test_prout_reserve_access_wear(void) test_prout_reserve_access_wear(void)
{ {
struct scsi_device *sd2; struct scsi_device *sd2;
int ret; int ret;
if (sd->iscsi_ctx == NULL) { if (sd->iscsi_ctx == NULL) {
const char *err = "[SKIPPED] This PERSISTENT RESERVE test is " const char *err = "[SKIPPED] This PERSISTENT RESERVE test is "
"only supported for iSCSI backends"; "only supported for iSCSI backends";
logging(LOG_NORMAL, "%s", err); logging(LOG_NORMAL, "%s", err);
CU_PASS(err); CU_PASS(err);
return; return;
} }
ret = mpath_sd2_get_or_clone(sd, &sd2); ret = mpath_sd2_get_or_clone(sd, &sd2);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
if (ret < 0) if (ret < 0)
return; return;
verify_persistent_reserve_access(sd, sd2, verify_persistent_reserve_access(sd, sd2,
SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE_ALL_REGISTRANTS, SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE_ALL_REGISTRANTS,
1, 1, 1, 0); 1, 1, 1, 0);
mpath_sd2_put(sd2); mpath_sd2_put(sd2);
} }

View File

@@ -30,204 +30,204 @@ verify_persistent_reserve_ownership(struct scsi_device *sd1, struct scsi_device
const enum scsi_persistent_out_type pr_type, const enum scsi_persistent_out_type pr_type,
int resvn_is_shared) int resvn_is_shared)
{ {
int ret; int ret;
const unsigned long long key1 = rand_key(); const unsigned long long key1 = rand_key();
const unsigned long long key2 = rand_key(); const unsigned long long key2 = rand_key();
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, logging(LOG_VERBOSE,
"Verify ownership for reservation type: %s", "Verify ownership for reservation type: %s",
scsi_pr_type_str(pr_type)); scsi_pr_type_str(pr_type));
/* send TURs to clear possible check conditions */ /* send TURs to clear possible check conditions */
(void) testunitready_clear_ua(sd1); (void) testunitready_clear_ua(sd1);
(void) testunitready_clear_ua(sd2); (void) testunitready_clear_ua(sd2);
/* register our reservation key with the target */ /* register our reservation key with the target */
ret = prout_register_and_ignore(sd1, key1); ret = prout_register_and_ignore(sd1, key1);
if (ret == -2) { if (ret == -2) {
logging(LOG_NORMAL, "[SKIPPED] PERSISTEN RESERVE OUT is not implemented."); logging(LOG_NORMAL, "[SKIPPED] PERSISTEN RESERVE OUT is not implemented.");
CU_PASS("PERSISTENT RESERVE OUT is not implemented."); CU_PASS("PERSISTENT RESERVE OUT is not implemented.");
return; return;
} }
CU_ASSERT_EQUAL(0, ret); CU_ASSERT_EQUAL(0, ret);
ret = prout_register_and_ignore(sd2, key2); ret = prout_register_and_ignore(sd2, key2);
CU_ASSERT_EQUAL(0, ret); CU_ASSERT_EQUAL(0, ret);
/* reserve the target through initiator 1 */ /* reserve the target through initiator 1 */
ret = prout_reserve(sd1, key1, pr_type); ret = prout_reserve(sd1, key1, pr_type);
CU_ASSERT_EQUAL(0, ret); CU_ASSERT_EQUAL(0, ret);
/* verify target reservation */ /* verify target reservation */
ret = prin_verify_reserved_as(sd1, ret = prin_verify_reserved_as(sd1,
pr_type_is_all_registrants(pr_type) ? 0 : key1, pr_type_is_all_registrants(pr_type) ? 0 : key1,
pr_type); pr_type);
CU_ASSERT_EQUAL(0, ret); CU_ASSERT_EQUAL(0, ret);
/* unregister init1 */ /* unregister init1 */
ret = prout_register_key(sd1, 0, key1); ret = prout_register_key(sd1, 0, key1);
CU_ASSERT_EQUAL(0, ret); CU_ASSERT_EQUAL(0, ret);
/* verify if reservation is still present */ /* verify if reservation is still present */
if (resvn_is_shared) { if (resvn_is_shared) {
/* verify target reservation */ /* verify target reservation */
ret = prin_verify_reserved_as(sd1, ret = prin_verify_reserved_as(sd1,
pr_type_is_all_registrants(pr_type) ? 0 : key1, pr_type_is_all_registrants(pr_type) ? 0 : key1,
pr_type); pr_type);
CU_ASSERT_EQUAL(0, ret); CU_ASSERT_EQUAL(0, ret);
/* release our reservation */ /* release our reservation */
ret = prout_release(sd2, key2, pr_type); ret = prout_release(sd2, key2, pr_type);
CU_ASSERT_EQUAL(0, ret); CU_ASSERT_EQUAL(0, ret);
} else { } else {
/* verify target is not reserved now */ /* verify target is not reserved now */
ret = prin_verify_not_reserved(sd1); ret = prin_verify_not_reserved(sd1);
CU_ASSERT_EQUAL(0, ret); CU_ASSERT_EQUAL(0, ret);
/* send TUR to clear possible check condition */ /* send TUR to clear possible check condition */
(void) testunitready_clear_ua(sd2); (void) testunitready_clear_ua(sd2);
} }
/* remove our remaining key from the target */ /* remove our remaining key from the target */
ret = prout_register_key(sd2, 0, key2); ret = prout_register_key(sd2, 0, key2);
CU_ASSERT_EQUAL(0, ret); CU_ASSERT_EQUAL(0, ret);
} }
void void
test_prout_reserve_ownership_ea(void) test_prout_reserve_ownership_ea(void)
{ {
struct scsi_device *sd2; struct scsi_device *sd2;
int ret; int ret;
if (sd->iscsi_ctx == NULL) { if (sd->iscsi_ctx == NULL) {
const char *err = "[SKIPPED] This PERSISTENT RESERVE test is " const char *err = "[SKIPPED] This PERSISTENT RESERVE test is "
"only supported for iSCSI backends"; "only supported for iSCSI backends";
logging(LOG_NORMAL, "%s", err); logging(LOG_NORMAL, "%s", err);
CU_PASS(err); CU_PASS(err);
return; return;
} }
ret = mpath_sd2_get_or_clone(sd, &sd2); ret = mpath_sd2_get_or_clone(sd, &sd2);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
if (ret < 0) if (ret < 0)
return; return;
verify_persistent_reserve_ownership(sd, sd2, verify_persistent_reserve_ownership(sd, sd2,
SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS, 0); SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS, 0);
mpath_sd2_put(sd2); mpath_sd2_put(sd2);
} }
void void
test_prout_reserve_ownership_we(void) test_prout_reserve_ownership_we(void)
{ {
struct scsi_device *sd2; struct scsi_device *sd2;
int ret; int ret;
if (sd->iscsi_ctx == NULL) { if (sd->iscsi_ctx == NULL) {
const char *err = "[SKIPPED] This PERSISTENT RESERVE test is " const char *err = "[SKIPPED] This PERSISTENT RESERVE test is "
"only supported for iSCSI backends"; "only supported for iSCSI backends";
logging(LOG_NORMAL, "%s", err); logging(LOG_NORMAL, "%s", err);
CU_PASS(err); CU_PASS(err);
return; return;
} }
ret = mpath_sd2_get_or_clone(sd, &sd2); ret = mpath_sd2_get_or_clone(sd, &sd2);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
if (ret < 0) if (ret < 0)
return; return;
verify_persistent_reserve_ownership(sd, sd2, verify_persistent_reserve_ownership(sd, sd2,
SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE, 0); SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE, 0);
mpath_sd2_put(sd2); mpath_sd2_put(sd2);
} }
void void
test_prout_reserve_ownership_earo(void) test_prout_reserve_ownership_earo(void)
{ {
struct scsi_device *sd2; struct scsi_device *sd2;
int ret; int ret;
if (sd->iscsi_ctx == NULL) { if (sd->iscsi_ctx == NULL) {
const char *err = "[SKIPPED] This PERSISTENT RESERVE test is " const char *err = "[SKIPPED] This PERSISTENT RESERVE test is "
"only supported for iSCSI backends"; "only supported for iSCSI backends";
logging(LOG_NORMAL, "%s", err); logging(LOG_NORMAL, "%s", err);
CU_PASS(err); CU_PASS(err);
return; return;
} }
ret = mpath_sd2_get_or_clone(sd, &sd2); ret = mpath_sd2_get_or_clone(sd, &sd2);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
if (ret < 0) if (ret < 0)
return; return;
verify_persistent_reserve_ownership(sd, sd2, verify_persistent_reserve_ownership(sd, sd2,
SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS_REGISTRANTS_ONLY, 0); SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS_REGISTRANTS_ONLY, 0);
mpath_sd2_put(sd2); mpath_sd2_put(sd2);
} }
void void
test_prout_reserve_ownership_wero(void) test_prout_reserve_ownership_wero(void)
{ {
struct scsi_device *sd2; struct scsi_device *sd2;
int ret; int ret;
if (sd->iscsi_ctx == NULL) { if (sd->iscsi_ctx == NULL) {
const char *err = "[SKIPPED] This PERSISTENT RESERVE test is " const char *err = "[SKIPPED] This PERSISTENT RESERVE test is "
"only supported for iSCSI backends"; "only supported for iSCSI backends";
logging(LOG_NORMAL, "%s", err); logging(LOG_NORMAL, "%s", err);
CU_PASS(err); CU_PASS(err);
return; return;
} }
ret = mpath_sd2_get_or_clone(sd, &sd2); ret = mpath_sd2_get_or_clone(sd, &sd2);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
if (ret < 0) if (ret < 0)
return; return;
verify_persistent_reserve_ownership(sd, sd2, verify_persistent_reserve_ownership(sd, sd2,
SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE_REGISTRANTS_ONLY, 0); SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE_REGISTRANTS_ONLY, 0);
mpath_sd2_put(sd2); mpath_sd2_put(sd2);
} }
void void
test_prout_reserve_ownership_eaar(void) test_prout_reserve_ownership_eaar(void)
{ {
struct scsi_device *sd2; struct scsi_device *sd2;
int ret; int ret;
if (sd->iscsi_ctx == NULL) { if (sd->iscsi_ctx == NULL) {
const char *err = "[SKIPPED] This PERSISTENT RESERVE test is " const char *err = "[SKIPPED] This PERSISTENT RESERVE test is "
"only supported for iSCSI backends"; "only supported for iSCSI backends";
logging(LOG_NORMAL, "%s", err); logging(LOG_NORMAL, "%s", err);
CU_PASS(err); CU_PASS(err);
return; return;
} }
ret = mpath_sd2_get_or_clone(sd, &sd2); ret = mpath_sd2_get_or_clone(sd, &sd2);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
if (ret < 0) if (ret < 0)
return; return;
verify_persistent_reserve_ownership(sd, sd2, verify_persistent_reserve_ownership(sd, sd2,
SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS_ALL_REGISTRANTS, 1); SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS_ALL_REGISTRANTS, 1);
mpath_sd2_put(sd2); mpath_sd2_put(sd2);
} }
void void
test_prout_reserve_ownership_wear(void) test_prout_reserve_ownership_wear(void)
{ {
struct scsi_device *sd2; struct scsi_device *sd2;
int ret; int ret;
if (sd->iscsi_ctx == NULL) { if (sd->iscsi_ctx == NULL) {
const char *err = "[SKIPPED] This PERSISTENT RESERVE test is " const char *err = "[SKIPPED] This PERSISTENT RESERVE test is "
"only supported for iSCSI backends"; "only supported for iSCSI backends";
logging(LOG_NORMAL, "%s", err); logging(LOG_NORMAL, "%s", err);
CU_PASS(err); CU_PASS(err);
return; return;
} }
ret = mpath_sd2_get_or_clone(sd, &sd2); ret = mpath_sd2_get_or_clone(sd, &sd2);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
if (ret < 0) if (ret < 0)
return; return;
verify_persistent_reserve_ownership(sd, sd2, verify_persistent_reserve_ownership(sd, sd2,
SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE_ALL_REGISTRANTS, 1); SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE_ALL_REGISTRANTS, 1);
mpath_sd2_put(sd2); mpath_sd2_put(sd2);
} }

View File

@@ -31,57 +31,57 @@
* list of persistent reservation types to test, in order * list of persistent reservation types to test, in order
*/ */
static enum scsi_persistent_out_type pr_types_to_test[] = { static enum scsi_persistent_out_type pr_types_to_test[] = {
SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE, SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE,
SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS, SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS,
SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE_REGISTRANTS_ONLY, SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE_REGISTRANTS_ONLY,
SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS_REGISTRANTS_ONLY, SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS_REGISTRANTS_ONLY,
SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE_ALL_REGISTRANTS, SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE_ALL_REGISTRANTS,
SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS_ALL_REGISTRANTS, SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS_ALL_REGISTRANTS,
0 0
}; };
void void
test_prout_reserve_simple(void) test_prout_reserve_simple(void)
{ {
int ret = 0; int ret = 0;
int i; int i;
const unsigned long long key = rand_key(); const unsigned long long key = rand_key();
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test Persistent Reserve IN RESERVE works."); logging(LOG_VERBOSE, "Test Persistent Reserve IN RESERVE works.");
/* register our reservation key with the target */ /* register our reservation key with the target */
ret = prout_register_and_ignore(sd, key); ret = prout_register_and_ignore(sd, key);
if (ret == -2) { if (ret == -2) {
logging(LOG_NORMAL, "[SKIPPED] PERSISTEN RESERVE OUT is not implemented."); logging(LOG_NORMAL, "[SKIPPED] PERSISTEN RESERVE OUT is not implemented.");
CU_PASS("PERSISTENT RESERVE OUT is not implemented."); CU_PASS("PERSISTENT RESERVE OUT is not implemented.");
return; return;
} }
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
/* test each reservatoin type */ /* test each reservatoin type */
for (i = 0; pr_types_to_test[i] != 0; i++) { for (i = 0; pr_types_to_test[i] != 0; i++) {
enum scsi_persistent_out_type pr_type = pr_types_to_test[i]; enum scsi_persistent_out_type pr_type = pr_types_to_test[i];
/* reserve the target */ /* reserve the target */
ret = prout_reserve(sd, key, pr_type); ret = prout_reserve(sd, key, pr_type);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
/* verify target reservation */ /* verify target reservation */
ret = prin_verify_reserved_as(sd, ret = prin_verify_reserved_as(sd,
pr_type_is_all_registrants(pr_type) ? 0 : key, pr_type_is_all_registrants(pr_type) ? 0 : key,
pr_type); pr_type);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
/* release our reservation */ /* release our reservation */
ret = prout_release(sd, key, pr_type); ret = prout_release(sd, key, pr_type);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
} }
/* remove our key from the target */ /* remove our key from the target */
ret = prout_register_key(sd, 0, key); ret = prout_register_key(sd, 0, key);
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
} }

View File

@@ -27,26 +27,26 @@
void void
test_read10_0blocks(void) test_read10_0blocks(void)
{ {
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test READ10 0-blocks at LBA==0"); logging(LOG_VERBOSE, "Test READ10 0-blocks at LBA==0");
READ10(sd, NULL, 0, 0, block_size, 0, 0, 0, 0, 0, NULL, READ10(sd, NULL, 0, 0, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
if (num_blocks > 0x80000000) { if (num_blocks > 0x80000000) {
CU_PASS("[SKIPPED] LUN is too big"); CU_PASS("[SKIPPED] LUN is too big");
return; return;
} }
logging(LOG_VERBOSE, "Test READ10 0-blocks one block past end-of-LUN"); logging(LOG_VERBOSE, "Test READ10 0-blocks one block past end-of-LUN");
READ10(sd, NULL, num_blocks + 1, 0, block_size, 0, 0, 0, 0, 0, NULL, READ10(sd, NULL, num_blocks + 1, 0, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
logging(LOG_VERBOSE, "Test READ10 0-blocks at LBA==2^31"); logging(LOG_VERBOSE, "Test READ10 0-blocks at LBA==2^31");
READ10(sd, NULL, 0x80000000, 0, block_size, 0, 0, 0, 0, 0, NULL, READ10(sd, NULL, 0x80000000, 0, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
logging(LOG_VERBOSE, "Test READ10 0-blocks at LBA==-1"); logging(LOG_VERBOSE, "Test READ10 0-blocks at LBA==-1");
READ10(sd, NULL, -1, 0, block_size, 0, 0, 0, 0, 0, NULL, READ10(sd, NULL, -1, 0, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }

View File

@@ -28,51 +28,51 @@
void void
test_read10_beyond_eol(void) test_read10_beyond_eol(void)
{ {
int i; int i;
if (num_blocks >= 0x80000000) { if (num_blocks >= 0x80000000) {
CU_PASS("LUN is too big for read-beyond-eol tests with READ10. Skipping test.\n"); CU_PASS("LUN is too big for read-beyond-eol tests with READ10. Skipping test.\n");
return; return;
} }
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test READ10 1-256 blocks one block beyond the end"); logging(LOG_VERBOSE, "Test READ10 1-256 blocks one block beyond the end");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
READ10(sd, NULL, num_blocks + 1 - i, READ10(sd, NULL, num_blocks + 1 - i,
i * block_size, block_size, 0, 0, 0, 0, 0, NULL, i * block_size, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }
logging(LOG_VERBOSE, "Test READ10 1-256 blocks at LBA==2^31"); logging(LOG_VERBOSE, "Test READ10 1-256 blocks at LBA==2^31");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
READ10(sd, NULL, 0x80000000, READ10(sd, NULL, 0x80000000,
i * block_size, block_size, 0, 0, 0, 0, 0, NULL, i * block_size, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }
logging(LOG_VERBOSE, "Test READ10 1-256 blocks at LBA==-1"); logging(LOG_VERBOSE, "Test READ10 1-256 blocks at LBA==-1");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
READ10(sd, NULL, -1, i * block_size, READ10(sd, NULL, -1, i * block_size,
block_size, 0, 0, 0, 0, 0, NULL, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }
logging(LOG_VERBOSE, "Test READ10 2-256 blocks all but one block beyond the end"); logging(LOG_VERBOSE, "Test READ10 2-256 blocks all but one block beyond the end");
for (i = 2; i <= 256; i++) { for (i = 2; i <= 256; i++) {
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
READ10(sd, NULL, num_blocks - 1, READ10(sd, NULL, num_blocks - 1,
i * block_size, block_size, 0, 0, 0, 0, 0, NULL, i * block_size, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }
} }

View File

@@ -29,80 +29,80 @@
void void
test_read10_dpofua(void) test_read10_dpofua(void)
{ {
int dpofua, usage_data_dpofua; int dpofua, usage_data_dpofua;
struct scsi_task *ms_task = NULL; struct scsi_task *ms_task = NULL;
struct scsi_mode_sense *ms; struct scsi_mode_sense *ms;
struct scsi_task *rso_task = NULL; struct scsi_task *rso_task = NULL;
struct scsi_report_supported_op_codes_one_command *rsoc; struct scsi_report_supported_op_codes_one_command *rsoc;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test READ10 DPO/FUA flags"); logging(LOG_VERBOSE, "Test READ10 DPO/FUA flags");
CHECK_FOR_SBC; CHECK_FOR_SBC;
logging(LOG_VERBOSE, "Read the DPOFUA flag from mode sense data"); logging(LOG_VERBOSE, "Read the DPOFUA flag from mode sense data");
MODESENSE6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT, MODESENSE6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT,
SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255, SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "[SUCCESS] Mode sense returned status GOOD"); logging(LOG_VERBOSE, "[SUCCESS] Mode sense returned status GOOD");
ms = scsi_datain_unmarshall(ms_task); ms = scsi_datain_unmarshall(ms_task);
dpofua = ms && (ms->device_specific_parameter & 0x10); dpofua = ms && (ms->device_specific_parameter & 0x10);
scsi_free_scsi_task(ms_task); scsi_free_scsi_task(ms_task);
if (dpofua) { if (dpofua) {
logging(LOG_VERBOSE, "DPOFUA flag is set. Device should allow " logging(LOG_VERBOSE, "DPOFUA flag is set. Device should allow "
"DPO/FUA flags in CDBs"); "DPO/FUA flags in CDBs");
} else { } else {
logging(LOG_VERBOSE, "DPOFUA flag is clear. Device should fail " logging(LOG_VERBOSE, "DPOFUA flag is clear. Device should fail "
"CDBs with DPO/FUA set"); "CDBs with DPO/FUA set");
} }
logging(LOG_VERBOSE, "Test READ10 with DPO==1"); logging(LOG_VERBOSE, "Test READ10 with DPO==1");
if (dpofua) { if (dpofua) {
READ10(sd, NULL, 0, READ10(sd, NULL, 0,
block_size, block_size, 0, 1, 0, 0, 0, NULL, block_size, block_size, 0, 1, 0, 0, 0, NULL,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} else { } else {
READ10(sd, NULL, 0, READ10(sd, NULL, 0,
block_size, block_size, 0, 1, 0, 0, 0, NULL, block_size, block_size, 0, 1, 0, 0, 0, NULL,
EXPECT_INVALID_FIELD_IN_CDB); EXPECT_INVALID_FIELD_IN_CDB);
} }
logging(LOG_VERBOSE, "Test READ10 with FUA==1"); logging(LOG_VERBOSE, "Test READ10 with FUA==1");
if (dpofua) { if (dpofua) {
READ10(sd, NULL, 0, READ10(sd, NULL, 0,
block_size, block_size, 0, 0, 1, 0, 0, NULL, block_size, block_size, 0, 0, 1, 0, 0, NULL,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} else { } else {
READ10(sd, NULL, 0, READ10(sd, NULL, 0,
block_size, block_size, 0, 0, 1, 0, 0, NULL, block_size, block_size, 0, 0, 1, 0, 0, NULL,
EXPECT_INVALID_FIELD_IN_CDB); EXPECT_INVALID_FIELD_IN_CDB);
} }
logging(LOG_VERBOSE, "Test READ10 with DPO==1 FUA==1"); logging(LOG_VERBOSE, "Test READ10 with DPO==1 FUA==1");
if (dpofua) { if (dpofua) {
READ10(sd, NULL, 0, READ10(sd, NULL, 0,
block_size, block_size, 0, 1, 1, 0, 0, NULL, block_size, block_size, 0, 1, 1, 0, 0, NULL,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} else { } else {
READ10(sd, NULL, 0, READ10(sd, NULL, 0,
block_size, block_size, 0, 1, 1, 0, 0, NULL, block_size, block_size, 0, 1, 1, 0, 0, NULL,
EXPECT_INVALID_FIELD_IN_CDB); EXPECT_INVALID_FIELD_IN_CDB);
} }
logging(LOG_VERBOSE, "Try fetching REPORT_SUPPORTED_OPCODES " logging(LOG_VERBOSE, "Try fetching REPORT_SUPPORTED_OPCODES "
"for READ10"); "for READ10");
REPORT_SUPPORTED_OPCODES(sd, &rso_task, REPORT_SUPPORTED_OPCODES(sd, &rso_task,
0, SCSI_REPORT_SUPPORTING_OPCODE, 0, SCSI_REPORT_SUPPORTING_OPCODE,
SCSI_OPCODE_READ10, SCSI_OPCODE_READ10,
0, 0,
65535, 65535,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer"); logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer");
rsoc = scsi_datain_unmarshall(rso_task); rsoc = scsi_datain_unmarshall(rso_task);
CU_ASSERT_PTR_NOT_NULL_FATAL(rsoc); CU_ASSERT_PTR_NOT_NULL_FATAL(rsoc);
usage_data_dpofua = rsoc->cdb_usage_data[1] & 0x18; usage_data_dpofua = rsoc->cdb_usage_data[1] & 0x18;
if (dpofua) { if (dpofua) {
@@ -123,5 +123,5 @@ test_read10_dpofua(void)
} }
} }
scsi_free_scsi_task(rso_task); scsi_free_scsi_task(rso_task);
} }

View File

@@ -32,236 +32,236 @@
void void
test_read10_invalid(void) test_read10_invalid(void)
{ {
struct iscsi_data data; struct iscsi_data data;
struct scsi_task *task_ret; struct scsi_task *task_ret;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test invalid READ10 commands"); logging(LOG_VERBOSE, "Test invalid READ10 commands");
logging(LOG_VERBOSE, "Block size is %zu", block_size); logging(LOG_VERBOSE, "Block size is %zu", block_size);
if (sd->iscsi_ctx == NULL) { if (sd->iscsi_ctx == NULL) {
const char *err = "[SKIPPED] This READ10 test is only " const char *err = "[SKIPPED] This READ10 test is only "
"supported for iSCSI backends"; "supported for iSCSI backends";
logging(LOG_NORMAL, "%s", err); logging(LOG_NORMAL, "%s", err);
CU_PASS(err); CU_PASS(err);
return; return;
} }
/* Try a read10 of 1 block but xferlength == 0 */ /* Try a read10 of 1 block but xferlength == 0 */
task = malloc(sizeof(struct scsi_task)); task = malloc(sizeof(struct scsi_task));
CU_ASSERT_PTR_NOT_NULL_FATAL(task); CU_ASSERT_PTR_NOT_NULL_FATAL(task);
memset(task, 0, sizeof(struct scsi_task)); memset(task, 0, sizeof(struct scsi_task));
task->cdb[0] = SCSI_OPCODE_READ10; task->cdb[0] = SCSI_OPCODE_READ10;
task->cdb[8] = 1; task->cdb[8] = 1;
task->cdb_size = 10; task->cdb_size = 10;
task->xfer_dir = SCSI_XFER_READ; task->xfer_dir = SCSI_XFER_READ;
task->expxferlen = 0; task->expxferlen = 0;
/* /*
* we don't want autoreconnect since some targets will drop the session * we don't want autoreconnect since some targets will drop the session
* on this condition. * on this condition.
*/ */
iscsi_set_noautoreconnect(sd->iscsi_ctx, 1); iscsi_set_noautoreconnect(sd->iscsi_ctx, 1);
logging(LOG_VERBOSE, "Try reading one block but with iSCSI expected transfer length==0"); logging(LOG_VERBOSE, "Try reading one block but with iSCSI expected transfer length==0");
task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL); task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL);
CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret); CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret);
CU_ASSERT_NOT_EQUAL(task->status, SCSI_STATUS_CANCELLED); /* XXX redundant? */ CU_ASSERT_NOT_EQUAL(task->status, SCSI_STATUS_CANCELLED); /* XXX redundant? */
logging(LOG_VERBOSE, "Verify that the target returned SUCCESS"); logging(LOG_VERBOSE, "Verify that the target returned SUCCESS");
if (task->status != SCSI_STATUS_GOOD) { if (task->status != SCSI_STATUS_GOOD) {
logging(LOG_VERBOSE, "[FAILED] Target returned error %s", logging(LOG_VERBOSE, "[FAILED] Target returned error %s",
iscsi_get_error(sd->iscsi_ctx)); iscsi_get_error(sd->iscsi_ctx));
} }
CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD); CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD);
logging(LOG_VERBOSE, "Verify residual overflow flag is set"); logging(LOG_VERBOSE, "Verify residual overflow flag is set");
if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) { if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) {
logging(LOG_VERBOSE, "[FAILED] Target did not set residual " logging(LOG_VERBOSE, "[FAILED] Target did not set residual "
"overflow flag"); "overflow flag");
} }
CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW); CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW);
logging(LOG_VERBOSE, "Verify we got %zu bytes of residual overflow", logging(LOG_VERBOSE, "Verify we got %zu bytes of residual overflow",
block_size); block_size);
if (task->residual != block_size) { if (task->residual != block_size) {
logging(LOG_VERBOSE, "[FAILED] Target did not set correct " logging(LOG_VERBOSE, "[FAILED] Target did not set correct "
"amount of residual. Expected %zu but got %zu.", "amount of residual. Expected %zu but got %zu.",
block_size, task->residual); block_size, task->residual);
} }
CU_ASSERT_EQUAL(task->residual, block_size); CU_ASSERT_EQUAL(task->residual, block_size);
scsi_free_scsi_task(task); scsi_free_scsi_task(task);
task = NULL; task = NULL;
/* in case the previous test failed the session */ /* in case the previous test failed the session */
iscsi_set_noautoreconnect(sd->iscsi_ctx, 0); iscsi_set_noautoreconnect(sd->iscsi_ctx, 0);
logging(LOG_VERBOSE, "Try reading one block but with iSCSI expected transfer length==10000"); logging(LOG_VERBOSE, "Try reading one block but with iSCSI expected transfer length==10000");
task = malloc(sizeof(struct scsi_task)); task = malloc(sizeof(struct scsi_task));
CU_ASSERT_PTR_NOT_NULL_FATAL(task); CU_ASSERT_PTR_NOT_NULL_FATAL(task);
memset(task, 0, sizeof(struct scsi_task)); memset(task, 0, sizeof(struct scsi_task));
task->cdb[0] = SCSI_OPCODE_READ10; task->cdb[0] = SCSI_OPCODE_READ10;
task->cdb[8] = 1; task->cdb[8] = 1;
task->cdb_size = 10; task->cdb_size = 10;
task->xfer_dir = SCSI_XFER_READ; task->xfer_dir = SCSI_XFER_READ;
task->expxferlen = 10000; task->expxferlen = 10000;
task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL); task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL);
CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret); CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret);
logging(LOG_VERBOSE, "Verify that the target returned SUCCESS"); logging(LOG_VERBOSE, "Verify that the target returned SUCCESS");
if (task->status != SCSI_STATUS_GOOD) { if (task->status != SCSI_STATUS_GOOD) {
logging(LOG_VERBOSE, "[FAILED] Target returned error %s", logging(LOG_VERBOSE, "[FAILED] Target returned error %s",
iscsi_get_error(sd->iscsi_ctx)); iscsi_get_error(sd->iscsi_ctx));
} }
CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD); CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD);
logging(LOG_VERBOSE, "Verify we got a whole block back from the target"); logging(LOG_VERBOSE, "Verify we got a whole block back from the target");
CU_ASSERT_EQUAL(task->datain.size, (int)block_size); CU_ASSERT_EQUAL(task->datain.size, (int)block_size);
logging(LOG_VERBOSE, "Verify residual underflow flag is set"); logging(LOG_VERBOSE, "Verify residual underflow flag is set");
if (task->residual_status != SCSI_RESIDUAL_UNDERFLOW) { if (task->residual_status != SCSI_RESIDUAL_UNDERFLOW) {
logging(LOG_VERBOSE, "[FAILED] Target did not set residual " logging(LOG_VERBOSE, "[FAILED] Target did not set residual "
"underflow flag"); "underflow flag");
} }
CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_UNDERFLOW); CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_UNDERFLOW);
logging(LOG_VERBOSE, "Verify we got %zu bytes of residual underflow", logging(LOG_VERBOSE, "Verify we got %zu bytes of residual underflow",
10000 - block_size); 10000 - block_size);
if (task->residual != 10000 - block_size) { if (task->residual != 10000 - block_size) {
logging(LOG_VERBOSE, "[FAILED] Target did not set correct " logging(LOG_VERBOSE, "[FAILED] Target did not set correct "
"amount of residual. Expected %zu but got %zu.", "amount of residual. Expected %zu but got %zu.",
10000 - block_size, task->residual); 10000 - block_size, task->residual);
} }
CU_ASSERT_EQUAL(task->residual, 10000 - block_size); CU_ASSERT_EQUAL(task->residual, 10000 - block_size);
scsi_free_scsi_task(task); scsi_free_scsi_task(task);
task = NULL; task = NULL;
logging(LOG_VERBOSE, "Try reading one block but with iSCSI expected transfer length==200"); logging(LOG_VERBOSE, "Try reading one block but with iSCSI expected transfer length==200");
task = malloc(sizeof(struct scsi_task)); task = malloc(sizeof(struct scsi_task));
CU_ASSERT_PTR_NOT_NULL_FATAL(task); CU_ASSERT_PTR_NOT_NULL_FATAL(task);
memset(task, 0, sizeof(struct scsi_task)); memset(task, 0, sizeof(struct scsi_task));
task->cdb[0] = SCSI_OPCODE_READ10; task->cdb[0] = SCSI_OPCODE_READ10;
task->cdb[8] = 1; task->cdb[8] = 1;
task->cdb_size = 10; task->cdb_size = 10;
task->xfer_dir = SCSI_XFER_READ; task->xfer_dir = SCSI_XFER_READ;
task->expxferlen = 200; task->expxferlen = 200;
task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL); task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL);
CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret); CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret);
logging(LOG_VERBOSE, "Verify that the target returned SUCCESS"); logging(LOG_VERBOSE, "Verify that the target returned SUCCESS");
if (task->status != SCSI_STATUS_GOOD) { if (task->status != SCSI_STATUS_GOOD) {
logging(LOG_VERBOSE, "[FAILED] Target returned error %s", logging(LOG_VERBOSE, "[FAILED] Target returned error %s",
iscsi_get_error(sd->iscsi_ctx)); iscsi_get_error(sd->iscsi_ctx));
} }
CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD); CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD);
logging(LOG_VERBOSE, "Verify we got 200 bytes back from the target"); logging(LOG_VERBOSE, "Verify we got 200 bytes back from the target");
CU_ASSERT_EQUAL(task->datain.size, 200); CU_ASSERT_EQUAL(task->datain.size, 200);
logging(LOG_VERBOSE, "Verify residual overflow flag is set"); logging(LOG_VERBOSE, "Verify residual overflow flag is set");
if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) { if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) {
logging(LOG_VERBOSE, "[FAILED] Target did not set residual " logging(LOG_VERBOSE, "[FAILED] Target did not set residual "
"overflow flag"); "overflow flag");
} }
CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW); CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW);
logging(LOG_VERBOSE, "Verify we got %zu bytes of residual overflow", logging(LOG_VERBOSE, "Verify we got %zu bytes of residual overflow",
block_size - 200); block_size - 200);
if (task->residual != block_size - 200) { if (task->residual != block_size - 200) {
logging(LOG_VERBOSE, "[FAILED] Target did not set correct " logging(LOG_VERBOSE, "[FAILED] Target did not set correct "
"amount of residual. Expected %zu but got %zu.", "amount of residual. Expected %zu but got %zu.",
block_size - 200, task->residual); block_size - 200, task->residual);
} }
CU_ASSERT_EQUAL(task->residual, block_size - 200); CU_ASSERT_EQUAL(task->residual, block_size - 200);
scsi_free_scsi_task(task); scsi_free_scsi_task(task);
task = NULL; task = NULL;
logging(LOG_VERBOSE, "Try reading two blocks but iSCSI expected " logging(LOG_VERBOSE, "Try reading two blocks but iSCSI expected "
"transfer length==%zu (==one block)", block_size); "transfer length==%zu (==one block)", block_size);
task = malloc(sizeof(struct scsi_task)); task = malloc(sizeof(struct scsi_task));
CU_ASSERT_PTR_NOT_NULL_FATAL(task); CU_ASSERT_PTR_NOT_NULL_FATAL(task);
memset(task, 0, sizeof(struct scsi_task)); memset(task, 0, sizeof(struct scsi_task));
task->cdb[0] = SCSI_OPCODE_READ10; task->cdb[0] = SCSI_OPCODE_READ10;
task->cdb[8] = 2; task->cdb[8] = 2;
task->cdb_size = 10; task->cdb_size = 10;
task->xfer_dir = SCSI_XFER_READ; task->xfer_dir = SCSI_XFER_READ;
task->expxferlen = block_size; task->expxferlen = block_size;
task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL); task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL);
CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret); CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret);
logging(LOG_VERBOSE, "Verify that the target returned SUCCESS"); logging(LOG_VERBOSE, "Verify that the target returned SUCCESS");
if (task->status != SCSI_STATUS_GOOD) { if (task->status != SCSI_STATUS_GOOD) {
logging(LOG_VERBOSE, "[FAILED] Target returned error %s", logging(LOG_VERBOSE, "[FAILED] Target returned error %s",
iscsi_get_error(sd->iscsi_ctx)); iscsi_get_error(sd->iscsi_ctx));
} }
CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD); CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD);
logging(LOG_VERBOSE, "Verify we got one whole block back from the target"); logging(LOG_VERBOSE, "Verify we got one whole block back from the target");
CU_ASSERT_EQUAL(task->datain.size, (int)block_size); CU_ASSERT_EQUAL(task->datain.size, (int)block_size);
logging(LOG_VERBOSE, "Verify residual overflow flag is set"); logging(LOG_VERBOSE, "Verify residual overflow flag is set");
if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) { if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) {
logging(LOG_VERBOSE, "[FAILED] Target did not set residual " logging(LOG_VERBOSE, "[FAILED] Target did not set residual "
"overflow flag"); "overflow flag");
} }
CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW); CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW);
logging(LOG_VERBOSE, "Verify we got one block of residual overflow"); logging(LOG_VERBOSE, "Verify we got one block of residual overflow");
if (task->residual != block_size) { if (task->residual != block_size) {
logging(LOG_VERBOSE, "[FAILED] Target did not set correct " logging(LOG_VERBOSE, "[FAILED] Target did not set correct "
"amount of residual. Expected %zu but got %zu.", "amount of residual. Expected %zu but got %zu.",
block_size, task->residual); block_size, task->residual);
} }
CU_ASSERT_EQUAL(task->residual, block_size); CU_ASSERT_EQUAL(task->residual, block_size);
scsi_free_scsi_task(task); scsi_free_scsi_task(task);
task = NULL; task = NULL;
logging(LOG_VERBOSE, "Try READ10 for one block but flag it as a write on the iSCSI layer."); logging(LOG_VERBOSE, "Try READ10 for one block but flag it as a write on the iSCSI layer.");
task = malloc(sizeof(struct scsi_task)); task = malloc(sizeof(struct scsi_task));
CU_ASSERT_PTR_NOT_NULL_FATAL(task); CU_ASSERT_PTR_NOT_NULL_FATAL(task);
memset(task, 0, sizeof(struct scsi_task)); memset(task, 0, sizeof(struct scsi_task));
task->cdb[0] = SCSI_OPCODE_READ10; task->cdb[0] = SCSI_OPCODE_READ10;
task->cdb[8] = 1; task->cdb[8] = 1;
task->cdb_size = 10; task->cdb_size = 10;
task->xfer_dir = SCSI_XFER_WRITE; task->xfer_dir = SCSI_XFER_WRITE;
task->expxferlen = block_size; task->expxferlen = block_size;
memset(scratch, 0xa6, block_size); memset(scratch, 0xa6, block_size);
data.size = block_size; data.size = block_size;
data.data = (unsigned char *)scratch; data.data = (unsigned char *)scratch;
iscsi_set_noautoreconnect(sd->iscsi_ctx, 1); iscsi_set_noautoreconnect(sd->iscsi_ctx, 1);
iscsi_set_timeout(sd->iscsi_ctx, 3); iscsi_set_timeout(sd->iscsi_ctx, 3);
task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, &data); task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, &data);
iscsi_set_noautoreconnect(sd->iscsi_ctx, 0); iscsi_set_noautoreconnect(sd->iscsi_ctx, 0);
CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret); CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret);
logging(LOG_VERBOSE, "Verify that the target returned SUCCESS"); logging(LOG_VERBOSE, "Verify that the target returned SUCCESS");
if (task->status != SCSI_STATUS_GOOD) { if (task->status != SCSI_STATUS_GOOD) {
logging(LOG_VERBOSE, "[FAILED] Target returned error %s", logging(LOG_VERBOSE, "[FAILED] Target returned error %s",
iscsi_get_error(sd->iscsi_ctx)); iscsi_get_error(sd->iscsi_ctx));
} }
CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD); CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD);
scsi_free_scsi_task(task); scsi_free_scsi_task(task);
task = NULL; task = NULL;
} }

View File

@@ -29,25 +29,25 @@
void void
test_read10_rdprotect(void) test_read10_rdprotect(void)
{ {
int i; int i;
/* /*
* Try out different non-zero values for RDPROTECT. * Try out different non-zero values for RDPROTECT.
*/ */
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test READ10 with non-zero RDPROTECT"); logging(LOG_VERBOSE, "Test READ10 with non-zero RDPROTECT");
CHECK_FOR_SBC; CHECK_FOR_SBC;
if (!inq->protect || (rc16 != NULL && !rc16->prot_en)) { if (!inq->protect || (rc16 != NULL && !rc16->prot_en)) {
logging(LOG_VERBOSE, "Device does not support/use protection information. All commands should fail."); logging(LOG_VERBOSE, "Device does not support/use protection information. All commands should fail.");
for (i = 1; i < 8; i++) { for (i = 1; i < 8; i++) {
READ10(sd, NULL, 0, block_size, block_size, READ10(sd, NULL, 0, block_size, block_size,
i, 0, 0, 0, 0, NULL, i, 0, 0, 0, 0, NULL,
EXPECT_INVALID_FIELD_IN_CDB); EXPECT_INVALID_FIELD_IN_CDB);
} }
return; return;
} }
logging(LOG_NORMAL, "No tests for devices that support protection information yet."); logging(LOG_NORMAL, "No tests for devices that support protection information yet.");
} }

View File

@@ -35,206 +35,206 @@
void void
test_read10_residuals(void) test_read10_residuals(void)
{ {
struct scsi_task *task_ret; struct scsi_task *task_ret;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test READ10 commands with residuals"); logging(LOG_VERBOSE, "Test READ10 commands with residuals");
logging(LOG_VERBOSE, "Block size is %zu", block_size); logging(LOG_VERBOSE, "Block size is %zu", block_size);
if (sd->iscsi_ctx == NULL) { if (sd->iscsi_ctx == NULL) {
const char *err = "[SKIPPED] This READ10 test is only " const char *err = "[SKIPPED] This READ10 test is only "
"supported for iSCSI backends"; "supported for iSCSI backends";
logging(LOG_NORMAL, "%s", err); logging(LOG_NORMAL, "%s", err);
CU_PASS(err); CU_PASS(err);
return; return;
} }
/* Try a read10 of 1 block but xferlength == 0 */ /* Try a read10 of 1 block but xferlength == 0 */
task = malloc(sizeof(struct scsi_task)); task = malloc(sizeof(struct scsi_task));
CU_ASSERT_PTR_NOT_NULL_FATAL(task); CU_ASSERT_PTR_NOT_NULL_FATAL(task);
memset(task, 0, sizeof(struct scsi_task)); memset(task, 0, sizeof(struct scsi_task));
task->cdb[0] = SCSI_OPCODE_READ10; task->cdb[0] = SCSI_OPCODE_READ10;
task->cdb[8] = 1; task->cdb[8] = 1;
task->cdb_size = 10; task->cdb_size = 10;
task->xfer_dir = SCSI_XFER_READ; task->xfer_dir = SCSI_XFER_READ;
task->expxferlen = 0; task->expxferlen = 0;
/* /*
* we don't want autoreconnect since some targets will drop the session * we don't want autoreconnect since some targets will drop the session
* on this condition. * on this condition.
*/ */
iscsi_set_noautoreconnect(sd->iscsi_ctx, 1); iscsi_set_noautoreconnect(sd->iscsi_ctx, 1);
logging(LOG_VERBOSE, "Try reading one block but with iSCSI expected transfer length==0"); logging(LOG_VERBOSE, "Try reading one block but with iSCSI expected transfer length==0");
task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL); task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL);
CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret); CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret);
CU_ASSERT_NOT_EQUAL(task->status, SCSI_STATUS_CANCELLED); /* XXX redundant? */ CU_ASSERT_NOT_EQUAL(task->status, SCSI_STATUS_CANCELLED); /* XXX redundant? */
logging(LOG_VERBOSE, "Verify that the target returned SUCCESS"); logging(LOG_VERBOSE, "Verify that the target returned SUCCESS");
if (task->status != SCSI_STATUS_GOOD) { if (task->status != SCSI_STATUS_GOOD) {
logging(LOG_VERBOSE, "[FAILED] Target returned error %s", logging(LOG_VERBOSE, "[FAILED] Target returned error %s",
iscsi_get_error(sd->iscsi_ctx)); iscsi_get_error(sd->iscsi_ctx));
} }
CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD); CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD);
logging(LOG_VERBOSE, "Verify residual overflow flag is set"); logging(LOG_VERBOSE, "Verify residual overflow flag is set");
if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) { if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) {
logging(LOG_VERBOSE, "[FAILED] Target did not set residual " logging(LOG_VERBOSE, "[FAILED] Target did not set residual "
"overflow flag"); "overflow flag");
} }
CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW); CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW);
logging(LOG_VERBOSE, "Verify we got %zu bytes of residual overflow", logging(LOG_VERBOSE, "Verify we got %zu bytes of residual overflow",
block_size); block_size);
if (task->residual != block_size) { if (task->residual != block_size) {
logging(LOG_VERBOSE, "[FAILED] Target did not set correct " logging(LOG_VERBOSE, "[FAILED] Target did not set correct "
"amount of residual. Expected %zu but got %zu.", "amount of residual. Expected %zu but got %zu.",
block_size, task->residual); block_size, task->residual);
} }
CU_ASSERT_EQUAL(task->residual, block_size); CU_ASSERT_EQUAL(task->residual, block_size);
scsi_free_scsi_task(task); scsi_free_scsi_task(task);
task = NULL; task = NULL;
/* in case the previous test failed the session */ /* in case the previous test failed the session */
iscsi_set_noautoreconnect(sd->iscsi_ctx, 0); iscsi_set_noautoreconnect(sd->iscsi_ctx, 0);
logging(LOG_VERBOSE, "Try reading one block but with iSCSI expected transfer length==10000"); logging(LOG_VERBOSE, "Try reading one block but with iSCSI expected transfer length==10000");
task = malloc(sizeof(struct scsi_task)); task = malloc(sizeof(struct scsi_task));
CU_ASSERT_PTR_NOT_NULL_FATAL(task); CU_ASSERT_PTR_NOT_NULL_FATAL(task);
memset(task, 0, sizeof(struct scsi_task)); memset(task, 0, sizeof(struct scsi_task));
task->cdb[0] = SCSI_OPCODE_READ10; task->cdb[0] = SCSI_OPCODE_READ10;
task->cdb[8] = 1; task->cdb[8] = 1;
task->cdb_size = 10; task->cdb_size = 10;
task->xfer_dir = SCSI_XFER_READ; task->xfer_dir = SCSI_XFER_READ;
task->expxferlen = 10000; task->expxferlen = 10000;
task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL); task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL);
CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret); CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret);
logging(LOG_VERBOSE, "Verify that the target returned SUCCESS"); logging(LOG_VERBOSE, "Verify that the target returned SUCCESS");
if (task->status != SCSI_STATUS_GOOD) { if (task->status != SCSI_STATUS_GOOD) {
logging(LOG_VERBOSE, "[FAILED] Target returned error %s", logging(LOG_VERBOSE, "[FAILED] Target returned error %s",
iscsi_get_error(sd->iscsi_ctx)); iscsi_get_error(sd->iscsi_ctx));
} }
CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD); CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD);
logging(LOG_VERBOSE, "Verify we got one whole block back from the target"); logging(LOG_VERBOSE, "Verify we got one whole block back from the target");
if (task->datain.size != (int)block_size) { if (task->datain.size != (int)block_size) {
logging(LOG_VERBOSE, "[FAILED] Target returned %u bytes " logging(LOG_VERBOSE, "[FAILED] Target returned %u bytes "
"of data but should have returned %zu bytes.", "of data but should have returned %zu bytes.",
task->datain.size,block_size); task->datain.size,block_size);
} }
CU_ASSERT_EQUAL(task->datain.size, (int)block_size); CU_ASSERT_EQUAL(task->datain.size, (int)block_size);
logging(LOG_VERBOSE, "Verify residual underflow flag is set"); logging(LOG_VERBOSE, "Verify residual underflow flag is set");
if (task->residual_status != SCSI_RESIDUAL_UNDERFLOW) { if (task->residual_status != SCSI_RESIDUAL_UNDERFLOW) {
logging(LOG_VERBOSE, "[FAILED] Target did not set residual " logging(LOG_VERBOSE, "[FAILED] Target did not set residual "
"underflow flag"); "underflow flag");
} }
CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_UNDERFLOW); CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_UNDERFLOW);
logging(LOG_VERBOSE, "Verify we got %zu bytes of residual underflow", logging(LOG_VERBOSE, "Verify we got %zu bytes of residual underflow",
10000 - block_size); 10000 - block_size);
if (task->residual != 10000 - block_size) { if (task->residual != 10000 - block_size) {
logging(LOG_VERBOSE, "[FAILED] Target did not set correct " logging(LOG_VERBOSE, "[FAILED] Target did not set correct "
"amount of residual. Expected %zu but got %zu.", "amount of residual. Expected %zu but got %zu.",
10000 - block_size, task->residual); 10000 - block_size, task->residual);
} }
CU_ASSERT_EQUAL(task->residual, 10000 - block_size); CU_ASSERT_EQUAL(task->residual, 10000 - block_size);
scsi_free_scsi_task(task); scsi_free_scsi_task(task);
task = NULL; task = NULL;
logging(LOG_VERBOSE, "Try reading one block but with iSCSI expected transfer length==200"); logging(LOG_VERBOSE, "Try reading one block but with iSCSI expected transfer length==200");
task = malloc(sizeof(struct scsi_task)); task = malloc(sizeof(struct scsi_task));
CU_ASSERT_PTR_NOT_NULL_FATAL(task); CU_ASSERT_PTR_NOT_NULL_FATAL(task);
memset(task, 0, sizeof(struct scsi_task)); memset(task, 0, sizeof(struct scsi_task));
task->cdb[0] = SCSI_OPCODE_READ10; task->cdb[0] = SCSI_OPCODE_READ10;
task->cdb[8] = 1; task->cdb[8] = 1;
task->cdb_size = 10; task->cdb_size = 10;
task->xfer_dir = SCSI_XFER_READ; task->xfer_dir = SCSI_XFER_READ;
task->expxferlen = 200; task->expxferlen = 200;
task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL); task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL);
CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret); CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret);
logging(LOG_VERBOSE, "Verify that the target returned SUCCESS"); logging(LOG_VERBOSE, "Verify that the target returned SUCCESS");
if (task->status != SCSI_STATUS_GOOD) { if (task->status != SCSI_STATUS_GOOD) {
logging(LOG_VERBOSE, "[FAILED] Target returned error %s", logging(LOG_VERBOSE, "[FAILED] Target returned error %s",
iscsi_get_error(sd->iscsi_ctx)); iscsi_get_error(sd->iscsi_ctx));
} }
CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD); CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD);
logging(LOG_VERBOSE, "Verify we got 200 bytes back from the target"); logging(LOG_VERBOSE, "Verify we got 200 bytes back from the target");
CU_ASSERT_EQUAL(task->datain.size, 200); CU_ASSERT_EQUAL(task->datain.size, 200);
logging(LOG_VERBOSE, "Verify residual overflow flag is set"); logging(LOG_VERBOSE, "Verify residual overflow flag is set");
if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) { if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) {
logging(LOG_VERBOSE, "[FAILED] Target did not set residual " logging(LOG_VERBOSE, "[FAILED] Target did not set residual "
"overflow flag"); "overflow flag");
} }
CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW); CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW);
logging(LOG_VERBOSE, "Verify we got %zu bytes of residual overflow", logging(LOG_VERBOSE, "Verify we got %zu bytes of residual overflow",
block_size - 200); block_size - 200);
if (task->residual != block_size - 200) { if (task->residual != block_size - 200) {
logging(LOG_VERBOSE, "[FAILED] Target did not set correct " logging(LOG_VERBOSE, "[FAILED] Target did not set correct "
"amount of residual. Expected %zu but got %zu.", "amount of residual. Expected %zu but got %zu.",
block_size - 200, task->residual); block_size - 200, task->residual);
} }
CU_ASSERT_EQUAL(task->residual, block_size - 200); CU_ASSERT_EQUAL(task->residual, block_size - 200);
scsi_free_scsi_task(task); scsi_free_scsi_task(task);
task = NULL; task = NULL;
logging(LOG_VERBOSE, "Try reading two blocks but iSCSI expected " logging(LOG_VERBOSE, "Try reading two blocks but iSCSI expected "
"transfer length==%zu (==one block)", block_size); "transfer length==%zu (==one block)", block_size);
task = malloc(sizeof(struct scsi_task)); task = malloc(sizeof(struct scsi_task));
CU_ASSERT_PTR_NOT_NULL_FATAL(task); CU_ASSERT_PTR_NOT_NULL_FATAL(task);
memset(task, 0, sizeof(struct scsi_task)); memset(task, 0, sizeof(struct scsi_task));
task->cdb[0] = SCSI_OPCODE_READ10; task->cdb[0] = SCSI_OPCODE_READ10;
task->cdb[8] = 2; task->cdb[8] = 2;
task->cdb_size = 10; task->cdb_size = 10;
task->xfer_dir = SCSI_XFER_READ; task->xfer_dir = SCSI_XFER_READ;
task->expxferlen = block_size; task->expxferlen = block_size;
task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL); task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL);
CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret); CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret);
logging(LOG_VERBOSE, "Verify that the target returned SUCCESS"); logging(LOG_VERBOSE, "Verify that the target returned SUCCESS");
if (task->status != SCSI_STATUS_GOOD) { if (task->status != SCSI_STATUS_GOOD) {
logging(LOG_VERBOSE, "[FAILED] Target returned error %s", logging(LOG_VERBOSE, "[FAILED] Target returned error %s",
iscsi_get_error(sd->iscsi_ctx)); iscsi_get_error(sd->iscsi_ctx));
} }
CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD); CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD);
logging(LOG_VERBOSE, "Verify we got one whole block back from the target"); logging(LOG_VERBOSE, "Verify we got one whole block back from the target");
CU_ASSERT_EQUAL(task->datain.size, (int)block_size); CU_ASSERT_EQUAL(task->datain.size, (int)block_size);
logging(LOG_VERBOSE, "Verify residual overflow flag is set"); logging(LOG_VERBOSE, "Verify residual overflow flag is set");
if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) { if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) {
logging(LOG_VERBOSE, "[FAILED] Target did not set residual " logging(LOG_VERBOSE, "[FAILED] Target did not set residual "
"overflow flag"); "overflow flag");
} }
CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW); CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW);
logging(LOG_VERBOSE, "Verify we got one block of residual overflow"); logging(LOG_VERBOSE, "Verify we got one block of residual overflow");
if (task->residual != block_size) { if (task->residual != block_size) {
logging(LOG_VERBOSE, "[FAILED] Target did not set correct " logging(LOG_VERBOSE, "[FAILED] Target did not set correct "
"amount of residual. Expected %zu but got %zu.", "amount of residual. Expected %zu but got %zu.",
block_size, task->residual); block_size, task->residual);
} }
CU_ASSERT_EQUAL(task->residual, block_size); CU_ASSERT_EQUAL(task->residual, block_size);
scsi_free_scsi_task(task); scsi_free_scsi_task(task);
task = NULL; task = NULL;
} }

View File

@@ -29,26 +29,26 @@
void void
test_read10_simple(void) test_read10_simple(void)
{ {
int i; int i;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test READ10 of 1-256 blocks at the start of the LUN"); logging(LOG_VERBOSE, "Test READ10 of 1-256 blocks at the start of the LUN");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
READ10(sd, NULL, 0, i * block_size, READ10(sd, NULL, 0, i * block_size,
block_size, 0, 0, 0, 0, 0, NULL, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }
logging(LOG_VERBOSE, "Test READ10 of 1-256 blocks at the end of the LUN"); logging(LOG_VERBOSE, "Test READ10 of 1-256 blocks at the end of the LUN");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
READ10(sd, NULL, num_blocks - i, READ10(sd, NULL, num_blocks - i,
i * block_size, block_size, 0, 0, 0, 0, 0, NULL, i * block_size, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }
} }

View File

@@ -27,25 +27,25 @@
void void
test_read12_0blocks(void) test_read12_0blocks(void)
{ {
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test READ12 0-blocks at LBA==0"); logging(LOG_VERBOSE, "Test READ12 0-blocks at LBA==0");
READ12(sd, NULL, 0, 0, block_size, 0, 0, 0, 0, 0, NULL, READ12(sd, NULL, 0, 0, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
if (num_blocks > 0x80000000) { if (num_blocks > 0x80000000) {
CU_PASS("[SKIPPED] LUN is too big"); CU_PASS("[SKIPPED] LUN is too big");
return; return;
} }
logging(LOG_VERBOSE, "Test READ12 0-blocks one block past end-of-LUN"); logging(LOG_VERBOSE, "Test READ12 0-blocks one block past end-of-LUN");
READ12(sd, NULL, num_blocks + 1, 0, block_size, 0, 0, 0, 0, 0, NULL, READ12(sd, NULL, num_blocks + 1, 0, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
logging(LOG_VERBOSE, "Test READ12 0-blocks at LBA==2^31"); logging(LOG_VERBOSE, "Test READ12 0-blocks at LBA==2^31");
READ12(sd, NULL, 0x80000000, 0, block_size, 0, 0, 0, 0, 0, NULL, READ12(sd, NULL, 0x80000000, 0, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
logging(LOG_VERBOSE, "Test READ12 0-blocks at LBA==-1"); logging(LOG_VERBOSE, "Test READ12 0-blocks at LBA==-1");
READ12(sd, NULL, -1, 0, block_size, 0, 0, 0, 0, 0, NULL, READ12(sd, NULL, -1, 0, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }

View File

@@ -28,51 +28,51 @@
void void
test_read12_beyond_eol(void) test_read12_beyond_eol(void)
{ {
int i; int i;
if (num_blocks >= 0x80000000) { if (num_blocks >= 0x80000000) {
CU_PASS("LUN is too big for read-beyond-eol tests with READ12. Skipping test.\n"); CU_PASS("LUN is too big for read-beyond-eol tests with READ12. Skipping test.\n");
return; return;
} }
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test READ12 1-256 blocks one block beyond the end"); logging(LOG_VERBOSE, "Test READ12 1-256 blocks one block beyond the end");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
READ12(sd, NULL, num_blocks + 1 - i, READ12(sd, NULL, num_blocks + 1 - i,
i * block_size, block_size, 0, 0, 0, 0, 0, NULL, i * block_size, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }
logging(LOG_VERBOSE, "Test READ12 1-256 blocks at LBA==2^31"); logging(LOG_VERBOSE, "Test READ12 1-256 blocks at LBA==2^31");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
READ12(sd, NULL, 0x80000000, READ12(sd, NULL, 0x80000000,
i * block_size, block_size, 0, 0, 0, 0, 0, NULL, i * block_size, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }
logging(LOG_VERBOSE, "Test READ12 1-256 blocks at LBA==-1"); logging(LOG_VERBOSE, "Test READ12 1-256 blocks at LBA==-1");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
READ12(sd, NULL, -1, i * block_size, READ12(sd, NULL, -1, i * block_size,
block_size, 0, 0, 0, 0, 0, NULL, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }
logging(LOG_VERBOSE, "Test READ12 2-256 blocks all but one block beyond the end"); logging(LOG_VERBOSE, "Test READ12 2-256 blocks all but one block beyond the end");
for (i = 2; i <= 256; i++) { for (i = 2; i <= 256; i++) {
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
READ12(sd, NULL, num_blocks - 1, READ12(sd, NULL, num_blocks - 1,
i * block_size, block_size, 0, 0, 0, 0, 0, NULL, i * block_size, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }
} }

View File

@@ -29,79 +29,79 @@
void void
test_read12_dpofua(void) test_read12_dpofua(void)
{ {
int dpofua, usage_data_dpofua; int dpofua, usage_data_dpofua;
struct scsi_task *ms_task = NULL; struct scsi_task *ms_task = NULL;
struct scsi_mode_sense *ms; struct scsi_mode_sense *ms;
struct scsi_task *rso_task = NULL; struct scsi_task *rso_task = NULL;
struct scsi_report_supported_op_codes_one_command *rsoc; struct scsi_report_supported_op_codes_one_command *rsoc;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test READ12 DPO/FUA flags"); logging(LOG_VERBOSE, "Test READ12 DPO/FUA flags");
CHECK_FOR_SBC; CHECK_FOR_SBC;
logging(LOG_VERBOSE, "Read the DPOFUA flag from mode sense data"); logging(LOG_VERBOSE, "Read the DPOFUA flag from mode sense data");
MODESENSE6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT, MODESENSE6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT,
SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255, SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "[SUCCESS] Mode sense returned status GOOD"); logging(LOG_VERBOSE, "[SUCCESS] Mode sense returned status GOOD");
ms = scsi_datain_unmarshall(ms_task); ms = scsi_datain_unmarshall(ms_task);
dpofua = ms && (ms->device_specific_parameter & 0x10); dpofua = ms && (ms->device_specific_parameter & 0x10);
scsi_free_scsi_task(ms_task); scsi_free_scsi_task(ms_task);
if (dpofua) { if (dpofua) {
logging(LOG_VERBOSE, "DPOFUA flag is set. Device should allow " logging(LOG_VERBOSE, "DPOFUA flag is set. Device should allow "
"DPO/FUA flags in CDBs"); "DPO/FUA flags in CDBs");
} else { } else {
logging(LOG_VERBOSE, "DPOFUA flag is clear. Device should fail " logging(LOG_VERBOSE, "DPOFUA flag is clear. Device should fail "
"CDBs with DPO/FUA set"); "CDBs with DPO/FUA set");
} }
logging(LOG_VERBOSE, "Test READ12 with DPO==1"); logging(LOG_VERBOSE, "Test READ12 with DPO==1");
if (dpofua) { if (dpofua) {
READ12(sd, NULL, 0, READ12(sd, NULL, 0,
block_size, block_size, 0, 1, 0, 0, 0, NULL, block_size, block_size, 0, 1, 0, 0, 0, NULL,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} else { } else {
READ12(sd, NULL, 0, READ12(sd, NULL, 0,
block_size, block_size, 0, 1, 0, 0, 0, NULL, block_size, block_size, 0, 1, 0, 0, 0, NULL,
EXPECT_INVALID_FIELD_IN_CDB); EXPECT_INVALID_FIELD_IN_CDB);
} }
logging(LOG_VERBOSE, "Test READ12 with FUA==1"); logging(LOG_VERBOSE, "Test READ12 with FUA==1");
if (dpofua) { if (dpofua) {
READ12(sd, NULL, 0, READ12(sd, NULL, 0,
block_size, block_size, 0, 0, 1, 0, 0, NULL, block_size, block_size, 0, 0, 1, 0, 0, NULL,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} else { } else {
READ12(sd, NULL, 0, READ12(sd, NULL, 0,
block_size, block_size, 0, 0, 1, 0, 0, NULL, block_size, block_size, 0, 0, 1, 0, 0, NULL,
EXPECT_INVALID_FIELD_IN_CDB); EXPECT_INVALID_FIELD_IN_CDB);
} }
logging(LOG_VERBOSE, "Test READ12 with DPO==1 FUA==1"); logging(LOG_VERBOSE, "Test READ12 with DPO==1 FUA==1");
if (dpofua) { if (dpofua) {
READ12(sd, NULL, 0, READ12(sd, NULL, 0,
block_size, block_size, 0, 1, 1, 0, 0, NULL, block_size, block_size, 0, 1, 1, 0, 0, NULL,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} else { } else {
READ12(sd, NULL, 0, READ12(sd, NULL, 0,
block_size, block_size, 0, 1, 1, 0, 0, NULL, block_size, block_size, 0, 1, 1, 0, 0, NULL,
EXPECT_INVALID_FIELD_IN_CDB); EXPECT_INVALID_FIELD_IN_CDB);
} }
logging(LOG_VERBOSE, "Try fetching REPORT_SUPPORTED_OPCODES " logging(LOG_VERBOSE, "Try fetching REPORT_SUPPORTED_OPCODES "
"for READ12"); "for READ12");
REPORT_SUPPORTED_OPCODES(sd, &rso_task, REPORT_SUPPORTED_OPCODES(sd, &rso_task,
0, SCSI_REPORT_SUPPORTING_OPCODE, 0, SCSI_REPORT_SUPPORTING_OPCODE,
SCSI_OPCODE_READ12, SCSI_OPCODE_READ12,
0, 0,
65535, 65535,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer"); logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer");
rsoc = scsi_datain_unmarshall(rso_task); rsoc = scsi_datain_unmarshall(rso_task);
CU_ASSERT_PTR_NOT_NULL_FATAL(rsoc); CU_ASSERT_PTR_NOT_NULL_FATAL(rsoc);
usage_data_dpofua = rsoc->cdb_usage_data[1] & 0x18; usage_data_dpofua = rsoc->cdb_usage_data[1] & 0x18;
if (dpofua) { if (dpofua) {
@@ -122,5 +122,5 @@ test_read12_dpofua(void)
} }
} }
scsi_free_scsi_task(rso_task); scsi_free_scsi_task(rso_task);
} }

View File

@@ -29,25 +29,25 @@
void void
test_read12_rdprotect(void) test_read12_rdprotect(void)
{ {
int i; int i;
/* /*
* Try out different non-zero values for RDPROTECT. * Try out different non-zero values for RDPROTECT.
*/ */
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test READ12 with non-zero RDPROTECT"); logging(LOG_VERBOSE, "Test READ12 with non-zero RDPROTECT");
CHECK_FOR_SBC; CHECK_FOR_SBC;
if (!inq->protect || (rc16 != NULL && !rc16->prot_en)) { if (!inq->protect || (rc16 != NULL && !rc16->prot_en)) {
logging(LOG_VERBOSE, "Device does not support/use protection information. All commands should fail."); logging(LOG_VERBOSE, "Device does not support/use protection information. All commands should fail.");
for (i = 1; i < 8; i++) { for (i = 1; i < 8; i++) {
READ12(sd, NULL, 0, block_size, block_size, READ12(sd, NULL, 0, block_size, block_size,
i, 0, 0, 0, 0, NULL, i, 0, 0, 0, 0, NULL,
EXPECT_INVALID_FIELD_IN_CDB); EXPECT_INVALID_FIELD_IN_CDB);
} }
return; return;
} }
logging(LOG_NORMAL, "No tests for devices that support protection information yet."); logging(LOG_NORMAL, "No tests for devices that support protection information yet.");
} }

View File

@@ -31,212 +31,212 @@
void void
test_read12_residuals(void) test_read12_residuals(void)
{ {
struct scsi_task *task_ret; struct scsi_task *task_ret;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test READ12 commands with residuals"); logging(LOG_VERBOSE, "Test READ12 commands with residuals");
logging(LOG_VERBOSE, "Block size is %zu", block_size); logging(LOG_VERBOSE, "Block size is %zu", block_size);
if (sd->iscsi_ctx == NULL) { if (sd->iscsi_ctx == NULL) {
const char *err = "[SKIPPED] This READ12 test is only " const char *err = "[SKIPPED] This READ12 test is only "
"supported for iSCSI backends"; "supported for iSCSI backends";
logging(LOG_NORMAL, "%s", err); logging(LOG_NORMAL, "%s", err);
CU_PASS(err); CU_PASS(err);
return; return;
} }
task = malloc(sizeof(struct scsi_task)); task = malloc(sizeof(struct scsi_task));
CU_ASSERT_PTR_NOT_NULL_FATAL(task); CU_ASSERT_PTR_NOT_NULL_FATAL(task);
memset(task, 0, sizeof(struct scsi_task)); memset(task, 0, sizeof(struct scsi_task));
task->cdb[0] = SCSI_OPCODE_READ12; task->cdb[0] = SCSI_OPCODE_READ12;
task->cdb[9] = 1; task->cdb[9] = 1;
task->cdb_size = 12; task->cdb_size = 12;
task->xfer_dir = SCSI_XFER_READ; task->xfer_dir = SCSI_XFER_READ;
task->expxferlen = 0; task->expxferlen = 0;
/* /*
* we don't want autoreconnect since some targets will drop the session * we don't want autoreconnect since some targets will drop the session
* on this condition. * on this condition.
*/ */
iscsi_set_noautoreconnect(sd->iscsi_ctx, 1); iscsi_set_noautoreconnect(sd->iscsi_ctx, 1);
logging(LOG_VERBOSE, "Try reading one block but with iSCSI expected transfer length==0"); logging(LOG_VERBOSE, "Try reading one block but with iSCSI expected transfer length==0");
task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL); task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL);
CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret); CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret);
CU_ASSERT_NOT_EQUAL(task->status, SCSI_STATUS_CANCELLED); /* XXX redundant? */ CU_ASSERT_NOT_EQUAL(task->status, SCSI_STATUS_CANCELLED); /* XXX redundant? */
if (task->status == SCSI_STATUS_CHECK_CONDITION if (task->status == SCSI_STATUS_CHECK_CONDITION
&& task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST && task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST
&& task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE) { && task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE) {
logging(LOG_NORMAL, "[SKIPPED] READ12 is not implemented on this target."); logging(LOG_NORMAL, "[SKIPPED] READ12 is not implemented on this target.");
CU_PASS("READ12 is not implemented."); CU_PASS("READ12 is not implemented.");
return; return;
} }
logging(LOG_VERBOSE, "Verify that the target returned SUCCESS"); logging(LOG_VERBOSE, "Verify that the target returned SUCCESS");
if (task->status != SCSI_STATUS_GOOD) { if (task->status != SCSI_STATUS_GOOD) {
logging(LOG_VERBOSE, "[FAILED] Target returned error %s", logging(LOG_VERBOSE, "[FAILED] Target returned error %s",
iscsi_get_error(sd->iscsi_ctx)); iscsi_get_error(sd->iscsi_ctx));
} }
CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD); CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD);
logging(LOG_VERBOSE, "Verify residual overflow flag is set"); logging(LOG_VERBOSE, "Verify residual overflow flag is set");
if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) { if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) {
logging(LOG_VERBOSE, "[FAILED] Target did not set residual " logging(LOG_VERBOSE, "[FAILED] Target did not set residual "
"overflow flag"); "overflow flag");
} }
CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW); CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW);
logging(LOG_VERBOSE, "Verify we got %zu bytes of residual overflow", logging(LOG_VERBOSE, "Verify we got %zu bytes of residual overflow",
block_size); block_size);
if (task->residual != block_size) { if (task->residual != block_size) {
logging(LOG_VERBOSE, "[FAILED] Target did not set correct " logging(LOG_VERBOSE, "[FAILED] Target did not set correct "
"amount of residual. Expected %zu but got %zu.", "amount of residual. Expected %zu but got %zu.",
block_size, task->residual); block_size, task->residual);
} }
CU_ASSERT_EQUAL(task->residual, block_size); CU_ASSERT_EQUAL(task->residual, block_size);
scsi_free_scsi_task(task); scsi_free_scsi_task(task);
task = NULL; task = NULL;
/* in case the previous test failed the session */ /* in case the previous test failed the session */
iscsi_set_noautoreconnect(sd->iscsi_ctx, 0); iscsi_set_noautoreconnect(sd->iscsi_ctx, 0);
logging(LOG_VERBOSE, "Try reading one block but with iSCSI expected transfer length==10000"); logging(LOG_VERBOSE, "Try reading one block but with iSCSI expected transfer length==10000");
task = malloc(sizeof(struct scsi_task)); task = malloc(sizeof(struct scsi_task));
CU_ASSERT_PTR_NOT_NULL_FATAL(task); CU_ASSERT_PTR_NOT_NULL_FATAL(task);
memset(task, 0, sizeof(struct scsi_task)); memset(task, 0, sizeof(struct scsi_task));
task->cdb[0] = SCSI_OPCODE_READ12; task->cdb[0] = SCSI_OPCODE_READ12;
task->cdb[9] = 1; task->cdb[9] = 1;
task->cdb_size = 12; task->cdb_size = 12;
task->xfer_dir = SCSI_XFER_READ; task->xfer_dir = SCSI_XFER_READ;
task->expxferlen = 10000; task->expxferlen = 10000;
task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL); task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL);
CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret); CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret);
logging(LOG_VERBOSE, "Verify that the target returned SUCCESS"); logging(LOG_VERBOSE, "Verify that the target returned SUCCESS");
if (task->status != SCSI_STATUS_GOOD) { if (task->status != SCSI_STATUS_GOOD) {
logging(LOG_VERBOSE, "[FAILED] Target returned error %s", logging(LOG_VERBOSE, "[FAILED] Target returned error %s",
iscsi_get_error(sd->iscsi_ctx)); iscsi_get_error(sd->iscsi_ctx));
} }
CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD); CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD);
logging(LOG_VERBOSE, "Verify we got one whole block back from the target"); logging(LOG_VERBOSE, "Verify we got one whole block back from the target");
if (task->datain.size != (int)block_size) { if (task->datain.size != (int)block_size) {
logging(LOG_VERBOSE, "[FAILED] Target returned %u bytes " logging(LOG_VERBOSE, "[FAILED] Target returned %u bytes "
"of data but should have returned %zu bytes.", "of data but should have returned %zu bytes.",
task->datain.size,block_size); task->datain.size,block_size);
} }
CU_ASSERT_EQUAL(task->datain.size, (int)block_size); CU_ASSERT_EQUAL(task->datain.size, (int)block_size);
logging(LOG_VERBOSE, "Verify residual underflow flag is set"); logging(LOG_VERBOSE, "Verify residual underflow flag is set");
if (task->residual_status != SCSI_RESIDUAL_UNDERFLOW) { if (task->residual_status != SCSI_RESIDUAL_UNDERFLOW) {
logging(LOG_VERBOSE, "[FAILED] Target did not set residual " logging(LOG_VERBOSE, "[FAILED] Target did not set residual "
"underflow flag"); "underflow flag");
} }
CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_UNDERFLOW); CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_UNDERFLOW);
logging(LOG_VERBOSE, "Verify we got %zu bytes of residual underflow", logging(LOG_VERBOSE, "Verify we got %zu bytes of residual underflow",
10000 - block_size); 10000 - block_size);
if (task->residual != 10000 - block_size) { if (task->residual != 10000 - block_size) {
logging(LOG_VERBOSE, "[FAILED] Target did not set correct " logging(LOG_VERBOSE, "[FAILED] Target did not set correct "
"amount of residual. Expected %zu but got %zu.", "amount of residual. Expected %zu but got %zu.",
10000 - block_size, task->residual); 10000 - block_size, task->residual);
} }
CU_ASSERT_EQUAL(task->residual, 10000 - block_size); CU_ASSERT_EQUAL(task->residual, 10000 - block_size);
scsi_free_scsi_task(task); scsi_free_scsi_task(task);
task = NULL; task = NULL;
logging(LOG_VERBOSE, "Try reading one block but with iSCSI expected transfer length==200"); logging(LOG_VERBOSE, "Try reading one block but with iSCSI expected transfer length==200");
task = malloc(sizeof(struct scsi_task)); task = malloc(sizeof(struct scsi_task));
CU_ASSERT_PTR_NOT_NULL_FATAL(task); CU_ASSERT_PTR_NOT_NULL_FATAL(task);
memset(task, 0, sizeof(struct scsi_task)); memset(task, 0, sizeof(struct scsi_task));
task->cdb[0] = SCSI_OPCODE_READ12; task->cdb[0] = SCSI_OPCODE_READ12;
task->cdb[9] = 1; task->cdb[9] = 1;
task->cdb_size = 12; task->cdb_size = 12;
task->xfer_dir = SCSI_XFER_READ; task->xfer_dir = SCSI_XFER_READ;
task->expxferlen = 200; task->expxferlen = 200;
task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL); task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL);
CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret); CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret);
logging(LOG_VERBOSE, "Verify that the target returned SUCCESS"); logging(LOG_VERBOSE, "Verify that the target returned SUCCESS");
if (task->status != SCSI_STATUS_GOOD) { if (task->status != SCSI_STATUS_GOOD) {
logging(LOG_VERBOSE, "[FAILED] Target returned error %s", logging(LOG_VERBOSE, "[FAILED] Target returned error %s",
iscsi_get_error(sd->iscsi_ctx)); iscsi_get_error(sd->iscsi_ctx));
} }
CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD); CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD);
logging(LOG_VERBOSE, "Verify we got 200 bytes back from the target"); logging(LOG_VERBOSE, "Verify we got 200 bytes back from the target");
CU_ASSERT_EQUAL(task->datain.size, 200); CU_ASSERT_EQUAL(task->datain.size, 200);
logging(LOG_VERBOSE, "Verify residual overflow flag is set"); logging(LOG_VERBOSE, "Verify residual overflow flag is set");
if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) { if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) {
logging(LOG_VERBOSE, "[FAILED] Target did not set residual " logging(LOG_VERBOSE, "[FAILED] Target did not set residual "
"overflow flag"); "overflow flag");
} }
CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW); CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW);
logging(LOG_VERBOSE, "Verify we got %zu bytes of residual overflow", logging(LOG_VERBOSE, "Verify we got %zu bytes of residual overflow",
block_size - 200); block_size - 200);
if (task->residual != block_size - 200) { if (task->residual != block_size - 200) {
logging(LOG_VERBOSE, "[FAILED] Target did not set correct " logging(LOG_VERBOSE, "[FAILED] Target did not set correct "
"amount of residual. Expected %zu but got %zu.", "amount of residual. Expected %zu but got %zu.",
block_size - 200, task->residual); block_size - 200, task->residual);
} }
CU_ASSERT_EQUAL(task->residual, block_size - 200); CU_ASSERT_EQUAL(task->residual, block_size - 200);
scsi_free_scsi_task(task); scsi_free_scsi_task(task);
task = NULL; task = NULL;
logging(LOG_VERBOSE, "Try reading two blocks but iSCSI expected " logging(LOG_VERBOSE, "Try reading two blocks but iSCSI expected "
"transfer length==%zu (==one block)", block_size); "transfer length==%zu (==one block)", block_size);
task = malloc(sizeof(struct scsi_task)); task = malloc(sizeof(struct scsi_task));
CU_ASSERT_PTR_NOT_NULL_FATAL(task); CU_ASSERT_PTR_NOT_NULL_FATAL(task);
memset(task, 0, sizeof(struct scsi_task)); memset(task, 0, sizeof(struct scsi_task));
task->cdb[0] = SCSI_OPCODE_READ12; task->cdb[0] = SCSI_OPCODE_READ12;
task->cdb[9] = 2; task->cdb[9] = 2;
task->cdb_size = 12; task->cdb_size = 12;
task->xfer_dir = SCSI_XFER_READ; task->xfer_dir = SCSI_XFER_READ;
task->expxferlen = block_size; task->expxferlen = block_size;
task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL); task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL);
CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret); CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret);
logging(LOG_VERBOSE, "Verify that the target returned SUCCESS"); logging(LOG_VERBOSE, "Verify that the target returned SUCCESS");
if (task->status != SCSI_STATUS_GOOD) { if (task->status != SCSI_STATUS_GOOD) {
logging(LOG_VERBOSE, "[FAILED] Target returned error %s", logging(LOG_VERBOSE, "[FAILED] Target returned error %s",
iscsi_get_error(sd->iscsi_ctx)); iscsi_get_error(sd->iscsi_ctx));
} }
CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD); CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD);
logging(LOG_VERBOSE, "Verify we got one whole block back from the target"); logging(LOG_VERBOSE, "Verify we got one whole block back from the target");
CU_ASSERT_EQUAL(task->datain.size, (int)block_size); CU_ASSERT_EQUAL(task->datain.size, (int)block_size);
logging(LOG_VERBOSE, "Verify residual overflow flag is set"); logging(LOG_VERBOSE, "Verify residual overflow flag is set");
if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) { if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) {
logging(LOG_VERBOSE, "[FAILED] Target did not set residual " logging(LOG_VERBOSE, "[FAILED] Target did not set residual "
"overflow flag"); "overflow flag");
} }
CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW); CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW);
logging(LOG_VERBOSE, "Verify we got one block of residual overflow"); logging(LOG_VERBOSE, "Verify we got one block of residual overflow");
if (task->residual != block_size) { if (task->residual != block_size) {
logging(LOG_VERBOSE, "[FAILED] Target did not set correct " logging(LOG_VERBOSE, "[FAILED] Target did not set correct "
"amount of residual. Expected %zu but got %zu.", "amount of residual. Expected %zu but got %zu.",
block_size, task->residual); block_size, task->residual);
} }
CU_ASSERT_EQUAL(task->residual, block_size); CU_ASSERT_EQUAL(task->residual, block_size);
scsi_free_scsi_task(task); scsi_free_scsi_task(task);
task = NULL; task = NULL;
} }

View File

@@ -29,27 +29,27 @@
void void
test_read12_simple(void) test_read12_simple(void)
{ {
int i; int i;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test READ12 of 1-256 blocks at the start of the LUN"); logging(LOG_VERBOSE, "Test READ12 of 1-256 blocks at the start of the LUN");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
READ12(sd, NULL, 0, i * block_size, READ12(sd, NULL, 0, i * block_size,
block_size, 0, 0, 0, 0, 0, NULL, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }
logging(LOG_VERBOSE, "Test READ12 of 1-256 blocks at the end of the LUN"); logging(LOG_VERBOSE, "Test READ12 of 1-256 blocks at the end of the LUN");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
READ12(sd, NULL, num_blocks - i, READ12(sd, NULL, num_blocks - i,
i * block_size, block_size, 0, 0, 0, 0, 0, NULL, i * block_size, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }
} }

View File

@@ -27,23 +27,23 @@
void void
test_read16_0blocks(void) test_read16_0blocks(void)
{ {
CHECK_FOR_SBC; CHECK_FOR_SBC;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test READ16 0-blocks at LBA==0"); logging(LOG_VERBOSE, "Test READ16 0-blocks at LBA==0");
READ16(sd, NULL, 0, 0, block_size, 0, 0, 0, 0, 0, NULL, READ16(sd, NULL, 0, 0, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Test READ16 0-blocks one block past end-of-LUN"); logging(LOG_VERBOSE, "Test READ16 0-blocks one block past end-of-LUN");
READ16(sd, NULL, num_blocks + 1, 0, block_size, 0, 0, 0, 0, 0, NULL, READ16(sd, NULL, num_blocks + 1, 0, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
logging(LOG_VERBOSE, "Test READ16 0-blocks at LBA==2^63"); logging(LOG_VERBOSE, "Test READ16 0-blocks at LBA==2^63");
READ16(sd, NULL, 0x8000000000000000ULL, 0, READ16(sd, NULL, 0x8000000000000000ULL, 0,
block_size, 0, 0, 0, 0, 0, NULL, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
logging(LOG_VERBOSE, "Test READ16 0-blocks at LBA==-1"); logging(LOG_VERBOSE, "Test READ16 0-blocks at LBA==-1");
READ16(sd, NULL, -1, 0, block_size, 0, 0, 0, 0, 0, NULL, READ16(sd, NULL, -1, 0, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }

View File

@@ -27,82 +27,82 @@
static int ilog2(size_t i) static int ilog2(size_t i)
{ {
int j = -1; int j = -1;
while (i) { while (i) {
i >>= 1; i >>= 1;
j++; j++;
} }
return j; return j;
} }
void void
test_read16_beyond_eol(void) test_read16_beyond_eol(void)
{ {
int i; int i;
CHECK_FOR_SBC; CHECK_FOR_SBC;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test READ16 1-256 blocks one block beyond the end"); logging(LOG_VERBOSE, "Test READ16 1-256 blocks one block beyond the end");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
READ16(sd, NULL, num_blocks + 1 - i, READ16(sd, NULL, num_blocks + 1 - i,
i * block_size, block_size, 0, 0, 0, 0, 0, NULL, i * block_size, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }
logging(LOG_VERBOSE, "Test READ16 1-256 blocks at LBA==2^63"); logging(LOG_VERBOSE, "Test READ16 1-256 blocks at LBA==2^63");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
READ16(sd, NULL, 0x8000000000000000ULL, READ16(sd, NULL, 0x8000000000000000ULL,
i * block_size, block_size, 0, 0, 0, 0, 0, NULL, i * block_size, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }
logging(LOG_VERBOSE, "Test READ16 1-256 blocks at LBA==2^%d", logging(LOG_VERBOSE, "Test READ16 1-256 blocks at LBA==2^%d",
64 - ilog2(block_size)); 64 - ilog2(block_size));
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
READ16(sd, NULL, 1ULL << (64 - ilog2(block_size)), READ16(sd, NULL, 1ULL << (64 - ilog2(block_size)),
i * block_size, block_size, 0, 0, 0, 0, 0, NULL, i * block_size, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }
logging(LOG_VERBOSE, "Test READ16 1-256 blocks at LBA==2^%d", logging(LOG_VERBOSE, "Test READ16 1-256 blocks at LBA==2^%d",
63 - ilog2(block_size)); 63 - ilog2(block_size));
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
READ16(sd, NULL, 1ULL << (63 - ilog2(block_size)), READ16(sd, NULL, 1ULL << (63 - ilog2(block_size)),
i * block_size, block_size, 0, 0, 0, 0, 0, NULL, i * block_size, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }
logging(LOG_VERBOSE, "Test READ16 1-256 blocks at LBA==-1"); logging(LOG_VERBOSE, "Test READ16 1-256 blocks at LBA==-1");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
READ16(sd, NULL, -1, i * block_size, READ16(sd, NULL, -1, i * block_size,
block_size, 0, 0, 0, 0, 0, NULL, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }
logging(LOG_VERBOSE, "Test READ16 2-256 blocks all but one block beyond the end"); logging(LOG_VERBOSE, "Test READ16 2-256 blocks all but one block beyond the end");
for (i = 2; i <= 256; i++) { for (i = 2; i <= 256; i++) {
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
READ16(sd, NULL, num_blocks - 1, READ16(sd, NULL, num_blocks - 1,
i * block_size, block_size, 0, 0, 0, 0, 0, NULL, i * block_size, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }
} }

View File

@@ -29,73 +29,73 @@
void void
test_read16_dpofua(void) test_read16_dpofua(void)
{ {
int dpofua, usage_data_dpofua; int dpofua, usage_data_dpofua;
struct scsi_task *ms_task = NULL; struct scsi_task *ms_task = NULL;
struct scsi_mode_sense *ms; struct scsi_mode_sense *ms;
struct scsi_task *rso_task = NULL; struct scsi_task *rso_task = NULL;
struct scsi_report_supported_op_codes_one_command *rsoc; struct scsi_report_supported_op_codes_one_command *rsoc;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test READ16 DPO/FUA flags"); logging(LOG_VERBOSE, "Test READ16 DPO/FUA flags");
CHECK_FOR_SBC; CHECK_FOR_SBC;
logging(LOG_VERBOSE, "Read the DPOFUA flag from mode sense data"); logging(LOG_VERBOSE, "Read the DPOFUA flag from mode sense data");
MODESENSE6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT, MODESENSE6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT,
SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255, SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "[SUCCESS] Mode sense returned status GOOD"); logging(LOG_VERBOSE, "[SUCCESS] Mode sense returned status GOOD");
ms = scsi_datain_unmarshall(ms_task); ms = scsi_datain_unmarshall(ms_task);
dpofua = ms && (ms->device_specific_parameter & 0x10); dpofua = ms && (ms->device_specific_parameter & 0x10);
scsi_free_scsi_task(ms_task); scsi_free_scsi_task(ms_task);
if (dpofua) { if (dpofua) {
logging(LOG_VERBOSE, "DPOFUA flag is set. Device should allow " logging(LOG_VERBOSE, "DPOFUA flag is set. Device should allow "
"DPO/FUA flags in CDBs"); "DPO/FUA flags in CDBs");
} else { } else {
logging(LOG_VERBOSE, "DPOFUA flag is clear. Device should fail " logging(LOG_VERBOSE, "DPOFUA flag is clear. Device should fail "
"CDBs with DPO/FUA set"); "CDBs with DPO/FUA set");
} }
logging(LOG_VERBOSE, "Test READ16 with DPO==1"); logging(LOG_VERBOSE, "Test READ16 with DPO==1");
if (dpofua) { if (dpofua) {
READ16(sd, NULL, 0, block_size, block_size, 0, 1, 0, 0, 0, NULL, READ16(sd, NULL, 0, block_size, block_size, 0, 1, 0, 0, 0, NULL,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} else { } else {
READ16(sd, NULL, 0, block_size, block_size, 0, 1, 0, 0, 0, NULL, READ16(sd, NULL, 0, block_size, block_size, 0, 1, 0, 0, 0, NULL,
EXPECT_INVALID_FIELD_IN_CDB); EXPECT_INVALID_FIELD_IN_CDB);
} }
logging(LOG_VERBOSE, "Test READ16 with FUA==1"); logging(LOG_VERBOSE, "Test READ16 with FUA==1");
if (dpofua) { if (dpofua) {
READ16(sd, NULL, 0, block_size, block_size, 0, 0, 1, 0, 0, NULL, READ16(sd, NULL, 0, block_size, block_size, 0, 0, 1, 0, 0, NULL,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} else { } else {
READ16(sd, NULL, 0, block_size, block_size, 0, 0, 1, 0, 0, NULL, READ16(sd, NULL, 0, block_size, block_size, 0, 0, 1, 0, 0, NULL,
EXPECT_INVALID_FIELD_IN_CDB); EXPECT_INVALID_FIELD_IN_CDB);
} }
logging(LOG_VERBOSE, "Test READ16 with DPO==1 FUA==1"); logging(LOG_VERBOSE, "Test READ16 with DPO==1 FUA==1");
if (dpofua) { if (dpofua) {
READ16(sd, NULL, 0, block_size, block_size, 0, 1, 1, 0, 0, NULL, READ16(sd, NULL, 0, block_size, block_size, 0, 1, 1, 0, 0, NULL,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} else { } else {
READ16(sd, NULL, 0, block_size, block_size, 0, 1, 1, 0, 0, NULL, READ16(sd, NULL, 0, block_size, block_size, 0, 1, 1, 0, 0, NULL,
EXPECT_INVALID_FIELD_IN_CDB); EXPECT_INVALID_FIELD_IN_CDB);
} }
logging(LOG_VERBOSE, "Try fetching REPORT_SUPPORTED_OPCODES " logging(LOG_VERBOSE, "Try fetching REPORT_SUPPORTED_OPCODES "
"for READ16"); "for READ16");
REPORT_SUPPORTED_OPCODES(sd, &rso_task, REPORT_SUPPORTED_OPCODES(sd, &rso_task,
0, SCSI_REPORT_SUPPORTING_OPCODE, 0, SCSI_REPORT_SUPPORTING_OPCODE,
SCSI_OPCODE_READ16, SCSI_OPCODE_READ16,
0, 0,
65535, 65535,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer"); logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer");
rsoc = scsi_datain_unmarshall(rso_task); rsoc = scsi_datain_unmarshall(rso_task);
CU_ASSERT_PTR_NOT_NULL_FATAL(rsoc); CU_ASSERT_PTR_NOT_NULL_FATAL(rsoc);
usage_data_dpofua = rsoc->cdb_usage_data[1] & 0x18; usage_data_dpofua = rsoc->cdb_usage_data[1] & 0x18;
if (dpofua) { if (dpofua) {
@@ -116,5 +116,5 @@ test_read16_dpofua(void)
} }
} }
scsi_free_scsi_task(rso_task); scsi_free_scsi_task(rso_task);
} }

View File

@@ -29,24 +29,24 @@
void void
test_read16_rdprotect(void) test_read16_rdprotect(void)
{ {
int i; int i;
/* /*
* Try out different non-zero values for RDPROTECT. * Try out different non-zero values for RDPROTECT.
*/ */
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test READ16 with non-zero RDPROTECT"); logging(LOG_VERBOSE, "Test READ16 with non-zero RDPROTECT");
CHECK_FOR_SBC; CHECK_FOR_SBC;
if (!inq->protect || (rc16 != NULL && !rc16->prot_en)) { if (!inq->protect || (rc16 != NULL && !rc16->prot_en)) {
logging(LOG_VERBOSE, "Device does not support/use protection information. All commands should fail."); logging(LOG_VERBOSE, "Device does not support/use protection information. All commands should fail.");
for (i = 1; i < 8; i++) { for (i = 1; i < 8; i++) {
READ16(sd, NULL, 0, block_size, block_size, READ16(sd, NULL, 0, block_size, block_size,
i, 0, 0, 0, 0, NULL, i, 0, 0, 0, 0, NULL,
EXPECT_INVALID_FIELD_IN_CDB); EXPECT_INVALID_FIELD_IN_CDB);
} }
return; return;
} }
logging(LOG_NORMAL, "No tests for devices that support protection information yet."); logging(LOG_NORMAL, "No tests for devices that support protection information yet.");
} }

View File

@@ -31,212 +31,212 @@
void void
test_read16_residuals(void) test_read16_residuals(void)
{ {
struct scsi_task *task_ret; struct scsi_task *task_ret;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test READ16 commands with residuals"); logging(LOG_VERBOSE, "Test READ16 commands with residuals");
logging(LOG_VERBOSE, "Block size is %zu", block_size); logging(LOG_VERBOSE, "Block size is %zu", block_size);
if (sd->iscsi_ctx == NULL) { if (sd->iscsi_ctx == NULL) {
const char *err = "[SKIPPED] This READ16 test is only " const char *err = "[SKIPPED] This READ16 test is only "
"supported for iSCSI backends"; "supported for iSCSI backends";
logging(LOG_NORMAL, "%s", err); logging(LOG_NORMAL, "%s", err);
CU_PASS(err); CU_PASS(err);
return; return;
} }
task = malloc(sizeof(struct scsi_task)); task = malloc(sizeof(struct scsi_task));
CU_ASSERT_PTR_NOT_NULL_FATAL(task); CU_ASSERT_PTR_NOT_NULL_FATAL(task);
memset(task, 0, sizeof(struct scsi_task)); memset(task, 0, sizeof(struct scsi_task));
task->cdb[0] = SCSI_OPCODE_READ16; task->cdb[0] = SCSI_OPCODE_READ16;
task->cdb[13] = 1; task->cdb[13] = 1;
task->cdb_size = 16; task->cdb_size = 16;
task->xfer_dir = SCSI_XFER_READ; task->xfer_dir = SCSI_XFER_READ;
task->expxferlen = 0; task->expxferlen = 0;
/* /*
* we don't want autoreconnect since some targets will drop the session * we don't want autoreconnect since some targets will drop the session
* on this condition. * on this condition.
*/ */
iscsi_set_noautoreconnect(sd->iscsi_ctx, 1); iscsi_set_noautoreconnect(sd->iscsi_ctx, 1);
logging(LOG_VERBOSE, "Try reading one block but with iSCSI expected transfer length==0"); logging(LOG_VERBOSE, "Try reading one block but with iSCSI expected transfer length==0");
task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL); task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL);
CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret); CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret);
CU_ASSERT_NOT_EQUAL(task->status, SCSI_STATUS_CANCELLED); /* XXX redundant? */ CU_ASSERT_NOT_EQUAL(task->status, SCSI_STATUS_CANCELLED); /* XXX redundant? */
if (task->status == SCSI_STATUS_CHECK_CONDITION if (task->status == SCSI_STATUS_CHECK_CONDITION
&& task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST && task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST
&& task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE) { && task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE) {
logging(LOG_NORMAL, "[SKIPPED] READ16 is not implemented on this target and it does not claim SBC-3 support."); logging(LOG_NORMAL, "[SKIPPED] READ16 is not implemented on this target and it does not claim SBC-3 support.");
CU_PASS("READ16 is not implemented and no SBC-3 support claimed."); CU_PASS("READ16 is not implemented and no SBC-3 support claimed.");
return; return;
} }
logging(LOG_VERBOSE, "Verify that the target returned SUCCESS"); logging(LOG_VERBOSE, "Verify that the target returned SUCCESS");
if (task->status != SCSI_STATUS_GOOD) { if (task->status != SCSI_STATUS_GOOD) {
logging(LOG_VERBOSE, "[FAILED] Target returned error %s", logging(LOG_VERBOSE, "[FAILED] Target returned error %s",
iscsi_get_error(sd->iscsi_ctx)); iscsi_get_error(sd->iscsi_ctx));
} }
CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD); CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD);
logging(LOG_VERBOSE, "Verify residual overflow flag is set"); logging(LOG_VERBOSE, "Verify residual overflow flag is set");
if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) { if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) {
logging(LOG_VERBOSE, "[FAILED] Target did not set residual " logging(LOG_VERBOSE, "[FAILED] Target did not set residual "
"overflow flag"); "overflow flag");
} }
CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW); CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW);
logging(LOG_VERBOSE, "Verify we got %zu bytes of residual overflow", logging(LOG_VERBOSE, "Verify we got %zu bytes of residual overflow",
block_size); block_size);
if (task->residual != block_size) { if (task->residual != block_size) {
logging(LOG_VERBOSE, "[FAILED] Target did not set correct " logging(LOG_VERBOSE, "[FAILED] Target did not set correct "
"amount of residual. Expected %zu but got %zu.", "amount of residual. Expected %zu but got %zu.",
block_size, task->residual); block_size, task->residual);
} }
CU_ASSERT_EQUAL(task->residual, block_size); CU_ASSERT_EQUAL(task->residual, block_size);
scsi_free_scsi_task(task); scsi_free_scsi_task(task);
task = NULL; task = NULL;
/* in case the previous test failed the session */ /* in case the previous test failed the session */
iscsi_set_noautoreconnect(sd->iscsi_ctx, 0); iscsi_set_noautoreconnect(sd->iscsi_ctx, 0);
logging(LOG_VERBOSE, "Try reading one block but with iSCSI expected transfer length==10000"); logging(LOG_VERBOSE, "Try reading one block but with iSCSI expected transfer length==10000");
task = malloc(sizeof(struct scsi_task)); task = malloc(sizeof(struct scsi_task));
CU_ASSERT_PTR_NOT_NULL_FATAL(task); CU_ASSERT_PTR_NOT_NULL_FATAL(task);
memset(task, 0, sizeof(struct scsi_task)); memset(task, 0, sizeof(struct scsi_task));
task->cdb[0] = SCSI_OPCODE_READ16; task->cdb[0] = SCSI_OPCODE_READ16;
task->cdb[13] = 1; task->cdb[13] = 1;
task->cdb_size = 16; task->cdb_size = 16;
task->xfer_dir = SCSI_XFER_READ; task->xfer_dir = SCSI_XFER_READ;
task->expxferlen = 10000; task->expxferlen = 10000;
task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL); task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL);
CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret); CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret);
logging(LOG_VERBOSE, "Verify that the target returned SUCCESS"); logging(LOG_VERBOSE, "Verify that the target returned SUCCESS");
if (task->status != SCSI_STATUS_GOOD) { if (task->status != SCSI_STATUS_GOOD) {
logging(LOG_VERBOSE, "[FAILED] Target returned error %s", logging(LOG_VERBOSE, "[FAILED] Target returned error %s",
iscsi_get_error(sd->iscsi_ctx)); iscsi_get_error(sd->iscsi_ctx));
} }
CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD); CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD);
logging(LOG_VERBOSE, "Verify we got one whole block back from the target"); logging(LOG_VERBOSE, "Verify we got one whole block back from the target");
if (task->datain.size != (int)block_size) { if (task->datain.size != (int)block_size) {
logging(LOG_VERBOSE, "[FAILED] Target returned %u bytes " logging(LOG_VERBOSE, "[FAILED] Target returned %u bytes "
"of data but should have returned %zu bytes.", "of data but should have returned %zu bytes.",
task->datain.size,block_size); task->datain.size,block_size);
} }
CU_ASSERT_EQUAL(task->datain.size, (int)block_size); CU_ASSERT_EQUAL(task->datain.size, (int)block_size);
logging(LOG_VERBOSE, "Verify residual underflow flag is set"); logging(LOG_VERBOSE, "Verify residual underflow flag is set");
if (task->residual_status != SCSI_RESIDUAL_UNDERFLOW) { if (task->residual_status != SCSI_RESIDUAL_UNDERFLOW) {
logging(LOG_VERBOSE, "[FAILED] Target did not set residual " logging(LOG_VERBOSE, "[FAILED] Target did not set residual "
"underflow flag"); "underflow flag");
} }
CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_UNDERFLOW); CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_UNDERFLOW);
logging(LOG_VERBOSE, "Verify we got %zu bytes of residual underflow", logging(LOG_VERBOSE, "Verify we got %zu bytes of residual underflow",
10000 - block_size); 10000 - block_size);
if (task->residual != 10000 - block_size) { if (task->residual != 10000 - block_size) {
logging(LOG_VERBOSE, "[FAILED] Target did not set correct " logging(LOG_VERBOSE, "[FAILED] Target did not set correct "
"amount of residual. Expected %zu but got %zu.", "amount of residual. Expected %zu but got %zu.",
10000 - block_size, task->residual); 10000 - block_size, task->residual);
} }
CU_ASSERT_EQUAL(task->residual, 10000 - block_size); CU_ASSERT_EQUAL(task->residual, 10000 - block_size);
scsi_free_scsi_task(task); scsi_free_scsi_task(task);
task = NULL; task = NULL;
logging(LOG_VERBOSE, "Try reading one block but with iSCSI expected transfer length==200"); logging(LOG_VERBOSE, "Try reading one block but with iSCSI expected transfer length==200");
task = malloc(sizeof(struct scsi_task)); task = malloc(sizeof(struct scsi_task));
CU_ASSERT_PTR_NOT_NULL_FATAL(task); CU_ASSERT_PTR_NOT_NULL_FATAL(task);
memset(task, 0, sizeof(struct scsi_task)); memset(task, 0, sizeof(struct scsi_task));
task->cdb[0] = SCSI_OPCODE_READ16; task->cdb[0] = SCSI_OPCODE_READ16;
task->cdb[13] = 1; task->cdb[13] = 1;
task->cdb_size = 16; task->cdb_size = 16;
task->xfer_dir = SCSI_XFER_READ; task->xfer_dir = SCSI_XFER_READ;
task->expxferlen = 200; task->expxferlen = 200;
task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL); task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL);
CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret); CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret);
logging(LOG_VERBOSE, "Verify that the target returned SUCCESS"); logging(LOG_VERBOSE, "Verify that the target returned SUCCESS");
if (task->status != SCSI_STATUS_GOOD) { if (task->status != SCSI_STATUS_GOOD) {
logging(LOG_VERBOSE, "[FAILED] Target returned error %s", logging(LOG_VERBOSE, "[FAILED] Target returned error %s",
iscsi_get_error(sd->iscsi_ctx)); iscsi_get_error(sd->iscsi_ctx));
} }
CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD); CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD);
logging(LOG_VERBOSE, "Verify we got 200 bytes back from the target"); logging(LOG_VERBOSE, "Verify we got 200 bytes back from the target");
CU_ASSERT_EQUAL(task->datain.size, 200); CU_ASSERT_EQUAL(task->datain.size, 200);
logging(LOG_VERBOSE, "Verify residual overflow flag is set"); logging(LOG_VERBOSE, "Verify residual overflow flag is set");
if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) { if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) {
logging(LOG_VERBOSE, "[FAILED] Target did not set residual " logging(LOG_VERBOSE, "[FAILED] Target did not set residual "
"overflow flag"); "overflow flag");
} }
CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW); CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW);
logging(LOG_VERBOSE, "Verify we got %zu bytes of residual overflow", logging(LOG_VERBOSE, "Verify we got %zu bytes of residual overflow",
block_size - 200); block_size - 200);
if (task->residual != block_size - 200) { if (task->residual != block_size - 200) {
logging(LOG_VERBOSE, "[FAILED] Target did not set correct " logging(LOG_VERBOSE, "[FAILED] Target did not set correct "
"amount of residual. Expected %zu but got %zu.", "amount of residual. Expected %zu but got %zu.",
block_size - 200, task->residual); block_size - 200, task->residual);
} }
CU_ASSERT_EQUAL(task->residual, block_size - 200); CU_ASSERT_EQUAL(task->residual, block_size - 200);
scsi_free_scsi_task(task); scsi_free_scsi_task(task);
task = NULL; task = NULL;
logging(LOG_VERBOSE, "Try reading two blocks but iSCSI expected " logging(LOG_VERBOSE, "Try reading two blocks but iSCSI expected "
"transfer length==%zu (==one block)", block_size); "transfer length==%zu (==one block)", block_size);
task = malloc(sizeof(struct scsi_task)); task = malloc(sizeof(struct scsi_task));
CU_ASSERT_PTR_NOT_NULL_FATAL(task); CU_ASSERT_PTR_NOT_NULL_FATAL(task);
memset(task, 0, sizeof(struct scsi_task)); memset(task, 0, sizeof(struct scsi_task));
task->cdb[0] = SCSI_OPCODE_READ16; task->cdb[0] = SCSI_OPCODE_READ16;
task->cdb[13] = 2; task->cdb[13] = 2;
task->cdb_size = 16; task->cdb_size = 16;
task->xfer_dir = SCSI_XFER_READ; task->xfer_dir = SCSI_XFER_READ;
task->expxferlen = block_size; task->expxferlen = block_size;
task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL); task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_lun, task, NULL);
CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret); CU_ASSERT_PTR_NOT_NULL_FATAL(task_ret);
logging(LOG_VERBOSE, "Verify that the target returned SUCCESS"); logging(LOG_VERBOSE, "Verify that the target returned SUCCESS");
if (task->status != SCSI_STATUS_GOOD) { if (task->status != SCSI_STATUS_GOOD) {
logging(LOG_VERBOSE, "[FAILED] Target returned error %s", logging(LOG_VERBOSE, "[FAILED] Target returned error %s",
iscsi_get_error(sd->iscsi_ctx)); iscsi_get_error(sd->iscsi_ctx));
} }
CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD); CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD);
logging(LOG_VERBOSE, "Verify we got one whole block back from the target"); logging(LOG_VERBOSE, "Verify we got one whole block back from the target");
CU_ASSERT_EQUAL(task->datain.size, (int)block_size); CU_ASSERT_EQUAL(task->datain.size, (int)block_size);
logging(LOG_VERBOSE, "Verify residual overflow flag is set"); logging(LOG_VERBOSE, "Verify residual overflow flag is set");
if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) { if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) {
logging(LOG_VERBOSE, "[FAILED] Target did not set residual " logging(LOG_VERBOSE, "[FAILED] Target did not set residual "
"overflow flag"); "overflow flag");
} }
CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW); CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW);
logging(LOG_VERBOSE, "Verify we got one block of residual overflow"); logging(LOG_VERBOSE, "Verify we got one block of residual overflow");
if (task->residual != block_size) { if (task->residual != block_size) {
logging(LOG_VERBOSE, "[FAILED] Target did not set correct " logging(LOG_VERBOSE, "[FAILED] Target did not set correct "
"amount of residual. Expected %zu but got %zu.", "amount of residual. Expected %zu but got %zu.",
block_size, task->residual); block_size, task->residual);
} }
CU_ASSERT_EQUAL(task->residual, block_size); CU_ASSERT_EQUAL(task->residual, block_size);
scsi_free_scsi_task(task); scsi_free_scsi_task(task);
task = NULL; task = NULL;
} }

View File

@@ -29,29 +29,29 @@
void void
test_read16_simple(void) test_read16_simple(void)
{ {
int i; int i;
CHECK_FOR_SBC; CHECK_FOR_SBC;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test READ16 of 1-256 blocks at the start of the LUN"); logging(LOG_VERBOSE, "Test READ16 of 1-256 blocks at the start of the LUN");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
READ16(sd, NULL, 0, i * block_size, READ16(sd, NULL, 0, i * block_size,
block_size, 0, 0, 0, 0, 0, NULL, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }
logging(LOG_VERBOSE, "Test READ16 of 1-256 blocks at the end of the LUN"); logging(LOG_VERBOSE, "Test READ16 of 1-256 blocks at the end of the LUN");
for (i = 1; i <= 256; i++) { for (i = 1; i <= 256; i++) {
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
READ16(sd, NULL, num_blocks - i, READ16(sd, NULL, num_blocks - i,
i * block_size, block_size, 0, 0, 0, 0, 0, NULL, i * block_size, block_size, 0, 0, 0, 0, 0, NULL,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }
} }

View File

@@ -28,36 +28,36 @@
void void
test_read6_beyond_eol(void) test_read6_beyond_eol(void)
{ {
int i; int i;
if (num_blocks > 0x1fffff) { if (num_blocks > 0x1fffff) {
CU_PASS("LUN is too big for read-beyond-eol tests with READ6. Skipping test.\n"); CU_PASS("LUN is too big for read-beyond-eol tests with READ6. Skipping test.\n");
return; return;
} }
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test READ6 1-255 blocks one block beyond the end"); logging(LOG_VERBOSE, "Test READ6 1-255 blocks one block beyond the end");
for (i = 1; i <= 255 && i + 0U <= num_blocks + 1; i++) { for (i = 1; i <= 255 && i + 0U <= num_blocks + 1; i++) {
READ6(sd, NULL, num_blocks + 1 - i, READ6(sd, NULL, num_blocks + 1 - i,
i * block_size, block_size, NULL, i * block_size, block_size, NULL,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }
logging(LOG_VERBOSE, "Test READ6 1-255 blocks at LBA==0x1fffff"); logging(LOG_VERBOSE, "Test READ6 1-255 blocks at LBA==0x1fffff");
for (i = 1; i <= 255; i++) { for (i = 1; i <= 255; i++) {
READ6(sd, NULL, 0x1fffff, i * block_size, block_size, NULL, READ6(sd, NULL, 0x1fffff, i * block_size, block_size, NULL,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }
if (num_blocks == 0) { if (num_blocks == 0) {
CU_PASS("LUN is too small for read-beyond-eol tests with READ6. Skipping test.\n"); CU_PASS("LUN is too small for read-beyond-eol tests with READ6. Skipping test.\n");
return; return;
} }
logging(LOG_VERBOSE, "Test READ6 2-255 blocks all but one block beyond the end"); logging(LOG_VERBOSE, "Test READ6 2-255 blocks all but one block beyond the end");
for (i = 2; i <= 255; i++) { for (i = 2; i <= 255; i++) {
READ6(sd, NULL, num_blocks - 1, READ6(sd, NULL, num_blocks - 1,
i * block_size, block_size, NULL, i * block_size, block_size, NULL,
EXPECT_LBA_OOB); EXPECT_LBA_OOB);
} }
} }

View File

@@ -29,54 +29,54 @@
void void
test_read6_simple(void) test_read6_simple(void)
{ {
int i; int i;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test READ6 of 1-255 blocks at the start of the LUN"); logging(LOG_VERBOSE, "Test READ6 of 1-255 blocks at the start of the LUN");
for (i = 1; i <= 255; i++) { for (i = 1; i <= 255; i++) {
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
READ6(sd, NULL, 0, i * block_size, block_size, NULL, READ6(sd, NULL, 0, i * block_size, block_size, NULL,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }
logging(LOG_VERBOSE, "Test READ6 of 1-255 blocks at the end of the LUN"); logging(LOG_VERBOSE, "Test READ6 of 1-255 blocks at the end of the LUN");
if (num_blocks > 0x200000) { if (num_blocks > 0x200000) {
CU_PASS("LUN is too big for read-at-eol tests with READ6. Skipping test.\n"); CU_PASS("LUN is too big for read-at-eol tests with READ6. Skipping test.\n");
} else { } else {
for (i = 1; i <= 255 && i + 0U <= num_blocks; i++) { for (i = 1; i <= 255 && i + 0U <= num_blocks; i++) {
if (maximum_transfer_length && maximum_transfer_length < i) { if (maximum_transfer_length && maximum_transfer_length < i) {
break; break;
} }
READ6(sd, NULL, num_blocks - i, READ6(sd, NULL, num_blocks - i,
i * block_size, block_size, NULL, i * block_size, block_size, NULL,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }
} }
/* 256 is converted to 0 when the CDB is marshalled by the helper */ /* 256 is converted to 0 when the CDB is marshalled by the helper */
if (maximum_transfer_length >= 256) { if (maximum_transfer_length >= 256) {
logging(LOG_VERBOSE, "Transfer length == 0 means we want to " logging(LOG_VERBOSE, "Transfer length == 0 means we want to "
"transfer 256 blocks"); "transfer 256 blocks");
READ6(sd, &task, 0, READ6(sd, &task, 0,
256 * block_size, block_size, NULL, 256 * block_size, block_size, NULL,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
if (task->status != SCSI_STATUS_GOOD) { if (task->status != SCSI_STATUS_GOOD) {
logging(LOG_NORMAL, "[FAILED] READ6 command: " logging(LOG_NORMAL, "[FAILED] READ6 command: "
"failed with sense. %s", sd->error_str ); "failed with sense. %s", sd->error_str );
} }
CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD); CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD);
logging(LOG_VERBOSE, "Verify that we did get 256 blocks of " logging(LOG_VERBOSE, "Verify that we did get 256 blocks of "
"data back"); "data back");
if (task->datain.size == (int)(256 * block_size)) { if (task->datain.size == (int)(256 * block_size)) {
logging(LOG_VERBOSE, "[SUCCESS] Target returned 256 " logging(LOG_VERBOSE, "[SUCCESS] Target returned 256 "
"blocks of data"); "blocks of data");
} else { } else {
logging(LOG_NORMAL, "[FAILED] Target did not return " logging(LOG_NORMAL, "[FAILED] Target did not return "
"256 blocks of data"); "256 blocks of data");
} }
CU_ASSERT_EQUAL(task->datain.size, (int)(256 * block_size)); CU_ASSERT_EQUAL(task->datain.size, (int)(256 * block_size));
} }
} }

View File

@@ -29,9 +29,9 @@
void void
test_readcapacity10_simple(void) test_readcapacity10_simple(void)
{ {
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test basic READCAPACITY10"); logging(LOG_VERBOSE, "Test basic READCAPACITY10");
READCAPACITY10(sd, NULL, 0, 0, READCAPACITY10(sd, NULL, 0, 0,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }

View File

@@ -29,13 +29,13 @@
void void
test_readcapacity16_alloclen(void) test_readcapacity16_alloclen(void)
{ {
int i; int i;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test that READCAPACITY16 with alloc_len 0-15 is not an error"); logging(LOG_VERBOSE, "Test that READCAPACITY16 with alloc_len 0-15 is not an error");
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++) {
READCAPACITY16(sd, NULL, i, READCAPACITY16(sd, NULL, i,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }
} }

View File

@@ -29,95 +29,95 @@
void void
test_readcapacity16_protection(void) test_readcapacity16_protection(void)
{ {
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test READCAPACITY16 Protection Information"); logging(LOG_VERBOSE, "Test READCAPACITY16 Protection Information");
CHECK_FOR_SBC; CHECK_FOR_SBC;
if (rc16 == NULL) { if (rc16 == NULL) {
logging(LOG_NORMAL, "[SKIPPED] READCAPACITY16 is not implemented on this target."); logging(LOG_NORMAL, "[SKIPPED] READCAPACITY16 is not implemented on this target.");
CU_PASS("READCAPACITY16 is not implemented."); CU_PASS("READCAPACITY16 is not implemented.");
return; return;
} }
if (!inq->protect) { if (!inq->protect) {
logging(LOG_VERBOSE, "This device does not support PI. " logging(LOG_VERBOSE, "This device does not support PI. "
"Verify that all relevant fields in READCAPACITY16 " "Verify that all relevant fields in READCAPACITY16 "
"are 0"); "are 0");
logging(LOG_VERBOSE, "Verify that PROT_EN is 0"); logging(LOG_VERBOSE, "Verify that PROT_EN is 0");
if (rc16->prot_en) { if (rc16->prot_en) {
logging(LOG_VERBOSE, "[FAILED] PROT_EN is set but " logging(LOG_VERBOSE, "[FAILED] PROT_EN is set but "
"the device does not claim support for " "the device does not claim support for "
"protection information in the standard " "protection information in the standard "
"inquiry VPD."); "inquiry VPD.");
} else { } else {
logging(LOG_VERBOSE, "[SUCCESS] PROT_EN is 0"); logging(LOG_VERBOSE, "[SUCCESS] PROT_EN is 0");
} }
CU_ASSERT_EQUAL(rc16->prot_en, 0); CU_ASSERT_EQUAL(rc16->prot_en, 0);
logging(LOG_VERBOSE, "Verify that P_TYPE is 0"); logging(LOG_VERBOSE, "Verify that P_TYPE is 0");
if (rc16->p_type) { if (rc16->p_type) {
logging(LOG_VERBOSE, "[FAILED] P_TYPE is non-zero but " logging(LOG_VERBOSE, "[FAILED] P_TYPE is non-zero but "
"the device does not claim support for " "the device does not claim support for "
"protection information in the standard " "protection information in the standard "
"inquiry VPD."); "inquiry VPD.");
} else { } else {
logging(LOG_VERBOSE, "[SUCCESS] P_TYPE is 0"); logging(LOG_VERBOSE, "[SUCCESS] P_TYPE is 0");
} }
CU_ASSERT_EQUAL(rc16->p_type, 0); CU_ASSERT_EQUAL(rc16->p_type, 0);
logging(LOG_VERBOSE, "Verify that P_I_EXP is 0"); logging(LOG_VERBOSE, "Verify that P_I_EXP is 0");
if (rc16->p_i_exp) { if (rc16->p_i_exp) {
logging(LOG_VERBOSE, "[FAILED] P_I_EXP is non-zero but " logging(LOG_VERBOSE, "[FAILED] P_I_EXP is non-zero but "
"the device does not claim support for " "the device does not claim support for "
"protection information in the standard " "protection information in the standard "
"inquiry VPD."); "inquiry VPD.");
} else { } else {
logging(LOG_VERBOSE, "[SUCCESS] P_I_EXP is 0"); logging(LOG_VERBOSE, "[SUCCESS] P_I_EXP is 0");
} }
CU_ASSERT_EQUAL(rc16->p_i_exp, 0); CU_ASSERT_EQUAL(rc16->p_i_exp, 0);
return; return;
} }
logging(LOG_VERBOSE, "This device supports PI. " logging(LOG_VERBOSE, "This device supports PI. "
"Verify that all relevant fields are sane"); "Verify that all relevant fields are sane");
if (!rc16->prot_en) { if (!rc16->prot_en) {
logging(LOG_VERBOSE, "Protection is not enabled. Verify " logging(LOG_VERBOSE, "Protection is not enabled. Verify "
"that all relevant fields are zero"); "that all relevant fields are zero");
logging(LOG_VERBOSE, "Verify that P_TYPE is 0"); logging(LOG_VERBOSE, "Verify that P_TYPE is 0");
if (rc16->p_type) { if (rc16->p_type) {
logging(LOG_VERBOSE, "[FAILED] P_TYPE is non-zero but " logging(LOG_VERBOSE, "[FAILED] P_TYPE is non-zero but "
"protection information is not enabled."); "protection information is not enabled.");
} else { } else {
logging(LOG_VERBOSE, "[SUCCESS] P_TYPE is 0"); logging(LOG_VERBOSE, "[SUCCESS] P_TYPE is 0");
} }
CU_ASSERT_EQUAL(rc16->p_type, 0); CU_ASSERT_EQUAL(rc16->p_type, 0);
logging(LOG_VERBOSE, "Verify that P_I_EXP is 0"); logging(LOG_VERBOSE, "Verify that P_I_EXP is 0");
if (rc16->p_i_exp) { if (rc16->p_i_exp) {
logging(LOG_VERBOSE, "[FAILED] P_I_EXP is non-zero but " logging(LOG_VERBOSE, "[FAILED] P_I_EXP is non-zero but "
"protection information is not enabled"); "protection information is not enabled");
} else { } else {
logging(LOG_VERBOSE, "[SUCCESS] P_I_EXP is 0"); logging(LOG_VERBOSE, "[SUCCESS] P_I_EXP is 0");
} }
CU_ASSERT_EQUAL(rc16->p_i_exp, 0); CU_ASSERT_EQUAL(rc16->p_i_exp, 0);
return; return;
} }
logging(LOG_VERBOSE, "Protection is enabled. Verify " logging(LOG_VERBOSE, "Protection is enabled. Verify "
"that all relevant fields are sane"); "that all relevant fields are sane");
switch (rc16->p_type) { switch (rc16->p_type) {
case 0: case 0:
case 1: case 1:
case 2: case 2:
break; break;
default: default:
logging(LOG_VERBOSE, "[FAILED] P_TYPE is invalid. Must be " logging(LOG_VERBOSE, "[FAILED] P_TYPE is invalid. Must be "
"0,1,2 but was %d", rc16->p_type); "0,1,2 but was %d", rc16->p_type);
CU_FAIL("P_TYPE is invalid"); CU_FAIL("P_TYPE is invalid");
} }
} }

View File

@@ -29,9 +29,9 @@
void void
test_readcapacity16_simple(void) test_readcapacity16_simple(void)
{ {
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test that READCAPACITY16 works"); logging(LOG_VERBOSE, "Test that READCAPACITY16 works");
READCAPACITY16(sd, NULL, 16, READCAPACITY16(sd, NULL, 16,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }

View File

@@ -31,19 +31,19 @@ test_readcapacity16_support(void)
{ {
int ret; int ret;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test that READCAPACITY16 is supported on SBC3"); logging(LOG_VERBOSE, "Test that READCAPACITY16 is supported on SBC3");
ret = readcapacity16(sd, NULL, 15, ret = readcapacity16(sd, NULL, 15,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
if (ret == -2) { if (ret == -2) {
if (sbc3_support) { if (sbc3_support) {
logging(LOG_NORMAL, "[FAILED] READCAPACITY16 is not available but the device claims SBC-3 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."); CU_FAIL("READCAPACITY16 failed but the device claims SBC-3 support.");
} else { } else {
logging(LOG_NORMAL, "[SKIPPED] READCAPACITY16 is not implemented on this target and it does not claim SBC-3 support."); logging(LOG_NORMAL, "[SKIPPED] READCAPACITY16 is not implemented on this target and it does not claim SBC-3 support.");
} }
} else { } else {
CU_ASSERT_EQUAL(ret, 0); CU_ASSERT_EQUAL(ret, 0);
} }
} }

View File

@@ -28,38 +28,38 @@
static void static void
test_write10(void) test_write10(void)
{ {
logging(LOG_VERBOSE, "Test WRITE10 fails with WRITE_PROTECTED"); logging(LOG_VERBOSE, "Test WRITE10 fails with WRITE_PROTECTED");
memset(scratch, 0xa6, block_size); memset(scratch, 0xa6, block_size);
WRITE10(sd, 0, block_size, block_size, 0, 0, 0, 0, 0, scratch, WRITE10(sd, 0, block_size, block_size, 0, 0, 0, 0, 0, scratch,
EXPECT_WRITE_PROTECTED); EXPECT_WRITE_PROTECTED);
} }
static void static void
test_write12(void) test_write12(void)
{ {
logging(LOG_VERBOSE, "Test WRITE12 fails with WRITE_PROTECTED"); logging(LOG_VERBOSE, "Test WRITE12 fails with WRITE_PROTECTED");
memset(scratch, 0xa6, block_size); memset(scratch, 0xa6, block_size);
WRITE12(sd, 0, block_size, block_size, 0, 0, 0, 0, 0, scratch, WRITE12(sd, 0, block_size, block_size, 0, 0, 0, 0, 0, scratch,
EXPECT_WRITE_PROTECTED); EXPECT_WRITE_PROTECTED);
} }
static void static void
test_write16(void) test_write16(void)
{ {
logging(LOG_VERBOSE, "Test WRITE16 fails with WRITE_PROTECTED"); logging(LOG_VERBOSE, "Test WRITE16 fails with WRITE_PROTECTED");
memset(scratch, 0xa6, block_size); memset(scratch, 0xa6, block_size);
WRITE16(sd, 0, block_size, block_size, 0, 0, 0, 0, 0, scratch, WRITE16(sd, 0, block_size, block_size, 0, 0, 0, 0, 0, scratch,
EXPECT_WRITE_PROTECTED); EXPECT_WRITE_PROTECTED);
} }
static void static void
test_writesame10(void) test_writesame10(void)
{ {
logging(LOG_VERBOSE, "Test WRITE_SAME10 fails with WRITE_PROTECTED"); logging(LOG_VERBOSE, "Test WRITE_SAME10 fails with WRITE_PROTECTED");
WRITESAME10(sd, 0, block_size, 1, 0, 0, 0, 0, scratch, WRITESAME10(sd, 0, block_size, 1, 0, 0, 0, 0, scratch,
EXPECT_WRITE_PROTECTED); EXPECT_WRITE_PROTECTED);
logging(LOG_VERBOSE, "Test WRITE_SAME10 UNMAP fails with " logging(LOG_VERBOSE, "Test WRITE_SAME10 UNMAP fails with "
"WRITE_PROTECTED"); "WRITE_PROTECTED");
WRITESAME10(sd, 0, block_size, 1, 0, 1, 0, 0, NULL, WRITESAME10(sd, 0, block_size, 1, 0, 1, 0, 0, NULL,
EXPECT_WRITE_PROTECTED); EXPECT_WRITE_PROTECTED);
@@ -68,11 +68,11 @@ test_writesame10(void)
static void static void
test_writesame16(void) test_writesame16(void)
{ {
logging(LOG_VERBOSE, "Test WRITE_SAME16 fails with WRITE_PROTECTED"); logging(LOG_VERBOSE, "Test WRITE_SAME16 fails with WRITE_PROTECTED");
WRITESAME16(sd, 0, block_size, 1, 0, 0, 0, 0, scratch, WRITESAME16(sd, 0, block_size, 1, 0, 0, 0, 0, scratch,
EXPECT_WRITE_PROTECTED); EXPECT_WRITE_PROTECTED);
logging(LOG_VERBOSE, "Test WRITE_SAME16 UNMAP fails with " logging(LOG_VERBOSE, "Test WRITE_SAME16 UNMAP fails with "
"WRITE_PROTECTED"); "WRITE_PROTECTED");
WRITESAME16(sd, 0, block_size, 1, 0, 1, 0, 0, NULL, WRITESAME16(sd, 0, block_size, 1, 0, 1, 0, 0, NULL,
EXPECT_WRITE_PROTECTED); EXPECT_WRITE_PROTECTED);
@@ -81,39 +81,39 @@ test_writesame16(void)
static void static void
test_writeverify10(void) test_writeverify10(void)
{ {
logging(LOG_VERBOSE, "Test WRITEVERIFY10 fails with WRITE_PROTECTED"); logging(LOG_VERBOSE, "Test WRITEVERIFY10 fails with WRITE_PROTECTED");
WRITEVERIFY10(sd, 0, block_size, block_size, 0, 0, 0, 0, scratch, WRITEVERIFY10(sd, 0, block_size, block_size, 0, 0, 0, 0, scratch,
EXPECT_WRITE_PROTECTED); EXPECT_WRITE_PROTECTED);
} }
static void static void
test_writeverify12(void) test_writeverify12(void)
{ {
logging(LOG_VERBOSE, "Test WRITEVERIFY12 fails with WRITE_PROTECTED"); logging(LOG_VERBOSE, "Test WRITEVERIFY12 fails with WRITE_PROTECTED");
WRITEVERIFY12(sd, 0, block_size, block_size, 0, 0, 0, 0, scratch, WRITEVERIFY12(sd, 0, block_size, block_size, 0, 0, 0, 0, scratch,
EXPECT_WRITE_PROTECTED); EXPECT_WRITE_PROTECTED);
} }
static void static void
test_writeverify16(void) test_writeverify16(void)
{ {
logging(LOG_VERBOSE, "Test WRITEVERIFY16 fails with WRITE_PROTECTED"); logging(LOG_VERBOSE, "Test WRITEVERIFY16 fails with WRITE_PROTECTED");
WRITEVERIFY16(sd, 0, block_size, block_size, 0, 0, 0, 0, scratch, WRITEVERIFY16(sd, 0, block_size, block_size, 0, 0, 0, 0, scratch,
EXPECT_WRITE_PROTECTED); EXPECT_WRITE_PROTECTED);
} }
static void static void
test_orwrite(void) test_orwrite(void)
{ {
logging(LOG_VERBOSE, "Test ORWRITE fails with WRITE_PROTECTED"); logging(LOG_VERBOSE, "Test ORWRITE fails with WRITE_PROTECTED");
ORWRITE(sd, 0, block_size, block_size, 0, 0, 0, 0, 0, scratch, ORWRITE(sd, 0, block_size, block_size, 0, 0, 0, 0, 0, scratch,
EXPECT_WRITE_PROTECTED); EXPECT_WRITE_PROTECTED);
} }
static void static void
test_compareandwrite(void) test_compareandwrite(void)
{ {
logging(LOG_VERBOSE, "Test COMPAREANDWRITE fails with WRITE_PROTECTED"); logging(LOG_VERBOSE, "Test COMPAREANDWRITE fails with WRITE_PROTECTED");
COMPAREANDWRITE(sd, 0, scratch, 2 * block_size, block_size, 0, 0, 0, 0, COMPAREANDWRITE(sd, 0, scratch, 2 * block_size, block_size, 0, 0, 0, 0,
EXPECT_WRITE_PROTECTED); EXPECT_WRITE_PROTECTED);
} }
@@ -121,32 +121,32 @@ test_compareandwrite(void)
static void static void
test_unmap(void) test_unmap(void)
{ {
struct unmap_list list[1]; struct unmap_list list[1];
logging(LOG_VERBOSE, "Test UNMAP of one physical block fails with " logging(LOG_VERBOSE, "Test UNMAP of one physical block fails with "
"WRITE_PROTECTED"); "WRITE_PROTECTED");
list[0].lba = 0; list[0].lba = 0;
list[0].num = lbppb; list[0].num = lbppb;
UNMAP(sd, 0, list, 1, UNMAP(sd, 0, list, 1,
EXPECT_WRITE_PROTECTED); EXPECT_WRITE_PROTECTED);
logging(LOG_VERBOSE, "Test UNMAP of one logical block fails with " logging(LOG_VERBOSE, "Test UNMAP of one logical block fails with "
"WRITE_PROTECTED"); "WRITE_PROTECTED");
list[0].lba = 0; list[0].lba = 0;
list[0].num = 1; list[0].num = 1;
UNMAP(sd, 0, list, 1, UNMAP(sd, 0, list, 1,
EXPECT_WRITE_PROTECTED); EXPECT_WRITE_PROTECTED);
} }
void void
test_readonly_sbc(void) test_readonly_sbc(void)
{ {
CHECK_FOR_DATALOSS; CHECK_FOR_DATALOSS;
CHECK_FOR_READONLY; CHECK_FOR_READONLY;
CHECK_FOR_SBC; CHECK_FOR_SBC;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test that Medium write commands fail for READ-ONLY SBC devices"); logging(LOG_VERBOSE, "Test that Medium write commands fail for READ-ONLY SBC devices");
test_compareandwrite(); test_compareandwrite();
test_orwrite(); test_orwrite();

View File

@@ -30,52 +30,52 @@
void void
test_receive_copy_results_copy_status(void) test_receive_copy_results_copy_status(void)
{ {
struct scsi_task *cs_task; struct scsi_task *cs_task;
struct scsi_copy_results_copy_status *csp; struct scsi_copy_results_copy_status *csp;
int tgt_desc_len = 0, seg_desc_len = 0; int tgt_desc_len = 0, seg_desc_len = 0;
int offset = XCOPY_DESC_OFFSET, list_id = 1; int offset = XCOPY_DESC_OFFSET, list_id = 1;
struct iscsi_data data; struct iscsi_data data;
unsigned char *xcopybuf; unsigned char *xcopybuf;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test RECEIVE COPY RESULTS, COPY STATUS"); logging(LOG_VERBOSE, "Test RECEIVE COPY RESULTS, COPY STATUS");
logging(LOG_VERBOSE, "No copy in progress"); logging(LOG_VERBOSE, "No copy in progress");
RECEIVE_COPY_RESULTS(&cs_task, sd, SCSI_COPY_RESULTS_COPY_STATUS, RECEIVE_COPY_RESULTS(&cs_task, sd, SCSI_COPY_RESULTS_COPY_STATUS,
list_id, NULL, EXPECT_INVALID_FIELD_IN_CDB); list_id, NULL, EXPECT_INVALID_FIELD_IN_CDB);
scsi_free_scsi_task(cs_task); scsi_free_scsi_task(cs_task);
cs_task = NULL; cs_task = NULL;
CHECK_FOR_DATALOSS; CHECK_FOR_DATALOSS;
logging(LOG_VERBOSE, "Issue Extended Copy"); logging(LOG_VERBOSE, "Issue Extended Copy");
data.size = XCOPY_DESC_OFFSET + data.size = XCOPY_DESC_OFFSET +
get_desc_len(IDENT_DESCR_TGT_DESCR) + get_desc_len(IDENT_DESCR_TGT_DESCR) +
get_desc_len(BLK_TO_BLK_SEG_DESCR); get_desc_len(BLK_TO_BLK_SEG_DESCR);
data.data = alloca(data.size); data.data = alloca(data.size);
xcopybuf = data.data; xcopybuf = data.data;
memset(xcopybuf, 0, data.size); memset(xcopybuf, 0, data.size);
/* Initialize target descriptor list with one target descriptor */ /* Initialize target descriptor list with one target descriptor */
offset += populate_tgt_desc(xcopybuf+offset, IDENT_DESCR_TGT_DESCR, offset += populate_tgt_desc(xcopybuf+offset, IDENT_DESCR_TGT_DESCR,
LU_ID_TYPE_LUN, 0, 0, 0, 0, sd); LU_ID_TYPE_LUN, 0, 0, 0, 0, sd);
tgt_desc_len = offset - XCOPY_DESC_OFFSET; tgt_desc_len = offset - XCOPY_DESC_OFFSET;
/* Initialize segment descriptor list with one segment descriptor */ /* Initialize segment descriptor list with one segment descriptor */
offset += populate_seg_desc_b2b(xcopybuf+offset, 0, 0, 0, 0, offset += populate_seg_desc_b2b(xcopybuf+offset, 0, 0, 0, 0,
2048, 0, num_blocks - 2048); 2048, 0, num_blocks - 2048);
seg_desc_len = offset - XCOPY_DESC_OFFSET - tgt_desc_len; seg_desc_len = offset - XCOPY_DESC_OFFSET - tgt_desc_len;
/* Initialize the parameter list header */ /* Initialize the parameter list header */
populate_param_header(xcopybuf, list_id, 0, 0, 0, populate_param_header(xcopybuf, list_id, 0, 0, 0,
tgt_desc_len, seg_desc_len, 0); tgt_desc_len, seg_desc_len, 0);
EXTENDEDCOPY(sd, &data, EXPECT_STATUS_GOOD); EXTENDEDCOPY(sd, &data, EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, logging(LOG_VERBOSE,
"Copy Status for the above Extended Copy command"); "Copy Status for the above Extended Copy command");
RECEIVE_COPY_RESULTS(&cs_task, sd, SCSI_COPY_RESULTS_COPY_STATUS, RECEIVE_COPY_RESULTS(&cs_task, sd, SCSI_COPY_RESULTS_COPY_STATUS,
list_id, (void **)&csp, EXPECT_STATUS_GOOD); list_id, (void **)&csp, EXPECT_STATUS_GOOD);
scsi_free_scsi_task(cs_task); scsi_free_scsi_task(cs_task);
} }

View File

@@ -30,19 +30,19 @@
void void
test_receive_copy_results_op_params(void) test_receive_copy_results_op_params(void)
{ {
struct scsi_task *op_task = NULL; struct scsi_task *op_task = NULL;
struct scsi_copy_results_op_params *opp; struct scsi_copy_results_op_params *opp;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test RECEIVE COPY RESULTS, OPERATING PARAMS"); logging(LOG_VERBOSE, "Test RECEIVE COPY RESULTS, OPERATING PARAMS");
RECEIVE_COPY_RESULTS(&op_task, sd, SCSI_COPY_RESULTS_OP_PARAMS, 0, RECEIVE_COPY_RESULTS(&op_task, sd, SCSI_COPY_RESULTS_OP_PARAMS, 0,
(void **)&opp, EXPECT_STATUS_GOOD); (void **)&opp, EXPECT_STATUS_GOOD);
logging(LOG_NORMAL, logging(LOG_NORMAL,
"max_target_desc=%d, max_seg_desc=%d", "max_target_desc=%d, max_seg_desc=%d",
opp->max_target_desc_count, opp->max_target_desc_count,
opp->max_segment_desc_count); opp->max_segment_desc_count);
scsi_free_scsi_task(op_task); scsi_free_scsi_task(op_task);
} }

View File

@@ -29,82 +29,82 @@
void void
test_report_supported_opcodes_one_command(void) test_report_supported_opcodes_one_command(void)
{ {
int i; int i;
struct scsi_task *rso_task; struct scsi_task *rso_task;
struct scsi_task *one_task; struct scsi_task *one_task;
struct scsi_report_supported_op_codes *rsoc; struct scsi_report_supported_op_codes *rsoc;
struct scsi_report_supported_op_codes_one_command *rsoc_one; struct scsi_report_supported_op_codes_one_command *rsoc_one;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test READ_SUPPORTED_OPCODES reading one-command"); logging(LOG_VERBOSE, "Test READ_SUPPORTED_OPCODES reading one-command");
logging(LOG_VERBOSE, "Fetch list of all supported opcodes"); logging(LOG_VERBOSE, "Fetch list of all supported opcodes");
REPORT_SUPPORTED_OPCODES(sd, &rso_task, REPORT_SUPPORTED_OPCODES(sd, &rso_task,
0, SCSI_REPORT_SUPPORTING_OPS_ALL, 0, SCSI_REPORT_SUPPORTING_OPS_ALL,
0, 0, 65535, 0, 0, 65535,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer"); logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer");
rsoc = scsi_datain_unmarshall(rso_task); rsoc = scsi_datain_unmarshall(rso_task);
CU_ASSERT_PTR_NOT_NULL_FATAL(rsoc); CU_ASSERT_PTR_NOT_NULL_FATAL(rsoc);
logging(LOG_VERBOSE, "Verify read one-command works for all supported " logging(LOG_VERBOSE, "Verify read one-command works for all supported "
"opcodes"); "opcodes");
for (i = 0; i < rsoc->num_descriptors; i++) { for (i = 0; i < rsoc->num_descriptors; i++) {
logging(LOG_VERBOSE, "Check opcode:0x%02x ServiceAction:0x%02x", logging(LOG_VERBOSE, "Check opcode:0x%02x ServiceAction:0x%02x",
rsoc->descriptors[i].opcode, rsoc->descriptors[i].opcode,
rsoc->descriptors[i].sa); rsoc->descriptors[i].sa);
if (rsoc->descriptors[i].servactv) { if (rsoc->descriptors[i].servactv) {
logging(LOG_VERBOSE, "This opcode has service actions. " logging(LOG_VERBOSE, "This opcode has service actions. "
"Reporting Options 001b should fail"); "Reporting Options 001b should fail");
REPORT_SUPPORTED_OPCODES(sd, NULL, 0, REPORT_SUPPORTED_OPCODES(sd, NULL, 0,
SCSI_REPORT_SUPPORTING_OPCODE, SCSI_REPORT_SUPPORTING_OPCODE,
rsoc->descriptors[i].opcode, rsoc->descriptors[i].opcode,
rsoc->descriptors[i].sa, rsoc->descriptors[i].sa,
65535, 65535,
EXPECT_INVALID_FIELD_IN_CDB); EXPECT_INVALID_FIELD_IN_CDB);
} else { } else {
logging(LOG_VERBOSE, "This opcode does not have " logging(LOG_VERBOSE, "This opcode does not have "
"service actions. Reporting Options 001b " "service actions. Reporting Options 001b "
"should work"); "should work");
REPORT_SUPPORTED_OPCODES(sd, NULL, 0, REPORT_SUPPORTED_OPCODES(sd, NULL, 0,
SCSI_REPORT_SUPPORTING_OPCODE, SCSI_REPORT_SUPPORTING_OPCODE,
rsoc->descriptors[i].opcode, rsoc->descriptors[i].opcode,
rsoc->descriptors[i].sa, rsoc->descriptors[i].sa,
65535, 65535,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} }
if (rsoc->descriptors[i].servactv) { if (rsoc->descriptors[i].servactv) {
logging(LOG_VERBOSE, "This opcode has service actions. " logging(LOG_VERBOSE, "This opcode has service actions. "
"Reporting Options 002b should work"); "Reporting Options 002b should work");
REPORT_SUPPORTED_OPCODES(sd, NULL, 0, REPORT_SUPPORTED_OPCODES(sd, NULL, 0,
SCSI_REPORT_SUPPORTING_SERVICEACTION, SCSI_REPORT_SUPPORTING_SERVICEACTION,
rsoc->descriptors[i].opcode, rsoc->descriptors[i].opcode,
rsoc->descriptors[i].sa, rsoc->descriptors[i].sa,
65535, 65535,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
} else { } else {
logging(LOG_VERBOSE, "This opcode does not have " logging(LOG_VERBOSE, "This opcode does not have "
"service actions. Reporting Options 002b " "service actions. Reporting Options 002b "
"should fail"); "should fail");
REPORT_SUPPORTED_OPCODES(sd, NULL, 0, REPORT_SUPPORTED_OPCODES(sd, NULL, 0,
SCSI_REPORT_SUPPORTING_SERVICEACTION, SCSI_REPORT_SUPPORTING_SERVICEACTION,
rsoc->descriptors[i].opcode, rsoc->descriptors[i].opcode,
rsoc->descriptors[i].sa, rsoc->descriptors[i].sa,
65535, 65535,
EXPECT_INVALID_FIELD_IN_CDB); EXPECT_INVALID_FIELD_IN_CDB);
} }
} }
logging(LOG_VERBOSE, "Verify read one-command CDB looks sane"); logging(LOG_VERBOSE, "Verify read one-command CDB looks sane");
for (i = 0; i < rsoc->num_descriptors; i++) { for (i = 0; i < rsoc->num_descriptors; i++) {
logging(LOG_VERBOSE, "Check CDB for opcode:0x%02x " logging(LOG_VERBOSE, "Check CDB for opcode:0x%02x "
"ServiceAction:0x%02x", "ServiceAction:0x%02x",
rsoc->descriptors[i].opcode, rsoc->descriptors[i].opcode,
rsoc->descriptors[i].sa); rsoc->descriptors[i].sa);
REPORT_SUPPORTED_OPCODES(sd, &one_task, 0, REPORT_SUPPORTED_OPCODES(sd, &one_task, 0,
rsoc->descriptors[i].servactv ? rsoc->descriptors[i].servactv ?
SCSI_REPORT_SUPPORTING_SERVICEACTION : SCSI_REPORT_SUPPORTING_SERVICEACTION :
SCSI_REPORT_SUPPORTING_OPCODE, SCSI_REPORT_SUPPORTING_OPCODE,
@@ -113,29 +113,29 @@ test_report_supported_opcodes_one_command(void)
65535, 65535,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer"); logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer");
rsoc_one = scsi_datain_unmarshall(one_task); rsoc_one = scsi_datain_unmarshall(one_task);
CU_ASSERT_PTR_NOT_NULL_FATAL(rsoc_one); CU_ASSERT_PTR_NOT_NULL_FATAL(rsoc_one);
logging(LOG_VERBOSE, "Verify CDB length is not 0"); logging(LOG_VERBOSE, "Verify CDB length is not 0");
CU_ASSERT_NOT_EQUAL(rsoc_one->cdb_length, 0); CU_ASSERT_NOT_EQUAL(rsoc_one->cdb_length, 0);
if (rsoc_one->cdb_length == 0) { if (rsoc_one->cdb_length == 0) {
logging(LOG_NORMAL, "[FAILED] CDB length is 0"); logging(LOG_NORMAL, "[FAILED] CDB length is 0");
} }
logging(LOG_VERBOSE, "Verify CDB[0] Usage Data == <opcode>"); logging(LOG_VERBOSE, "Verify CDB[0] Usage Data == <opcode>");
CU_ASSERT_EQUAL(rsoc_one->cdb_usage_data[0], CU_ASSERT_EQUAL(rsoc_one->cdb_usage_data[0],
rsoc->descriptors[i].opcode); rsoc->descriptors[i].opcode);
if (rsoc_one->cdb_usage_data[0] != rsoc->descriptors[i].opcode) { if (rsoc_one->cdb_usage_data[0] != rsoc->descriptors[i].opcode) {
logging(LOG_NORMAL, "[FAILED] CDB[0] Usage Data was " logging(LOG_NORMAL, "[FAILED] CDB[0] Usage Data was "
"0x%02x, expected 0x%02x for opcode 0x%02x", "0x%02x, expected 0x%02x for opcode 0x%02x",
rsoc_one->cdb_usage_data[0], rsoc_one->cdb_usage_data[0],
rsoc->descriptors[i].opcode, rsoc->descriptors[i].opcode,
rsoc->descriptors[i].opcode); rsoc->descriptors[i].opcode);
} }
scsi_free_scsi_task(one_task); scsi_free_scsi_task(one_task);
} }
scsi_free_scsi_task(rso_task); scsi_free_scsi_task(rso_task);
} }

View File

@@ -29,70 +29,70 @@
void void
test_report_supported_opcodes_rctd(void) test_report_supported_opcodes_rctd(void)
{ {
int i; int i;
struct scsi_task *rso_task; struct scsi_task *rso_task;
struct scsi_report_supported_op_codes *rsoc; struct scsi_report_supported_op_codes *rsoc;
logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, LOG_BLANK_LINE);
logging(LOG_VERBOSE, "Test READ_SUPPORTED_OPCODES RCTD flag"); logging(LOG_VERBOSE, "Test READ_SUPPORTED_OPCODES RCTD flag");
logging(LOG_VERBOSE, "Test READ_SUPPORTED_OPCODES report ALL opcodes " logging(LOG_VERBOSE, "Test READ_SUPPORTED_OPCODES report ALL opcodes "
"without timeout descriptors. RCTD==0"); "without timeout descriptors. RCTD==0");
REPORT_SUPPORTED_OPCODES(sd, &rso_task, REPORT_SUPPORTED_OPCODES(sd, &rso_task,
0, SCSI_REPORT_SUPPORTING_OPS_ALL, 0, 0, 0, SCSI_REPORT_SUPPORTING_OPS_ALL, 0, 0,
65535, 65535,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer"); logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer");
rsoc = scsi_datain_unmarshall(rso_task); rsoc = scsi_datain_unmarshall(rso_task);
CU_ASSERT_PTR_NOT_NULL_FATAL(rsoc); CU_ASSERT_PTR_NOT_NULL_FATAL(rsoc);
logging(LOG_VERBOSE, "Verify that all returned command descriptors " logging(LOG_VERBOSE, "Verify that all returned command descriptors "
"lack timeout description"); "lack timeout description");
for (i = 0; i < rsoc->num_descriptors; i++) { for (i = 0; i < rsoc->num_descriptors; i++) {
if (rsoc->descriptors[i].ctdp) { if (rsoc->descriptors[i].ctdp) {
logging(LOG_NORMAL, "[FAILED] Command descriptor with " logging(LOG_NORMAL, "[FAILED] Command descriptor with "
"CTDP set received when RCTD==0"); "CTDP set received when RCTD==0");
CU_FAIL("[FAILED] Command descriptor with " CU_FAIL("[FAILED] Command descriptor with "
"CTDP set"); "CTDP set");
} }
} }
scsi_free_scsi_task(rso_task); scsi_free_scsi_task(rso_task);
logging(LOG_VERBOSE, "Test READ_SUPPORTED_OPCODES report ALL opcodes " logging(LOG_VERBOSE, "Test READ_SUPPORTED_OPCODES report ALL opcodes "
"with timeout descriptors. RCTD==1"); "with timeout descriptors. RCTD==1");
REPORT_SUPPORTED_OPCODES(sd, &rso_task, REPORT_SUPPORTED_OPCODES(sd, &rso_task,
1, SCSI_REPORT_SUPPORTING_OPS_ALL, 0, 0, 1, SCSI_REPORT_SUPPORTING_OPS_ALL, 0, 0,
65535, 65535,
EXPECT_STATUS_GOOD); EXPECT_STATUS_GOOD);
logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer"); logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer");
rsoc = scsi_datain_unmarshall(rso_task); rsoc = scsi_datain_unmarshall(rso_task);
CU_ASSERT_NOT_EQUAL(rsoc, NULL); CU_ASSERT_NOT_EQUAL(rsoc, NULL);
logging(LOG_VERBOSE, "Verify that all returned command descriptors " logging(LOG_VERBOSE, "Verify that all returned command descriptors "
"have a timeout description"); "have a timeout description");
for (i = 0; i < rsoc->num_descriptors; i++) { for (i = 0; i < rsoc->num_descriptors; i++) {
if (!rsoc->descriptors[i].ctdp) { if (!rsoc->descriptors[i].ctdp) {
logging(LOG_NORMAL, "[FAILED] Command descriptor " logging(LOG_NORMAL, "[FAILED] Command descriptor "
"with CTDP clear when RCTD==1"); "with CTDP clear when RCTD==1");
CU_FAIL("[FAILED] Command descriptor without " CU_FAIL("[FAILED] Command descriptor without "
"CTDP set"); "CTDP set");
} }
} }
logging(LOG_VERBOSE, "Verify that all timeout descriptors have the " logging(LOG_VERBOSE, "Verify that all timeout descriptors have the "
"correct length"); "correct length");
for (i = 0; i < rsoc->num_descriptors; i++) { for (i = 0; i < rsoc->num_descriptors; i++) {
if (rsoc->descriptors[i].ctdp && if (rsoc->descriptors[i].ctdp &&
rsoc->descriptors[i].to.descriptor_length != 0x0a) { rsoc->descriptors[i].to.descriptor_length != 0x0a) {
logging(LOG_NORMAL, "[FAILED] Command descriptor " logging(LOG_NORMAL, "[FAILED] Command descriptor "
"with invalid TimeoutDescriptor length"); "with invalid TimeoutDescriptor length");
CU_FAIL("[FAILED] Command descriptor with " CU_FAIL("[FAILED] Command descriptor with "
"invalid TimeoutDescriptor length"); "invalid TimeoutDescriptor length");
} }
} }
scsi_free_scsi_task(rso_task); scsi_free_scsi_task(rso_task);
} }

Some files were not shown because too many files have changed in this diff Show More