]> Zhao Yanbai Git Server - minix.git/commitdiff
blocktest: prepare to be run as part of tests 85/985/2
authorDavid van Moolenbroek <david@minix3.org>
Wed, 18 Sep 2013 11:41:56 +0000 (13:41 +0200)
committerLionel Sambuc <lionel@minix3.org>
Sat, 1 Mar 2014 08:04:53 +0000 (09:04 +0100)
- fail SEF initialization if any of the subtests failed, so that the
  party invoking the "service up" can tell whether the test succeeded;
- add "nocontig" option, because VM isn't particularly good at
  allocating contiguous memory;
- add "silent" option, because it floods the console otherwise;
- allow the device size to be smaller than the maximum transfer size;
- install files to installed test directory.

Change-Id: I45c818f817c11d90c5f94ae26a2fc49e36e6761e

distrib/sets/lists/minix/mi
etc/mtree/NetBSD.dist.base
test/Makefile
test/blocktest/Makefile
test/blocktest/blocktest.c

index ad6db8febbd999b010d3426c7be3745b3d61a7d7..17b3d94f11a508d434c490775622bd0166f1b780 100644 (file)
 ./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/blocktest              minix-sys
+./usr/tests/minix-posix/blocktest/README       minix-sys
+./usr/tests/minix-posix/blocktest/blocktest    minix-sys
+./usr/tests/minix-posix/blocktest/support.sh   minix-sys
+./usr/tests/minix-posix/blocktest/system.conf  minix-sys
+./usr/tests/minix-posix/blocktest/test.sh      minix-sys
 ./usr/tests/usr.bin/jot/Atffile                minix-sys       atf
 ./usr/tests/usr.bin/jot/d_basic.out    minix-sys       atf
 ./usr/tests/usr.bin/jot/t_jot          minix-sys       atf
index 5cb3df9852dafdeaa1202a8c19fb872d26bf1e56..d41b00655caf8173d5a004736d6a5bddbf0e1f23 100644 (file)
 
 /set type=dir uid=2 gid=0 mode=755
 ./usr/tests/minix-posix
+./usr/tests/minix-posix/blocktest
 
 # this one is for term(1)
 /set type=dir uid=0 gid=5 mode=775
index 331cb3b3e124dcd92be71a6703d8dda5da6c24ee..945b56e6798fbd6dbe7a3550e1a338c60bdea5e4 100644 (file)
@@ -16,6 +16,8 @@ LDADD+=               -lm -lcompat_minix
 
 .include <bsd.own.mk>
 
+SUBDIR=                blocktest
+
 # Some have special flags compiling
 .if ${MACHINE_ARCH} == "i386"
 # LSC FIXME: Compilation error for now on ARM with that!
@@ -110,3 +112,4 @@ clean: .PHONY .MAKE
        @rm -rf DIR*
 
 .include <bsd.prog.mk>
+.include <bsd.subdir.mk>
index fdd4d78112f02f8bce658afb5bfa5689144948c9..b13ba095cc022f8acce8ae9903e7ed64f9e5d3ba 100644 (file)
@@ -1,13 +1,15 @@
 # Makefile for the Block Device Driver Test driver (blocktest)
 PROG=  blocktest
 SRCS=  blocktest.c
+FILES= system.conf support.sh test.sh README
 
 DPADD+=        ${LIBSYS}
 LDADD+=        -lsys
 
 MAN=
 
-BINDIR?= /usr/sbin
+BINDIR?= /usr/tests/minix-posix/blocktest
+FILESDIR?= /usr/tests/minix-posix/blocktest
 
 .include "Makefile.inc"
 .include <minix.service.mk>
index 15723310e0eed7e24837ef2e5ca8ff3d3d3263c1..7d7526cb342de9355fcc746fc0ab70addbc1cfe0 100644 (file)
@@ -1,10 +1,12 @@
 /* Block Device Driver Test driver, by D.C. van Moolenbroek */
 #include <stdlib.h>
+#include <stdarg.h>
 #include <minix/blockdriver.h>
 #include <minix/drvlib.h>
 #include <minix/ds.h>
 #include <minix/optset.h>
 #include <sys/ioc_disk.h>
