Files
libiscsi/test-tool/iscsi-support.h
Anatoliy Glagolev 19d05ab7a7 RTPG support
Implementing support of the Report Target Port Groups command.

Tested on Ubuntu against Pure Storage Flash Array
using designated unit tests and new iscsi-rtpg utility

./iscsi-rtpg  -i iqn.2005-03.org.open-iscsi:6feb2db21ea iscsi://192.168.1.12/iqn.2010-06.com.purestorage:flasharray.4e8d52d82e4b2c0f/1
RTPG retrieved 2 groups
Group 0x0000: preferred 0, format 0x00, ALUA state ACTIVE-OPTIMIZED,flags 0x8f, status code 0x02, port count 65
Ports: [ 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf 0x10 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48 0x49 0x4a 0x4b 0x4c
0x4d 0x4e 0x4f 0x50 0x51 0x52 0x53 0x54 0x55 0x56 0x57 0x58 0x59 0x5a 0x5b 0x5c 0x5d 0x5e 0x5f 0x60 0x61 0x62 0x63 0x64 0x65 0x66 0x67
0x68 0x69 0x6a 0x6b 0x6c 0x6d 0x6e 0x6f 0x70 0x71]
Group 0x0001: preferred 0, format 0x00, ALUA state ACTIVE-OPTIMIZED,flags 0x8f, status code 0x02, port count 65
Ports: [ 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f 0x20 0x72 0x73 0x74 0x75 0x76 0x77 0x78 0x79 0x7a
0x7b 0x7c 0x7d 0x7e 0x7f 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 0x90 0x91 0x92 0x93 0x94 0x95
0x96 0x97 0x98 0x99 0x9a 0x9b 0x9c 0x9d 0x9e 0x9f 0xa0 0xa1 0xa2]
2025-07-03 17:20:52 -06:00

939 lines
58 KiB
C

