1 /*
2    iscsi-test tool support
3 
4    Copyright (C) 2012 by Lee Duncan <leeman.duncan@gmail.com>
5    Copyright (C) 2014 by Ronnie sahlberg <ronniesahlberg@gmail.com>
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 #ifndef        _ISCSI_SUPPORT_H_
22 #define        _ISCSI_SUPPORT_H_
23 
24 #include <time.h>
25 #include <sys/types.h>
26 #include <sys/time.h>
27 #include <unistd.h>
28 #include <stdlib.h>
29 
30 #ifndef discard_const
31 #define discard_const(ptr) ((void *)((intptr_t)(ptr)))
32 #endif
33 
34 extern const char *initiatorname1;
35 extern const char *initiatorname2;
36 
37 #define EXPECT_STATUS_GOOD SCSI_STATUS_GOOD, SCSI_SENSE_NO_SENSE, NULL, 0
38 #define EXPECT_STATUS_GENERIC_BAD SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_ILLEGAL_REQUEST, NULL, 0
39 #define EXPECT_STATUS_TIMEOUT SCSI_STATUS_TIMEOUT, SCSI_SENSE_NO_SENSE, NULL, 0
40 #define EXPECT_NO_MEDIUM SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_NOT_READY, no_medium_ascqs, 3
41 #define EXPECT_LBA_OOB SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_ILLEGAL_REQUEST, lba_oob_ascqs, 1
42 #define EXPECT_INVALID_FIELD_IN_CDB SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_ILLEGAL_REQUEST, invalid_cdb_ascqs,2
43 #define EXPECT_PARAM_LIST_LEN_ERR SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_ILLEGAL_REQUEST, param_list_len_err_ascqs, 1
44 #define EXPECT_TOO_MANY_DESCR SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_ILLEGAL_REQUEST, too_many_desc_ascqs, 2
45 #define EXPECT_UNSUPP_DESCR_CODE SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_ILLEGAL_REQUEST, unsupp_desc_code_ascqs, 2
46 #define EXPECT_MISCOMPARE SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_MISCOMPARE, miscompare_ascqs, 1
47 #define EXPECT_WRITE_PROTECTED SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_DATA_PROTECTION, write_protect_ascqs, 3
48 #define EXPECT_SANITIZE SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_NOT_READY, sanitize_ascqs, 1
49 #define EXPECT_REMOVAL_PREVENTED SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_ILLEGAL_REQUEST, removal_ascqs, 1
50 #define EXPECT_RESERVATION_CONFLICT SCSI_STATUS_RESERVATION_CONFLICT, 0, NULL, 0
51 #define EXPECT_COPY_ABORTED SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_COPY_ABORTED, copy_aborted_ascqs, 3
52 
53 int no_medium_ascqs[3];
54 int lba_oob_ascqs[1];
55 int invalid_cdb_ascqs[2];
56 int param_list_len_err_ascqs[1];
57 int too_many_desc_ascqs[2];
58 int unsupp_desc_code_ascqs[2];
59 int write_protect_ascqs[3];
60 int sanitize_ascqs[1];
61 int removal_ascqs[1];
62 int miscompare_ascqs[1];
63 int copy_aborted_ascqs[3];
64 
65 extern int loglevel;
66 #define LOG_SILENT  0
67 #define LOG_NORMAL  1
68 #define LOG_VERBOSE 2
69 void logging(int level, const char *format, ...) _R_(2,3);
70 
71 /*
72  * define special flags for logging a blank line, so compiler
73  * does not commplain when logging a ""
74  */
75 #define        LOG_BLANK_LINE " "
76 #define LOG_BLANK_LINE_CMP_LEN 2
77 
78 #define CHECK_FOR_DATALOSS                                                \
79 do {                                                                        \
80         if (!data_loss) {                                                \
81                 logging(LOG_NORMAL, "[SKIPPED] --dataloss flag is not " \
82                                 "set. Skipping test.");                                     \
83                 CU_PASS("[SKIPPED] --dataloss flag is not set."                \
84                         " Skipping test");                                \
85                 return;                                                        \
86         }                                                                \
87 } while (0);
88 
89 #define CHECK_FOR_SANITIZE                                                \
90 do {                                                                        \
91         if (!allow_sanitize) {                                                \
92                 logging(LOG_NORMAL, "[SKIPPED] --allow-sanitize flag " \
93                         "is not set. Skipping test.");                                     \
94                 CU_PASS("[SKIPPED] --allow-sanitize flag is not set."        \
95                         " Skipping test");                                \
96                 return;                                                        \
97         }                                                                \
98 } while (0);
99 
100 #define CHECK_FOR_READONLY                                                \
101 do {                                                                        \
102         if (!readonly) {                                                \
103                 logging(LOG_NORMAL, "[SKIPPED] Logical unit is not "        \
104                                 "write-protected. Skipping test.");        \
105                 CU_PASS("[SKIPPED] Logical unit is not write-"                \
106                                    "protected. Skipping test");                \
107                 return;                                                        \
108         }                                                                \
109 } while (0);
110 
111 #define CHECK_FOR_REMOVABLE                                                \
112 do {                                                                        \
113         if (!inq->rmb) {                                                \
114                 logging(LOG_NORMAL, "[SKIPPED] Logical unit is not "        \
115                         "removable. Skipping test.");                        \
116                 CU_PASS("[SKIPPED] Logical unit is not removable"        \
117                         " Skipping test");                                \
118                 return;                                                        \
119         }                                                                \
120 } while (0);
121 
122 #define CHECK_FOR_THIN_PROVISIONING                                        \
123 do {                                                                        \
124         if (rc16 == NULL || rc16->lbpme == 0) {                                              \
125                 logging(LOG_NORMAL, "[SKIPPED] Logical unit is fully"        \
126                         " provisioned. Skipping test");                        \
127                 CU_PASS("[SKIPPED] Logical unit is fully provisioned."        \
128                         " Skipping test");                                \
129                 return;                                                             \
130         }                                                                \
131 } while (0);
132 
133 #define CHECK_FOR_LBPWS10                                                \
134 do {                                                                        \
135         if (inq_lbp->lbpws10 == 0) {                                               \
136                 logging(LOG_NORMAL, "[SKIPPED] Logical unit does not"        \
137                         " have LBPWS10. Skipping test");                \
138                 CU_PASS("[SKIPPED] Logical unit does not have LBPWS10."        \
139                         " Skipping test");                                \
140                 return;                                                             \
141         }                                                                \
142 } while (0);
143 
144 #define CHECK_FOR_LBPWS                                                        \
145 do {                                                                        \
146         if (inq_lbp->lbpws == 0) {                                               \
147                 logging(LOG_NORMAL, "[SKIPPED] Logical unit does not"        \
148                         " have LBPWS. Skipping test");                               \
149                 CU_PASS("[SKIPPED] Logical unit does not have LBPWS."        \
150                         " Skipping test");                                \
151                 return;                                                             \
152         }                                                                \
153 } while (0);
154 
155 #define CHECK_FOR_LBPU                                                        \
156 do {                                                                        \
157         if (inq_lbp->lbpu == 0) {                                               \
158                 logging(LOG_NORMAL, "[SKIPPED] Logical unit does not"        \
159                         " have LBPU. Skipping test");                               \
160                 CU_PASS("[SKIPPED] Logical unit does not have LBPU."        \
161                         " Skipping test");                                \
162                 return;                                                             \
163         }                                                                \
164 } while (0);
165 
166 #define CHECK_FOR_LBPPB_GT_1                                                \
167 do {                                                                        \
168         if (lbppb < 2) {                                                \
169           logging(LOG_NORMAL, "[SKIPPED] LBPPB < 2. Skipping test");        \
170                 CU_PASS("[SKIPPED] LBPPB < 2. Skipping test");                \
171                 return;                                                             \
172         }                                                                \
173 } while (0);
174 
175 #define CHECK_FOR_SBC                                                        \
176 do {                                                                        \
177         if (inq->device_type != SCSI_INQUIRY_PERIPHERAL_DEVICE_TYPE_DIRECT_ACCESS) {\
178                 logging(LOG_NORMAL, "[SKIPPED] Not SBC device."        \
179                         " Skipping test");                                \
180                 CU_PASS("[SKIPPED] Not SBC device."                        \
181                         " Skipping test");                                \
182                 return;                                                             \
183         }                                                                \
184 } while (0);
185 
186 #define CHECK_SIZE(_min_blocks, _c)                                     \
187         do {                                                            \
188                 if (num_blocks < _min_blocks) {                         \
189                         logging(LOG_VERBOSE, "[SKIPPED] "               \
190                                 "LUN too small. Skipping assert");      \
191                 } else {                                                \
192                         _c                                              \
193                 }                                                       \
194         } while (0);
195 
196 #define COMPAREANDWRITE(...)                                            \
197         do {                                                            \
198                 int _r;                                                 \
199                 _r = compareandwrite(__VA_ARGS__);                      \
200                 if (_r == -2) {                                         \
201                         logging(LOG_NORMAL, "[SKIPPED] COMPAREANDWRITE " \
202                                 "is not implemented.");                 \
203                         CU_PASS("[SKIPPED] Target does not support "    \
204                                 "COMPAREANDWRITE. Skipping test");      \
205                         return;                                         \
206                 }                                                       \
207                 CU_ASSERT_EQUAL(_r, 0);                                 \
208         } while (0);
209 
210 #define EXTENDEDCOPY(...)                                               \
211         do {                                                            \
212                 int _r;                                                 \
213                 _r = extendedcopy(__VA_ARGS__);                         \
214                 if (_r == -2) {                                         \
215                         logging(LOG_NORMAL, "[SKIPPED] EXTENDEDCOPY "   \
216                                 "is not implemented.");                 \
217                         CU_PASS("[SKIPPED] Target does not support "    \
218                                 "EXTENDEDCOPY. Skipping test");         \
219                         return;                                         \
220                 }                                                       \
221                 CU_ASSERT_EQUAL(_r, 0);                                 \
222         } while (0);
223 
224 #define GETLBASTATUS(...)                                               \
225         do {                                                            \
226                 int _r;                                                 \
227                 _r = get_lba_status(__VA_ARGS__);                       \
228                 if (_r == -2) {                                         \
229                         logging(LOG_NORMAL, "[SKIPPED] GETLBASTATUS "   \
230                                 "is not implemented.");                 \
231                         CU_PASS("[SKIPPED] Target does not support "    \
232                                 "GETLBASTATUS. Skipping test");         \
233                         return;                                         \
234                 }                                                       \
235                 CU_ASSERT_EQUAL(_r, 0);                                 \
236         } while (0);
237 
238 #define MODESENSE6(...)                                                 \
239         do {                                                            \
240                 int _r;                                                 \
241                 _r = modesense6(__VA_ARGS__);                           \
242                 if (_r == -2) {                                         \
243                         logging(LOG_NORMAL, "[SKIPPED] MODESENSE6 "     \
244                                 "is not implemented.");                 \
245                         CU_PASS("[SKIPPED] Target does not support "    \
246                                 "MODESENSE6. Skipping test");           \
247                         return;                                         \
248                 }                                                       \
249                 CU_ASSERT_EQUAL(_r, 0);                                 \
250         } while (0);
251 
252 #define ORWRITE(...)                                                    \
253         do {                                                            \
254                 int _r;                                                 \
255                 _r = orwrite(__VA_ARGS__);                              \
256                 if (_r == -2) {                                         \
257                         logging(LOG_NORMAL, "[SKIPPED] ORWRITE "        \
258                                 "is not implemented.");                 \
259                         CU_PASS("[SKIPPED] Target does not support "    \
260                                 "ORWRITE. Skipping test");              \
261                         return;                                         \
262                 }                                                       \
263                 CU_ASSERT_EQUAL(_r, 0);                                 \
264         } while (0);
265 
266 #define PREFETCH10(...)                                                 \
267         do {                                                            \
268                 int _r;                                                 \
269                 _r = prefetch10(__VA_ARGS__);                           \
270                 if (_r == -2) {                                         \
271                         logging(LOG_NORMAL, "[SKIPPED] PREFETCH10 "     \
272                                 "is not implemented.");                 \
273                         CU_PASS("[SKIPPED] Target does not support "    \
274                                 "PREFETCH10. Skipping test");           \
275                         return;                                         \
276                 }                                                       \
277                 CU_ASSERT_EQUAL(_r, 0);                                 \
278         } while (0);
279 
280 #define PREFETCH16(...)                                                 \
281         do {                                                            \
282                 int _r;                                                 \
283                 _r = prefetch16(__VA_ARGS__);                           \
284                 if (_r == -2) {                                         \
285                         logging(LOG_NORMAL, "[SKIPPED] PREFETCH16 "     \
286                                 "is not implemented.");                 \
287                         CU_PASS("[SKIPPED] Target does not support "    \
288                                 "PREFETCH16. Skipping test");           \
289                         return;                                         \
290                 }                                                       \
291                 CU_ASSERT_EQUAL(_r, 0);                                 \
292         } while (0);
293 
294 #define PREVENTALLOW(...)                                               \
295         do {                                                            \
296                 int _r;                                                 \
297                 _r = preventallow(__VA_ARGS__);                         \
298                 if (_r == -2) {                                         \
299                         logging(LOG_NORMAL, "[SKIPPED] PREVENTALLOW "   \
300                                 "is not implemented.");                 \
301                         CU_PASS("[SKIPPED] Target does not support "    \
302                                 "PREVENTALLOW. Skipping test");         \
303                         return;                                         \
304                 }                                                       \
305                 CU_ASSERT_EQUAL(_r, 0);                                 \
306         } while (0);
307 
308 #define READ6(...)                                                      \
309         do {                                                            \
310                 int _r;                                                 \
311                 _r = read6(__VA_ARGS__);                                \
312                 if (_r == -2) {                                         \
313                         logging(LOG_NORMAL, "[SKIPPED] READ6 "          \
314                                 "is not implemented.");                 \
315                         CU_PASS("[SKIPPED] Target does not support "    \
316                                 "READ6. Skipping test");                \
317                         return;                                         \
318                 }                                                       \
319                 CU_ASSERT_EQUAL(_r, 0);                                 \
320         } while (0);
321 
322 #define READ10(...)                                                     \
323         ({								\
324                 int _r;                                                 \
325                 _r = read10(__VA_ARGS__);                               \
326                 if (_r == -2) {                                         \
327                         logging(LOG_NORMAL, "[SKIPPED] READ10 "         \
328                                 "is not implemented.");                 \
329                         CU_PASS("[SKIPPED] Target does not support "    \
330                                 "READ10. Skipping test");               \
331                         return;                                         \
332                 }                                                       \
333                 CU_ASSERT_EQUAL(_r, 0);                                 \
334 		_r;							\
335         })
336 
337 #define READ12(...)                                                     \
338         do {                                                            \
339                 int _r;                                                 \
340                 _r = read12(__VA_ARGS__);                               \
341                 if (_r == -2) {                                         \
342                         logging(LOG_NORMAL, "[SKIPPED] READ12 "         \
343                                 "is not implemented.");                 \
344                         CU_PASS("[SKIPPED] Target does not support "    \
345                                 "READ12. Skipping test");               \
346                         return;                                         \
347                 }                                                       \
348                 CU_ASSERT_EQUAL(_r, 0);                                 \
349         } while (0);
350 
351 #define READ16(...)                                                     \
352         do {                                                            \
353                 int _r;                                                 \
354                 _r = read16(__VA_ARGS__);                               \
355                 if (_r == -2) {                                         \
356                         logging(LOG_NORMAL, "[SKIPPED] READ16 "         \
357                                 "is not implemented.");                 \
358                         CU_PASS("[SKIPPED] Target does not support "    \
359                                 "READ16. Skipping test");               \
360                         return;                                         \
361                 }                                                       \
362                 CU_ASSERT_EQUAL(_r, 0);                                 \
363         } while (0);
364 
365 #define READCAPACITY10(...)                                             \
366         do {                                                            \
367                 int _r;                                                 \
368                 _r = readcapacity10(__VA_ARGS__);                       \
369                 if (_r == -2) {                                         \
370                         logging(LOG_NORMAL, "[SKIPPED] READCAPACITY10 " \
371                                 "is not implemented.");                 \
372                         CU_PASS("[SKIPPED] Target does not support "    \
373                                 "READCAPACITY10. Skipping test");       \
374                         return;                                         \
375                 }                                                       \
376                 CU_ASSERT_EQUAL(_r, 0);                                 \
377         } while (0);
378 
379 #define READCAPACITY16(...)                                             \
380         do {                                                            \
381                 int _r;                                                 \
382                 _r = readcapacity16(__VA_ARGS__);                       \
383                 if (_r == -2) {                                         \
384                         logging(LOG_NORMAL, "[SKIPPED] READCAPACITY16 " \
385                                 "is not implemented.");                 \
386                         CU_PASS("[SKIPPED] Target does not support "    \
387                                 "READCAPACITY16. Skipping test");       \
388                         return;                                         \
389                 }                                                       \
390                 CU_ASSERT_EQUAL(_r, 0);                                 \
391         } while (0);
392 
393 #define READDEFECTDATA10(...)                                           \
394         do {                                                            \
395                 int _r;                                                 \
396                 _r = readdefectdata10(__VA_ARGS__);                     \
397                 if (_r == -2) {                                         \
398                         logging(LOG_NORMAL, "[SKIPPED] READDEFECTDATA10 " \
399                                 "is not implemented.");                 \
400                         CU_PASS("[SKIPPED] Target does not support "    \
401                                 "READDEFECTDATA10. Skipping test");     \
402                         return;                                         \
403                 }                                                       \
404                 CU_ASSERT_EQUAL(_r, 0);                                 \
405         } while (0);
406 
407 #define READDEFECTDATA12(...)                                           \
408         do {                                                            \
409                 int _r;                                                 \
410                 _r = readdefectdata12(__VA_ARGS__);                     \
411                 if (_r == -2) {                                         \
412                         logging(LOG_NORMAL, "[SKIPPED] READDEFECTDATA12 " \
413                                 "is not implemented.");                 \
414                         CU_PASS("[SKIPPED] Target does not support "    \
415                                 "READDEFECTDATA12. Skipping test");     \
416                         return;                                         \
417                 }                                                       \
418                 CU_ASSERT_EQUAL(_r, 0);                                 \
419         } while (0);
420 
421 #define RECEIVE_COPY_RESULTS(...)                                       \
422         ({								\
423                 int _r;                                                 \
424                 _r = receive_copy_results(__VA_ARGS__);                 \
425                 if (_r == -2) {                                         \
426                         logging(LOG_NORMAL, "[SKIPPED] RECEIVE_COPY"    \
427                                 "_RESULTS is not implemented.");        \
428                         CU_PASS("[SKIPPED] Target does not support "    \
429                                 "RECEIVE_COPY_RESULTS. Skipping test"); \
430                         return;                                         \
431                 }                                                       \
432                 CU_ASSERT_EQUAL(_r, 0);                                 \
433 		_r;							\
434         })
435 
436 #define RELEASE6(...)                                                   \
437         do {                                                            \
438                 int _r;                                                 \
439                 _r = release6(__VA_ARGS__);                             \
440                 if (_r == -2) {                                         \
441                         logging(LOG_NORMAL, "[SKIPPED] RELEASE6 "       \
442                                 "is not implemented.");                 \
443                         CU_PASS("[SKIPPED] Target does not support "    \
444                                 "RELEASE6. Skipping test");             \
445                         return;                                         \
446                 }                                                       \
447                 CU_ASSERT_EQUAL(_r, 0);                                 \
448         } while (0);
449 
450 #define REPORT_SUPPORTED_OPCODES(...)                                   \
451         do {                                                            \
452                 int _r;                                                 \
453                 _r = report_supported_opcodes(__VA_ARGS__);             \
454                 if (_r == -2) {                                         \
455                         logging(LOG_NORMAL, "[SKIPPED] REPORT_SUPPORTED" \
456                                 "_OPCODES is not implemented.");        \
457                         CU_PASS("[SKIPPED] Target does not support "    \
458                                 "REPORT_SUPPORTED_OPCODES. Skipping "   \
459                                 "test");                                \
460                         return;                                         \
461                 }                                                       \
462                 CU_ASSERT_EQUAL(_r, 0);                                 \
463         } while (0);
464 
465 #define RESERVE6(...)                                                   \
466         do {                                                            \
467                 int _r;                                                 \
468                 _r = reserve6(__VA_ARGS__);                             \
469                 if (_r == -2) {                                         \
470                         logging(LOG_NORMAL, "[SKIPPED] RESERVE6 "       \
471                                 "is not implemented.");                 \
472                         CU_PASS("[SKIPPED] Target does not support "    \
473                                 "RESERVE6. Skipping test");             \
474                         return;                                         \
475                 }                                                       \
476                 CU_ASSERT_EQUAL(_r, 0);                                 \
477         } while (0);
478 
479 #define SANITIZE(...)                                                   \
480         do {                                                            \
481                 int _r;                                                 \
482                 _r = sanitize(__VA_ARGS__);                             \
483                 if (_r == -2) {                                         \
484                         logging(LOG_NORMAL, "[SKIPPED] SANITIZE "       \
485                                 "is not implemented.");                 \
486                         CU_PASS("[SKIPPED] Target does not support "    \
487                                 "SANITIZE. Skipping test");             \
488                         return;                                         \
489                 }                                                       \
490                 CU_ASSERT_EQUAL(_r, 0);                                 \
491         } while (0);
492 
493 #define STARTSTOPUNIT(...)                                              \
494         do {                                                            \
495                 int _r;                                                 \
496                 _r = startstopunit(__VA_ARGS__);                        \
497                 if (_r == -2) {                                         \
498                         logging(LOG_NORMAL, "[SKIPPED] STARTSTOPUNIT "  \
499                                 "is not implemented.");                 \
500                         CU_PASS("[SKIPPED] Target does not support "    \
501                                 "STARTSTOPUNIT. Skipping test");        \
502                         return;                                         \
503                 }                                                       \
504                 CU_ASSERT_EQUAL(_r, 0);                                 \
505         } while (0);
506 
507 #define SYNCHRONIZECACHE10(...)                                         \
508         do {                                                            \
509                 int _r;                                                 \
510                 _r = synchronizecache10(__VA_ARGS__);                   \
511                 if (_r == -2) {                                         \
512                         logging(LOG_NORMAL, "[SKIPPED] SYNCHRONIZECACHE10 "  \
513                                 "is not implemented.");                 \
514                         CU_PASS("[SKIPPED] Target does not support "    \
515                                 "SYNCHRONIZECACHE10. Skipping test");   \
516                         return;                                         \
517                 }                                                       \
518                 CU_ASSERT_EQUAL(_r, 0);                                 \
519         } while (0);
520 
521 #define SYNCHRONIZECACHE16(...)                                         \
522         do {                                                            \
523                 int _r;                                                 \
524                 _r = synchronizecache16(__VA_ARGS__);                   \
525                 if (_r == -2) {                                         \
526                         logging(LOG_NORMAL, "[SKIPPED] SYNCHRONIZECACHE16 "  \
527                                 "is not implemented.");                 \
528                         CU_PASS("[SKIPPED] Target does not support "    \
529                                 "SYNCHRONIZECACHE16. Skipping test");   \
530                         return;                                         \
531                 }                                                       \
532                 CU_ASSERT_EQUAL(_r, 0);                                 \
533         } while (0);
534 
535 #define TESTUNITREADY(...)                                              \
536         do {                                                            \
537                 int _r;                                                 \
538                 _r = testunitready(__VA_ARGS__);                        \
539                 if (_r == -2) {                                         \
540                         logging(LOG_NORMAL, "[SKIPPED] TESTUNITREADY "  \
541                                 "is not implemented.");                 \
542                         CU_PASS("[SKIPPED] Target does not support "    \
543                                 "TESTUNITREADY. Skipping test");        \
544                         return;                                         \
545                 }                                                       \
546                 CU_ASSERT_EQUAL(_r, 0);                                 \
547         } while (0);
548 
549 #define UNMAP(...)                                                      \
550         do {                                                            \
551                 int _r;                                                 \
552                 _r = unmap(__VA_ARGS__);                                \
553                 if (_r == -2) {                                         \
554                         logging(LOG_NORMAL, "[SKIPPED] UNMAP "          \
555                                 "is not implemented.");                 \
556                         CU_PASS("[SKIPPED] Target does not support "    \
557                                 "UNMAP. Skipping test");                \
558                         return;                                         \
559                 }                                                       \
560                 CU_ASSERT_EQUAL(_r, 0);                                 \
561         } while (0);
562 
563 #define VERIFY10(...)                                                   \
564         do {                                                            \
565                 int _r;                                                 \
566                 _r = verify10(__VA_ARGS__);                             \
567                 if (_r == -2) {                                         \
568                         logging(LOG_NORMAL, "[SKIPPED] VERIFY10 "       \
569                                 "is not implemented.");                 \
570                         CU_PASS("[SKIPPED] Target does not support "    \
571                                 "VERIFY10. Skipping test");             \
572                         return;                                         \
573                 }                                                       \
574                 CU_ASSERT_EQUAL(_r, 0);                                 \
575         } while (0);
576 
577 #define VERIFY12(...)                                                   \
578         do {                                                            \
579                 int _r;                                                 \
580                 _r = verify12(__VA_ARGS__);                             \
581                 if (_r == -2) {                                         \
582                         logging(LOG_NORMAL, "[SKIPPED] VERIFY12 "       \
583                                 "is not implemented.");                 \
584                         CU_PASS("[SKIPPED] Target does not support "    \
585                                 "VERIFY12. Skipping test");             \
586                         return;                                         \
587                 }                                                       \
588                 CU_ASSERT_EQUAL(_r, 0);                                 \
589         } while (0);
590 
591 #define VERIFY16(...)                                                   \
592         do {                                                            \
593                 int _r;                                                 \
594                 _r = verify16(__VA_ARGS__);                             \
595                 if (_r == -2) {                                         \
596                         logging(LOG_NORMAL, "[SKIPPED] VERIFY16 "       \
597                                 "is not implemented.");                 \
598                         CU_PASS("[SKIPPED] Target does not support "    \
599                                 "VERIFY16. Skipping test");             \
600                         return;                                         \
601                 }                                                       \
602                 CU_ASSERT_EQUAL(_r, 0);                                 \
603         } while (0);
604 
605 #define WRITE10(...)                                                    \
606         ({								\
607                 int _r;                                                 \
608                 _r = write10(__VA_ARGS__);                              \
609                 if (_r == -2) {                                         \
610                         logging(LOG_NORMAL, "[SKIPPED] WRITE10 "        \
611                                 "is not implemented.");                 \
612                         CU_PASS("[SKIPPED] Target does not support "    \
613                                 "WRITE10. Skipping test");              \
614                         return;                                         \
615                 }                                                       \
616                 CU_ASSERT_EQUAL(_r, 0);                                 \
617 		_r;							\
618         })
619 
620 #define WRITE12(...)                                                    \
621         do {                                                            \
622                 int _r;                                                 \
623                 _r = write12(__VA_ARGS__);                              \
624                 if (_r == -2) {                                         \
625                         logging(LOG_NORMAL, "[SKIPPED] WRITE12 "        \
626                                 "is not implemented.");                 \
627                         CU_PASS("[SKIPPED] Target does not support "    \
628                                 "WRITE12. Skipping test");              \
629                         return;                                         \
630                 }                                                       \
631                 CU_ASSERT_EQUAL(_r, 0);                                 \
632         } while (0);
633 
634 #define WRITE16(...)                                                    \
635         do {                                                            \
636                 int _r;                                                 \
637                 _r = write16(__VA_ARGS__);                              \
638                 if (_r == -2) {                                         \
639                         logging(LOG_NORMAL, "[SKIPPED] WRITE16 "        \
640                                 "is not implemented.");                 \
641                         CU_PASS("[SKIPPED] Target does not support "    \
642                                 "WRITE16. Skipping test");              \
643                         return;                                         \
644                 }                                                       \
645                 CU_ASSERT_EQUAL(_r, 0);                                 \
646         } while (0);
647 
648 #define WRITEATOMIC16(...)                                              \
649         do {                                                            \
650                 int _r;                                                 \
651                 _r = writeatomic16(__VA_ARGS__);                        \
652                 if (_r == -2) {                                         \
653                         logging(LOG_NORMAL, "[SKIPPED] WRITEATOMIC16 "  \
654                                 "is not implemented.");                 \
655                         CU_PASS("[SKIPPED] Target does not support "    \
656                                 "WRITEATOMIC16. Skipping test");        \
657                         return;                                         \
658                 }                                                       \
659                 CU_ASSERT_EQUAL(_r, 0);                                 \
660         } while (0);
661 
662 #define WRITESAME10(...)                                                \
663         do {                                                            \
664                 int _r;                                                 \
665                 _r = writesame10(__VA_ARGS__);                          \
666                 if (_r == -2) {                                         \
667                         logging(LOG_NORMAL, "[SKIPPED] WRITESAME10 "    \
668                                 "is not implemented.");                 \
669                         CU_PASS("[SKIPPED] Target does not support "    \
670                                 "WRITESAME10. Skipping test");          \
671                         return;                                         \
672                 }                                                       \
673                 CU_ASSERT_EQUAL(_r, 0);                                 \
674         } while (0);
675 
676 #define WRITESAME16(...)                                                \
677         do {                                                            \
678                 int _r;                                                 \
679                 _r = writesame16(__VA_ARGS__);                          \
680                 if (_r == -2) {                                         \
681                         logging(LOG_NORMAL, "[SKIPPED] WRITESAME16 "    \
682                                 "is not implemented.");                 \
683                         CU_PASS("[SKIPPED] Target does not support "    \
684                                 "WRITESAME16. Skipping test");          \
685                         return;                                         \
686                 }                                                       \
687                 CU_ASSERT_EQUAL(_r, 0);                                 \
688         } while (0);
689 
690 #define WRITEVERIFY10(...)                                              \
691         do {                                                            \
692                 int _r;                                                 \
693                 _r = writeverify10(__VA_ARGS__);                        \
694                 if (_r == -2) {                                         \
695                         logging(LOG_NORMAL, "[SKIPPED] WRITEVERIFY10 "  \
696                                 "is not implemented.");                 \
697                         CU_PASS("[SKIPPED] Target does not support "    \
698                                 "WRITEVERIFY10. Skipping test");        \
699                         return;                                         \
700                 }                                                       \
701                 CU_ASSERT_EQUAL(_r, 0);                                 \
702         } while (0);
703 
704 #define WRITEVERIFY12(...)                                              \
705         do {                                                            \
706                 int _r;                                                 \
707                 _r = writeverify12(__VA_ARGS__);                        \
708                 if (_r == -2) {                                         \
709                         logging(LOG_NORMAL, "[SKIPPED] WRITEVERIFY12 "  \
710                                 "is not implemented.");                 \
711                         CU_PASS("[SKIPPED] Target does not support "    \
712                                 "WRITEVERIFY12. Skipping test");        \
713                         return;                                         \
714                 }                                                       \
715                 CU_ASSERT_EQUAL(_r, 0);                                 \
716         } while (0);
717 
718 #define WRITEVERIFY16(...)                                              \
719         do {                                                            \
720                 int _r;                                                 \
721                 _r = writeverify16(__VA_ARGS__);                        \
722                 if (_r == -2) {                                         \
723                         logging(LOG_NORMAL, "[SKIPPED] WRITEVERIFY16 "  \
724                                 "is not implemented.");                 \
725                         CU_PASS("[SKIPPED] Target does not support "    \
726                                 "WRITEVERIFY16. Skipping test");        \
727                         return;                                         \
728                 }                                                       \
729                 CU_ASSERT_EQUAL(_r, 0);                                 \
730         } while (0);
731 
732 #define ALL_ZERO(...)                                                   \
733         do {                                                            \
734                 if (all_zero(__VA_ARGS__) == 0) {                       \
735                         logging(LOG_NORMAL, "[FAILED] Blocks did not "  \
736                                 "read back as zero");                   \
737                         CU_FAIL("[FAILED] Blocks did not read back "    \
738                                 "as zero");                             \
739                         return;                                         \
740                 }                                                       \
741         } while (0);
742 
743 extern struct scsi_inquiry_standard *inq;
744 extern struct scsi_inquiry_logical_block_provisioning *inq_lbp;
745 extern struct scsi_inquiry_block_device_characteristics *inq_bdc;
746 extern struct scsi_inquiry_block_limits *inq_bl;
747 extern struct scsi_readcapacity16 *rc16;
748 extern struct scsi_report_supported_op_codes *rsop;
749 
750 extern unsigned char *scratch;
751 extern size_t block_size;
752 extern uint64_t num_blocks;
753 extern int lbppb;
754 extern int data_loss;
755 extern int allow_sanitize;
756 extern int readonly;
757 extern int sbc3_support;
758 extern int maximum_transfer_length;
759 
760 struct scsi_device {
761         char *error_str;
762 
763         struct iscsi_context *iscsi_ctx;
764         int iscsi_lun;
765         char *iscsi_url;
766 
767         char *sgio_dev;
768         int sgio_fd;
769 };
770 extern struct scsi_device *sd;
771 
772 struct iscsi_context *iscsi_context_login(const char *initiatorname, const char *url, int *lun);
773 
774 struct iscsi_async_state {
775         struct scsi_task *task;
776         int status;
777         int finished;
778 };
779 void wait_until_test_finished(struct iscsi_context *iscsi, struct iscsi_async_state *test_state);
780 
781 struct iscsi_pdu;
782 int (*local_iscsi_queue_pdu)(struct iscsi_context *iscsi, struct iscsi_pdu *pdu);
783 
784 struct scsi_command_descriptor *get_command_descriptor(int opcode, int sa);
785 
786 /*
787  * PGR support
788  */
789 
rand_key(void)790 static inline long rand_key(void)
791 {
792         static int seed = 0;
793 
794         if (!seed) {
795                 struct timeval tv;
796                 pid_t p;
797                 unsigned int s;
798 
799                 gettimeofday(&tv, NULL);
800                 p = getpid();
801                 s = p ^ tv.tv_sec ^ tv.tv_usec;
802                 srandom(s);
803         }
804         seed = 1;
805         return random();
806 }
807 
pr_type_is_all_registrants(enum scsi_persistent_out_type pr_type)808 static inline int pr_type_is_all_registrants(
809         enum scsi_persistent_out_type pr_type)
810 {
811         switch (pr_type) {
812         case SCSI_PERSISTENT_RESERVE_TYPE_WRITE_EXCLUSIVE_ALL_REGISTRANTS:
813         case SCSI_PERSISTENT_RESERVE_TYPE_EXCLUSIVE_ACCESS_ALL_REGISTRANTS:
814                 return 1;
815         default:
816                 return 0;
817         }
818 }
819 
820 int all_zero(const unsigned char *buf, unsigned size);
821 
822 int prin_task(struct scsi_device *sdev, int service_action,
823     int success_expected);
824 int prin_read_keys(struct scsi_device *sdev, struct scsi_task **tp,
825                    struct scsi_persistent_reserve_in_read_keys **rkp,
826                    uint16_t allocation_len);
827 int prout_register_and_ignore(struct scsi_device *sdev,
828     unsigned long long key);
829 int prout_register_key(struct scsi_device *sdev,
830     unsigned long long sark, unsigned long long rk);
831 int prin_verify_key_presence(struct scsi_device *sdev,
832     unsigned long long key, int present);
833 int prout_reregister_key_fails(struct scsi_device *sdev,
834     unsigned long long sark);
835 int prout_reserve(struct scsi_device *sdev,
836     unsigned long long key, enum scsi_persistent_out_type pr_type);
837 int prout_release(struct scsi_device *sdev,
838     unsigned long long key, enum scsi_persistent_out_type pr_type);
839 int prout_clear(struct scsi_device *sdev, unsigned long long key);
840 int prout_preempt(struct scsi_device *sdev,
841                   unsigned long long sark, unsigned long long rk,
842                   enum scsi_persistent_out_type pr_type);
843 int prin_verify_not_reserved(struct scsi_device *sdev);
844 int prin_verify_reserved_as(struct scsi_device *sdev,
845     unsigned long long key, enum scsi_persistent_out_type pr_type);
846 int prin_report_caps(struct scsi_device *sdev, struct scsi_task **tp,
847         struct scsi_persistent_reserve_in_report_capabilities **_rcaps);
848 int verify_read_works(struct scsi_device *sdev, unsigned char *buf);
849 int verify_write_works(struct scsi_device *sdev, unsigned char *buf);
850 int verify_read_fails(struct scsi_device *sdev, unsigned char *buf);
851 int verify_write_fails(struct scsi_device *sdev, unsigned char *buf);
852 
853 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);
854 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);
855 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);
856 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);
857 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);
858 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);
859 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);
860 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);
861 int preventallow(struct scsi_device *sdev, int prevent);
862 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);
863 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);
864 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);
865 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);
866 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);
867 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);
868 int readdefectdata10(struct scsi_device *sdev, struct scsi_task **task,
869                      int req_plist, int req_glist,
870                      int defect_list_format, uint16_t alloc_len,
871                      int status, enum scsi_sense_key key,
872                      int *ascq, int num_ascq);
873 int readdefectdata12(struct scsi_device *sdev, struct scsi_task **task,
874                      int req_plist, int req_glist,
875                      int defect_list_format,
876                      uint32_t address_descriptor_index,
877                      uint32_t alloc_len,
878                      int status, enum scsi_sense_key key,
879                      int *ascq, int num_ascq);
880 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);
881 int release6(struct scsi_device *sdev);
882 int reserve6(struct scsi_device *sdev);
883 int reserve6_conflict(struct scsi_device *sdev);
884 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);
885 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);
886 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);
887 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);
888 int testunitready_clear_ua(struct scsi_device *sdev);
889 int testunitready(struct scsi_device *sdev, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
890 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);
891 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);
892 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);
893 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);
894 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);
895 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);
896 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);
897 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);
898 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);
899 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);
900 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);
901 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);
902 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);
903 
904 int set_swp(struct scsi_device *sdev);
905 int clear_swp(struct scsi_device *sdev);
906 
907 int extendedcopy(struct scsi_device *sdev, struct iscsi_data *data, int status, enum scsi_sense_key key, int *ascq, int num_ascq);
908 int get_desc_len(enum ec_descr_type_code desc_type);
909 int populate_tgt_desc(unsigned char *desc, enum ec_descr_type_code desc_type, int luid_type, int nul, int peripheral_type, int rel_init_port_id, int pad, struct scsi_device *dev);
910 int populate_seg_desc_hdr(unsigned char *hdr, enum ec_descr_type_code desc_type, int dc, int cat, int src_index, int dst_index);
911 int populate_seg_desc_b2b(unsigned char *desc, int dc, int cat, int src_index, int dst_index, int num_blks, uint64_t src_lba, uint64_t dst_lba);
912 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);
913 int receive_copy_results(struct scsi_task **task, struct scsi_device *sdev,
914                          enum scsi_copy_results_sa sa, int list_id,
915                          void **datap, int status, enum scsi_sense_key key,
916                          int *ascq, int num_ascq);
917 int test_iscsi_tur_until_good(struct scsi_device *iscsi_sd, int *num_uas);
918 
919 uint64_t test_get_clock_sec(void);
920 
921 #endif        /* _ISCSI_SUPPORT_H_ */
922