+#include <sys/mman.h>
 #include <assert.h>
 
 enum {
@@ -40,6 +42,10 @@ static int max_size = 131072;                /* maximum total size of any req */
  * it to a value lower than the driver supports.
  */
 
+/* These settings are used for automated test runs. */
+static int contig = TRUE;              /* allocate contiguous DMA memory? */
+static int silent = FALSE;             /* do not produce console output? */
+
 static struct part_geom part;          /* base and size of target partition */
 
 #define NR_OPENED 10                   /* maximum number of opened devices */
@@ -63,9 +69,58 @@ static struct optset optset_table[] = {
        { "min_read",   OPT_INT,        &min_read,      10                   },
        { "min_write",  OPT_INT,        &min_write,     10                   },
        { "max",        OPT_INT,        &max_size,      10                   },
+       { "nocontig",   OPT_BOOL,       &contig,        FALSE                },
+       { "silent",     OPT_BOOL,       &silent,        TRUE                 },
        { NULL,         0,              NULL,           0                    }
 };
 
+static void output(char *fmt, ...)
+{
+       /* Print debugging information, unless configured to be silent.
+        */
+       va_list argp;
+
+       if (silent)
+               return;
+
+       va_start(argp, fmt);
+
+       vprintf(fmt, argp);
+
+       va_end(argp);
+}
+
+static void *alloc_dma_memory(size_t size)
+{
+       /* Allocate memory that may be used for direct DMA. For most drivers,
+        * this means that the memory has to be physically contiguous. For some
+        * drivers (e.g. VND) we allow non-contiguous allocation, because VM is
+        * currently flaky and does not always manage to provide contiguous
+        * memory even when it should, thus causing needless test failures.
+        */
+       void *ptr;
+
+       if (contig)
+               ptr = alloc_contig(size, 0, NULL);
+       else
+               ptr = minix_mmap(NULL, size, PROT_READ | PROT_WRITE,
+                       MAP_PREALLOC | MAP_ANON, -1, 0);
+
+       if (ptr == MAP_FAILED)
+               panic("unable to allocate %d bytes of memory", size);
+
+       return ptr;
+}
+
+static void free_dma_memory(void *ptr, size_t size)
+{
+       /* Free memory previously allocated for direct DMA. */
+       if (contig)
+               free_contig(ptr, size);
+       else
+               minix_munmap(ptr, size);
+}
+
 static int set_result(result_t *res, int type, ssize_t value)
 {
        /* Set the result to the given result type and with the given optional
@@ -109,42 +164,42 @@ static void got_result(result_t *res, char *desc)
                }
        }
 
-       printf("#%02d: %-38s\t[%s]\n", ++i, desc,
+       output("#%02d: %-38s\t[%s]\n", ++i, desc,
                (res->type == RESULT_OK) ? "PASS" : "FAIL");
 
        switch (res->type) {
        case RESULT_DEATH:
-               printf("- driver died\n");
+               output("- driver died\n");
                break;
        case RESULT_COMMFAIL:
-               printf("- communication failed; sendrec returned %d\n",
+               output("- communication failed; sendrec returned %d\n",
                        res->value);
                break;
        case RESULT_BADTYPE:
-               printf("- bad type %d in reply message\n", res->value);
+               output("- bad type %d in reply message\n", res->value);
                break;
        case RESULT_BADID:
-               printf("- mismatched ID %d in reply message\n", res->value);
+               output("- mismatched ID %d in reply message\n", res->value);
                break;
        case RESULT_BADSTATUS:
-               printf("- bad or unexpected status %d in reply message\n",
+               output("- bad or unexpected status %d in reply message\n",
                        res->value);
                break;
        case RESULT_TRUNC:
-               printf("- result size not as expected (%u bytes left)\n",
+               output("- result size not as expected (%u bytes left)\n",
                        res->value);
                break;
        case RESULT_CORRUPT:
-               printf("- buffer has been modified erroneously\n");
+               output("- buffer has been modified erroneously\n");
                break;
        case RESULT_MISSING:
-               printf("- buffer has been left untouched erroneously\n");
+               output("- buffer has been left untouched erroneously\n");
                break;
        case RESULT_OVERFLOW:
-               printf("- area around target buffer modified\n");
+               output("- area around target buffer modified\n");
                break;
        case RESULT_BADVALUE:
-               printf("- bad or unexpected return value %d from call\n",
+               output("- bad or unexpected return value %d from call\n",
                        res->value);
                break;
        }
@@ -155,7 +210,7 @@ static void test_group(char *name, int exec)
        /* Start a new group of tests.
         */
 
-       printf("Test group: %s%s\n", name, exec ? "" : " (skipping)");
+       output("Test group: %s%s\n", name, exec ? "" : " (skipping)");
 
        group_failure = FALSE;
 }
@@ -196,7 +251,7 @@ static int sendrec_driver(message *m_ptr, ssize_t exp, result_t *res)
                /* The driver has died. Find its new endpoint, and reopen all
                 * devices that we opened earlier. Then return failure.
                 */
-               printf("WARNING: driver has died, attempting to proceed\n");
+               output("WARNING: driver has died, attempting to proceed\n");
 
                driver_deaths++;
 
@@ -325,9 +380,7 @@ static void alloc_buf_and_grant(u8_t **ptr, cp_grant_id_t *grant,
         * grant for it with the requested CPF_* grant permissions.
         */
 
-       *ptr = alloc_contig(size, 0, NULL);
-       if (*ptr == NULL)
-               panic("unable to allocate memory");
+       *ptr = alloc_dma_memory(size);
 
        if ((*grant = cpf_grant_direct(driver_endpt, (vir_bytes) *ptr, size,
                        perms)) == GRANT_INVALID)
@@ -341,7 +394,7 @@ static void free_buf_and_grant(u8_t *ptr, cp_grant_id_t grant, size_t size)
 
        cpf_revoke(grant);
 
-       free_contig(ptr, size);
+       free_dma_memory(ptr, size);
 }
 
 static void bad_read1(void)
@@ -895,10 +948,8 @@ static void vector_and_large_sub(size_t small_size)
        buf_size = large_size + sizeof(u32_t) * 2;
        buf2_size = large_size + sizeof(u32_t) * (NR_IOREQS + 1);
 
-       buf_ptr = alloc_contig(buf_size, 0, NULL);
-       buf2_ptr = alloc_contig(buf2_size, 0, NULL);
-       if (buf_ptr == NULL || buf2_ptr == NULL)
-               panic("unable to allocate memory");
+       buf_ptr = alloc_dma_memory(buf_size);
+       buf2_ptr = alloc_dma_memory(buf2_size);
 
        /* The first buffer has one large chunk with dword-sized guards on each
         * side. LPTR(n) points to the start of the nth small data chunk within
@@ -1002,8 +1053,8 @@ static void vector_and_large_sub(size_t small_size)
 #undef SPTR
 
        /* Clean up. */
-       free_contig(buf2_ptr, buf2_size);
-       free_contig(buf_ptr, buf_size);
+       free_dma_memory(buf2_ptr, buf2_size);
+       free_dma_memory(buf_ptr, buf_size);
 }
 
 static void vector_and_large(void)
