4 * Copyright (c) Intel Corporation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include "spdk/stdinc.h"
36 #include "scsi/port.c"
37 #include "scsi/scsi_pr.c"
39 #include "spdk_cunit.h"
41 #include "spdk_internal/mock.h"
43 SPDK_LOG_REGISTER_COMPONENT("scsi", SPDK_LOG_SCSI
)
46 spdk_scsi_task_set_status(struct spdk_scsi_task
*task
, int sc
, int sk
,
53 * Reservation Unit Test Configuration
55 * -------- -------- -------
56 * | Host A | | Host B | | Host C|
57 * -------- -------- -------
59 * ------ ------ ------
60 * |Port A| |Port B| |Port C|
61 * ------ ------ ------
65 * ------------------------
66 * | Target Node 1 Port 0 |
67 * ------------------------
69 * ----------------------------------
71 * ----------------------------------
79 static struct spdk_scsi_lun g_lun
;
80 static struct spdk_scsi_port g_i_port_a
;
81 static struct spdk_scsi_port g_i_port_b
;
82 static struct spdk_scsi_port g_i_port_c
;
83 static struct spdk_scsi_port g_t_port_0
;
88 struct spdk_scsi_pr_registrant
*reg
, *tmp
;
90 TAILQ_FOREACH_SAFE(reg
, &g_lun
.reg_head
, link
, tmp
) {
91 TAILQ_REMOVE(&g_lun
.reg_head
, reg
, link
);
94 g_lun
.reservation
.rtype
= 0;
95 g_lun
.reservation
.crkey
= 0;
96 g_lun
.reservation
.holder
= NULL
;
97 g_lun
.pr_generation
= 0;
106 rc
= spdk_scsi_port_construct(&g_i_port_a
, 0xa, 0,
107 "iqn.2016-06.io.spdk:fe5aacf7420a,i,0x00023d00000a");
108 SPDK_CU_ASSERT_FATAL(rc
== 0);
109 spdk_scsi_port_set_iscsi_transport_id(&g_i_port_a
,
110 "iqn.2016-06.io.spdk:fe5aacf7420a", 0x00023d00000a);
112 rc
= spdk_scsi_port_construct(&g_i_port_b
, 0xb, 0,
113 "iqn.2016-06.io.spdk:fe5aacf7420b,i,0x00023d00000b");
114 SPDK_CU_ASSERT_FATAL(rc
== 0);
115 spdk_scsi_port_set_iscsi_transport_id(&g_i_port_b
,
116 "iqn.2016-06.io.spdk:fe5aacf7420b", 0x00023d00000b);
118 rc
= spdk_scsi_port_construct(&g_i_port_c
, 0xc, 0,
119 "iqn.2016-06.io.spdk:fe5aacf7420c,i,0x00023d00000c");
120 SPDK_CU_ASSERT_FATAL(rc
== 0);
121 spdk_scsi_port_set_iscsi_transport_id(&g_i_port_c
,
122 "iqn.2016-06.io.spdk:fe5aacf7420c", 0x00023d00000c);
124 rc
= spdk_scsi_port_construct(&g_t_port_0
, 0x0, 1,
125 "iqn.2016-06.io.spdk:fe5aacf74200,t,0x00023d000000");
126 SPDK_CU_ASSERT_FATAL(rc
== 0);
127 spdk_scsi_port_set_iscsi_transport_id(&g_t_port_0
,
128 "iqn.2016-06.io.spdk:fe5aacf74200", 0x00023d000000);
134 TAILQ_INIT(&g_lun
.reg_head
);
138 ut_init_reservation_test(void)
146 ut_deinit_reservation_test(void)
151 /* Host A: register with key 0xa.
152 * Host B: register with key 0xb.
153 * Host C: register with key 0xc.
156 test_build_registrants(void)
158 struct spdk_scsi_pr_registrant
*reg
;
159 struct spdk_scsi_task task
= {0};
164 task
.target_port
= &g_t_port_0
;
166 gen
= g_lun
.pr_generation
;
168 /* I_T nexus: Initiator Port A to Target Port 0 */
169 task
.initiator_port
= &g_i_port_a
;
170 /* Test Case: Host A registers with a new key */
172 rc
= spdk_scsi_pr_out_register(&task
, SPDK_SCSI_PR_OUT_REGISTER
,
174 SPDK_CU_ASSERT_FATAL(rc
== 0);
175 reg
= spdk_scsi_pr_get_registrant(&g_lun
, &g_i_port_a
, &g_t_port_0
);
176 SPDK_CU_ASSERT_FATAL(reg
!= NULL
);
177 SPDK_CU_ASSERT_FATAL(reg
->rkey
== 0xa1);
178 SPDK_CU_ASSERT_FATAL(g_lun
.pr_generation
== gen
+ 1);
180 /* Test Case: Host A replaces with a new key */
182 rc
= spdk_scsi_pr_out_register(&task
, SPDK_SCSI_PR_OUT_REGISTER
,
184 SPDK_CU_ASSERT_FATAL(rc
== 0);
185 reg
= spdk_scsi_pr_get_registrant(&g_lun
, &g_i_port_a
, &g_t_port_0
);
186 SPDK_CU_ASSERT_FATAL(reg
!= NULL
);
187 SPDK_CU_ASSERT_FATAL(reg
->rkey
== 0xa);
188 SPDK_CU_ASSERT_FATAL(g_lun
.pr_generation
== gen
+ 2);
190 /* Test Case: Host A replaces with a new key, reservation conflict is expected */
192 rc
= spdk_scsi_pr_out_register(&task
, SPDK_SCSI_PR_OUT_REGISTER
,
193 0xa1, 0xdead, 0, 0, 0);
194 SPDK_CU_ASSERT_FATAL(rc
< 0);
195 reg
= spdk_scsi_pr_get_registrant(&g_lun
, &g_i_port_a
, &g_t_port_0
);
196 SPDK_CU_ASSERT_FATAL(reg
!= NULL
);
197 SPDK_CU_ASSERT_FATAL(reg
->rkey
== 0xa);
198 SPDK_CU_ASSERT_FATAL(g_lun
.pr_generation
== gen
+ 2);
199 SPDK_CU_ASSERT_FATAL(task
.status
== SPDK_SCSI_STATUS_RESERVATION_CONFLICT
);
201 /* I_T nexus: Initiator Port B to Target Port 0 */
202 task
.initiator_port
= &g_i_port_b
;
203 /* Test Case: Host B registers with a new key */
205 rc
= spdk_scsi_pr_out_register(&task
, SPDK_SCSI_PR_OUT_REGISTER
,
207 SPDK_CU_ASSERT_FATAL(rc
== 0);
208 reg
= spdk_scsi_pr_get_registrant(&g_lun
, &g_i_port_b
, &g_t_port_0
);
209 SPDK_CU_ASSERT_FATAL(reg
!= NULL
);
210 SPDK_CU_ASSERT_FATAL(reg
->rkey
== 0xb);
211 SPDK_CU_ASSERT_FATAL(g_lun
.pr_generation
== gen
+ 3);
213 /* I_T nexus: Initiator Port C to Target Port 0 */
214 task
.initiator_port
= &g_i_port_c
;
215 /* Test Case: Host C registers with a new key */
217 rc
= spdk_scsi_pr_out_register(&task
, SPDK_SCSI_PR_OUT_REGISTER
,
219 SPDK_CU_ASSERT_FATAL(rc
== 0);
220 reg
= spdk_scsi_pr_get_registrant(&g_lun
, &g_i_port_c
, &g_t_port_0
);
221 SPDK_CU_ASSERT_FATAL(reg
!= NULL
);
222 SPDK_CU_ASSERT_FATAL(reg
->rkey
== 0xc);
223 SPDK_CU_ASSERT_FATAL(g_lun
.pr_generation
== gen
+ 4);
227 test_reservation_register(void)
229 ut_init_reservation_test();
231 test_build_registrants();
233 ut_deinit_reservation_test();
237 test_reservation_reserve(void)
239 struct spdk_scsi_pr_registrant
*reg
;
240 struct spdk_scsi_task task
= {0};
245 task
.target_port
= &g_t_port_0
;
247 ut_init_reservation_test();
248 test_build_registrants();
250 gen
= g_lun
.pr_generation
;
252 task
.initiator_port
= &g_i_port_a
;
254 /* Test Case: Host A acquires the reservation */
255 rc
= spdk_scsi_pr_out_reserve(&task
, SPDK_SCSI_PR_WRITE_EXCLUSIVE
,
257 SPDK_CU_ASSERT_FATAL(rc
== 0);
258 SPDK_CU_ASSERT_FATAL(g_lun
.reservation
.rtype
== SPDK_SCSI_PR_WRITE_EXCLUSIVE
);
259 SPDK_CU_ASSERT_FATAL(g_lun
.reservation
.crkey
== 0xa);
260 SPDK_CU_ASSERT_FATAL(g_lun
.pr_generation
== gen
);
262 /* Test Case: Host B acquires the reservation, reservation
263 * conflict is expected.
265 task
.initiator_port
= &g_i_port_b
;
267 rc
= spdk_scsi_pr_out_reserve(&task
, SPDK_SCSI_PR_WRITE_EXCLUSIVE
,
269 SPDK_CU_ASSERT_FATAL(rc
< 0);
270 SPDK_CU_ASSERT_FATAL(task
.status
== SPDK_SCSI_STATUS_RESERVATION_CONFLICT
);
271 SPDK_CU_ASSERT_FATAL(g_lun
.reservation
.rtype
== SPDK_SCSI_PR_WRITE_EXCLUSIVE
);
272 SPDK_CU_ASSERT_FATAL(g_lun
.reservation
.crkey
== 0xa);
273 SPDK_CU_ASSERT_FATAL(g_lun
.pr_generation
== gen
);
275 /* Test Case: Host A unregister with reservation */
276 task
.initiator_port
= &g_i_port_a
;
278 rc
= spdk_scsi_pr_out_register(&task
, SPDK_SCSI_PR_OUT_REGISTER
,
280 SPDK_CU_ASSERT_FATAL(rc
== 0);
281 SPDK_CU_ASSERT_FATAL(g_lun
.reservation
.rtype
== 0);
282 SPDK_CU_ASSERT_FATAL(g_lun
.reservation
.crkey
== 0);
283 SPDK_CU_ASSERT_FATAL(g_lun
.pr_generation
== gen
+ 1);
284 reg
= spdk_scsi_pr_get_registrant(&g_lun
, &g_i_port_a
, &g_t_port_0
);
285 SPDK_CU_ASSERT_FATAL(reg
== NULL
);
287 /* Test Case: Host B acquires the reservation */
288 task
.initiator_port
= &g_i_port_b
;
290 rc
= spdk_scsi_pr_out_reserve(&task
, SPDK_SCSI_PR_WRITE_EXCLUSIVE_ALL_REGS
,
292 SPDK_CU_ASSERT_FATAL(rc
== 0);
293 SPDK_CU_ASSERT_FATAL(g_lun
.reservation
.rtype
== SPDK_SCSI_PR_WRITE_EXCLUSIVE_ALL_REGS
);
294 SPDK_CU_ASSERT_FATAL(g_lun
.pr_generation
== gen
+ 1);
296 /* Test Case: Host C acquires the reservation with invalid type */
297 task
.initiator_port
= &g_i_port_c
;
299 rc
= spdk_scsi_pr_out_reserve(&task
, SPDK_SCSI_PR_WRITE_EXCLUSIVE
,
301 SPDK_CU_ASSERT_FATAL(rc
< 0);
302 SPDK_CU_ASSERT_FATAL(task
.status
== SPDK_SCSI_STATUS_RESERVATION_CONFLICT
);
303 SPDK_CU_ASSERT_FATAL(g_lun
.reservation
.rtype
== SPDK_SCSI_PR_WRITE_EXCLUSIVE_ALL_REGS
);
304 SPDK_CU_ASSERT_FATAL(g_lun
.pr_generation
== gen
+ 1);
306 /* Test Case: Host C acquires the reservation, all registrants type */
308 rc
= spdk_scsi_pr_out_reserve(&task
, SPDK_SCSI_PR_WRITE_EXCLUSIVE_ALL_REGS
,
310 SPDK_CU_ASSERT_FATAL(rc
== 0);
311 SPDK_CU_ASSERT_FATAL(g_lun
.reservation
.rtype
== SPDK_SCSI_PR_WRITE_EXCLUSIVE_ALL_REGS
);
312 SPDK_CU_ASSERT_FATAL(g_lun
.pr_generation
== gen
+ 1);
314 ut_deinit_reservation_test();
318 test_reservation_preempt_non_all_regs(void)
320 struct spdk_scsi_pr_registrant
*reg
;
321 struct spdk_scsi_task task
= {0};
326 task
.target_port
= &g_t_port_0
;
328 ut_init_reservation_test();
329 test_build_registrants();
331 task
.initiator_port
= &g_i_port_a
;
333 gen
= g_lun
.pr_generation
;
334 /* Host A acquires the reservation */
335 rc
= spdk_scsi_pr_out_reserve(&task
, SPDK_SCSI_PR_WRITE_EXCLUSIVE_REGS_ONLY
,
337 SPDK_CU_ASSERT_FATAL(rc
== 0);
338 SPDK_CU_ASSERT_FATAL(g_lun
.reservation
.rtype
== SPDK_SCSI_PR_WRITE_EXCLUSIVE_REGS_ONLY
);
339 SPDK_CU_ASSERT_FATAL(g_lun
.reservation
.crkey
== 0xa);
340 SPDK_CU_ASSERT_FATAL(g_lun
.pr_generation
== gen
);
342 /* Test Case: Host B premmpts Host A, Check condition is expected
343 * for zeroed service action reservation key */
344 task
.initiator_port
= &g_i_port_b
;
346 rc
= spdk_scsi_pr_out_preempt(&task
, SPDK_SCSI_PR_OUT_PREEMPT
,
347 SPDK_SCSI_PR_WRITE_EXCLUSIVE_REGS_ONLY
,
349 SPDK_CU_ASSERT_FATAL(rc
< 0);
350 SPDK_CU_ASSERT_FATAL(task
.status
== SPDK_SCSI_STATUS_CHECK_CONDITION
);
352 /* Test Case: Host B preempts Host A, Host A is unregisted */
354 gen
= g_lun
.pr_generation
;
355 rc
= spdk_scsi_pr_out_preempt(&task
, SPDK_SCSI_PR_OUT_PREEMPT
,
356 SPDK_SCSI_PR_WRITE_EXCLUSIVE
,
358 SPDK_CU_ASSERT_FATAL(rc
== 0);
359 SPDK_CU_ASSERT_FATAL(g_lun
.reservation
.rtype
== SPDK_SCSI_PR_WRITE_EXCLUSIVE
);
360 SPDK_CU_ASSERT_FATAL(g_lun
.reservation
.crkey
== 0xb);
361 SPDK_CU_ASSERT_FATAL(g_lun
.pr_generation
> gen
);
362 reg
= spdk_scsi_pr_get_registrant(&g_lun
, &g_i_port_a
, &g_t_port_0
);
363 SPDK_CU_ASSERT_FATAL(reg
== NULL
);
365 /* Test Case: Host B preempts itself */
367 gen
= g_lun
.pr_generation
;
368 rc
= spdk_scsi_pr_out_preempt(&task
, SPDK_SCSI_PR_OUT_PREEMPT
,
369 SPDK_SCSI_PR_WRITE_EXCLUSIVE
,
371 SPDK_CU_ASSERT_FATAL(rc
== 0);
372 SPDK_CU_ASSERT_FATAL(g_lun
.reservation
.rtype
== SPDK_SCSI_PR_WRITE_EXCLUSIVE
);
373 SPDK_CU_ASSERT_FATAL(g_lun
.reservation
.crkey
== 0xb);
374 SPDK_CU_ASSERT_FATAL(g_lun
.pr_generation
> gen
);
376 /* Test Case: Host B preempts itself and remove registrants */
378 gen
= g_lun
.pr_generation
;
379 rc
= spdk_scsi_pr_out_preempt(&task
, SPDK_SCSI_PR_OUT_PREEMPT
,
380 SPDK_SCSI_PR_WRITE_EXCLUSIVE
,
382 SPDK_CU_ASSERT_FATAL(rc
== 0);
383 SPDK_CU_ASSERT_FATAL(g_lun
.reservation
.rtype
== SPDK_SCSI_PR_WRITE_EXCLUSIVE
);
384 SPDK_CU_ASSERT_FATAL(g_lun
.reservation
.crkey
== 0xb);
385 reg
= spdk_scsi_pr_get_registrant(&g_lun
, &g_i_port_c
, &g_t_port_0
);
386 SPDK_CU_ASSERT_FATAL(reg
== NULL
);
387 SPDK_CU_ASSERT_FATAL(g_lun
.pr_generation
> gen
);
389 ut_deinit_reservation_test();
393 test_reservation_preempt_all_regs(void)
395 struct spdk_scsi_pr_registrant
*reg
;
396 struct spdk_scsi_task task
= {0};
401 task
.target_port
= &g_t_port_0
;
403 ut_init_reservation_test();
404 test_build_registrants();
406 /* Test Case: No reservation yet, Host B removes Host C's registrant */
407 task
.initiator_port
= &g_i_port_b
;
409 gen
= g_lun
.pr_generation
;
410 rc
= spdk_scsi_pr_out_preempt(&task
, SPDK_SCSI_PR_OUT_PREEMPT
,
411 SPDK_SCSI_PR_WRITE_EXCLUSIVE_REGS_ONLY
,
413 SPDK_CU_ASSERT_FATAL(rc
== 0);
414 reg
= spdk_scsi_pr_get_registrant(&g_lun
, &g_i_port_c
, &g_t_port_0
);
415 SPDK_CU_ASSERT_FATAL(reg
== NULL
);
416 SPDK_CU_ASSERT_FATAL(g_lun
.pr_generation
> gen
);
418 task
.initiator_port
= &g_i_port_a
;
420 gen
= g_lun
.pr_generation
;
421 /* Host A acquires the reservation */
422 rc
= spdk_scsi_pr_out_reserve(&task
, SPDK_SCSI_PR_WRITE_EXCLUSIVE_ALL_REGS
,
424 SPDK_CU_ASSERT_FATAL(rc
== 0);
425 SPDK_CU_ASSERT_FATAL(g_lun
.reservation
.rtype
== SPDK_SCSI_PR_WRITE_EXCLUSIVE_ALL_REGS
);
426 SPDK_CU_ASSERT_FATAL(g_lun
.pr_generation
== gen
);
428 /* Test Case: Host B removes Host A's registrant and preempt */
429 task
.initiator_port
= &g_i_port_b
;
431 gen
= g_lun
.pr_generation
;
432 rc
= spdk_scsi_pr_out_preempt(&task
, SPDK_SCSI_PR_OUT_PREEMPT
,
433 SPDK_SCSI_PR_EXCLUSIVE_ACCESS_ALL_REGS
,
435 SPDK_CU_ASSERT_FATAL(rc
== 0);
436 reg
= spdk_scsi_pr_get_registrant(&g_lun
, &g_i_port_a
, &g_t_port_0
);
437 SPDK_CU_ASSERT_FATAL(reg
== NULL
);
438 SPDK_CU_ASSERT_FATAL(g_lun
.reservation
.rtype
== SPDK_SCSI_PR_EXCLUSIVE_ACCESS_ALL_REGS
);
439 SPDK_CU_ASSERT_FATAL(g_lun
.pr_generation
> gen
);
441 ut_deinit_reservation_test();
445 test_reservation_cmds_conflict(void)
447 struct spdk_scsi_pr_registrant
*reg
;
448 struct spdk_scsi_task task
= {0};
453 task
.target_port
= &g_t_port_0
;
456 ut_init_reservation_test();
457 test_build_registrants();
459 /* Host A acquires the reservation */
460 task
.initiator_port
= &g_i_port_a
;
461 rc
= spdk_scsi_pr_out_reserve(&task
, SPDK_SCSI_PR_WRITE_EXCLUSIVE_REGS_ONLY
,
463 SPDK_CU_ASSERT_FATAL(rc
== 0);
464 SPDK_CU_ASSERT_FATAL(g_lun
.reservation
.rtype
== SPDK_SCSI_PR_WRITE_EXCLUSIVE_REGS_ONLY
);
465 SPDK_CU_ASSERT_FATAL(g_lun
.reservation
.crkey
== 0xa);
467 /* Remove Host B registrant */
468 task
.initiator_port
= &g_i_port_b
;
470 rc
= spdk_scsi_pr_out_register(&task
, SPDK_SCSI_PR_OUT_REGISTER
,
472 SPDK_CU_ASSERT_FATAL(rc
== 0);
473 reg
= spdk_scsi_pr_get_registrant(&g_lun
, &g_i_port_b
, &g_t_port_0
);
474 SPDK_CU_ASSERT_FATAL(reg
== NULL
);
476 /* Test Case: Host B sends Read/Write commands,
477 * reservation conflict is expected.
479 task
.cdb
[0] = SPDK_SBC_READ_10
;
481 rc
= spdk_scsi_pr_check(&task
);
482 SPDK_CU_ASSERT_FATAL(rc
== 0);
483 task
.cdb
[0] = SPDK_SBC_WRITE_10
;
485 rc
= spdk_scsi_pr_check(&task
);
486 SPDK_CU_ASSERT_FATAL(rc
< 0);
487 SPDK_CU_ASSERT_FATAL(task
.status
== SPDK_SCSI_STATUS_RESERVATION_CONFLICT
);
489 /* Test Case: Host C sends Read/Write commands */
490 task
.initiator_port
= &g_i_port_c
;
491 task
.cdb
[0] = SPDK_SBC_READ_10
;
493 rc
= spdk_scsi_pr_check(&task
);
494 SPDK_CU_ASSERT_FATAL(rc
== 0);
495 task
.cdb
[0] = SPDK_SBC_WRITE_10
;
497 rc
= spdk_scsi_pr_check(&task
);
498 SPDK_CU_ASSERT_FATAL(rc
== 0);
500 /* Host A preempts itself with SPDK_SCSI_PR_EXCLUSIVE_ACCESS */
501 task
.initiator_port
= &g_i_port_a
;
502 rc
= spdk_scsi_pr_out_preempt(&task
, SPDK_SCSI_PR_OUT_PREEMPT
,
503 SPDK_SCSI_PR_EXCLUSIVE_ACCESS
,
505 SPDK_CU_ASSERT_FATAL(rc
== 0);
506 SPDK_CU_ASSERT_FATAL(g_lun
.reservation
.rtype
== SPDK_SCSI_PR_EXCLUSIVE_ACCESS
);
507 SPDK_CU_ASSERT_FATAL(g_lun
.reservation
.crkey
== 0xa);
509 /* Test Case: Host C sends Read/Write commands */
510 task
.initiator_port
= &g_i_port_c
;
511 task
.cdb
[0] = SPDK_SBC_READ_10
;
513 rc
= spdk_scsi_pr_check(&task
);
514 SPDK_CU_ASSERT_FATAL(rc
< 0);
515 SPDK_CU_ASSERT_FATAL(task
.status
== SPDK_SCSI_STATUS_RESERVATION_CONFLICT
);
516 task
.cdb
[0] = SPDK_SBC_WRITE_10
;
518 rc
= spdk_scsi_pr_check(&task
);
519 SPDK_CU_ASSERT_FATAL(rc
< 0);
520 SPDK_CU_ASSERT_FATAL(task
.status
== SPDK_SCSI_STATUS_RESERVATION_CONFLICT
);
522 /* Test Case: Host B sends Read/Write commands */
523 task
.initiator_port
= &g_i_port_b
;
524 task
.cdb
[0] = SPDK_SBC_READ_10
;
526 rc
= spdk_scsi_pr_check(&task
);
527 SPDK_CU_ASSERT_FATAL(rc
< 0);
528 SPDK_CU_ASSERT_FATAL(task
.status
== SPDK_SCSI_STATUS_RESERVATION_CONFLICT
);
529 task
.cdb
[0] = SPDK_SBC_WRITE_10
;
531 rc
= spdk_scsi_pr_check(&task
);
532 SPDK_CU_ASSERT_FATAL(rc
< 0);
533 SPDK_CU_ASSERT_FATAL(task
.status
== SPDK_SCSI_STATUS_RESERVATION_CONFLICT
);
535 ut_deinit_reservation_test();
539 main(int argc
, char **argv
)
541 CU_pSuite suite
= NULL
;
542 unsigned int num_failures
;
544 if (CU_initialize_registry() != CUE_SUCCESS
) {
545 return CU_get_error();
548 suite
= CU_add_suite("reservation_suite", NULL
, NULL
);
550 CU_cleanup_registry();
551 return CU_get_error();
554 if (CU_add_test(suite
, "register", test_reservation_register
) == NULL
||
555 CU_add_test(suite
, "reserve", test_reservation_reserve
) == NULL
||
556 CU_add_test(suite
, "preempt", test_reservation_preempt_non_all_regs
) == NULL
||
557 CU_add_test(suite
, "preempt all regs", test_reservation_preempt_all_regs
) == NULL
||
558 CU_add_test(suite
, "conflict", test_reservation_cmds_conflict
) == NULL
) {
559 CU_cleanup_registry();
560 return CU_get_error();
563 CU_basic_set_mode(CU_BRM_VERBOSE
);
564 CU_basic_run_tests();
565 num_failures
= CU_get_number_of_failures();
566 CU_cleanup_registry();