Add "blocktest" test, for testing block drivers

The test is located in test/blocktest. It requires hand-editing of
its configuration, and is not part of any automated test set.
This commit is contained in:
David van Moolenbroek
2011-11-07 14:55:55 +01:00
parent ff542f0b27
commit fc34180cca
6 changed files with 2959 additions and 0 deletions
+13
View File
@@ -0,0 +1,13 @@
# Makefile for the Block Device Driver Test driver (blocktest)
PROG= blocktest
SRCS= blocktest.c optset.c
DPADD+= ${LIBSYS}
LDADD+= -lsys
CPPFLAGS+=-I${MINIXSRCDIR}
MAN=
BINDIR?= /usr/sbin
.include <bsd.prog.mk>
+10
View File
@@ -0,0 +1,10 @@
Instructions on how to use blocktest:
1) compile it by running 'make'
2) read test.sh
3) edit and uncomment one line from test.sh
4) run './test.sh'
5) read the output in /var/log/messages
WARNING: while this tool works with both VFS and AVFS, it has been configured
to use AVFS's headers. Either use with AVFS, or edit blocktest.c first.
File diff suppressed because it is too large Load Diff
+128
View File
@@ -0,0 +1,128 @@
/* This file provides functionality to parse strings of comma-separated
* options, each being either a single key name or a key=value pair, where the
* value may be enclosed in quotes. A table of optset entries is provided to
* determine which options are recognized, how to parse their values, and where
* to store those. Unrecognized options are silently ignored; improperly
* formatted options are silently set to reasonably acceptable values.
*
* The entry points into this file are:
* optset_parse parse the given options string using the given table
*
* Created:
* May 2009 (D.C. van Moolenbroek)
*/
#define _MINIX 1
#include <stdlib.h>
#include <string.h>
#include <minix/config.h>
#include <minix/const.h>
#include "optset.h"
FORWARD _PROTOTYPE( void optset_parse_entry, (struct optset *entry,
char *ptr, int len) );
/*===========================================================================*
* optset_parse_entry *
*===========================================================================*/
PRIVATE void optset_parse_entry(entry, ptr, len)
struct optset *entry;
char *ptr;
int len;
{
/* Parse and store the value of a single option.
*/
char *dst;
int val;
switch (entry->os_type) {
case OPT_BOOL:
*((int *) entry->os_ptr) = entry->os_val;
break;
case OPT_STRING:
if (len >= entry->os_val)
len = entry->os_val - 1;
dst = (char *) entry->os_ptr;
if (len > 0)
memcpy(dst, ptr, len);
dst[len] = 0;
break;
case OPT_INT:
if (len > 0)
val = strtol(ptr, NULL, entry->os_val);
else
val = 0;
*((int *) entry->os_ptr) = val;
break;
}
}
/*===========================================================================*
* optset_parse *
*===========================================================================*/
PUBLIC void optset_parse(table, string)
struct optset *table;
char *string;
{
/* Parse a string of options, using the provided table of optset entries.
*/
char *p, *kptr, *vptr;
int i, klen, vlen;
for (p = string; *p; ) {
/* Get the key name for the field. */
for (kptr = p, klen = 0; *p && *p != '=' && *p != ','; p++, klen++);
if (*p == '=') {
/* The field has an associated value. */
vptr = ++p;
/* If the first character after the '=' is a quote character,
* find a matching quote character followed by either a comma
* or the terminating null character, and use the string in
* between. Otherwise, use the string up to the next comma or
* the terminating null character.
*/
if (*p == '\'' || *p == '"') {
p++;
for (vlen = 0; *p && (*p != *vptr ||
(p[1] && p[1] != ',')); p++, vlen++);
if (*p) p++;
vptr++;
}
else
for (vlen = 0; *p && *p != ','; p++, vlen++);
}
else {
vptr = NULL;
vlen = 0;
}
if (*p == ',') p++;
/* Find a matching entry for this key in the given table. If found,
* call optset_parse_entry() on it. Silently ignore the option
* otherwise.
*/
for (i = 0; table[i].os_name != NULL; i++) {
if ((int) strlen(table[i].os_name) == klen &&
!strncasecmp(table[i].os_name, kptr, klen)) {
optset_parse_entry(&table[i], vptr, vlen);
break;
}
}
}
}
+30
View File
@@ -0,0 +1,30 @@
#ifndef _OPTSET_H
#define _OPTSET_H
typedef enum {
OPT_BOOL,
OPT_STRING,
OPT_INT
} opt_type;
/* An entry for the parser of an options set. The 'os_name' field must point
* to a string, which is treated case-insensitively; the last entry of a table
* must have NULL name. The 'os_type' field must be set to one of the OPT_
* values defined above. The 'os_ptr' field must point to the field that is to
* receive the value of a recognized option. For OPT_STRING, it must point to a
* string of a size set in 'os_val'; the resulting string may be truncated, but
* will always be null-terminated. For OPT_BOOL, it must point to an int which
* will be set to the value in 'os_val' if the option is present. For OPT_INT,
* it must point to an int which will be set to the provided option value;
* 'os_val' is then a base passed to strtol().
*/
struct optset {
char *os_name;
opt_type os_type;
void *os_ptr;
int os_val;
};
_PROTOTYPE( void optset_parse, (struct optset *table, char *string) );
#endif /* _OPTSET_H */
+56
View File
@@ -0,0 +1,56 @@
#!/bin/sh
# The blocktest driver expects the following parameters:
#
# device Path to the device node to perform the test on. This may be a
# full disk, a partition, or a subpartition. If possible, give
# blocktest the whole disk; otherwise preferably the first
# partition with a size of slightly over 8GB (for ATA) (better
# yet: slightly over 128GB); even fewer tests can be done if you
# give it only a subpartition.
# rw (or) ro Specifying "rw" will let blocktest write to the target
# partition. This allows for a lot more tests, but keep in mind
# that any data on the partition (and, if the driver misbehaves,
# on other partitions and possibly other disks) WILL BE DESTROYED.
# Use "ro" for read-only mediums, such as CD-ROMs.
# sector Sector size, in bytes. This should be 512 for ATA devices, and
# 2048 for ATAPI devices.
# min_read Minimum size of a read request. This must be at least 2 and at
# most the sector size, and the sector size must be divisible by
# it. A value other than the sector size allows blocktest to test
# sub-sector reads. Sub-sector writes are currently not supported
# by any driver and hence not by blocktest, so there is no
# matching "min_write" (yet).
# element Minimum size of a vector element within a larger I/O request.
# This must be at least 2 and at most min_read, and min_read must
# be divisible by this value. The idea is that several small
# elements may add up to the minimum read size.
# max Maximum size of any request. This should be a multiple of the
# sector size. Blocktest will not test what happens when this
# value is exceeded, but it will generate large requests up to
# this value. For drivers that do not have a maximum request size,
# simply use some large value (typically several megabytes).
# The following are examples of how to configure blocktest for certain driver
# and device pairs. Before commenting out any entry, you MUST edit the "device"
# option for that entry, or you WILL risk losing arbitrary data. You may run
# multiple tests in parallel (on different devices), but you will then have to
# give them different labels. Note that at_wini has no maximum request size, so
# an arbitray size is used. Finally, a disclaimer: a buggy device driver may
# destroy any data it has access to, so use at your own risk.
# AT_WINI ATA TEST (for IDE disk devices)
#service up `pwd`/blocktest -script /etc/rs.single -args "device=/dev/c0d1,rw,sector=512,min_read=512,element=2,max=16777216" -config system.conf -label blocktest_0
# AT_WINI ATAPI TEST (for IDE CD-ROM devices)
#service up `pwd`/blocktest -script /etc/rs.single -args "device=/dev/c0d2,ro,sector=2048,min_read=2,element=2,max=16777216" -config system.conf -label blocktest_0
# AHCI ATA TEST (for SATA disk devices)
#service up `pwd`/blocktest -script /etc/rs.single -args "device=/dev/c2d0,rw,sector=512,min_read=2,element=2,max=4194304" -config system.conf -label blocktest_0
# AHCI ATAPI TEST (for SATA CD-ROM devices)
#service up `pwd`/blocktest -script /etc/rs.single -args "device=/dev/c2d1,ro,sector=2048,min_read=2,element=2,max=4194304" -config system.conf -label blocktest_0