@@ -1015,6 +1066,12 @@ static void vector_and_large(void)
         */
        size_t max_block;
 
+       /* Make sure that the maximum size does not exceed the target device
+        * size, minus the margins we need for testing here and there.
+        */
+       if (max_size > part.size - sector_size * 4)
+               max_size = part.size - sector_size * 4;
+
        /* Compute the largest sector multiple which, when multiplied by
         * NR_IOREQS, is no more than the maximum transfer size. Note that if
         * max_size is not a multiple of sector_size, we're not going up to the
@@ -1141,7 +1198,7 @@ static void misc_ioctl(void)
 
        /* The other tests do not check whether there is sufficient room. */
        if (res.type == RESULT_OK && part.size < (u64_t)max_size * 2)
-               printf("WARNING: small partition, some tests may fail\n");
+               output("WARNING: small partition, some tests may fail\n");
 
        /* Test retrieving global driver open count. */
        openct = 0x0badcafe;
@@ -1197,9 +1254,7 @@ static void read_limits(dev_t sub0_minor, dev_t sub1_minor, size_t sub_size)
        test_group("read around subpartition limits", TRUE);
 
        buf_size = sector_size * 3;
-
-       if ((buf_ptr = alloc_contig(buf_size, 0, NULL)) == NULL)
-               panic("unable to allocate memory");
+       buf_ptr = alloc_dma_memory(buf_size);
 
        /* Read one sector up to the partition limit. */
        fill_rand(buf_ptr, buf_size);
@@ -1295,7 +1350,7 @@ static void read_limits(dev_t sub0_minor, dev_t sub1_minor, size_t sub_size)
        got_result(&res, "read with negative offset");
 
        /* Clean up. */
-       free_contig(buf_ptr, buf_size);
+       free_dma_memory(buf_ptr, buf_size);
 }
 
 static void write_limits(dev_t sub0_minor, dev_t sub1_minor, size_t sub_size)
@@ -1317,9 +1372,7 @@ static void write_limits(dev_t sub0_minor, dev_t sub1_minor, size_t sub_size)
                return;
 
        buf_size = sector_size * 3;
-
-       if ((buf_ptr = alloc_contig(buf_size, 0, NULL)) == NULL)
-               panic("unable to allocate memory");
+       buf_ptr = alloc_dma_memory(buf_size);
 
        /* Write to the start of the second subpartition, so that we can
         * reliably check whether the contents have changed later.
@@ -1436,7 +1489,7 @@ static void write_limits(dev_t sub0_minor, dev_t sub1_minor, size_t sub_size)
        got_result(&res, "read up to partition end");
 
        /* Clean up. */
-       free_contig(buf_ptr, buf_size);
+       free_dma_memory(buf_ptr, buf_size);
 }
 
 static void vir_limits(dev_t sub0_minor, dev_t sub1_minor, int part_secs)
@@ -1531,9 +1584,7 @@ static void real_limits(dev_t sub0_minor, dev_t sub1_minor, int part_secs)
         * anyway.
         */
        buf_size = sector_size;
-
-       if ((buf_ptr = alloc_contig(buf_size, 0, NULL)) == NULL)
-               panic("unable to allocate memory");
+       buf_ptr = alloc_dma_memory(buf_size);
 
        memset(buf_ptr, 0, buf_size);
 
@@ -1642,7 +1693,7 @@ static void real_limits(dev_t sub0_minor, dev_t sub1_minor, int part_secs)
        close_device(sub0_minor);
        close_device(sub1_minor);
 
-       free_contig(buf_ptr, buf_size);
+       free_dma_memory(buf_ptr, buf_size);
 }
 
 static void part_limits(void)
@@ -1658,7 +1709,7 @@ static void part_limits(void)
         * cannot conduct this test.
         */
        if (driver_minor >= MINOR_d0p0s0) {
-               printf("WARNING: operating on subpartition, "
+               output("WARNING: operating on subpartition, "
                        "skipping partition tests\n");
                return;
        }
@@ -1879,14 +1930,9 @@ static void unaligned_size(void)
 
        base_pos = (u64_t)sector_size * 2;
 
-       if ((buf_ptr = alloc_contig(buf_size, 0, NULL)) == NULL)
-               panic("unable to allocate memory");
-
-       if ((sec_ptr[0] = alloc_contig(sector_size, 0, NULL)) == NULL)
-               panic("unable to allocate memory");
-
-       if ((sec_ptr[1] = alloc_contig(sector_size, 0, NULL)) == NULL)
-               panic("unable to allocate memory");
+       buf_ptr = alloc_dma_memory(buf_size);
+       sec_ptr[0] = alloc_dma_memory(sector_size);
+       sec_ptr[1] = alloc_dma_memory(sector_size);
 
        if (may_write) {
                sum = fill_rand(buf_ptr, buf_size);
@@ -1947,9 +1993,9 @@ static void unaligned_size(void)
        }
 
        /* Clean up. */
-       free_contig(sec_ptr[1], sector_size);
-       free_contig(sec_ptr[0], sector_size);
-       free_contig(buf_ptr, buf_size);
+       free_dma_memory(sec_ptr[1], sector_size);
+       free_dma_memory(sec_ptr[0], sector_size);
+       free_dma_memory(buf_ptr, buf_size);
 }
 
 static void unaligned_pos1(void)
@@ -1983,11 +2029,8 @@ static void unaligned_pos1(void)
 
        base_pos = (u64_t)sector_size * 3;
 
-       if ((buf_ptr = alloc_contig(buf_size, 0, NULL)) == NULL)
-               panic("unable to allocate memory");
-
-       if ((buf2_ptr = alloc_contig(buf2_size, 0, NULL)) == NULL)
-               panic("unable to allocate memory");
+       buf_ptr = alloc_dma_memory(buf_size);
+       buf2_ptr = alloc_dma_memory(buf2_size);
 
        if (may_write) {
                sum = fill_rand(buf_ptr, buf_size);
@@ -2100,8 +2143,8 @@ static void unaligned_pos1(void)
        got_result(&res, "multisector read with lead and trail");
 
        /* Clean up. */
-       free_contig(buf2_ptr, buf2_size);
-       free_contig(buf_ptr, buf_size);
+       free_dma_memory(buf2_ptr, buf2_size);
+       free_dma_memory(buf_ptr, buf_size);
 }
 
 static void unaligned_pos2(void)
