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
33 # Demonstrate various multi-conn filter behaviors.
41 requires
dd iflag
=count_bytes
</dev
/null
43 files
="test-multi-conn.out test-multi-conn.stat"
45 cleanup_fn
rm -f $files
48 export handles preamble uri
49 uri
= # will be set by --run later
54 uri = os.environ["uri"]
55 handles = int(os.environ["handles"])
57 for i in range(handles):
60 print(h[0].can_multi_conn())
63 # Demonstrate the caching present without use of filter
64 for filter
in '' '--filter=multi-conn multi-conn-mode=plugin'; do
65 nbdkit
-vf -U - sh test-multi-conn-plugin.sh
$filter \
66 --run 'handles=4 nbdsh -c "$preamble" -c "
67 # Without flush, reads cache, and writes do not affect persistent data
68 print(bytes(h[0].pread(4, 0)))
69 h[1].pwrite(b'\''next '\'', 0)
70 print(bytes(h[0].pread(4, 0)))
71 print(bytes(h[1].pread(4, 0)))
72 print(bytes(h[2].pread(4, 0)))
73 # Flushing an unrelated connection does not make writes persistent
75 print(bytes(h[0].pread(4, 0)))
76 print(bytes(h[1].pread(4, 0)))
77 print(bytes(h[2].pread(4, 0)))
78 # After write is flushed, only connections without cache see new data
80 print(bytes(h[0].pread(4, 0)))
81 print(bytes(h[1].pread(4, 0)))
82 print(bytes(h[2].pread(4, 0)))
83 print(bytes(h[3].pread(4, 0)))
84 # Flushing before reads clears the cache
87 print(bytes(h[0].pread(4, 0)))
88 print(bytes(h[2].pread(4, 0)))
89 "' > test-multi-conn.out || fail
=1
106 ) test-multi-conn.out || fail
=1
109 # Demonstrate specifics of FUA flag
110 for filter
in '' '--filter=multi-conn multi-conn-mode=plugin'; do
111 nbdkit
-vf -U - sh test-multi-conn-plugin.sh
$filter \
112 --run 'nbdsh -c "$preamble" -c "
113 # Some servers let FUA flush all outstanding requests
114 h[0].pwrite(b'\''hello '\'', 0)
115 h[0].pwrite(b'\''world.'\'', 6, nbd.CMD_FLAG_FUA)
116 print(bytes(h[1].pread(12, 0)))
117 "' > test-multi-conn.out || fail
=1
122 ) test-multi-conn.out || fail
=1
124 for filter
in '' '--filter=multi-conn multi-conn-mode=plugin'; do
125 nbdkit
-vf -U - sh test-multi-conn-plugin.sh strictfua
=1 $filter \
126 --run 'nbdsh -c "$preamble" -c "
127 # But it is also compliant for a server that only flushes the exact request
128 h[0].pwrite(b'\''hello '\'', 0)
129 h[0].pwrite(b'\''world.'\'', 6, nbd.CMD_FLAG_FUA)
130 print(bytes(h[1].pread(12, 0)))
131 # Without multi-conn, data flushed in one connection can later be reverted
132 # by a flush of earlier data in another connection
133 h[1].pwrite(b'\''H'\'', 0, nbd.CMD_FLAG_FUA)
135 print(bytes(h[2].pread(12, 0)))
138 print(bytes(h[2].pread(12, 0)))
141 print(bytes(h[2].pread(12, 0)))
142 "' > test-multi-conn.out || fail
=1
150 ) test-multi-conn.out || fail
=1
153 # Demonstrate multi-conn effects. The cache filter in writeback
154 # mode is also able to supply multi-conn by a different technique.
155 for filter
in '--filter=multi-conn' 'strictfua=1 --filter=multi-conn' \
156 '--filter=multi-conn multi-conn-mode=plugin --filter=cache' ; do
157 nbdkit
-vf -U - sh test-multi-conn-plugin.sh
$filter \
158 --run 'nbdsh -c "$preamble" -c "
159 # FUA writes are immediately visible on all connections
161 h[1].pwrite(b'\''Hello '\'', 0, nbd.CMD_FLAG_FUA)
162 print(bytes(h[0].pread(12, 0)))
163 # A flush on an unrelated connection makes all other connections consistent
164 h[1].pwrite(b'\''world.'\'', 6)
166 print(bytes(h[0].pread(12, 0)))
167 "' > test-multi-conn.out || fail
=1
173 ) test-multi-conn.out || fail
=1
176 # unsafe mode intentionally lacks consistency, use at your own risk
177 nbdkit
-vf -U - sh test-multi-conn-plugin.sh \
178 --filter=multi-conn multi-conn-mode
=unsafe \
179 --run 'nbdsh -c "$preamble" -c "
181 h[1].pwrite(b'\''Hello '\'', 0, nbd.CMD_FLAG_FUA)
182 print(bytes(h[0].pread(12, 0)))
183 h[1].pwrite(b'\''world.'\'', 6)
185 print(bytes(h[0].pread(12, 0)))
186 "' > test-multi-conn.out || fail
=1
192 ) test-multi-conn.out || fail
=1
194 # auto mode devolves to multi-conn disable when connections are serialized
195 nbdkit
-vf -U - sh test-multi-conn-plugin.sh
--filter=noparallel \
196 serialize
=connections
--filter=multi-conn
--filter=cache \
197 --run 'handles=1 nbdsh -c "$preamble"
198 ' > test-multi-conn.out || fail
=1
202 ) test-multi-conn.out || fail
=1
204 # Use --filter=stats to show track-dirty effects
205 for level
in off connection fast
; do
206 for mode
in emulate
'emulate --filter=cache' \
207 plugin
'plugin --filter=cache'; do
208 echo "setup: $level $mode" >> test-multi-conn.stat
209 # Flush with no activity
210 nbdkit
-vf -U - sh test-multi-conn-plugin.sh
--filter=multi-conn \
211 --filter=stats statsfile
=test-multi-conn.stat statsappend
=true \
212 multi-conn-track-dirty
=$level multi-conn-mode
=$mode \
213 --run 'nbdsh -c "$preamble" -c "
217 "' > test-multi-conn.out || fail
=1
218 # Client that flushes assuming multi-conn semantics
219 nbdkit
-vf -U - sh test-multi-conn-plugin.sh
--filter=multi-conn \
220 --filter=stats statsfile
=test-multi-conn.stat statsappend
=true \
221 multi-conn-track-dirty
=$level multi-conn-mode
=$mode \
222 --run 'handles=4 nbdsh -c "$preamble" -c "
230 "' > test-multi-conn.out || fail
=1
231 # Client that flushes assuming inconsistent semantics
232 nbdkit
-vf -U - sh test-multi-conn-plugin.sh
--filter=multi-conn \
233 --filter=stats statsfile
=test-multi-conn.stat statsappend
=true \
234 multi-conn-track-dirty
=$level multi-conn-mode
=$mode \
235 --run 'nbdsh -c "$preamble" -c "
244 "' > test-multi-conn.out || fail
=1
247 cat test-multi-conn.stat
253 setup
: off emulate
--filter=cache
261 setup
: off plugin
--filter=cache
265 setup
: connection emulate
268 setup
: connection emulate
--filter=cache
271 setup
: connection plugin
274 setup
: connection plugin
--filter=cache
280 setup
: fast emulate
--filter=cache
286 setup
: fast plugin
--filter=cache
290 ) <($SED -n 's/\(flush:.*ops\).*/\1/p; /^setup:/p' \
291 test-multi-conn.stat
) || fail
=1