blocktest: resolve label/minor in userland
The test script now resolves the device node into a <label,minor> pair, so that the blocktest driver itself no longer has to. This removes blocktest's dependency on VFS' internal data structures. Also allow blocktest to be linked using with gcc/clang.
This commit is contained in:
parent
35cf8beb33
commit
95d1f25b28
6 changed files with 66 additions and 73 deletions
|
@ -4,10 +4,10 @@ SRCS= blocktest.c
|
|||
|
||||
DPADD+= ${LIBSYS}
|
||||
LDADD+= -lsys
|
||||
CPPFLAGS+=-I${MINIXSRCDIR}
|
||||
|
||||
MAN=
|
||||
|
||||
BINDIR?= /usr/sbin
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
.include "Makefile.inc"
|
||||
.include <minix.service.mk>
|
||||
|
|
9
test/blocktest/Makefile.inc
Normal file
9
test/blocktest/Makefile.inc
Normal file
|
@ -0,0 +1,9 @@
|
|||
# Copied from drivers/Makefile.inc, and slightly edited.
|
||||
.if ${COMPILER_TYPE} == "gnu"
|
||||
CPPFLAGS+= -D_MINIX -D_NETBSD_SOURCE
|
||||
LDADD+= -lminlib -lcompat_minix -lc
|
||||
DPADD+= ${LIBMINLIB} ${LIBCOMPAT_MINIX}
|
||||
.else
|
||||
CPPFLAGS+= -D_MINIX -D_POSIX_SOURCE
|
||||
.endif
|
||||
BINDIR?=/usr/sbin
|
|
@ -5,6 +5,3 @@ Instructions on how to use blocktest:
|
|||
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.
|
||||
|
|
|
@ -1,19 +1,12 @@
|
|||
/* Block Device Driver Test driver, by D.C. van Moolenbroek */
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <minix/blockdriver.h>
|
||||
#include <minix/drvlib.h>
|
||||
#include <minix/dmap.h>
|
||||
#include <minix/sysinfo.h>
|
||||
#include <minix/ds.h>
|
||||
#include <minix/optset.h>
|
||||
#include <sys/ioc_disk.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* FIXME: use servers/vfs/.. with VFS */
|
||||
#include "servers/avfs/const.h"
|
||||
#include "servers/avfs/dmap.h"
|
||||
|
||||
enum {
|
||||
RESULT_OK, /* exactly as expected */
|
||||
RESULT_COMMFAIL, /* communication failed */
|
||||
|
@ -32,9 +25,8 @@ typedef struct {
|
|||
ssize_t value;
|
||||
} result_t;
|
||||
|
||||
PRIVATE char device_path[PATH_MAX]; /* path to device node to use */
|
||||
PRIVATE char driver_label[LABEL_MAX]; /* driver DS label */
|
||||
PRIVATE dev_t driver_minor; /* driver's partition minor to use */
|
||||
PRIVATE char driver_label[32] = ""; /* driver DS label */
|
||||
PRIVATE dev_t driver_minor = -1; /* driver's partition minor to use */
|
||||
PRIVATE endpoint_t driver_endpt; /* driver endpoint */
|
||||
|
||||
PRIVATE int may_write = FALSE; /* may we write to the device? */
|
||||
|
@ -60,7 +52,8 @@ PRIVATE int driver_deaths = 0; /* number of restarts that we saw */
|
|||
|
||||
/* Options supported by this driver. */
|
||||
PRIVATE struct optset optset_table[] = {
|
||||
{ "device", OPT_STRING, device_path, sizeof(device_path) },
|
||||
{ "label", OPT_STRING, driver_label, sizeof(driver_label) },
|
||||
{ "minor", OPT_INT, &driver_minor, 10 },
|
||||
{ "rw", OPT_BOOL, &may_write, TRUE },
|
||||
{ "ro", OPT_BOOL, &may_write, FALSE },
|
||||
{ "sector", OPT_INT, §or_size, 10 },
|
||||
|
@ -2569,41 +2562,6 @@ PRIVATE void do_tests(void)
|
|||
close_primary();
|
||||
}
|
||||
|
||||
PRIVATE void map_device(char *path)
|
||||
{
|
||||
/* Map a device node to a label, endpoint, and minor device number.
|
||||
* This should be replaced with something better some day. For now,
|
||||
* it seems this is the only working approach.
|
||||
*/
|
||||
static struct dmap dmap[NR_DEVICES];
|
||||
struct stat statbuf;
|
||||
dev_t major;
|
||||
int r;
|
||||
|
||||
if ((r = stat(path, &statbuf)) != OK)
|
||||
panic("unable to stat '%s'", path);
|
||||
|
||||
if (!S_ISBLK(statbuf.st_mode) || major(statbuf.st_rdev) >= NR_DEVICES)
|
||||
panic("'%s' is not a block device", path);
|
||||
|
||||
major = major(statbuf.st_rdev);
|
||||
driver_minor = minor(statbuf.st_rdev);
|
||||
|
||||
if ((r = getsysinfo(VFS_PROC_NR, SI_DMAP_TAB, dmap)) != OK)
|
||||
panic("unable to get dmap table from VFS: %d", r);
|
||||
|
||||
if (driver_endpt == NONE || !dmap[major].dmap_label[0])
|
||||
panic("no driver present for given device");
|
||||
|
||||
strcpy(driver_label, dmap[major].dmap_label);
|
||||
|
||||
if (ds_retrieve_label_endpt(driver_label, &driver_endpt))
|
||||
panic("unable to resolve label");
|
||||
|
||||
if (driver_endpt != dmap[major].dmap_driver)
|
||||
panic("endpoint mismatch between VFS and DS");
|
||||
}
|
||||
|
||||
PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
|
||||
{
|
||||
/* Initialize.
|
||||
|
@ -2614,10 +2572,14 @@ PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
|
|||
if (env_argc > 1)
|
||||
optset_parse(optset_table, env_argv[1]);
|
||||
|
||||
if (device_path[0] == '\0')
|
||||
panic("no device path given");
|
||||
if (driver_label[0] == '\0')
|
||||
panic("no driver label given");
|
||||
|
||||
map_device(device_path);
|
||||
if (ds_retrieve_label_endpt(driver_label, &driver_endpt))
|
||||
panic("unable to resolve driver label");
|
||||
|
||||
if (driver_minor > 255)
|
||||
panic("invalid or no driver minor given");
|
||||
|
||||
if ((r = getuptime(&now)) != OK)
|
||||
panic("unable to get uptime: %d", r);
|
||||
|
|
19
test/blocktest/support.sh
Normal file
19
test/blocktest/support.sh
Normal file
|
@ -0,0 +1,19 @@
|
|||
# Supporting routines for blocktest. Do not run directly.
|
||||
|
||||
# usage: devtopair /dev/cXdY..
|
||||
# returns a label, minor pair in the form "label=at_wini_N,minor=M"
|
||||
devtopair() {
|
||||
label=`awk "/^$(stat -f '%Hr' $1) / "'{print $2}' /proc/dmap`
|
||||
if [ ! -z "$label" ]; then echo "label=$label,minor=`stat -f '%Lr' $1`"; fi
|
||||
}
|
||||
|
||||
# usage: blocktest /dev/cXdY.. "params,for,blocktest"
|
||||
# runs the blocktest driver on the given device with the given parameters
|
||||
blocktest() {
|
||||
if [ ! -x blocktest ]; then echo "compile blocktest first!" >&2; exit 1; fi
|
||||
if [ ! -b "$1" ]; then echo "$1 is not a block device" >&2; exit 1; fi
|
||||
pair=$(devtopair $1)
|
||||
if [ -z "$pair" ]; then echo "driver not found for $1" >&2; exit 1; fi
|
||||
service up `pwd`/blocktest -args "$pair,$2" -config system.conf \
|
||||
-script /etc/rs.single -label blocktest_$(stat -f '%r' $1)
|
||||
}
|
|
@ -1,13 +1,21 @@
|
|||
#!/bin/sh
|
||||
|
||||
# The blocktest driver expects the following parameters:
|
||||
. support.sh
|
||||
|
||||
# The following commented-out examples of how to run blocktest for certain
|
||||
# driver and device pairs. The syntax of the calls is:
|
||||
#
|
||||
# blocktest <device> <parameters>
|
||||
#
|
||||
# <device> is the path to a device to run blocktest 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.
|
||||
#
|
||||
# <parameters> is a comma-separated list of parameters for blocktest. The
|
||||
# following parameters are supported and in fact expected:
|
||||
#
|
||||
# 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,
|
||||
|
@ -30,27 +38,25 @@
|
|||
# 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.
|
||||
#
|
||||
# Before commenting out any entry, you MUST edit the device name for that
|
||||
# entry, or you WILL risk losing arbitrary data. You may run multiple tests in
|
||||
# parallel, on different devices. 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
|
||||
#blocktest /dev/c0d1 "rw,sector=512,min_read=512,element=2,max=16777216"
|
||||
|
||||
# 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
|
||||
#blocktest /dev/c0d2 "ro,sector=2048,min_read=2,element=2,max=16777216"
|
||||
|
||||
# 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
|
||||
#blocktest /dev/c2d0 "rw,sector=512,min_read=2,element=2,max=4194304"
|
||||
|
||||
# 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
|
||||
#blocktest /dev/c2d1 "ro,sector=2048,min_read=2,element=2,max=4194304"
|
||||
|
|
Loading…
Reference in a new issue