3 # Copyright (C) 2018-2020 Red Hat Inc.
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are
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
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).
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"
54 files
="eflags.out eflags.err"
57 cleanup_fn
rm -f $files
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 ))
69 CAN_MULTI_CONN=$(( 1 << 8 ))
70 SEND_RESIZE=$(( 1 << 9 ))
71 SEND_CACHE=$(( 1 << 10 ))
72 SEND_FAST_ZERO=$(( 1 << 11 ))
76 # Prepend a check for internal caching to the script on stdin.
78 if test -f $tmpdir/seen_$1; then
79 echo "repeat call to $1" >>'"$PWD/eflags.err"'
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
"
101 echo "error
: $@
(actual flags were $
(printf 0x
%x
$eflags))"
105 #----------------------------------------------------------------------
108 # nbdkit supports DF if client requests SR.
117 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
118 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF
"
120 #----------------------------------------------------------------------
124 # When SR is disabled, so is the DF flag.
126 do_nbdkit --no-sr <<'EOF'
133 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY )) ] ||
134 fail "$LINENO: expected HAS_FLAGS|READ_ONLY
"
136 #----------------------------------------------------------------------
147 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
148 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF
"
150 #----------------------------------------------------------------------
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.
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 #----------------------------------------------------------------------
172 # NBD_FLAG_SEND_WRITE_ZEROES is omitted when a filter says so.
174 do_nbdkit --filter=nozero <<'EOF'
182 [ $eflags -eq $(( HAS_FLAGS|SEND_DF )) ] ||
183 fail "$LINENO: expected HAS_FLAGS|SEND_DF
"
185 #----------------------------------------------------------------------
190 # Absolute minimum in flags.
192 do_nbdkit --no-sr --filter=nozero <<'EOF'
200 [ $eflags -eq $(( HAS_FLAGS )) ] ||
201 fail "$LINENO: expected HAS_FLAGS
"
203 #----------------------------------------------------------------------
207 # The -r flag overrides the plugin so this behaves as if can_write is
218 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
219 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF
"
221 #----------------------------------------------------------------------
226 # If writing is not possible then trim and zero are always disabled.
238 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
239 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF
"
241 #----------------------------------------------------------------------
247 # This is a formality, but check it's the same as above.
259 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
260 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF
"
262 #----------------------------------------------------------------------
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 #----------------------------------------------------------------------
286 is_rotational) exit 0 ;;
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 #----------------------------------------------------------------------
303 is_rotational) exit 0 ;;
308 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|ROTATIONAL|SEND_DF )) ] ||
309 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|ROTATIONAL|SEND_DF
"
311 #----------------------------------------------------------------------
319 can_fua) echo "native
" ;;
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 #----------------------------------------------------------------------
332 # Setting read-only should ignore can_fua.
338 can_fua) echo "native
" ;;
343 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
344 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF
"
346 #----------------------------------------------------------------------
351 # Setting read-only does not ignore can_flush.
362 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_FLUSH|SEND_DF )) ] ||
363 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_FLUSH|SEND_DF
"
365 #----------------------------------------------------------------------
369 # When can_flush is true, nbdkit reckons it can emulate fua with flush.
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 #----------------------------------------------------------------------
388 # Explicit request for no fua emulation.
395 can_fua) echo "none
" ;;
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 #----------------------------------------------------------------------
405 # can_multi_conn=true
410 can_multi_conn) exit 0 ;;
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 #----------------------------------------------------------------------
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'
428 can_multi_conn) exit 0 ;;
433 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
434 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF
"
436 #----------------------------------------------------------------------
438 # thread_model=serialize_connections
439 # can_multi_conn=true
441 # A single-threaded server does not allow multiple connections.
446 can_multi_conn) exit 0 ;;
447 thread_model) echo "serialize_connections
" ;;
452 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
453 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF
"
455 #----------------------------------------------------------------------
462 can_cache) echo "emulate
" ;;
467 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF|SEND_CACHE )) ] ||
468 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF|SEND_CACHE
"
470 #----------------------------------------------------------------------
472 # --filter=nocache cachemode=none
475 # Filters override the plugin's choice of caching.
477 late_args="cachemode
=none
" do_nbdkit -r --filter=nocache <<'EOF'
480 can_cache) echo "emulate
" ;;
485 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
486 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF
"
488 #----------------------------------------------------------------------
492 # Fast zero support isn't advertised without regular zero support
497 can_fast_zero) exit 0 ;;
502 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
503 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF
"
505 #----------------------------------------------------------------------
510 # Fast zero support isn't advertised without regular zero support
512 do_nbdkit --filter=nozero <<'EOF'
516 can_fast_zero) exit 0 ;;
521 [ $eflags -eq $(( HAS_FLAGS|SEND_DF )) ] ||
522 fail "$LINENO: expected HAS_FLAGS|SEND_DF
"
524 #----------------------------------------------------------------------
528 # Fast zero support is omitted for a plugin that has .zero but did not opt in
539 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
540 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF
"
542 #----------------------------------------------------------------------
545 # can_fast_zero=false
547 # Fast zero support is omitted if the plugin says so
554 can_fast_zero) exit 3 ;;
559 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
560 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF
"
562 #----------------------------------------------------------------------
565 # can_fast_zero=false
567 # Fast zero support is omitted if the plugin says so
573 can_fast_zero) exit 3 ;;
578 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
579 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF
"