Beispiel #1
0
void
test_read10_simple(void)
{
	int i, ret;


	logging(LOG_VERBOSE, LOG_BLANK_LINE);
	logging(LOG_VERBOSE, "Test READ10 of 1-256 blocks at the start of the LUN");
	for (i = 1; i <= 256; i++) {
		if (maximum_transfer_length && maximum_transfer_length < i) {
			break;
		}
		ret = read10(sd, NULL, 0, i * block_size,
			     block_size, 0, 0, 0, 0, 0, NULL,
			     EXPECT_STATUS_GOOD);
		CU_ASSERT_EQUAL(ret, 0);
	}


	logging(LOG_VERBOSE, "Test READ10 of 1-256 blocks at the end of the LUN");
	for (i = 1; i <= 256; i++) {
		if (maximum_transfer_length && maximum_transfer_length < i) {
			break;
		}
		ret = read10(sd, NULL, num_blocks - i,
			     i * block_size, block_size, 0, 0, 0, 0, 0, NULL,
			     EXPECT_STATUS_GOOD);
		CU_ASSERT_EQUAL(ret, 0);
	}
}
void
test_verify10_mismatch_no_cmp(void)
{
	int i, ret;
	unsigned char *buf = alloca(256 * block_size);

	logging(LOG_VERBOSE, LOG_BLANK_LINE);
	logging(LOG_VERBOSE, "Test VERIFY10 without BYTCHK for blocks 1-255");
	for (i = 1; i <= 256; i++) {
		int offset = random() % (i * block_size);

		if (maximum_transfer_length && maximum_transfer_length < i) {
			break;
		}
		ret = read10(sd, NULL, 0, i * block_size,
			     block_size, 0, 0, 0, 0, 0, buf,
			     EXPECT_STATUS_GOOD);
		CU_ASSERT_EQUAL(ret, 0);

		/* flip a random byte in the data */
		buf[offset] ^= 'X';
		logging(LOG_VERBOSE, "Flip some bits in the data");

		ret = verify10(sd, 0, i * block_size,
			       block_size, 0, 0, 0, buf,
			       EXPECT_STATUS_GOOD);
		if (ret == -2) {
			logging(LOG_NORMAL, "[SKIPPED] VERIFY10 is not implemented.");
			CU_PASS("[SKIPPED] Target does not support VERIFY10. Skipping test");
			return;
		}
		CU_ASSERT_EQUAL(ret, 0);
	}

	logging(LOG_VERBOSE, "Test VERIFY10 without BYTCHK of 1-256 blocks at the end of the LUN");
	for (i = 1; i <= 256; i++) {
		int offset = random() % (i * block_size);

		if (maximum_transfer_length && maximum_transfer_length < i) {
			break;
		}
		ret = read10(sd, NULL, num_blocks - i,
			     i * block_size, block_size, 0, 0, 0, 0, 0, buf,
			     EXPECT_STATUS_GOOD);
		CU_ASSERT_EQUAL(ret, 0);

		/* flip a random byte in the data */
		buf[offset] ^= 'X';
		logging(LOG_VERBOSE, "Flip some bits in the data");

		ret = verify10(sd, num_blocks - i,
			       i * block_size, block_size, 0, 0, 0, buf,
			       EXPECT_STATUS_GOOD);
		CU_ASSERT_EQUAL(ret, 0);
	}
}
Beispiel #3
0
void
test_verify12_flags(void)
{
	int ret;
	unsigned char *buf = alloca(block_size);

	logging(LOG_VERBOSE, LOG_BLANK_LINE);
	logging(LOG_VERBOSE, "Test VERIFY12 flags");

	ret = read10(iscsic, tgt_lun, 0, block_size,
		     block_size, 0, 0, 0, 0, 0, buf);
	CU_ASSERT_EQUAL(ret, 0);


	logging(LOG_VERBOSE, "Test VERIFY12 with DPO==1");
	ret = verify12(iscsic, tgt_lun, 0, block_size,
		       block_size, 0, 1, 0, buf);
	if (ret == -2) {
		logging(LOG_NORMAL, "[SKIPPED] VERIFY12 is not implemented.");
		CU_PASS("[SKIPPED] Target does not support VERIFY12. Skipping test");
		return;
	}
	CU_ASSERT_EQUAL(ret, 0);


	logging(LOG_VERBOSE, "Test VERIFY12 with BYTCHK==1");
	ret = verify12(iscsic, tgt_lun, 0, block_size,
		       block_size, 0, 0, 1, buf);
	CU_ASSERT_EQUAL(ret, 0);
}
void
test_verify10_vrprotect(void)
{
	int i, ret;
	unsigned char *buf = alloca(block_size);


	logging(LOG_VERBOSE, LOG_BLANK_LINE);
	logging(LOG_VERBOSE, "Test VERIFY10 with non-zero VRPROTECT");

	CHECK_FOR_SBC;

	if (!inq->protect || (rc16 != NULL && !rc16->prot_en)) {
		logging(LOG_VERBOSE, "Device does not support/use protection information. All commands should fail.");
		for (i = 1; i < 8; i++) {
			ret = read10(iscsic, tgt_lun, 0, block_size,
			    block_size, 0, 0, 0, 0, 0, buf);
			CU_ASSERT_EQUAL(ret, 0);
	
			ret = verify10_invalidfieldincdb(iscsic, tgt_lun, 0, block_size,
							 block_size, i, 0, 1, buf);
			if (ret == -2) {
				logging(LOG_NORMAL, "[SKIPPED] VERIFY10 is not implemented.");
				CU_PASS("[SKIPPED] Target does not support VERIFY10. Skipping test");
				return;
			}
			CU_ASSERT_EQUAL(ret, 0);
		}
		return;
	}

	logging(LOG_NORMAL, "No tests for devices that support protection information yet.");
}
void
test_read10_0blocks(void)
{
	int ret;

	logging(LOG_VERBOSE, LOG_BLANK_LINE);
	logging(LOG_VERBOSE, "Test READ10 0-blocks at LBA==0");
	ret = read10(iscsic, tgt_lun, 0, 0, block_size,
		     0, 0, 0, 0, 0, NULL);
	CU_ASSERT_EQUAL(ret, 0);

	if (num_blocks > 0x80000000) {
		CU_PASS("[SKIPPED] LUN is too big");
		return;
	}

	logging(LOG_VERBOSE, "Test READ10 0-blocks one block past end-of-LUN");
	ret = read10_lbaoutofrange(iscsic, tgt_lun, num_blocks + 1, 0,
				   block_size, 0, 0, 0, 0, 0, NULL);
	CU_ASSERT_EQUAL(ret, 0);


	logging(LOG_VERBOSE, "Test READ10 0-blocks at LBA==2^31");
	ret = read10_lbaoutofrange(iscsic, tgt_lun, 0x80000000, 0, block_size,
				   0, 0, 0, 0, 0, NULL);
	CU_ASSERT_EQUAL(ret, 0);


	logging(LOG_VERBOSE, "Test READ10 0-blocks at LBA==-1");
	ret = read10_lbaoutofrange(iscsic, tgt_lun, -1, 0, block_size,
				   0, 0, 0, 0, 0, NULL);
	CU_ASSERT_EQUAL(ret, 0);
}
Beispiel #6
0
int main(void) {
    usb_dev_handle *dev = NULL; /* the device handle */
    uint8_t readBuffer[0x200*0x100];

    /* Set up USB */
    usb_init();
    usb_find_busses();
    usb_find_devices();

    if (!(dev = open_dev())) {
        perror("device not found!\n");
		exit(EXIT_FAILURE);
    }
/*
    if (usb_set_configuration(dev, 1) < 0) {
        perror("setting config 1 failed\n");
        usb_close(dev);
        exit(EXIT_FAILURE);
    }
*/
    if (usb_claim_interface(dev, 0) < 0)
    {
        perror("claiming interface failed\n");
        usb_close(dev);
        exit(EXIT_FAILURE);
    }
    //FIXME: sniffed
    read10(readBuffer,0x100,0x0,dev);
    printReadBuffer(readBuffer);

    /* Clean up */
    usb_release_interface(dev, 0);
    usb_close(dev);
    exit(0);
}
Beispiel #7
0
void
test_verify10_flags(void)
{
	int ret;
	unsigned char *buf = malloc(block_size);

	logging(LOG_VERBOSE, LOG_BLANK_LINE);
	logging(LOG_VERBOSE, "Test VERIFY10 flags");

	ret = read10(sd, NULL, 0, block_size,
		     block_size, 0, 0, 0, 0, 0, buf,
		     EXPECT_STATUS_GOOD);
	CU_ASSERT_EQUAL(ret, 0);


	logging(LOG_VERBOSE, "Test VERIFY10 with BYTCHK==1");
	ret = verify10(sd, 0, block_size,
		       block_size, 0, 0, 1, buf,
		       EXPECT_STATUS_GOOD);
	if (ret == -2) {
		logging(LOG_NORMAL, "[SKIPPED] VERIFY10 is not implemented.");
		CU_PASS("[SKIPPED] Target does not support VERIFY10. Skipping test");
		free(buf);
		return;
	}
	CU_ASSERT_EQUAL(ret, 0);
	free(buf);
}
void
test_writesame10_unmap_until_end(void)
{
	int ret;
	unsigned int i;

	CHECK_FOR_DATALOSS;
	CHECK_FOR_THIN_PROVISIONING;
	CHECK_FOR_LBPWS10;
	CHECK_FOR_SBC;

	if (inq_bl->wsnz) {
	    logging(LOG_NORMAL, "[SKIPPED] WRITESAME10 does not support 0-blocks.");
	    CU_PASS("[SKIPPED] WRITESAME10 does not support 0-blocks.");
	    return;
	}

	logging(LOG_VERBOSE, LOG_BLANK_LINE);
	logging(LOG_VERBOSE, "Test WRITESAME10 of 1-256 blocks at the end of the LUN by setting number-of-blocks==0");
	for (i = 1; i <= 256; i++) {
		unsigned char *buf = malloc(block_size * i);

		logging(LOG_VERBOSE, "Write %d blocks of 0xFF", i);
		memset(buf, 0xff, block_size * i);
		ret = write10(sd, num_blocks - i,
			      i * block_size, block_size, 0, 0, 0, 0, 0, buf,
			      EXPECT_STATUS_GOOD);
		CU_ASSERT_EQUAL(ret, 0);

		logging(LOG_VERBOSE, "Unmap %d blocks using WRITESAME10", i);
		ret = writesame10(sd, num_blocks - i,
				  block_size, 0, 0, 1, 0, 0, buf,
				  EXPECT_STATUS_GOOD);
		CU_ASSERT_EQUAL(ret, 0);

		if (rc16->lbprz) {
			logging(LOG_VERBOSE, "LBPRZ is set. Read the unmapped "
				"blocks back and verify they are all zero");

			logging(LOG_VERBOSE, "Read %d blocks and verify they "
				"are now zero", i);
			ret = read10(sd, NULL, num_blocks - i,
				     i * block_size, block_size,
				     0, 0, 0, 0, 0, buf,
				     EXPECT_STATUS_GOOD);
			CU_ASSERT(all_zeroes(buf, i * block_size));
		} else {
			logging(LOG_VERBOSE, "LBPRZ is clear. Skip the read "
				"and verify zero test");
		}
		free(buf);
	}
}
Beispiel #9
0
void
test_mandatory_sbc(void)
{
	int ret;
	//unsigned char buf[4096];
	//struct unmap_list list[1];

	logging(LOG_VERBOSE, LOG_BLANK_LINE);
	logging(LOG_VERBOSE, "Test support for all mandatory opcodes on SBC devices");

	CHECK_FOR_SBC;

	logging(LOG_VERBOSE, "Test INQUIRY.");
	ret = inquiry(sd, NULL, 0, 0, 255,
		      EXPECT_STATUS_GOOD);
	CU_ASSERT_EQUAL(ret, 0);

	logging(LOG_VERBOSE, "Test READCAPACITY10.");
	ret = readcapacity10(sd, NULL, 0, 0,
			     EXPECT_STATUS_GOOD);
	CU_ASSERT_EQUAL(ret, 0);

	if (sbc3_support) {
		logging(LOG_VERBOSE, "Test READCAPACITY16. The device claims SBC-3 support.");
		ret = readcapacity16(sd, NULL, 15,
				     EXPECT_STATUS_GOOD);
		CU_ASSERT_EQUAL(ret, 0);
	}

	logging(LOG_VERBOSE, "Test READ10.");
	ret = read10(sd, NULL, 0, block_size, block_size,
		     0, 0, 0, 0, 0, NULL,
		     EXPECT_STATUS_GOOD);
	CU_ASSERT_EQUAL(ret, 0);

	if (sbc3_support) {
		logging(LOG_VERBOSE, "Test READ16. the device claims SBC-3 support.");
		ret = read16(sd, 0, block_size, block_size,
			     0, 0, 0, 0, 0, NULL,
			     EXPECT_STATUS_GOOD);
		CU_ASSERT_EQUAL(ret, 0);
	}

	logging(LOG_VERBOSE, "Test TESTUNITREADY.");
	ret = testunitready(sd,
			    EXPECT_STATUS_GOOD);
	CU_ASSERT_EQUAL(ret, 0);
}
void
test_verify12_simple(void)
{
	int i, ret;
	unsigned char *buf = alloca(256 * block_size);

	logging(LOG_VERBOSE, LOG_BLANK_LINE);
	logging(LOG_VERBOSE, "Test VERIFY12 of 1-256 blocks at the start of the LUN");
	for (i = 1; i <= 256; i++) {
		if (maximum_transfer_length && maximum_transfer_length < i) {
			break;
		}
		ret = read10(sd, NULL, 0, i * block_size,
			     block_size, 0, 0, 0, 0, 0, buf,
			     EXPECT_STATUS_GOOD);
		CU_ASSERT_EQUAL(ret, 0);

		ret = verify12(sd, 0, i * block_size,
			       block_size, 0, 0, 1, buf,
			       EXPECT_STATUS_GOOD);
		if (ret == -2) {
			logging(LOG_NORMAL, "[SKIPPED] VERIFY12 is not implemented.");
			CU_PASS("[SKIPPED] Target does not support VERIFY12. Skipping test");
			return;
		}
		CU_ASSERT_EQUAL(ret, 0);
	}

	logging(LOG_VERBOSE, "Test VERIFY12 of 1-256 blocks at the end of the LUN");
	for (i = 1; i <= 256; i++) {
		if (maximum_transfer_length && maximum_transfer_length < i) {
			break;
		}
		ret = read12(sd, num_blocks - i,
			     i * block_size, block_size, 0, 0, 0, 0, 0, buf,
			     EXPECT_STATUS_GOOD);
		CU_ASSERT_EQUAL(ret, 0);

		ret = verify12(sd, num_blocks - i,
			       i * block_size, block_size, 0, 0, 1, buf,
			       EXPECT_STATUS_GOOD);
		CU_ASSERT_EQUAL(ret, 0);
	}
}
Beispiel #11
0
void
test_write10_residuals(void)
{
	struct scsi_task *task_ret;
	unsigned char buf[10000];
	struct iscsi_data data;
	int ret;
	unsigned int i;

	logging(LOG_VERBOSE, LOG_BLANK_LINE);
	logging(LOG_VERBOSE, "Test WRITE10 commands with residuals");
	logging(LOG_VERBOSE, "Block size is %zu", block_size);

	CHECK_FOR_DATALOSS;
	CHECK_FOR_SBC;

	/* Try a write10 of 1 block but xferlength == 0 */
	task = malloc(sizeof(struct scsi_task));
	CU_ASSERT_PTR_NOT_NULL(task);

	memset(task, 0, sizeof(struct scsi_task));
	task->cdb[0] = SCSI_OPCODE_WRITE10;
	task->cdb[8] = 1;
	task->cdb_size = 10;
	task->xfer_dir = SCSI_XFER_WRITE;
	task->expxferlen = 0;

	/*
	 * we don't want autoreconnect since some targets will drop the session
	 * on this condition.
	 */
	iscsi_set_noautoreconnect(iscsic, 1);

	logging(LOG_VERBOSE, "Try writing one block but with iSCSI expected transfer length==0");

	task_ret = iscsi_scsi_command_sync(iscsic, tgt_lun, task, NULL);
	CU_ASSERT_PTR_NOT_NULL(task_ret);
	CU_ASSERT_NOT_EQUAL(task->status, SCSI_STATUS_CANCELLED); /* XXX redundant? */

	if (task->status        == SCSI_STATUS_CHECK_CONDITION
	    && task->sense.key  == SCSI_SENSE_ILLEGAL_REQUEST
	    && task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE) {
		logging(LOG_NORMAL, "[SKIPPED] WRITE10 is not implemented.");
		CU_PASS("WRITE10 is not implemented.");
		return;
	}	
	logging(LOG_VERBOSE, "Verify that the target returned SUCCESS");
	if (task->status != SCSI_STATUS_GOOD) {
		logging(LOG_VERBOSE, "[FAILED] Target returned error %s",
			iscsi_get_error(iscsic));
	}
	CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD);

	logging(LOG_VERBOSE, "Verify residual overflow flag is set");
	if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) {
		logging(LOG_VERBOSE, "[FAILED] Target did not set residual "
			"overflow flag");
	}
	CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW);

	logging(LOG_VERBOSE, "Verify we got %zu bytes of residual overflow",
		block_size);
	if (task->residual != block_size) {
		logging(LOG_VERBOSE, "[FAILED] Target did not set correct "
			"amount of residual. Expected %zu but got %zu.",
			block_size, task->residual);
	}
	CU_ASSERT_EQUAL(task->residual, block_size);
	scsi_free_scsi_task(task);
	task = NULL;

	/* in case the previous test failed the session */
	iscsi_set_noautoreconnect(iscsic, 0);


	logging(LOG_VERBOSE, "Try writing one block but with iSCSI expected transfer length==10000");
	task = malloc(sizeof(struct scsi_task));
	CU_ASSERT_PTR_NOT_NULL(task);

	memset(task, 0, sizeof(struct scsi_task));
	task->cdb[0] = SCSI_OPCODE_WRITE10;
	task->cdb[8] = 1;
	task->cdb_size = 10;
	task->xfer_dir = SCSI_XFER_WRITE;
	task->expxferlen = 10000;

	data.size = task->expxferlen;
	data.data = &buf[0];
	task_ret = iscsi_scsi_command_sync(iscsic, tgt_lun, task, &data);
	CU_ASSERT_PTR_NOT_NULL(task_ret);

	logging(LOG_VERBOSE, "Verify that the target returned SUCCESS");
	if (task->status != SCSI_STATUS_GOOD) {
		logging(LOG_VERBOSE, "[FAILED] Target returned error %s",
			iscsi_get_error(iscsic));
	}
	CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD);

	logging(LOG_VERBOSE, "Verify residual underflow flag is set");
	if (task->residual_status != SCSI_RESIDUAL_UNDERFLOW) {
		logging(LOG_VERBOSE, "[FAILED] Target did not set residual "
			"underflow flag");
	}
	CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_UNDERFLOW);

	logging(LOG_VERBOSE, "Verify we got %zu bytes of residual underflow",
		10000 - block_size);
	if (task->residual != 10000 - block_size) {
		logging(LOG_VERBOSE, "[FAILED] Target did not set correct "
			"amount of residual. Expected %zu but got %zu.",
			10000 - block_size, task->residual);
	}
	CU_ASSERT_EQUAL(task->residual, 10000 - block_size);
	scsi_free_scsi_task(task);
	task = NULL;


	logging(LOG_VERBOSE, "Try writing one block but with iSCSI expected transfer length==200");
	task = malloc(sizeof(struct scsi_task));
	CU_ASSERT_PTR_NOT_NULL(task);

	memset(task, 0, sizeof(struct scsi_task));
	task->cdb[0] = SCSI_OPCODE_WRITE10;
	task->cdb[8] = 1;
	task->cdb_size = 10;
	task->xfer_dir = SCSI_XFER_WRITE;
	task->expxferlen = 200;

	data.size = task->expxferlen;
	data.data = &buf[0];
	task_ret = iscsi_scsi_command_sync(iscsic, tgt_lun, task, &data);
	CU_ASSERT_PTR_NOT_NULL(task_ret);

	logging(LOG_VERBOSE, "Verify that the target returned SUCCESS");
	if (task->status != SCSI_STATUS_GOOD) {
		logging(LOG_VERBOSE, "[FAILED] Target returned error %s",
			iscsi_get_error(iscsic));
	}
	CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD);

	logging(LOG_VERBOSE, "Verify residual overflow flag is set");
	if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) {
		logging(LOG_VERBOSE, "[FAILED] Target did not set residual "
			"overflow flag");
	}
	CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW);

	logging(LOG_VERBOSE, "Verify we got %zu bytes of residual overflow",
		block_size - 200);
	if (task->residual != block_size - 200) {
		logging(LOG_VERBOSE, "[FAILED] Target did not set correct "
			"amount of residual. Expected %zu but got %zu.",
			block_size - 200, task->residual);
	}
	CU_ASSERT_EQUAL(task->residual, block_size - 200);

	scsi_free_scsi_task(task);
	task = NULL;



	logging(LOG_VERBOSE, "Try writing two blocks but iSCSI expected "
		"transfer length==%zu (==one block)", block_size);
	task = malloc(sizeof(struct scsi_task));
	CU_ASSERT_PTR_NOT_NULL(task);

	memset(task, 0, sizeof(struct scsi_task));
	task->cdb[0] = SCSI_OPCODE_WRITE10;
	task->cdb[8] = 2;
	task->cdb_size = 10;
	task->xfer_dir = SCSI_XFER_WRITE;
	task->expxferlen = block_size;

	data.size = task->expxferlen;
	data.data = &buf[0];
	task_ret = iscsi_scsi_command_sync(iscsic, tgt_lun, task, &data);
	CU_ASSERT_PTR_NOT_NULL(task_ret);

	logging(LOG_VERBOSE, "Verify that the target returned SUCCESS");
	if (task->status != SCSI_STATUS_GOOD) {
		logging(LOG_VERBOSE, "[FAILED] Target returned error %s",
			iscsi_get_error(iscsic));
	}
	CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD);

	logging(LOG_VERBOSE, "Verify residual overflow flag is set");
	if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) {
		logging(LOG_VERBOSE, "[FAILED] Target did not set residual "
			"overflow flag");
	}
	CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW);

	logging(LOG_VERBOSE, "Verify we got one block of residual overflow");
	if (task->residual != block_size) {
		logging(LOG_VERBOSE, "[FAILED] Target did not set correct "
			"amount of residual. Expected %zu but got %zu.",
			block_size, task->residual);
	}
	CU_ASSERT_EQUAL(task->residual, block_size);

	scsi_free_scsi_task(task);
	task = NULL;




	logging(LOG_VERBOSE, "Verify that if iSCSI EDTL > SCSI TL then we only write SCSI TL amount of data");

	logging(LOG_VERBOSE, "Write two blocks of 'a'");
	memset(buf, 'a', 10000);
	ret = write10(iscsic, tgt_lun, 0, 2 * block_size,
	    block_size, 0, 0, 0, 0, 0, buf);
	CU_ASSERT_EQUAL(ret, 0);

	logging(LOG_VERBOSE, "Write one block of 'b' but set iSCSI EDTL to 2 blocks.");
	task = malloc(sizeof(struct scsi_task));
	CU_ASSERT_PTR_NOT_NULL(task);

	memset(buf, 'b', 10000);

	memset(task, 0, sizeof(struct scsi_task));
	task->cdb[0] = SCSI_OPCODE_WRITE10;
	task->cdb[8] = 1;
	task->cdb_size = 10;
	task->xfer_dir = SCSI_XFER_WRITE;
	task->expxferlen = 2 * block_size;

	data.size = task->expxferlen;
	data.data = &buf[0];
	task_ret = iscsi_scsi_command_sync(iscsic, tgt_lun, task, &data);
	CU_ASSERT_PTR_NOT_NULL(task_ret);

	logging(LOG_VERBOSE, "Verify that the target returned SUCCESS");
	if (task->status != SCSI_STATUS_GOOD) {
		logging(LOG_VERBOSE, "[FAILED] Target returned error %s",
			iscsi_get_error(iscsic));
	}
	CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD);

	logging(LOG_VERBOSE, "Verify residual underflow flag is set");
	if (task->residual_status != SCSI_RESIDUAL_UNDERFLOW) {
		logging(LOG_VERBOSE, "[FAILED] Target did not set residual "
			"underflow flag");
	}
	CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_UNDERFLOW);

	logging(LOG_VERBOSE, "Verify we got one block of residual underflow");
	if (task->residual != block_size) {
		logging(LOG_VERBOSE, "[FAILED] Target did not set correct "
			"amount of residual. Expected %zu but got %zu.",
			block_size, task->residual);
	}
	CU_ASSERT_EQUAL(task->residual, block_size);
	scsi_free_scsi_task(task);
	task = NULL;

	logging(LOG_VERBOSE, "Read the two blocks");
	ret = read10(iscsic, tgt_lun, 0, 2* block_size,
		     block_size, 0, 0, 0, 0, 0, buf);
	CU_ASSERT_EQUAL(ret, 0);

	logging(LOG_VERBOSE, "Verify that the first block was changed to 'b'");
	for (i = 0; i < block_size; i++) {
		if (buf[i] != 'b') {
			logging(LOG_NORMAL, "First block did not contain expected 'b'");
			CU_FAIL("Block was not written correctly");
			break;
		}
	}

	logging(LOG_VERBOSE, "Verify that the second block was NOT overwritten and still contains 'a'");
	for (i = block_size; i < 2 * block_size; i++) {
		if (buf[i] != 'a') {
			logging(LOG_NORMAL, "Second block was overwritten and no longer contain 'a'");
			CU_FAIL("Second block was incorrectly overwritten");
			break;
		}
	}


	logging(LOG_VERBOSE, "Verify that if iSCSI EDTL < SCSI TL then we only write iSCSI EDTL amount of data");

	logging(LOG_VERBOSE, "Write two blocks of 'a'");
	memset(buf, 'a', 10000);
	ret = write10(iscsic, tgt_lun, 0, 2 * block_size,
	    block_size, 0, 0, 0, 0, 0, buf);
	CU_ASSERT_EQUAL(ret, 0);

	logging(LOG_VERBOSE, "Write two blocks of 'b' but set iSCSI EDTL to 1 blocks.");
	task = malloc(sizeof(struct scsi_task));
	CU_ASSERT_PTR_NOT_NULL(task);

	memset(buf, 'b', 10000);

	memset(task, 0, sizeof(struct scsi_task));
	task->cdb[0] = SCSI_OPCODE_WRITE10;
	task->cdb[8] = 2;
	task->cdb_size = 10;
	task->xfer_dir = SCSI_XFER_WRITE;
	task->expxferlen = block_size;

	data.size = task->expxferlen;
	data.data = &buf[0];
	task_ret = iscsi_scsi_command_sync(iscsic, tgt_lun, task, &data);
	CU_ASSERT_PTR_NOT_NULL(task_ret);

	logging(LOG_VERBOSE, "Verify that the target returned SUCCESS");
	if (task->status != SCSI_STATUS_GOOD) {
		logging(LOG_VERBOSE, "[FAILED] Target returned error %s",
			iscsi_get_error(iscsic));
	}
	CU_ASSERT_EQUAL(task->status, SCSI_STATUS_GOOD);

	logging(LOG_VERBOSE, "Verify residual overflow flag is set");
	if (task->residual_status != SCSI_RESIDUAL_OVERFLOW) {
		logging(LOG_VERBOSE, "[FAILED] Target did not set residual "
			"overflow flag");
	}
	CU_ASSERT_EQUAL(task->residual_status, SCSI_RESIDUAL_OVERFLOW);

	logging(LOG_VERBOSE, "Verify we got one block of residual overflow");
	if (task->residual != block_size) {
		logging(LOG_VERBOSE, "[FAILED] Target did not set correct "
			"amount of residual. Expected %zu but got %zu.",
			block_size, task->residual);
	}
	CU_ASSERT_EQUAL(task->residual, block_size);
	scsi_free_scsi_task(task);
	task = NULL;

	logging(LOG_VERBOSE, "Read the two blocks");
	ret = read10(iscsic, tgt_lun, 0, 2* block_size,
		     block_size, 0, 0, 0, 0, 0, buf);
	CU_ASSERT_EQUAL(ret, 0);

	logging(LOG_VERBOSE, "Verify that the first block was changed to 'b'");
	for (i = 0; i < block_size; i++) {
		if (buf[i] != 'b') {
			logging(LOG_NORMAL, "First block did not contain expected 'b'");
			CU_FAIL("Block was not written correctly");
			break;
		}
	}

	logging(LOG_VERBOSE, "Verify that the second block was NOT overwritten and still contains 'a'");
	for (i = block_size; i < 2 * block_size; i++) {
		if (buf[i] != 'a') {
			logging(LOG_NORMAL, "Second block was overwritten and no longer contain 'a'");
			CU_FAIL("Second block was incorrectly overwritten");
			break;
		}
	}
}
void
test_modesense6_control_swp(void)
{
	struct scsi_task *ms_task = NULL;
	struct scsi_mode_sense *ms;
	struct scsi_mode_page *page;
	unsigned char *buf = alloca(block_size);
	int ret;

	CHECK_FOR_DATALOSS;
	CHECK_FOR_SBC;

	logging(LOG_VERBOSE, LOG_BLANK_LINE);
	logging(LOG_VERBOSE, "Test of MODESENSE6 CONTROL SWP flag");


	logging(LOG_VERBOSE, "Set SWP to enable write protect");
	ret = set_swp(sd);
	if (ret == -2) {
		CU_PASS("[SKIPPED] Target does not support changing SWP");
		return;
	}
	CU_ASSERT_EQUAL(ret, 0);
	if (ret) {
		goto finished;
	}

	logging(LOG_VERBOSE, "Read the CONTROL page back from the device");
	ret = modesense6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT,
			 SCSI_MODEPAGE_CONTROL, 0, 255,
			 EXPECT_STATUS_GOOD);
	CU_ASSERT_EQUAL(ret, 0);
	logging(LOG_VERBOSE, "[SUCCESS] CONTROL page fetched.");

	logging(LOG_VERBOSE, "Try to unmarshall the DATA-IN buffer.");
	ms = scsi_datain_unmarshall(ms_task);
	if (ms == NULL) {
		logging(LOG_NORMAL, "[FAILED] failed to unmarshall mode sense "
			"datain buffer");
		CU_FAIL("[FAILED] Failed to unmarshall the data-in buffer.");
		goto finished;
	}
	logging(LOG_VERBOSE, "[SUCCESS] Unmarshalling successful.");
	for (page = ms->pages; page; page = page->next) {
		if (page->page_code == SCSI_MODEPAGE_CONTROL) {
			break;
		}
	}
	if(page == NULL) {
		logging(LOG_NORMAL, "[WARNING] CONTROL page was not returned."
			"All devices SHOULD implement this page.");
	}

	logging(LOG_VERBOSE, "Verify that the SWP bit is set");
	if (page->control.swp == 0) {
		logging(LOG_NORMAL, "[FAILED] SWP bit is not set");
		CU_FAIL("[FAILED] SWP is not set");
		goto finished;
	}
	logging(LOG_VERBOSE, "[SUCCESS] SWP was set successfully");


	logging(LOG_VERBOSE, "Read a block from the now Read-Only device");
	ret = read10(sd, NULL, 0, block_size,
		     block_size, 0, 0, 0, 0, 0, buf,
		     EXPECT_STATUS_GOOD);
	CU_ASSERT_EQUAL(ret, 0);

	logging(LOG_VERBOSE, "Try to write a block to the Read-Only device");
	ret = write10(sd, 0, block_size,
		      block_size, 0, 0, 0, 0, 0, buf,
		      EXPECT_WRITE_PROTECTED);
	CU_ASSERT_EQUAL(ret, 0);


 finished:
	if (ms_task != NULL) {
		scsi_free_scsi_task(ms_task);
	}
	logging(LOG_VERBOSE, "Clear SWP to disable write protect");
	clear_swp(sd);
}
void
test_compareandwrite_dpofua(void)
{ 
        int ret, dpofua, usage_data_dpofua;
        struct scsi_task *ms_task = NULL;
        struct scsi_mode_sense *ms;
        struct scsi_task *rso_task = NULL;
        struct scsi_report_supported_op_codes_one_command *rsoc;

        logging(LOG_VERBOSE, LOG_BLANK_LINE);
        logging(LOG_VERBOSE, "Test COMPAREANDWRITE DPO/FUA flags");

        CHECK_FOR_SBC;
        CHECK_FOR_DATALOSS;

        logging(LOG_VERBOSE, "Read the DPOFUA flag from mode sense data");
        MODESENSE6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT,
                   SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255,
                   EXPECT_STATUS_GOOD);

        logging(LOG_VERBOSE, "[SUCCESS] Mode sense returned status GOOD");
        ms = scsi_datain_unmarshall(ms_task);
        dpofua = ms && (ms->device_specific_parameter & 0x10);
        scsi_free_scsi_task(ms_task);

        logging(LOG_VERBOSE, "Read the first block");
        ret = read10(sd, NULL, 0, block_size,
                     block_size, 0, 0, 0, 0, 0, scratch,
                     EXPECT_STATUS_GOOD);
        CU_ASSERT_EQUAL(ret, 0);
        if (ret == 0)
                memcpy(scratch + block_size, scratch, block_size);
        else
                memset(scratch, 0xa6, 2 * block_size);

        if (dpofua) {
                logging(LOG_VERBOSE, "DPOFUA flag is set. Device should allow "
                        "DPO/FUA flags in CDBs");
        } else {
                logging(LOG_VERBOSE, "DPOFUA flag is clear. Device should fail "
                        "CDBs with DPO/FUA set");
        }

        logging(LOG_VERBOSE, "Test COMPAREANDWRITE with DPO==1");
        if (dpofua) {
                COMPAREANDWRITE(sd, 0, scratch, 2 * block_size,
                                block_size, 0, 1, 0, 0,
                                EXPECT_STATUS_GOOD);
        } else {
                COMPAREANDWRITE(sd, 0, scratch, 2 * block_size,
                                block_size, 0, 1, 0, 0,
                                EXPECT_INVALID_FIELD_IN_CDB);
        }

        logging(LOG_VERBOSE, "Test COMPAREANDWRITE with FUA==1");
        if (dpofua) {
                COMPAREANDWRITE(sd, 0, scratch, 2 * block_size,
                                block_size, 0, 0, 1, 0,
                                EXPECT_STATUS_GOOD);
        } else {
                COMPAREANDWRITE(sd, 0, scratch, 2 * block_size,
                                block_size, 0, 0, 1, 0,
                                EXPECT_INVALID_FIELD_IN_CDB);
        }

        logging(LOG_VERBOSE, "Test COMPAREANDWRITE with DPO==1 FUA==1");
        if (dpofua) {
                COMPAREANDWRITE(sd, 0, scratch, 2 * block_size,
                                block_size, 0, 1, 1, 0,
                                EXPECT_STATUS_GOOD);
        } else {
                COMPAREANDWRITE(sd, 0, scratch, 2 * block_size,
                                block_size, 0, 1, 1, 0,
                                EXPECT_INVALID_FIELD_IN_CDB);
        }

        logging(LOG_VERBOSE, "Try fetching REPORT_SUPPORTED_OPCODES "
                "for COMPAREANDWRITE");
        REPORT_SUPPORTED_OPCODES(sd, &rso_task,
                                 0, SCSI_REPORT_SUPPORTING_OPCODE,
                                 SCSI_OPCODE_COMPARE_AND_WRITE,
                                 0,
                                 65535,
                                 EXPECT_STATUS_GOOD);
        logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer");
        rsoc = scsi_datain_unmarshall(rso_task);
        CU_ASSERT_PTR_NOT_NULL_FATAL(rsoc);
        
        usage_data_dpofua = rsoc->cdb_usage_data[1] & 0x18;
        if (dpofua) {
                logging(LOG_VERBOSE, "DPOFUA is set. Verify the "
                        "DPO/FUA flags are set in the CDB_USAGE_DATA");
                if (!usage_data_dpofua) {
                        logging(LOG_NORMAL, "[FAILED] DpoFua not set "
                                "in CDB_USAGE_DATE");
                        CU_FAIL("DpoFua not set in CDB_USAGE_DATE");
                }
        } else {
                logging(LOG_VERBOSE, "DPOFUA is clear. Verify the "
                        "DPO/FUA flags are clear in the CDB_USAGE_DATA");
                if (usage_data_dpofua) {
                        logging(LOG_NORMAL, "[FAILED] DpoFua not clear "
                                "in CDB_USAGE_DATE");
                        CU_FAIL("DpoFua not clear in CDB_USAGE_DATE");
                }
        }

        scsi_free_scsi_task(rso_task);
}
Beispiel #14
0
void
test_verify10_dpo(void)
{ 
	int ret, dpofua, usage_data_dpo;
	struct scsi_task *ms_task = NULL;
	struct scsi_mode_sense *ms;
	struct scsi_task *rso_task = NULL;
	struct scsi_report_supported_op_codes_one_command *rsoc;
	unsigned char *buf = alloca(block_size);

	logging(LOG_VERBOSE, LOG_BLANK_LINE);
	logging(LOG_VERBOSE, "Test VERIFY10 DPO flag");

	CHECK_FOR_SBC;

	ret = read10(sd, NULL, 0, block_size,
		     block_size, 0, 0, 0, 0, 0, buf,
		     EXPECT_STATUS_GOOD);
	CU_ASSERT_EQUAL(ret, 0);

	logging(LOG_VERBOSE, "Read the DPOFUA flag from mode sense data");
	ret = modesense6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT,
			 SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255,
			 EXPECT_STATUS_GOOD);
	CU_ASSERT_EQUAL(ret, 0);
	logging(LOG_VERBOSE, "[SUCCESS] Mode sense returned status GOOD");
	ms = scsi_datain_unmarshall(ms_task);
	dpofua = ms && (ms->device_specific_parameter & 0x10);
	scsi_free_scsi_task(ms_task);

	if (dpofua) {
		logging(LOG_VERBOSE, "DPOFUA flag is set. Device should allow "
			"DPO/FUA flags in CDBs");
	} else {
		logging(LOG_VERBOSE, "DPOFUA flag is clear. Device should fail "
			"CDBs with DPO/FUA set");
	}

	logging(LOG_VERBOSE, "Test VERIFY10 with DPO==1");
	if (dpofua) {
		ret = verify10(sd, 0, block_size,
			       block_size, 0, 1, 0, buf,
			       EXPECT_STATUS_GOOD);
		if (ret == -2) {
			logging(LOG_NORMAL, "[SKIPPED] VERIFY10 is not implemented.");
			CU_PASS("VERIFY10 is not implemented.");
			return;
		}
		CU_ASSERT_EQUAL(ret, 0);
	} else {
		ret = verify10(sd, 0, block_size,
			       block_size, 0, 1, 0, buf,
			       EXPECT_INVALID_FIELD_IN_CDB);
		if (ret == -2) {
			logging(LOG_NORMAL, "[SKIPPED] VERIFY10 is not implemented.");
			CU_PASS("VERIFY10 is not implemented.");
			return;
		}
		CU_ASSERT_EQUAL(ret, 0);
	}

	logging(LOG_VERBOSE, "Try fetching REPORT_SUPPORTED_OPCODES "
		"for VERIFY10");
	ret = report_supported_opcodes(sd, &rso_task,
				       0, SCSI_REPORT_SUPPORTING_OPCODE,
				       SCSI_OPCODE_VERIFY10,
				       0,
				       65535,
				       EXPECT_STATUS_GOOD);
	if (ret == -2) {
		logging(LOG_NORMAL, "REPORT_SUPPORTED_OPCODES not implemented. "
			"Skipping this part of the test");
		return;
	}
	logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer");
	rsoc = scsi_datain_unmarshall(rso_task);
	CU_ASSERT_NOT_EQUAL(rsoc, NULL);
	usage_data_dpo = rsoc ? rsoc->cdb_usage_data[1] & 0x10 : -1;
	if (dpofua) {
		logging(LOG_VERBOSE, "DPOFUA is set. Verify the DPO flag "
			"is set in the CDB_USAGE_DATA");
		CU_ASSERT_EQUAL(usage_data_dpo, 0x10);
	} else {
		logging(LOG_VERBOSE, "DPOFUA is clear. Verify the DPO "
			"flag is clear in the CDB_USAGE_DATA");
		CU_ASSERT_EQUAL(usage_data_dpo, 0x00);
	}
	scsi_free_scsi_task(rso_task);
}
void
test_compareandwrite_dpofua(void)
{ 
	int ret, dpofua, usage_data_dpofua;
	struct scsi_task *ms_task = NULL;
	struct scsi_mode_sense *ms;
	struct scsi_task *rso_task = NULL;
	struct scsi_report_supported_op_codes_one_command *rsoc;
	unsigned char *buf = alloca(2 * block_size);

	logging(LOG_VERBOSE, LOG_BLANK_LINE);
	logging(LOG_VERBOSE, "Test COMPAREANDWRITE DPO/FUA flags");

	CHECK_FOR_SBC;
	CHECK_FOR_DATALOSS;

	logging(LOG_VERBOSE, "Read the DPOFUA flag from mode sense data");
	ret = modesense6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT,
			 SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255,
			 EXPECT_STATUS_GOOD);
	CU_ASSERT_EQUAL(ret, 0);
	logging(LOG_VERBOSE, "[SUCCESS] Mode sense returned status GOOD");
	ms = scsi_datain_unmarshall(ms_task);
	dpofua = ms && (ms->device_specific_parameter & 0x10);
	scsi_free_scsi_task(ms_task);

	logging(LOG_VERBOSE, "Read the first block");
	ret = read10(sd, NULL, 0, block_size,
		     block_size, 0, 0, 0, 0, 0, buf,
		     EXPECT_STATUS_GOOD);
	CU_ASSERT_EQUAL(ret, 0);
	if (ret == 0)
		memcpy(buf + block_size, buf, block_size);
	else
		memset(buf, 0xa6, 2 * block_size);

	if (dpofua) {
		logging(LOG_VERBOSE, "DPOFUA flag is set. Device should allow "
			"DPO/FUA flags in CDBs");
	} else {
		logging(LOG_VERBOSE, "DPOFUA flag is clear. Device should fail "
			"CDBs with DPO/FUA set");
	}

	logging(LOG_VERBOSE, "Test COMPAREANDWRITE with DPO==1");
	if (dpofua) {
		ret = compareandwrite(sd, 0, buf, 2 * block_size,
				      block_size, 0, 1, 0, 0,
				      EXPECT_STATUS_GOOD);
		CU_ASSERT_EQUAL(ret, 0);
	} else {
		ret = compareandwrite(sd, 0, buf, 2 * block_size,
				      block_size, 0, 1, 0, 0,
				      EXPECT_INVALID_FIELD_IN_CDB);
		CU_ASSERT_EQUAL(ret, 0);
	}

	logging(LOG_VERBOSE, "Test COMPAREANDWRITE with FUA==1");
	if (dpofua) {
		ret = compareandwrite(sd, 0, buf, 2 * block_size,
				      block_size, 0, 0, 1, 0,
				      EXPECT_STATUS_GOOD);
		CU_ASSERT_EQUAL(ret, 0);
	} else {
		ret = compareandwrite(sd, 0, buf, 2 * block_size,
				      block_size, 0, 0, 1, 0,
				      EXPECT_INVALID_FIELD_IN_CDB);
		CU_ASSERT_EQUAL(ret, 0);
	}

	logging(LOG_VERBOSE, "Test COMPAREANDWRITE with DPO==1 FUA==1");
	if (dpofua) {
		ret = compareandwrite(sd, 0, buf, 2 * block_size,
				      block_size, 0, 1, 1, 0,
				      EXPECT_STATUS_GOOD);
		CU_ASSERT_EQUAL(ret, 0);
	} else {
		ret = compareandwrite(sd, 0, buf, 2 * block_size,
				      block_size, 0, 1, 1, 0,
				      EXPECT_INVALID_FIELD_IN_CDB);
		CU_ASSERT_EQUAL(ret, 0);
	}

	logging(LOG_VERBOSE, "Try fetching REPORT_SUPPORTED_OPCODES "
		"for COMPAREANDWRITE");
	ret = report_supported_opcodes(sd, &rso_task,
				       0, SCSI_REPORT_SUPPORTING_OPCODE,
				       SCSI_OPCODE_COMPARE_AND_WRITE,
				       0,
				       65535,
				       EXPECT_STATUS_GOOD);
	if (ret == -2) {
		logging(LOG_NORMAL, "REPORT_SUPPORTED_OPCODES not implemented. "
			"Skipping this part of the test");
		return;
	}
	logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer");
	rsoc = scsi_datain_unmarshall(rso_task);
	CU_ASSERT_NOT_EQUAL(rsoc, NULL);
	usage_data_dpofua = rsoc ? rsoc->cdb_usage_data[1] & 0x18 : -1;
	if (dpofua) {
		logging(LOG_VERBOSE, "DPOFUA is set. Verify the DPO/FUA flags "
			"are set in the CDB_USAGE_DATA");
		CU_ASSERT_EQUAL(usage_data_dpofua, 0x18);
	} else {
		logging(LOG_VERBOSE, "DPOFUA is clear. Verify the DPO/FUA "
			"flags are clear in the CDB_USAGE_DATA");
		CU_ASSERT_EQUAL(usage_data_dpofua, 0x00);
	}
	scsi_free_scsi_task(rso_task);
}
Beispiel #16
0
void
test_read10_dpofua(void)
{ 
	int ret, dpofua, usage_data_dpofua;
	struct scsi_task *ms_task = NULL;
	struct scsi_mode_sense *ms;
	struct scsi_task *rso_task = NULL;
	struct scsi_report_supported_op_codes_one_command *rsoc;

	logging(LOG_VERBOSE, LOG_BLANK_LINE);
	logging(LOG_VERBOSE, "Test READ10 DPO/FUA flags");

	CHECK_FOR_SBC;

	logging(LOG_VERBOSE, "Read the DPOFUA flag from mode sense data");
	ret = modesense6(sd, &ms_task, 0, SCSI_MODESENSE_PC_CURRENT,
			 SCSI_MODEPAGE_RETURN_ALL_PAGES, 0, 255,
			 EXPECT_STATUS_GOOD);
	CU_ASSERT_EQUAL(ret, 0);
	logging(LOG_VERBOSE, "[SUCCESS] Mode sense returned status GOOD");
	ms = scsi_datain_unmarshall(ms_task);
	dpofua = ms && (ms->device_specific_parameter & 0x10);
	scsi_free_scsi_task(ms_task);

	if (dpofua) {
		logging(LOG_VERBOSE, "DPOFUA flag is set. Device should allow "
			"DPO/FUA flags in CDBs");
	} else {
		logging(LOG_VERBOSE, "DPOFUA flag is clear. Device should fail "
			"CDBs with DPO/FUA set");
	}

	logging(LOG_VERBOSE, "Test READ10 with DPO==1");
	if (dpofua) {
		ret = read10(sd, NULL, 0,
			     block_size, block_size, 0, 1, 0, 0, 0, NULL,
			     EXPECT_STATUS_GOOD);
		CU_ASSERT_EQUAL(ret, 0);
	} else {
		ret = read10(sd, NULL, 0,
			     block_size, block_size, 0, 1, 0, 0, 0, NULL,
			     EXPECT_INVALID_FIELD_IN_CDB);
		CU_ASSERT_EQUAL(ret, 0);
	}

	logging(LOG_VERBOSE, "Test READ10 with FUA==1");
	if (dpofua) {
		ret = read10(sd, NULL, 0,
			     block_size, block_size, 0, 0, 1, 0, 0, NULL,
			     EXPECT_STATUS_GOOD);
		CU_ASSERT_EQUAL(ret, 0);
	} else {
		ret = read10(sd, NULL, 0,
			     block_size, block_size, 0, 0, 1, 0, 0, NULL,
			     EXPECT_INVALID_FIELD_IN_CDB);
		CU_ASSERT_EQUAL(ret, 0);
	}

	logging(LOG_VERBOSE, "Test READ10 with DPO==1 FUA==1");
	if (dpofua) {
		ret = read10(sd, NULL, 0,
			     block_size, block_size, 0, 1, 1, 0, 0, NULL,
			     EXPECT_STATUS_GOOD);
		CU_ASSERT_EQUAL(ret, 0);
	} else {
		ret = read10(sd, NULL, 0,
			     block_size, block_size, 0, 1, 1, 0, 0, NULL,
			     EXPECT_INVALID_FIELD_IN_CDB);
		CU_ASSERT_EQUAL(ret, 0);
	}


	logging(LOG_VERBOSE, "Try fetching REPORT_SUPPORTED_OPCODES "
		"for READ10");
	ret = report_supported_opcodes(sd, &rso_task,
				       0, SCSI_REPORT_SUPPORTING_OPCODE,
				       SCSI_OPCODE_READ10,
				       0,
				       65535,
				       EXPECT_STATUS_GOOD);
	if (ret == -2) {
		logging(LOG_NORMAL, "REPORT_SUPPORTED_OPCODES not implemented. "
			"Skipping this part of the test");
		return;
	}
	logging(LOG_VERBOSE, "Unmarshall the DATA-IN buffer");
	rsoc = scsi_datain_unmarshall(rso_task);
	if (rsoc) {
		usage_data_dpofua = rsoc->cdb_usage_data[1] & 0x18;
		if (dpofua) {
			logging(LOG_VERBOSE, "DPOFUA is set. Verify the "
				"DPO/FUA flags are set in the CDB_USAGE_DATA");
			if (!usage_data_dpofua) {
				logging(LOG_NORMAL, "[FAILED] DpoFua not set "
					"in CDB_USAGE_DATE");
				CU_FAIL("DpoFua not set in CDB_USAGE_DATE");
			}
		} else {
			logging(LOG_VERBOSE, "DPOFUA is clear. Verify the "
				"DPO/FUA flags are clear in the CDB_USAGE_DATA");
			if (usage_data_dpofua) {
				logging(LOG_NORMAL, "[FAILED] DpoFua not clear "
					"in CDB_USAGE_DATE");
				CU_FAIL("DpoFua not clear in CDB_USAGE_DATE");
			}
		}
	} else {
		logging(LOG_NORMAL, "[FAILED] Target did not return any data "
			"for ReportSupportedOpcodes\n");
		CU_FAIL("Target did not return any data for "
			"ReportSupportedOpcodes");
	}
	scsi_free_scsi_task(rso_task);
}
Beispiel #17
0
void
test_orwrite_verify(void)
{
	int i, ret;
	unsigned char *buf     = alloca(256 * block_size);
	unsigned char *readbuf = alloca(256 * block_size);


	CHECK_FOR_DATALOSS;
	CHECK_FOR_SBC;

	logging(LOG_VERBOSE, LOG_BLANK_LINE);
	logging(LOG_VERBOSE, "Test ORWRITE of 1-256 blocks at the start of the LUN");
	for (i = 1; i <= 256; i++) {
		if (maximum_transfer_length && maximum_transfer_length < i) {
			break;
		}

		logging(LOG_VERBOSE, "Write %d blocks of all-zero", i);
		memset(buf, 0, block_size * i);
		ret = write10(iscsic, tgt_lun, 0, i * block_size,
		    block_size, 0, 0, 0, 0, 0, buf);
		CU_ASSERT_EQUAL(ret, 0);

		logging(LOG_VERBOSE, "OrWrite %d blocks with 0xa5", i);
		memset(buf, 0xa5, block_size * i);
		ret = orwrite(iscsic, tgt_lun, 0, i * block_size,
			      block_size, 0, 0, 0, 0, 0, buf);
		if (ret == -2) {
			logging(LOG_NORMAL, "[SKIPPED] ORWRITE is not implemented.");
			CU_PASS("ORWRITE is not implemented.");
			return;
		}	
		CU_ASSERT_EQUAL(ret, 0);

		logging(LOG_VERBOSE, "Read %d blocks back", i);
		ret = read10(iscsic, tgt_lun, 0, i * block_size,
		    block_size, 0, 0, 0, 0, 0, readbuf);
		CU_ASSERT_EQUAL(ret, 0);

		logging(LOG_VERBOSE, "Verify that the blocks are all 0xa5");
		ret = memcmp(buf, readbuf, block_size * i);
		CU_ASSERT_EQUAL(ret, 0);

		logging(LOG_VERBOSE, "OrWrite %d blocks with 0x5a", i);
		memset(buf, 0x5a, block_size * i);
		ret = orwrite(iscsic, tgt_lun, 0, i * block_size,
			      block_size, 0, 0, 0, 0, 0, buf);
		CU_ASSERT_EQUAL(ret, 0);

		logging(LOG_VERBOSE, "Read %d blocks back", i);
		ret = read10(iscsic, tgt_lun, 0, i * block_size,
		    block_size, 0, 0, 0, 0, 0, readbuf);
		CU_ASSERT_EQUAL(ret, 0);

		logging(LOG_VERBOSE, "Verify that the blocks are all 0xff");
		memset(buf, 0xff, block_size * i);
		ret = memcmp(buf, readbuf, block_size * i);
		CU_ASSERT_EQUAL(ret, 0);
	}

	logging(LOG_VERBOSE, "Test ORWRITE of 1-256 blocks at the end of the LUN");
	for (i = 1; i <= 256; i++) {
		if (maximum_transfer_length && maximum_transfer_length < i) {
			break;
		}

		logging(LOG_VERBOSE, "Write %d blocks of all-zero", i);
		memset(buf, 0, block_size * i);
		ret = write16(iscsic, tgt_lun, num_blocks - i, i * block_size,
		    block_size, 0, 0, 0, 0, 0, buf);
		CU_ASSERT_EQUAL(ret, 0);

		logging(LOG_VERBOSE, "OrWrite %d blocks with 0xa5", i);
		memset(buf, 0xa5, block_size * i);
		ret = orwrite(iscsic, tgt_lun, num_blocks - i, i * block_size,
			      block_size, 0, 0, 0, 0, 0, buf);
		CU_ASSERT_EQUAL(ret, 0);

		logging(LOG_VERBOSE, "Read %d blocks back", i);
		ret = read16(iscsic, tgt_lun, num_blocks - i, i * block_size,
		    block_size, 0, 0, 0, 0, 0, readbuf);
		CU_ASSERT_EQUAL(ret, 0);

		logging(LOG_VERBOSE, "Verify that the blocks are all 0xa5");
		ret = memcmp(buf, readbuf, block_size * i);
		CU_ASSERT_EQUAL(ret, 0);

		logging(LOG_VERBOSE, "OrWrite %d blocks with 0x5a", i);
		memset(buf, 0x5a, block_size * i);
		ret = orwrite(iscsic, tgt_lun, num_blocks - i, i * block_size,
			      block_size, 0, 0, 0, 0, 0, buf);
		CU_ASSERT_EQUAL(ret, 0);

		logging(LOG_VERBOSE, "Read %d blocks back", i);
		ret = read16(iscsic, tgt_lun, num_blocks - i, i * block_size,
		    block_size, 0, 0, 0, 0, 0, readbuf);
		CU_ASSERT_EQUAL(ret, 0);

		logging(LOG_VERBOSE, "Verify that the blocks are all 0xff");
		memset(buf, 0xff, block_size * i);
		ret = memcmp(buf, readbuf, block_size * i);
		CU_ASSERT_EQUAL(ret, 0);
	}
}