コード例 #1
0
void
test_writeverify16_simple(void)
{
	int i, ret;
	unsigned char *buf = alloca(256 * block_size);

	CHECK_FOR_DATALOSS;
	CHECK_FOR_SBC;

	logging(LOG_VERBOSE, LOG_BLANK_LINE);
	logging(LOG_VERBOSE, "Test WRITEVERIFY16 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 = writeverify16(iscsic, tgt_lun, 0, i * block_size,
		    block_size, 0, 0, 0, 0, buf);
		if (ret == -2) {
			logging(LOG_NORMAL, "[SKIPPED] WRITE1VERIFY16 is not implemented.");
			CU_PASS("WRITEVERIFY16 is not implemented.");
			return;
	       	}	
		CU_ASSERT_EQUAL(ret, 0);
	}

	logging(LOG_VERBOSE, "Test WRITEVERIFY16 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 = writeverify16(iscsic, tgt_lun, num_blocks - i,
		    i * block_size, block_size, 0, 0, 0, 0, buf);
		CU_ASSERT_EQUAL(ret, 0);
	}

}
コード例 #2
0
void
test_writeverify16_0blocks(void)
{
	int ret;

	CHECK_FOR_DATALOSS;
	CHECK_FOR_SBC;

	logging(LOG_VERBOSE, LOG_BLANK_LINE);
	logging(LOG_VERBOSE, "Test WRITEVERIFY16 0-blocks at LBA==0");
	ret = writeverify16(iscsic, tgt_lun, 0,
			    0, block_size,
			    0, 0, 0, 0, NULL);
	if (ret == -2) {
		logging(LOG_NORMAL, "[SKIPPED] WRITE1VERIFY16 is not implemented.");
		CU_PASS("WRITEVERIFY16 is not implemented.");
		return;
       	}	
	CU_ASSERT_EQUAL(ret, 0);

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


	logging(LOG_VERBOSE, "Test WRITEVERIFY16 0-blocks at LBA==2^63");
	ret = writeverify16_lbaoutofrange(iscsic, tgt_lun, 0x8000000000000000ULL,
					  0, block_size,
					  0, 0, 0, 0, NULL);
	CU_ASSERT_EQUAL(ret, 0);


	logging(LOG_VERBOSE, "Test WRITEVERIFY16 0-blocks at LBA==-1");
	ret = writeverify16_lbaoutofrange(iscsic, tgt_lun, -1,
					  0, block_size,
					  0, 0, 0, 0, NULL);
	CU_ASSERT_EQUAL(ret, 0);
}
コード例 #3
0
void
test_writeverify16_residuals(void)
{
	struct scsi_task *task_ret;
	unsigned char buf[10000];
	struct iscsi_data data;
	int ret, ok;
	unsigned int i;

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

	CHECK_FOR_DATALOSS;
	CHECK_FOR_SBC;

	if (sd->iscsi_ctx == NULL) {
		const char *err = "[SKIPPED] This WRITEVERIFY16 test is only "
			"supported for iSCSI backends";
		logging(LOG_NORMAL, "%s", err);
		CU_PASS(err);
		return;
	}

	/* check if writeverify16 is supported */
	ret = writeverify16(sd, 0, 0,
			    block_size, 0, 0, 0, 0, NULL,
			    EXPECT_STATUS_GOOD);
	if (ret == -2) {
		logging(LOG_NORMAL, "[SKIPPED] WRITEVERIFY16 is not implemented.");
		CU_PASS("[SKIPPED] Target does not support WRITEVERIFY16. Skipping test");
		return;
	}

	if (sd->iscsi_ctx == NULL) {
		const char *err = "[SKIPPED] WRITEVERIFY16 tests are only "
			"supported for iSCSI backends";
		logging(LOG_NORMAL, "%s", err);
		CU_PASS(err);
		return;
	}

	/* Try a writeverify16 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_WRITE_VERIFY16;
	task->cdb[13] = 1;
	task->cdb_size = 16;
	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(sd->iscsi_ctx, 1);

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

	task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_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] WRITEVERIFY16 is not implemented.");
		CU_PASS("WRITEVERIFY16 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(sd->iscsi_ctx));
	}
	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(sd->iscsi_ctx, 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_WRITE_VERIFY16;
	task->cdb[13] = 1;
	task->cdb_size = 16;
	task->xfer_dir = SCSI_XFER_WRITE;
	task->expxferlen = 10000;

	memset(buf, 0xa6, sizeof(buf));
	data.size = task->expxferlen;
	data.data = &buf[0];
	task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_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(sd->iscsi_ctx));
	}
	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_WRITE_VERIFY16;
	task->cdb[13] = 1;
	task->cdb_size = 16;
	task->xfer_dir = SCSI_XFER_WRITE;
	task->expxferlen = 200;

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

	logging(LOG_VERBOSE, "Verify that the target returned SUCCESS");
	ok = task->status == SCSI_STATUS_GOOD ||
		(task->status == SCSI_STATUS_CHECK_CONDITION &&
		 task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST &&
		 task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_FIELD_IN_INFORMATION_UNIT);
	if (!ok) {
		logging(LOG_VERBOSE, "[FAILED] Target returned error %s",
			iscsi_get_error(sd->iscsi_ctx));
	}
	CU_ASSERT(ok);

	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_WRITE_VERIFY16;
	task->cdb[13] = 2;
	task->cdb_size = 16;
	task->xfer_dir = SCSI_XFER_WRITE;
	task->expxferlen = block_size;

	data.size = task->expxferlen;
	data.data = &buf[0];
	task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_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(sd->iscsi_ctx));
	}
	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 = write16(sd, 0, 2 * block_size,
		      block_size, 0, 0, 0, 0, 0, buf,
		      EXPECT_STATUS_GOOD);
	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_WRITE_VERIFY16;
	task->cdb[13] = 1;
	task->cdb_size = 16;
	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(sd->iscsi_ctx, sd->iscsi_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(sd->iscsi_ctx));
	}
	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 = read16(sd, NULL, 0, 2* block_size,
		     block_size, 0, 0, 0, 0, 0, buf,
		     EXPECT_STATUS_GOOD);
	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 = write16(sd, 0, 2 * block_size,
		      block_size, 0, 0, 0, 0, 0, buf,
		      EXPECT_STATUS_GOOD);
	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_WRITE_VERIFY16;
	task->cdb[13] = 2;
	task->cdb_size = 16;
	task->xfer_dir = SCSI_XFER_WRITE;
	task->expxferlen = block_size;

	data.size = task->expxferlen;
	data.data = &buf[0];
	task_ret = iscsi_scsi_command_sync(sd->iscsi_ctx, sd->iscsi_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(sd->iscsi_ctx));
	}
	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 = read16(sd, NULL, 0, 2* block_size,
		     block_size, 0, 0, 0, 0, 0, buf,
		     EXPECT_STATUS_GOOD);
	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;
		}
	}
}
コード例 #4
0
void
test_writeverify16_beyond_eol(void)
{ 
	int i, ret;
	unsigned char *buf = alloca(256 * block_size);

	CHECK_FOR_DATALOSS;
	CHECK_FOR_SBC;

	logging(LOG_VERBOSE, LOG_BLANK_LINE);
	logging(LOG_VERBOSE, "Test WRITEVERIFY16 1-256 blocks one block beyond the end");
	memset(buf, 0xa6, 256 * block_size);
	for (i = 1; i <= 256; i++) {
		if (maximum_transfer_length && maximum_transfer_length < i) {
			break;
		}

		ret = writeverify16(sd, num_blocks + 1 - i,
				    i * block_size, block_size, 0, 0, 0, 0, buf,
				    EXPECT_LBA_OOB);
		if (ret == -2) {
			logging(LOG_NORMAL, "[SKIPPED] WRITEVERIFY16 is not implemented.");
			CU_PASS("WRITEVERIFY16 is not implemented.");
			return;
	       	}	
		CU_ASSERT_EQUAL(ret, 0);
	}


	logging(LOG_VERBOSE, "Test WRITEVERIFY16 1-256 blocks at LBA==2^63");
	for (i = 1; i <= 256; i++) {
		if (maximum_transfer_length && maximum_transfer_length < i) {
			break;
		}

		ret = writeverify16(sd, 0x8000000000000000ULL,
				    i * block_size, block_size, 0, 0, 0, 0, buf,
				    EXPECT_LBA_OOB);
		CU_ASSERT_EQUAL(ret, 0);
	}


	logging(LOG_VERBOSE, "Test WRITEVERIFY16 1-256 blocks at LBA==-1");
	for (i = 1; i <= 256; i++) {
		if (maximum_transfer_length && maximum_transfer_length < i) {
			break;
		}

		ret = writeverify16(sd, -1,
				    i * block_size, block_size, 0, 0, 0, 0, buf,
				    EXPECT_LBA_OOB);
		CU_ASSERT_EQUAL(ret, 0);
	}


	logging(LOG_VERBOSE, "Test WRITEVERIFY16 2-256 blocks all but one block beyond the end");
	for (i = 2; i <= 256; i++) {
		if (maximum_transfer_length && maximum_transfer_length < i) {
			break;
		}

		ret = writeverify16(sd, num_blocks - 1,
				    i * block_size, block_size, 0, 0, 0, 0, buf,
				    EXPECT_LBA_OOB);
		CU_ASSERT_EQUAL(ret, 0);
	}
}