Update Red Hat Copyright Notices
[nbdkit.git] / tests / test-eflags.sh
blob09f550016f41e1c605854e8bce9c556008559798
1 #!/usr/bin/env bash
2 # nbdkit
3 # Copyright Red Hat
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are
7 # met:
9 # * Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer.
12 # * Redistributions in binary form must reproduce the above copyright
13 # notice, this list of conditions and the following disclaimer in the
14 # documentation and/or other materials provided with the distribution.
16 # * Neither the name of Red Hat nor the names of its contributors may be
17 # used to endorse or promote products derived from this software without
18 # specific prior written permission.
20 # THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
21 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
24 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
27 # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
30 # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 # SUCH DAMAGE.
33 # Test export flags.
35 # Run nbdkit with various can_* callbacks defined and with or without
36 # the -r flag, and check that nbdkit constructs the export flags
37 # controlling READ_ONLY, ROTATIONAL, SEND_TRIM, etc. as expected.
39 # We use the shell plugin because it gives maximum control over the
40 # can_* callbacks (at least, max without having to write a C plugin).
42 source ./functions.sh
43 set -e
45 requires_plugin sh
46 requires qemu-nbd --version
48 # This test uses the ‘qemu-nbd --list’ option added in qemu 4.0.
49 if ! qemu-nbd --help | grep -sq -- --list; then
50 echo "$0: skipping because qemu-nbd does not support the --list option"
51 exit 77
54 files="eflags.out eflags.err"
55 late_args=
56 rm -f $files
57 cleanup_fn rm -f $files
59 # The export flags.
60 # See also common/protocol/protocol.h
61 HAS_FLAGS=$(( 1 << 0 ))
62 READ_ONLY=$(( 1 << 1 ))
63 SEND_FLUSH=$(( 1 << 2 ))
64 SEND_FUA=$(( 1 << 3 ))
65 ROTATIONAL=$(( 1 << 4 ))
66 SEND_TRIM=$(( 1 << 5 ))
67 SEND_WRITE_ZEROES=$(( 1 << 6 ))
68 SEND_DF=$(( 1 << 7 ))
69 CAN_MULTI_CONN=$(( 1 << 8 ))
70 SEND_RESIZE=$(( 1 << 9 ))
71 SEND_CACHE=$(( 1 << 10 ))
72 SEND_FAST_ZERO=$(( 1 << 11 ))
74 do_nbdkit ()
76 # Prepend a check for internal caching to the script on stdin.
77 { printf %s '
78 if test -f $tmpdir/seen_$1; then
79 echo "repeat call to $1" >>'"$PWD/eflags.err"'
80 else
81 touch $tmpdir/seen_$1
83 '; cat; } | nbdkit -v -U - "$@" sh - $late_args \
84 --run 'qemu-nbd --list -k $unixsocket' |
85 grep -E "flags: 0x" | grep -Eoi '0x[a-f0-9]+' >eflags.out 2>eflags.err
86 printf eflags=; cat eflags.out
88 # Convert hex flags to decimal and assign it to $eflags.
89 eflags=$(printf "%d" $(cat eflags.out))
91 # See if nbdkit failed to cache a callback.
92 if test -s eflags.err; then
93 echo "error: nbdkit did not cache callbacks properly"
94 cat eflags.err
95 exit 1
99 fail ()
101 echo "error: $@ (actual flags were $(printf 0x%x $eflags))"
102 exit 1
105 #----------------------------------------------------------------------
106 # can_write=false
108 # nbdkit supports DF if client requests SR.
110 do_nbdkit <<'EOF'
111 case "$1" in
112 get_size) echo 1M ;;
113 *) exit 2 ;;
114 esac
117 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
118 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF"
120 #----------------------------------------------------------------------
121 # --no-sr
122 # can_write=false
124 # When SR is disabled, so is the DF flag.
126 do_nbdkit --no-sr <<'EOF'
127 case "$1" in
128 get_size) echo 1M ;;
129 *) exit 2 ;;
130 esac
133 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY )) ] ||
134 fail "$LINENO: expected HAS_FLAGS|READ_ONLY"
136 #----------------------------------------------------------------------
137 # -r
138 # can_write=false
140 do_nbdkit -r <<'EOF'
141 case "$1" in
142 get_size) echo 1M ;;
143 *) exit 2 ;;
144 esac
147 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
148 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF"
150 #----------------------------------------------------------------------
151 # can_write=true
153 # NBD_FLAG_SEND_WRITE_ZEROES and NBD_FLAG_SEND_FAST_ZERO are set on writable
154 # connections even when can_zero returns false, because nbdkit reckons it
155 # can emulate zeroing using pwrite.
157 do_nbdkit <<'EOF'
158 case "$1" in
159 get_size) echo 1M ;;
160 can_write) exit 0 ;;
161 *) exit 2 ;;
162 esac
165 [ $eflags -eq $(( HAS_FLAGS|SEND_WRITE_ZEROES|SEND_DF|SEND_FAST_ZERO )) ] ||
166 fail "$LINENO: expected HAS_FLAGS|SEND_WRITE_ZEROES|SEND_DF|SEND_FAST_ZERO"
168 #----------------------------------------------------------------------
169 # --filter=nozero
170 # can_write=true
172 # NBD_FLAG_SEND_WRITE_ZEROES is omitted when a filter says so.
174 do_nbdkit --filter=nozero <<'EOF'
175 case "$1" in
176 get_size) echo 1M ;;
177 can_write) exit 0 ;;
178 *) exit 2 ;;
179 esac
182 [ $eflags -eq $(( HAS_FLAGS|SEND_DF )) ] ||
183 fail "$LINENO: expected HAS_FLAGS|SEND_DF"
185 #----------------------------------------------------------------------
186 # --no=sr
187 # --filter=nozero
188 # can_write=true
190 # Absolute minimum in flags.
192 do_nbdkit --no-sr --filter=nozero <<'EOF'
193 case "$1" in
194 get_size) echo 1M ;;
195 can_write) exit 0 ;;
196 *) exit 2 ;;
197 esac
200 [ $eflags -eq $(( HAS_FLAGS )) ] ||
201 fail "$LINENO: expected HAS_FLAGS"
203 #----------------------------------------------------------------------
204 # -r
205 # can_write=true
207 # The -r flag overrides the plugin so this behaves as if can_write is
208 # false.
210 do_nbdkit -r <<'EOF'
211 case "$1" in
212 get_size) echo 1M ;;
213 can_write) exit 0 ;;
214 *) exit 2 ;;
215 esac
218 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
219 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF"
221 #----------------------------------------------------------------------
222 # can_write=false
223 # can_trim=true
224 # can_zero=true
226 # If writing is not possible then trim and zero are always disabled.
228 do_nbdkit <<'EOF'
229 case "$1" in
230 get_size) echo 1M ;;
231 can_write) exit 3 ;;
232 can_trim) exit 0 ;;
233 can_zero) exit 0 ;;
234 *) exit 2 ;;
235 esac
238 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
239 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF"
241 #----------------------------------------------------------------------
242 # -r
243 # can_write=false
244 # can_trim=true
245 # can_zero=true
247 # This is a formality, but check it's the same as above.
249 do_nbdkit -r <<'EOF'
250 case "$1" in
251 get_size) echo 1M ;;
252 can_write) exit 3 ;;
253 can_trim) exit 0 ;;
254 can_zero) exit 0 ;;
255 *) exit 2 ;;
256 esac
259 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
260 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF"
262 #----------------------------------------------------------------------
263 # can_write=true
264 # can_trim=true
266 do_nbdkit <<'EOF'
267 case "$1" in
268 get_size) echo 1M ;;
269 can_write) exit 0 ;;
270 can_trim) exit 0 ;;
271 *) exit 2 ;;
272 esac
275 [ $eflags -eq $(( HAS_FLAGS|SEND_TRIM|SEND_WRITE_ZEROES|SEND_DF|SEND_FAST_ZERO )) ] ||
276 fail "$LINENO: expected HAS_FLAGS|SEND_TRIM|SEND_WRITE_ZEROES|SEND_DF|SEND_FAST_ZERO"
278 #----------------------------------------------------------------------
279 # can_write=true
280 # is_rotational=true
282 do_nbdkit <<'EOF'
283 case "$1" in
284 get_size) echo 1M ;;
285 can_write) exit 0 ;;
286 is_rotational) exit 0 ;;
287 *) exit 2 ;;
288 esac
291 [ $eflags -eq $(( HAS_FLAGS|ROTATIONAL|SEND_WRITE_ZEROES|SEND_DF|SEND_FAST_ZERO )) ] ||
292 fail "$LINENO: expected HAS_FLAGS|ROTATIONAL|SEND_WRITE_ZEROES|SEND_DF|SEND_FAST_ZERO"
294 #----------------------------------------------------------------------
295 # -r
296 # can_write=true
297 # is_rotational=true
299 do_nbdkit -r <<'EOF'
300 case "$1" in
301 get_size) echo 1M ;;
302 can_write) exit 0 ;;
303 is_rotational) exit 0 ;;
304 *) exit 2 ;;
305 esac
308 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|ROTATIONAL|SEND_DF )) ] ||
309 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|ROTATIONAL|SEND_DF"
311 #----------------------------------------------------------------------
312 # can_write=true
313 # can_fua=native
315 do_nbdkit <<'EOF'
316 case "$1" in
317 get_size) echo 1M ;;
318 can_write) exit 0 ;;
319 can_fua) echo "native" ;;
320 *) exit 2 ;;
321 esac
324 [ $eflags -eq $(( HAS_FLAGS|SEND_FUA|SEND_WRITE_ZEROES|SEND_DF|SEND_FAST_ZERO )) ] ||
325 fail "$LINENO: expected HAS_FLAGS|SEND_FUA|SEND_WRITE_ZEROES|SEND_DF|SEND_FAST_ZERO"
327 #----------------------------------------------------------------------
328 # -r
329 # can_write=true
330 # can_fua=native
332 # Setting read-only should ignore can_fua.
334 do_nbdkit -r <<'EOF'
335 case "$1" in
336 get_size) echo 1M ;;
337 can_write) exit 0 ;;
338 can_fua) echo "native" ;;
339 *) exit 2 ;;
340 esac
343 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
344 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF"
346 #----------------------------------------------------------------------
347 # -r
348 # can_write=true
349 # can_flush=true
351 # Setting read-only does not ignore can_flush.
353 do_nbdkit -r <<'EOF'
354 case "$1" in
355 get_size) echo 1M ;;
356 can_write) exit 0 ;;
357 can_flush) exit 0 ;;
358 *) exit 2 ;;
359 esac
362 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_FLUSH|SEND_DF )) ] ||
363 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_FLUSH|SEND_DF"
365 #----------------------------------------------------------------------
366 # can_write=true
367 # can_flush=true
369 # When can_flush is true, nbdkit reckons it can emulate fua with flush.
371 do_nbdkit <<'EOF'
372 case "$1" in
373 get_size) echo 1M ;;
374 can_write) exit 0 ;;
375 can_flush) exit 0 ;;
376 *) exit 2 ;;
377 esac
380 [ $eflags -eq $(( HAS_FLAGS|SEND_FLUSH|SEND_FUA|SEND_WRITE_ZEROES|SEND_DF|SEND_FAST_ZERO )) ] ||
381 fail "$LINENO: expected HAS_FLAGS|SEND_FLUSH|SEND_FUA|SEND_WRITE_ZEROES|SEND_DF|SEND_FAST_ZERO"
383 #----------------------------------------------------------------------
384 # can_write=true
385 # can_flush=true
386 # can_fua=none
388 # Explicit request for no fua emulation.
390 do_nbdkit <<'EOF'
391 case "$1" in
392 get_size) echo 1M ;;
393 can_write) exit 0 ;;
394 can_flush) exit 0 ;;
395 can_fua) echo "none" ;;
396 *) exit 2 ;;
397 esac
400 [ $eflags -eq $(( HAS_FLAGS|SEND_FLUSH|SEND_WRITE_ZEROES|SEND_DF|SEND_FAST_ZERO )) ] ||
401 fail "$LINENO: expected HAS_FLAGS|SEND_FLUSH|SEND_WRITE_ZEROES|SEND_DF|SEND_FAST_ZERO"
403 #----------------------------------------------------------------------
404 # -r
405 # can_multi_conn=true
407 do_nbdkit -r <<'EOF'
408 case "$1" in
409 get_size) echo 1M ;;
410 can_multi_conn) exit 0 ;;
411 *) exit 2 ;;
412 esac
415 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF|CAN_MULTI_CONN )) ] ||
416 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF|CAN_MULTI_CONN"
418 #----------------------------------------------------------------------
419 # -r
420 # --filter=noparallel serialize=connections
421 # can_multi_conn=true
423 # A single-threaded server does not allow multiple connections.
425 late_args="serialize=connections" do_nbdkit -r --filter=noparallel <<'EOF'
426 case "$1" in
427 get_size) echo 1M ;;
428 can_multi_conn) exit 0 ;;
429 *) exit 2 ;;
430 esac
433 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
434 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF"
436 #----------------------------------------------------------------------
437 # -r
438 # thread_model=serialize_connections
439 # can_multi_conn=true
441 # A single-threaded server does not allow multiple connections.
443 do_nbdkit -r <<'EOF'
444 case "$1" in
445 get_size) echo 1M ;;
446 can_multi_conn) exit 0 ;;
447 thread_model) echo "serialize_connections" ;;
448 *) exit 2 ;;
449 esac
452 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
453 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF"
455 #----------------------------------------------------------------------
456 # -r
457 # can_cache=emulate
459 do_nbdkit -r <<'EOF'
460 case "$1" in
461 get_size) echo 1M ;;
462 can_cache) echo "emulate" ;;
463 *) exit 2 ;;
464 esac
467 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF|SEND_CACHE )) ] ||
468 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF|SEND_CACHE"
470 #----------------------------------------------------------------------
471 # -r
472 # --filter=nocache cachemode=none
473 # can_cache=emulate
475 # Filters override the plugin's choice of caching.
477 late_args="cachemode=none" do_nbdkit -r --filter=nocache <<'EOF'
478 case "$1" in
479 get_size) echo 1M ;;
480 can_cache) echo "emulate" ;;
481 *) exit 2 ;;
482 esac
485 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
486 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF"
488 #----------------------------------------------------------------------
489 # -r
490 # can_fast_zero=true
492 # Fast zero support isn't advertised without regular zero support
494 do_nbdkit -r <<'EOF'
495 case "$1" in
496 get_size) echo 1M ;;
497 can_fast_zero) exit 0 ;;
498 *) exit 2 ;;
499 esac
502 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
503 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF"
505 #----------------------------------------------------------------------
506 # --filter=nozero
507 # can_write=true
508 # can_fast_zero=true
510 # Fast zero support isn't advertised without regular zero support
512 do_nbdkit --filter=nozero <<'EOF'
513 case "$1" in
514 get_size) echo 1M ;;
515 can_write) exit 0 ;;
516 can_fast_zero) exit 0 ;;
517 *) exit 2 ;;
518 esac
521 [ $eflags -eq $(( HAS_FLAGS|SEND_DF )) ] ||
522 fail "$LINENO: expected HAS_FLAGS|SEND_DF"
524 #----------------------------------------------------------------------
525 # can_write=true
526 # can_zero=true
528 # Fast zero support is omitted for a plugin that has .zero but did not opt in
530 do_nbdkit -r <<'EOF'
531 case "$1" in
532 get_size) echo 1M ;;
533 can_write) exit 0 ;;
534 can_zero) exit 0 ;;
535 *) exit 2 ;;
536 esac
539 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
540 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF"
542 #----------------------------------------------------------------------
543 # can_write=true
544 # can_zero=true
545 # can_fast_zero=false
547 # Fast zero support is omitted if the plugin says so
549 do_nbdkit -r <<'EOF'
550 case "$1" in
551 get_size) echo 1M ;;
552 can_write) exit 0 ;;
553 can_zero) exit 0 ;;
554 can_fast_zero) exit 3 ;;
555 *) exit 2 ;;
556 esac
559 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
560 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF"
562 #----------------------------------------------------------------------
563 # can_write=true
564 # can_zero=false
565 # can_fast_zero=false
567 # Fast zero support is omitted if the plugin says so
569 do_nbdkit -r <<'EOF'
570 case "$1" in
571 get_size) echo 1M ;;
572 can_write) exit 0 ;;
573 can_fast_zero) exit 3 ;;
574 *) exit 2 ;;
575 esac
578 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
579 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF"