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; }
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; }
int T0292_write10_flags(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; unsigned char data[256 * 512]; printf("0292_write10_flags:\n"); printf("===================\n"); if (show_info) { printf("Test how WRITE10 handles the flags\n"); printf("1, Write with DPU should work.\n"); printf("2, Write with FUA should work.\n"); printf("3, Write with FUA_NV should work.\n"); printf("4, Write 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; } /* 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; scsi_free_scsi_task(task); printf("Write10 with DPO "); task = iscsi_write10_sync(iscsi, lun, 0, data, block_size, block_size, 0, 1, 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"); if (!data_loss) { printf("--dataloss flag is not set. Skipping test\n"); ret = -1; goto finished; } printf("Write10 with FUA "); task = iscsi_write10_sync(iscsi, lun, 0, data, block_size, block_size, 0, 0, 1, 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 with FUA_NV "); task = iscsi_write10_sync(iscsi, lun, 0, data, block_size, block_size, 0, 0, 0, 1, 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 with FUA+FUA_NV "); task = iscsi_write10_sync(iscsi, lun, 0, data, block_size, block_size, 0, 0, 1, 1, 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"); finished: iscsi_logout_sync(iscsi); iscsi_destroy_context(iscsi); return ret; }
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; }
int T0290_write10_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; uint32_t num_blocks; unsigned char data[512 * 256]; printf("0290_write10_simple:\n"); printf("===================\n"); if (show_info) { printf("Test basic WRITE10 functionality.\n"); printf("1, Verify we can write the first 1-256 blocks of the LUN.\n"); printf("2, Verify we can write 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("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; } ret = 0; /* write the first 1 - 256 blocks at the start of the LUN */ printf("Writing first 1-256 blocks ... "); for (i = 1; i <= 256; i++) { task = iscsi_write10_sync(iscsi, lun, 0, 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: 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"); /* write the last 1 - 256 blocks at the end of the LUN */ printf("Writing last 1-256 blocks ... "); for (i = 1; i <= 256; i++) { task = iscsi_write10_sync(iscsi, lun, num_blocks +1 - i, 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: 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; }