3 # Copyright (C) 2018-2019 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).
45 requires qemu-nbd
--version
47 # This test uses the ‘qemu-nbd --list’ option added in qemu 4.0.
48 if ! qemu-nbd
--help |
grep -sq -- --list; then
49 echo "$0: skipping because qemu-nbd does not support the --list option"
56 cleanup_fn
rm -f $files
59 # See also common/protocol/protocol.h
60 HAS_FLAGS
=$
(( 1 << 0 ))
61 READ_ONLY=$(( 1 << 1 ))
62 SEND_FLUSH=$(( 1 << 2 ))
63 SEND_FUA=$(( 1 << 3 ))
64 ROTATIONAL=$(( 1 << 4 ))
65 SEND_TRIM=$(( 1 << 5 ))
66 SEND_WRITE_ZEROES=$(( 1 << 6 ))
68 CAN_MULTI_CONN=$(( 1 << 8 ))
69 SEND_RESIZE=$(( 1 << 9 ))
70 SEND_CACHE=$(( 1 << 10 ))
71 SEND_FAST_ZERO=$(( 1 << 11 ))
75 nbdkit -v -U - "$@" sh - $late_args --run 'qemu-nbd --list -k $unixsocket' |
76 grep -E "flags: 0x
" | grep -Eoi '0x[a-f0-9]+' > eflags.out
77 printf eflags=; cat eflags.out
79 # Convert hex flags to decimal and assign it to $eflags.
80 eflags=$(printf "%d
" $(cat eflags.out))
85 echo "error
: $@
(actual flags were $
(printf 0x
%x
$eflags))"
89 #----------------------------------------------------------------------
92 # nbdkit supports DF if client requests SR.
101 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
102 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF
"
104 #----------------------------------------------------------------------
108 # When SR is disabled, so is the DF flag.
110 do_nbdkit --no-sr <<'EOF'
117 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY )) ] ||
118 fail "$LINENO: expected HAS_FLAGS|READ_ONLY
"
120 #----------------------------------------------------------------------
131 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
132 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF
"
134 #----------------------------------------------------------------------
137 # NBD_FLAG_SEND_WRITE_ZEROES and NBD_FLAG_SEND_FAST_ZERO are set on writable
138 # connections even when can_zero returns false, because nbdkit reckons it
139 # can emulate zeroing using pwrite.
149 [ $eflags -eq $(( HAS_FLAGS|SEND_WRITE_ZEROES|SEND_DF|SEND_FAST_ZERO )) ] ||
150 fail "$LINENO: expected HAS_FLAGS|SEND_WRITE_ZEROES|SEND_DF|SEND_FAST_ZERO
"
152 #----------------------------------------------------------------------
156 # NBD_FLAG_SEND_WRITE_ZEROES is omitted when a filter says so.
158 do_nbdkit --filter=nozero <<'EOF'
166 [ $eflags -eq $(( HAS_FLAGS|SEND_DF )) ] ||
167 fail "$LINENO: expected HAS_FLAGS|SEND_DF
"
169 #----------------------------------------------------------------------
174 # Absolute minimum in flags.
176 do_nbdkit --no-sr --filter=nozero <<'EOF'
184 [ $eflags -eq $(( HAS_FLAGS )) ] ||
185 fail "$LINENO: expected HAS_FLAGS
"
187 #----------------------------------------------------------------------
191 # The -r flag overrides the plugin so this behaves as if can_write is
202 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
203 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF
"
205 #----------------------------------------------------------------------
210 # If writing is not possible then trim and zero are always disabled.
222 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
223 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF
"
225 #----------------------------------------------------------------------
231 # This is a formality, but check it's the same as above.
243 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
244 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF
"
246 #----------------------------------------------------------------------
259 [ $eflags -eq $(( HAS_FLAGS|SEND_TRIM|SEND_WRITE_ZEROES|SEND_DF|SEND_FAST_ZERO )) ] ||
260 fail "$LINENO: expected HAS_FLAGS|SEND_TRIM|SEND_WRITE_ZEROES|SEND_DF|SEND_FAST_ZERO
"
262 #----------------------------------------------------------------------
270 is_rotational) exit 0 ;;
275 [ $eflags -eq $(( HAS_FLAGS|ROTATIONAL|SEND_WRITE_ZEROES|SEND_DF|SEND_FAST_ZERO )) ] ||
276 fail "$LINENO: expected HAS_FLAGS|ROTATIONAL|SEND_WRITE_ZEROES|SEND_DF|SEND_FAST_ZERO
"
278 #----------------------------------------------------------------------
287 is_rotational) exit 0 ;;
292 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|ROTATIONAL|SEND_DF )) ] ||
293 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|ROTATIONAL|SEND_DF
"
295 #----------------------------------------------------------------------
303 can_fua) echo "native
" ;;
308 [ $eflags -eq $(( HAS_FLAGS|SEND_FUA|SEND_WRITE_ZEROES|SEND_DF|SEND_FAST_ZERO )) ] ||
309 fail "$LINENO: expected HAS_FLAGS|SEND_FUA|SEND_WRITE_ZEROES|SEND_DF|SEND_FAST_ZERO
"
311 #----------------------------------------------------------------------
316 # Setting read-only should ignore can_fua.
322 can_fua) echo "native
" ;;
327 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
328 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF
"
330 #----------------------------------------------------------------------
334 # When can_flush is true, nbdkit reckons it can emulate fua with flush.
345 [ $eflags -eq $(( HAS_FLAGS|SEND_FLUSH|SEND_FUA|SEND_WRITE_ZEROES|SEND_DF|SEND_FAST_ZERO )) ] ||
346 fail "$LINENO: expected HAS_FLAGS|SEND_FLUSH|SEND_FUA|SEND_WRITE_ZEROES|SEND_DF|SEND_FAST_ZERO
"
348 #----------------------------------------------------------------------
353 # Explicit request for no fua emulation.
360 can_fua) echo "none
" ;;
365 [ $eflags -eq $(( HAS_FLAGS|SEND_FLUSH|SEND_WRITE_ZEROES|SEND_DF|SEND_FAST_ZERO )) ] ||
366 fail "$LINENO: expected HAS_FLAGS|SEND_FLUSH|SEND_WRITE_ZEROES|SEND_DF|SEND_FAST_ZERO
"
368 #----------------------------------------------------------------------
370 # can_multi_conn=true
375 can_multi_conn) exit 0 ;;
380 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF|CAN_MULTI_CONN )) ] ||
381 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF|CAN_MULTI_CONN
"
383 #----------------------------------------------------------------------
385 # --filter=noparallel serialize=connections
386 # can_multi_conn=true
388 # A single-threaded server does not allow multiple connections.
390 late_args="serialize
=connections
" do_nbdkit -r --filter=noparallel <<'EOF'
393 can_multi_conn) exit 0 ;;
398 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
399 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF
"
401 #----------------------------------------------------------------------
403 # thread_model=serialize_connections
404 # can_multi_conn=true
406 # A single-threaded server does not allow multiple connections.
411 can_multi_conn) exit 0 ;;
412 thread_model) echo "serialize_connections
" ;;
417 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
418 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF
"
420 #----------------------------------------------------------------------
427 can_cache) echo "emulate
" ;;
432 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF|SEND_CACHE )) ] ||
433 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF|SEND_CACHE
"
435 #----------------------------------------------------------------------
437 # --filter=nocache cachemode=none
440 # Filters override the plugin's choice of caching.
442 late_args="cachemode
=none
" do_nbdkit -r --filter=nocache <<'EOF'
445 can_cache) echo "emulate
" ;;
450 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
451 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF
"
453 #----------------------------------------------------------------------
457 # Fast zero support isn't advertised without regular zero support
462 can_fast_zero) exit 0 ;;
467 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
468 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF
"
470 #----------------------------------------------------------------------
475 # Fast zero support isn't advertised without regular zero support
477 do_nbdkit --filter=nozero <<'EOF'
481 can_fast_zero) exit 0 ;;
486 [ $eflags -eq $(( HAS_FLAGS|SEND_DF )) ] ||
487 fail "$LINENO: expected HAS_FLAGS|SEND_DF
"
489 #----------------------------------------------------------------------
493 # Fast zero support is omitted for a plugin that has .zero but did not opt in
504 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
505 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF
"
507 #----------------------------------------------------------------------
510 # can_fast_zero=false
512 # Fast zero support is omitted if the plugin says so
519 can_fast_zero) exit 3 ;;
524 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
525 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF
"
527 #----------------------------------------------------------------------
530 # can_fast_zero=false
532 # Fast zero support is omitted if the plugin says so
538 can_fast_zero) exit 3 ;;
543 [ $eflags -eq $(( HAS_FLAGS|READ_ONLY|SEND_DF )) ] ||
544 fail "$LINENO: expected HAS_FLAGS|READ_ONLY|SEND_DF
"