On 12/14/18 4:16 PM, Richard W.M. Jones wrote:
---
tests/Makefile.am | 3 +
tests/test-eflags.sh | 222 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 225 insertions(+)
+# Test export flags.
+#
+# Run nbdkit with various can_* callbacks defined and with or without
+# the -r flag, and check that nbdkit constructs the export flags
+# controlling READ_ONLY, ROTATIONAL, SEND_TRIM, etc. as expected.
+#
+# We use the oldstyle (-o) protocol here because it's simpler to read
+# out the eflags.
Indeed - the client has to talk in newstyle, but not in oldstyle :)
We use the shell plugin because it gives maximum
+# control over the can_* callbacks (at least, max without having to
+# write a C plugin).
+
+source ./functions.sh
+set -e
+
+if ! socat -h >/dev/null; then
+ echo "$0: 'socat' command not available"
+ exit 77
+fi
+
+# Check 'od' command exists and can do endian swaps (which the FreeBSD
+# version cannot).
Do we need endian swaps, or can we just read one byte at a time and then
reconstruct things by hand (after all, we know the bytes are in network
order, so we don't have to worry about whether we are running on a big-
or little-endian machine to do the integer math to build up the 16-bit
value from those two bytes).
+if ! od --endian=big </dev/null >/dev/null; then
+ echo "$0: 'od' command not available or doesn't support endian
swaps"
+ exit 77
+fi
+
+files="eflags.out"
+rm -f $files
+cleanup_fn rm -f $files
+
+# The export flags.
+# See also src/protocol.h
Comment may need tweaking if I finish my patches to move src/proto* to
common/proto/. We'll see what lands first :)
+HAS_FLAGS=$(( 1 << 0 ))
+READ_ONLY=$(( 1 << 1 ))
+SEND_FLUSH=$(( 1 << 2 ))
+SEND_FUA=$(( 1 << 3 ))
+ROTATIONAL=$(( 1 << 4 ))
+SEND_TRIM=$(( 1 << 5 ))
+SEND_WRITE_ZEROES=$(( 1 << 6 ))
+
+all_flags="HAS_FLAGS READ_ONLY SEND_FLUSH SEND_FUA ROTATIONAL SEND_TRIM
SEND_WRITE_ZEROES"
Well, that's all the flags we currently drive, although more flags exist
(and we may eventually patch nbdkit to drive those, as well).
+
+do_nbdkit ()
+{
+ nbdkit -v -U - -o "$@" sh script=- --run '
+ socat -b 28 unix-connect:$unixsocket \
+ exec:"dd bs=1 skip=26 count=2 of=eflags.out status=none"
dd can portably do byteswaps, with conv=swab, but then you have to know
if you are big- or little-endian to know whether to use it.
+ '
+
+ # By adding 0 we convert the string to an integer (removing
+ # whitespace).
+ eflags=$((0 + $(od --endian=big -An -N2 -d < eflags.out)))
So back to my earlier thought of just reading 1 byte at a time and
building up the value ourselves:
eflags=$(( ($(od -An -N1 -tu1 eflags.out) << 8) |
$(od -An -N1 -j1 -tu1 eflags.out) ))
+ printf "eflags 0x%04x" $eflags
+ for f in $all_flags; do
+ [ $(( eflags & ${!f} )) -ne 0 ] && echo -n " $f"
+ done
+ echo
+}
+
+
+# no -r
+# can_write=true
+#
+# NBD_FLAG_SEND_WRITE_ZEROES is always set on writable connections
+# even if can_zero returns false, because nbdkit reckons it can
+# emulate zeroing using pwrite.
And we have the nozero filter if we want things otherwise (if you want
to use that in this test).
Otherwise, this looks sane.
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3266
Virtualization:
qemu.org |
libvirt.org