From 214c4e152b514ee01d110d3cf0e7881dbffcfa8e Mon Sep 17 00:00:00 2001 From: David van Moolenbroek Date: Wed, 18 Sep 2013 14:09:47 +0200 Subject: [PATCH] Add testvnd.sh test script As part of this, change the "run" script to allow certain scripts to be run as root only. Change-Id: I846e41037f9d4f6c7fc0b5ea8250303a7bd72f5d --- distrib/sets/lists/minix/mi | 2 + test/Makefile | 4 +- test/blocktest/test.sh | 4 + test/run | 4 +- test/testvnd.sh | 155 ++++++++++++++++++++++++++++++++++++ test/tvnd.c | 53 ++++++++++++ 6 files changed, 218 insertions(+), 4 deletions(-) create mode 100755 test/testvnd.sh create mode 100644 test/tvnd.c diff --git a/distrib/sets/lists/minix/mi b/distrib/sets/lists/minix/mi index 71814ed0a..5e4512501 100644 --- a/distrib/sets/lists/minix/mi +++ b/distrib/sets/lists/minix/mi @@ -5674,6 +5674,8 @@ ./usr/tests/minix-posix/testsh2 minix-sys ./usr/tests/minix-posix/testvm minix-sys ./usr/tests/minix-posix/testvm.conf minix-sys +./usr/tests/minix-posix/testvnd minix-sys +./usr/tests/minix-posix/tvnd minix-sys ./usr/tests/minix-posix/blocktest minix-sys ./usr/tests/minix-posix/blocktest/README minix-sys ./usr/tests/minix-posix/blocktest/blocktest minix-sys diff --git a/test/Makefile b/test/Makefile index 945b56e67..c5c29e394 100644 --- a/test/Makefile +++ b/test/Makefile @@ -70,9 +70,9 @@ PROGS+= test${t} .endfor PROGS+= t10a t11a t11b t40a t40b t40c t40d t40e t40f t40g t60a t60b \ - t67a t67b t68a t68b + t67a t67b t68a t68b tvnd -SCRIPTS+= run testinterp.sh testsh1.sh testsh2.sh testmfs.sh testisofs.sh +SCRIPTS+= run testinterp.sh testsh1.sh testsh2.sh testmfs.sh testisofs.sh testvnd.sh .if ${MKPIC} == "yes" # Build them as dynamic executables by default if shared libraries diff --git a/test/blocktest/test.sh b/test/blocktest/test.sh index e03cd78ea..bd48dd132 100755 --- a/test/blocktest/test.sh +++ b/test/blocktest/test.sh @@ -62,3 +62,7 @@ # AHCI ATAPI TEST (for SATA CD-ROM devices) #block_test /dev/c2d1 "ro,sector=2048,min_read=2,element=2,max=4194304" + +# VND TEST (for configured vnode disk devices) + +#block_test /dev/vnd0 "rw,min_read=1,min_write=1,element=1,max=16777216" diff --git a/test/run b/test/run index d30115bfd..acd2596e9 100755 --- a/test/run +++ b/test/run @@ -23,13 +23,13 @@ badones= # list of tests that failed setuids="test11 test33 test43 test44 test46 test56 test60 test61 test65 \ test69 test76 test77" # test73" # Scripts that require to be run as root -rootscripts="testisofs" +rootscripts="testisofs testvnd" alltests="1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \ 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \ 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \ 61 62 63 64 65 66 67 68 69 70 71 72 75 76 77 \ - sh1 sh2 interp mfs isofs" + sh1 sh2 interp mfs isofs vnd" tests_no=`expr 0` # test mmap only if enabled in sysenv diff --git a/test/testvnd.sh b/test/testvnd.sh new file mode 100755 index 000000000..96fdf1833 --- /dev/null +++ b/test/testvnd.sh @@ -0,0 +1,155 @@ +#!/bin/sh + +# Shell script used to test the VNode Disk (VND) driver. + +# The main purpose of this script is to test the ability of the driver to cope +# with regular operational conditions. It also calls the blocktest test suite +# to perform I/O stress testing. It does not aim to cover all of vndconfig(8). + +bomb() { + echo $* + cd .. + rm -rf $TESTDIR + umount /dev/vnd1 >/dev/null 2>&1 + umount /dev/vnd0 >/dev/null 2>&1 + vndconfig -u vnd1 >/dev/null 2>&1 + vndconfig -u vnd0 >/dev/null 2>&1 + exit 1 +} + +PATH=/bin:/usr/bin:/sbin:/usr/sbin +export PATH + +TESTDIR=DIR_VND +export TESTDIR + +echo -n "Test VND " + +# We cannot run the test if vnd0 or vnd1 are in use. +if vndconfig -l vnd0 >/dev/null 2>&1; then + if ! vndconfig -l vnd0 2>/dev/null | grep "not in use" >/dev/null; then + echo "vnd0 in use, skipping test" >&2 + echo "ok" + exit 0 + else + service down vnd0 + fi +fi +if vndconfig -l vnd1 >/dev/null 2>&1; then + if ! vndconfig -l vnd1 2>/dev/null | grep "not in use" >/dev/null; then + echo "vnd1 in use, skipping test" >&2 + echo "ok" + exit 0 + else + service down vnd1 + fi +fi + +rm -rf $TESTDIR +mkdir $TESTDIR +cd $TESTDIR + +mkdir mnt0 +mkdir mnt1 + +# Test persisting a file inside a vnode device. +dd if=/dev/zero of=image0 bs=4096 count=257 2>/dev/null || bomb "out of space?" +vndconfig vnd0 image0 || bomb "unable to configure vnd0" +[ "`devsize /dev/vnd0`" = 2056 ] || bomb "unexpected vnd0 device size" +mkfs.mfs /dev/vnd0 || bomb "unable to mkfs vnd0" +mount -t mfs /dev/vnd0 mnt0 >/dev/null || bomb "unable to mount vnd0" +STRING="Hello, world!" +echo "$STRING" >mnt0/TEST || bomb "unable to create file on vnd0" +umount /dev/vnd0 >/dev/null || bomb "unable to unmount vnd0" +[ ! -f mnt0/TEST ] || bomb "was vnd0 ever really mounted?" +mount -t mfs /dev/vnd0 mnt0 >/dev/null || bomb "unable to mount vnd0" +[ -f mnt0/TEST ] || bomb "test file was not saved across mounts" +[ "`cat mnt0/TEST`" = "$STRING" ] || bomb "test file was corrupted" +umount /dev/vnd0 >/dev/null || bomb "unable to unmount vnd0" +vndconfig -u vnd0 || bomb "unable to unconfigure vnd0" +vndconfig vnd1 image0 || bomb "unable to configure vnd1" +mount -t mfs /dev/vnd1 mnt1 >/dev/null || bomb "unable to mount vnd1" +[ "`cat mnt1/TEST`" = "$STRING" ] || bomb "test file was corrupted" + +# Test nesting images. +dd if=/dev/zero of=mnt1/image1 bs=4096 count=128 2>/dev/null || bomb "dd fail" +vndconfig vnd0 mnt1/image1 +mkfs.mfs /dev/vnd0 || bomb "unable to mkfs vnd0" +mount -t mfs /dev/vnd0 mnt0 >/dev/null || bomb "unable to mount vnd0" +echo "x" >mnt0/TEST2 || bomb "unable to create file on vnd0" +umount mnt1 >/dev/null 2>&1 && bomb "should not be able to unmount vnd1" +umount mnt0 >/dev/null || bomb "unable to unmount vnd0" +umount mnt1 >/dev/null 2>&1 && bomb "should not be able to unmount vnd1" +vndconfig -u vnd0 || bomb "unable to unconfigure vnd0" +cp mnt1/image1 . || bomb "unable to copy image off vnd1" +umount mnt1 >/dev/null || bomb "unable to unmount vnd1" +vndconfig -uS vnd1 || bomb "unable to unconfigure vnd1" +vndconfig -S vnd1 ./image1 +mount -t mfs /dev/vnd1 mnt1 >/dev/null || bomb "unable to mount vnd1" +[ -f mnt1/TEST2 ] || bomb "test file not found, VM cache broken again?" +[ "`cat mnt1/TEST2`" = "x" ] || bomb "test file corrupted" +umount /dev/vnd1 >/dev/null || bomb "unable to unmount vnd1" +vndconfig -u /dev/vnd1 || bomb "unable to unconfigure vnd1" + +# Test a read-only configuration. +SUM=`sha1 image0` +vndconfig -r vnd0 image0 +dd if=/dev/zero of=/dev/vnd0 bs=4096 count=1 2>/dev/null && bomb "dd succeeded" +mount /dev/vnd0 mnt0 >/dev/null 2>&1 && bomb "mounting read-write should fail" +mount -r /dev/vnd0 mnt0 >/dev/null || bomb "unable to mount vnd0" +[ "`cat mnt0/TEST`" = "$STRING" ] || bomb "test file was corrupted" +dd if=/dev/zero of=/dev/vnd0 bs=4096 count=1 2>/dev/null && bomb "dd succeeded" +umount /dev/vnd0 >/dev/null +vndconfig -uS vnd0 +[ "`sha1 image0`" = "$SUM" ] || bomb "read-only file changed" + +# Test geometry and sub/partitions. +vndconfig -c vnd0 image0 512/32/64/2 2>/dev/null && bomb "vndconfig succeeded" +vndconfig -c vnd0 image0 512/32/64/1 || bomb "unable to configure vnd0" +# no need for repartition: nobody is holding the device open +[ "`devsize /dev/vnd0`" = 2048 ] || bomb "geometry not applied to size" +partition -mf /dev/vnd0 8 81:512 81:512* 81:512 81:1+ >/dev/null +partition -f /dev/vnd0p1 81:256 81:1 81:8 81:1+ >/dev/null +dd if=/dev/zero of=/dev/vnd0p1s2 bs=512 count=8 2>/dev/null || bomb "dd failed" +dd if=/dev/zero of=/dev/vnd0p1s2 bs=512 count=9 2>/dev/null && bomb "dd nofail" +mkfs.mfs /dev/vnd0p0 || bomb "unable to mkfs vnd0p1s3" +mkfs.mfs /dev/vnd0p1s3 || bomb "unable to mkfs vnd0p1s3" +mount /dev/vnd0p0 mnt0 >/dev/null || bomb "unable to mount vnd0p0" +mount /dev/vnd0p1s3 mnt1 >/dev/null || bomb "unable to mount vnd0p1s3" +umount /dev/vnd0p0 >/dev/null || bomb "unable to unmount vnd0p0" +umount mnt1 >/dev/null || bomb "unable to unmount vnd0p1s3" +vndconfig -u /dev/vnd0 +vndconfig /dev/vnd1 image1 512/1/1/1025 2>/dev/null && bomb "can config vnd1" +vndconfig /dev/vnd1 image1 512/1/1/1024 2>/dev/null || bomb "can't config vnd1" +[ "`devsize /dev/vnd1`" = 1024 ] || bomb "invalid vnd1 device size" +dd if=/dev/vnd1 of=/dev/null bs=512 count=1024 2>/dev/null || bomb "dd fail" +dd if=/dev/vnd1 of=tmp bs=512 skip=1023 count=2 2>/dev/null +[ "`stat -f '%z' tmp`" = 512 ] || bomb "unexpected dd result" + +# Test miscellaneous stuff. +vndconfig /dev/vnd1 image1 2>/dev/null && bomb "reconfiguring should not work" +# the -r is needed here to pass vndconfig(8)'s open test (which is buggy, too!) +vndconfig -r vnd0 . 2>/dev/null && bomb "config to a directory should not work" +vndconfig vnd0 /dev/vnd1 2>/dev/null && bomb "config to another vnd? horrible!" +diskctl /dev/vnd1 flush >/dev/null || bomb "unable to flush vnd1" +vndconfig -u vnd1 + +# Test the low-level driver API. +vndconfig vnd0 image0 || bomb "unable to configure vnd0" +../tvnd /dev/vnd0 || bomb "API subtest failed" +# the device is now unconfigured, but the driver is still running + +# Invoke the blocktest test set to test various other aspects. +vndconfig -S vnd0 image0 || bomb "unable to configure vnd0" +cd ../blocktest +. support.sh +block_test /dev/vnd0 \ + "rw,min_read=1,min_write=1,element=1,max=16777216,nocontig,silent" || \ + bomb "blocktest test set failed" +vndconfig -u vnd0 || bomb "unable to unconfigure vnd0" + +cd .. +rm -rf $TESTDIR + +echo "ok" +exit 0 diff --git a/test/tvnd.c b/test/tvnd.c new file mode 100644 index 000000000..68b76b26d --- /dev/null +++ b/test/tvnd.c @@ -0,0 +1,53 @@ +/* Tests for the VND driver API. Part of testvnd.sh. */ +#include +#include +#include +#include +#include +#include + +/* + * For now, just test the most dreaded case: the driver being told to use the + * file descriptor used to configure the device. Without appropriate checks, + * this would cause a deadlock in VFS, since the corresponding filp object is + * locked to perform the ioctl(2) call when VFS gets the dupfrom(2) back-call. + */ +int +main(int argc, char **argv) +{ + struct vnd_ioctl vnd; + int fd; + + if (argc != 2) { + fprintf(stderr, "usage: %s /dev/vnd0\n", argv[0]); + return EXIT_FAILURE; + } + + if ((fd = open(argv[1], O_RDONLY)) < 0) { + perror("open"); + return EXIT_FAILURE; + } + + memset(&vnd, 0, sizeof(vnd)); + + if (ioctl(fd, VNDIOCCLR, &vnd) < 0) { + perror("ioctl(VNDIOCCLR)"); + return EXIT_FAILURE; + } + + vnd.vnd_fildes = fd; + + if (ioctl(fd, VNDIOCSET, &vnd) >= 0) { + fprintf(stderr, "ioctl(VNDIOCSET): unexpected success\n"); + return EXIT_FAILURE; + } + + if (errno != EINVAL) { + perror("ioctl(VNDIOCSET)"); + return EXIT_FAILURE; + } + + close(fd); + + return EXIT_SUCCESS; +}