Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2019 Intel Corporation.
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include "spdk/stdinc.h"
7 : :
8 : : #include "scsi/port.c"
9 : : #include "scsi/scsi_pr.c"
10 : :
11 : : #include "spdk_internal/cunit.h"
12 : :
13 : : #include "spdk_internal/mock.h"
14 : :
15 : 5 : SPDK_LOG_REGISTER_COMPONENT(scsi)
16 : :
17 : : void
18 : 100 : spdk_scsi_task_set_status(struct spdk_scsi_task *task, int sc, int sk,
19 : : int asc, int ascq)
20 : : {
21 : 100 : task->status = sc;
22 : 100 : }
23 : :
24 : : /*
25 : : * Reservation Unit Test Configuration
26 : : *
27 : : * -------- -------- -------
28 : : * | Host A | | Host B | | Host C|
29 : : * -------- -------- -------
30 : : * | | |
31 : : * ------ ------ ------
32 : : * |Port A| |Port B| |Port C|
33 : : * ------ ------ ------
34 : : * \ | /
35 : : * \ | /
36 : : * \ | /
37 : : * ------------------------
38 : : * | Target Node 1 Port 0 |
39 : : * ------------------------
40 : : * |
41 : : * ----------------------------------
42 : : * | Target Node |
43 : : * ----------------------------------
44 : : * |
45 : : * -----
46 : : * |LUN 0|
47 : : * -----
48 : : *
49 : : */
50 : :
51 : : static struct spdk_scsi_lun g_lun;
52 : : static struct spdk_scsi_port g_i_port_a;
53 : : static struct spdk_scsi_port g_i_port_b;
54 : : static struct spdk_scsi_port g_i_port_c;
55 : : static struct spdk_scsi_port g_t_port_0;
56 : :
57 : : static void
58 : 45 : ut_lun_deinit(void)
59 : : {
60 : : struct spdk_scsi_pr_registrant *reg, *tmp;
61 : :
62 [ + + ]: 120 : TAILQ_FOREACH_SAFE(reg, &g_lun.reg_head, link, tmp) {
63 [ + + ]: 75 : TAILQ_REMOVE(&g_lun.reg_head, reg, link);
64 : 75 : free(reg);
65 : : }
66 : 45 : g_lun.reservation.rtype = 0;
67 : 45 : g_lun.reservation.crkey = 0;
68 : 45 : g_lun.reservation.holder = NULL;
69 : 45 : g_lun.pr_generation = 0;
70 : 45 : }
71 : :
72 : : static void
73 : 45 : ut_port_init(void)
74 : : {
75 : : int rc;
76 : :
77 : : /* g_i_port_a */
78 : 45 : rc = scsi_port_construct(&g_i_port_a, 0xa, 0,
79 : : "iqn.2016-06.io.spdk:fe5aacf7420a,i,0x00023d00000a");
80 [ - + ]: 45 : SPDK_CU_ASSERT_FATAL(rc == 0);
81 : 45 : spdk_scsi_port_set_iscsi_transport_id(&g_i_port_a,
82 : : "iqn.2016-06.io.spdk:fe5aacf7420a", 0x00023d00000a);
83 : : /* g_i_port_b */
84 : 45 : rc = scsi_port_construct(&g_i_port_b, 0xb, 0,
85 : : "iqn.2016-06.io.spdk:fe5aacf7420b,i,0x00023d00000b");
86 [ - + ]: 45 : SPDK_CU_ASSERT_FATAL(rc == 0);
87 : 45 : spdk_scsi_port_set_iscsi_transport_id(&g_i_port_b,
88 : : "iqn.2016-06.io.spdk:fe5aacf7420b", 0x00023d00000b);
89 : : /* g_i_port_c */
90 : 45 : rc = scsi_port_construct(&g_i_port_c, 0xc, 0,
91 : : "iqn.2016-06.io.spdk:fe5aacf7420c,i,0x00023d00000c");
92 [ - + ]: 45 : SPDK_CU_ASSERT_FATAL(rc == 0);
93 : 45 : spdk_scsi_port_set_iscsi_transport_id(&g_i_port_c,
94 : : "iqn.2016-06.io.spdk:fe5aacf7420c", 0x00023d00000c);
95 : : /* g_t_port_0 */
96 : 45 : rc = scsi_port_construct(&g_t_port_0, 0x0, 1,
97 : : "iqn.2016-06.io.spdk:fe5aacf74200,t,0x00023d000000");
98 [ - + ]: 45 : SPDK_CU_ASSERT_FATAL(rc == 0);
99 : 45 : spdk_scsi_port_set_iscsi_transport_id(&g_t_port_0,
100 : : "iqn.2016-06.io.spdk:fe5aacf74200", 0x00023d000000);
101 : 45 : }
102 : :
103 : : static void
104 : 90 : ut_lun_init(void)
105 : : {
106 : 90 : TAILQ_INIT(&g_lun.reg_head);
107 : 90 : }
108 : :
109 : : static void
110 : 45 : ut_init_reservation_test(void)
111 : : {
112 : 45 : ut_lun_init();
113 : 45 : ut_port_init();
114 : 45 : ut_lun_init();
115 : 45 : }
116 : :
117 : : static void
118 : 45 : ut_deinit_reservation_test(void)
119 : : {
120 : 45 : ut_lun_deinit();
121 : 45 : }
122 : :
123 : : /* Host A: register with key 0xa.
124 : : * Host B: register with key 0xb.
125 : : * Host C: register with key 0xc.
126 : : */
127 : : static void
128 : 40 : test_build_registrants(void)
129 : : {
130 : : struct spdk_scsi_pr_registrant *reg;
131 : 40 : struct spdk_scsi_task task = {0};
132 : : uint32_t gen;
133 : : int rc;
134 : :
135 : 40 : task.lun = &g_lun;
136 : 40 : task.target_port = &g_t_port_0;
137 : :
138 : 40 : gen = g_lun.pr_generation;
139 : :
140 : : /* I_T nexus: Initiator Port A to Target Port 0 */
141 : 40 : task.initiator_port = &g_i_port_a;
142 : : /* Test Case: Host A registers with a new key */
143 : 40 : task.status = 0;
144 : 40 : rc = scsi_pr_out_register(&task, SPDK_SCSI_PR_OUT_REGISTER,
145 : : 0x0, 0xa1, 0, 0, 0);
146 [ - + ]: 40 : SPDK_CU_ASSERT_FATAL(rc == 0);
147 : 40 : reg = scsi_pr_get_registrant(&g_lun, &g_i_port_a, &g_t_port_0);
148 [ - + ]: 40 : SPDK_CU_ASSERT_FATAL(reg != NULL);
149 [ - + ]: 40 : SPDK_CU_ASSERT_FATAL(reg->rkey == 0xa1);
150 [ - + ]: 40 : SPDK_CU_ASSERT_FATAL(g_lun.pr_generation == gen + 1);
151 : :
152 : : /* Test Case: Host A replaces with a new key */
153 : 40 : task.status = 0;
154 : 40 : rc = scsi_pr_out_register(&task, SPDK_SCSI_PR_OUT_REGISTER,
155 : : 0xa1, 0xa, 0, 0, 0);
156 [ - + ]: 40 : SPDK_CU_ASSERT_FATAL(rc == 0);
157 : 40 : reg = scsi_pr_get_registrant(&g_lun, &g_i_port_a, &g_t_port_0);
158 [ - + ]: 40 : SPDK_CU_ASSERT_FATAL(reg != NULL);
159 [ - + ]: 40 : SPDK_CU_ASSERT_FATAL(reg->rkey == 0xa);
160 [ - + ]: 40 : SPDK_CU_ASSERT_FATAL(g_lun.pr_generation == gen + 2);
161 : :
162 : : /* Test Case: Host A replaces with a new key, reservation conflict is expected */
163 : 40 : task.status = 0;
164 : 40 : rc = scsi_pr_out_register(&task, SPDK_SCSI_PR_OUT_REGISTER,
165 : : 0xa1, 0xdead, 0, 0, 0);
166 [ - + ]: 40 : SPDK_CU_ASSERT_FATAL(rc < 0);
167 : 40 : reg = scsi_pr_get_registrant(&g_lun, &g_i_port_a, &g_t_port_0);
168 [ - + ]: 40 : SPDK_CU_ASSERT_FATAL(reg != NULL);
169 [ - + ]: 40 : SPDK_CU_ASSERT_FATAL(reg->rkey == 0xa);
170 [ - + ]: 40 : SPDK_CU_ASSERT_FATAL(g_lun.pr_generation == gen + 2);
171 [ - + ]: 40 : SPDK_CU_ASSERT_FATAL(task.status == SPDK_SCSI_STATUS_RESERVATION_CONFLICT);
172 : :
173 : : /* I_T nexus: Initiator Port B to Target Port 0 */
174 : 40 : task.initiator_port = &g_i_port_b;
175 : : /* Test Case: Host B registers with a new key */
176 : 40 : task.status = 0;
177 : 40 : rc = scsi_pr_out_register(&task, SPDK_SCSI_PR_OUT_REGISTER,
178 : : 0x0, 0xb, 0, 0, 0);
179 [ - + ]: 40 : SPDK_CU_ASSERT_FATAL(rc == 0);
180 : 40 : reg = scsi_pr_get_registrant(&g_lun, &g_i_port_b, &g_t_port_0);
181 [ - + ]: 40 : SPDK_CU_ASSERT_FATAL(reg != NULL);
182 [ - + ]: 40 : SPDK_CU_ASSERT_FATAL(reg->rkey == 0xb);
183 [ - + ]: 40 : SPDK_CU_ASSERT_FATAL(g_lun.pr_generation == gen + 3);
184 : :
185 : : /* I_T nexus: Initiator Port C to Target Port 0 */
186 : 40 : task.initiator_port = &g_i_port_c;
187 : : /* Test Case: Host C registers with a new key */
188 : 40 : task.status = 0;
189 : 40 : rc = scsi_pr_out_register(&task, SPDK_SCSI_PR_OUT_REGISTER,
190 : : 0x0, 0xc, 0, 0, 0);
191 [ - + ]: 40 : SPDK_CU_ASSERT_FATAL(rc == 0);
192 : 40 : reg = scsi_pr_get_registrant(&g_lun, &g_i_port_c, &g_t_port_0);
193 [ - + ]: 40 : SPDK_CU_ASSERT_FATAL(reg != NULL);
194 [ - + ]: 40 : SPDK_CU_ASSERT_FATAL(reg->rkey == 0xc);
195 [ - + ]: 40 : SPDK_CU_ASSERT_FATAL(g_lun.pr_generation == gen + 4);
196 : 40 : }
197 : :
198 : : static void
199 : 5 : test_reservation_register(void)
200 : : {
201 : 5 : ut_init_reservation_test();
202 : :
203 : 5 : test_build_registrants();
204 : :
205 : 5 : ut_deinit_reservation_test();
206 : 5 : }
207 : :
208 : : static void
209 : 5 : test_all_registrant_reservation_reserve(void)
210 : : {
211 : : struct spdk_scsi_pr_registrant *reg;
212 : 5 : struct spdk_scsi_task task = {0};
213 : : uint32_t gen;
214 : : int rc;
215 : :
216 : 5 : task.lun = &g_lun;
217 : 5 : task.target_port = &g_t_port_0;
218 : :
219 : 5 : ut_init_reservation_test();
220 : :
221 : 5 : test_build_registrants();
222 : 5 : gen = g_lun.pr_generation;
223 : : /* Test Case: Host A takes all registrant reservation */
224 : 5 : task.initiator_port = &g_i_port_a;
225 : 5 : task.status = 0;
226 : 5 : rc = scsi_pr_out_reserve(&task, SPDK_SCSI_PR_WRITE_EXCLUSIVE_ALL_REGS,
227 : : 0xa, 0, 0, 0);
228 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
229 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(task.status == 0);
230 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.rtype == SPDK_SCSI_PR_WRITE_EXCLUSIVE_ALL_REGS);
231 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.crkey == 0xa);
232 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.pr_generation == gen);
233 : :
234 : : /* Test case: Host A release reservation - which should pass to next inline -> Host B */
235 : 5 : task.initiator_port = &g_i_port_a;
236 : 5 : task.status = 0;
237 : 5 : rc = scsi_pr_out_release(&task, SPDK_SCSI_PR_WRITE_EXCLUSIVE_ALL_REGS, 0xa);
238 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
239 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(task.status == 0);
240 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.rtype == SPDK_SCSI_PR_WRITE_EXCLUSIVE_ALL_REGS);
241 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.crkey == 0xb);
242 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.pr_generation == gen);
243 : :
244 : : /* Test case: Host A unregister + Host C unregister: Host B left alone.
245 : : * Host B than releases reservation - lun should not have any reservation holder *
246 : : */
247 : 5 : task.initiator_port = &g_i_port_a;
248 : 5 : task.status = 0;
249 : 5 : rc = scsi_pr_out_register(&task, SPDK_SCSI_PR_OUT_REGISTER,
250 : : 0xa, 0, 0, 0, 0);
251 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
252 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(task.status == 0);
253 : 5 : reg = scsi_pr_get_registrant(&g_lun, &g_i_port_a, &g_t_port_0);
254 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(reg == NULL);
255 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.pr_generation == ++gen);
256 : :
257 : 5 : task.initiator_port = &g_i_port_c;
258 : 5 : task.status = 0;
259 : 5 : rc = scsi_pr_out_register(&task, SPDK_SCSI_PR_OUT_REGISTER,
260 : : 0xc, 0, 0, 0, 0);
261 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
262 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(task.status == 0);
263 : 5 : reg = scsi_pr_get_registrant(&g_lun, &g_i_port_c, &g_t_port_0);
264 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(reg == NULL);
265 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.pr_generation == ++gen);
266 : :
267 : 5 : task.initiator_port = &g_i_port_b;
268 : 5 : task.status = 0;
269 : 5 : rc = scsi_pr_out_release(&task, SPDK_SCSI_PR_WRITE_EXCLUSIVE_ALL_REGS, 0xb);
270 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
271 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(task.status == 0);
272 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.rtype == 0x0);
273 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.crkey == 0x0);
274 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.holder == NULL);
275 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.pr_generation == gen);
276 : :
277 : 5 : ut_deinit_reservation_test();
278 : 5 : }
279 : :
280 : : static void
281 : 5 : test_all_registrant_reservation_access(void)
282 : : {
283 : : struct spdk_scsi_pr_registrant *reg;
284 : 5 : struct spdk_scsi_task task = {0};
285 : 5 : uint8_t cdb[32] = {0};
286 : : uint32_t gen;
287 : : int rc;
288 : :
289 : 5 : task.lun = &g_lun;
290 : 5 : task.target_port = &g_t_port_0;
291 : 5 : task.cdb = cdb;
292 : :
293 : 5 : ut_init_reservation_test();
294 : :
295 : 5 : test_build_registrants();
296 : 5 : gen = g_lun.pr_generation;
297 : :
298 : : /* Test case: registered host A takes EXCLUSIVE_ACCESS_ALL_REGS reservation */
299 : 5 : task.initiator_port = &g_i_port_a;
300 : 5 : task.status = 0;
301 : 5 : rc = scsi_pr_out_reserve(&task, SPDK_SCSI_PR_EXCLUSIVE_ACCESS_ALL_REGS,
302 : : 0xa, 0, 0, 0);
303 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
304 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(task.status == 0);
305 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.rtype == SPDK_SCSI_PR_EXCLUSIVE_ACCESS_ALL_REGS);
306 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.crkey == 0xa);
307 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.pr_generation == gen);
308 : :
309 : : /* Test case: registered host B tries getting read access */
310 : 5 : task.initiator_port = &g_i_port_b;
311 : 5 : task.status = 0;
312 : 5 : task.cdb[0] = SPDK_SBC_READ_6;
313 : 5 : rc = scsi_pr_check(&task);
314 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
315 : :
316 : : /* Test case: registered host B tries getting write access */
317 : 5 : task.initiator_port = &g_i_port_b;
318 : 5 : task.status = 0;
319 : 5 : task.cdb[0] = SPDK_SBC_WRITE_12;
320 : 5 : rc = scsi_pr_check(&task);
321 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
322 : :
323 : : /* Test case: B unregisters */
324 : 5 : task.initiator_port = &g_i_port_b;
325 : 5 : task.status = 0;
326 : 5 : rc = scsi_pr_out_register(&task, SPDK_SCSI_PR_OUT_REGISTER,
327 : : 0xb, 0, 0, 0, 0);
328 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
329 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(task.status == 0);
330 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.pr_generation == ++gen);
331 : 5 : reg = scsi_pr_get_registrant(&g_lun, &g_i_port_b, &g_t_port_0);
332 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(reg == NULL);
333 : :
334 : : /* Test case: un register host B tries getting read access */
335 : 5 : task.initiator_port = &g_i_port_b;
336 : 5 : task.status = 0;
337 : 5 : task.cdb[0] = SPDK_SBC_READ_6;
338 : 5 : rc = scsi_pr_check(&task);
339 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc < 0);
340 : :
341 : : /* Test case: un register host B tries getting write access */
342 : 5 : task.initiator_port = &g_i_port_b;
343 : 5 : task.status = 0;
344 : 5 : task.cdb[0] = SPDK_SBC_WRITE_12;
345 : 5 : rc = scsi_pr_check(&task);
346 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc < 0);
347 : :
348 : 5 : ut_deinit_reservation_test();
349 : 5 : }
350 : :
351 : : static void
352 : 5 : test_reservation_reserve(void)
353 : : {
354 : : struct spdk_scsi_pr_registrant *reg;
355 : 5 : struct spdk_scsi_task task = {0};
356 : : uint32_t gen;
357 : : int rc;
358 : :
359 : 5 : task.lun = &g_lun;
360 : 5 : task.target_port = &g_t_port_0;
361 : :
362 : 5 : ut_init_reservation_test();
363 : : /* Test Case: call Release without a reservation */
364 : 5 : rc = scsi2_release(&task);
365 : 5 : CU_ASSERT(rc == -EINVAL);
366 : 5 : CU_ASSERT(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
367 : :
368 : 5 : test_build_registrants();
369 : :
370 : 5 : gen = g_lun.pr_generation;
371 : :
372 : 5 : task.initiator_port = &g_i_port_a;
373 : 5 : task.status = 0;
374 : : /* Test Case: Host A acquires the reservation */
375 : 5 : rc = scsi_pr_out_reserve(&task, SPDK_SCSI_PR_WRITE_EXCLUSIVE,
376 : : 0xa, 0, 0, 0);
377 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
378 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.rtype == SPDK_SCSI_PR_WRITE_EXCLUSIVE);
379 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.crkey == 0xa);
380 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.pr_generation == gen);
381 : :
382 : : /* Test Case: Host B acquires the reservation, reservation
383 : : * conflict is expected.
384 : : */
385 : 5 : task.initiator_port = &g_i_port_b;
386 : 5 : task.status = 0;
387 : 5 : rc = scsi_pr_out_reserve(&task, SPDK_SCSI_PR_WRITE_EXCLUSIVE,
388 : : 0xb, 0, 0, 0);
389 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc < 0);
390 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(task.status == SPDK_SCSI_STATUS_RESERVATION_CONFLICT);
391 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.rtype == SPDK_SCSI_PR_WRITE_EXCLUSIVE);
392 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.crkey == 0xa);
393 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.pr_generation == gen);
394 : :
395 : : /* Test Case: Host A unregister with reservation */
396 : 5 : task.initiator_port = &g_i_port_a;
397 : 5 : task.status = 0;
398 : 5 : rc = scsi_pr_out_register(&task, SPDK_SCSI_PR_OUT_REGISTER,
399 : : 0xa, 0, 0, 0, 0);
400 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
401 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.rtype == 0);
402 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.crkey == 0);
403 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.pr_generation == gen + 1);
404 : 5 : reg = scsi_pr_get_registrant(&g_lun, &g_i_port_a, &g_t_port_0);
405 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(reg == NULL);
406 : :
407 : : /* Test Case: Host B acquires the reservation */
408 : 5 : task.initiator_port = &g_i_port_b;
409 : 5 : task.status = 0;
410 : 5 : rc = scsi_pr_out_reserve(&task, SPDK_SCSI_PR_WRITE_EXCLUSIVE_ALL_REGS,
411 : : 0xb, 0, 0, 0);
412 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
413 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.rtype == SPDK_SCSI_PR_WRITE_EXCLUSIVE_ALL_REGS);
414 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.pr_generation == gen + 1);
415 : :
416 : : /* Test Case: Host C acquires the reservation with invalid type */
417 : 5 : task.initiator_port = &g_i_port_c;
418 : 5 : task.status = 0;
419 : 5 : rc = scsi_pr_out_reserve(&task, SPDK_SCSI_PR_WRITE_EXCLUSIVE,
420 : : 0xc, 0, 0, 0);
421 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc < 0);
422 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(task.status == SPDK_SCSI_STATUS_RESERVATION_CONFLICT);
423 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.rtype == SPDK_SCSI_PR_WRITE_EXCLUSIVE_ALL_REGS);
424 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.pr_generation == gen + 1);
425 : :
426 : : /* Test Case: Host C acquires the reservation, all registrants type */
427 : 5 : task.status = 0;
428 : 5 : rc = scsi_pr_out_reserve(&task, SPDK_SCSI_PR_WRITE_EXCLUSIVE_ALL_REGS,
429 : : 0xc, 0, 0, 0);
430 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
431 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.rtype == SPDK_SCSI_PR_WRITE_EXCLUSIVE_ALL_REGS);
432 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.pr_generation == gen + 1);
433 : :
434 : 5 : ut_deinit_reservation_test();
435 : 5 : }
436 : :
437 : : static void
438 : 5 : test_reservation_preempt_non_all_regs(void)
439 : : {
440 : : struct spdk_scsi_pr_registrant *reg;
441 : 5 : struct spdk_scsi_task task = {0};
442 : : uint32_t gen;
443 : : int rc;
444 : :
445 : 5 : task.lun = &g_lun;
446 : 5 : task.target_port = &g_t_port_0;
447 : :
448 : 5 : ut_init_reservation_test();
449 : 5 : test_build_registrants();
450 : :
451 : 5 : task.initiator_port = &g_i_port_a;
452 : 5 : task.status = 0;
453 : 5 : gen = g_lun.pr_generation;
454 : : /* Host A acquires the reservation */
455 : 5 : rc = scsi_pr_out_reserve(&task, SPDK_SCSI_PR_WRITE_EXCLUSIVE_REGS_ONLY,
456 : : 0xa, 0, 0, 0);
457 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
458 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.rtype == SPDK_SCSI_PR_WRITE_EXCLUSIVE_REGS_ONLY);
459 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.crkey == 0xa);
460 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.pr_generation == gen);
461 : :
462 : : /* Test Case: Host B preempts Host A, Check condition is expected
463 : : * for zeroed service action reservation key */
464 : 5 : task.initiator_port = &g_i_port_b;
465 : 5 : task.status = 0;
466 : 5 : rc = scsi_pr_out_preempt(&task, SPDK_SCSI_PR_OUT_PREEMPT,
467 : : SPDK_SCSI_PR_WRITE_EXCLUSIVE_REGS_ONLY,
468 : : 0xb, 0);
469 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc < 0);
470 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(task.status == SPDK_SCSI_STATUS_CHECK_CONDITION);
471 : :
472 : : /* Test Case: Host B preempts Host A, Host A is unregistered */
473 : 5 : task.status = 0;
474 : 5 : gen = g_lun.pr_generation;
475 : 5 : rc = scsi_pr_out_preempt(&task, SPDK_SCSI_PR_OUT_PREEMPT,
476 : : SPDK_SCSI_PR_WRITE_EXCLUSIVE,
477 : : 0xb, 0xa);
478 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
479 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.rtype == SPDK_SCSI_PR_WRITE_EXCLUSIVE);
480 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.crkey == 0xb);
481 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.pr_generation > gen);
482 : 5 : reg = scsi_pr_get_registrant(&g_lun, &g_i_port_a, &g_t_port_0);
483 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(reg == NULL);
484 : :
485 : : /* Test Case: Host B preempts itself */
486 : 5 : task.status = 0;
487 : 5 : gen = g_lun.pr_generation;
488 : 5 : rc = scsi_pr_out_preempt(&task, SPDK_SCSI_PR_OUT_PREEMPT,
489 : : SPDK_SCSI_PR_WRITE_EXCLUSIVE,
490 : : 0xb, 0xb);
491 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
492 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.rtype == SPDK_SCSI_PR_WRITE_EXCLUSIVE);
493 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.crkey == 0xb);
494 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.pr_generation > gen);
495 : :
496 : : /* Test Case: Host B preempts itself and remove registrants */
497 : 5 : task.status = 0;
498 : 5 : gen = g_lun.pr_generation;
499 : 5 : rc = scsi_pr_out_preempt(&task, SPDK_SCSI_PR_OUT_PREEMPT,
500 : : SPDK_SCSI_PR_WRITE_EXCLUSIVE,
501 : : 0xb, 0xc);
502 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
503 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.rtype == SPDK_SCSI_PR_WRITE_EXCLUSIVE);
504 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.crkey == 0xb);
505 : 5 : reg = scsi_pr_get_registrant(&g_lun, &g_i_port_c, &g_t_port_0);
506 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(reg == NULL);
507 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.pr_generation > gen);
508 : :
509 : 5 : ut_deinit_reservation_test();
510 : 5 : }
511 : :
512 : : static void
513 : 5 : test_reservation_preempt_all_regs(void)
514 : : {
515 : : struct spdk_scsi_pr_registrant *reg;
516 : 5 : struct spdk_scsi_task task = {0};
517 : : uint32_t gen;
518 : : int rc;
519 : :
520 : 5 : task.lun = &g_lun;
521 : 5 : task.target_port = &g_t_port_0;
522 : :
523 : 5 : ut_init_reservation_test();
524 : 5 : test_build_registrants();
525 : :
526 : : /* Test Case: No reservation yet, Host B removes Host C's registrant */
527 : 5 : task.initiator_port = &g_i_port_b;
528 : 5 : task.status = 0;
529 : 5 : gen = g_lun.pr_generation;
530 : 5 : rc = scsi_pr_out_preempt(&task, SPDK_SCSI_PR_OUT_PREEMPT,
531 : : SPDK_SCSI_PR_WRITE_EXCLUSIVE_REGS_ONLY,
532 : : 0xb, 0xc);
533 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
534 : 5 : reg = scsi_pr_get_registrant(&g_lun, &g_i_port_c, &g_t_port_0);
535 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(reg == NULL);
536 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.pr_generation > gen);
537 : :
538 : 5 : task.initiator_port = &g_i_port_a;
539 : 5 : task.status = 0;
540 : 5 : gen = g_lun.pr_generation;
541 : : /* Host A acquires the reservation */
542 : 5 : rc = scsi_pr_out_reserve(&task, SPDK_SCSI_PR_WRITE_EXCLUSIVE_ALL_REGS,
543 : : 0xa, 0, 0, 0);
544 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
545 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.rtype == SPDK_SCSI_PR_WRITE_EXCLUSIVE_ALL_REGS);
546 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.pr_generation == gen);
547 : :
548 : : /* Test Case: Host B removes Host A's registrant and preempt */
549 : 5 : task.initiator_port = &g_i_port_b;
550 : 5 : task.status = 0;
551 : 5 : gen = g_lun.pr_generation;
552 : 5 : rc = scsi_pr_out_preempt(&task, SPDK_SCSI_PR_OUT_PREEMPT,
553 : : SPDK_SCSI_PR_EXCLUSIVE_ACCESS_ALL_REGS,
554 : : 0xb, 0x0);
555 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
556 : 5 : reg = scsi_pr_get_registrant(&g_lun, &g_i_port_a, &g_t_port_0);
557 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(reg == NULL);
558 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.rtype == SPDK_SCSI_PR_EXCLUSIVE_ACCESS_ALL_REGS);
559 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.pr_generation > gen);
560 : :
561 : 5 : ut_deinit_reservation_test();
562 : 5 : }
563 : :
564 : : static void
565 : 5 : test_reservation_cmds_conflict(void)
566 : : {
567 : : struct spdk_scsi_pr_registrant *reg;
568 : 5 : struct spdk_scsi_task task = {0};
569 : 4 : uint8_t cdb[32];
570 : : int rc;
571 : :
572 : 5 : task.lun = &g_lun;
573 : 5 : task.target_port = &g_t_port_0;
574 : 5 : task.cdb = cdb;
575 : :
576 : 5 : ut_init_reservation_test();
577 : 5 : test_build_registrants();
578 : :
579 : : /* Host A acquires the reservation */
580 : 5 : task.initiator_port = &g_i_port_a;
581 : 5 : rc = scsi_pr_out_reserve(&task, SPDK_SCSI_PR_WRITE_EXCLUSIVE_REGS_ONLY,
582 : : 0xa, 0, 0, 0);
583 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
584 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.rtype == SPDK_SCSI_PR_WRITE_EXCLUSIVE_REGS_ONLY);
585 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.crkey == 0xa);
586 : :
587 : : /* Remove Host B registrant */
588 : 5 : task.initiator_port = &g_i_port_b;
589 : 5 : task.status = 0;
590 : 5 : rc = scsi_pr_out_register(&task, SPDK_SCSI_PR_OUT_REGISTER,
591 : : 0xb, 0, 0, 0, 0);
592 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
593 : 5 : reg = scsi_pr_get_registrant(&g_lun, &g_i_port_b, &g_t_port_0);
594 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(reg == NULL);
595 : :
596 : : /* Test Case: Host B sends Read/Write commands,
597 : : * reservation conflict is expected.
598 : : */
599 : 5 : task.cdb[0] = SPDK_SBC_READ_10;
600 : 5 : task.status = 0;
601 : 5 : rc = scsi_pr_check(&task);
602 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
603 : 5 : task.cdb[0] = SPDK_SBC_WRITE_10;
604 : 5 : task.status = 0;
605 : 5 : rc = scsi_pr_check(&task);
606 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc < 0);
607 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(task.status == SPDK_SCSI_STATUS_RESERVATION_CONFLICT);
608 : :
609 : : /* Test Case: Host C sends Read/Write commands */
610 : 5 : task.initiator_port = &g_i_port_c;
611 : 5 : task.cdb[0] = SPDK_SBC_READ_10;
612 : 5 : task.status = 0;
613 : 5 : rc = scsi_pr_check(&task);
614 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
615 : 5 : task.cdb[0] = SPDK_SBC_WRITE_10;
616 : 5 : task.status = 0;
617 : 5 : rc = scsi_pr_check(&task);
618 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
619 : :
620 : : /* Host A preempts itself with SPDK_SCSI_PR_EXCLUSIVE_ACCESS */
621 : 5 : task.initiator_port = &g_i_port_a;
622 : 5 : rc = scsi_pr_out_preempt(&task, SPDK_SCSI_PR_OUT_PREEMPT,
623 : : SPDK_SCSI_PR_EXCLUSIVE_ACCESS,
624 : : 0xa, 0xa);
625 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
626 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.rtype == SPDK_SCSI_PR_EXCLUSIVE_ACCESS);
627 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.crkey == 0xa);
628 : :
629 : : /* Test Case: Host C sends Read/Write commands */
630 : 5 : task.initiator_port = &g_i_port_c;
631 : 5 : task.cdb[0] = SPDK_SBC_READ_10;
632 : 5 : task.status = 0;
633 : 5 : rc = scsi_pr_check(&task);
634 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc < 0);
635 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(task.status == SPDK_SCSI_STATUS_RESERVATION_CONFLICT);
636 : 5 : task.cdb[0] = SPDK_SBC_WRITE_10;
637 : 5 : task.status = 0;
638 : 5 : rc = scsi_pr_check(&task);
639 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc < 0);
640 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(task.status == SPDK_SCSI_STATUS_RESERVATION_CONFLICT);
641 : :
642 : : /* Test Case: Host B sends Read/Write commands */
643 : 5 : task.initiator_port = &g_i_port_b;
644 : 5 : task.cdb[0] = SPDK_SBC_READ_10;
645 : 5 : task.status = 0;
646 : 5 : rc = scsi_pr_check(&task);
647 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc < 0);
648 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(task.status == SPDK_SCSI_STATUS_RESERVATION_CONFLICT);
649 : 5 : task.cdb[0] = SPDK_SBC_WRITE_10;
650 : 5 : task.status = 0;
651 : 5 : rc = scsi_pr_check(&task);
652 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc < 0);
653 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(task.status == SPDK_SCSI_STATUS_RESERVATION_CONFLICT);
654 : :
655 : 5 : ut_deinit_reservation_test();
656 : 5 : }
657 : :
658 : : static void
659 : 5 : test_scsi2_reserve_release(void)
660 : : {
661 : 5 : struct spdk_scsi_task task = {0};
662 : 5 : uint8_t cdb[32] = {};
663 : : int rc;
664 : :
665 : 5 : task.lun = &g_lun;
666 : 5 : task.target_port = &g_t_port_0;
667 : 5 : task.cdb = cdb;
668 : :
669 : 5 : ut_init_reservation_test();
670 : :
671 : : /* Test Case: SPC2 RESERVE from Host A */
672 : 5 : task.initiator_port = &g_i_port_a;
673 : 5 : task.cdb[0] = SPDK_SPC2_RESERVE_10;
674 : 5 : rc = scsi2_reserve(&task, task.cdb);
675 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
676 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.holder != NULL);
677 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.flags == SCSI_SPC2_RESERVE);
678 : :
679 : : /* Test Case: READ command from Host B */
680 : 5 : task.initiator_port = &g_i_port_b;
681 : 5 : task.cdb[0] = SPDK_SBC_READ_10;
682 : 5 : task.status = 0;
683 : 5 : rc = scsi2_reserve_check(&task);
684 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc < 0);
685 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(task.status == SPDK_SCSI_STATUS_RESERVATION_CONFLICT);
686 : :
687 : : /* Test Case: SPDK_SPC2_RELEASE10 command from Host B */
688 : 5 : task.initiator_port = &g_i_port_b;
689 : 5 : task.cdb[0] = SPDK_SPC2_RELEASE_10;
690 : 5 : task.status = 0;
691 : 5 : rc = scsi2_reserve_check(&task);
692 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
693 : :
694 : 5 : rc = scsi2_release(&task);
695 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
696 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.holder == NULL);
697 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.flags == 0);
698 : :
699 : : /* Test Case: SPC2 RESERVE from Host B */
700 : 5 : task.initiator_port = &g_i_port_b;
701 : 5 : task.cdb[0] = SPDK_SPC2_RESERVE_10;
702 : 5 : rc = scsi2_reserve(&task, task.cdb);
703 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
704 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.holder != NULL);
705 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.flags == SCSI_SPC2_RESERVE);
706 : :
707 : : /* Test Case: READ command from Host B */
708 : 5 : task.initiator_port = &g_i_port_b;
709 : 5 : task.cdb[0] = SPDK_SBC_READ_10;
710 : 5 : rc = scsi2_reserve_check(&task);
711 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
712 : :
713 : : /* Test Case: SPDK_SPC2_RELEASE10 command from Host A */
714 : 5 : task.initiator_port = &g_i_port_a;
715 : 5 : task.cdb[0] = SPDK_SPC2_RELEASE_10;
716 : :
717 : 5 : rc = scsi2_release(&task);
718 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
719 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.holder == NULL);
720 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.flags == 0);
721 : :
722 : 5 : ut_deinit_reservation_test();
723 : 5 : }
724 : :
725 : : static void
726 : 5 : test_pr_with_scsi2_reserve_release(void)
727 : : {
728 : 5 : struct spdk_scsi_task task = {0};
729 : 5 : uint8_t cdb[32] = {};
730 : : int rc;
731 : :
732 : 5 : task.lun = &g_lun;
733 : 5 : task.target_port = &g_t_port_0;
734 : 5 : task.cdb = cdb;
735 : :
736 : 5 : ut_init_reservation_test();
737 : 5 : test_build_registrants();
738 : :
739 : 5 : task.initiator_port = &g_i_port_a;
740 : 5 : task.status = 0;
741 : : /* Test Case: Host A acquires the reservation */
742 : 5 : rc = scsi_pr_out_reserve(&task, SPDK_SCSI_PR_WRITE_EXCLUSIVE_REGS_ONLY,
743 : : 0xa, 0, 0, 0);
744 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
745 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.rtype == SPDK_SCSI_PR_WRITE_EXCLUSIVE_REGS_ONLY);
746 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.crkey == 0xa);
747 : :
748 : : /* Test Case: SPDK_SPC2_RESERVE_10 command from Host B */
749 : 5 : task.initiator_port = &g_i_port_b;
750 : 5 : task.cdb[0] = SPDK_SPC2_RESERVE_10;
751 : : /* SPC2 RESERVE/RELEASE will pass to scsi2_reserve/release */
752 : 5 : rc = scsi_pr_check(&task);
753 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
754 : :
755 : : /* do nothing with PR but have good status */
756 : 5 : rc = scsi2_reserve(&task, task.cdb);
757 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
758 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.holder != NULL);
759 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.rtype == SPDK_SCSI_PR_WRITE_EXCLUSIVE_REGS_ONLY);
760 : :
761 : 5 : rc = scsi2_release(&task);
762 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(rc == 0);
763 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.holder != NULL);
764 [ - + ]: 5 : SPDK_CU_ASSERT_FATAL(g_lun.reservation.rtype == SPDK_SCSI_PR_WRITE_EXCLUSIVE_REGS_ONLY);
765 : :
766 : 5 : ut_deinit_reservation_test();
767 : 5 : }
768 : :
769 : : int
770 : 5 : main(int argc, char **argv)
771 : : {
772 : 5 : CU_pSuite suite = NULL;
773 : : unsigned int num_failures;
774 : :
775 : 5 : CU_initialize_registry();
776 : :
777 : 5 : suite = CU_add_suite("reservation_suite", NULL, NULL);
778 : 5 : CU_ADD_TEST(suite, test_reservation_register);
779 : 5 : CU_ADD_TEST(suite, test_reservation_reserve);
780 : 5 : CU_ADD_TEST(suite, test_all_registrant_reservation_reserve);
781 : 5 : CU_ADD_TEST(suite, test_all_registrant_reservation_access);
782 : 5 : CU_ADD_TEST(suite, test_reservation_preempt_non_all_regs);
783 : 5 : CU_ADD_TEST(suite, test_reservation_preempt_all_regs);
784 : 5 : CU_ADD_TEST(suite, test_reservation_cmds_conflict);
785 : 5 : CU_ADD_TEST(suite, test_scsi2_reserve_release);
786 : 5 : CU_ADD_TEST(suite, test_pr_with_scsi2_reserve_release);
787 : :
788 : 5 : num_failures = spdk_ut_run_tests(argc, argv, NULL);
789 : 5 : CU_cleanup_registry();
790 : 5 : return num_failures;
791 : :
792 : : }
|