Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/tests/sys/cam/ctl/persist.sh
39536 views
1
# SPDX-License-Identifier: BSD-2-Clause
2
#
3
# Copyright (c) 2024 ConnectWise
4
# All rights reserved.
5
#
6
# Redistribution and use in source and binary forms, with or without
7
# modification, are permitted provided that the following conditions
8
# are met:
9
# 1. Redistributions of source code must retain the above copyright
10
# notice, this list of conditions and the following disclaimer.
11
# 2. Redistributions in binary form must reproduce the above copyright
12
# notice, this list of conditions and the following disclaimer in the
13
# documentation and/or other materials provided with the distribution.
14
#
15
# THIS DOCUMENTATION IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
26
. $(atf_get_srcdir)/ctl.subr
27
28
# TODO
29
# * PRIN READ RESERVATION, with one reservation
30
# * PROUT with illegal type
31
# * PROUT REGISTER AND IGNORE EXISTING KEY
32
# * PROUT REGISTER AND IGNORE EXISTING KEY with a RESERVATION KEY that isn't registered
33
# * PROUT REGISTER AND IGNORE EXISTING KEY to unregister
34
# * PROUT CLEAR allows previously prevented medium removal
35
# * PROUT PREEMPT
36
# * PROUT PREEMPT with a RESERVATION KEY that isn't registered
37
# * PROUT PREEMPT_AND_ABORT
38
# * PROUT PREEMPT_AND_ABORT with a RESERVATION KEY that isn't registered
39
# * PROUT REGISTER AND MOVE
40
# * PROUT REGISTER AND MOVE with a RESERVATION KEY that isn't registered
41
# * multiple initiators
42
43
# Not Tested
44
# * PROUT REPLACE LOST RESERVATION (not supported by ctl)
45
# * Specify Initiator Ports bit (not supported by ctl)
46
# * Activate Persist Through Power Loss bit (not supported by ctl)
47
# * All Target Ports bit (not supported by ctl)
48
49
RESERVATION_KEY=0xdeadbeef1a7ebabe
50
51
atf_test_case prin_read_full_status_empty cleanup
52
prin_read_full_status_empty_head()
53
{
54
atf_set "descr" "PERSISTENT RESERVATION IN with the READ FULL STATUS service action, with no status descriptors"
55
atf_set "require.user" "root"
56
atf_set "require.progs" sg_persist ctladm
57
}
58
prin_read_full_status_empty_body()
59
{
60
create_ramdisk
61
62
atf_check -o match:"No full status descriptors" sg_persist -ns /dev/$dev
63
}
64
prin_read_full_status_empty_cleanup()
65
{
66
cleanup
67
}
68
69
atf_test_case prin_read_keys_empty cleanup
70
prin_read_keys_empty_head()
71
{
72
atf_set "descr" "PERSISTENT RESERVATION IN with the READ KEYS service action, with no registered keys"
73
atf_set "require.user" "root"
74
atf_set "require.progs" sg_persist ctladm
75
}
76
prin_read_keys_empty_body()
77
{
78
create_ramdisk
79
80
atf_check -o match:"there are NO registered reservation keys" sg_persist -nk /dev/$dev
81
}
82
prin_read_keys_empty_cleanup()
83
{
84
cleanup
85
}
86
87
atf_test_case prin_read_reservation_empty cleanup
88
prin_read_reservation_empty_head()
89
{
90
atf_set "descr" "PERSISTENT RESERVATION IN with the READ RESERVATION service action, with no reservations"
91
atf_set "require.user" "root"
92
atf_set "require.progs" sg_persist ctladm
93
}
94
prin_read_reservation_empty_body()
95
{
96
create_ramdisk
97
98
atf_check -o match:"there is NO reservation held" sg_persist -nr /dev/$dev
99
}
100
prin_read_reservation_empty_cleanup()
101
{
102
cleanup
103
}
104
105
atf_test_case prin_report_capabilities cleanup
106
prin_report_capabilities_head()
107
{
108
atf_set "descr" "PERSISTENT RESERVATION IN with the REPORT CAPABILITIES service action"
109
atf_set "require.user" "root"
110
atf_set "require.progs" sg_persist ctladm
111
}
112
prin_report_capabilities_body()
113
{
114
create_ramdisk
115
116
cat > expected <<HERE
117
Report capabilities response:
118
Replace Lost Reservation Capable(RLR_C): 0
119
Compatible Reservation Handling(CRH): 1
120
Specify Initiator Ports Capable(SIP_C): 0
121
All Target Ports Capable(ATP_C): 0
122
Persist Through Power Loss Capable(PTPL_C): 0
123
Type Mask Valid(TMV): 1
124
Allow Commands: 5
125
Persist Through Power Loss Active(PTPL_A): 0
126
Support indicated in Type mask:
127
Write Exclusive, all registrants: 1
128
Exclusive Access, registrants only: 1
129
Write Exclusive, registrants only: 1
130
Exclusive Access: 1
131
Write Exclusive: 1
132
Exclusive Access, all registrants: 1
133
HERE
134
atf_check -o file:expected sg_persist -nc /dev/$dev
135
}
136
prin_report_capabilities_cleanup()
137
{
138
cleanup
139
}
140
141
atf_test_case prout_clear cleanup
142
prout_clear_head()
143
{
144
atf_set "descr" "PERSISTENT RESERVATION OUT with the CLEAR service action"
145
atf_set "require.user" "root"
146
atf_set "require.progs" sg_persist ctladm
147
}
148
prout_clear_body()
149
{
150
create_ramdisk
151
152
# First register a key
153
atf_check sg_persist -n --out --param-rk=0 --param-sark=$RESERVATION_KEY -G /dev/$dev
154
155
# Then make a reservation using that key
156
atf_check sg_persist -n --out --param-rk=$RESERVATION_KEY --reserve --prout-type=8 /dev/$dev
157
158
# Now, clear all reservations and registrations
159
atf_check sg_persist -n --out --param-rk=$RESERVATION_KEY --clear /dev/$dev
160
161
# Finally, check that all reservations and keys are gone
162
atf_check -o match:"there is NO reservation held" sg_persist -nr /dev/$dev
163
atf_check -o match:"there are NO registered reservation keys" sg_persist -nk /dev/$dev
164
}
165
prout_clear_cleanup()
166
{
167
cleanup
168
}
169
170
171
atf_test_case prout_register cleanup
172
prout_register_head()
173
{
174
atf_set "descr" "PERSISTENT RESERVATION OUT with the REGISTER service action"
175
atf_set "require.user" "root"
176
atf_set "require.progs" sg_persist ctladm
177
}
178
prout_register_body()
179
{
180
create_ramdisk
181
atf_check sg_persist -n --out --param-rk=0 --param-sark=$RESERVATION_KEY -G /dev/$dev
182
atf_check -o match:$RESERVATION_KEY sg_persist -nk /dev/$dev
183
}
184
prout_register_cleanup()
185
{
186
cleanup
187
}
188
189
atf_test_case prout_register_duplicate cleanup
190
prout_register_duplicate_head()
191
{
192
atf_set "descr" "attempting to register a key twice should fail"
193
atf_set "require.user" "root"
194
atf_set "require.progs" sg_persist ctladm
195
}
196
prout_register_duplicate_body()
197
{
198
create_ramdisk
199
atf_check sg_persist -n --out --param-rk=0 --param-sark=$RESERVATION_KEY -G /dev/$dev
200
atf_check -s exit:24 -e match:"Reservation conflict" sg_persist -n --out --param-rk=0 --param-sark=$RESERVATION_KEY -G /dev/$dev
201
atf_check -o match:$RESERVATION_KEY sg_persist -nk /dev/$dev
202
}
203
prout_register_duplicate_cleanup()
204
{
205
cleanup
206
}
207
208
atf_test_case prout_register_huge_cdb cleanup
209
prout_register_huge_cdb_head()
210
{
211
atf_set "descr" "PERSISTENT RESERVATION OUT with an enormous CDB size should not cause trouble"
212
atf_set "require.user" "root"
213
atf_set "require.progs" sg_persist ctladm
214
}
215
prout_register_huge_cdb_body()
216
{
217
create_ramdisk
218
219
atf_check -s exit:1 $(atf_get_srcdir)/prout_register_huge_cdb $LUN
220
}
221
prout_register_huge_cdb_cleanup()
222
{
223
cleanup
224
}
225
226
atf_test_case prout_register_unregister cleanup
227
prout_register_unregister_head()
228
{
229
atf_set "descr" "use PERSISTENT RESERVATION OUT with the REGISTER service action to remove a prior registration"
230
atf_set "require.user" "root"
231
atf_set "require.progs" sg_persist ctladm
232
}
233
prout_register_unregister_body()
234
{
235
create_ramdisk
236
# First register a key
237
atf_check sg_persist -n --out --param-rk=0 --param-sark=$RESERVATION_KEY -G /dev/$dev
238
# Then unregister it
239
atf_check sg_persist -n --out --param-sark=0 --param-rk=$RESERVATION_KEY -G /dev/$dev
240
# Finally, check that no keys are registered
241
atf_check -o match:"there are NO registered reservation keys" sg_persist -nk /dev/$dev
242
}
243
prout_register_unregister_cleanup()
244
{
245
cleanup
246
}
247
248
atf_test_case prout_release cleanup
249
prout_release_head()
250
{
251
atf_set "descr" "PERSISTENT RESERVATION OUT with the RESERVE service action"
252
atf_set "require.user" "root"
253
atf_set "require.progs" sg_persist ctladm
254
}
255
prout_release_body()
256
{
257
create_ramdisk
258
259
# First register a key
260
atf_check sg_persist -n --out --param-rk=0 --param-sark=$RESERVATION_KEY -G /dev/$dev
261
262
# Then make a reservation using that key
263
atf_check sg_persist -n --out --param-rk=$RESERVATION_KEY --reserve --prout-type=8 /dev/$dev
264
atf_check sg_persist -n --out --param-rk=$RESERVATION_KEY --prout-type=8 --release /dev/$dev
265
266
# Now check that the reservation is released
267
atf_check -o match:"there is NO reservation held" sg_persist -nr /dev/$dev
268
# But the registration shouldn't be.
269
atf_check -o match:$RESERVATION_KEY sg_persist -nk /dev/$dev
270
}
271
prout_release_cleanup()
272
{
273
cleanup
274
}
275
276
277
atf_test_case prout_reserve cleanup
278
prout_reserve_head()
279
{
280
atf_set "descr" "PERSISTENT RESERVATION OUT with the RESERVE service action"
281
atf_set "require.user" "root"
282
atf_set "require.progs" sg_persist ctladm
283
}
284
prout_reserve_body()
285
{
286
create_ramdisk
287
# First register a key
288
atf_check sg_persist -n --out --param-rk=0 --param-sark=$RESERVATION_KEY -G /dev/$dev
289
# Then make a reservation using that key
290
atf_check sg_persist -n --out --param-rk=$RESERVATION_KEY --reserve --prout-type=8 /dev/$dev
291
# Finally, check that the reservation is correct
292
cat > expected <<HERE
293
PR generation=0x1
294
Key=0xdeadbeef1a7ebabe
295
All target ports bit clear
296
Relative port address: 0x0
297
<< Reservation holder >>
298
scope: LU_SCOPE, type: Exclusive Access, all registrants
299
Transport Id of initiator:
300
Parallel SCSI initiator SCSI address: 0x1
301
relative port number (of corresponding target): 0x0
302
HERE
303
atf_check -o file:expected sg_persist -ns /dev/$dev
304
}
305
prout_reserve_cleanup()
306
{
307
cleanup
308
}
309
310
atf_test_case prout_reserve_bad_scope cleanup
311
prout_reserve_bad_scope_head()
312
{
313
atf_set "descr" "PERSISTENT RESERVATION OUT will be rejected with an unknown scope field"
314
atf_set "require.user" "root"
315
atf_set "require.progs" sg_persist camcontrol ctladm
316
}
317
prout_reserve_bad_scope_body()
318
{
319
create_ramdisk
320
# First register a key
321
atf_check sg_persist -n --out --param-rk=0 --param-sark=$RESERVATION_KEY -G /dev/$dev
322
323
# Then make a reservation using that key
324
atf_check -s exit:1 -e match:"ILLEGAL REQUEST asc:24,0 .Invalid field in CDB." camcontrol persist $dev -o reserve -k $RESERVATION_KEY -T read_shared -s 15 -v
325
326
# Finally, check that nothing has been reserved
327
atf_check -o match:"there is NO reservation held" sg_persist -nr /dev/$dev
328
}
329
prout_reserve_bad_scope_cleanup()
330
{
331
cleanup
332
}
333
334
335
atf_init_test_cases()
336
{
337
atf_add_test_case prin_read_full_status_empty
338
atf_add_test_case prin_read_keys_empty
339
atf_add_test_case prin_read_reservation_empty
340
atf_add_test_case prin_report_capabilities
341
atf_add_test_case prout_clear
342
atf_add_test_case prout_register
343
atf_add_test_case prout_register_duplicate
344
atf_add_test_case prout_register_huge_cdb
345
atf_add_test_case prout_register_unregister
346
atf_add_test_case prout_release
347
atf_add_test_case prout_reserve
348
atf_add_test_case prout_reserve_bad_scope
349
}
350
351