@@ -2131,11 +2174,8 @@ static void unaligned_pos2(void)
 
        base_pos = (u64_t)sector_size * 3;
 
-       if ((buf_ptr = alloc_contig(buf_size, 0, NULL)) == NULL)
-               panic("unable to allocate memory");
-
-       if ((buf2_ptr = alloc_contig(buf2_size, 0, NULL)) == NULL)
-               panic("unable to allocate memory");
+       buf_ptr = alloc_dma_memory(buf_size);
+       buf2_ptr = alloc_dma_memory(buf2_size);
 
        /* First establish a baseline. We need two requests for this, as the
         * total area intentionally exceeds the max request size.
@@ -2244,8 +2284,8 @@ static void unaligned_pos2(void)
        got_result(&res, "large fully unaligned filled vector");
 
        /* Clean up. */
-       free_contig(buf2_ptr, buf2_size);
-       free_contig(buf_ptr, buf_size);
+       free_dma_memory(buf2_ptr, buf2_size);
+       free_dma_memory(buf_ptr, buf_size);
 }
 
 static void sweep_area(u64_t base_pos)
@@ -2261,9 +2301,7 @@ static void sweep_area(u64_t base_pos)
        int i, j;
 
        buf_size = sector_size * 8;
-
-       if ((buf_ptr = alloc_contig(buf_size, 0, NULL)) == NULL)
-               panic("unable to allocate memory");
+       buf_ptr = alloc_dma_memory(buf_size);
 
        /* First (write to, if allowed, and) read from the entire area in one
         * go, so that we know the (initial) contents of the area.
@@ -2336,7 +2374,7 @@ static void sweep_area(u64_t base_pos)
        }
 
        /* Clean up. */
-       free_contig(buf_ptr, buf_size);
+       free_dma_memory(buf_ptr, buf_size);
 }
 
 static void sweep_and_check(u64_t pos, int check_integ)
@@ -2353,9 +2391,7 @@ static void sweep_and_check(u64_t pos, int check_integ)
 
        if (check_integ) {
                buf_size = sector_size * 3;
-
-               if ((buf_ptr = alloc_contig(buf_size, 0, NULL)) == NULL)
-                       panic("unable to allocate memory");
+               buf_ptr = alloc_dma_memory(buf_size);
 
                if (may_write) {
                        sum = fill_rand(buf_ptr, buf_size);
@@ -2391,7 +2427,7 @@ static void sweep_and_check(u64_t pos, int check_integ)
 
                got_result(&res, "check integrity zone");
 
-               free_contig(buf_ptr, buf_size);
+               free_dma_memory(buf_ptr, buf_size);
        }
 }
 
@@ -2653,7 +2689,20 @@ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
 
        srand48(now);
 
-       return OK;
+       output("BLOCKTEST: driver label '%s' (endpt %d), minor %d\n",
+               driver_label, driver_endpt, driver_minor);
+
+       do_tests();
+
+       output("BLOCKTEST: summary: %d out of %d tests failed "
+               "across %d group%s; %d driver deaths\n",
+               failed_tests, total_tests, failed_groups,
+               failed_groups == 1 ? "" : "s", driver_deaths);
+
+       /* The returned code will determine the outcome of the RS call, and
+        * thus the entire test. The actual error code does not matter.
+        */
+       return (failed_tests) ? EINVAL : OK;
 }
 
 static void sef_local_startup(void)
@@ -2674,15 +2723,5 @@ int main(int argc, char **argv)
        env_setargs(argc, argv);
        sef_local_startup();
 
-       printf("BLOCKTEST: driver label '%s' (endpt %d), minor %d\n",
-               driver_label, driver_endpt, driver_minor);
-
-       do_tests();
-
-       printf("BLOCKTEST: summary: %d out of %d tests failed "
-               "across %d group%s; %d driver deaths\n",
-               failed_tests, total_tests, failed_groups,
-               failed_groups == 1 ? "" : "s", driver_deaths);
-
        return 0;
 }