Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

205 lines (184 sloc) 6.323 kb
/*
Copyright (C) 2012 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include "iscsi.h"
#include "scsi-lowlevel.h"
#include "iscsi-test.h"
int T0182_writesame10_beyondeol(const char *initiator, const char *url, int data_loss _U_, int show_info)
{
struct iscsi_context *iscsi;
struct scsi_task *task;
struct scsi_readcapacity16 *rc16;
int ret, i, lun;
uint32_t block_size;
uint64_t num_blocks;
unsigned char buf[4096];
printf("0182_writesame10_beyondeol:\n");
printf("=======================\n");
if (show_info) {
printf("Test that WRITESAME10 fails if writing beyond end-of-lun.\n");
printf("This test is skipped for LUNs with more than 2^31 blocks\n");
printf("1, Write 1-256 blocks one block beyond end-of-lun.\n");
printf("2, Write 1-256 blocks at LBA 2^31\n");
printf("3, Write 1-256 blocks at LBA -1\n");
printf("\n");
return 0;
}
iscsi = iscsi_context_login(initiator, url, &lun);
if (iscsi == NULL) {
printf("Failed to login to target\n");
return -1;
}
/* find the size of the LUN */
task = iscsi_readcapacity16_sync(iscsi, lun);
if (task == NULL) {
printf("Failed to send READCAPACITY16 command: %s\n", iscsi_get_error(iscsi));
ret = -1;
goto finished;
}
if (task->status != SCSI_STATUS_GOOD) {
printf("READCAPACITY16 command: failed with sense. %s\n", iscsi_get_error(iscsi));
ret = -1;
scsi_free_scsi_task(task);
goto finished;
}
rc16 = scsi_datain_unmarshall(task);
if (rc16 == NULL) {
printf("failed to unmarshall READCAPACITY10 data. %s\n", iscsi_get_error(iscsi));
ret = -1;
scsi_free_scsi_task(task);
goto finished;
}
block_size = rc16->block_length;
num_blocks = rc16->returned_lba;
scsi_free_scsi_task(task);
if (!data_loss) {
printf("--dataloss flag is not set. Skipping test\n");
ret = -2;
goto finished;
}
ret = 0;
if (num_blocks >= 0x80000000) {
printf("[SKIPPED]\n");
printf("LUN is too big for read-beyond-eol tests with WRITESAME10. Skipping test.\n");
ret = -2;
goto finished;
}
/* write 1 - 256 blocks beyond the end of the device */
printf("Writing 1-256 blocks beyond end-of-device ... ");
for (i = 2; i <= 257; i++) {
task = iscsi_writesame10_sync(iscsi, lun, buf, block_size,
num_blocks, i, 0, 0, 0, 0, 0, 0);
if (task == NULL) {
printf("[FAILED]\n");
printf("Failed to send WRITESAME10 command: %s\n", iscsi_get_error(iscsi));
ret = -1;
goto test2;
}
if (task->status == SCSI_STATUS_CHECK_CONDITION
&& task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST
&& task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE) {
printf("[SKIPPED]\n");
printf("Opcode is not implemented on target\n");
scsi_free_scsi_task(task);
ret = -2;
goto finished;
}
if (task->status == SCSI_STATUS_GOOD) {
printf("[FAILED]\n");
printf("WRITESAME10 command should fail when writing beyond end of device\n");
ret = -1;
scsi_free_scsi_task(task);
goto test2;
}
if (task->status != SCSI_STATUS_CHECK_CONDITION
|| task->sense.key != SCSI_SENSE_ILLEGAL_REQUEST
|| task->sense.ascq != SCSI_SENSE_ASCQ_LBA_OUT_OF_RANGE) {
printf("[FAILED]\n");
printf("WRITESAME10 failed but with the wrong sense code. It should have failed with ILLEGAL_REQUEST/LBA_OUT_OF_RANGE. Sense:%s\n", iscsi_get_error(iscsi));
ret = -1;
scsi_free_scsi_task(task);
goto test2;
}
scsi_free_scsi_task(task);
}
printf("[OK]\n");
test2:
/* writing 1 - 256 blocks at LBA 2^31 */
printf("Writing 1-256 blocks at LBA 2^31 ... ");
for (i = 1; i <= 256; i++) {
task = iscsi_writesame10_sync(iscsi, lun, buf, block_size,
0x80000000, i, 0, 0, 0, 0, 0, 0);
if (task == NULL) {
printf("[FAILED]\n");
printf("Failed to send WRITESAME10 command: %s\n", iscsi_get_error(iscsi));
ret = -1;
goto test3;
}
if (task->status == SCSI_STATUS_GOOD) {
printf("[FAILED]\n");
printf("WRITESAME10 command should fail when writing at LBA 2^31\n");
ret = -1;
scsi_free_scsi_task(task);
goto test3;
}
if (task->status != SCSI_STATUS_CHECK_CONDITION
|| task->sense.key != SCSI_SENSE_ILLEGAL_REQUEST
|| task->sense.ascq != SCSI_SENSE_ASCQ_LBA_OUT_OF_RANGE) {
printf("[FAILED]\n");
printf("WRITESAME10 failed but with the wrong sense code. It should have failed with ILLEGAL_REQUEST/LBA_OUT_OF_RANGE. Sense:%s\n", iscsi_get_error(iscsi));
ret = -1;
scsi_free_scsi_task(task);
goto test3;
}
scsi_free_scsi_task(task);
}
printf("[OK]\n");
test3:
/* write 1 - 256 blocks at LBA -1 */
printf("Writing 1-256 blocks at LBA -1 ... ");
for (i = 1; i <= 256; i++) {
task = iscsi_writesame10_sync(iscsi, lun, buf, block_size,
-1, i, 0, 0, 0, 0, 0, 0);
if (task == NULL) {
printf("[FAILED]\n");
printf("Failed to send WRITESAME10 command: %s\n", iscsi_get_error(iscsi));
ret = -1;
goto test4;
}
if (task->status == SCSI_STATUS_GOOD) {
printf("[FAILED]\n");
printf("WRITESAME10 command should fail when reading at LBA -1\n");
ret = -1;
scsi_free_scsi_task(task);
goto test4;
}
if (task->status != SCSI_STATUS_CHECK_CONDITION
|| task->sense.key != SCSI_SENSE_ILLEGAL_REQUEST
|| task->sense.ascq != SCSI_SENSE_ASCQ_LBA_OUT_OF_RANGE) {
printf("[FAILED]\n");
printf("WRITESAME10 failed but with the wrong sense code. It should have failed with ILLEGAL_REQUEST/LBA_OUT_OF_RANGE. Sense:%s\n", iscsi_get_error(iscsi));
ret = -1;
scsi_free_scsi_task(task);
goto test4;
}
scsi_free_scsi_task(task);
}
printf("[OK]\n");
test4:
finished:
iscsi_logout_sync(iscsi);
iscsi_destroy_context(iscsi);
return ret;
}
Jump to Line
Something went wrong with that request. Please try again.