blocktest: prepare to be run as part of tests
- 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
This commit is contained in:
parent
d266a94fea
commit
38f7b96048
5 changed files with 133 additions and 82 deletions
|
@ -5668,6 +5668,12 @@
|
|||
./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
|
||||
|
|
|
@ -161,6 +161,7 @@
|
|||
|
||||
/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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue