[Ocfs2-devel] [PATCH] tailtest: Add a test for the tail zeroing bug

tristan tristan.ye at oracle.com
Tue Jul 6 00:45:50 PDT 2010


Hi Joel,

I'm totally trusting the logic of your testcase to test tail zeroing.

Just two concerns as follows:

1. It should be better to make the script runnable for none-privilege 
users for the sake of security concerns.

2. Why not make variations with different bs and cs combinations

Also some other tiny comments inlined:)


Joel Becker wrote:
> This test tests tail zeroing by writing a byte at the start of a new
> file, then writing another byte at various offsets.
>
> Currently, the test uses 4K/1M filesystems.  The offsets are 10M, 1M,
> 512K, and 1K.  This tests a new write location well past the existing
> extent, right after the existing extent, in the middle of the existing
> extent but past the last valid block of the file, and inside the last
> valid block of the file.
>
> Each offset is tested twice.  First with truncation out to the new
> location, then without truncation.  This tests zeroing via truncate and
> zeroing via write.
>
> The full set of tests is run on four different filesystem
> configurations: sparse,inline-data sparse,noinline-data
> nosparse,inline-data and nosparse,noinline-data.
>
> Signed-off-by: Joel Becker <joel.becker at oracle.com>
> ---
>  programs/tailtest/tailtest |  179 ++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 179 insertions(+), 0 deletions(-)
>  create mode 100755 programs/tailtest/tailtest
>
> diff --git a/programs/tailtest/tailtest b/programs/tailtest/tailtest
> new file mode 100755
> index 0000000..5bf70f7
> --- /dev/null
> +++ b/programs/tailtest/tailtest
> @@ -0,0 +1,179 @@
> +#!/bin/bash
> +#
> +# Test for the ocfs2 tail zero bug
> +#
> +
> +_IMAGE=""
> +_MOUNTPOINT=""
> +_LOOP=""
> +
> +cleanup()
> +{
> +    [ -d "$_MOUNTPOINT" ] && umount "$_MOUNTPOINT"
> +    [ -d "$_MOUNTPOINT" ] && rmdir "$_MOUNTPOINT"
> +    [ -n "$_LOOP" ] && losetup -d "$_LOOP"
> +    [ -n "$_IMAGE" ] && rm -f "$_IMAGE"

You may also need to cleanup expected template files for comparison? if 
the test aborts abnormally.

or rmdir never succeeds. I guess using "rm -rf $MOUNTPOINT" here will be 
more aggressive to handle this.

> +}
> +trap "exitcode=\$?; cleanup 2>/dev/null && exit \$exitcode" 0
> +trap "cleanup; die \"Signal caught, exiting\"" 1 2 13 15
> +
> +die()
> +{
> +    [ -n "$*" ] && echo "$@" >&2
> +    exit 1
> +}
> +
> +make_image()
> +{
> +    local image="$1"
> +
> +    dd if=/dev/urandom of="$image" bs=1M count=1 seek=10000 conv=notrunc 2>/dev/null ||
> +        die "Unable to create image \"$image\""
> +    dd if=/dev/urandom of="$image" bs=1M count=200 conv=notrunc 2>/dev/null ||
> +        die "Unable to poison the start of image \"$image\""
> +    losetup -f --show "$image" || die "Unable to attach loopback device"
> +}
> +
> +make_fs()
> +{
> +    local device="$1"
> +    local mountpoint="$2"
> +    local extra_features="$3"
> +    case "$extra_features" in
> +        ,*) ;;
> +        *)
> +            extra_features=",$extra_features"
> +            ;;
> +    esac
> +
> +    mkfs -t ocfs2 -C 1M \
> +        --fs-features=local"$extra_features" "$device" ||
> +        die "Unable to create ocfs2 filesystem"
> +    mount -t ocfs2 "$device" "$mountpoint" ||
> +        die "Unable to mount ocfs2 filesystem"
> +}
> +
> +clean_one_test()
> +{
> +    for f in "$@"
> +    do
> +        megs="$(ls -l "$f" | awk '{printf "%lu", ($5 + 1048576 - 1) / 1048576}')"
> +        [ -z "$megs" ] && die "Unable to clean test file \"$f\""
> +        dd if=/dev/urandom of="$f" bs=1M count="${megs}" 2>/dev/null ||
> +            die "Unable to scribble over test file \"$f\""
> +        rm -f "$f" || die "Unable to remove test file \"$f\""
> +    done
> +}
> +
> +run_one_test()
> +{
> +    local device="$1"
> +    local mountpoint="$2"
> +    local offset="$3"
> +    local trunc=""
> +    [ "$4" = "true" ] && trunc="conv=notrunc"

I guess

run_one_test "$device" "$mountpoint" "$offset" "trunc"
or
run_one_test "$device" "$mountpoint" "$offset" "notrunc"

making the readers understand better.


> +
> +    local testfile="${mountpoint}/testfile"
> +    local comparefile="${mountpoint}/diff"
> +    local expectedfile="${mountpoint}/expected-$offset"
> +
> +    echo "Testing seek=$offset $trunc ..."
> +    echo -n 'a' | dd of="$testfile" bs=1 count=1 2>/dev/null
> +    umount "$mountpoint" || die "Unable to unmount \"$mountpoint\""
> +    mount -t ocfs2 "$device" "$mountpoint" ||
> +        die "Unable to remount \"$mountpoint\""
> +    echo -n 'a' | dd of="$testfile" bs=1 count=1 seek=$offset $trunc 2>/dev/null
> +    dd if="$testfile" bs=1M count=1 2>/dev/null | hexdump -C >"$comparefile"
> +    if diff -q "$comparefile" "$expectedfile" >/dev/null 2>&1;
> +    then
> +        echo "    Test passed."
> +    else
> +        echo "    Test failed.  Extent contents:"
> +        cat "$comparefile"
> +    fi
> +
> +    echo "Cleaning up after test ..."
> +    clean_one_test "$testfile" "$comparefile"
> +}
> +
> +setup_expected()
> +{
> +    local mountpoint="$1"
> +
> +    cat >"${mountpoint}/expected-10M" <<EOCAT
> +00000000  61 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |a...............|
> +00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
> +*
> +00100000
> +EOCAT
> +    [ $? = 0 ] || die "Unable to create \"expected-10M\""
> +
> +    cp "${mountpoint}/expected-10M" "${mountpoint}/expected-1M" ||
> +        die "Unable to create \"expected-1M\""
> +
> +    cat >"${mountpoint}/expected-512K" <<EOCAT
> +00000000  61 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |a...............|
> +00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
> +*
> +00080000  61                                                |a|
> +00080001
> +EOCAT
> +    [ $? = 0 ] || die "Unable to create \"expected-512K\""
> +
> +    cat >"${mountpoint}/expected-1K" <<EOCAT
> +00000000  61 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |a...............|
> +00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
> +*
> +00000400  61                                                |a|
> +00000401
> +EOCAT
> +    [ $? = 0 ] || die "Unable to create \"expected-1K\""
> +
> +}
> +
> +run_tests()
> +{
> +    local device="$1"
> +    local mountpoint="$2"
> +    local extra_features="$3"
> +
> +    echo "Generating filesystem ..."
> +    make_fs "$device" "$mountpoint" $extra_features ||
> +        die "Unable to create ocfs2 filesystem"
> +    setup_expected "$mountpoint"
> +
> +    local offset
> +    for offset in 10M 1M 512K 1K
> +    do
> +        run_one_test "$device" "$mountpoint" "$offset" "false"
> +        run_one_test "$device" "$mountpoint" "$offset" "true"
> +    done
> +
> +    echo "Destroying filesystem ..."
> +    umount "$mountpoint" || die "Unable to unmount filesystem"
> +    dd if=/dev/urandom of="$device" bs=1M count=1 2>/dev/null ||
> +        die "Unable to reset device"
> +}
> +
> +main()
> +{
> +    echo "Generating image ..."
> +    _IMAGE="$(mktemp ${TMPDIR:-/tmp}/tailtest-image.XXXXXX 2>/dev/null)"
> +    [ -z "$_IMAGE" ] && die "Unable to create image file"
> +    _LOOP="$(make_image "$_IMAGE")"
> +    [ -z "$_LOOP" ] && die "Unable to attach loopback device"
> +
> +    _MOUNTPOINT="$(mktemp -d ${TMPDIR:-/tmp}/tailtest-mountpoint.XXXXXX 2>/dev/null)"
> +    [ -z "$_MOUNTPOINT" ] && die "Unable to create mountpoint"
> +
> +    run_tests "$_LOOP" "$_MOUNTPOINT" "sparse,inline-data"
> +    run_tests "$_LOOP" "$_MOUNTPOINT" "sparse,noinline-data"
> +    run_tests "$_LOOP" "$_MOUNTPOINT" "nosparse,inline-data"
> +    run_tests "$_LOOP" "$_MOUNTPOINT" "nosparse,noinline-data"
> +
> +    return 0
> +}
> +
> +main "$@"
> +exit $?
> +




More information about the Ocfs2-devel mailing list