Skip to content

Commit 87e6cd7

Browse files
James Bottomleyardbiesheuvel
authored andcommitted
selftests/efivarfs: add concurrent update tests
The delete on last close functionality can now only be tested properly by using multiple threads to hold open the variable files and testing what happens as they complete. Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
1 parent fd3aa3d commit 87e6cd7

File tree

1 file changed

+134
-0
lines changed

1 file changed

+134
-0
lines changed

tools/testing/selftests/efivarfs/efivarfs.sh

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,136 @@ test_no_set_size()
227227
exit $ret
228228
}
229229

230+
setup_test_multiple()
231+
{
232+
##
233+
# we're going to do multi-threaded tests, so create a set of
234+
# pipes for synchronization. We use pipes 1..3 to start the
235+
# stalled shell job and pipes 4..6 as indicators that the job
236+
# has started. If you need more than 3 jobs the two +3's below
237+
# need increasing
238+
##
239+
240+
declare -ag p
241+
242+
# empty is because arrays number from 0 but jobs number from 1
243+
p[0]=""
244+
245+
for f in 1 2 3 4 5 6; do
246+
p[$f]=/tmp/efivarfs_pipe${f}
247+
mknod ${p[$f]} p
248+
done
249+
250+
declare -g var=$efivarfs_mount/test_multiple-$test_guid
251+
252+
cleanup() {
253+
for f in ${p[@]}; do
254+
rm -f ${f}
255+
done
256+
if [ -e $var ]; then
257+
file_cleanup $var
258+
fi
259+
}
260+
trap cleanup exit
261+
262+
waitstart() {
263+
cat ${p[$[$1+3]]} > /dev/null
264+
}
265+
266+
waitpipe() {
267+
echo 1 > ${p[$[$1+3]]}
268+
cat ${p[$1]} > /dev/null
269+
}
270+
271+
endjob() {
272+
echo 1 > ${p[$1]}
273+
wait -n %$1
274+
}
275+
}
276+
277+
test_multiple_zero_size()
278+
{
279+
##
280+
# check for remove on last close, set up three threads all
281+
# holding the variable (one write and two reads) and then
282+
# close them sequentially (waiting for completion) and check
283+
# the state of the variable
284+
##
285+
286+
{ waitpipe 1; echo 1; } > $var 2> /dev/null &
287+
waitstart 1
288+
# zero length file should exist
289+
[ -e $var ] || exit 1
290+
# second and third delayed close
291+
{ waitpipe 2; } < $var &
292+
waitstart 2
293+
{ waitpipe 3; } < $var &
294+
waitstart 3
295+
# close first fd
296+
endjob 1
297+
# var should only be deleted on last close
298+
[ -e $var ] || exit 1
299+
# close second fd
300+
endjob 2
301+
[ -e $var ] || exit 1
302+
# file should go on last close
303+
endjob 3
304+
[ ! -e $var ] || exit 1
305+
}
306+
307+
test_multiple_create()
308+
{
309+
##
310+
# set multiple threads to access the variable but delay
311+
# the final write to check the close of 2 and 3. The
312+
# final write should succeed in creating the variable
313+
##
314+
{ waitpipe 1; printf '\x07\x00\x00\x00\x54'; } > $var &
315+
waitstart 1
316+
[ -e $var -a ! -s $var ] || exit 1
317+
{ waitpipe 2; } < $var &
318+
waitstart 2
319+
{ waitpipe 3; } < $var &
320+
waitstart 3
321+
# close second and third fds
322+
endjob 2
323+
# var should only be created (have size) on last close
324+
[ -e $var -a ! -s $var ] || exit 1
325+
endjob 3
326+
[ -e $var -a ! -s $var ] || exit 1
327+
# close first fd
328+
endjob 1
329+
# variable should still exist
330+
[ -s $var ] || exit 1
331+
file_cleanup $var
332+
}
333+
334+
test_multiple_delete_on_write() {
335+
##
336+
# delete the variable on final write; seqencing similar
337+
# to test_multiple_create()
338+
##
339+
printf '\x07\x00\x00\x00\x54' > $var
340+
chattr -i $var
341+
{ waitpipe 1; printf '\x07\x00\x00\x00'; } > $var &
342+
waitstart 1
343+
[ -e $var -a -s $var ] || exit 1
344+
{ waitpipe 2; } < $var &
345+
waitstart 2
346+
{ waitpipe 3; } < $var &
347+
waitstart 3
348+
# close first fd; write should set variable size to zero
349+
endjob 1
350+
# var should only be deleted on last close
351+
[ -e $var -a ! -s $var ] || exit 1
352+
endjob 2
353+
[ -e $var ] || exit 1
354+
# close last fd
355+
endjob 3
356+
# variable should now be removed
357+
[ ! -e $var ] || exit 1
358+
}
359+
230360
check_prereqs
231361

232362
rc=0
@@ -240,5 +370,9 @@ run_test test_open_unlink
240370
run_test test_valid_filenames
241371
run_test test_invalid_filenames
242372
run_test test_no_set_size
373+
setup_test_multiple
374+
run_test test_multiple_zero_size
375+
run_test test_multiple_create
376+
run_test test_multiple_delete_on_write
243377

244378
exit $rc

0 commit comments

Comments
 (0)