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;
}
static void
verify_persistent_reserve_access(struct scsi_device *sd1, struct scsi_device *sd2,
    const enum scsi_persistent_out_type pr_type,
    int reg_i2_can_read,
    int reg_i2_can_write,
    int unreg_i2_can_read,
    int unreg_i2_can_write)
{
        int ret;
        const unsigned long long key = rand_key();
        const unsigned long long key2 = rand_key();


        logging(LOG_VERBOSE, LOG_BLANK_LINE);
        logging(LOG_VERBOSE,
            "Verify access for reservation type: %s",
            scsi_pr_type_str(pr_type));

        /* send TURs to clear possible check conditions */
        (void) testunitready_clear_ua(sd1);
        (void) testunitready_clear_ua(sd2);

        /* register our reservation key with the target */
        ret = prout_register_and_ignore(sd1, key);
        if (ret == -2) {
                CU_PASS("PERSISTENT RESERVE OUT is not implemented.");
                return;
        }        
        CU_ASSERT_EQUAL(0, ret);
        ret = prout_register_and_ignore(sd2, key2);
        CU_ASSERT_EQUAL(0, ret);

        /* reserve the target through initiator 1 */
        ret = prout_reserve(sd1, key, pr_type);
        CU_ASSERT_EQUAL(0, ret);

        /* verify target reservation */
        ret = prin_verify_reserved_as(sd1,
            pr_type_is_all_registrants(pr_type) ? 0 : key,
            pr_type);
        CU_ASSERT_EQUAL(0, ret);

        CU_ASSERT_PTR_NOT_NULL_FATAL(scratch);

        /* make sure init1 can read */
        ret = verify_read_works(sd1, scratch);
        CU_ASSERT_EQUAL(0, ret);

        /* make sure init1 can write */
        ret = verify_write_works(sd1, scratch);
        CU_ASSERT_EQUAL(0, ret);

        /* verify registered init2 read access */
        if (reg_i2_can_read)
                ret = verify_read_works(sd2, scratch);
        else
                ret = verify_read_fails(sd2, scratch);
        CU_ASSERT_EQUAL(0, ret);

        /* verify registered init2 write access */
        if (reg_i2_can_write)
                ret = verify_write_works(sd2, scratch);
        else
                ret = verify_write_fails(sd2, scratch);
        CU_ASSERT_EQUAL(0, ret);

        /* unregister init2 */
        ret = prout_register_key(sd2, 0, key2);
        CU_ASSERT_EQUAL(0, ret);

        /* verify unregistered init2 read access */
        if (unreg_i2_can_read)
                ret = verify_read_works(sd2, scratch);
        else
                ret = verify_read_fails(sd2, scratch);
        CU_ASSERT_EQUAL(0, ret);

        /* verify unregistered init2 write access */
        if (unreg_i2_can_write)
                ret = verify_write_works(sd2, scratch);
        else
                ret = verify_write_fails(sd2, scratch);
        CU_ASSERT_EQUAL(0, ret);

        /* release our reservation */
        ret = prout_release(sd1, key, pr_type);
        CU_ASSERT_EQUAL(0, ret);

        /* remove our key from the target */
        ret = prout_register_key(sd1, 0, key);
        CU_ASSERT_EQUAL(0, ret);
}