TESTS: change modeselect to become /dev/sg-aware

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
This commit is contained in:
Ronnie Sahlberg
2014-09-27 08:10:14 -07:00
parent 0666691b2a
commit abbf9a11b0
5 changed files with 96 additions and 131 deletions

View File

@@ -1482,6 +1482,40 @@ int modesense6(struct scsi_device *sdev, struct scsi_task **out_task, int dbd, e
return ret; return ret;
} }
int modeselect6(struct scsi_device *sdev, int pf, int sp, struct scsi_mode_page *mp, int status, enum scsi_sense_key key, int *ascq, int num_ascq)
{
struct scsi_task *task;
int ret;
struct scsi_data *data;
struct iscsi_data d;
logging(LOG_VERBOSE, "Send MODESELECT6 (Expecting %s) ",
scsi_status_str(status));
task = scsi_cdb_modeselect6(pf, sp, 255);
assert(task != NULL);
data = scsi_modesense_dataout_marshall(task, mp, 1);
if (data == NULL) {
logging(LOG_VERBOSE, "Failed to marshall MODESELECT6 data");
scsi_free_scsi_task(task);
return -1;
}
d.data = data->data;
d.size = data->size;
task->cdb[4] = data->size;
task->expxferlen = data->size;
task = send_scsi_command(sdev, task, &d);
ret = check_result("MODESELECT6", sdev, task, status, key, ascq, num_ascq);
if (task) {
scsi_free_scsi_task(task);
}
return ret;
}
int compareandwrite(struct scsi_device *sdev, uint64_t lba, int compareandwrite(struct scsi_device *sdev, uint64_t lba,
unsigned char *data, uint32_t datalen, int blocksize, unsigned char *data, uint32_t datalen, int blocksize,
int wrprotect, int dpo, int wrprotect, int dpo,
@@ -2394,29 +2428,21 @@ get_command_descriptor(int opcode, int sa)
int set_swp(struct scsi_device *sdev) int set_swp(struct scsi_device *sdev)
{ {
int ret = 0; int ret;
struct scsi_task *sense_task = NULL; struct scsi_task *sense_task = NULL;
struct scsi_task *select_task = NULL;
struct scsi_mode_sense *ms; struct scsi_mode_sense *ms;
struct scsi_mode_page *mp; struct scsi_mode_page *mp;
logging(LOG_VERBOSE, "Read CONTROL page"); logging(LOG_VERBOSE, "Read CONTROL page");
sense_task = iscsi_modesense6_sync(sdev->iscsi_ctx, sdev->iscsi_lun, ret = modesense6(sdev, &sense_task, 1, SCSI_MODESENSE_PC_CURRENT,
1, SCSI_MODESENSE_PC_CURRENT, SCSI_MODEPAGE_CONTROL, 0, 255,
SCSI_MODEPAGE_CONTROL, EXPECT_STATUS_GOOD);
0, 255); if (ret) {
if (sense_task == NULL) { logging(LOG_NORMAL, "Failed to read CONTROL mode page.");
logging(LOG_NORMAL, "Failed to send MODE_SENSE6 command: %s",
iscsi_get_error(sdev->iscsi_ctx));
ret = -1;
goto finished;
}
if (sense_task->status != SCSI_STATUS_GOOD) {
logging(LOG_NORMAL, "MODE_SENSE6 failed: %s",
iscsi_get_error(sdev->iscsi_ctx));
ret = -1;
goto finished; goto finished;
} }
logging(LOG_VERBOSE, "[SUCCESS] CONTROL page fetched.");
ms = scsi_datain_unmarshall(sense_task); ms = scsi_datain_unmarshall(sense_task);
if (ms == NULL) { if (ms == NULL) {
logging(LOG_NORMAL, "failed to unmarshall mode sense datain " logging(LOG_NORMAL, "failed to unmarshall mode sense datain "
@@ -2434,56 +2460,38 @@ int set_swp(struct scsi_device *sdev)
logging(LOG_VERBOSE, "Turn SWP ON"); logging(LOG_VERBOSE, "Turn SWP ON");
mp->control.swp = 1; mp->control.swp = 1;
select_task = iscsi_modeselect6_sync(sdev->iscsi_ctx, sdev->iscsi_lun, ret = modeselect6(sdev, 1, 0, mp,
1, 0, mp); EXPECT_STATUS_GOOD);
if (select_task == NULL) { if (ret) {
logging(LOG_NORMAL, "Failed to send MODE_SELECT6 command: %s", logging(LOG_NORMAL, "Failed to write CONTROL mode page.");
iscsi_get_error(sdev->iscsi_ctx));
ret = -1;
goto finished;
}
if (select_task->status != SCSI_STATUS_GOOD) {
logging(LOG_NORMAL, "MODE_SELECT6 failed: %s",
iscsi_get_error(sdev->iscsi_ctx));
ret = -1;
goto finished; goto finished;
} }
logging(LOG_VERBOSE, "[SUCCESS] CONTROL page written.");
finished: finished:
if (sense_task != NULL) { if (sense_task != NULL) {
scsi_free_scsi_task(sense_task); scsi_free_scsi_task(sense_task);
} }
if (select_task != NULL) {
scsi_free_scsi_task(select_task);
}
return ret; return ret;
} }
int clear_swp(struct scsi_device *sdev) int clear_swp(struct scsi_device *sdev)
{ {
int ret = 0; int ret;
struct scsi_task *sense_task = NULL; struct scsi_task *sense_task = NULL;
struct scsi_task *select_task = NULL;
struct scsi_mode_sense *ms; struct scsi_mode_sense *ms;
struct scsi_mode_page *mp; struct scsi_mode_page *mp;
logging(LOG_VERBOSE, "Read CONTROL page"); logging(LOG_VERBOSE, "Read CONTROL page");
sense_task = iscsi_modesense6_sync(sdev->iscsi_ctx, sdev->iscsi_lun, ret = modesense6(sdev, &sense_task, 1, SCSI_MODESENSE_PC_CURRENT,
1, SCSI_MODESENSE_PC_CURRENT, SCSI_MODEPAGE_CONTROL, 0, 255,
SCSI_MODEPAGE_CONTROL, EXPECT_STATUS_GOOD);
0, 255); if (ret) {
if (sense_task == NULL) { logging(LOG_NORMAL, "Failed to read CONTROL mode page.");
logging(LOG_NORMAL, "Failed to send MODE_SENSE6 command: %s",
iscsi_get_error(sdev->iscsi_ctx));
ret = -1;
goto finished;
}
if (sense_task->status != SCSI_STATUS_GOOD) {
logging(LOG_NORMAL, "MODE_SENSE6 failed: %s",
iscsi_get_error(sdev->iscsi_ctx));
ret = -1;
goto finished; goto finished;
} }
logging(LOG_VERBOSE, "[SUCCESS] CONTROL page fetched.");
ms = scsi_datain_unmarshall(sense_task); ms = scsi_datain_unmarshall(sense_task);
if (ms == NULL) { if (ms == NULL) {
logging(LOG_NORMAL, "failed to unmarshall mode sense datain " logging(LOG_NORMAL, "failed to unmarshall mode sense datain "
@@ -2501,27 +2509,17 @@ int clear_swp(struct scsi_device *sdev)
logging(LOG_VERBOSE, "Turn SWP OFF"); logging(LOG_VERBOSE, "Turn SWP OFF");
mp->control.swp = 0; mp->control.swp = 0;
select_task = iscsi_modeselect6_sync(sdev->iscsi_ctx, sdev->iscsi_lun, ret = modeselect6(sdev, 1, 0, mp,
1, 0, mp); EXPECT_STATUS_GOOD);
if (select_task == NULL) { if (ret) {
logging(LOG_NORMAL, "Failed to send MODE_SELECT6 command: %s", logging(LOG_NORMAL, "Failed to write CONTROL mode page.");
iscsi_get_error(sdev->iscsi_ctx));
ret = -1;
goto finished;
}
if (select_task->status != SCSI_STATUS_GOOD) {
logging(LOG_NORMAL, "MODE_SELECT6 failed: %s",
iscsi_get_error(sdev->iscsi_ctx));
ret = -1;
goto finished; goto finished;
} }
logging(LOG_VERBOSE, "[SUCCESS] CONTROL page written.");
finished: finished:
if (sense_task != NULL) { if (sense_task != NULL) {
scsi_free_scsi_task(sense_task); scsi_free_scsi_task(sense_task);
} }
if (select_task != NULL) {
scsi_free_scsi_task(select_task);
}
return ret; return ret;
} }

View File

@@ -272,6 +272,7 @@ int compareandwrite(struct scsi_device *sdev, uint64_t lba, unsigned char *data,
int get_lba_status(struct scsi_device *sdev, struct scsi_task **task, uint64_t lba, uint32_t len, int status, enum scsi_sense_key key, int *ascq, int num_ascq); int get_lba_status(struct scsi_device *sdev, struct scsi_task **task, uint64_t lba, uint32_t len, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int inquiry(struct scsi_device *sdev, struct scsi_task **task, int evpd, int page_code, int maxsize, int status, enum scsi_sense_key key, int *ascq, int num_ascq); int inquiry(struct scsi_device *sdev, struct scsi_task **task, int evpd, int page_code, int maxsize, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int modesense6(struct scsi_device *sdev, struct scsi_task **task, int dbd, enum scsi_modesense_page_control pc, enum scsi_modesense_page_code page_code, int sub_page_code, unsigned char alloc_len, int status, enum scsi_sense_key key, int *ascq, int num_ascq); int modesense6(struct scsi_device *sdev, struct scsi_task **task, int dbd, enum scsi_modesense_page_control pc, enum scsi_modesense_page_code page_code, int sub_page_code, unsigned char alloc_len, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int modeselect6(struct scsi_device *sdev, int pf, int sp, struct scsi_mode_page *mp, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int orwrite(struct scsi_device *sdev, uint64_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data, int status, enum scsi_sense_key key, int *ascq, int num_ascq); int orwrite(struct scsi_device *sdev, uint64_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int prefetch10(struct scsi_device *sdev, uint32_t lba, int num_blocks, int immed, int group, int status, enum scsi_sense_key key, int *ascq, int num_ascq); int prefetch10(struct scsi_device *sdev, uint32_t lba, int num_blocks, int immed, int group, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int prefetch16(struct scsi_device *sdev, uint64_t lba, int num_blocks, int immed, int group, int status, enum scsi_sense_key key, int *ascq, int num_ascq); int prefetch16(struct scsi_device *sdev, uint64_t lba, int num_blocks, int immed, int group, int status, enum scsi_sense_key key, int *ascq, int num_ascq);

View File

@@ -28,39 +28,28 @@ 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;
int ret;
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");
if (task != NULL) {
scsi_free_scsi_task(task);
task = NULL;
}
logging(LOG_VERBOSE, "Send MODESENSE6 command to fetch AllPages"); logging(LOG_VERBOSE, "Send MODESENSE6 command to fetch AllPages");
task = iscsi_modesense6_sync(sd->iscsi_ctx, sd->iscsi_lun, 0, ret = modesense6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT,
SCSI_MODESENSE_PC_CURRENT, SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255,
SCSI_MODEPAGE_RETURN_ALL_PAGES, EXPECT_STATUS_GOOD);
0, 255); CU_ASSERT_EQUAL(ret, 0);
if (task == NULL || task->status != SCSI_STATUS_GOOD) {
logging(LOG_VERBOSE, "[FAILED] Failed to send MODE_SENSE6 "
"command:%s",
iscsi_get_error(sd->iscsi_ctx));
CU_FAIL("[FAILED] Failed to fetch the All Pages page.");
return;
}
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(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(task); scsi_free_scsi_task(ms_task);
task = NULL;
return; return;
} }
logging(LOG_VERBOSE, "[SUCCESS] Unmarshalling successful."); logging(LOG_VERBOSE, "[SUCCESS] Unmarshalling successful.");
@@ -75,8 +64,5 @@ test_modesense6_all_pages(void)
CU_ASSERT_TRUE(ms->mode_data_length >= 3); CU_ASSERT_TRUE(ms->mode_data_length >= 3);
if (task != NULL) { scsi_free_scsi_task(ms_task);
scsi_free_scsi_task(task);
task = NULL;
}
} }

View File

@@ -27,6 +27,9 @@
void void
test_modesense6_residuals(void) test_modesense6_residuals(void)
{ {
struct scsi_task *ms_task = NULL;
int ret;
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");
@@ -36,95 +39,69 @@ test_modesense6_residuals(void)
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.");
if (task != NULL) { ret = modesense6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT,
scsi_free_scsi_task(task); SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 4,
task = NULL; EXPECT_STATUS_GOOD);
} CU_ASSERT_EQUAL(ret, 0);
task = iscsi_modesense6_sync(sd->iscsi_ctx, sd->iscsi_lun, 0,
SCSI_MODESENSE_PC_CURRENT,
SCSI_MODEPAGE_RETURN_ALL_PAGES,
0, 4);
if (task == NULL || task->status != SCSI_STATUS_GOOD) {
logging(LOG_VERBOSE, "[FAILED] Failed to send MODE_SENSE6 "
"command:%s",
iscsi_get_error(sd->iscsi_ctx));
CU_FAIL("[FAILED] Failed to fetch the All Pages page.");
return;
}
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 (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(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 (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(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.");
if (task != NULL) { scsi_free_scsi_task(ms_task);
scsi_free_scsi_task(task); ret = modesense6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT,
task = NULL; SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255,
} EXPECT_STATUS_GOOD);
task = iscsi_modesense6_sync(sd->iscsi_ctx, sd->iscsi_lun, 0, CU_ASSERT_EQUAL(ret, 0);
SCSI_MODESENSE_PC_CURRENT,
SCSI_MODEPAGE_RETURN_ALL_PAGES,
0, 255);
if (task == NULL || task->status != SCSI_STATUS_GOOD) {
logging(LOG_VERBOSE, "[FAILED] Failed to send MODE_SENSE6 "
"command:%s",
iscsi_get_error(sd->iscsi_ctx));
CU_FAIL("[FAILED] Failed to fetch the All Pages page.");
return;
}
logging(LOG_VERBOSE, "[SUCCESS] All Pages fetched."); logging(LOG_VERBOSE, "[SUCCESS] All Pages fetched.");
if (ms_task->datain.size == 255) {
if (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 (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(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 (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(task->residual_status, CU_ASSERT_EQUAL(ms_task->residual_status,
SCSI_RESIDUAL_UNDERFLOW); SCSI_RESIDUAL_UNDERFLOW);
} }
scsi_free_scsi_task(ms_task);
if (task != NULL) {
scsi_free_scsi_task(task);
task = NULL;
}
} }

View File

@@ -41,7 +41,10 @@ test_sanitize_readonly(void)
CHECK_FOR_DATALOSS; CHECK_FOR_DATALOSS;
logging(LOG_VERBOSE, "Create a second connection to the target"); logging(LOG_VERBOSE, "Create a second connection to the target");
sd2.iscsi_ctx = iscsi_context_login(initiatorname2, sd->iscsi_url, &sd2.iscsi_lun); memset(&sd2, 0, sizeof(sd2));
sd2.iscsi_url = sd->iscsi_url;
sd2.iscsi_lun = sd->iscsi_lun;
sd2.iscsi_ctx = iscsi_context_login(initiatorname2, sd2.iscsi_url, &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");
return; return;