/*
iscsi-test tool support
Copyright (C) 2012 by Lee Duncan <leeman.duncan@gmail.com>
Copyright (C) 2014 by Ronnie sahlberg <ronniesahlberg@gmail.com>
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 <http://www.gnu.org/licenses/>.
*/
#ifndef _ISCSI_SUPPORT_H_
#define _ISCSI_SUPPORT_H_
#include <time.h>
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdlib.h>
#include "iscsi.h"
#include "scsi-lowlevel.h"
extern const char *initiatorname1;
extern const char *initiatorname2;
#define EXPECT_STATUS_GOOD SCSI_STATUS_GOOD, SCSI_SENSE_NO_SENSE, NULL, 0
#define EXPECT_STATUS_GENERIC_BAD SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_ILLEGAL_REQUEST, NULL, 0
#define EXPECT_STATUS_TIMEOUT SCSI_STATUS_TIMEOUT, SCSI_SENSE_NO_SENSE, NULL, 0
#define EXPECT_NO_MEDIUM SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_NOT_READY, no_medium_ascqs, 3
#define EXPECT_LBA_OOB SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_ILLEGAL_REQUEST, lba_oob_ascqs, 1
#define EXPECT_INVALID_FIELD_IN_CDB SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_ILLEGAL_REQUEST, invalid_cdb_ascqs,2
#define EXPECT_PARAM_LIST_LEN_ERR SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_ILLEGAL_REQUEST, param_list_len_err_ascqs, 1
#define EXPECT_TOO_MANY_DESCR SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_ILLEGAL_REQUEST, too_many_desc_ascqs, 2
#define EXPECT_UNSUPP_DESCR_CODE SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_ILLEGAL_REQUEST, unsupp_desc_code_ascqs, 2
#define EXPECT_MISCOMPARE SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_MISCOMPARE, miscompare_ascqs, 1
#define EXPECT_WRITE_PROTECTED SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_DATA_PROTECTION, write_protect_ascqs, 3
#define EXPECT_SANITIZE SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_NOT_READY, sanitize_ascqs, 1
#define EXPECT_REMOVAL_PREVENTED SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_ILLEGAL_REQUEST, removal_ascqs, 1
#define EXPECT_RESERVATION_CONFLICT SCSI_STATUS_RESERVATION_CONFLICT, 0, NULL, 0
#define EXPECT_COPY_ABORTED SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_COPY_ABORTED, copy_aborted_ascqs, 3
extern int no_medium_ascqs[3];
extern int lba_oob_ascqs[1];
extern int invalid_cdb_ascqs[2];
extern int param_list_len_err_ascqs[1];
extern int too_many_desc_ascqs[2];
extern int unsupp_desc_code_ascqs[2];
extern int write_protect_ascqs[3];
extern int sanitize_ascqs[1];
extern int removal_ascqs[1];
extern int miscompare_ascqs[1];
extern int copy_aborted_ascqs[3];
extern int loglevel;
#define LOG_SILENT 0
#define LOG_NORMAL 1
#define LOG_VERBOSE 2
void logging(int level, const char *format, ...)
__attribute__((format(printf, 2, 3)));
/*
* define special flags for logging a blank line, so compiler
* does not commplain when logging a ""
*/
#define LOG_BLANK_LINE " "
#define LOG_BLANK_LINE_CMP_LEN 2
#define CHECK_FOR_DATALOSS \
do { \
if (!data_loss) { \
logging(LOG_NORMAL, "[SKIPPED] --dataloss flag is not " \
"set. Skipping test."); \
CU_PASS("[SKIPPED] --dataloss flag is not set." \
" Skipping test"); \
return; \
} \
} while (0);
#define CHECK_FOR_SANITIZE \
do { \
if (!allow_sanitize) { \
logging(LOG_NORMAL, "[SKIPPED] --allow-sanitize flag " \
"is not set. Skipping test."); \
CU_PASS("[SKIPPED] --allow-sanitize flag is not set." \
" Skipping test"); \
return; \
} \
} while (0);
#define CHECK_FOR_READONLY \
do { \
if (!readonly) { \
logging(LOG_NORMAL, "[SKIPPED] Logical unit is not " \
"write-protected. Skipping test."); \
CU_PASS("[SKIPPED] Logical unit is not write-" \
"protected. Skipping test"); \
return; \
} \
} while (0);
#define CHECK_FOR_REMOVABLE \
do { \
if (!inq->rmb) { \
logging(LOG_NORMAL, "[SKIPPED] Logical unit is not " \
"removable. Skipping test."); \
CU_PASS("[SKIPPED] Logical unit is not removable" \
" Skipping test"); \
return; \
} \
} while (0);
#define CHECK_FOR_THIN_PROVISIONING \
do { \
if (rc16 == NULL || rc16->lbpme == 0) { \
logging(LOG_NORMAL, "[SKIPPED] Logical unit is fully" \
" provisioned. Skipping test"); \
CU_PASS("[SKIPPED] Logical unit is fully provisioned." \
" Skipping test"); \
return; \
} \
} while (0);
#define CHECK_FOR_LBPWS10 \
do { \
if (inq_lbp->lbpws10 == 0) { \
logging(LOG_NORMAL, "[SKIPPED] Logical unit does not" \
" have LBPWS10. Skipping test"); \
CU_PASS("[SKIPPED] Logical unit does not have LBPWS10." \
" Skipping test"); \
return; \
} \
} while (0);
#define CHECK_FOR_LBPWS \
do { \
if (inq_lbp->lbpws == 0) { \
logging(LOG_NORMAL, "[SKIPPED] Logical unit does not" \
" have LBPWS. Skipping test"); \
CU_PASS("[SKIPPED] Logical unit does not have LBPWS." \
" Skipping test"); \
return; \
} \
} while (0);
#define CHECK_FOR_LBPU \
do { \
if (inq_lbp->lbpu == 0) { \
logging(LOG_NORMAL, "[SKIPPED] Logical unit does not" \
" have LBPU. Skipping test"); \
CU_PASS("[SKIPPED] Logical unit does not have LBPU." \
" Skipping test"); \
return; \
} \
} while (0);
#define CHECK_FOR_LBPPB_GT_1 \
do { \
if (lbppb < 2) { \
logging(LOG_NORMAL, "[SKIPPED] LBPPB < 2. Skipping test"); \
CU_PASS("[SKIPPED] LBPPB < 2. Skipping test"); \
return; \
} \
} while (0);
#define CHECK_FOR_SBC \
do { \
if (inq->device_type != SCSI_INQUIRY_PERIPHERAL_DEVICE_TYPE_DIRECT_ACCESS) {\
logging(LOG_NORMAL, "[SKIPPED] Not SBC device." \
" Skipping test"); \
CU_PASS("[SKIPPED] Not SBC device." \
" Skipping test"); \
return; \
} \
} while (0);
#define CHECK_FOR_ISCSI(_sd) \
do { \
if (_sd->iscsi_ctx == NULL) { \
logging(LOG_NORMAL, "[SKIPPED] Not an iSCSI device." \
" Skipping test"); \
CU_PASS("[SKIPPED] Not an iSCSI device. Skipping test"); \
return; \
} \
} while (0);
#define CHECK_SIZE(_min_blocks, _c) \
do { \
if (num_blocks < _min_blocks) { \
logging(LOG_VERBOSE, "[SKIPPED] " \
"LUN too small. Skipping assert"); \
} else { \
_c \
} \
} while (0);
#define COMPAREANDWRITE(...) \
do { \
int _r; \
_r = compareandwrite(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] COMPAREANDWRITE " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"COMPAREANDWRITE. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define EXTENDEDCOPY(...) \
do { \
int _r; \
_r = extendedcopy(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] EXTENDEDCOPY " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"EXTENDEDCOPY. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define GETLBASTATUS(...) \
do { \
int _r; \
_r = get_lba_status(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] GETLBASTATUS " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"GETLBASTATUS. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define MODESENSE6(...) \
do { \
int _r; \
_r = modesense6(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] MODESENSE6 " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"MODESENSE6. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define ORWRITE(...) \
do { \
int _r; \
_r = orwrite(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] ORWRITE " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"ORWRITE. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define PREFETCH10(...) \
do { \
int _r; \
_r = prefetch10(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] PREFETCH10 " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"PREFETCH10. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define PREFETCH16(...) \
do { \
int _r; \
_r = prefetch16(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] PREFETCH16 " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"PREFETCH16. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define PREVENTALLOW(...) \
do { \
int _r; \
_r = preventallow(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] PREVENTALLOW " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"PREVENTALLOW. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define READ6(...) \
do { \
int _r; \
_r = read6(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] READ6 " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"READ6. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define READ10(...) \
({ \
int _r; \
_r = read10(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] READ10 " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"READ10. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
_r; \
})
#define READ12(...) \
do { \
int _r; \
_r = read12(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] READ12 " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"READ12. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define READ16(...) \
do { \
int _r; \
_r = read16(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] READ16 " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"READ16. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define READCAPACITY10(...) \
do { \
int _r; \
_r = readcapacity10(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] READCAPACITY10 " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"READCAPACITY10. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define READCAPACITY16(...) \
do { \
int _r; \
_r = readcapacity16(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] READCAPACITY16 " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"READCAPACITY16. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define READDEFECTDATA10(...) \
do { \
int _r; \
_r = readdefectdata10(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] READDEFECTDATA10 " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"READDEFECTDATA10. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define READDEFECTDATA12(...) \
do { \
int _r; \
_r = readdefectdata12(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] READDEFECTDATA12 " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"READDEFECTDATA12. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define RECEIVE_COPY_RESULTS(...) \
({ \
int _r; \
_r = receive_copy_results(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] RECEIVE_COPY" \
"_RESULTS is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"RECEIVE_COPY_RESULTS. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
_r; \
})
#define RELEASE6(...) \
do { \
int _r; \
_r = release6(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] RELEASE6 " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"RELEASE6. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define REPORT_SUPPORTED_OPCODES(...) \
do { \
int _r; \
_r = report_supported_opcodes(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] REPORT_SUPPORTED" \
"_OPCODES is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"REPORT_SUPPORTED_OPCODES. Skipping " \
"test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define RESERVE6(...) \
do { \
int _r; \
_r = reserve6(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] RESERVE6 " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"RESERVE6. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define SANITIZE(...) \
do { \
int _r; \
_r = sanitize(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] SANITIZE " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"SANITIZE. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define STARTSTOPUNIT(...) \
do { \
int _r; \
_r = startstopunit(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] STARTSTOPUNIT " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"STARTSTOPUNIT. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define SYNCHRONIZECACHE10(...) \
do { \
int _r; \
_r = synchronizecache10(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] SYNCHRONIZECACHE10 " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"SYNCHRONIZECACHE10. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define SYNCHRONIZECACHE16(...) \
do { \
int _r; \
_r = synchronizecache16(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] SYNCHRONIZECACHE16 " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"SYNCHRONIZECACHE16. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define TESTUNITREADY(...) \
do { \
int _r; \
_r = testunitready(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] TESTUNITREADY " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"TESTUNITREADY. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define UNMAP(...) \
do { \
int _r; \
_r = unmap(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] UNMAP " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"UNMAP. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define VERIFY10(...) \
do { \
int _r; \
_r = verify10(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] VERIFY10 " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"VERIFY10. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define VERIFY12(...) \
do { \
int _r; \
_r = verify12(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] VERIFY12 " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"VERIFY12. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define VERIFY16(...) \
do { \
int _r; \
_r = verify16(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] VERIFY16 " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"VERIFY16. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define WRITE10(...) \
({ \
int _r; \
_r = write10(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] WRITE10 " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"WRITE10. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
_r; \
})
#define WRITE12(...) \
do { \
int _r; \
_r = write12(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] WRITE12 " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"WRITE12. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define WRITE16(...) \
do { \
int _r; \
_r = write16(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] WRITE16 " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"WRITE16. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define WRITEATOMIC16(...) \
do { \
int _r; \
_r = writeatomic16(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] WRITEATOMIC16 " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"WRITEATOMIC16. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define WRITESAME10(...) \
do { \
int _r; \
_r = writesame10(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] WRITESAME10 " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"WRITESAME10. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define WRITESAME16(...) \
do { \
int _r; \
_r = writesame16(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] WRITESAME16 " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"WRITESAME16. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define WRITEVERIFY10(...) \
do { \
int _r; \
_r = writeverify10(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] WRITEVERIFY10 " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"WRITEVERIFY10. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define WRITEVERIFY12(...) \
do { \
int _r; \
_r = writeverify12(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] WRITEVERIFY12 " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"WRITEVERIFY12. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define WRITEVERIFY16(...) \
do { \
int _r; \
_r = writeverify16(__VA_ARGS__); \
if (_r == -2) { \
logging(LOG_NORMAL, "[SKIPPED] WRITEVERIFY16 " \
"is not implemented."); \
CU_PASS("[SKIPPED] Target does not support " \
"WRITEVERIFY16. Skipping test"); \
return; \
} \
CU_ASSERT_EQUAL(_r, 0); \
} while (0);
#define ALL_ZERO(...) \
do { \
if (all_zero(__VA_ARGS__) == 0) { \
logging(LOG_NORMAL, "[FAILED] Blocks did not " \
"read back as zero"); \
CU_FAIL("[FAILED] Blocks did not read back " \
"as zero"); \
return; \
} \
} while (0);
extern struct scsi_inquiry_standard *inq;
extern struct scsi_inquiry_logical_block_provisioning *inq_lbp;
extern struct scsi_inquiry_block_device_characteristics *inq_bdc;
extern struct scsi_inquiry_block_limits *inq_bl;
extern struct scsi_readcapacity16 *rc16;
extern struct scsi_report_supported_op_codes *rsop;
extern unsigned char *scratch;
extern size_t block_size;
extern uint64_t num_blocks;
extern int lbppb;
extern int data_loss;
extern int allow_sanitize;
extern int readonly;
extern int sbc3_support;
extern int maximum_transfer_length;
struct scsi_device {
char *error_str;
struct iscsi_context *iscsi_ctx;
int iscsi_lun;
char *iscsi_url;
char *sgio_dev;
int sgio_fd;
};
extern struct scsi_device *sd;
struct iscsi_context *iscsi_context_login(const char *initiatorname, const char *url, int *lun);
struct iscsi_async_state {
struct scsi_task *task;
int status;
int finished;
};
void wait_until_test_finished(struct iscsi_context *iscsi, struct iscsi_async_state *test_state);
struct iscsi_pdu;
struct scsi_command_descriptor *get_command_descriptor(int opcode, int sa);
/*
* PGR support
*/
static inline long rand_key(void)
{
static int seed = 0;
if (!seed) {
struct timeval tv;
pid_t p;
unsigned int s;
gettimeofday(&tv, NULL);
p = getpid();
s = p ^ tv.tv_sec ^ tv.tv_usec;
srandom(s);
}
seed = 1;
return random();
}
static inline int pr_type_is_all_registrants(
enum scsi_persistent_out_type pr_type)
{
switch (pr_type) {
case SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE_ALL_REGISTRANTS:
case SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS_ALL_REGISTRANTS:
return 1;
default:
return 0;
}
}
int all_zero(const unsigned char *buf, unsigned size);
int prin_task(struct scsi_device *sdev, int service_action,
int success_expected);
int prin_read_keys(struct scsi_device *sdev, struct scsi_task **tp,
struct scsi_persistent_reserve_in_read_keys **rkp,
uint16_t allocation_len);
int prout_register_and_ignore(struct scsi_device *sdev,
unsigned long long key);
int prout_register_key(struct scsi_device *sdev,
unsigned long long sark, unsigned long long rk);
int prin_verify_key_presence(struct scsi_device *sdev,
unsigned long long key, int present);
int prout_reregister_key_fails(struct scsi_device *sdev,
unsigned long long sark);
int prout_reserve(struct scsi_device *sdev,
unsigned long long key, enum scsi_persistent_out_type pr_type);
int prout_release(struct scsi_device *sdev,
unsigned long long key, enum scsi_persistent_out_type pr_type);
int prout_clear(struct scsi_device *sdev, unsigned long long key);
int prout_preempt(struct scsi_device *sdev,
unsigned long long sark, unsigned long long rk,
enum scsi_persistent_out_type pr_type);
int prin_verify_not_reserved(struct scsi_device *sdev);
int prin_verify_reserved_as(struct scsi_device *sdev,
unsigned long long key, enum scsi_persistent_out_type pr_type);
int prin_report_caps(struct scsi_device *sdev, struct scsi_task **tp,
struct scsi_persistent_reserve_in_report_capabilities **_rcaps);
int verify_read_works(struct scsi_device *sdev, unsigned char *buf);
int verify_write_works(struct scsi_device *sdev, unsigned char *buf);
int verify_read_fails(struct scsi_device *sdev, unsigned char *buf);
int verify_write_fails(struct scsi_device *sdev, unsigned char *buf);
int compareandwrite(struct scsi_device *sdev, uint64_t lba, unsigned char *data, uint32_t len, int blocksize, int wrprotect, int dpo, int fua, int group_number, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int get_lba_status(struct scsi_device *sdev, struct scsi_task **task, uint64_t lba, uint32_t len, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int inquiry(struct scsi_device *sdev, struct scsi_task **task, int evpd, int page_code, int maxsize, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int modesense6(struct scsi_device *sdev, struct scsi_task **task, int dbd, enum scsi_modesense_page_control pc, enum scsi_modesense_page_code page_code, int sub_page_code, unsigned char alloc_len, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int modeselect6(struct scsi_device *sdev, int pf, int sp, struct scsi_mode_page *mp, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int orwrite(struct scsi_device *sdev, uint64_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int prefetch10(struct scsi_device *sdev, uint32_t lba, int num_blocks, int immed, int group, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int prefetch16(struct scsi_device *sdev, uint64_t lba, int num_blocks, int immed, int group, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int preventallow(struct scsi_device *sdev, int prevent);
int read6(struct scsi_device *sdev, struct scsi_task **task, uint32_t lba, uint32_t datalen, int blocksize, unsigned char *data, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int read10(struct scsi_device *sdev, struct scsi_task **task, uint32_t lba, uint32_t datalen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int read12(struct scsi_device *sdev, struct scsi_task **task, uint32_t lba, uint32_t datalen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int read16(struct scsi_device *sdev, struct scsi_task **task, uint64_t lba, uint32_t datalen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int readcapacity10(struct scsi_device *sdev, struct scsi_task **task, uint32_t lba, int pmi, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int readcapacity16(struct scsi_device *sdev, struct scsi_task **task, int alloc_len, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int readdefectdata10(struct scsi_device *sdev, struct scsi_task **task,
int req_plist, int req_glist,
int defect_list_format, uint16_t alloc_len,
int status, enum scsi_sense_key key,
int *ascq, int num_ascq);
int readdefectdata12(struct scsi_device *sdev, struct scsi_task **task,
int req_plist, int req_glist,
int defect_list_format,
uint32_t address_descriptor_index,
uint32_t alloc_len,
int status, enum scsi_sense_key key,
int *ascq, int num_ascq);
int report_supported_opcodes(struct scsi_device *sdev, struct scsi_task **save_task, int rctd, int options, int opcode, int sa, int alloc_len, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int release6(struct scsi_device *sdev);
int reserve6(struct scsi_device *sdev);
int reserve6_conflict(struct scsi_device *sdev);
int rtpg(struct scsi_device *sdev, struct scsi_task **out_task, int maxsize, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int sanitize(struct scsi_device *sdev, int immed, int ause, int sa, int param_len, struct iscsi_data *data, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int startstopunit(struct scsi_device *sdev, int immed, int pcm, int pc, int no_flush, int loej, int start, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int synchronizecache10(struct scsi_device *sdev, uint32_t lba, int num_blocks, int sync_nv, int immed, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int synchronizecache16(struct scsi_device *sdev, uint64_t lba, int num_blocks, int sync_nv, int immed, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int testunitready_clear_ua(struct scsi_device *sdev);
int testunitready(struct scsi_device *sdev, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int unmap(struct scsi_device *sdev, int anchor, struct unmap_list *list, int list_len, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int verify10(struct scsi_device *sdev, uint32_t lba, uint32_t datalen, int blocksize, int vprotect, int dpo, int bytchk, unsigned char *data, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int verify12(struct scsi_device *sdev, uint32_t lba, uint32_t datalen, int blocksize, int vprotect, int dpo, int bytchk, unsigned char *data, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int verify16(struct scsi_device *sdev, uint64_t lba, uint32_t datalen, int blocksize, int vprotect, int dpo, int bytchk, unsigned char *data, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int write10(struct scsi_device *sdev, uint32_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int write12(struct scsi_device *sdev, uint32_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int write16(struct scsi_device *sdev, uint64_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group, unsigned char *data, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int writeatomic16(struct scsi_device *sdev, uint64_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int fua, int group, unsigned char *data, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int writesame10(struct scsi_device *sdev, uint32_t lba, uint32_t datalen, int num_blocks, int anchor, int unmap, int wrprotect, int group, unsigned char *data, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int writesame16(struct scsi_device *sdev, uint64_t lba, uint32_t datalen, int num_blocks, int anchor, int unmap, int wrprotect, int group, unsigned char *data, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int writeverify10(struct scsi_device *sdev, uint32_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int bytchk, int group, unsigned char *data, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int writeverify12(struct scsi_device *sdev, uint32_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int bytchk, int group, unsigned char *data, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int writeverify16(struct scsi_device *sdev, uint64_t lba, uint32_t datalen, int blocksize, int wrprotect, int dpo, int bytchk, int group, unsigned char *data, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int set_swp(struct scsi_device *sdev);
int clear_swp(struct scsi_device *sdev);
int extendedcopy(struct scsi_device *sdev, struct iscsi_data *data, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
int get_desc_len(enum ec_descr_type_code desc_type);
int populate_tgt_desc(uint8_t desc[32], enum ec_descr_type_code desc_type,
int luid_type, int nul, int peripheral_type,
uint16_t rel_init_port_id, int pad,
struct scsi_device *dev);
int populate_seg_desc_hdr(unsigned char *hdr, enum ec_descr_type_code desc_type, int dc, int cat, uint16_t src_index, uint16_t dst_index);
int populate_seg_desc_b2b(unsigned char *desc, int dc, int cat, int src_index, int dst_index, uint16_t num_blks, uint64_t src_lba, uint64_t dst_lba);
int populate_seg_desc_b2b_off(unsigned char *desc, int cat, int src_index,
int dst_index, uint32_t num_bytes,
uint64_t src_lba, uint64_t dst_lba,
uint16_t src_byte_off, uint16_t dst_byte_off);
void populate_param_header(unsigned char *buf, int list_id, int str, int list_id_usage, int prio, int tgt_desc_len, int seg_desc_len, int inline_data_len);
int receive_copy_results(struct scsi_task **task, struct scsi_device *sdev,
enum scsi_copy_results_sa sa, int list_id,
void **datap, int status, enum scsi_sense_key key,
int *ascq, int num_ascq);
int test_iscsi_tur_until_good(struct scsi_device *iscsi_sd, int *num_uas);
uint64_t test_get_clock_sec(void);
#endif /* _ISCSI_SUPPORT_H_ */