diff --git a/Makefile.am b/Makefile.am index 6f5b635..305a313 100644 --- a/Makefile.am +++ b/Makefile.am @@ -188,6 +188,7 @@ bin_iscsi_test_cu_SOURCES = test-tool/iscsi-test-cu.c \ test-tool/iscsi-support.c \ test-tool/test_get_lba_status_simple.c \ test-tool/test_get_lba_status_beyond_eol.c \ + test-tool/test_nomedia_sbc.c \ test-tool/test_orwrite_simple.c \ test-tool/test_orwrite_beyond_eol.c \ test-tool/test_orwrite_0blocks.c \ diff --git a/test-tool/iscsi-support.c b/test-tool/iscsi-support.c index 5fb5134..cea6d53 100644 --- a/test-tool/iscsi-support.c +++ b/test-tool/iscsi-support.c @@ -368,6 +368,61 @@ orwrite_writeprotected(struct iscsi_context *iscsi, int lun, uint64_t lba, return 0; } +int +orwrite_nomedium(struct iscsi_context *iscsi, int lun, uint64_t lba, + uint32_t datalen, int blocksize, int wrprotect, + int dpo, int fua, int fua_nv, int group, + unsigned char *data) +{ + struct scsi_task *task; + + logging(LOG_VERBOSE, "Send ORWRITE (Expecting MEDIUM_NOT_PRESENT) " + "LBA:%" PRIu64 " blocks:%d wrprotect:%d " + "dpo:%d fua:%d fua_nv:%d group:%d", + lba, datalen / blocksize, wrprotect, + dpo, fua, fua_nv, group); + + if (!data_loss) { + printf("--dataloss flag is not set in. Skipping write\n"); + return -1; + } + + task = iscsi_orwrite_sync(iscsi, lun, lba, data, datalen, blocksize, + wrprotect, dpo, fua, fua_nv, group); + if (task == NULL) { + logging(LOG_NORMAL, "[FAILED] Failed to send ORWRITE command: %s", + iscsi_get_error(iscsi)); + return -1; + } + if (task->status == SCSI_STATUS_CHECK_CONDITION + && task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST + && task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE) { + logging(LOG_NORMAL, "[SKIPPED] ORWRITE is not implemented on target"); + scsi_free_scsi_task(task); + return -2; + } + if (task->status == SCSI_STATUS_GOOD) { + logging(LOG_NORMAL, "[FAILED] ORWRITE command successful. But should have failed with NOT_READY/MEDIUM_NOT_PRESENT*"); + scsi_free_scsi_task(task); + return -1; + } + if (task->status != SCSI_STATUS_CHECK_CONDITION + || task->sense.key != SCSI_SENSE_NOT_READY + || (task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_OPEN + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_CLOSED)) { + logging(LOG_NORMAL, "[FAILED] ORWRITE Should have failed " + "with NOT_READY/MEDIUM_NOT_PRESENT* But failed " + "with %s", iscsi_get_error(iscsi)); + scsi_free_scsi_task(task); + return -1; + } + + scsi_free_scsi_task(task); + logging(LOG_VERBOSE, "[OK] ORWRITE returned MEDIUM_NOT_PRESENT."); + return 0; +} + int prin_task(struct iscsi_context *iscsi, int lun, int service_action, int success_expected) @@ -1022,11 +1077,171 @@ verify_write_fails(struct iscsi_context *iscsi, int lun, unsigned char *buf) return ret; } +int +synchronizecache10(struct iscsi_context *iscsi, int lun, uint32_t lba, int num, int sync_nv, int immed) +{ + struct scsi_task *task; + + logging(LOG_VERBOSE, "Send SYNCHRONIZECACHE10 LBA:%d blocks:%d" + " sync_nv:%d immed:%d", + lba, num, sync_nv, immed); + + task = iscsi_synchronizecache10_sync(iscsi, lun, lba, num, + sync_nv, immed); + if (task == NULL) { + logging(LOG_NORMAL, "[FAILED] Failed to send SYNCHRONIZECAHCE10 command: %s", + iscsi_get_error(iscsi)); + return -1; + } + if (task->status == SCSI_STATUS_CHECK_CONDITION + && task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST + && task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE) { + logging(LOG_NORMAL, "[SKIPPED] SYNCHRONIZECAHCE10 is not implemented on target"); + scsi_free_scsi_task(task); + return -2; + } + if (task->status != SCSI_STATUS_GOOD) { + logging(LOG_NORMAL, "[FAILED] SYNCHRONIZECACHE10 command: " + "failed with sense. %s", iscsi_get_error(iscsi)); + scsi_free_scsi_task(task); + return -1; + } + + scsi_free_scsi_task(task); + logging(LOG_VERBOSE, "[OK] SYNCHRONIZECAHCE10 returned SUCCESS."); + return 0; +} + +int +synchronizecache10_nomedium(struct iscsi_context *iscsi, int lun, uint32_t lba, int num, int sync_nv, int immed) +{ + struct scsi_task *task; + + logging(LOG_VERBOSE, "Send SYNCHRONIZECACHE10 (Expecting MEDIUM_NOT_PRESENT) LBA:%d blocks:%d" + " sync_nv:%d immed:%d", + lba, num, sync_nv, immed); + + task = iscsi_synchronizecache10_sync(iscsi, lun, lba, num, + sync_nv, immed); + if (task == NULL) { + logging(LOG_NORMAL, "[FAILED] Failed to send SYNCHRONIZECAHCE10 command: %s", + iscsi_get_error(iscsi)); + return -1; + } + if (task->status == SCSI_STATUS_CHECK_CONDITION + && task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST + && task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE) { + logging(LOG_NORMAL, "[SKIPPED] SYNCHRONIZECAHCE10 is not implemented on target"); + scsi_free_scsi_task(task); + return -2; + } + if (task->status == SCSI_STATUS_GOOD) { + logging(LOG_NORMAL, "[FAILED] SYNCHRONIZECACHE10 command successful. But should have failed with NOT_READY/MEDIUM_NOT_PRESENT*"); + scsi_free_scsi_task(task); + return -1; + } + if (task->status != SCSI_STATUS_CHECK_CONDITION + || task->sense.key != SCSI_SENSE_NOT_READY + || (task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_OPEN + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_CLOSED)) { + logging(LOG_NORMAL, "[FAILED] SYNCHRONIZECAHCE10 Should have failed " + "with NOT_READY/MEDIUM_NOT_PRESENT* But failed " + "with %s", iscsi_get_error(iscsi)); + scsi_free_scsi_task(task); + return -1; + } + + scsi_free_scsi_task(task); + logging(LOG_VERBOSE, "[OK] SYNCHRONIZECAHCE10 returned MEDIUM_NOT_PRESENT."); + return 0; +} + +int +synchronizecache16(struct iscsi_context *iscsi, int lun, uint64_t lba, int num, int sync_nv, int immed) +{ + struct scsi_task *task; + + logging(LOG_VERBOSE, "Send SYNCHRONIZECACHE16 LBA:%" PRIu64 " blocks:%d" + " sync_nv:%d immed:%d", + lba, num, sync_nv, immed); + + task = iscsi_synchronizecache16_sync(iscsi, lun, lba, num, + sync_nv, immed); + if (task == NULL) { + logging(LOG_NORMAL, "[FAILED] Failed to send SYNCHRONIZECAHCE16 command: %s", + iscsi_get_error(iscsi)); + return -1; + } + if (task->status == SCSI_STATUS_CHECK_CONDITION + && task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST + && task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE) { + logging(LOG_NORMAL, "[SKIPPED] SYNCHRONIZECAHCE16 is not implemented on target"); + scsi_free_scsi_task(task); + return -2; + } + if (task->status != SCSI_STATUS_GOOD) { + logging(LOG_NORMAL, "[FAILED] SYNCHRONIZECACHE16 command: " + "failed with sense. %s", iscsi_get_error(iscsi)); + scsi_free_scsi_task(task); + return -1; + } + + scsi_free_scsi_task(task); + logging(LOG_VERBOSE, "[OK] SYNCHRONIZECAHCE16 returned SUCCESS."); + return 0; +} + +int +synchronizecache16_nomedium(struct iscsi_context *iscsi, int lun, uint64_t lba, int num, int sync_nv, int immed) +{ + struct scsi_task *task; + + logging(LOG_VERBOSE, "Send SYNCHRONIZECACHE16 (Expecting MEDIUM_NOT_PRESENT) LBA:%" PRIu64 " blocks:%d" + " sync_nv:%d immed:%d", + lba, num, sync_nv, immed); + + task = iscsi_synchronizecache16_sync(iscsi, lun, lba, num, + sync_nv, immed); + if (task == NULL) { + logging(LOG_NORMAL, "[FAILED] Failed to send SYNCHRONIZECAHCE16 command: %s", + iscsi_get_error(iscsi)); + return -1; + } + if (task->status == SCSI_STATUS_CHECK_CONDITION + && task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST + && task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE) { + logging(LOG_NORMAL, "[SKIPPED] SYNCHRONIZECAHCE16 is not implemented on target"); + scsi_free_scsi_task(task); + return -2; + } + if (task->status == SCSI_STATUS_GOOD) { + logging(LOG_NORMAL, "[FAILED] SYNCHRONIZECACHE16 command successful. But should have failed with NOT_READY/MEDIUM_NOT_PRESENT*"); + scsi_free_scsi_task(task); + return -1; + } + if (task->status != SCSI_STATUS_CHECK_CONDITION + || task->sense.key != SCSI_SENSE_NOT_READY + || (task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_OPEN + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_CLOSED)) { + logging(LOG_NORMAL, "[FAILED] SYNCHRONIZECACHE16 Should have failed " + "with NOT_READY/MEDIUM_NOT_PRESENT* But failed " + "with %s", iscsi_get_error(iscsi)); + scsi_free_scsi_task(task); + return -1; + } + + scsi_free_scsi_task(task); + logging(LOG_VERBOSE, "[OK] SYNCHRONIZECAHCE16 returned MEDIUM_NOT_PRESENT."); + return 0; +} + int startstopunit(struct iscsi_context *iscsi, int lun, int immed, int pcm, int pc, int no_flush, int loej, int start) { struct scsi_task *task; - logging(LOG_VERBOSE, "Send STARTSTOPUNIT (Expecting SUCCESS) IMMED:%d PCM:%d PC:%d NO_FLUSH:%d LOEJ:%d START:%d", immed, pcm, pc, no_flush, loej, start); + logging(LOG_VERBOSE, "Send STARTSTOPUNIT IMMED:%d PCM:%d PC:%d NO_FLUSH:%d LOEJ:%d START:%d", immed, pcm, pc, no_flush, loej, start); task = iscsi_startstopunit_sync(iscsi, lun, immed, pcm, pc, no_flush, loej, start); if (task == NULL) { @@ -1052,7 +1267,7 @@ testunitready(struct iscsi_context *iscsi, int lun) { struct scsi_task *task; - logging(LOG_VERBOSE, "Send TESTUNITREADY (Expecting SUCCESS)"); + logging(LOG_VERBOSE, "Send TESTUNITREADY"); task = iscsi_testunitready_sync(iscsi, lun); if (task == NULL) { logging(LOG_NORMAL, @@ -1103,20 +1318,25 @@ testunitready_nomedium(struct iscsi_context *iscsi, int lun) { struct scsi_task *task; - logging(LOG_VERBOSE, "Send TESTUNITREADY (expecting NOT_READY/MEDIUM_NOT_PRESENT)"); + logging(LOG_VERBOSE, "Send TESTUNITREADY (Expecting MEDIUM_NOT_PRESENT)"); task = iscsi_testunitready_sync(iscsi, lun); if (task == NULL) { logging(LOG_NORMAL, "[FAILED] Failed to send TESTUNITREADY " "command: %s", iscsi_get_error(iscsi)); return -1; } + if (task->status == SCSI_STATUS_GOOD) { + logging(LOG_NORMAL, "[FAILED] TESTUNITREADY command successful. But should have failed with NOT_READY/MEDIUM_NOT_PRESENT*"); + scsi_free_scsi_task(task); + return -1; + } if (task->status != SCSI_STATUS_CHECK_CONDITION || task->sense.key != SCSI_SENSE_NOT_READY || (task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_OPEN && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_CLOSED)) { logging(LOG_NORMAL, "[FAILED] TESTUNITREADY Should have failed " - "with NOT_READY/MEDIUM_NOT_PRESENT* Buut failed " + "with NOT_READY/MEDIUM_NOT_PRESENT* But failed " "with %s", iscsi_get_error(iscsi)); scsi_free_scsi_task(task); return -1; @@ -1131,7 +1351,7 @@ testunitready_conflict(struct iscsi_context *iscsi, int lun) { struct scsi_task *task; - logging(LOG_VERBOSE, "Send TESTUNITREADY (expecting RESERVATION_CONFLICT)"); + logging(LOG_VERBOSE, "Send TESTUNITREADY (Expecting RESERVATION_CONFLICT)"); task = iscsi_testunitready_sync(iscsi, lun); if (task == NULL) { logging(LOG_NORMAL, "[FAILED] Failed to send TESTUNITREADY " @@ -1185,7 +1405,7 @@ int get_lba_status_lbaoutofrange(struct iscsi_context *iscsi, int lun, uint64_t { struct scsi_task *task; - logging(LOG_VERBOSE, "Send GET_LBA_STATUS (expecting LBA_OUT_OF_RANGE) LBA:%" PRIu64 " blocks:%d", + logging(LOG_VERBOSE, "Send GET_LBA_STATUS (Expecting LBA_OUT_OF_RANGE) LBA:%" PRIu64 " blocks:%d", lba, len); task = iscsi_get_lba_status_sync(iscsi, lun, lba, len); @@ -1221,6 +1441,49 @@ int get_lba_status_lbaoutofrange(struct iscsi_context *iscsi, int lun, uint64_t return 0; } +int get_lba_status_nomedium(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t len) +{ + struct scsi_task *task; + + logging(LOG_VERBOSE, "Send GET_LBA_STATUS (Expecting MEDIUM_NOT_PRESENT) " + "LBA:%" PRIu64 " blocks:%d", + lba, len); + + task = iscsi_get_lba_status_sync(iscsi, lun, lba, len); + if (task == NULL) { + logging(LOG_NORMAL, "[FAILED] Failed to send GET_LBA_STATUS " + "command: %s", + iscsi_get_error(iscsi)); + return -1; + } + if (task->status == SCSI_STATUS_CHECK_CONDITION + && task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST + && task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE) { + logging(LOG_NORMAL, "[SKIPPED] GET_LBA_STATUS is not " + "implemented on target"); + scsi_free_scsi_task(task); + return -2; + } + if (task->status == SCSI_STATUS_GOOD) { + logging(LOG_NORMAL, "[FAILED] GET_LBA_STATUS returned SUCCESS. Should have failed with MEDIUM_NOT_PRESENT."); + scsi_free_scsi_task(task); + return -1; + } + if (task->status != SCSI_STATUS_CHECK_CONDITION + || task->sense.key != SCSI_SENSE_NOT_READY + || (task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_OPEN + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_CLOSED)) { + logging(LOG_NORMAL, "[FAILED] GET_LBA_STATUS failed with the wrong sense code. Should have failed with NOT_READY/MEDIUM_NOT_PRESENT but failed with sense:%s", iscsi_get_error(iscsi)); + scsi_free_scsi_task(task); + return -1; + } + + scsi_free_scsi_task(task); + logging(LOG_VERBOSE, "[OK] GET_LBA_STATUS returned MEDIUM_NOT_PRESENT."); + return 0; +} + int prefetch10(struct iscsi_context *iscsi, int lun, uint32_t lba, int num, int immed, int group) { @@ -1261,10 +1524,9 @@ prefetch10_lbaoutofrange(struct iscsi_context *iscsi, int lun, uint32_t lba, { struct scsi_task *task; - logging(LOG_VERBOSE, "Send PREFETCH10 (expecting ILLEGAL_REQUEST/" - "LBA_OUT_OF_RANGE) LBA:%d blocks:%d" - " immed:%d group:%d", - lba, num, immed, group); + logging(LOG_VERBOSE, "Send PREFETCH10 (Expecting LBA_OUT_OF_RANGE) " + "LBA:%d blocks:%d immed:%d group:%d", + lba, num, immed, group); task = iscsi_prefetch10_sync(iscsi, lun, lba, num, immed, group); if (task == NULL) { @@ -1303,10 +1565,9 @@ prefetch10_nomedium(struct iscsi_context *iscsi, int lun, uint32_t lba, { struct scsi_task *task; - logging(LOG_VERBOSE, "Send PREFETCH10 (expecting NOT_READY/" - "MEDIUM_NOT_PRESENT) LBA:%d blocks:%d" - " immed:%d group:%d", - lba, num, immed, group); + logging(LOG_VERBOSE, "Send PREFETCH10 (Expecting MEDIUM_NOT_PRESENT) " + "LBA:%d blocks:%d immed:%d group:%d", + lba, num, immed, group); task = iscsi_prefetch10_sync(iscsi, lun, lba, num, immed, group); if (task == NULL) { @@ -1338,7 +1599,7 @@ prefetch10_nomedium(struct iscsi_context *iscsi, int lun, uint32_t lba, } scsi_free_scsi_task(task); - logging(LOG_VERBOSE, "[OK] PREFETCH10 returned NOT_READY/MEDIUM_NOT_PRESENT."); + logging(LOG_VERBOSE, "[OK] PREFETCH10 returned MEDIUM_NOT_PRESENT."); return 0; } @@ -1382,10 +1643,9 @@ prefetch16_lbaoutofrange(struct iscsi_context *iscsi, int lun, uint64_t lba, { struct scsi_task *task; - logging(LOG_VERBOSE, "Send PREFETCH16 (expecting ILLEGAL_REQUEST/" - "LBA_OUT_OF_RANGE) LBA:%" PRIu64 " blocks:%d" - " immed:%d group:%d", - lba, num, immed, group); + logging(LOG_VERBOSE, "Send PREFETCH16 (Expecting LBA_OUT_OF_RANGE) " + "LBA:%" PRIu64 " blocks:%d immed:%d group:%d", + lba, num, immed, group); task = iscsi_prefetch16_sync(iscsi, lun, lba, num, immed, group); if (task == NULL) { @@ -1424,10 +1684,9 @@ prefetch16_nomedium(struct iscsi_context *iscsi, int lun, uint64_t lba, { struct scsi_task *task; - logging(LOG_VERBOSE, "Send PREFETCH16 (expecting NOT_READY/" - "MEDIUM_NOT_PRESENT) LBA:%" PRIu64 " blocks:%d" - " immed:%d group:%d", - lba, num, immed, group); + logging(LOG_VERBOSE, "Send PREFETCH16 (Expecting MEDIUM_NOT_PRESENT) " + "LBA:%" PRIu64 " blocks:%d immed:%d group:%d", + lba, num, immed, group); task = iscsi_prefetch16_sync(iscsi, lun, lba, num, immed, group); if (task == NULL) { @@ -1459,7 +1718,7 @@ prefetch16_nomedium(struct iscsi_context *iscsi, int lun, uint64_t lba, } scsi_free_scsi_task(task); - logging(LOG_VERBOSE, "[OK] PREFETCH16 returned NOT_READY/MEDIUM_NOT_PRESENT."); + logging(LOG_VERBOSE, "[OK] PREFETCH16 returned MEDIUM_NOT_PRESENT."); return 0; } @@ -1666,6 +1925,54 @@ read10_lbaoutofrange(struct iscsi_context *iscsi, int lun, uint32_t lba, return 0; } +int +read10_nomedium(struct iscsi_context *iscsi, int lun, uint32_t lba, + uint32_t datalen, int blocksize, int rdprotect, + int dpo, int fua, int fua_nv, int group, + unsigned char *data) +{ + struct scsi_task *task; + + logging(LOG_VERBOSE, "Send READ10 (Expecting MEDIUM_NOT_PRESENT) " + "LBA:%d blocks:%d rdprotect:%d " + "dpo:%d fua:%d fua_nv:%d group:%d", + lba, datalen / blocksize, rdprotect, + dpo, fua, fua_nv, group); + + task = iscsi_read10_sync(iscsi, lun, lba, datalen, blocksize, + rdprotect, dpo, fua, fua_nv, group); + if (task == NULL) { + logging(LOG_NORMAL, "[FAILED] Failed to send READ10 command: %s", + iscsi_get_error(iscsi)); + return -1; + } + if (task->status == SCSI_STATUS_GOOD) { + logging(LOG_NORMAL, "[FAILED] READ10 successful but should " + "have failed with NOT_READY/MEDIUM_NOT_PRESENT*"); + scsi_free_scsi_task(task); + return -1; + } + if (task->status != SCSI_STATUS_CHECK_CONDITION + || task->sense.key != SCSI_SENSE_NOT_READY + || (task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_OPEN + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_CLOSED)) { + logging(LOG_NORMAL, "[FAILED] READ10 Should have failed " + "with NOT_READY/MEDIUM_NOT_PRESENT* But failed " + "with %s", iscsi_get_error(iscsi)); + scsi_free_scsi_task(task); + return -1; + } + + if (data != NULL) { + memcpy(data, task->datain.data, task->datain.size); + } + + scsi_free_scsi_task(task); + logging(LOG_VERBOSE, "[OK] READ10 returned MEDIUM_NOT_PRESENT."); + return 0; +} + int read12(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int rdprotect, @@ -1795,6 +2102,54 @@ read12_lbaoutofrange(struct iscsi_context *iscsi, int lun, uint32_t lba, return 0; } +int +read12_nomedium(struct iscsi_context *iscsi, int lun, uint32_t lba, + uint32_t datalen, int blocksize, int rdprotect, + int dpo, int fua, int fua_nv, int group, + unsigned char *data) +{ + struct scsi_task *task; + + logging(LOG_VERBOSE, "Send READ12 (Expecting MEDIUM_NOT_PRESENT) " + "LBA:%d blocks:%d rdprotect:%d " + "dpo:%d fua:%d fua_nv:%d group:%d", + lba, datalen / blocksize, rdprotect, + dpo, fua, fua_nv, group); + + task = iscsi_read12_sync(iscsi, lun, lba, datalen, blocksize, + rdprotect, dpo, fua, fua_nv, group); + if (task == NULL) { + logging(LOG_NORMAL, "[FAILED] Failed to send READ12 command: %s", + iscsi_get_error(iscsi)); + return -1; + } + if (task->status == SCSI_STATUS_GOOD) { + logging(LOG_NORMAL, "[FAILED] READ12 successful but should " + "have failed with NOT_READY/MEDIUM_NOT_PRESENT*"); + scsi_free_scsi_task(task); + return -1; + } + if (task->status != SCSI_STATUS_CHECK_CONDITION + || task->sense.key != SCSI_SENSE_NOT_READY + || (task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_OPEN + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_CLOSED)) { + logging(LOG_NORMAL, "[FAILED] READ12 Should have failed " + "with NOT_READY/MEDIUM_NOT_PRESENT* But failed " + "with %s", iscsi_get_error(iscsi)); + scsi_free_scsi_task(task); + return -1; + } + + if (data != NULL) { + memcpy(data, task->datain.data, task->datain.size); + } + + scsi_free_scsi_task(task); + logging(LOG_VERBOSE, "[OK] READ12 returned MEDIUM_NOT_PRESENT*."); + return 0; +} + int read16(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int blocksize, int rdprotect, @@ -1924,6 +2279,54 @@ read16_lbaoutofrange(struct iscsi_context *iscsi, int lun, uint64_t lba, return 0; } +int +read16_nomedium(struct iscsi_context *iscsi, int lun, uint64_t lba, + uint32_t datalen, int blocksize, int rdprotect, + int dpo, int fua, int fua_nv, int group, + unsigned char *data) +{ + struct scsi_task *task; + + logging(LOG_VERBOSE, "Send READ16 (Expecting MEDIUM_NOT_PRESENT) " + "LBA:%" PRId64 " blocks:%d rdprotect:%d " + "dpo:%d fua:%d fua_nv:%d group:%d", + lba, datalen / blocksize, rdprotect, + dpo, fua, fua_nv, group); + + task = iscsi_read16_sync(iscsi, lun, lba, datalen, blocksize, + rdprotect, dpo, fua, fua_nv, group); + if (task == NULL) { + logging(LOG_NORMAL, "[FAILED] Failed to send READ16 command: %s", + iscsi_get_error(iscsi)); + return -1; + } + if (task->status == SCSI_STATUS_GOOD) { + logging(LOG_NORMAL, "[FAILED] READ16 successful but should " + "have failed with NOT_READY/MEDIUM_NOT_PRESENT*"); + scsi_free_scsi_task(task); + return -1; + } + if (task->status != SCSI_STATUS_CHECK_CONDITION + || task->sense.key != SCSI_SENSE_NOT_READY + || (task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_OPEN + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_CLOSED)) { + logging(LOG_NORMAL, "[FAILED] READ16 Should have failed " + "with NOT_READY/MEDIUM_NOT_PRESENT* But failed " + "with %s", iscsi_get_error(iscsi)); + scsi_free_scsi_task(task); + return -1; + } + + if (data != NULL) { + memcpy(data, task->datain.data, task->datain.size); + } + + scsi_free_scsi_task(task); + logging(LOG_VERBOSE, "[OK] READ16 returned MEDIUM_NOT_PRESENT."); + return 0; +} + int readcapacity10(struct iscsi_context *iscsi, int lun, uint32_t lba, int pmi) { @@ -1950,6 +2353,43 @@ readcapacity10(struct iscsi_context *iscsi, int lun, uint32_t lba, int pmi) return 0; } +int +readcapacity10_nomedium(struct iscsi_context *iscsi, int lun, uint32_t lba, int pmi) +{ + struct scsi_task *task; + + logging(LOG_VERBOSE, "Send READCAPACITY10 (Expecting MEDIUM_NOT_PRESENT) " + "LBA:%d pmi:%d", + lba, pmi); + + task = iscsi_readcapacity10_sync(iscsi, lun, lba, pmi); + if (task == NULL) { + logging(LOG_NORMAL, "[FAILED] Failed to send READCAPACITY10 command: %s", + iscsi_get_error(iscsi)); + return -1; + } + if (task->status == SCSI_STATUS_GOOD) { + logging(LOG_NORMAL, "[FAILED] READCAPACITY10 command successful. But should have failed with NOT_READY/MEDIUM_NOT_PRESENT*"); + scsi_free_scsi_task(task); + return -1; + } + if (task->status != SCSI_STATUS_CHECK_CONDITION + || task->sense.key != SCSI_SENSE_NOT_READY + || (task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_OPEN + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_CLOSED)) { + logging(LOG_NORMAL, "[FAILED] READCAPACITY10 Should have failed " + "with NOT_READY/MEDIUM_NOT_PRESENT* But failed " + "with %s", iscsi_get_error(iscsi)); + scsi_free_scsi_task(task); + return -1; + } + + scsi_free_scsi_task(task); + logging(LOG_VERBOSE, "[OK] READCAPACITY10 returned MEDIUM_NOT_PRESENT."); + return 0; +} + int readcapacity16(struct iscsi_context *iscsi, int lun, int alloc_len) { @@ -1983,6 +2423,49 @@ readcapacity16(struct iscsi_context *iscsi, int lun, int alloc_len) return 0; } +int +readcapacity16_nomedium(struct iscsi_context *iscsi, int lun, int alloc_len) +{ + struct scsi_task *task; + + logging(LOG_VERBOSE, "Send READCAPACITY16 (Expecting MEDIUM_NOT_PRESENT) " + "alloc_len:%d", alloc_len); + + task = scsi_cdb_serviceactionin16(SCSI_READCAPACITY16, alloc_len); + if (task == NULL) { + logging(LOG_NORMAL, "[FAILED] Failed to send READCAPACITY16 command: %s", + iscsi_get_error(iscsi)); + return -1; + } + task = iscsi_scsi_command_sync(iscsi, lun, task, NULL); + if (task == NULL) { + logging(LOG_NORMAL, "[FAILED] Failed to send READCAPACITY16 command: %s", + iscsi_get_error(iscsi)); + return -1; + } + + if (task->status == SCSI_STATUS_GOOD) { + logging(LOG_NORMAL, "[FAILED] READCAPACITY16 command successful. But should have failed with NOT_READY/MEDIUM_NOT_PRESENT*"); + scsi_free_scsi_task(task); + return -1; + } + if (task->status != SCSI_STATUS_CHECK_CONDITION + || task->sense.key != SCSI_SENSE_NOT_READY + || (task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_OPEN + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_CLOSED)) { + logging(LOG_NORMAL, "[FAILED] READCAPACITY16 Should have failed " + "with NOT_READY/MEDIUM_NOT_PRESENT* But failed " + "with %s", iscsi_get_error(iscsi)); + scsi_free_scsi_task(task); + return -1; + } + + scsi_free_scsi_task(task); + logging(LOG_VERBOSE, "[OK] READCAPACITY16 returned MEDIUM_NOT_PRESENT."); + return 0; +} + int unmap(struct iscsi_context *iscsi, int lun, int anchor, struct unmap_list *list, int list_len) { @@ -2018,7 +2501,9 @@ unmap_writeprotected(struct iscsi_context *iscsi, int lun, int anchor, struct un { struct scsi_task *task; - logging(LOG_VERBOSE, "Send UNMAP (Expecting WRITE_PROTECTED) list_len:%d anchor:%d", list_len, anchor); + logging(LOG_VERBOSE, "Send UNMAP (Expecting WRITE_PROTECTED) " + "list_len:%d anchor:%d", list_len, anchor); + task = iscsi_unmap_sync(iscsi, lun, anchor, 0, list, list_len); if (task == NULL) { logging(LOG_NORMAL, "[FAILED] Failed to send UNMAP command: %s", @@ -2054,6 +2539,50 @@ unmap_writeprotected(struct iscsi_context *iscsi, int lun, int anchor, struct un return 0; } +int +unmap_nomedium(struct iscsi_context *iscsi, int lun, int anchor, struct unmap_list *list, int list_len) +{ + struct scsi_task *task; + + logging(LOG_VERBOSE, "Send UNMAP (Expecting MEDIUM_NOT_PRESENT) " + "list_len:%d anchor:%d", list_len, anchor); + + task = iscsi_unmap_sync(iscsi, lun, anchor, 0, list, list_len); + if (task == NULL) { + logging(LOG_NORMAL, "[FAILED] Failed to send UNMAP command: %s", + iscsi_get_error(iscsi)); + return -1; + } + if (task->status == SCSI_STATUS_CHECK_CONDITION + && task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST + && task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE) { + logging(LOG_NORMAL, "[SKIPPED] UNMAP is not implemented on target"); + scsi_free_scsi_task(task); + return -2; + } + if (task->status == SCSI_STATUS_GOOD) { + logging(LOG_NORMAL, "[FAILED] UNMAP successful but should " + "have failed with NOT_READY/MEDIUM_NOT_PRESENT*"); + scsi_free_scsi_task(task); + return -1; + } + if (task->status != SCSI_STATUS_CHECK_CONDITION + || task->sense.key != SCSI_SENSE_NOT_READY + || (task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_OPEN + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_CLOSED)) { + logging(LOG_NORMAL, "[FAILED] UNMAP Should have failed " + "with NOT_READY/MEDIUM_NOT_PRESENT* But failed " + "with %s", iscsi_get_error(iscsi)); + scsi_free_scsi_task(task); + return -1; + } + + scsi_free_scsi_task(task); + logging(LOG_VERBOSE, "[OK] UNMAP returned MEDIUM_NOT_PRESENT."); + return 0; +} + int verify10(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int vprotect, int dpo, int bytchk, unsigned char *data) { @@ -2089,7 +2618,10 @@ verify10_nomedium(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t d { struct scsi_task *task; - logging(LOG_VERBOSE, "Send VERIFY10 LBA:%d blocks:%d vprotect:%d dpo:%d bytchk:%d (expecting NOT_READY/MEDIUM_NOT_PRESENT)", lba, datalen / blocksize, vprotect, dpo, bytchk); + logging(LOG_VERBOSE, "Send VERIFY10 (Expecting MEDIUM_NOT_PRESENT) " + "LBA:%d blocks:%d vprotect:%d dpo:%d bytchk:%d", + lba, datalen / blocksize, vprotect, dpo, bytchk); + task = iscsi_verify10_sync(iscsi, lun, data, datalen, lba, vprotect, dpo, bytchk, blocksize); if (task == NULL) { logging(LOG_NORMAL, "[FAILED] Failed to send VERIFY10 command: %s", @@ -2119,7 +2651,7 @@ verify10_nomedium(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t d } scsi_free_scsi_task(task); - logging(LOG_VERBOSE, "[OK] VERIFY10 returned NOT_READY/MEDIUM_NOT_PRESENT."); + logging(LOG_VERBOSE, "[OK] VERIFY10 returned MEDIUM_NOT_PRESENT."); return 0; } @@ -2128,7 +2660,10 @@ verify10_miscompare(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t { struct scsi_task *task; - logging(LOG_VERBOSE, "Send VERIFY10 LBA:%d blocks:%d vprotect:%d dpo:%d bytchk:%d (expecting MISCOMPARE)", lba, datalen / blocksize, vprotect, dpo, bytchk); + logging(LOG_VERBOSE, "Send VERIFY10 (Expecting MISCOMPARE) " + "LBA:%d blocks:%d vprotect:%d dpo:%d bytchk:%d", + lba, datalen / blocksize, vprotect, dpo, bytchk); + task = iscsi_verify10_sync(iscsi, lun, data, datalen, lba, vprotect, dpo, bytchk, blocksize); if (task == NULL) { logging(LOG_NORMAL, "[FAILED] Failed to send VERIFY10 command: %s", @@ -2163,7 +2698,10 @@ verify10_lbaoutofrange(struct iscsi_context *iscsi, int lun, uint32_t lba, uint3 { struct scsi_task *task; - logging(LOG_VERBOSE, "Send VERIFY10 LBA:%d blocks:%d vprotect:%d dpo:%d bytchk:%d (expecting LBA_OUT_OF_RANGE)", lba, datalen / blocksize, vprotect, dpo, bytchk); + logging(LOG_VERBOSE, "Send VERIFY10 (Expecting LBA_OUT_OF_RANGE) " + "LBA:%d blocks:%d vprotect:%d dpo:%d bytchk:%d", + lba, datalen / blocksize, vprotect, dpo, bytchk); + task = iscsi_verify10_sync(iscsi, lun, data, datalen, lba, vprotect, dpo, bytchk, blocksize); if (task == NULL) { logging(LOG_NORMAL, "[FAILED] Failed to send VERIFY10 command: %s", @@ -2200,7 +2738,10 @@ verify10_invalidfieldincdb(struct iscsi_context *iscsi, int lun, uint32_t lba, u { struct scsi_task *task; - logging(LOG_VERBOSE, "Send VERIFY10 LBA:%d blocks:%d vprotect:%d dpo:%d bytchk:%d (expecting INVALID_FIELD_IN_CDB)", lba, datalen / blocksize, vprotect, dpo, bytchk); + logging(LOG_VERBOSE, "Send VERIFY10 (Expecting INVALID_FIELD_IN_CDB) " + "LBA:%d blocks:%d vprotect:%d dpo:%d bytchk:%d", + lba, datalen / blocksize, vprotect, dpo, bytchk); + task = iscsi_verify10_sync(iscsi, lun, data, datalen, lba, vprotect, dpo, bytchk, blocksize); if (task == NULL) { logging(LOG_NORMAL, "[FAILED] Failed to send VERIFY10 command: %s", @@ -2267,7 +2808,10 @@ verify12_nomedium(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t d { struct scsi_task *task; - logging(LOG_VERBOSE, "Send VERIFY12 LBA:%d blocks:%d vprotect:%d dpo:%d bytchk:%d (expecting NOT_READY/MEDIUM_NOT_PRESENT)", lba, datalen / blocksize, vprotect, dpo, bytchk); + logging(LOG_VERBOSE, "Send VERIFY12 (Expecting MEDIUM_NOT_PRESENT) " + "LBA:%d blocks:%d vprotect:%d dpo:%d bytchk:%d", + lba, datalen / blocksize, vprotect, dpo, bytchk); + task = iscsi_verify12_sync(iscsi, lun, data, datalen, lba, vprotect, dpo, bytchk, blocksize); if (task == NULL) { logging(LOG_NORMAL, "[FAILED] Failed to send VERIFY12 command: %s", @@ -2297,7 +2841,7 @@ verify12_nomedium(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t d } scsi_free_scsi_task(task); - logging(LOG_VERBOSE, "[OK] VERIFY12 returned NOT_READY/MEDIUM_NOT_PRESENT."); + logging(LOG_VERBOSE, "[OK] VERIFY12 returned MEDIUM_NOT_PRESENT."); return 0; } @@ -2306,7 +2850,10 @@ verify12_miscompare(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t { struct scsi_task *task; - logging(LOG_VERBOSE, "Send VERIFY12 LBA:%d blocks:%d vprotect:%d dpo:%d bytchk:%d (expecting MISCOMPARE)", lba, datalen / blocksize, vprotect, dpo, bytchk); + logging(LOG_VERBOSE, "Send VERIFY12 (expecting MISCOMPARE) " + "LBA:%d blocks:%d vprotect:%d dpo:%d bytchk:%d", + lba, datalen / blocksize, vprotect, dpo, bytchk); + task = iscsi_verify12_sync(iscsi, lun, data, datalen, lba, vprotect, dpo, bytchk, blocksize); if (task == NULL) { logging(LOG_NORMAL, "[FAILED] Failed to send VERIFY12 command: %s", @@ -2341,7 +2888,10 @@ verify12_lbaoutofrange(struct iscsi_context *iscsi, int lun, uint32_t lba, uint3 { struct scsi_task *task; - logging(LOG_VERBOSE, "Send VERIFY12 LBA:%d blocks:%d vprotect:%d dpo:%d bytchk:%d (expecting LBA_OUT_OF_RANGE)", lba, datalen / blocksize, vprotect, dpo, bytchk); + logging(LOG_VERBOSE, "Send VERIFY12 (Expecting LBA_OUT_OF_RANGE) " + "LBA:%d blocks:%d vprotect:%d dpo:%d bytchk:%d", + lba, datalen / blocksize, vprotect, dpo, bytchk); + task = iscsi_verify12_sync(iscsi, lun, data, datalen, lba, vprotect, dpo, bytchk, blocksize); if (task == NULL) { logging(LOG_NORMAL, "[FAILED] Failed to send VERIFY12 command: %s", @@ -2378,7 +2928,10 @@ verify12_invalidfieldincdb(struct iscsi_context *iscsi, int lun, uint32_t lba, u { struct scsi_task *task; - logging(LOG_VERBOSE, "Send VERIFY12 LBA:%d blocks:%d vprotect:%d dpo:%d bytchk:%d (expecting INVALID_FIELD_IN_CDB)", lba, datalen / blocksize, vprotect, dpo, bytchk); + logging(LOG_VERBOSE, "Send VERIFY12 (Expecting INVALID_FIELD_IN_CDB) " + "LBA:%d blocks:%d vprotect:%d dpo:%d bytchk:%d", + lba, datalen / blocksize, vprotect, dpo, bytchk); + task = iscsi_verify12_sync(iscsi, lun, data, datalen, lba, vprotect, dpo, bytchk, blocksize); if (task == NULL) { logging(LOG_NORMAL, "[FAILED] Failed to send VERIFY12 command: %s", @@ -2445,7 +2998,10 @@ verify16_nomedium(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t d { struct scsi_task *task; - logging(LOG_VERBOSE, "Send VERIFY16 LBA:%" PRIu64 " blocks:%d vprotect:%d dpo:%d bytchk:%d (expecting NOT_READY/MEDIUM_NOT_PRESENT)", lba, datalen / blocksize, vprotect, dpo, bytchk); + logging(LOG_VERBOSE, "Send VERIFY16 (Expecting MEDIUM_NOT_PRESENT) " + "LBA:%" PRIu64 " blocks:%d vprotect:%d dpo:%d bytchk:%d", + lba, datalen / blocksize, vprotect, dpo, bytchk); + task = iscsi_verify16_sync(iscsi, lun, data, datalen, lba, vprotect, dpo, bytchk, blocksize); if (task == NULL) { logging(LOG_NORMAL, "[FAILED] Failed to send VERIFY16 command: %s", @@ -2475,7 +3031,7 @@ verify16_nomedium(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t d } scsi_free_scsi_task(task); - logging(LOG_VERBOSE, "[OK] VERIFY16 returned NOT_READY/MEDIUM_NOT_PRESENT."); + logging(LOG_VERBOSE, "[OK] VERIFY16 returned NOT_MEDIUM_NOT_PRESENT."); return 0; } @@ -2484,7 +3040,10 @@ verify16_miscompare(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t { struct scsi_task *task; - logging(LOG_VERBOSE, "Send VERIFY16 LBA:%" PRIu64 " blocks:%d vprotect:%d dpo:%d bytchk:%d (expecting MISCOMPARE)", lba, datalen / blocksize, vprotect, dpo, bytchk); + logging(LOG_VERBOSE, "Send VERIFY16 (Expecting MISCOMPARE) " + "LBA:%" PRIu64 " blocks:%d vprotect:%d dpo:%d bytchk:%d", + lba, datalen / blocksize, vprotect, dpo, bytchk); + task = iscsi_verify16_sync(iscsi, lun, data, datalen, lba, vprotect, dpo, bytchk, blocksize); if (task == NULL) { logging(LOG_NORMAL, "[FAILED] Failed to send VERIFY16 command: %s", @@ -2519,7 +3078,10 @@ verify16_lbaoutofrange(struct iscsi_context *iscsi, int lun, uint64_t lba, uint3 { struct scsi_task *task; - logging(LOG_VERBOSE, "Send VERIFY16 LBA:%" PRIu64 " blocks:%d vprotect:%d dpo:%d bytchk:%d (expecting LBA_OUT_OF_RANGE)", lba, datalen / blocksize, vprotect, dpo, bytchk); + logging(LOG_VERBOSE, "Send VERIFY16 (Expecting LBA_OUT_OF_RANGE) " + "LBA:%" PRIu64 " blocks:%d vprotect:%d dpo:%d bytchk:%d", + lba, datalen / blocksize, vprotect, dpo, bytchk); + task = iscsi_verify16_sync(iscsi, lun, data, datalen, lba, vprotect, dpo, bytchk, blocksize); if (task == NULL) { logging(LOG_NORMAL, "[FAILED] Failed to send VERIFY16 command: %s", @@ -2556,7 +3118,10 @@ verify16_invalidfieldincdb(struct iscsi_context *iscsi, int lun, uint64_t lba, u { struct scsi_task *task; - logging(LOG_VERBOSE, "Send VERIFY16 LBA:%" PRIu64 " blocks:%d vprotect:%d dpo:%d bytchk:%d (expecting INVALID_FIELD_IN_CDB)", lba, datalen / blocksize, vprotect, dpo, bytchk); + logging(LOG_VERBOSE, "Send VERIFY16 (Expecting INVALID_FIELD_IN_CDB) " + "LBA:%" PRIu64 " blocks:%d vprotect:%d dpo:%d bytchk:%d", + lba, datalen / blocksize, vprotect, dpo, bytchk); + task = iscsi_verify16_sync(iscsi, lun, data, datalen, lba, vprotect, dpo, bytchk, blocksize); if (task == NULL) { logging(LOG_NORMAL, "[FAILED] Failed to send VERIFY16 command: %s", @@ -2769,6 +3334,55 @@ write10_writeprotected(struct iscsi_context *iscsi, int lun, uint32_t lba, return 0; } +int +write10_nomedium(struct iscsi_context *iscsi, int lun, uint32_t lba, + uint32_t datalen, int blocksize, int wrprotect, + int dpo, int fua, int fua_nv, int group, + unsigned char *data) +{ + struct scsi_task *task; + + logging(LOG_VERBOSE, "Send WRITE10 (Expecting MEDIUM_NOT_PRESENT) " + "LBA:%d blocks:%d wrprotect:%d " + "dpo:%d fua:%d fua_nv:%d group:%d", + lba, datalen / blocksize, wrprotect, + dpo, fua, fua_nv, group); + + if (!data_loss) { + printf("--dataloss flag is not set in. Skipping write\n"); + return -1; + } + + task = iscsi_write10_sync(iscsi, lun, lba, data, datalen, blocksize, + wrprotect, dpo, fua, fua_nv, group); + if (task == NULL) { + logging(LOG_NORMAL, "[FAILED] Failed to send WRITE10 command: %s", + iscsi_get_error(iscsi)); + return -1; + } + if (task->status == SCSI_STATUS_GOOD) { + logging(LOG_NORMAL, "[FAILED] WRITE10 successful but should " + "have failed with NOT_READY/MEDIUM_NOT_PRESENT*"); + scsi_free_scsi_task(task); + return -1; + } + if (task->status != SCSI_STATUS_CHECK_CONDITION + || task->sense.key != SCSI_SENSE_NOT_READY + || (task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_OPEN + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_CLOSED)) { + logging(LOG_NORMAL, "[FAILED] WRITE10 Should have failed " + "with NOT_READY/MEDIUM_NOT_PRESENT* But failed " + "with %s", iscsi_get_error(iscsi)); + scsi_free_scsi_task(task); + return -1; + } + + scsi_free_scsi_task(task); + logging(LOG_VERBOSE, "[OK] WRITE10 returned MEDIUM_NOT_PRESENT."); + return 0; +} + int write12(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int wrprotect, @@ -2950,6 +3564,55 @@ write12_writeprotected(struct iscsi_context *iscsi, int lun, uint32_t lba, return 0; } +int +write12_nomedium(struct iscsi_context *iscsi, int lun, uint32_t lba, + uint32_t datalen, int blocksize, int wrprotect, + int dpo, int fua, int fua_nv, int group, + unsigned char *data) +{ + struct scsi_task *task; + + logging(LOG_VERBOSE, "Send WRITE12 (Expecting MEDIUM_NOT_PRESENT) " + "LBA:%d blocks:%d wrprotect:%d " + "dpo:%d fua:%d fua_nv:%d group:%d", + lba, datalen / blocksize, wrprotect, + dpo, fua, fua_nv, group); + + if (!data_loss) { + printf("--dataloss flag is not set in. Skipping write\n"); + return -1; + } + + task = iscsi_write12_sync(iscsi, lun, lba, data, datalen, blocksize, + wrprotect, dpo, fua, fua_nv, group); + if (task == NULL) { + logging(LOG_NORMAL, "[FAILED] Failed to send WRITE12 command: %s", + iscsi_get_error(iscsi)); + return -1; + } + if (task->status == SCSI_STATUS_GOOD) { + logging(LOG_NORMAL, "[FAILED] WRITE12 successful but should " + "have failed with NOT_READY/MEDIUM_NOT_PRESENT*"); + scsi_free_scsi_task(task); + return -1; + } + if (task->status != SCSI_STATUS_CHECK_CONDITION + || task->sense.key != SCSI_SENSE_NOT_READY + || (task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_OPEN + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_CLOSED)) { + logging(LOG_NORMAL, "[FAILED] WRITE12 Should have failed " + "with NOT_READY/MEDIUM_NOT_PRESENT* But failed " + "with %s", iscsi_get_error(iscsi)); + scsi_free_scsi_task(task); + return -1; + } + + scsi_free_scsi_task(task); + logging(LOG_VERBOSE, "[OK] WRITE12 returned MEDIUM_NOT_PRESENT."); + return 0; +} + int write16(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int blocksize, int wrprotect, @@ -3131,6 +3794,55 @@ write16_writeprotected(struct iscsi_context *iscsi, int lun, uint64_t lba, return 0; } +int +write16_nomedium(struct iscsi_context *iscsi, int lun, uint64_t lba, + uint32_t datalen, int blocksize, int wrprotect, + int dpo, int fua, int fua_nv, int group, + unsigned char *data) +{ + struct scsi_task *task; + + logging(LOG_VERBOSE, "Send WRITE16 (Expecting MEDIUM_NOT_PRESENT) " + "LBA:%" PRIu64 " blocks:%d wrprotect:%d " + "dpo:%d fua:%d fua_nv:%d group:%d", + lba, datalen / blocksize, wrprotect, + dpo, fua, fua_nv, group); + + if (!data_loss) { + printf("--dataloss flag is not set in. Skipping write\n"); + return -1; + } + + task = iscsi_write16_sync(iscsi, lun, lba, data, datalen, blocksize, + wrprotect, dpo, fua, fua_nv, group); + if (task == NULL) { + logging(LOG_NORMAL, "[FAILED] Failed to send WRITE16 command: %s", + iscsi_get_error(iscsi)); + return -1; + } + if (task->status == SCSI_STATUS_GOOD) { + logging(LOG_NORMAL, "[FAILED] WRITE16 successful but should " + "have failed with NOT_READY/MEDIUM_NOT_PRESENT*"); + scsi_free_scsi_task(task); + return -1; + } + if (task->status != SCSI_STATUS_CHECK_CONDITION + || task->sense.key != SCSI_SENSE_NOT_READY + || (task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_OPEN + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_CLOSED)) { + logging(LOG_NORMAL, "[FAILED] WRITE16 Should have failed " + "with NOT_READY/MEDIUM_NOT_PRESENT* But failed " + "with %s", iscsi_get_error(iscsi)); + scsi_free_scsi_task(task); + return -1; + } + + scsi_free_scsi_task(task); + logging(LOG_VERBOSE, "[OK] WRITE16 returned MEDIUM_NOT_PRESENT."); + return 0; +} + int writesame10(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int num, int anchor, int unmap_flag, int wrprotect, int group, unsigned char *data) { @@ -3178,9 +3890,10 @@ writesame10_lbaoutofrange(struct iscsi_context *iscsi, int lun, uint32_t lba, ui { struct scsi_task *task; - logging(LOG_VERBOSE, "Send WRITESAME10 (Expecting LBA_OUT_OF_RANGE) LBA:%d blocks:%d " - "wrprotect:%d anchor:%d unmap:%d group:%d", - lba, num, wrprotect, + logging(LOG_VERBOSE, "Send WRITESAME10 (Expecting LBA_OUT_OF_RANGE) " + "LBA:%d blocks:%d " + "wrprotect:%d anchor:%d unmap:%d group:%d", + lba, num, wrprotect, anchor, unmap_flag, group); if (!data_loss) { @@ -3229,9 +3942,10 @@ writesame10_invalidfieldincdb(struct iscsi_context *iscsi, int lun, uint32_t lba { struct scsi_task *task; - logging(LOG_VERBOSE, "Send WRITESAME10 (Expecting INVALID_FIELD_IN_CDB) LBA:%d blocks:%d " - "wrprotect:%d anchor:%d unmap:%d group:%d", - lba, num, wrprotect, + logging(LOG_VERBOSE, "Send WRITESAME10 (Expecting INVALID_FIELD_IN_CDB) " + "LBA:%d blocks:%d " + "wrprotect:%d anchor:%d unmap:%d group:%d", + lba, num, wrprotect, anchor, unmap_flag, group); if (!data_loss) { @@ -3281,9 +3995,10 @@ writesame10_writeprotected(struct iscsi_context *iscsi, int lun, uint32_t lba, u { struct scsi_task *task; - logging(LOG_VERBOSE, "Send WRITESAME10 (Expecting WRITE_PROTECTED) LBA:%d blocks:%d " - "wrprotect:%d anchor:%d unmap:%d group:%d", - lba, num, wrprotect, + logging(LOG_VERBOSE, "Send WRITESAME10 (Expecting WRITE_PROTECTED) " + "LBA:%d blocks:%d " + "wrprotect:%d anchor:%d unmap:%d group:%d", + lba, num, wrprotect, anchor, unmap_flag, group); if (!data_loss) { @@ -3327,6 +4042,59 @@ writesame10_writeprotected(struct iscsi_context *iscsi, int lun, uint32_t lba, u return 0; } +int +writesame10_nomedium(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int num, int anchor, int unmap_flag, int wrprotect, int group, unsigned char *data) +{ + struct scsi_task *task; + + logging(LOG_VERBOSE, "Send WRITESAME10 (Expecting MEDIUM_NOT_PRESENT) " + "LBA:%d blocks:%d " + "wrprotect:%d anchor:%d unmap:%d group:%d", + lba, num, wrprotect, + anchor, unmap_flag, group); + + if (!data_loss) { + printf("--dataloss flag is not set in. Skipping write\n"); + return -1; + } + + task = iscsi_writesame10_sync(iscsi, lun, lba, + data, datalen, num, + anchor, unmap_flag, wrprotect, group); + if (task == NULL) { + logging(LOG_NORMAL, "[FAILED] Failed to send WRITESAME10 command: %s", + iscsi_get_error(iscsi)); + return -1; + } + if (task->status == SCSI_STATUS_CHECK_CONDITION + && task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST + && task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE) { + logging(LOG_NORMAL, "[SKIPPED] WRITESAME10 is not implemented on target"); + scsi_free_scsi_task(task); + return -2; + } + if (task->status == SCSI_STATUS_GOOD) { + logging(LOG_NORMAL, "[FAILED] WRITESAME10 command successful. But should have failed with NOT_READY/MEDIUM_NOT_PRESENT*"); + scsi_free_scsi_task(task); + return -1; + } + if (task->status != SCSI_STATUS_CHECK_CONDITION + || task->sense.key != SCSI_SENSE_NOT_READY + || (task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_OPEN + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_CLOSED)) { + logging(LOG_NORMAL, "[FAILED] WRITESAME10 Should have failed " + "with NOT_READY/MEDIUM_NOT_PRESENT* But failed " + "with %s", iscsi_get_error(iscsi)); + scsi_free_scsi_task(task); + return -1; + } + + scsi_free_scsi_task(task); + logging(LOG_VERBOSE, "[OK] WRITESAME10 returned MEDIUM_NOT_PRESENT."); + return 0; +} + int writesame16(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int num, int anchor, int unmap_flag, int wrprotect, int group, unsigned char *data) { @@ -3374,9 +4142,10 @@ writesame16_lbaoutofrange(struct iscsi_context *iscsi, int lun, uint64_t lba, ui { struct scsi_task *task; - logging(LOG_VERBOSE, "Send WRITESAME16 (Expecting LBA_OUT_OF_RANGE) LBA:%" PRIu64 " blocks:%d " - "wrprotect:%d anchor:%d unmap:%d group:%d", - lba, num, wrprotect, + logging(LOG_VERBOSE, "Send WRITESAME16 (Expecting LBA_OUT_OF_RANGE) " + "LBA:%" PRIu64 " blocks:%d " + "wrprotect:%d anchor:%d unmap:%d group:%d", + lba, num, wrprotect, anchor, unmap_flag, group); if (!data_loss) { @@ -3425,9 +4194,10 @@ writesame16_invalidfieldincdb(struct iscsi_context *iscsi, int lun, uint64_t lba { struct scsi_task *task; - logging(LOG_VERBOSE, "Send WRITESAME16 (Expecting INVALID_FIELD_IN_CDB) LBA:%" PRIu64 " blocks:%d " - "wrprotect:%d anchor:%d unmap:%d group:%d", - lba, num, wrprotect, + logging(LOG_VERBOSE, "Send WRITESAME16 (Expecting INVALID_FIELD_IN_CDB) " + "LBA:%" PRIu64 " blocks:%d " + "wrprotect:%d anchor:%d unmap:%d group:%d", + lba, num, wrprotect, anchor, unmap_flag, group); if (!data_loss) { @@ -3524,6 +4294,59 @@ writesame16_writeprotected(struct iscsi_context *iscsi, int lun, uint64_t lba, u return 0; } +int +writesame16_nomedium(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int num, int anchor, int unmap_flag, int wrprotect, int group, unsigned char *data) +{ + struct scsi_task *task; + + logging(LOG_VERBOSE, "Send WRITESAME16 (Expecting MEDIUM_NOT_PRESENT) " + "LBA:%" PRIu64 " blocks:%d " + "wrprotect:%d anchor:%d unmap:%d group:%d", + lba, num, wrprotect, + anchor, unmap_flag, group); + + if (!data_loss) { + printf("--dataloss flag is not set in. Skipping write\n"); + return -1; + } + + task = iscsi_writesame16_sync(iscsi, lun, lba, + data, datalen, num, + anchor, unmap_flag, wrprotect, group); + if (task == NULL) { + logging(LOG_NORMAL, "[FAILED] Failed to send WRITESAME16 command: %s", + iscsi_get_error(iscsi)); + return -1; + } + if (task->status == SCSI_STATUS_CHECK_CONDITION + && task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST + && task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE) { + logging(LOG_NORMAL, "[SKIPPED] WRITESAME16 is not implemented on target"); + scsi_free_scsi_task(task); + return -2; + } + if (task->status == SCSI_STATUS_GOOD) { + logging(LOG_NORMAL, "[FAILED] WRITESAME16 command successful. But should have failed with NOT_READY/MEDIUM_NOT_PRESENT*"); + scsi_free_scsi_task(task); + return -1; + } + if (task->status != SCSI_STATUS_CHECK_CONDITION + || task->sense.key != SCSI_SENSE_NOT_READY + || (task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_OPEN + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_CLOSED)) { + logging(LOG_NORMAL, "[FAILED] WRITESAME16 Should have failed " + "with NOT_READY/MEDIUM_NOT_PRESENT* But failed " + "with %s", iscsi_get_error(iscsi)); + scsi_free_scsi_task(task); + return -1; + } + + scsi_free_scsi_task(task); + logging(LOG_VERBOSE, "[OK] WRITESAME16 returned MEDIUM_NOT_PRESENT."); + return 0; +} + int writeverify10(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int wrprotect, @@ -3705,6 +4528,55 @@ writeverify10_writeprotected(struct iscsi_context *iscsi, int lun, uint32_t lba, return 0; } +int +writeverify10_nomedium(struct iscsi_context *iscsi, int lun, uint32_t lba, + uint32_t datalen, int blocksize, int wrprotect, + int dpo, int bytchk, int group, + unsigned char *data) +{ + struct scsi_task *task; + + logging(LOG_VERBOSE, "Send WRITEVERIFY10 (Expecting MEDIUM_NOT_PRESENT) " + "LBA:%d blocks:%d wrprotect:%d " + "dpo:%d bytchk:%d group:%d", + lba, datalen / blocksize, wrprotect, + dpo, bytchk, group); + + if (!data_loss) { + printf("--dataloss flag is not set in. Skipping write\n"); + return -1; + } + + task = iscsi_writeverify10_sync(iscsi, lun, lba, data, datalen, blocksize, + wrprotect, dpo, bytchk, group); + if (task == NULL) { + logging(LOG_NORMAL, "[FAILED] Failed to send WRITEVERIFY10 command: %s", + iscsi_get_error(iscsi)); + return -1; + } + if (task->status == SCSI_STATUS_GOOD) { + logging(LOG_NORMAL, "[FAILED] WRITEVERIFY10 successful but should " + "have failed with NOT_READY/MEDIUM_NOT_PRESENT*"); + scsi_free_scsi_task(task); + return -1; + } + if (task->status != SCSI_STATUS_CHECK_CONDITION + || task->sense.key != SCSI_SENSE_NOT_READY + || (task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_OPEN + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_CLOSED)) { + logging(LOG_NORMAL, "[FAILED] WRITEVERIFY10 Should have failed " + "with NOT_READY/MEDIUM_NOT_PRESENT* But failed " + "with %s", iscsi_get_error(iscsi)); + scsi_free_scsi_task(task); + return -1; + } + + scsi_free_scsi_task(task); + logging(LOG_VERBOSE, "[OK] WRITEVERIFY10 returned MEDIUM_NOT_PRESENT."); + return 0; +} + int writeverify12(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int wrprotect, @@ -3886,6 +4758,55 @@ writeverify12_writeprotected(struct iscsi_context *iscsi, int lun, uint32_t lba, return 0; } +int +writeverify12_nomedium(struct iscsi_context *iscsi, int lun, uint32_t lba, + uint32_t datalen, int blocksize, int wrprotect, + int dpo, int bytchk, int group, + unsigned char *data) +{ + struct scsi_task *task; + + logging(LOG_VERBOSE, "Send WRITEVERIFY12 (Expecting MEDIUM_NOT_PRESENT) " + "LBA:%d blocks:%d wrprotect:%d " + "dpo:%d bytchk:%d group:%d", + lba, datalen / blocksize, wrprotect, + dpo, bytchk, group); + + if (!data_loss) { + printf("--dataloss flag is not set in. Skipping write\n"); + return -1; + } + + task = iscsi_writeverify12_sync(iscsi, lun, lba, data, datalen, blocksize, + wrprotect, dpo, bytchk, group); + if (task == NULL) { + logging(LOG_NORMAL, "[FAILED] Failed to send WRITEVERIFY12 command: %s", + iscsi_get_error(iscsi)); + return -1; + } + if (task->status == SCSI_STATUS_GOOD) { + logging(LOG_NORMAL, "[FAILED] WRITEVERIFY12 successful but should " + "have failed with NOT_READY/MEDIUM_NOT_PRESENT*"); + scsi_free_scsi_task(task); + return -1; + } + if (task->status != SCSI_STATUS_CHECK_CONDITION + || task->sense.key != SCSI_SENSE_NOT_READY + || (task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_OPEN + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_CLOSED)) { + logging(LOG_NORMAL, "[FAILED] WRITEVERIFY12 Should have failed " + "with NOT_READY/MEDIUM_NOT_PRESENT* But failed " + "with %s", iscsi_get_error(iscsi)); + scsi_free_scsi_task(task); + return -1; + } + + scsi_free_scsi_task(task); + logging(LOG_VERBOSE, "[OK] WRITEVERIFY12 returned MEDIUM_NOT_PRESENT."); + return 0; +} + int writeverify16(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int blocksize, int wrprotect, @@ -4067,6 +4988,55 @@ writeverify16_writeprotected(struct iscsi_context *iscsi, int lun, uint64_t lba, return 0; } +int +writeverify16_nomedium(struct iscsi_context *iscsi, int lun, uint64_t lba, + uint32_t datalen, int blocksize, int wrprotect, + int dpo, int bytchk, int group, + unsigned char *data) +{ + struct scsi_task *task; + + logging(LOG_VERBOSE, "Send WRITEVERIFY16 (Expecting MEDIUM_NOT_PRESENT) " + "LBA:%" PRIu64 " blocks:%d wrprotect:%d " + "dpo:%d bytchk:%d group:%d", + lba, datalen / blocksize, wrprotect, + dpo, bytchk, group); + + if (!data_loss) { + printf("--dataloss flag is not set in. Skipping write\n"); + return -1; + } + + task = iscsi_writeverify16_sync(iscsi, lun, lba, data, datalen, blocksize, + wrprotect, dpo, bytchk, group); + if (task == NULL) { + logging(LOG_NORMAL, "[FAILED] Failed to send WRITEVERIFY16 command: %s", + iscsi_get_error(iscsi)); + return -1; + } + if (task->status == SCSI_STATUS_GOOD) { + logging(LOG_NORMAL, "[FAILED] WRITEVERIFY16 successful but should " + "have failed with NOT_READY/MEDIUM_NOT_PRESENT*"); + scsi_free_scsi_task(task); + return -1; + } + if (task->status != SCSI_STATUS_CHECK_CONDITION + || task->sense.key != SCSI_SENSE_NOT_READY + || (task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_OPEN + && task->sense.ascq != SCSI_SENSE_ASCQ_MEDIUM_NOT_PRESENT_TRAY_CLOSED)) { + logging(LOG_NORMAL, "[FAILED] WRITEVERIFY16 Should have failed " + "with NOT_READY/MEDIUM_NOT_PRESENT* But failed " + "with %s", iscsi_get_error(iscsi)); + scsi_free_scsi_task(task); + return -1; + } + + scsi_free_scsi_task(task); + logging(LOG_VERBOSE, "[OK] WRITEVERIFY16 returned MEDIUM_NOT_PRESENT."); + return 0; +} + int inquiry(struct iscsi_context *iscsi, int lun, int evpd, int page_code, int maxsize) { diff --git a/test-tool/iscsi-support.h b/test-tool/iscsi-support.h index 93afea6..fea3c13 100644 --- a/test-tool/iscsi-support.h +++ b/test-tool/iscsi-support.h @@ -202,6 +202,12 @@ int verify_write_fails(struct iscsi_context *iscsi, int lun, unsigned char *buf) int inquiry(struct iscsi_context *iscsi, int lun, int evpd, int page_code, int maxsize); int get_lba_status(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t len); int get_lba_status_lbaoutofrange(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t len); +int get_lba_status_nomedium(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t len); +int orwrite(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); +int orwrite_invalidfieldincdb(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); +int orwrite_lbaoutofrange(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); +int orwrite_writeprotected(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); +int orwrite_nomedium(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); int prefetch10(struct iscsi_context *iscsi, int lun, uint32_t lba, int num_blocks, int immed, int group); int prefetch10_lbaoutofrange(struct iscsi_context *iscsi, int lun, uint32_t lba, int num_blocks, int immed, int group); int prefetch10_nomedium(struct iscsi_context *iscsi, int lun, uint32_t lba, int num_blocks, int immed, int group); @@ -213,21 +219,31 @@ int read6_lbaoutofrange(struct iscsi_context *iscsi, int lun, uint32_t lba, uint int read10(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); int read10_invalidfieldincdb(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); int read10_lbaoutofrange(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); +int read10_nomedium(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); int read12(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); int read12_invalidfieldincdb(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); int read12_lbaoutofrange(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); +int read12_nomedium(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); int read16(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); int read16_invalidfieldincdb(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); int read16_lbaoutofrange(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); +int read16_nomedium(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); int readcapacity10(struct iscsi_context *iscsi, int lun, uint32_t lba, int pmi); +int readcapacity10_nomedium(struct iscsi_context *iscsi, int lun, uint32_t lba, int pmi); int readcapacity16(struct iscsi_context *iscsi, int lun, int alloc_len); +int readcapacity16_nomedium(struct iscsi_context *iscsi, int lun, int alloc_len); int startstopunit(struct iscsi_context *iscsi, int lun, int immed, int pcm, int pc, int no_flush, int loej, int start); +int synchronizecache10(struct iscsi_context *iscsi, int lun, uint32_t lba, int num_blocks, int sync_nv, int immed); +int synchronizecache10_nomedium(struct iscsi_context *iscsi, int lun, uint32_t lba, int num_blocks, int sync_nv, int immed); +int synchronizecache16(struct iscsi_context *iscsi, int lun, uint64_t lba, int num_blocks, int sync_nv, int immed); +int synchronizecache16_nomedium(struct iscsi_context *iscsi, int lun, uint64_t lba, int num_blocks, int sync_nv, int immed); int testunitready_clear_ua(struct iscsi_context *iscsi, int lun); int testunitready(struct iscsi_context *iscsi, int lun); int testunitready_nomedium(struct iscsi_context *iscsi, int lun); int testunitready_conflict(struct iscsi_context *iscsi, int lun); int unmap(struct iscsi_context *iscsi, int lun, int anchor, struct unmap_list *list, int list_len); int unmap_writeprotected(struct iscsi_context *iscsi, int lun, int anchor, struct unmap_list *list, int list_len); +int unmap_nomedium(struct iscsi_context *iscsi, int lun, int anchor, struct unmap_list *list, int list_len); int verify10(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int vprotect, int dpo, int bytchk, unsigned char *data); int verify10_nomedium(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int vprotect, int dpo, int bytchk, unsigned char *data); int verify10_miscompare(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int vprotect, int dpo, int bytchk, unsigned char *data); @@ -247,38 +263,42 @@ int write10(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen int write10_invalidfieldincdb(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); int write10_lbaoutofrange(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); int write10_writeprotected(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); +int write10_nomedium(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); int write12(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); int write12_invalidfieldincdb(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); int write12_lbaoutofrange(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); int write12_writeprotected(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); +int write12_nomedium(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); int write16(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); int write16_invalidfieldincdb(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); int write16_lbaoutofrange(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); int write16_writeprotected(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); +int write16_nomedium(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); int writesame10(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int num_blocks, int anchor, int unmap, int wrprotect, int group, unsigned char *data); int writesame10_lbaoutofrange(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int num_blocks, int anchor, int unmap, int wrprotect, int group, unsigned char *data); int writesame10_invalidfieldincdb(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int num_blocks, int anchor, int unmap, int wrprotect, int group, unsigned char *data); int writesame10_writeprotected(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int num_blocks, int anchor, int unmap, int wrprotect, int group, unsigned char *data); +int writesame10_nomedium(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int num_blocks, int anchor, int unmap, int wrprotect, int group, unsigned char *data); int writesame16(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int num_blocks, int anchor, int unmap, int wrprotect, int group, unsigned char *data); int writesame16_lbaoutofrange(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int num_blocks, int anchor, int unmap, int wrprotect, int group, unsigned char *data); int writesame16_invalidfieldincdb(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int num_blocks, int anchor, int unmap, int wrprotect, int group, unsigned char *data); int writesame16_writeprotected(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int num_blocks, int anchor, int unmap, int wrprotect, int group, unsigned char *data); +int writesame16_nomedium(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int num_blocks, int anchor, int unmap, int wrprotect, int group, unsigned char *data); int writeverify10(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int bytchk, int group, unsigned char *data); int writeverify10_invalidfieldincdb(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int bytchk, int group, unsigned char *data); int writeverify10_lbaoutofrange(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int bytchk, int group, unsigned char *data); int writeverify10_writeprotected(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int bytchk, int group, unsigned char *data); +int writeverify10_nomedium(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int bytchk, int group, unsigned char *data); int writeverify12(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int bytchk, int group, unsigned char *data); int writeverify12_invalidfieldincdb(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int bytchk, int group, unsigned char *data); int writeverify12_lbaoutofrange(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int bytchk, int group, unsigned char *data); int writeverify12_writeprotected(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int bytchk, int group, unsigned char *data); +int writeverify12_nomedium(struct iscsi_context *iscsi, int lun, uint32_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int bytchk, int group, unsigned char *data); int writeverify16(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int bytchk, int group, unsigned char *data); int writeverify16_invalidfieldincdb(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int bytchk, int group, unsigned char *data); int writeverify16_lbaoutofrange(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int bytchk, int group, unsigned char *data); int writeverify16_writeprotected(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int bytchk, int group, unsigned char *data); -int orwrite(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); -int orwrite_invalidfieldincdb(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); -int orwrite_lbaoutofrange(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); -int orwrite_writeprotected(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data); +int writeverify16_nomedium(struct iscsi_context *iscsi, int lun, uint64_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int bytchk, int group, unsigned char *data); diff --git a/test-tool/iscsi-test-cu.c b/test-tool/iscsi-test-cu.c index 0b4ab44..a17c5fb 100644 --- a/test-tool/iscsi-test-cu.c +++ b/test-tool/iscsi-test-cu.c @@ -66,6 +66,11 @@ static CU_TestInfo tests_get_lba_status[] = { CU_TEST_INFO_NULL }; +static CU_TestInfo tests_nomedia[] = { + { (char *)"testNoMediaSBC", test_nomedia_sbc }, + CU_TEST_INFO_NULL +}; + static CU_TestInfo tests_orwrite[] = { { (char *)"testOrWriteSimple", test_orwrite_simple }, { (char *)"testOrWriteBeyondEol", test_orwrite_beyond_eol }, @@ -318,6 +323,8 @@ static CU_TestInfo tests_writeverify16[] = { static CU_SuiteInfo suites[] = { { (char *)"TestGetLBAStatus", test_setup, test_teardown, tests_get_lba_status }, + { (char *)"TestNoMedia", test_setup, test_teardown, + tests_nomedia }, { (char *)"TestOrWrite", test_setup, test_teardown, tests_orwrite }, { (char *)"TestPrefetch10", test_setup, test_teardown, diff --git a/test-tool/iscsi-test-cu.h b/test-tool/iscsi-test-cu.h index caa299b..8702f96 100644 --- a/test-tool/iscsi-test-cu.h +++ b/test-tool/iscsi-test-cu.h @@ -43,6 +43,8 @@ int test_teardown_pgr(void); void test_get_lba_status_simple(void); void test_get_lba_status_beyond_eol(void); +void test_nomedia_sbc(void); + void test_orwrite_simple(void); void test_orwrite_beyond_eol(void); void test_orwrite_0blocks(void); diff --git a/test-tool/test_nomedia_sbc.c b/test-tool/test_nomedia_sbc.c new file mode 100644 index 0000000..ed460e7 --- /dev/null +++ b/test-tool/test_nomedia_sbc.c @@ -0,0 +1,250 @@ +/* + Copyright (C) 2013 by Ronnie Sahlberg + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . +*/ + +#include + +#include + +#include "iscsi.h" +#include "scsi-lowlevel.h" +#include "iscsi-support.h" +#include "iscsi-test-cu.h" + +void +test_nomedia_sbc(void) +{ + int ret; + unsigned char buf[4096]; + struct unmap_list list[1]; + + CHECK_FOR_SBC; + + logging(LOG_VERBOSE, LOG_BLANK_LINE); + logging(LOG_VERBOSE, "Test that Medium commands fail when medium is ejected on SBC devices"); + + if (!removable) { + logging(LOG_VERBOSE, "[SKIPPED] LUN is not removable. " + "Skipping test."); + return; + } + + logging(LOG_VERBOSE, "Eject the medium."); + ret = startstopunit(iscsic, tgt_lun, 1, 0, 0, 0, 1, 0); + CU_ASSERT_EQUAL(ret, 0); + + logging(LOG_VERBOSE, "Test TESTUNITREADY when medium is ejected."); + ret = testunitready_nomedium(iscsic, tgt_lun); + CU_ASSERT_EQUAL(ret, 0); + + logging(LOG_VERBOSE, "Test SYNCHRONIZECACHE10 when medium is ejected."); + ret = synchronizecache10_nomedium(iscsic, tgt_lun, 0, 1, 1, 1); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] target does not support " + "SYNCHRONIZECACHE10"); + } else { + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Test SYNCHRONIZECACHE16 when medium is ejected."); + ret = synchronizecache16_nomedium(iscsic, tgt_lun, 0, 1, 1, 1); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] target does not support " + "SYNCHRONIZECACHE16"); + } else { + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Test READ10 when medium is ejected."); + ret = read10_nomedium(iscsic, tgt_lun, 0, block_size, block_size, + 0, 0, 0, 0, 0, NULL); + CU_ASSERT_EQUAL(ret, 0); + + logging(LOG_VERBOSE, "Test READ12 when medium is ejected."); + ret = read12_nomedium(iscsic, tgt_lun, 0, block_size, block_size, + 0, 0, 0, 0, 0, NULL); + CU_ASSERT_EQUAL(ret, 0); + + logging(LOG_VERBOSE, "Test READ16 when medium is ejected."); + ret = read16_nomedium(iscsic, tgt_lun, 0, block_size, block_size, + 0, 0, 0, 0, 0, NULL); + CU_ASSERT_EQUAL(ret, 0); + + logging(LOG_VERBOSE, "Test READCAPACITY10 when medium is ejected."); + ret = readcapacity10_nomedium(iscsic, tgt_lun, 0, 0); + CU_ASSERT_EQUAL(ret, 0); + + logging(LOG_VERBOSE, "Test READCAPACITY16 when medium is ejected."); + ret = readcapacity16_nomedium(iscsic, tgt_lun, 15); + CU_ASSERT_EQUAL(ret, 0); + + logging(LOG_VERBOSE, "Test GET_LBA_STATUS when medium is ejected."); + ret = get_lba_status_nomedium(iscsic, tgt_lun, 0, 24); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] target does not support " + "GET_LBA_STATUS"); + } else { + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Test PREFETCH10 when medium is ejected."); + ret = prefetch10_nomedium(iscsic, tgt_lun, 0, 1, 1, 0); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] target does not support " + "PREFETCH10"); + } else { + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Test PREFETCH16 when medium is ejected."); + ret = prefetch16_nomedium(iscsic, tgt_lun, 0, 1, 1, 0); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] target does not support " + "PREFETCH16"); + } else { + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Test VERIFY10 when medium is ejected."); + ret = verify10_nomedium(iscsic, tgt_lun, 0, block_size, block_size, + 0, 0, 1, buf); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] target does not support " + "VERIFY10"); + } else { + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Test VERIFY12 when medium is ejected."); + ret = verify12_nomedium(iscsic, tgt_lun, 0, block_size, block_size, + 0, 0, 1, buf); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] target does not support " + "VERIFY102"); + } else { + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Test VERIFY16 when medium is ejected."); + ret = verify16_nomedium(iscsic, tgt_lun, 0, block_size, block_size, + 0, 0, 1, buf); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] target does not support " + "VERIFY16"); + } else { + CU_ASSERT_EQUAL(ret, 0); + } + + if (!data_loss) { + logging(LOG_VERBOSE, "[SKIPPING] Dataloss flag not set. Skipping test for WRITE commands"); + goto finished; + } + + logging(LOG_VERBOSE, "Test WRITE10 when medium is ejected."); + ret = write10_nomedium(iscsic, tgt_lun, 0, block_size, block_size, + 0, 0, 0, 0, 0, buf); + CU_ASSERT_EQUAL(ret, 0); + + logging(LOG_VERBOSE, "Test WRITE12 when medium is ejected."); + ret = write12_nomedium(iscsic, tgt_lun, 0, block_size, block_size, + 0, 0, 0, 0, 0, buf); + CU_ASSERT_EQUAL(ret, 0); + + logging(LOG_VERBOSE, "Test WRITE16 when medium is ejected."); + ret = write16_nomedium(iscsic, tgt_lun, 0, block_size, block_size, + 0, 0, 0, 0, 0, buf); + CU_ASSERT_EQUAL(ret, 0); + + logging(LOG_VERBOSE, "Test WRITEVERIFY10 when medium is ejected."); + ret = writeverify10_nomedium(iscsic, tgt_lun, 0, block_size, block_size, + 0, 0, 0, 0, buf); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] target does not support " + "WRITEVERIFY10"); + } else { + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Test WRITEVERIFY12 when medium is ejected."); + ret = writeverify12_nomedium(iscsic, tgt_lun, 0, block_size, block_size, + 0, 0, 0, 0, buf); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] target does not support " + "WRITEVERIFY12"); + } else { + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Test WRITEVERIFY16 when medium is ejected."); + ret = writeverify16_nomedium(iscsic, tgt_lun, 0, block_size, block_size, + 0, 0, 0, 0, buf); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] target does not support " + "WRITEVERIFY16"); + } else { + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Test ORWRITE when medium is ejected."); + ret = orwrite_nomedium(iscsic, tgt_lun, 0, block_size, block_size, + 0, 0, 0, 0, 0, buf); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] target does not support " + "ORWRITE"); + } else { + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Test COMPAREWRITE when medium is ejected."); + logging(LOG_VERBOSE, "[SKIPPED] Test not implemented yet"); + + logging(LOG_VERBOSE, "Test WRITESAME10 when medium is ejected."); + ret = writesame10_nomedium(iscsic, tgt_lun, 0, block_size, + 1, 0, 0, 0, 0, buf); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] target does not support " + "WRITESAME10"); + } else { + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Test WRITESAME16 when medium is ejected."); + ret = writesame16_nomedium(iscsic, tgt_lun, 0, block_size, + 1, 0, 0, 0, 0, buf); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] target does not support " + "WRITESAME16"); + } else { + CU_ASSERT_EQUAL(ret, 0); + } + + logging(LOG_VERBOSE, "Test UNMAP when medium is ejected."); + list[0].lba = 0; + list[0].num = lbppb; + ret = unmap_nomedium(iscsic, tgt_lun, 0, list, 1); + if (ret == -2) { + logging(LOG_NORMAL, "[SKIPPED] target does not support " + "UNMAP"); + } else { + CU_ASSERT_EQUAL(ret, 0); + } + + +finished: + logging(LOG_VERBOSE, "Load the medium again."); + ret = startstopunit(iscsic, tgt_lun, 1, 0, 0, 0, 1, 1); + CU_ASSERT_EQUAL(ret, 0); +} diff --git a/test-tool/test_startstopunit_noloej.c b/test-tool/test_startstopunit_noloej.c index c5ec2b4..c4bff2c 100644 --- a/test-tool/test_startstopunit_noloej.c +++ b/test-tool/test_startstopunit_noloej.c @@ -33,7 +33,7 @@ test_startstopunit_noloej(void) logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, "Test STARTSTOPUNIT LOEJ==0"); if (!removable) { - logging(LOG_VERBOSE, "[SKIPPED] LUN is not removalbe. " + logging(LOG_VERBOSE, "[SKIPPED] LUN is not removable. " "Skipping test."); return; } @@ -43,7 +43,7 @@ test_startstopunit_noloej(void) 0, 0, 0, 0, 0, 0); CU_ASSERT_EQUAL(ret, 0); - logging(LOG_VERBOSE, "Test TESTNUITREADY that medium is not ejected."); + logging(LOG_VERBOSE, "Test TESTUNITREADY that medium is not ejected."); ret = testunitready(iscsic, tgt_lun); CU_ASSERT_EQUAL(ret, 0); @@ -52,7 +52,7 @@ test_startstopunit_noloej(void) 0, 0, 0, 0, 0, 1); CU_ASSERT_EQUAL(ret, 0); - logging(LOG_VERBOSE, "Test TESTNUITREADY that medium is not ejected."); + logging(LOG_VERBOSE, "Test TESTUNITREADY that medium is not ejected."); ret = testunitready(iscsic, tgt_lun); CU_ASSERT_EQUAL(ret, 0); @@ -61,7 +61,7 @@ test_startstopunit_noloej(void) 1, 0, 0, 0, 0, 0); CU_ASSERT_EQUAL(ret, 0); - logging(LOG_VERBOSE, "Test TESTNUITREADY that medium is not ejected."); + logging(LOG_VERBOSE, "Test TESTUNITREADY that medium is not ejected."); ret = testunitready(iscsic, tgt_lun); CU_ASSERT_EQUAL(ret, 0); @@ -70,7 +70,7 @@ test_startstopunit_noloej(void) 1, 0, 0, 0, 0, 1); CU_ASSERT_EQUAL(ret, 0); - logging(LOG_VERBOSE, "Test TESTNUITREADY that medium is not ejected."); + logging(LOG_VERBOSE, "Test TESTUNITREADY that medium is not ejected."); ret = testunitready(iscsic, tgt_lun); CU_ASSERT_EQUAL(ret, 0); @@ -79,7 +79,7 @@ test_startstopunit_noloej(void) 0, 0, 0, 1, 0, 0); CU_ASSERT_EQUAL(ret, 0); - logging(LOG_VERBOSE, "Test TESTNUITREADY that medium is not ejected."); + logging(LOG_VERBOSE, "Test TESTUNITREADY that medium is not ejected."); ret = testunitready(iscsic, tgt_lun); CU_ASSERT_EQUAL(ret, 0); @@ -88,7 +88,7 @@ test_startstopunit_noloej(void) 0, 0, 0, 1, 0, 1); CU_ASSERT_EQUAL(ret, 0); - logging(LOG_VERBOSE, "Test TESTNUITREADY that medium is not ejected."); + logging(LOG_VERBOSE, "Test TESTUNITREADY that medium is not ejected."); ret = testunitready(iscsic, tgt_lun); CU_ASSERT_EQUAL(ret, 0); @@ -97,7 +97,7 @@ test_startstopunit_noloej(void) 1, 0, 0, 1, 0, 0); CU_ASSERT_EQUAL(ret, 0); - logging(LOG_VERBOSE, "Test TESTNUITREADY that medium is not ejected."); + logging(LOG_VERBOSE, "Test TESTUNITREADY that medium is not ejected."); ret = testunitready(iscsic, tgt_lun); CU_ASSERT_EQUAL(ret, 0); @@ -106,7 +106,7 @@ test_startstopunit_noloej(void) 1, 0, 0, 1, 0, 1); CU_ASSERT_EQUAL(ret, 0); - logging(LOG_VERBOSE, "Test TESTNUITREADY that medium is not ejected."); + logging(LOG_VERBOSE, "Test TESTUNITREADY that medium is not ejected."); ret = testunitready(iscsic, tgt_lun); CU_ASSERT_EQUAL(ret, 0); diff --git a/test-tool/test_startstopunit_pwrcnd.c b/test-tool/test_startstopunit_pwrcnd.c index 73fd06a..fffd169 100644 --- a/test-tool/test_startstopunit_pwrcnd.c +++ b/test-tool/test_startstopunit_pwrcnd.c @@ -33,7 +33,7 @@ test_startstopunit_pwrcnd(void) logging(LOG_VERBOSE, LOG_BLANK_LINE); logging(LOG_VERBOSE, "Test STARTSTOPUNIT PowerCondition"); if (!removable) { - logging(LOG_VERBOSE, "[SKIPPED] LUN is not removalbe. " + logging(LOG_VERBOSE, "[SKIPPED] LUN is not removable. " "Skipping test."); return; } @@ -44,7 +44,7 @@ test_startstopunit_pwrcnd(void) 1, 0, i, 0, 1, 0); CU_ASSERT_EQUAL(ret, 0); - logging(LOG_VERBOSE, "Test TESTNUITREADY that medium is not ejected."); + logging(LOG_VERBOSE, "Test TESTUNITREADY that medium is not ejected."); ret = testunitready(iscsic, tgt_lun); CU_ASSERT_EQUAL(ret, 0); } diff --git a/test-tool/test_startstopunit_simple.c b/test-tool/test_startstopunit_simple.c index bdc8d61..2216ac6 100644 --- a/test-tool/test_startstopunit_simple.c +++ b/test-tool/test_startstopunit_simple.c @@ -50,7 +50,7 @@ test_startstopunit_simple(void) CU_ASSERT_EQUAL(ret, 0); - logging(LOG_VERBOSE, "Test TESTNUITREADY that medium is ejected."); + logging(LOG_VERBOSE, "Test TESTUNITREADY that medium is ejected."); ret = testunitready_nomedium(iscsic, tgt_lun); CU_ASSERT_EQUAL(ret, 0); @@ -72,7 +72,7 @@ test_startstopunit_simple(void) CU_ASSERT_EQUAL(ret, 0); - logging(LOG_VERBOSE, "Test TESTNUITREADY that medium is ejected."); + logging(LOG_VERBOSE, "Test TESTUNITREADY that medium is ejected."); ret = testunitready_nomedium(iscsic, tgt_lun); CU_ASSERT_EQUAL(ret, 0);