Diskinfo is a small program to access the basic properties of a disk device:
sectorsize, mediasize etc. It also contains a small and naïve benchmark which reports on seek and transfer performance.
This commit is contained in:
parent
13ac082b26
commit
a362eb6374
@ -29,6 +29,7 @@ SUBDIR= IPXrouted \
|
||||
dev_mkdb \
|
||||
devinfo \
|
||||
digictl \
|
||||
diskinfo \
|
||||
edquota \
|
||||
extattr \
|
||||
extattrctl \
|
||||
|
11
usr.sbin/diskinfo/Makefile
Normal file
11
usr.sbin/diskinfo/Makefile
Normal file
@ -0,0 +1,11 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= diskinfo
|
||||
MAN= diskinfo.8
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
test: ${PROG}
|
||||
./${PROG} /dev/ad4 md50
|
||||
./${PROG} -v /dev/ad4 md50
|
||||
./${PROG} -t /dev/ad4
|
69
usr.sbin/diskinfo/diskinfo.8
Normal file
69
usr.sbin/diskinfo/diskinfo.8
Normal file
@ -0,0 +1,69 @@
|
||||
.\"
|
||||
.\" Copyright (c) 2003 Poul-Henning Kamp
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. The names of the authors may not be used to endorse or promote
|
||||
.\" products derived from this software without specific prior written
|
||||
.\" permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd April 9, 2003
|
||||
.Dt DISKINFO 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm diskinfo
|
||||
.Nd get information about disk device
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl v
|
||||
.Op Fl t
|
||||
.Ar disk ...
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility prints out information about a diskdevice and optionally runs a naïve performance test on the device.
|
||||
.Pp
|
||||
If given no arguments the output will be a single line per specified device
|
||||
with the following fields: device name, sectorsize, media size in bytes,
|
||||
media size in sectors, firmware cylinders, firmware heads and firmware sectors.
|
||||
The last three fields are only present if the information is available.
|
||||
.Pp
|
||||
If given the
|
||||
.Fl v
|
||||
option, the fields will be printed one per line with a descriptive comment.
|
||||
.Pp
|
||||
The
|
||||
.Fl t
|
||||
option triggers a simple and rather naïve benchmark of the disks seek
|
||||
and transfer performance.
|
||||
.Sh AUTHORS
|
||||
.An Poul-Henning Kamp
|
||||
.Sh BUGS
|
||||
There are in order of increasing severity lies,
|
||||
damn lines, statistics and computer benchmarks.
|
||||
.Sh HISTORY
|
||||
.The
|
||||
.Nm
|
||||
command appeared in
|
||||
.Fx 5.1
|
303
usr.sbin/diskinfo/diskinfo.c
Normal file
303
usr.sbin/diskinfo/diskinfo.c
Normal file
@ -0,0 +1,303 @@
|
||||
/*-
|
||||
* Copyright (c) 2003 Poul-Henning Kamp
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The names of the authors may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <paths.h>
|
||||
#include <err.h>
|
||||
#include <sys/disk.h>
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "Usage: diskinfo [-tv]\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
static int opt_t, opt_v;
|
||||
|
||||
static void speeddisk(const char *name, int fd, off_t mediasize, u_int sectorsize);
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int i, ch, fd, error;
|
||||
char buf[BUFSIZ];
|
||||
off_t mediasize;
|
||||
u_int sectorsize, fwsectors, fwheads;
|
||||
|
||||
while ((ch = getopt(argc, argv, "tv")) != -1) {
|
||||
switch (ch) {
|
||||
case 't':
|
||||
opt_t = 1;
|
||||
opt_v = 1;
|
||||
break;
|
||||
case 'v':
|
||||
opt_v = 1;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
fd = open(argv[i], O_RDONLY);
|
||||
if (fd < 0 && errno == ENOENT && *argv[i] != '/') {
|
||||
sprintf(buf, "%s%s", _PATH_DEV, argv[i]);
|
||||
fd = open(buf, O_RDONLY);
|
||||
}
|
||||
if (fd < 0)
|
||||
err(1, argv[i]);
|
||||
error = ioctl(fd, DIOCGMEDIASIZE, &mediasize);
|
||||
if (error)
|
||||
err(1, "%s: ioctl(DIOCGMEDIASIZE) failed, probably not a disk.", argv[i]);
|
||||
error = ioctl(fd, DIOCGSECTORSIZE, §orsize);
|
||||
if (error)
|
||||
err(1, "%s: DIOCGSECTORSIZE failed, probably not a disk.", argv[i]);
|
||||
error = ioctl(fd, DIOCGFWSECTORS, &fwsectors);
|
||||
if (error)
|
||||
fwsectors = 0;
|
||||
error = ioctl(fd, DIOCGFWHEADS, &fwheads);
|
||||
if (error)
|
||||
fwheads = 0;
|
||||
if (!opt_v) {
|
||||
printf("%s", argv[i]);
|
||||
printf("\t%u", sectorsize);
|
||||
printf("\t%jd", (intmax_t)mediasize);
|
||||
printf("\t%jd", (intmax_t)mediasize/sectorsize);
|
||||
if (fwsectors != 0 && fwheads != 0) {
|
||||
printf("\t%jd", (intmax_t)mediasize /
|
||||
(fwsectors * fwheads * sectorsize));
|
||||
printf("\t%u", fwheads);
|
||||
printf("\t%u", fwsectors);
|
||||
}
|
||||
} else {
|
||||
printf("%s\n", argv[i]);
|
||||
printf("\t%-12u\t# sectorsize\n", sectorsize);
|
||||
printf("\t%-12jd\t# mediasize in bytes\n",
|
||||
(intmax_t)mediasize);
|
||||
printf("\t%-12jd\t# mediasize in sectors\n",
|
||||
(intmax_t)mediasize/sectorsize);
|
||||
if (fwsectors != 0 && fwheads != 0) {
|
||||
printf("\t%-12jd\t# Cylinders according to firmware.\n", (intmax_t)mediasize /
|
||||
(fwsectors * fwheads * sectorsize));
|
||||
printf("\t%-12u\t# Heads according to firmware.\n", fwheads);
|
||||
printf("\t%-12u\t# Sectors according to firmware.\n", fwsectors);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
if (opt_t)
|
||||
speeddisk(argv[i], fd, mediasize, sectorsize);
|
||||
close(fd);
|
||||
}
|
||||
exit (0);
|
||||
}
|
||||
|
||||
|
||||
static char sector[65536];
|
||||
static char mega[1024 * 1024];
|
||||
|
||||
static void
|
||||
rdsect(int fd, u_int blockno, u_int sectorsize)
|
||||
{
|
||||
int error;
|
||||
|
||||
lseek(fd, blockno * sectorsize, SEEK_SET);
|
||||
error = read(fd, sector, sectorsize);
|
||||
if (error != sectorsize)
|
||||
err(1, "read error or disk too small for test.");
|
||||
}
|
||||
|
||||
static void
|
||||
rdmega(int fd)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = read(fd, mega, sizeof(mega));
|
||||
if (error != sizeof(mega))
|
||||
err(1, "read error or disk too small for test.");
|
||||
}
|
||||
|
||||
static struct timeval tv1, tv2;
|
||||
|
||||
static void
|
||||
T0(void)
|
||||
{
|
||||
|
||||
fflush(stdout);
|
||||
sync();
|
||||
sleep(1);
|
||||
sync();
|
||||
sync();
|
||||
gettimeofday(&tv1, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
TN(int count)
|
||||
{
|
||||
double dt;
|
||||
|
||||
gettimeofday(&tv2, NULL);
|
||||
dt = (tv2.tv_usec - tv1.tv_usec) / 1e6;
|
||||
dt += (tv2.tv_sec - tv1.tv_sec);
|
||||
printf("%5d iter in %10.6f sec = %8.3f msec\n",
|
||||
count, dt, dt * 1000.0 / count);
|
||||
}
|
||||
|
||||
static void
|
||||
TR(double count)
|
||||
{
|
||||
double dt;
|
||||
|
||||
gettimeofday(&tv2, NULL);
|
||||
dt = (tv2.tv_usec - tv1.tv_usec) / 1e6;
|
||||
dt += (tv2.tv_sec - tv1.tv_sec);
|
||||
printf("%8.0f kbytes in %10.6f sec = %8.0f kbytes/sec\n",
|
||||
count, dt, count / dt);
|
||||
}
|
||||
|
||||
static void
|
||||
speeddisk(const char *name, int fd, off_t mediasize, u_int sectorsize)
|
||||
{
|
||||
int error, i;
|
||||
uint b0, b1, sectorcount;
|
||||
|
||||
off_t size;
|
||||
sectorcount = mediasize / sectorsize;
|
||||
|
||||
printf("Seek times:\n");
|
||||
printf("\tFull stroke:\t");
|
||||
b0 = 0;
|
||||
b1 = sectorcount - 1 - 125 * 16384;
|
||||
T0();
|
||||
for (i = 0; i < 125; i++) {
|
||||
rdsect(fd, b0, sectorsize);
|
||||
b0 += 16384;
|
||||
rdsect(fd, b1, sectorsize);
|
||||
b1 += 16384;
|
||||
}
|
||||
TN(250);
|
||||
|
||||
printf("\tHalf stroke:\t");
|
||||
b0 = sectorcount / 4;
|
||||
b1 = b0 + sectorcount / 2;
|
||||
T0();
|
||||
for (i = 0; i < 125; i++) {
|
||||
rdsect(fd, b0, sectorsize);
|
||||
b0 += 16384;
|
||||
rdsect(fd, b1, sectorsize);
|
||||
b1 += 16384;
|
||||
}
|
||||
TN(250);
|
||||
printf("\tQuarter stroke:\t");
|
||||
b0 = sectorcount / 4;
|
||||
b1 = b0 + sectorcount / 4;
|
||||
T0();
|
||||
for (i = 0; i < 250; i++) {
|
||||
rdsect(fd, b0, sectorsize);
|
||||
b0 += 16384;
|
||||
rdsect(fd, b1, sectorsize);
|
||||
b1 += 16384;
|
||||
}
|
||||
TN(500);
|
||||
|
||||
printf("\tShort forward:\t");
|
||||
b0 = sectorcount / 2;
|
||||
T0();
|
||||
for (i = 0; i < 1000; i++) {
|
||||
rdsect(fd, b0, sectorsize);
|
||||
b0 += 16384;
|
||||
}
|
||||
TN(1000);
|
||||
|
||||
printf("\tShort backward:\t");
|
||||
b0 = sectorcount / 2;
|
||||
T0();
|
||||
for (i = 0; i < 1000; i++) {
|
||||
rdsect(fd, b0, sectorsize);
|
||||
b0 -= 16384;
|
||||
}
|
||||
TN(1000);
|
||||
|
||||
printf("\tSeq outer:\t");
|
||||
b0 = 0;
|
||||
T0();
|
||||
for (i = 0; i < 20480; i++) {
|
||||
rdsect(fd, b0, sectorsize);
|
||||
b0++;
|
||||
}
|
||||
TN(20480);
|
||||
|
||||
printf("\tSeq inner:\t");
|
||||
b0 = sectorcount - 20480 - 1;
|
||||
T0();
|
||||
for (i = 0; i < 20480; i++) {
|
||||
rdsect(fd, b0, sectorsize);
|
||||
b0++;
|
||||
}
|
||||
TN(20480);
|
||||
|
||||
printf("Transfer rates:\n");
|
||||
printf("\toutside: ");
|
||||
rdsect(fd, 0, sectorsize);
|
||||
T0();
|
||||
for (i = 0; i < 100; i++) {
|
||||
rdmega(fd);
|
||||
}
|
||||
TR(100 * 1024);
|
||||
|
||||
printf("\tmiddle: ");
|
||||
b0 = sectorcount / 2;
|
||||
rdsect(fd, b0, sectorsize);
|
||||
T0();
|
||||
for (i = 0; i < 100; i++) {
|
||||
rdmega(fd);
|
||||
}
|
||||
TR(100 * 1024);
|
||||
|
||||
printf("\tinside: ");
|
||||
b0 = sectorcount - 100 * (1024*1024 / sectorsize) - 1;;
|
||||
rdsect(fd, b0, sectorsize);
|
||||
T0();
|
||||
for (i = 0; i < 100; i++) {
|
||||
rdmega(fd);
|
||||
}
|
||||
TR(100 * 1024);
|
||||
|
||||
printf("\n");
|
||||
|
||||
return;
|
||||
}
|
Loading…
Reference in New Issue
Block a user