コード例 #1
0
ファイル: iscsi-test-cu.c プロジェクト: rcsheets/libiscsi
static void free_scsi_device(struct scsi_device *sdev)
{
	if (sdev->error_str) {
		free(discard_const(sdev->error_str));
		sdev->error_str = NULL;
	}
	if (sdev->iscsi_url) {
		free(discard_const(sdev->iscsi_url));
		sdev->iscsi_url = NULL;
	}
	if (sdev->iscsi_ctx) {
		iscsi_logout_sync(sdev->iscsi_ctx);
		iscsi_destroy_context(sdev->iscsi_ctx);
		sdev->iscsi_ctx = NULL;
	}

	if (sdev->sgio_dev) {
		free(discard_const(sdev->sgio_dev));
		sdev->sgio_dev = NULL;
	}
	if (sdev->sgio_fd != -1) {
		close(sdev->sgio_fd);
		sdev->sgio_fd = -1;
	}
	free(sdev);
}
コード例 #2
0
ファイル: iscsi-test-cu.c プロジェクト: rcsheets/libiscsi
int
suite_init(void)
{
	int i;

	for (i = 0; i < mp_num_sds; i++) {
		if (!mp_sds[i]->iscsi_url) {
			continue;
		}
		if (mp_sds[i]->iscsi_ctx) {
			iscsi_logout_sync(mp_sds[i]->iscsi_ctx);
			iscsi_destroy_context(mp_sds[i]->iscsi_ctx);
		}
		mp_sds[i]->iscsi_ctx = iscsi_context_login(initiatorname1,
							mp_sds[i]->iscsi_url,
							&mp_sds[i]->iscsi_lun);
		if (mp_sds[i]->iscsi_ctx == NULL) {
			fprintf(stderr,
				"error: Failed to login to target for test set-up\n");
			return 1;
		}
	}
#ifndef HAVE_CU_SUITEINFO_PSETUPFUNC
	/* libcunit version 1 */
	test_setup();
#endif
	return 0;
}
コード例 #3
0
void
test_reserve6_target_warm_reset(void)
{
	int ret;
	struct scsi_device sd2;

	logging(LOG_VERBOSE, LOG_BLANK_LINE);
	logging(LOG_VERBOSE, "Test that RESERVE6 is released on target warm reset");

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

	logging(LOG_VERBOSE, "Take out a RESERVE6 from the first initiator");
	ret = reserve6(sd);
	if (ret == -2) {
		logging(LOG_VERBOSE, "[SKIPPED] Target does not support RESERVE6. Skipping test");
		CU_PASS("[SKIPPED] Target does not support RESERVE6. Skipping test");
		return;
	}
	CU_ASSERT_EQUAL(ret, 0);


	logging(LOG_VERBOSE, "Send a Warm Reset to the target");
	ret = iscsi_task_mgmt_target_warm_reset_sync(sd->iscsi_ctx);
	if (ret != 0) {
		logging(LOG_NORMAL, "Warm reset failed. %s", iscsi_get_error(sd->iscsi_ctx));
	}
	CU_ASSERT_EQUAL(ret, 0);

	logging(LOG_VERBOSE, "Sleep for three seconds incase the target is slow to reset");
	sleep(3);


	logging(LOG_VERBOSE, "Create a second connection to the target");
	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) {
		logging(LOG_VERBOSE, "Failed to login to target");
		return;
	}


	logging(LOG_VERBOSE, "RESERVE6 from the second initiator should work now");
	ret = reserve6(&sd2);
	CU_ASSERT_EQUAL(ret, 0);

	logging(LOG_VERBOSE, "RELEASE6 from the second initiator");
	ret = release6(&sd2);
	CU_ASSERT_EQUAL(ret, 0);

	iscsi_logout_sync(sd2.iscsi_ctx);
	iscsi_destroy_context(sd2.iscsi_ctx);
}
コード例 #4
0
void
test_preventallow_logout(void)
{
        CHECK_FOR_SBC;
        CHECK_FOR_REMOVABLE;

        logging(LOG_VERBOSE, LOG_BLANK_LINE);
        logging(LOG_VERBOSE, "Test that Logout loss clears PREVENT MEDIUM REMOVAL");

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

        logging(LOG_VERBOSE, "Set the PREVENT flag");
        PREVENTALLOW(sd, 1);

        logging(LOG_VERBOSE, "Try to eject the medium");
        STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0,
                      EXPECT_REMOVAL_PREVENTED);

        logging(LOG_VERBOSE, "Verify we can still access the media.");
        TESTUNITREADY(sd,
                      EXPECT_STATUS_GOOD);

        logging(LOG_VERBOSE, "Logout from target");
        iscsi_logout_sync(sd->iscsi_ctx);
        iscsi_destroy_context(sd->iscsi_ctx);

        logging(LOG_VERBOSE, "Relogin to target");
        sd->iscsi_ctx = iscsi_context_login(initiatorname1, sd->iscsi_url, &sd->iscsi_lun);
        if (sd->iscsi_ctx == NULL) {
                logging(LOG_VERBOSE, "Failed to login to target");
                return;
        }

        logging(LOG_VERBOSE, "Try to eject the medium");
        STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0,
                      EXPECT_STATUS_GOOD);

        logging(LOG_VERBOSE, "Verify we can not access the media.");
        TESTUNITREADY(sd,
                      EXPECT_NO_MEDIUM);

        logging(LOG_VERBOSE, "Load the medium");
        STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 0,
                      EXPECT_STATUS_GOOD);

        logging(LOG_VERBOSE, "Clear PREVENT and load medium in case target failed");
        logging(LOG_VERBOSE, "Test we can clear PREVENT flag");
        PREVENTALLOW(sd, 0);

        logging(LOG_VERBOSE, "Load the medium");
        STARTSTOPUNIT(sd, 0, 0, 0, 0, 1, 1,
                      EXPECT_STATUS_GOOD);
}
コード例 #5
0
void
test_reserve6_logout(void)
{
	int ret;
	struct scsi_device *sd2;

	logging(LOG_VERBOSE, LOG_BLANK_LINE);
	logging(LOG_VERBOSE, "Test that RESERVE6 is released on logout");

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

	logging(LOG_NORMAL, "Take out a RESERVE6 from the first initiator");
	ret = reserve6(sd);
	if (ret == -2) {
		logging(LOG_VERBOSE, "[SKIPPED] Target does not support RESERVE6. Skipping test");
		CU_PASS("[SKIPPED] Target does not support RESERVE6. Skipping test");
		return;
	}
	CU_ASSERT_EQUAL(ret, 0);


	logging(LOG_VERBOSE, "Create a second connection to the target");
	ret = mpath_sd2_get_or_clone(sd, &sd2);
	CU_ASSERT_EQUAL(ret, 0);

	logging(LOG_NORMAL, "Try to take out a RESERVE6 from the second initiator");
	ret = reserve6_conflict(sd2);
	CU_ASSERT_EQUAL(ret, 0);

	logging(LOG_VERBOSE, "Logout from target");
	iscsi_logout_sync(sd->iscsi_ctx);
	iscsi_destroy_context(sd->iscsi_ctx);

	logging(LOG_VERBOSE, "Relogin to target");
	sd->iscsi_ctx = iscsi_context_login(initiatorname1, sd->iscsi_url, &sd->iscsi_lun);
	if (sd->iscsi_ctx == NULL) {
		logging(LOG_VERBOSE, "Failed to login to target");
		return;
	}

	logging(LOG_NORMAL, "RESERVE6 from the second initiator should work now");
	ret = reserve6(sd2);
	CU_ASSERT_EQUAL(ret, 0);

	logging(LOG_NORMAL, "RELEASE6 from the second initiator");
	ret = release6(sd2);
	CU_ASSERT_EQUAL(ret, 0);

	mpath_sd2_put(sd2);
}
コード例 #6
0
ファイル: iscsi-test-cu.c プロジェクト: gcbirzan/libiscsi
int
suite_cleanup_pgr(void)
{
	if (iscsic2) {
		iscsi_logout_sync(iscsic2);
		iscsi_destroy_context(iscsic2);
		iscsic2 = NULL;
	}
	suite_cleanup();
	return 0;
}
コード例 #7
0
ファイル: iscsi-test-cu.c プロジェクト: gcbirzan/libiscsi
int
suite_cleanup(void)
{
#ifndef HAVE_CU_SUITEINFO_PSETUPFUNC
	/* libcunit version 1 */
	test_teardown();
#endif
	if (iscsic) {
		iscsi_logout_sync(iscsic);
		iscsi_destroy_context(iscsic);
		iscsic = NULL;
	}
	return 0;
}
コード例 #8
0
int T0211_read12_rdprotect(const char *initiator, const char *url)
{
    struct iscsi_context *iscsi;
    struct scsi_task *task;
    int ret = 0, i, lun;

    printf("0211_read12_rdprotect:\n");
    printf("======================\n");
    if (show_info) {
        printf("Test how READ12 handles the rdprotect bits\n");
        printf("1, Any non-zero valued for rdprotect should fail.\n");
        printf("\n");
        return 0;
    }

    iscsi = iscsi_context_login(initiator, url, &lun);
    if (iscsi == NULL) {
        printf("Failed to login to target\n");
        return -1;
    }


    printf("Read12 with RDPROTECT ");
    for (i = 1; i <= 7; i++) {
        task = iscsi_read12_sync(iscsi, lun, 0, block_size, block_size, i, 0, 0, 0, 0);
        if (task == NULL) {
            printf("[FAILED]\n");
            printf("Failed to send read12 command: %s\n", iscsi_get_error(iscsi));
            ret = -1;
            goto finished;
        }
        if (task->status        != SCSI_STATUS_CHECK_CONDITION
                || task->sense.key  != SCSI_SENSE_ILLEGAL_REQUEST
                || task->sense.ascq != SCSI_SENSE_ASCQ_INVALID_FIELD_IN_CDB) {
            printf("[FAILED]\n");
            printf("Read12 with RDPROTECT!=0 should have failed with CHECK_CONDITION/ILLEGAL_REQUEST/INVALID_FIELD_IN_CDB\n");
            ret = -1;
            scsi_free_scsi_task(task);
            goto finished;
        }
        scsi_free_scsi_task(task);
    }
    printf("[OK]\n");


finished:
    iscsi_logout_sync(iscsi);
    iscsi_destroy_context(iscsi);
    return ret;
}
コード例 #9
0
void
test_reserve6_logout(void)
{
	int ret;


	logging(LOG_VERBOSE, LOG_BLANK_LINE);
	logging(LOG_VERBOSE, "Test that RESERVE6 is released on logout");


	logging(LOG_NORMAL, "Take out a RESERVE6 from the first initiator");
	ret = reserve6(iscsic, tgt_lun);
	if (ret == -2) {
		logging(LOG_VERBOSE, "[SKIPPED] Target does not support RESERVE6. Skipping test");
		CU_PASS("[SKIPPED] Target does not support RESERVE6. Skipping test");
		return;
	}
	CU_ASSERT_EQUAL(ret, 0);


	logging(LOG_VERBOSE, "Create a second connection to the target");
	iscsic2 = iscsi_context_login(initiatorname1, tgt_url, &tgt_lun);
	if (iscsic2 == NULL) {
		logging(LOG_VERBOSE, "Failed to login to target");
		return;
	}

	logging(LOG_NORMAL, "Try to take out a RESERVE6 from the second initiator");
	ret = reserve6_conflict(iscsic2, tgt_lun);
	CU_ASSERT_EQUAL(ret, 0);

	logging(LOG_VERBOSE, "Logout from target");
	iscsi_logout_sync(iscsic);

	logging(LOG_VERBOSE, "Relogin to target");
	iscsic = iscsi_context_login(initiatorname1, tgt_url, &tgt_lun);
	if (iscsic == NULL) {
		logging(LOG_VERBOSE, "Failed to login to target");
		return;
	}

	logging(LOG_NORMAL, "RESERVE6 from the second initiator should work now");
	ret = reserve6(iscsic2, tgt_lun);
	CU_ASSERT_EQUAL(ret, 0);

	logging(LOG_NORMAL, "RELEASE6 from the second initiator");
	ret = release6(iscsic2, tgt_lun);
	CU_ASSERT_EQUAL(ret, 0);
}
コード例 #10
0
ファイル: iscsi-multipath.c プロジェクト: daodewang/libiscsi
void
mpath_sd2_put(struct scsi_device *sd2)
{
	if (mp_num_sds > 1) {
		if (sd2 != mp_sds[1]) {
			logging(LOG_NORMAL, "Invalid sd2!");
		}
		return;
	}

	/* sd2 was allocated by mp_get - cleanup */
	iscsi_logout_sync(sd2->iscsi_ctx);
	iscsi_destroy_context(sd2->iscsi_ctx);
	free(sd2);
}
コード例 #11
0
ファイル: iscsi-test-cu.c プロジェクト: rcsheets/libiscsi
int
suite_cleanup(void)
{
	int i;

#ifndef HAVE_CU_SUITEINFO_PSETUPFUNC
	/* libcunit version 1 */
	test_teardown();
#endif
	for (i = 0; i < mp_num_sds; i++) {
		if (mp_sds[i]->iscsi_url) {
			if (mp_sds[i]->iscsi_ctx) {
				iscsi_logout_sync(mp_sds[i]->iscsi_ctx);
				iscsi_destroy_context(mp_sds[i]->iscsi_ctx);
				mp_sds[i]->iscsi_ctx = NULL;
			}
		}
	}
	return 0;
}
コード例 #12
0
int T0170_unmap_simple(const char *initiator, const char *url, int data_loss, int show_info)
{ 
	struct iscsi_context *iscsi;
	struct scsi_task *task;
	struct scsi_readcapacity16 *rc16;
	int ret, i, lun;
	uint32_t block_size, num_blocks;

	printf("0170_unmap_simple:\n");
	printf("==================\n");
	if (show_info) {
		printf("Test basic UNMAP functionality.\n");
		printf("1, Test UNMAP the first 1-256 blocks of the LUN.\n");
		printf("2, Test UNMAP the last 1-256 blocks of the LUN.\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("Readcapacity 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 readcapacity16 data. %s\n", iscsi_get_error(iscsi));
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}

	if (rc16->lbpme == 0){
		printf("Logical unit is fully provisioned. Skipping test\n");
		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("data_loss flag is not set. Skipping test\n");
		ret = -1;
		goto finished;
	}
	
	ret = 0;

	/* unmap the first 1 - 256 blocks at the start of the LUN */
	printf("Unmapping first 1-256 blocks ... ");
	for (i=1; i<=256; i++) {
		struct unmap_list list[1];

		list[0].lba = 0;
		list[0].num = i;
		task = iscsi_unmap_sync(iscsi, lun, 0, 0, &list[0], 1);
		if (task == NULL) {
		        printf("[FAILED]\n");
			printf("Failed to send UNMAP command: %s\n", iscsi_get_error(iscsi));
			ret = -1;
			goto finished;
		}
		if (task->status != SCSI_STATUS_GOOD) {
		        printf("[FAILED]\n");
			printf("UNMAP command: failed with sense. %s\n", iscsi_get_error(iscsi));
			ret = -1;
			scsi_free_scsi_task(task);
			goto finished;
		}
		scsi_free_scsi_task(task);
	}
	printf("[OK]\n");


	/* unmap the last 1 - 256 blocks at the end of the LUN */
	printf("Unmapping last 1-256 blocks ... ");
	for (i=1; i<=256; i++) {
		struct unmap_list list[1];

		list[0].lba = num_blocks + 1 - i;
		list[0].num = i;
		task = iscsi_unmap_sync(iscsi, lun, 0, 0, &list[0], 1);
		if (task == NULL) {
		        printf("[FAILED]\n");
			printf("Failed to send UNMAP command: %s\n", iscsi_get_error(iscsi));
			ret = -1;
			goto finished;
		}
		if (task->status != SCSI_STATUS_GOOD) {
		        printf("[FAILED]\n");
			printf("UNMAP command: failed with sense. %s\n", iscsi_get_error(iscsi));
			ret = -1;
			scsi_free_scsi_task(task);
			goto finished;
		}
		scsi_free_scsi_task(task);
	}
	printf("[OK]\n");


finished:
	iscsi_logout_sync(iscsi);
	iscsi_destroy_context(iscsi);
	return ret;
}
コード例 #13
0
int T0231_write12_wrprotect(const char *initiator, const char *url, int data_loss, int show_info)
{ 
	struct iscsi_context *iscsi;
	struct scsi_task *task;
	struct scsi_readcapacity16 *rc16;
	int ret = 0, i, lun;
	uint32_t block_size;
	unsigned char data[4096];

	printf("0231_write12_wrprotect:\n");
	printf("======================\n");
	if (show_info) {
		printf("Test how WRITE12 handles the wrprotect bits\n");
		printf("1, Any non-zero valued for wrprotect should fail.\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 READCAPACITY16 data. %s\n", iscsi_get_error(iscsi));
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}

	block_size = rc16->block_length;

	if(rc16->prot_en != 0) {
		printf("device is formatted with protection information, skipping test\n");
		scsi_free_scsi_task(task);
		ret = -2;
		goto finished;
	}
	scsi_free_scsi_task(task);

	if (!data_loss) {
		printf("--dataloss flag is not set. Skipping test\n");
		ret = -2;
		goto finished;
	}

	printf("Write12 with RDPROTECT ");
	for (i = 1; i <= 7; i++) {
		task = iscsi_write12_sync(iscsi, lun, 0, data, block_size, block_size, i, 0, 0, 0, 0);
		if (task == NULL) {
		        printf("[FAILED]\n");
			printf("Failed to send write12 command: %s\n", iscsi_get_error(iscsi));
			ret = -1;
			goto finished;
		}
		if (task->status        != SCSI_STATUS_CHECK_CONDITION
		    || task->sense.key  != SCSI_SENSE_ILLEGAL_REQUEST
		    || task->sense.ascq != SCSI_SENSE_ASCQ_INVALID_FIELD_IN_CDB) {
		        printf("[FAILED]\n");
			printf("Write12 with RDPROTECT!=0 should have failed with CHECK_CONDITION/ILLEGAL_REQUEST/INVALID_FIELD_IN_CDB\n");
			ret = -1;
			scsi_free_scsi_task(task);
			goto finished;
		}
		scsi_free_scsi_task(task);
	}
	printf("[OK]\n");

finished:
	iscsi_logout_sync(iscsi);
	iscsi_destroy_context(iscsi);
	return ret;
}
コード例 #14
0
int T0234_write12_beyondeol(const char *initiator, const char *url)
{ 
	struct iscsi_context *iscsi;
	struct scsi_task *task;
	int ret, i, lun;
	unsigned char data[4096 * 258];

	printf("0234_write12_beyond_eol:\n");
	printf("=======================\n");
	if (show_info) {
		printf("Test that WRITE12 fails if writing beyond end-of-lun.\n");
		printf("This test is skipped for LUNs with more than 2^31 blocks\n");
		printf("1, Writing 1-256 blocks beyond end-of-lun should fail.\n");
		printf("\n");
		return 0;
	}

	iscsi = iscsi_context_login(initiator, url, &lun);
	if (iscsi == NULL) {
		printf("Failed to login to target\n");
		return -1;
	}

	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 WRITE12. Skipping test.\n");
		ret = -2;
		goto finished;
	}

	/* read 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_write12_sync(iscsi, lun, num_blocks, data, i * block_size, block_size, 0, 0, 0, 0, 0);
		if (task == NULL) {
		        printf("[FAILED]\n");
			printf("Failed to send write12 command: %s\n", iscsi_get_error(iscsi));
			ret = -1;
			goto finished;
		}
		if (task->status == SCSI_STATUS_GOOD) {
		        printf("[FAILED]\n");
			printf("Write12 command should fail when writing beyond end of device\n");
			ret = -1;
			scsi_free_scsi_task(task);
			goto finished;
		}
		scsi_free_scsi_task(task);
	}
	printf("[OK]\n");


finished:
	iscsi_logout_sync(iscsi);
	iscsi_destroy_context(iscsi);
	return ret;
}
コード例 #15
0
ファイル: 0105_read10_invalid.c プロジェクト: djs55/libiscsi
int T0105_read10_invalid(const char *initiator, const char *url)
{
    struct iscsi_context *iscsi;
    struct scsi_task *task;
    struct iscsi_data data;
    char buf[512];
    int ret, lun;

    iscsi = iscsi_context_login(initiator, url, &lun);
    if (iscsi == NULL) {
        printf("Failed to login to target\n");
        return -1;
    }


    ret = 0;

    /* Try a read of 1 block but xferlength == 0 */
    printf("Read10 1 block but with iscsi ExpectedDataTransferLength==0 ... ");

    task = malloc(sizeof(struct scsi_task));
    if (task == NULL) {
        printf("Failed to allocate task structure\n");
        ret = -1;
        goto finished;
    }

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

    if (iscsi_scsi_command_sync(iscsi, lun, task, NULL) == NULL) {
        printf("[FAILED]\n");
        printf("Failed to send read10 command: %s\n", iscsi_get_error(iscsi));
        ret = -1;

        goto finished;
    }
    if (task->status != SCSI_STATUS_GOOD) {
        printf("[FAILED]\n");
        printf("Read10 of 1 block with iscsi ExpectedDataTransferLength==0 should not fail.\n");
        ret = -1;
        scsi_free_scsi_task(task);
        goto test2;
    }
    if (task->residual_status != SCSI_RESIDUAL_OVERFLOW || task->residual != 512) {
        printf("[FAILED]\n");
        printf("Read10 returned incorrect residual overflow.\n");
        ret = -1;
        scsi_free_scsi_task(task);
        goto test5;
    }
    scsi_free_scsi_task(task);
    printf("[OK]\n");


test2:
    /* Try a read of 1 block but xferlength == 1024 */
    printf("Read10 1 block but with iscsi ExpectedDataTransferLength==1024 ... ");

    task = malloc(sizeof(struct scsi_task));
    if (task == NULL) {
        printf("Failed to allocate task structure\n");
        ret = -1;
        goto finished;
    }

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

    if (iscsi_scsi_command_sync(iscsi, lun, task, NULL) == NULL) {
        printf("[FAILED]\n");
        printf("Failed to send read10 command: %s\n", iscsi_get_error(iscsi));
        ret = -1;

        goto finished;
    }
    if (task->status != SCSI_STATUS_GOOD) {
        printf("[FAILED]\n");
        printf("Read10 of 1 block with iscsi ExpectedDataTransferLength==1024 should not fail.\n");
        ret = -1;
        scsi_free_scsi_task(task);
        goto test3;
    }
    if (task->residual_status != SCSI_RESIDUAL_UNDERFLOW || task->residual != 512) {
        printf("[FAILED]\n");
        printf("Read10 returned incorrect residual underflow.\n");
        ret = -1;
        scsi_free_scsi_task(task);
        goto test5;
    }
    scsi_free_scsi_task(task);
    printf("[OK]\n");


test3:
    /* Try a read of 1 block but xferlength == 200 */
    printf("Read10 1 block but with iscsi ExpectedDataTransferLength==200 ... ");

    task = malloc(sizeof(struct scsi_task));
    if (task == NULL) {
        printf("Failed to allocate task structure\n");
        ret = -1;
        goto finished;
    }

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

    if (iscsi_scsi_command_sync(iscsi, lun, task, NULL) == NULL) {
        printf("[FAILED]\n");
        printf("Failed to send read10 command: %s\n", iscsi_get_error(iscsi));
        ret = -1;

        goto finished;
    }
    if (task->status != SCSI_STATUS_GOOD) {
        printf("[FAILED]\n");
        printf("Read10 of 1 block with iscsi ExpectedDataTransferLength==200 should not fail.\n");
        ret = -1;
        scsi_free_scsi_task(task);
        goto test4;
    }
    if (task->residual_status != SCSI_RESIDUAL_OVERFLOW || task->residual != 312) {
        printf("[FAILED]\n");
        printf("Read10 returned incorrect residual overflow.\n");
        ret = -1;
        scsi_free_scsi_task(task);
        goto test5;
    }
    scsi_free_scsi_task(task);
    printf("[OK]\n");

test4:
    /* Try a read of 2 blocks but xferlength == 512 */
    printf("Read10 2 blocks but with iscsi ExpectedDataTransferLength==512 ... ");

    task = malloc(sizeof(struct scsi_task));
    if (task == NULL) {
        printf("Failed to allocate task structure\n");
        ret = -1;
        goto finished;
    }

    memset(task, 0, sizeof(struct scsi_task));
    task->cdb[0] = SCSI_OPCODE_READ10;
    task->cdb[8] = 2;
    task->cdb_size = 10;
    task->xfer_dir = SCSI_XFER_READ;
    task->expxferlen = 512;

    if (iscsi_scsi_command_sync(iscsi, lun, task, NULL) == NULL) {
        printf("[FAILED]\n");
        printf("Failed to send read10 command: %s\n", iscsi_get_error(iscsi));
        ret = -1;

        goto finished;
    }
    if (task->status != SCSI_STATUS_GOOD) {
        printf("[FAILED]\n");
        printf("Read10 of 2 blocks with iscsi ExpectedDataTransferLength==512 should succeed.\n");
        ret = -1;
        scsi_free_scsi_task(task);
        goto test5;
    }
    if (task->residual_status != SCSI_RESIDUAL_OVERFLOW || task->residual != 512) {
        printf("[FAILED]\n");
        printf("Read10 returned incorrect residual overflow.\n");
        ret = -1;
        scsi_free_scsi_task(task);
        goto test5;
    }

    scsi_free_scsi_task(task);
    printf("[OK]\n");


test5:
    /* Try a read of 1 block but make it a data-out write on the iscsi layer */
    printf("Read10 of 1 block but sent as data-out write in iscsi layer ... ");

    task = malloc(sizeof(struct scsi_task));
    if (task == NULL) {
        printf("Failed to allocate task structure\n");
        ret = -1;
        goto finished;
    }

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

    data.size = sizeof(buf);
    data.data = &buf[0];

    if (iscsi_scsi_command_sync(iscsi, lun, task, &data) == NULL) {
        printf("[FAILED]\n");
        printf("Failed to send read10 command: %s\n", iscsi_get_error(iscsi));
        ret = -1;

        goto finished;
    }
    if (task->status == SCSI_STATUS_GOOD) {
        printf("[FAILED]\n");
        printf("Read10 of 1 block but iscsi data-out write should fail.\n");
        ret = -1;
        scsi_free_scsi_task(task);
        goto finished;
    }
    scsi_free_scsi_task(task);
    printf("[OK]\n");

finished:
    iscsi_logout_sync(iscsi);
    iscsi_destroy_context(iscsi);
    return ret;
}
コード例 #16
0
int T0360_startstopunit_simple(const char *initiator, const char *url)
{ 
	struct iscsi_context *iscsi;
	struct scsi_task *task;
	int ret, lun;

	printf("0360_startstopunit_simple:\n");
	printf("===================\n");
	if (show_info) {
		printf("Test basic STARTSTOPUNIT functionality.\n");
		printf("1, Verify we can eject removable the media with IMMED==1\n");
		printf("2, Verify we can load the media back again with IMMED==1\n");
		printf("3, Verify we can eject removable the media with IMMED==0\n");
		printf("4, Verify we can load the media back again with IMMED==0\n");
		printf("\n");
		return 0;
	}

	iscsi = iscsi_context_login(initiator, url, &lun);
	if (iscsi == NULL) {
		printf("Failed to login to target\n");
		return -1;
	}

	if (!data_loss) {
		printf("--dataloss flag is not set. Skipping test\n");
		ret = -2;
		goto finished;
	}
	

	ret = 0;


	if (inq->rmb) {
		printf("Media is removable. STARTSTOPUNIT should work\n");
	} else {
		printf("Media is not removable. STARTSTOPUNIT should fail\n");
	}


	printf("STARTSTOPUNIT try to eject the media with IMMED==1 ... ");
	task = iscsi_startstopunit_sync(iscsi, lun, 1, 0, 0, 0, 1, 0);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send STARTSTOPUNIT command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status != SCSI_STATUS_GOOD) {
	        printf("[FAILED]\n");
		printf("STARTSTOPUNIT command: failed with sense. %s\n", iscsi_get_error(iscsi));
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	scsi_free_scsi_task(task);
	printf("[OK]\n");

	if (inq->rmb) {
		printf("Medium is removable. Check with TESTUNITREADY that was removed.\n");
		ret = testunitready_nomedium(iscsi, lun);
		if (ret != 0) {
			goto finished;
		}
	} else {
		printf("Medium is not removable. Check with TESTUNITREADY that medium is still present.\n");
		ret = testunitready(iscsi, lun);
		if (ret != 0) {
			goto finished;
		}
	}


	printf("STARTSTOPUNIT try to mount the media again with IMMED==1 ... ");
	task = iscsi_startstopunit_sync(iscsi, lun, 1, 0, 0, 0, 1, 1);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send STARTSTOPUNIT command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status != SCSI_STATUS_GOOD) {
	        printf("[FAILED]\n");
		printf("STARTSTOPUNIT command: failed with sense. %s\n", iscsi_get_error(iscsi));
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	scsi_free_scsi_task(task);
	printf("[OK]\n");

	printf("Check with TESTUNITREADY that the medium is present.\n");
	ret = testunitready(iscsi, lun);
	if (ret != 0) {
		goto finished;
	}


	printf("STARTSTOPUNIT try to eject the media with IMMED==0 ... ");
	task = iscsi_startstopunit_sync(iscsi, lun, 0, 0, 0, 0, 1, 0);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send STARTSTOPUNIT command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status != SCSI_STATUS_GOOD) {
	        printf("[FAILED]\n");
		printf("STARTSTOPUNIT command: failed with sense. %s\n", iscsi_get_error(iscsi));
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	scsi_free_scsi_task(task);
	printf("[OK]\n");

	if (inq->rmb) {
		printf("Medium is removable. Check with TESTUNITREADY that was removed.\n");
		ret = testunitready_nomedium(iscsi, lun);
		if (ret != 0) {
			goto finished;
		}
	} else {
		printf("Medium is not removable. Check with TESTUNITREADY that medium is still present.\n");
		ret = testunitready(iscsi, lun);
		if (ret != 0) {
			goto finished;
		}
	}


	printf("STARTSTOPUNIT try to mount the media again with IMMED==0 ... ");
	task = iscsi_startstopunit_sync(iscsi, lun, 0, 0, 0, 0, 1, 1);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send STARTSTOPUNIT command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status != SCSI_STATUS_GOOD) {
	        printf("[FAILED]\n");
		printf("STARTSTOPUNIT command: failed with sense. %s\n", iscsi_get_error(iscsi));
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	scsi_free_scsi_task(task);
	printf("[OK]\n");


	printf("Check with TESTUNITREADY that the medium is present.\n");
	ret = testunitready(iscsi, lun);
	if (ret != 0) {
		goto finished;
	}


finished:
	iscsi_logout_sync(iscsi);
	iscsi_destroy_context(iscsi);
	return ret;
}
コード例 #17
0
ファイル: iscsi-inq.c プロジェクト: sahlberg/libiscsi
int main(int argc, char *argv[])
{
	struct iscsi_context *iscsi;
	const char *url = NULL;
	struct iscsi_url *iscsi_url = NULL;
	int evpd = 0, pagecode = 0;
	int show_help = 0, show_usage = 0, debug = 0;
	int c;

	static struct option long_options[] = {
		{"help",           no_argument,          NULL,        'h'},
		{"usage",          no_argument,          NULL,        'u'},
		{"debug",          no_argument,          NULL,        'd'},
		{"initiator-name", required_argument,    NULL,        'i'},
		{"evpd",           required_argument,    NULL,        'e'},
		{"pagecode",       required_argument,    NULL,        'c'},
		{0, 0, 0, 0}
	};
	int option_index;

	while ((c = getopt_long(argc, argv, "h?udi:e:c:", long_options,
			&option_index)) != -1) {
		switch (c) {
		case 'h':
		case '?':
			show_help = 1;
			break;
		case 'u':
			show_usage = 1;
			break;
		case 'd':
			debug = 1;
			break;
		case 'i':
			initiator = optarg;
			break;
		case 'e':
			evpd = atoi(optarg);
			break;
		case 'c':
			pagecode = atoi(optarg);
			break;
		default:
			fprintf(stderr, "Unrecognized option '%c'\n\n", c);
			print_help();
			exit(0);
		}
	}

	if (show_help != 0) {
		print_help();
		exit(0);
	}

	if (show_usage != 0) {
		print_usage();
		exit(0);
	}

	iscsi = iscsi_create_context(initiator);
	if (iscsi == NULL) {
		fprintf(stderr, "Failed to create context\n");
		exit(10);
	}

	if (debug > 0) {
		iscsi_set_log_level(iscsi, debug);
		iscsi_set_log_fn(iscsi, iscsi_log_to_stderr);
	}

	if (argv[optind] != NULL) {
		url = strdup(argv[optind]);
	}
	if (url == NULL) {
		fprintf(stderr, "You must specify the URL\n");
		print_usage();
		exit(10);
	}
	iscsi_url = iscsi_parse_full_url(iscsi, url);
	
	if (url) {
		free(discard_const(url));
	}

	if (iscsi_url == NULL) {
		fprintf(stderr, "Failed to parse URL: %s\n", 
			iscsi_get_error(iscsi));
		exit(10);
	}

	iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL);
	iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);

	if (iscsi_full_connect_sync(iscsi, iscsi_url->portal, iscsi_url->lun) != 0) {
		fprintf(stderr, "Login Failed. %s\n", iscsi_get_error(iscsi));
		iscsi_destroy_url(iscsi_url);
		iscsi_destroy_context(iscsi);
		exit(10);
	}

	do_inquiry(iscsi, iscsi_url->lun, evpd, pagecode);
	iscsi_destroy_url(iscsi_url);

	iscsi_logout_sync(iscsi);
	iscsi_destroy_context(iscsi);
	return 0;
}
コード例 #18
0
int T0293_write10_0blocks(const char *initiator, const char *url, int data_loss, int show_info)
{ 
	struct iscsi_context *iscsi;
	struct scsi_task *task;
	struct scsi_readcapacity16 *rc16;
	int ret = 0, lun;
	uint32_t block_size;
	uint32_t num_blocks;

	printf("0293_write10_0blocks:\n");
	printf("====================\n");
	if (show_info) {
		printf("Test that WRITE10 works correctly when writing 0 number of blocks.\n");
		printf("1, Read at LBA:0 should work.\n");
		printf("2, Read at LBA:end-of-lun should work.\n");
		printf("3, Read at LBA:end-of-lun+1 should fail.\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 READCAPACITY16 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 = -1;
		goto finished;
	}


	printf("Write10 0blocks at LBA:0 ");
	task = iscsi_write10_sync(iscsi, lun, 0, NULL, 0, block_size, 0, 0, 0, 0, 0);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send write10 command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status != SCSI_STATUS_GOOD) {
	        printf("[FAILED]\n");
		printf("Write10 command: failed with sense. %s\n", iscsi_get_error(iscsi));
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	printf("[OK]\n");

	printf("Write10 0blocks at LBA:<end-of-disk> ");
	task = iscsi_write10_sync(iscsi, lun, num_blocks, NULL, 0, block_size, 0, 0, 0, 0, 0);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send write10 command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status != SCSI_STATUS_GOOD) {
	        printf("[FAILED]\n");
		printf("Write10 command: failed with sense. %s\n", iscsi_get_error(iscsi));
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	printf("[OK]\n");

	printf("Write10 0blocks at LBA:<beyond end-of-disk> ");
	task = iscsi_write10_sync(iscsi, lun, num_blocks + 1, NULL, 0, block_size, 0, 0, 0, 0, 0);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send write10 command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status == SCSI_STATUS_GOOD) {
	        printf("[FAILED]\n");
		printf("Write10 command: Should fail when writing 0blocks beyond end\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	printf("[OK]\n");

finished:
	iscsi_logout_sync(iscsi);
	iscsi_destroy_context(iscsi);
	return ret;
}
コード例 #19
0
int T0294_write10_beyondeol(const char *initiator, const char *url, int data_loss, int show_info)
{ 
	struct iscsi_context *iscsi;
	struct scsi_task *task;
	struct scsi_readcapacity16 *rc16;
	int ret, i, lun;
	uint32_t block_size;
	uint32_t num_blocks;
	unsigned char data[258 * 512];

	printf("0294_write10_beyond_eol:\n");
	printf("=======================\n");
	if (show_info) {
		printf("Test that WRITE10 fails if writing beyond end-of-lun.\n");
		printf("1, Writing 1-256 blocks beyond end-of-lun should fail.\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 = -1;
		goto finished;
	}


	ret = 0;

	/* read 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_write10_sync(iscsi, lun, num_blocks, data, i * block_size, block_size, 0, 0, 0, 0, 0);
		if (task == NULL) {
		        printf("[FAILED]\n");
			printf("Failed to send write10 command: %s\n", iscsi_get_error(iscsi));
			ret = -1;
			goto finished;
		}
		if (task->status == SCSI_STATUS_GOOD) {
		        printf("[FAILED]\n");
			printf("Write10 command should fail when writing beyond end of device\n");
			ret = -1;
			scsi_free_scsi_task(task);
			goto finished;
		}
		scsi_free_scsi_task(task);
	}
	printf("[OK]\n");


finished:
	iscsi_logout_sync(iscsi);
	iscsi_destroy_context(iscsi);
	return ret;
}
コード例 #20
0
int T0270_verify16_simple(const char *initiator, const char *url)
{ 
	struct iscsi_context *iscsi;
	struct scsi_task *task;
	int ret, i, lun;
	unsigned char *buf = NULL;

	printf("0270_verify16_simple:\n");
	printf("=====================\n");
	if (show_info) {
		printf("Test basic VERIFY16 functionality.\n");
		printf("1, Read and verify the first 1-256 blocks of the LUN using READ16/VERIFY16.\n");
		printf("\n");
		return 0;
	}

	iscsi = iscsi_context_login(initiator, url, &lun);
	if (iscsi == NULL) {
		printf("Failed to login to target\n");
		return -1;
	}


	buf = malloc(256 * block_size);
	if (buf == NULL) {
		printf("Failed to allocate buffer.\n");
		ret = -1;
		goto finished;
	}

	printf("Read first 256 blocks.\n");
	task = iscsi_read10_sync(iscsi, lun, 0, 256 * block_size, block_size, 0, 0, 0, 0, 0);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send READ10 command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status != SCSI_STATUS_GOOD) {
	        printf("[FAILED]\n");
		printf("READ10 command: failed with sense. %s\n", iscsi_get_error(iscsi));
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	memcpy(buf, task->datain.data, task->datain.size);
	scsi_free_scsi_task(task);


	ret = 0;


	/* verify the first 1 - 256 blocks at the start of the LUN */
	printf("Verify first 1-256 blocks.\n");
	for (i = 1; i <= 256; i++) {
		ret = verify16(iscsi, lun, 0, i * block_size, block_size, 0, 1, 1, buf);
		if (ret != 0) {
			goto finished;
		}
	}


finished:
	free(buf);
	iscsi_logout_sync(iscsi);
	iscsi_destroy_context(iscsi);
	return ret;
}
コード例 #21
0
int T0213_read12_0blocks(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 = 0, lun;
	uint32_t block_size;
	uint64_t num_blocks;

	printf("0213_read12_0blocks:\n");
	printf("====================\n");
	if (show_info) {
		printf("Test that READ12 works correctly when reading 0 number of blocks.\n");
		printf("1, Read at 0 should work.\n");
		printf("2, Read at end-of-lun should work.\n");
		printf("3, Read beyond end-of-lun should fail.\n");
		printf("4, Read at LBA:-1 should fail. (only test this if the device is < 2TB)\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 READCAPACITY16 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);


	printf("Read12 0blocks at LBA:0 ");
	task = iscsi_read12_sync(iscsi, lun, 0, 0, block_size, 0, 0, 0, 0, 0);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send read12 command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status != SCSI_STATUS_GOOD) {
	        printf("[FAILED]\n");
		printf("Read12 command: failed with sense. %s\n", iscsi_get_error(iscsi));
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	printf("[OK]\n");

	printf("Read12 0blocks at LBA:<end-of-disk> ");
	task = iscsi_read12_sync(iscsi, lun, num_blocks, 0, block_size, 0, 0, 0, 0, 0);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send read12 command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status != SCSI_STATUS_GOOD) {
	        printf("[FAILED]\n");
		printf("Read12 command: failed with sense. %s\n", iscsi_get_error(iscsi));
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	printf("[OK]\n");

	printf("Read12 0blocks at LBA:<beyond end-of-disk> ");
	task = iscsi_read12_sync(iscsi, lun, num_blocks + 1, 0, block_size, 0, 0, 0, 0, 0);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send read12 command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status == SCSI_STATUS_GOOD) {
	        printf("[FAILED]\n");
		printf("Read12 command: Should fail when reading 0blocks beyond end\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	printf("[OK]\n");

	/* read12 0 at lba -1, only do this if the device is < 2TB */
	if (num_blocks == 0xffffffff) {
		goto finished;
	}
	printf("Reading 0 blocks at lba:-1 ... ");
	task = iscsi_read12_sync(iscsi, lun, -1, 0, block_size, 0, 0, 0, 0, 0);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send read12 command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status == SCSI_STATUS_GOOD) {
	        printf("[FAILED]\n");
		printf("Read12 command: Should fail when reading 0blocks at -1\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	printf("[OK]\n");

finished:
	iscsi_logout_sync(iscsi);
	iscsi_destroy_context(iscsi);
	return ret;
}
コード例 #22
0
int T0252_prefetch16_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;
	uint64_t num_blocks;

	printf("0252_prefetch16_beyondeol:\n");
	printf("===================\n");
	if (show_info) {
		printf("Test PREFETCH16 for blocks beyond the EOL.\n");
		printf("1, Prefetch 1-256 blocks one block beyond end-of-lun.\n");
		printf("2, Prefetch 1-256 blocks at LBA 2^63 should fail.\n");
		printf("3, Prefetch 1-256 blocks at LBA -1 should fail.\n");
		printf("4, Prefetch 1-256 blocks all but one block beyond eol\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 READCAPACITY16 data. %s\n", iscsi_get_error(iscsi));
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	num_blocks = rc16->returned_lba;
	scsi_free_scsi_task(task);

	ret = 0;



	/* prefetch 1-256 blocks, one block beyond the end-of-lun */
	printf("Prefetch last 1-256 blocks one block beyond eol ... ");
	for (i = 1; i <= 256; i++) {
		task = iscsi_prefetch16_sync(iscsi, lun, num_blocks + 2 - i, i, 0, 0);
		if (task == NULL) {
		        printf("[FAILED]\n");
			printf("Failed to send prefetch16 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_CHECK_CONDITION
			|| task->sense.key  != SCSI_SENSE_ILLEGAL_REQUEST
			|| task->sense.ascq != SCSI_SENSE_ASCQ_LBA_OUT_OF_RANGE) {
			printf("[FAILED]\n");
			printf("PREFETCH16 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:
	/* Prefetch 1 - 256 blocks at LBA 2^63 */
	printf("Prefetch 1-256 blocks at LBA 2^63 ... ");
	for (i = 1; i <= 256; i++) {
		task = iscsi_prefetch16_sync(iscsi, lun, 0x8000000000000000, i, 0, 0);
		if (task == NULL) {
		        printf("[FAILED]\n");
			printf("Failed to send PREFETCH16 command: %s\n", iscsi_get_error(iscsi));
			ret = -1;
			goto test3;
		}
		if (task->status == SCSI_STATUS_GOOD) {
		        printf("[FAILED]\n");
			printf("PREFETCH16 command should fail for 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("PREFETCH16 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:
	/* prefetch 1 - 256 blocks at LBA -1 */
	for (i = 1; i <= 256; i++) {
		task = iscsi_prefetch16_sync(iscsi, lun, -1, i, 0, 0);
		if (task == NULL) {
		        printf("[FAILED]\n");
			printf("Failed to send PREFETCH16 command: %s\n", iscsi_get_error(iscsi));
			ret = -1;
			goto test4;
		}
		if (task->status == SCSI_STATUS_GOOD) {
		        printf("[FAILED]\n");
			printf("PREFETCH16 command should fail for 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("PREFETCH16 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:
	/* prefetch 2-256 blocks, all but one block beyond the eol */
	printf("Prefetch 1-255 blocks beyond eol starting at last block ... ");
	for (i=2; i<=256; i++) {
		task = iscsi_prefetch16_sync(iscsi, lun, num_blocks, i, 0, 0);
		if (task == NULL) {
			printf("[FAILED]\n");
			printf("Failed to send PREFETCH16 command: %s\n", iscsi_get_error(iscsi));
			ret = -1;
			goto test5;
		}
		if (task->status == SCSI_STATUS_GOOD) {
			printf("[FAILED]\n");
			printf("PREFETCH16 beyond end-of-lun did not return sense.\n");
			ret = -1;
			scsi_free_scsi_task(task);
			goto test5;
		}
		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("PREFETCH16 failed but ascq was wrong. 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 test5;
		}
		scsi_free_scsi_task(task);
	}
	printf("[OK]\n");


test5:

finished:
	iscsi_logout_sync(iscsi);
	iscsi_destroy_context(iscsi);
	return ret;
}
コード例 #23
0
ファイル: iscsi-swp.c プロジェクト: bonzini/libiscsi
int main(int argc, char *argv[])
{
	struct iscsi_context *iscsi;
	const char *url = NULL;
	struct iscsi_url *iscsi_url = NULL;
	int show_help = 0, show_usage = 0, debug = 0;
	int c;
	int ret = 0;
	int swp = 0;
	struct scsi_task *sense_task = NULL;
	struct scsi_task *select_task = NULL;
	struct scsi_mode_sense *ms;
	struct scsi_mode_page *mp;

	static struct option long_options[] = {
		{"help",           no_argument,          NULL,        'h'},
		{"usage",          no_argument,          NULL,        'u'},
		{"debug",          no_argument,          NULL,        'd'},
		{"initiator-name", required_argument,    NULL,        'i'},
		{"swp",            required_argument,    NULL,        's'},
		{0, 0, 0, 0}
	};
	int option_index;

	while ((c = getopt_long(argc, argv, "h?udi:s:", long_options,
			&option_index)) != -1) {
		switch (c) {
		case 'h':
		case '?':
			show_help = 1;
			break;
		case 'u':
			show_usage = 1;
			break;
		case 'd':
			debug = 1;
			break;
		case 'i':
			initiator = optarg;
			break;
		case 's':
			if (!strcmp(optarg, "on") || !strcmp(optarg, "ON")) {
				swp = 1;
			}
			if (!strcmp(optarg, "off") || !strcmp(optarg, "OFF")) {
				swp = 2;
			}
			break;
		default:
			fprintf(stderr, "Unrecognized option '%c'\n\n", c);
			print_help();
			exit(0);
		}
	}

	if (show_help != 0) {
		print_help();
		exit(0);
	}

	if (show_usage != 0) {
		print_usage();
		exit(0);
	}

	iscsi = iscsi_create_context(initiator);
	if (iscsi == NULL) {
		fprintf(stderr, "Failed to create context\n");
		exit(10);
	}

	if (debug > 0) {
		iscsi_set_log_level(iscsi, debug);
		iscsi_set_log_fn(iscsi, iscsi_log_to_stderr);
	}

	if (argv[optind] != NULL) {
		url = strdup(argv[optind]);
	}
	if (url == NULL) {
		fprintf(stderr, "You must specify the URL\n");
		print_usage();
		ret = 10;
		goto finished;
	}
	iscsi_url = iscsi_parse_full_url(iscsi, url);
	
	free(discard_const(url));

	if (iscsi_url == NULL) {
		fprintf(stderr, "Failed to parse URL: %s\n", 
			iscsi_get_error(iscsi));
		ret = 10;
		goto finished;
	}

	iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL);
	iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);

	if (iscsi_full_connect_sync(iscsi, iscsi_url->portal, iscsi_url->lun) != 0) {
		fprintf(stderr, "Login Failed. %s\n", iscsi_get_error(iscsi));
		ret = 10;
		goto finished;
	}


	sense_task = iscsi_modesense10_sync(iscsi, iscsi_url->lun,
		0, 1, SCSI_MODESENSE_PC_CURRENT,
		SCSI_MODEPAGE_CONTROL,
		0, 255);
	if (sense_task == NULL) {
		printf("Failed to send MODE_SENSE10 command: %s\n",
			iscsi_get_error(iscsi));
		ret = 10;
		goto finished;
	}
	if (sense_task->status != SCSI_STATUS_GOOD) {
		printf("MODE_SENSE10 failed: %s\n",
			iscsi_get_error(iscsi));
		ret = 10;
		goto finished;
	}
	ms = scsi_datain_unmarshall(sense_task);
	if (ms == NULL) {
		printf("failed to unmarshall mode sense datain blob\n");
		ret = 10;
		goto finished;
	}
	mp = scsi_modesense_get_page(ms, SCSI_MODEPAGE_CONTROL, 0);
	if (mp == NULL) {
		printf("failed to read control mode page\n");
		ret = 10;
		goto finished;
	}

	/* For MODE SELECT PS is reserved and hence must be cleared */
	mp->ps = 0;

	printf("SWP:%d\n", mp->control.swp);

	switch (swp) {
	case 1:
		mp->control.swp = 1;
		break;
	case 2:
		mp->control.swp = 0;
		break;
	default:
		goto finished;
	}

	printf("Turning SWP %s\n", (swp == 1) ? "ON" : "OFF"); 
	select_task = iscsi_modeselect10_sync(iscsi, iscsi_url->lun,
		    1, 0, mp);
	if (select_task == NULL) {
		printf("Failed to send MODE_SELECT10 command: %s\n",
			iscsi_get_error(iscsi));
		ret = 10;
		goto finished;
	}
	if (select_task->status != SCSI_STATUS_GOOD) {
		printf("MODE_SELECT10 failed: %s\n",
			iscsi_get_error(iscsi));
		ret = 10;
		goto finished;
	}


finished:
	if (sense_task != NULL) {
		scsi_free_scsi_task(sense_task);
	}
	if (select_task != NULL) {
		scsi_free_scsi_task(select_task);
	}
	if (iscsi_url != NULL) {
		iscsi_destroy_url(iscsi_url);
	}
	iscsi_logout_sync(iscsi);
	iscsi_destroy_context(iscsi);
	return ret;
}
コード例 #24
0
int T0361_startstopunit_pwrcnd(const char *initiator, const char *url)
{ 
	struct iscsi_context *iscsi;
	struct scsi_task *task;
	int ret, i, lun;

	printf("0361_startstopunit_pwrcnd:\n");
	printf("===================\n");
	if (show_info) {
		printf("Test STARTSTOPUNIT POWERCONDITION functionality.\n");
		printf("1, If PC != 0 we can not eject the media\n");
		printf("2, Try to remount the media\n");
		printf("\n");
		return 0;
	}

	iscsi = iscsi_context_login(initiator, url, &lun);
	if (iscsi == NULL) {
		printf("Failed to login to target\n");
		return -1;
	}

	if (!data_loss) {
		printf("--dataloss flag is not set. Skipping test\n");
		ret = -2;
		goto finished;
	}
	

	ret = 0;


	if (inq->rmb) {
		printf("Media is removable. STARTSTOPUNIT should work\n");
	} else {
		printf("Media is not removable. STARTSTOPUNIT should fail\n");
	}
	for (i = 1; i < 16; i++) {
		printf("Try to eject media with PC == %d ... ", i);
		task = iscsi_startstopunit_sync(iscsi, lun, 1, 0, i, 0, 1, 0);
		if (task == NULL) {
		        printf("[FAILED]\n");
			printf("Failed to send STARTSTOPUNIT command: %s\n", iscsi_get_error(iscsi));
			ret = -1;
			goto finished;
		}
		if (task->status != SCSI_STATUS_GOOD) {
			printf("[FAILED]\n");
			printf("STARTSTOPUNIT command: failed with sense. %s\n", iscsi_get_error(iscsi));
			ret = -1;
			scsi_free_scsi_task(task);
			goto finished;
		}
		scsi_free_scsi_task(task);
		printf("[OK]\n");

		printf("Check with TESTUNITREADY that the medium is still present.\n");
		ret = testunitready(iscsi, lun);
		if (ret != 0) {
			goto finished;
		}
	}



	printf("Try to mount the media again ... ");
	task = iscsi_startstopunit_sync(iscsi, lun, 1, 0, 0, 0, 1, 1);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send STARTSTOPUNIT command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status != SCSI_STATUS_GOOD) {
	        printf("[FAILED]\n");
		printf("STARTSTOPUNIT command: failed with sense. %s\n", iscsi_get_error(iscsi));
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	scsi_free_scsi_task(task);
	printf("[OK]\n");


	printf("Check with TESTUNITREADY that the medium is still present.\n");
	ret = testunitready(iscsi, lun);
	if (ret != 0) {
		goto finished;
	}


finished:
	iscsi_logout_sync(iscsi);
	iscsi_destroy_context(iscsi);
	return ret;
}
コード例 #25
0
int T0212_read12_flags(const char *initiator, const char *url)
{ 
	struct iscsi_context *iscsi;
	struct scsi_task *task;
	int ret = 0, lun;

	printf("0212_read12_flags:\n");
	printf("==================\n");
	if (show_info) {
		printf("Test how READ12 handles the flag bits\n");
		printf("1, Reading with DPO should work\n");
		printf("2, Reading with FUA should work\n");
		printf("3, Reading with FUA_NV should work\n");
		printf("4, Reading with FUA+FUA_NV should work\n");
		printf("\n");
		return 0;
	}

	iscsi = iscsi_context_login(initiator, url, &lun);
	if (iscsi == NULL) {
		printf("Failed to login to target\n");
		return -1;
	}

	/* This test is only valid for SBC devices */
	if (device_type != SCSI_INQUIRY_PERIPHERAL_DEVICE_TYPE_DIRECT_ACCESS) {
		printf("LUN is not SBC device. Skipping test\n");
		return -2;
	}


	printf("Read12 with DPO ");
	task = iscsi_read12_sync(iscsi, lun, 0, block_size, block_size, 0, 1, 0, 0, 0);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send read12 command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status != SCSI_STATUS_GOOD) {
	        printf("[FAILED]\n");
		printf("Read12 command: failed with sense. %s\n", iscsi_get_error(iscsi));
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	printf("[OK]\n");

	printf("Read12 with FUA ");
	task = iscsi_read12_sync(iscsi, lun, 0, block_size, block_size, 0, 0, 1, 0, 0);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send read12 command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status != SCSI_STATUS_GOOD) {
	        printf("[FAILED]\n");
		printf("Read12 command: failed with sense. %s\n", iscsi_get_error(iscsi));
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	printf("[OK]\n");


	printf("Read12 with FUA_NV ");
	task = iscsi_read12_sync(iscsi, lun, 0, block_size, block_size, 0, 0, 0, 1, 0);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send read12 command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status != SCSI_STATUS_GOOD) {
	        printf("[FAILED]\n");
		printf("Read12 command: failed with sense. %s\n", iscsi_get_error(iscsi));
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	printf("[OK]\n");

	printf("Read12 with FUA+FUA_NV ");
	task = iscsi_read12_sync(iscsi, lun, 0, block_size, block_size, 0, 0, 1, 1, 0);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send read12 command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status != SCSI_STATUS_GOOD) {
	        printf("[FAILED]\n");
		printf("Read12 command: failed with sense. %s\n", iscsi_get_error(iscsi));
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	printf("[OK]\n");

finished:
	iscsi_logout_sync(iscsi);
	iscsi_destroy_context(iscsi);
	return ret;
}
コード例 #26
0
int T0362_startstopunit_noloej(const char *initiator, const char *url)
{ 
	struct iscsi_context *iscsi;
	struct scsi_task *task;
	int ret, lun;

	printf("0362_startstopunit_noloej:\n");
	printf("===================\n");
	if (show_info) {
		printf("Test STARTSTOPUNIT and LOEJ==0 will never eject/load media.\n");
		printf("1, LOEJ==0  IMMED==0 NO_FLUSH==0 START==0 will not eject the media\n");
		printf("2, LOEJ==0  IMMED==0 NO_FLUSH==0 START==1 will not eject the media\n");
		printf("3, LOEJ==0  IMMED==1 NO_FLUSH==0 START==0 will not eject the media\n");
		printf("4, LOEJ==0  IMMED==1 NO_FLUSH==0 START==1 will not eject the media\n");
		printf("5, LOEJ==0  IMMED==0 NO_FLUSH==1 START==0 will not eject the media\n");
		printf("6, LOEJ==0  IMMED==0 NO_FLUSH==1 START==1 will not eject the media\n");
		printf("7, LOEJ==0  IMMED==1 NO_FLUSH==1 START==0 will not eject the media\n");
		printf("8, LOEJ==0  IMMED==1 NO_FLUSH==1 START==1 will not eject the media\n");
		printf("\n");
		return 0;
	}

	iscsi = iscsi_context_login(initiator, url, &lun);
	if (iscsi == NULL) {
		printf("Failed to login to target\n");
		return -1;
	}

	if (!data_loss) {
		printf("--dataloss flag is not set. Skipping test\n");
		ret = -2;
		goto finished;
	}
	

	ret = 0;


	if (!removable) {
		printf("Media is not removable. SKIPPING tests\n");
		ret = -2;
		goto finished;
	}



	printf("STARTSTOP LOEJ==0 IMMED==0 NO_FLUSH==0 START==0 does not eject media ... ");
	task = iscsi_startstopunit_sync(iscsi, lun, 0, 0, 0, 0, 0, 0);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send STARTSTOPUNIT command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status != SCSI_STATUS_GOOD) {
		printf("[FAILED]\n");
		printf("STARTSTOPUNIT command: failed with sense. %s\n", iscsi_get_error(iscsi));
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	scsi_free_scsi_task(task);
	printf("[OK]\n");

	printf("Check with TESTUNITREADY that the medium is still present.\n");
	ret = testunitready(iscsi, lun);
	if (ret != 0) {
		goto finished;
	}


	/* in case the previous command did eject the media */
	iscsi_startstopunit_sync(iscsi, lun, 1, 0, 0, 0, 1, 1);

	printf("STARTSTOP LOEJ==0 IMMED==0 NO_FLUSH==0 START==1 does not eject media ... ");
	task = iscsi_startstopunit_sync(iscsi, lun, 0, 0, 0, 0, 0, 1);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send STARTSTOPUNIT command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status != SCSI_STATUS_GOOD) {
		printf("[FAILED]\n");
		printf("STARTSTOPUNIT command: failed with sense. %s\n", iscsi_get_error(iscsi));
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	scsi_free_scsi_task(task);
	printf("[OK]\n");

	printf("Check with TESTUNITREADY that the medium is still present.\n");
	ret = testunitready(iscsi, lun);
	if (ret != 0) {
		goto finished;
	}


	/* in case the previous command did eject the media */
	iscsi_startstopunit_sync(iscsi, lun, 1, 0, 0, 0, 1, 1);

	printf("STARTSTOP LOEJ==0 IMMED==1 NO_FLUSH==0 START==0 does not eject media ... ");
	task = iscsi_startstopunit_sync(iscsi, lun, 1, 0, 0, 0, 0, 0);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send STARTSTOPUNIT command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status != SCSI_STATUS_GOOD) {
		printf("[FAILED]\n");
		printf("STARTSTOPUNIT command: failed with sense. %s\n", iscsi_get_error(iscsi));
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	scsi_free_scsi_task(task);
	printf("[OK]\n");

	printf("Check with TESTUNITREADY that the medium is still present.\n");
	ret = testunitready(iscsi, lun);
	if (ret != 0) {
		goto finished;
	}


	/* in case the previous command did eject the media */
	iscsi_startstopunit_sync(iscsi, lun, 1, 0, 0, 0, 1, 1);

	printf("STARTSTOP LOEJ==0 IMMED==1 NO_FLUSH==0 START==1 does not eject media ... ");
	task = iscsi_startstopunit_sync(iscsi, lun, 1, 0, 0, 0, 0, 1);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send STARTSTOPUNIT command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status != SCSI_STATUS_GOOD) {
		printf("[FAILED]\n");
		printf("STARTSTOPUNIT command: failed with sense. %s\n", iscsi_get_error(iscsi));
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	scsi_free_scsi_task(task);
	printf("[OK]\n");

	printf("Check with TESTUNITREADY that the medium is still present.\n");
	ret = testunitready(iscsi, lun);
	if (ret != 0) {
		goto finished;
	}


	/* in case the previous command did eject the media */
	iscsi_startstopunit_sync(iscsi, lun, 1, 0, 0, 0, 1, 1);

	printf("STARTSTOP LOEJ==0 IMMED==0 NO_FLUSH==1 START==0 does not eject media ... ");
	task = iscsi_startstopunit_sync(iscsi, lun, 0, 0, 0, 1, 0, 0);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send STARTSTOPUNIT command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status != SCSI_STATUS_GOOD) {
		printf("[FAILED]\n");
		printf("STARTSTOPUNIT command: failed with sense. %s\n", iscsi_get_error(iscsi));
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	scsi_free_scsi_task(task);
	printf("[OK]\n");

	printf("Check with TESTUNITREADY that the medium is still present.\n");
	ret = testunitready(iscsi, lun);
	if (ret != 0) {
		goto finished;
	}


	/* in case the previous command did eject the media */
	iscsi_startstopunit_sync(iscsi, lun, 1, 0, 0, 0, 1, 1);

	printf("STARTSTOP LOEJ==0 IMMED==0 NO_FLUSH==1 START==1 does not eject media ... ");
	task = iscsi_startstopunit_sync(iscsi, lun, 0, 0, 0, 1, 0, 1);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send STARTSTOPUNIT command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status != SCSI_STATUS_GOOD) {
		printf("[FAILED]\n");
		printf("STARTSTOPUNIT command: failed with sense. %s\n", iscsi_get_error(iscsi));
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	scsi_free_scsi_task(task);
	printf("[OK]\n");

	printf("Check with TESTUNITREADY that the medium is still present.\n");
	ret = testunitready(iscsi, lun);
	if (ret != 0) {
		goto finished;
	}


	/* in case the previous command did eject the media */
	iscsi_startstopunit_sync(iscsi, lun, 1, 0, 0, 0, 1, 1);

	printf("STARTSTOP LOEJ==0 IMMED==1 NO_FLUSH==1 START==0 does not eject media ... ");
	task = iscsi_startstopunit_sync(iscsi, lun, 1, 0, 0, 1, 0, 0);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send STARTSTOPUNIT command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status != SCSI_STATUS_GOOD) {
		printf("[FAILED]\n");
		printf("STARTSTOPUNIT command: failed with sense. %s\n", iscsi_get_error(iscsi));
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	scsi_free_scsi_task(task);
	printf("[OK]\n");

	printf("Check with TESTUNITREADY that the medium is still present.\n");
	ret = testunitready(iscsi, lun);
	if (ret != 0) {
		goto finished;
	}


	/* in case the previous command did eject the media */
	iscsi_startstopunit_sync(iscsi, lun, 1, 0, 0, 0, 1, 1);

	printf("STARTSTOP LOEJ==0 IMMED==1 NO_FLUSH==1 START==1 does not eject media ... ");
	task = iscsi_startstopunit_sync(iscsi, lun, 1, 0, 0, 1, 0, 1);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send STARTSTOPUNIT command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status != SCSI_STATUS_GOOD) {
		printf("[FAILED]\n");
		printf("STARTSTOPUNIT command: failed with sense. %s\n", iscsi_get_error(iscsi));
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	scsi_free_scsi_task(task);
	printf("[OK]\n");

	printf("Check with TESTUNITREADY that the medium is still present.\n");
	ret = testunitready(iscsi, lun);
	if (ret != 0) {
		goto finished;
	}


	/* in case the previous command did eject the media */
	iscsi_startstopunit_sync(iscsi, lun, 1, 0, 0, 0, 1, 1);

finished:
	iscsi_logout_sync(iscsi);
	iscsi_destroy_context(iscsi);
	return ret;
}
コード例 #27
0
ファイル: 0300_readonly.c プロジェクト: gonzoleeman/libiscsi
int T0300_readonly(const char *initiator, const char *url)
{ 
	struct iscsi_context *iscsi;
	struct scsi_task *task;
	struct scsi_mode_sense *ms;
	int ret, lun;
	unsigned char data[4096];
	struct unmap_list list[1];
	int full_size;

	ret = -1;

	printf("0300_readonly:\n");
	printf("==============\n");
	if (show_info) {
		printf("Test that all commands that modify the medium fail for readonly devices\n");
		printf("1, WRITE10 at LUN 0 should fail.\n");
		printf("2, WRITE12 at LUN 0 should fail.\n");
		printf("3, WRITE16 at LUN 0 should fail.\n");
		printf("4, WRITESAME10 at LUN 0 should fail.\n");
		printf("5, WRITESAME16 at LUN 0 should fail.\n");
		printf("6, WRITESAME10 with UNMAP at LUN 0 should fail (skipped if not thin-provisioned).\n");
		printf("7, WRITESAME16 with UNMAP at LUN 0 should fail (skipped if not thin-provisioned).\n");
		printf("8, UNMAP at LUN 0 should fail (skipped if not thin-provisioned).\n");
		printf("9, WRITEVERIFY10 at LUN 0 should fail.\n");
		printf("10, WRITEVERIFY12 at LUN 0 should fail.\n");
		printf("11, WRITEVERIFY16 at LUN 0 should fail.\n");
		printf("12, COMPAREANDWRITE at LUN 0 should fail.\n");
		printf("13, ORWRITE at LUN 0 should fail.\n");
		printf("\n");
		return 0;
	}

	iscsi = iscsi_context_login(initiator, url, &lun);
	if (iscsi == NULL) {
		printf("Failed to login to target\n");
		return -1;
	}

	if (!data_loss) {
		printf("--dataloss flag is not set. Skipping test\n");
		ret = -2;
		goto finished;
	}

	/* This test is only valid for SBC devices */
	if (device_type != SCSI_INQUIRY_PERIPHERAL_DEVICE_TYPE_DIRECT_ACCESS) {
		printf("LUN is not SBC device. Skipping test\n");
		return -2;
	}

	/* verify the device is readonly */
	task = iscsi_modesense6_sync(iscsi, lun, 0, SCSI_MODESENSE_PC_CURRENT,
				     SCSI_MODESENSE_PAGECODE_RETURN_ALL_PAGES, 0,
				     4);
	if (task == NULL) {
		printf("Failed to send modesense6 command: %s\n", iscsi_get_error(iscsi));
		goto finished;
	}
	full_size = scsi_datain_getfullsize(task);
	if (full_size > task->datain.size) {
		scsi_free_scsi_task(task);
		task = iscsi_modesense6_sync(iscsi, lun, 0, SCSI_MODESENSE_PC_CURRENT,
					     SCSI_MODESENSE_PAGECODE_RETURN_ALL_PAGES, 0,
					     full_size);
		if (task == NULL) {
			printf("Failed to send modesense6 command: %s\n", iscsi_get_error(iscsi));
			goto finished;
		}
	}
	ms = scsi_datain_unmarshall(task);
	if (ms == NULL) {
		printf("failed to unmarshall mode sense datain blob\n");
		scsi_free_scsi_task(task);
		goto finished;
	}
	if (!(ms->device_specific_parameter & 0x80)) {
		printf("Device is not read-only. Skipping test\n");
		ret = -2;
		goto finished;
	}
	scsi_free_scsi_task(task);


	ret = 0;


	/* Write one block at lba 0 */
	printf("WRITE10 to LUN 0 ... ");
	task = iscsi_write10_sync(iscsi, lun, 0, data, block_size, block_size, 0, 0, 0, 0, 0);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send WRITE10 command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status == SCSI_STATUS_GOOD) {
	        printf("[FAILED]\n");
		printf("WRITE10 command should fail when writing to readonly devices\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	if (task->status        != SCSI_STATUS_CHECK_CONDITION
	    || task->sense.key  != SCSI_SENSE_DATA_PROTECTION
	    || task->sense.ascq != SCSI_SENSE_ASCQ_WRITE_PROTECTED) {
		printf("[FAILED]\n");
		printf("WRITE10 failed with the wrong sense code. Should fail with DATA_PROTECTION/WRITE_PROTECTED\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}	
	scsi_free_scsi_task(task);
	printf("[OK]\n");


	/* Write one block at lba 0 */
	printf("WRITE12 to LUN 0 ... ");
	task = iscsi_write12_sync(iscsi, lun, 0, data, block_size, block_size, 0, 0, 0, 0, 0);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send WRITE12 command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status == SCSI_STATUS_GOOD) {
	        printf("[FAILED]\n");
		printf("WRITE12 command should fail when writing to readonly devices\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	if (task->status        != SCSI_STATUS_CHECK_CONDITION
	    || task->sense.key  != SCSI_SENSE_DATA_PROTECTION
	    || task->sense.ascq != SCSI_SENSE_ASCQ_WRITE_PROTECTED) {
		printf("[FAILED]\n");
		printf("WRITE12 failed with the wrong sense code. Should fail with DATA_PROTECTION/WRITE_PROTECTED\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}	
	scsi_free_scsi_task(task);
	printf("[OK]\n");


	/* Write one block at lba 0 */
	printf("WRITE16 to LUN 0 ... ");
	task = iscsi_write16_sync(iscsi, lun, 0, data, block_size, block_size, 0, 0, 0, 0, 0);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send WRITE16 command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status == SCSI_STATUS_GOOD) {
	        printf("[FAILED]\n");
		printf("WRITE16 command should fail when writing to readonly devices\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	if (task->status        != SCSI_STATUS_CHECK_CONDITION
	    || task->sense.key  != SCSI_SENSE_DATA_PROTECTION
	    || task->sense.ascq != SCSI_SENSE_ASCQ_WRITE_PROTECTED) {
		printf("[FAILED]\n");
		printf("WRITE16 failed with the wrong sense code. Should fail with DATA_PROTECTION/WRITE_PROTECTED\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}	
	scsi_free_scsi_task(task);
	printf("[OK]\n");


	/* Write one block at lba 0 */
	printf("WRITESAME10 to LUN 0 ... ");
	task = iscsi_writesame10_sync(iscsi, lun, data, block_size, 0, 1, 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 finished;
	}
	if (task->status == SCSI_STATUS_GOOD) {
	        printf("[FAILED]\n");
		printf("WRITESAME10 command should fail when writing to readonly devices\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	if (task->status        != SCSI_STATUS_CHECK_CONDITION
	    || task->sense.key  != SCSI_SENSE_DATA_PROTECTION
	    || task->sense.ascq != SCSI_SENSE_ASCQ_WRITE_PROTECTED) {
		printf("[FAILED]\n");
		printf("WRITESAME10 failed with the wrong sense code. Should fail with DATA_PROTECTION/WRITE_PROTECTED\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}	
	scsi_free_scsi_task(task);
	printf("[OK]\n");


	/* Write one block at lba 0 */
	printf("WRITESAME16 to LUN 0 ... ");
	task = iscsi_writesame16_sync(iscsi, lun, data, block_size, 0, 1, 0, 0, 0, 0, 0, 0);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send WRITESAME16 command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status == SCSI_STATUS_GOOD) {
	        printf("[FAILED]\n");
		printf("WRITESAME16 command should fail when writing to readonly devices\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	if (task->status        != SCSI_STATUS_CHECK_CONDITION
	    || task->sense.key  != SCSI_SENSE_DATA_PROTECTION
	    || task->sense.ascq != SCSI_SENSE_ASCQ_WRITE_PROTECTED) {
		printf("[FAILED]\n");
		printf("WRITESAME16 failed with the wrong sense code. Should fail with DATA_PROTECTION/WRITE_PROTECTED\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}	
	scsi_free_scsi_task(task);
	printf("[OK]\n");


	/* UNMAP one block at lba 0 */
	printf("WRITESAME10 to UNMAP LUN 0 ... ");
	if (lbpme == 0) {
		printf("LUN is not thin-provisioned. [SKIPPED]\n");
		goto finished;
	}
	task = iscsi_writesame10_sync(iscsi, lun, data, block_size, 0, 1, 0, 1, 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 finished;
	}
	if (task->status == SCSI_STATUS_GOOD) {
	        printf("[FAILED]\n");
		printf("WRITESAME10 command should fail when writing to readonly devices\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	if (task->status        != SCSI_STATUS_CHECK_CONDITION
	    || task->sense.key  != SCSI_SENSE_DATA_PROTECTION
	    || task->sense.ascq != SCSI_SENSE_ASCQ_WRITE_PROTECTED) {
		printf("[FAILED]\n");
		printf("WRITESAME10 failed with the wrong sense code. Should fail with DATA_PROTECTION/WRITE_PROTECTED\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}	
	scsi_free_scsi_task(task);
	printf("[OK]\n");


	/* UNMAP one block at lba 0 */
	printf("WRITESAME16 to UNMAP LUN 0 ... ");
	if (lbpme == 0) {
		printf("LUN is not thin-provisioned. [SKIPPED]\n");
		goto finished;
	}
	task = iscsi_writesame16_sync(iscsi, lun, data, block_size, 0, 1, 0, 1, 0, 0, 0, 0);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send WRITESAME16 command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status == SCSI_STATUS_GOOD) {
	        printf("[FAILED]\n");
		printf("WRITESAME16 command should fail when writing to readonly devices\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	if (task->status        != SCSI_STATUS_CHECK_CONDITION
	    || task->sense.key  != SCSI_SENSE_DATA_PROTECTION
	    || task->sense.ascq != SCSI_SENSE_ASCQ_WRITE_PROTECTED) {
		printf("[FAILED]\n");
		printf("WRITESAME16 failed with the wrong sense code. Should fail with DATA_PROTECTION/WRITE_PROTECTED\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}	
	scsi_free_scsi_task(task);
	printf("[OK]\n");


	/* UNMAP one block at lba 0 */
	printf("UNMAP LUN 0 ... ");
	if (lbpme == 0) {
		printf("LUN is not thin-provisioned. [SKIPPED]\n");
		goto finished;
	}
	list[0].lba = 0;
	list[0].num = 1;
	task = iscsi_unmap_sync(iscsi, lun, 0, 0, &list[0], 1);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send UNMAP command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status == SCSI_STATUS_GOOD) {
	        printf("[FAILED]\n");
		printf("UNMAP command should fail when writing to readonly devices\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	if (task->status        != SCSI_STATUS_CHECK_CONDITION
	    || task->sense.key  != SCSI_SENSE_DATA_PROTECTION
	    || task->sense.ascq != SCSI_SENSE_ASCQ_WRITE_PROTECTED) {
		printf("[FAILED]\n");
		printf("UNMAP failed with the wrong sense code. Should fail with DATA_PROTECTION/WRITE_PROTECTED\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}	
	scsi_free_scsi_task(task);
	printf("[OK]\n");


	/* Write one block at lba 0 */
	printf("WRITEVERIFY10 to LUN 0 ... ");
	task = iscsi_writeverify10_sync(iscsi, lun, 0, data, block_size, block_size, 0, 0, 0, 0);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send WRITEVERIFY10 command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status == SCSI_STATUS_GOOD) {
	        printf("[FAILED]\n");
		printf("WRITEVERIFY10 command should fail when writing to readonly devices\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	if (task->status        != SCSI_STATUS_CHECK_CONDITION
	    || task->sense.key  != SCSI_SENSE_DATA_PROTECTION
	    || task->sense.ascq != SCSI_SENSE_ASCQ_WRITE_PROTECTED) {
		printf("[FAILED]\n");
		printf("WRITEVERIFY10 failed with the wrong sense code. Should fail with DATA_PROTECTION/WRITE_PROTECTED\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}	
	scsi_free_scsi_task(task);
	printf("[OK]\n");


	/* Write one block at lba 0 */
	printf("WRITEVERIFY12 to LUN 0 ... ");
	task = iscsi_writeverify12_sync(iscsi, lun, 0, data, block_size, block_size, 0, 0, 0, 0);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send WRITEVERIFY12 command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status == SCSI_STATUS_GOOD) {
	        printf("[FAILED]\n");
		printf("WRITEVERIFY12 command should fail when writing to readonly devices\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	if (task->status        != SCSI_STATUS_CHECK_CONDITION
	    || task->sense.key  != SCSI_SENSE_DATA_PROTECTION
	    || task->sense.ascq != SCSI_SENSE_ASCQ_WRITE_PROTECTED) {
		printf("[FAILED]\n");
		printf("WRITEVERIFY12 failed with the wrong sense code. Should fail with DATA_PROTECTION/WRITE_PROTECTED\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}	
	scsi_free_scsi_task(task);
	printf("[OK]\n");


	/* Write one block at lba 0 */
	printf("WRITEVERIFY16 to LUN 0 ... ");
	task = iscsi_writeverify16_sync(iscsi, lun, 0, data, block_size, block_size, 0, 0, 0, 0);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send WRITEVERIFY16 command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status == SCSI_STATUS_GOOD) {
	        printf("[FAILED]\n");
		printf("WRITEVERIFY16 command should fail when writing to readonly devices\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	if (task->status        != SCSI_STATUS_CHECK_CONDITION
	    || task->sense.key  != SCSI_SENSE_DATA_PROTECTION
	    || task->sense.ascq != SCSI_SENSE_ASCQ_WRITE_PROTECTED) {
		printf("[FAILED]\n");
		printf("WRITEVERIFY16 failed with the wrong sense code. Should fail with DATA_PROTECTION/WRITE_PROTECTED\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}	
	scsi_free_scsi_task(task);
	printf("[OK]\n");


	/* Write one block at lba 0 */
	printf("COMPAREWRITE to LUN 0 ... ");
	task = iscsi_compareandwrite_sync(iscsi, lun, 0, data, block_size, block_size, 0, 0, 0, 0, 0);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send COMPAREANDWRITE command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status == SCSI_STATUS_GOOD) {
	        printf("[FAILED]\n");
		printf("COMPAREANDWRITE command should fail when writing to readonly devices\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	if (task->status        != SCSI_STATUS_CHECK_CONDITION
	    || task->sense.key  != SCSI_SENSE_DATA_PROTECTION
	    || task->sense.ascq != SCSI_SENSE_ASCQ_WRITE_PROTECTED) {
		printf("[FAILED]\n");
		printf("COMPAREANDWRITE failed with the wrong sense code. Should fail with DATA_PROTECTION/WRITE_PROTECTED\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}	
	scsi_free_scsi_task(task);
	printf("[OK]\n");


	/* Write one block at lba 0 */
	printf("ORWRITE to LUN 0 ... ");
	task = iscsi_orwrite_sync(iscsi, lun, 0, data, block_size, block_size, 0, 0, 0, 0, 0);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send ORWRITE command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status == SCSI_STATUS_GOOD) {
	        printf("[FAILED]\n");
		printf("ORWRITE command should fail when writing to readonly devices\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	if (task->status        != SCSI_STATUS_CHECK_CONDITION
	    || task->sense.key  != SCSI_SENSE_DATA_PROTECTION
	    || task->sense.ascq != SCSI_SENSE_ASCQ_WRITE_PROTECTED) {
		printf("[FAILED]\n");
		printf("ORWRITE failed with the wrong sense code. Should fail with DATA_PROTECTION/WRITE_PROTECTED\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}	
	scsi_free_scsi_task(task);
	printf("[OK]\n");


finished:
	iscsi_logout_sync(iscsi);
	iscsi_destroy_context(iscsi);
	return ret;
}
コード例 #28
0
int T1145_persistent_reserve_access_check_wear(const char *initiator,
    const char *url)
{
	struct iscsi_context *iscsi = NULL, *iscsi2 = NULL;
	int ret;
	int lun, lun2;
	const unsigned long long key = rand_key();
	const unsigned long long key2 = rand_key();
	const enum scsi_persistent_out_type pr_type = 
		SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE_ALL_REGISTRANTS;
	const char *pr_type_str = scsi_pr_type_str(pr_type);
	unsigned char *buf = NULL;


	printf("1145_persistent_reserve_access_check_wear:\n");
	printf("=========================================\n");
	if (show_info) {
		int idx = 1;

		printf("Test that access constrols are correct for %s Persistent Reservations\n",
		    pr_type_str);
		printf("%d, %s Reservation Holder Read Access\n",
		    idx++, pr_type_str);
		printf("%d, %s Reservation Holder Write Access\n",
		    idx++, pr_type_str);
		printf("%d, non-%s Reservation Holder does not have read access\n",
		    idx++, pr_type_str);
		printf("%d, non-%s Reservation Holder does not have write access\n",
		    idx++, pr_type_str);
		return 0;
	}

	iscsi = iscsi_context_login(initiator, url, &lun);
	if (iscsi == NULL) {
		printf("Failed to login to target\n");
		ret = -1;
		goto finished;
	}
	iscsi2 = iscsi_context_login(initiatorname2, url, &lun2);
	if (iscsi2 == NULL) {
		printf("Failed to login to target (2nd initiator)\n");
		ret = -1;
		goto finished;
	}

	if (!data_loss) {
		printf("--dataloss flag is not set. Skipping test\n");
		ret = -2;
		goto finished;
	}
	
	/* register our reservation key with the target */
	ret = register_and_ignore(iscsi, lun, key);
	if (ret != 0)
		goto finished;
	ret = register_and_ignore(iscsi2, lun2, key2);
	if (ret != 0)
		goto finished;

	/* reserve the target through initiator 1 */
	ret = reserve(iscsi, lun, key, pr_type);
	if (ret != 0)
		goto finished;

	/* verify target reservation */
	ret = verify_reserved_as(iscsi, lun,
	    pr_type_is_all_registrants(pr_type) ? 0 : key,
	    pr_type);
	if (ret != 0)
		goto finished;

	buf = malloc(512);			/* allocate a buffer */
	if (buf == NULL) {
		printf("failed to allocate 512 byes of memory\n");
		ret = -1;
		goto finished;
	}

	/* make sure init1 can read */
	ret = verify_read_works(iscsi, lun, buf);
	if (ret != 0)
		goto finished;

	/* make sure init1 can write */
	ret = verify_write_works(iscsi, lun, buf);
	if (ret != 0)
		goto finished;

	/* make sure init2 does have read access */
	ret = verify_read_works(iscsi2, lun2, buf);
	if (ret != 0)
		goto finished;

	/* make sure init2 does have write access */
	ret = verify_write_works(iscsi2, lun2, buf);
	if (ret != 0)
		goto finished;

	/* unregister init2 */
	ret = register_key(iscsi2, lun2, 0, key);
	if (ret != 0) {
		goto finished;
	}

	/* make sure init2 does have read access */
	ret = verify_read_works(iscsi2, lun2, buf);
	if (ret != 0)
		goto finished;

	/* make sure init2 does not have write access */
	ret = verify_write_fails(iscsi2, lun2, buf);
	if (ret != 0)
		goto finished;

	/* release our reservation */
	ret = release(iscsi, lun, key, pr_type);
	if (ret != 0)
		goto finished;

	/* remove our key from the target */
	ret = register_key(iscsi, lun, 0, key);
	if (ret != 0)
		goto finished;

finished:
	/* XXX should we clean up key if needed? */
	if (iscsi) {
		iscsi_logout_sync(iscsi);
		iscsi_destroy_context(iscsi);
	}
	if (iscsi2) {
		iscsi_logout_sync(iscsi2);
		iscsi_destroy_context(iscsi2);
	}
	if (buf)
		free(buf);
	return ret;
}
コード例 #29
0
ファイル: 0102_read10_0blocks.c プロジェクト: djs55/libiscsi
int T0102_read10_0blocks(const char *initiator, const char *url)
{ 
	struct iscsi_context *iscsi;
	struct scsi_task *task;
	struct scsi_readcapacity10 *rc10;
	int ret, i, lun;
	uint32_t block_size, num_blocks;

	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_readcapacity10_sync(iscsi, lun, 0, 0);
	if (task == NULL) {
		printf("Failed to send readcapacity10 command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status != SCSI_STATUS_GOOD) {
		printf("Readcapacity command: failed with sense. %s\n", iscsi_get_error(iscsi));
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	rc10 = scsi_datain_unmarshall(task);
	if (rc10 == NULL) {
		printf("failed to unmarshall readcapacity10 data. %s\n", iscsi_get_error(iscsi));
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	block_size = rc10->block_size;
	num_blocks = rc10->lba;
	scsi_free_scsi_task(task);



	ret = 0;

	/* read10 0 blocks one block at lba 0 */
	printf("Reading 0 blocks at lba:0 ... ");
	task = iscsi_read10_sync(iscsi, lun, 0, 0, block_size);
	if (task == NULL) {
 	        printf("[FAILED]\n");
		printf("Failed to send read10 command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status != SCSI_STATUS_GOOD) {
 	        printf("[FAILED]\n");
		printf("Read10 of 0 at lba:0 failed with sense.\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	scsi_free_scsi_task(task);
	printf("[OK]\n");

	/* read10 0 blocks one block beyond the eol */
	printf("Reading 0 blocks at one block beyond end ... ");
	task = iscsi_read10_sync(iscsi, lun, num_blocks + 1, 0, block_size);
	if (task == NULL) {
 	        printf("[FAILED]\n");
		printf("Failed to send read10 command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status != SCSI_STATUS_GOOD) {
 	        printf("[FAILED]\n");
		printf("Read10 of 0 one block beyond end-of-lun failed with sense.\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	scsi_free_scsi_task(task);
	printf("[OK]\n");


	/* read10 0 blocks two blocks beyond the eol */
	printf("Reading 0 blocks at two blocks beyond end ... ");
	task = iscsi_read10_sync(iscsi, lun, num_blocks + 1, 0, block_size);
	if (task == NULL) {
 	        printf("[FAILED]\n");
		printf("Failed to send read10 command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status != SCSI_STATUS_GOOD) {
 	        printf("[FAILED]\n");
		printf("Read10 of 0 two blocks beyond end-of-lun failed with sense.\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	scsi_free_scsi_task(task);
	printf("[OK]\n");


	/* read10 0 at lba -1 */
	printf("Reading 0 blocks at lba:-1 ... ");
	task = iscsi_read10_sync(iscsi, lun, 0xffffff, 0, block_size);
	if (task == NULL) {
 	        printf("[FAILED]\n");
		printf("Failed to send read10 command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	if (task->status != SCSI_STATUS_GOOD) {
 	        printf("[FAILED]\n");
		printf("Read10 of 0 at lba:-1 failed with sense.\n");
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	scsi_free_scsi_task(task);
	printf("[OK]\n");


finished:
	iscsi_logout_sync(iscsi);
	iscsi_destroy_context(iscsi);
	return ret;
}
コード例 #30
0
void
test_preventallow_2_itnexuses(void)
{
	int ret;
	struct scsi_device sd2;

	CHECK_FOR_SBC;
	CHECK_FOR_REMOVABLE;

	logging(LOG_VERBOSE, LOG_BLANK_LINE);
	logging(LOG_VERBOSE, "Test that PREVENT MEDIUM REMOVAL are seen on other nexuses as well");

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

	logging(LOG_VERBOSE, "Set the PREVENT flag");
	ret = preventallow(sd, 1);
	CU_ASSERT_EQUAL(ret, 0);

	logging(LOG_VERBOSE, "Try to eject the medium");
	ret = startstopunit(sd, 0, 0, 0, 0, 1, 0,
			    EXPECT_REMOVAL_PREVENTED);
	CU_ASSERT_EQUAL(ret, 0);

	logging(LOG_VERBOSE, "Verify we can still access the media.");
	ret = testunitready(sd,
			    EXPECT_STATUS_GOOD);
	CU_ASSERT_EQUAL(ret, 0);

	logging(LOG_VERBOSE, "Create a second connection to the target");
	memset(&sd2, 0, sizeof(sd2));
	sd2.iscsi_ctx = iscsi_context_login(initiatorname2, sd->iscsi_url, &sd->iscsi_lun);
	if (sd2.iscsi_ctx == NULL) {
		logging(LOG_VERBOSE, "Failed to login to target");
		return;
	}

	logging(LOG_VERBOSE, "Try to eject the medium on the second connection");
	ret = startstopunit(&sd2, 0, 0, 0, 0, 1, 0,
			    EXPECT_REMOVAL_PREVENTED);
	CU_ASSERT_EQUAL(ret, 0);


	logging(LOG_VERBOSE, "Logout the second connection from target");
	iscsi_logout_sync(sd2.iscsi_ctx);
	iscsi_destroy_context(sd2.iscsi_ctx);



	logging(LOG_VERBOSE, "Clear PREVENT and load medium in case target failed");
	logging(LOG_VERBOSE, "Test we can clear PREVENT flag");
	ret = preventallow(sd, 0);
	CU_ASSERT_EQUAL(ret, 0);

	logging(LOG_VERBOSE, "Load the medium");
	ret = startstopunit(sd, 0, 0, 0, 0, 1, 1,
			    EXPECT_STATUS_GOOD);
	CU_ASSERT_EQUAL(ret, 0);

}