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
@ -4,10 +4,10 @@ SRCS= blocktest.c
|
|||||||
|
|
||||||
DPADD+= ${LIBSYS}
|
DPADD+= ${LIBSYS}
|
||||||
LDADD+= -lsys
|
LDADD+= -lsys
|
||||||
CPPFLAGS+=-I${MINIXSRCDIR}
|
|
||||||
|
|
||||||
MAN=
|
MAN=
|
||||||
|
|
||||||
BINDIR?= /usr/sbin
|
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
|
3) edit and uncomment one line from test.sh
|
||||||
4) run './test.sh'
|
4) run './test.sh'
|
||||||
5) read the output in /var/log/messages
|
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 */
|
/* Block Device Driver Test driver, by D.C. van Moolenbroek */
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <minix/blockdriver.h>
|
#include <minix/blockdriver.h>
|
||||||
#include <minix/drvlib.h>
|
#include <minix/drvlib.h>
|
||||||
#include <minix/dmap.h>
|
|
||||||
#include <minix/sysinfo.h>
|
|
||||||
#include <minix/ds.h>
|
#include <minix/ds.h>
|
||||||
#include <minix/optset.h>
|
#include <minix/optset.h>
|
||||||
#include <sys/ioc_disk.h>
|
#include <sys/ioc_disk.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
/* FIXME: use servers/vfs/.. with VFS */
|
|
||||||
#include "servers/avfs/const.h"
|
|
||||||
#include "servers/avfs/dmap.h"
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
RESULT_OK, /* exactly as expected */
|
RESULT_OK, /* exactly as expected */
|
||||||
RESULT_COMMFAIL, /* communication failed */
|
RESULT_COMMFAIL, /* communication failed */
|
||||||
@ -32,9 +25,8 @@ typedef struct {
|
|||||||
ssize_t value;
|
ssize_t value;
|
||||||
} result_t;
|
} result_t;
|
||||||
|
|
||||||
PRIVATE char device_path[PATH_MAX]; /* path to device node to use */
|
PRIVATE char driver_label[32] = ""; /* driver DS label */
|
||||||
PRIVATE char driver_label[LABEL_MAX]; /* driver DS label */
|
PRIVATE dev_t driver_minor = -1; /* driver's partition minor to use */
|
||||||
PRIVATE dev_t driver_minor; /* driver's partition minor to use */
|
|
||||||
PRIVATE endpoint_t driver_endpt; /* driver endpoint */
|
PRIVATE endpoint_t driver_endpt; /* driver endpoint */
|
||||||
|
|
||||||
PRIVATE int may_write = FALSE; /* may we write to the device? */
|
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. */
|
/* Options supported by this driver. */
|
||||||
PRIVATE struct optset optset_table[] = {
|
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 },
|
{ "rw", OPT_BOOL, &may_write, TRUE },
|
||||||
{ "ro", OPT_BOOL, &may_write, FALSE },
|
{ "ro", OPT_BOOL, &may_write, FALSE },
|
||||||
{ "sector", OPT_INT, §or_size, 10 },
|
{ "sector", OPT_INT, §or_size, 10 },
|
||||||
@ -2569,41 +2562,6 @@ PRIVATE void do_tests(void)
|
|||||||
close_primary();
|
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))
|
PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
|
||||||
{
|
{
|
||||||
/* Initialize.
|
/* Initialize.
|
||||||
@ -2614,10 +2572,14 @@ PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
|
|||||||
if (env_argc > 1)
|
if (env_argc > 1)
|
||||||
optset_parse(optset_table, env_argv[1]);
|
optset_parse(optset_table, env_argv[1]);
|
||||||
|
|
||||||
if (device_path[0] == '\0')
|
if (driver_label[0] == '\0')
|
||||||
panic("no device path given");
|
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)
|
if ((r = getuptime(&now)) != OK)
|
||||||
panic("unable to get uptime: %d", r);
|
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
|
#!/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
|
# rw (or) ro Specifying "rw" will let blocktest write to the target
|
||||||
# partition. This allows for a lot more tests, but keep in mind
|
# partition. This allows for a lot more tests, but keep in mind
|
||||||
# that any data on the partition (and, if the driver misbehaves,
|
# 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
|
# value is exceeded, but it will generate large requests up to
|
||||||
# this value. For drivers that do not have a maximum request size,
|
# this value. For drivers that do not have a maximum request size,
|
||||||
# simply use some large value (typically several megabytes).
|
# simply use some large value (typically several megabytes).
|
||||||
|
#
|
||||||
# The following are examples of how to configure blocktest for certain driver
|
# Before commenting out any entry, you MUST edit the device name for that
|
||||||
# and device pairs. Before commenting out any entry, you MUST edit the "device"
|
# entry, or you WILL risk losing arbitrary data. You may run multiple tests in
|
||||||
# option for that entry, or you WILL risk losing arbitrary data. You may run
|
# parallel, on different devices. Note that at_wini has no maximum request
|
||||||
# multiple tests in parallel (on different devices), but you will then have to
|
# size, so an arbitray size is used. Finally, a disclaimer: a buggy device
|
||||||
# give them different labels. Note that at_wini has no maximum request size, so
|
# driver may destroy any data it has access to, so use at your own risk.
|
||||||
# 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)
|
# 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)
|
# 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)
|
# 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)
|
# 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…
x
Reference in New Issue
Block a user