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:
parent
ff542f0b27
commit
fc34180cca
13
test/blocktest/Makefile
Normal file
13
test/blocktest/Makefile
Normal 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
test/blocktest/README
Normal file
10
test/blocktest/README
Normal 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.
|
2722
test/blocktest/blocktest.c
Normal file
2722
test/blocktest/blocktest.c
Normal file
File diff suppressed because it is too large
Load diff
128
test/blocktest/optset.c
Normal file
128
test/blocktest/optset.c
Normal 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
test/blocktest/optset.h
Normal file
30
test/blocktest/optset.h
Normal 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
test/blocktest/test.sh
Executable file
56
test/blocktest/test.sh
Executable 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
|
Loading…
Reference in a new issue