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;
}
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;
}
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;
}
int T0382_preventallow_itnexus_loss(const char *initiator, const char *url)
{
	struct iscsi_context *iscsi;
	struct scsi_task *task;
	int ret, lun;

	printf("0382_preventallow_itnexus_loss:\n");
	printf("===============================\n");
	if (show_info) {
		printf("Test that an I_T_Nexus loss clears PREVENTALLOW.\n");
		printf("1, Verify we can set PREVENTALLOW (if the medium is removable)\n");
		printf("2, Verify we can no longer eject the media\n");
		printf("3, Tear down the I_T_Nexus and re-login on a new nexus\n");
		printf("4, Verify we can eject the media\n");
		printf("5, Load the media again in case it was ejected\n");
		printf("6, Clear PREVENTALLOW again\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 not removable. Skipping tests\n");
		ret = -2;
		goto finished;
	}

	printf("Try to set PREVENTALLOW ... ");
	task = iscsi_preventallow_sync(iscsi, lun, 1);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send PREVENTALLOW command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}

	/* SPC doesnt really say anything about what should happen if using PREVENTALLOW 
	 * on a device that does not support medium removals.
	 */
	if (inq->rmb) {
		if (task->status != SCSI_STATUS_GOOD) {
			printf("[FAILED]\n");
			printf("PREVENTALLOW 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("Try to eject the media ... ");
	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_CHECK_CONDITION
	||  task->sense.key  != SCSI_SENSE_ILLEGAL_REQUEST
	||  task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_REMOVAL_PREVENTED) {
	        printf("[FAILED]\n");
		printf("STARTSTOPUNIT command should have failed with ILLEGAL_REQUEST/MEDIUM_REMOVAL_PREVENTED with : failed with sense. %s\n", iscsi_get_error(iscsi));
		ret = -1;
		scsi_free_scsi_task(task);
		goto finished;
	}
	scsi_free_scsi_task(task);
	printf("Eject failed. [OK]\n");


	printf("Tear down the IT_Nexus and create a new one ... ");
	iscsi_destroy_context(iscsi);
	iscsi = iscsi_context_login(initiator, url, &lun);
	if (iscsi == NULL) {
		printf("Failed to login to target\n");
		goto finished;
	}
	printf("[OK]\n");


//test4:

	printf("Try to eject the media ... ");
	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 should have worked but it 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("Load the media again in case it was ejected ... ");
	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;
	}
	/* SBC doesnt really say anything about whether we can LOAD media when the prevent
	 * flag is set
	 */
	scsi_free_scsi_task(task);
	printf("[OK]\n");


	printf("Clear the PREVENTALLOW again ... ");
	task = iscsi_preventallow_sync(iscsi, lun, 0);
	if (task == NULL) {
	        printf("[FAILED]\n");
		printf("Failed to send PREVENTALLOW command: %s\n", iscsi_get_error(iscsi));
		ret = -1;
		goto finished;
	}
	/* SPC doesnt really say anything about what should happen if using PREVENTALLOW 
	 * on a device that does not support medium removals.
	 */
	if (inq->rmb) {
		if (task->status != SCSI_STATUS_GOOD) {
			printf("[FAILED]\n");
			printf("PREVENTALLOW 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;
}