aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/diskinfo
diff options
context:
space:
mode:
authorEdward Tomasz Napierala <trasz@FreeBSD.org>2016-09-22 07:33:43 +0000
committerEdward Tomasz Napierala <trasz@FreeBSD.org>2016-09-22 07:33:43 +0000
commitb76ce4527bd292cb36cfbc0e4f390c3231ae4095 (patch)
treec81fc85f9a7b3f0a7bd7d045153667e7f082e2a7 /usr.sbin/diskinfo
parent5c6b397ff191ce6fbc32f3629d5bee5c12d14c82 (diff)
downloadsrc-b76ce4527bd292cb36cfbc0e4f390c3231ae4095.tar.gz
src-b76ce4527bd292cb36cfbc0e4f390c3231ae4095.zip
Notes
Diffstat (limited to 'usr.sbin/diskinfo')
-rw-r--r--usr.sbin/diskinfo/diskinfo.88
-rw-r--r--usr.sbin/diskinfo/diskinfo.c111
2 files changed, 114 insertions, 5 deletions
diff --git a/usr.sbin/diskinfo/diskinfo.8 b/usr.sbin/diskinfo/diskinfo.8
index f68d426e6b49..f4b466424de3 100644
--- a/usr.sbin/diskinfo/diskinfo.8
+++ b/usr.sbin/diskinfo/diskinfo.8
@@ -28,7 +28,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 9, 2004
+.Dd September 22, 2016
.Dt DISKINFO 8
.Os
.Sh NAME
@@ -36,7 +36,7 @@
.Nd get information about disk device
.Sh SYNOPSIS
.Nm
-.Op Fl ctv
+.Op Fl citv
.Ar disk ...
.Sh DESCRIPTION
The
@@ -59,6 +59,10 @@ The
option triggers a simple measurement of the I/O read command overhead.
.Pp
The
+.Fl i
+option triggers a simple IOPS benchmark.
+.Pp
+The
.Fl t
option triggers a simple and rather naive benchmark of the disks seek
and transfer performance.
diff --git a/usr.sbin/diskinfo/diskinfo.c b/usr.sbin/diskinfo/diskinfo.c
index 74fc91ed3ee1..df51aac2691e 100644
--- a/usr.sbin/diskinfo/diskinfo.c
+++ b/usr.sbin/diskinfo/diskinfo.c
@@ -40,22 +40,26 @@
#include <libutil.h>
#include <paths.h>
#include <err.h>
+#include <sys/aio.h>
#include <sys/disk.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/time.h>
+#define NAIO 128
+
static void
usage(void)
{
- fprintf(stderr, "usage: diskinfo [-ctv] disk ...\n");
+ fprintf(stderr, "usage: diskinfo [-citv] disk ...\n");
exit (1);
}
-static int opt_c, opt_t, opt_v;
+static int opt_c, opt_i, opt_t, opt_v;
static void speeddisk(int fd, off_t mediasize, u_int sectorsize);
static void commandtime(int fd, off_t mediasize, u_int sectorsize);
+static void iopsbench(int fd, off_t mediasize, u_int sectorsize);
static int zonecheck(int fd, uint32_t *zone_mode, char *zone_str,
size_t zone_str_len);
@@ -70,12 +74,16 @@ main(int argc, char **argv)
u_int sectorsize, fwsectors, fwheads, zoned = 0;
uint32_t zone_mode;
- while ((ch = getopt(argc, argv, "ctv")) != -1) {
+ while ((ch = getopt(argc, argv, "citv")) != -1) {
switch (ch) {
case 'c':
opt_c = 1;
opt_v = 1;
break;
+ case 'i':
+ opt_i = 1;
+ opt_v = 1;
+ break;
case 't':
opt_t = 1;
opt_v = 1;
@@ -188,6 +196,8 @@ main(int argc, char **argv)
commandtime(fd, mediasize, sectorsize);
if (opt_t)
speeddisk(fd, mediasize, sectorsize);
+ if (opt_i)
+ iopsbench(fd, mediasize, sectorsize);
out:
close(fd);
}
@@ -270,6 +280,16 @@ TR(double count)
}
static void
+TI(double count)
+{
+ double dt;
+
+ dt = delta_t();
+ printf("%8.0f ops in %10.6f sec = %8.0f IOPS\n",
+ count, dt, count / dt);
+}
+
+static void
speeddisk(int fd, off_t mediasize, u_int sectorsize)
{
int bulk, i;
@@ -418,6 +438,91 @@ commandtime(int fd, off_t mediasize, u_int sectorsize)
return;
}
+static void
+iops(int fd, off_t mediasize, u_int sectorsize)
+{
+ struct aiocb aios[NAIO], *aiop;
+ ssize_t ret;
+ off_t sectorcount;
+ int error, i, queued, completed;
+
+ sectorcount = mediasize / sectorsize;
+
+ for (i = 0; i < NAIO; i++) {
+ aiop = &(aios[i]);
+ bzero(aiop, sizeof(*aiop));
+ aiop->aio_buf = malloc(sectorsize);
+ if (aiop->aio_buf == NULL)
+ err(1, "malloc");
+ }
+
+ T0();
+ for (i = 0; i < NAIO; i++) {
+ aiop = &(aios[i]);
+
+ aiop->aio_fildes = fd;
+ aiop->aio_offset = (random() % (sectorcount)) * sectorsize;
+ aiop->aio_nbytes = sectorsize;
+
+ error = aio_read(aiop);
+ if (error != 0)
+ err(1, "aio_read");
+ }
+
+ queued = i;
+ completed = 0;
+
+ for (;;) {
+ ret = aio_waitcomplete(&aiop, NULL);
+ if (ret < 0)
+ err(1, "aio_waitcomplete");
+ if (ret != (ssize_t)sectorsize)
+ errx(1, "short read");
+
+ completed++;
+
+ if (delta_t() < 3.0) {
+ aiop->aio_fildes = fd;
+ aiop->aio_offset = (random() % (sectorcount)) * sectorsize;
+ aiop->aio_nbytes = sectorsize;
+
+ error = aio_read(aiop);
+ if (error != 0)
+ err(1, "aio_read");
+
+ queued++;
+ } else if (completed == queued) {
+ break;
+ }
+ }
+
+ TI(completed);
+
+ return;
+}
+
+static void
+iopsbench(int fd, off_t mediasize, u_int sectorsize)
+{
+ printf("Asynchronous random reads:\n");
+
+ printf("\tsectorsize: ");
+ iops(fd, mediasize, sectorsize);
+
+ if (sectorsize != 4096) {
+ printf("\t4 kbytes: ");
+ iops(fd, mediasize, 4096);
+ }
+
+ printf("\t32 kbytes: ");
+ iops(fd, mediasize, 32 * 1024);
+
+ printf("\t128 kbytes: ");
+ iops(fd, mediasize, 128 * 1024);
+
+ printf("\n");
+}
+
static int
zonecheck(int fd, uint32_t *zone_mode, char *zone_str, size_t zone_str_len)
{