1a362eb63SPoul-Henning Kamp /*-
21de7b4b8SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause
31de7b4b8SPedro F. Giffuni *
4a362eb63SPoul-Henning Kamp * Copyright (c) 2003 Poul-Henning Kamp
59a6844d5SKenneth D. Merry * Copyright (c) 2015 Spectra Logic Corporation
61a01f934SAlexander Motin * Copyright (c) 2017 Alexander Motin <mav@FreeBSD.org>
7a362eb63SPoul-Henning Kamp * All rights reserved.
8a362eb63SPoul-Henning Kamp *
9a362eb63SPoul-Henning Kamp * Redistribution and use in source and binary forms, with or without
10a362eb63SPoul-Henning Kamp * modification, are permitted provided that the following conditions
11a362eb63SPoul-Henning Kamp * are met:
12a362eb63SPoul-Henning Kamp * 1. Redistributions of source code must retain the above copyright
13a362eb63SPoul-Henning Kamp * notice, this list of conditions and the following disclaimer.
14a362eb63SPoul-Henning Kamp * 2. Redistributions in binary form must reproduce the above copyright
15a362eb63SPoul-Henning Kamp * notice, this list of conditions and the following disclaimer in the
16a362eb63SPoul-Henning Kamp * documentation and/or other materials provided with the distribution.
17a362eb63SPoul-Henning Kamp * 3. The names of the authors may not be used to endorse or promote
18a362eb63SPoul-Henning Kamp * products derived from this software without specific prior written
19a362eb63SPoul-Henning Kamp * permission.
20a362eb63SPoul-Henning Kamp *
21a362eb63SPoul-Henning Kamp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22a362eb63SPoul-Henning Kamp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23a362eb63SPoul-Henning Kamp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24a362eb63SPoul-Henning Kamp * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25a362eb63SPoul-Henning Kamp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26a362eb63SPoul-Henning Kamp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27a362eb63SPoul-Henning Kamp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28a362eb63SPoul-Henning Kamp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29a362eb63SPoul-Henning Kamp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30a362eb63SPoul-Henning Kamp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31a362eb63SPoul-Henning Kamp * SUCH DAMAGE.
32a362eb63SPoul-Henning Kamp */
33a362eb63SPoul-Henning Kamp
3427f0f2ecSAlan Somers #include <stdbool.h>
35a362eb63SPoul-Henning Kamp #include <stdio.h>
36a362eb63SPoul-Henning Kamp #include <stdint.h>
37cbf67506SPoul-Henning Kamp #include <stdlib.h>
38321728ceSAlexander Motin #include <string.h>
3923454425SAlexander Motin #include <strings.h>
40a362eb63SPoul-Henning Kamp #include <unistd.h>
41a362eb63SPoul-Henning Kamp #include <errno.h>
42a362eb63SPoul-Henning Kamp #include <fcntl.h>
43991d64ecSPawel Jakub Dawidek #include <libutil.h>
44a362eb63SPoul-Henning Kamp #include <paths.h>
45a362eb63SPoul-Henning Kamp #include <err.h>
4627f0f2ecSAlan Somers #include <geom/geom_disk.h>
471a01f934SAlexander Motin #include <sysexits.h>
48b76ce452SEdward Tomasz Napierala #include <sys/aio.h>
49a362eb63SPoul-Henning Kamp #include <sys/disk.h>
50416494d7SJustin T. Gibbs #include <sys/param.h>
515ac5a2b2SEdward Tomasz Napierala #include <sys/stat.h>
52cbf67506SPoul-Henning Kamp #include <sys/time.h>
53a362eb63SPoul-Henning Kamp
54b76ce452SEdward Tomasz Napierala #define NAIO 128
55e975a1abSAlexander Motin #define MAXTX (8*1024*1024)
56e975a1abSAlexander Motin #define MEGATX (1024*1024)
57b76ce452SEdward Tomasz Napierala
58a362eb63SPoul-Henning Kamp static void
usage(void)59a362eb63SPoul-Henning Kamp usage(void)
60a362eb63SPoul-Henning Kamp {
61*e333110dSEugene Grosbein fprintf(stderr, "usage: diskinfo [-ciStvw] disk ...\n"
62*e333110dSEugene Grosbein " diskinfo [-l] -p disk ...\n"
63*e333110dSEugene Grosbein " diskinfo [-l] -s disk ...\n"
64*e333110dSEugene Grosbein );
65a362eb63SPoul-Henning Kamp exit (1);
66a362eb63SPoul-Henning Kamp }
67a362eb63SPoul-Henning Kamp
68*e333110dSEugene Grosbein static int opt_c, opt_i, opt_l, opt_p, opt_s, opt_S, opt_t, opt_v, opt_w;
69a362eb63SPoul-Henning Kamp
7027f0f2ecSAlan Somers static bool candelete(int fd);
71cbf67506SPoul-Henning Kamp static void speeddisk(int fd, off_t mediasize, u_int sectorsize);
726a33b3c6SSøren Schmidt static void commandtime(int fd, off_t mediasize, u_int sectorsize);
73b76ce452SEdward Tomasz Napierala static void iopsbench(int fd, off_t mediasize, u_int sectorsize);
7427f0f2ecSAlan Somers static void rotationrate(int fd, char *buf, size_t buflen);
751a01f934SAlexander Motin static void slogbench(int fd, int isreg, off_t mediasize, u_int sectorsize);
769a6844d5SKenneth D. Merry static int zonecheck(int fd, uint32_t *zone_mode, char *zone_str,
779a6844d5SKenneth D. Merry size_t zone_str_len);
78a362eb63SPoul-Henning Kamp
79e975a1abSAlexander Motin static uint8_t *buf;
80e975a1abSAlexander Motin
81a362eb63SPoul-Henning Kamp int
main(int argc,char ** argv)82a362eb63SPoul-Henning Kamp main(int argc, char **argv)
83a362eb63SPoul-Henning Kamp {
845ac5a2b2SEdward Tomasz Napierala struct stat sb;
85f5d62d03SXin LI int i, ch, fd, error, exitval = 0;
86e975a1abSAlexander Motin char tstr[BUFSIZ], ident[DISK_IDENT_SIZE], physpath[MAXPATHLEN];
879a6844d5SKenneth D. Merry char zone_desc[64];
8827f0f2ecSAlan Somers char rrate[64];
89321728ceSAlexander Motin struct diocgattr_arg arg;
90851b967aSAlexander Motin off_t mediasize, stripesize, stripeoffset;
911a01f934SAlexander Motin u_int sectorsize, fwsectors, fwheads, zoned = 0, isreg;
929a6844d5SKenneth D. Merry uint32_t zone_mode;
93a362eb63SPoul-Henning Kamp
94*e333110dSEugene Grosbein while ((ch = getopt(argc, argv, "cilpsStvw")) != -1) {
95a362eb63SPoul-Henning Kamp switch (ch) {
966a33b3c6SSøren Schmidt case 'c':
976a33b3c6SSøren Schmidt opt_c = 1;
986a33b3c6SSøren Schmidt opt_v = 1;
996a33b3c6SSøren Schmidt break;
100b76ce452SEdward Tomasz Napierala case 'i':
101b76ce452SEdward Tomasz Napierala opt_i = 1;
102b76ce452SEdward Tomasz Napierala opt_v = 1;
103b76ce452SEdward Tomasz Napierala break;
104*e333110dSEugene Grosbein case 'l':
105*e333110dSEugene Grosbein opt_l = 1;
106*e333110dSEugene Grosbein break;
107278a04f5SAllan Jude case 'p':
108278a04f5SAllan Jude opt_p = 1;
109278a04f5SAllan Jude break;
110278a04f5SAllan Jude case 's':
111278a04f5SAllan Jude opt_s = 1;
112278a04f5SAllan Jude break;
1131a01f934SAlexander Motin case 'S':
1141a01f934SAlexander Motin opt_S = 1;
1151a01f934SAlexander Motin opt_v = 1;
1161a01f934SAlexander Motin break;
117a362eb63SPoul-Henning Kamp case 't':
118a362eb63SPoul-Henning Kamp opt_t = 1;
119a362eb63SPoul-Henning Kamp opt_v = 1;
120a362eb63SPoul-Henning Kamp break;
121a362eb63SPoul-Henning Kamp case 'v':
122a362eb63SPoul-Henning Kamp opt_v = 1;
123a362eb63SPoul-Henning Kamp break;
1241a01f934SAlexander Motin case 'w':
1251a01f934SAlexander Motin opt_w = 1;
1261a01f934SAlexander Motin break;
127a362eb63SPoul-Henning Kamp default:
128a362eb63SPoul-Henning Kamp usage();
129a362eb63SPoul-Henning Kamp }
130a362eb63SPoul-Henning Kamp }
131a362eb63SPoul-Henning Kamp argc -= optind;
132a362eb63SPoul-Henning Kamp argv += optind;
133a362eb63SPoul-Henning Kamp
1349137d52aSRuslan Ermilov if (argc < 1)
1359137d52aSRuslan Ermilov usage();
1369137d52aSRuslan Ermilov
137278a04f5SAllan Jude if ((opt_p && opt_s) || ((opt_p || opt_s) && (opt_c || opt_i || opt_t || opt_v))) {
138278a04f5SAllan Jude warnx("-p or -s cannot be used with other options");
139278a04f5SAllan Jude usage();
140278a04f5SAllan Jude }
141278a04f5SAllan Jude
1421a01f934SAlexander Motin if (opt_S && !opt_w) {
1431a01f934SAlexander Motin warnx("-S require also -w");
1441a01f934SAlexander Motin usage();
1451a01f934SAlexander Motin }
1461a01f934SAlexander Motin
147e975a1abSAlexander Motin if (posix_memalign((void **)&buf, PAGE_SIZE, MAXTX))
148e975a1abSAlexander Motin errx(1, "Can't allocate memory buffer");
149a362eb63SPoul-Henning Kamp for (i = 0; i < argc; i++) {
1501a01f934SAlexander Motin fd = open(argv[i], (opt_w ? O_RDWR : O_RDONLY) | O_DIRECT);
151a362eb63SPoul-Henning Kamp if (fd < 0 && errno == ENOENT && *argv[i] != '/') {
152e975a1abSAlexander Motin snprintf(tstr, sizeof(tstr), "%s%s", _PATH_DEV, argv[i]);
153e975a1abSAlexander Motin fd = open(tstr, O_RDONLY);
154a362eb63SPoul-Henning Kamp }
155f5d62d03SXin LI if (fd < 0) {
156f5d62d03SXin LI warn("%s", argv[i]);
1574c9f98e2SAlan Somers exit(1);
158f5d62d03SXin LI }
1595ac5a2b2SEdward Tomasz Napierala error = fstat(fd, &sb);
1605ac5a2b2SEdward Tomasz Napierala if (error != 0) {
1615ac5a2b2SEdward Tomasz Napierala warn("cannot stat %s", argv[i]);
1625ac5a2b2SEdward Tomasz Napierala exitval = 1;
1635ac5a2b2SEdward Tomasz Napierala goto out;
1645ac5a2b2SEdward Tomasz Napierala }
1651a01f934SAlexander Motin isreg = S_ISREG(sb.st_mode);
1661a01f934SAlexander Motin if (isreg) {
1675ac5a2b2SEdward Tomasz Napierala mediasize = sb.st_size;
1685ac5a2b2SEdward Tomasz Napierala sectorsize = S_BLKSIZE;
1695ac5a2b2SEdward Tomasz Napierala fwsectors = 0;
1705ac5a2b2SEdward Tomasz Napierala fwheads = 0;
1715ac5a2b2SEdward Tomasz Napierala stripesize = sb.st_blksize;
1725ac5a2b2SEdward Tomasz Napierala stripeoffset = 0;
173278a04f5SAllan Jude if (opt_p || opt_s) {
174278a04f5SAllan Jude warnx("-p and -s only operate on physical devices: %s", argv[i]);
175278a04f5SAllan Jude goto out;
176278a04f5SAllan Jude }
1775ac5a2b2SEdward Tomasz Napierala } else {
178*e333110dSEugene Grosbein if (opt_l && (opt_p || opt_s)) {
179*e333110dSEugene Grosbein printf("%s\t", argv[i]);
180*e333110dSEugene Grosbein }
181278a04f5SAllan Jude if (opt_p) {
182278a04f5SAllan Jude if (ioctl(fd, DIOCGPHYSPATH, physpath) == 0) {
183278a04f5SAllan Jude printf("%s\n", physpath);
184278a04f5SAllan Jude } else {
185278a04f5SAllan Jude warnx("Failed to determine physpath for: %s", argv[i]);
186278a04f5SAllan Jude }
187278a04f5SAllan Jude goto out;
188278a04f5SAllan Jude }
189278a04f5SAllan Jude if (opt_s) {
190278a04f5SAllan Jude if (ioctl(fd, DIOCGIDENT, ident) == 0) {
191278a04f5SAllan Jude printf("%s\n", ident);
192278a04f5SAllan Jude } else {
193278a04f5SAllan Jude warnx("Failed to determine serial number for: %s", argv[i]);
194278a04f5SAllan Jude }
195278a04f5SAllan Jude goto out;
196278a04f5SAllan Jude }
197a362eb63SPoul-Henning Kamp error = ioctl(fd, DIOCGMEDIASIZE, &mediasize);
198f5d62d03SXin LI if (error) {
1996b381ff3SEdward Tomasz Napierala warnx("%s: ioctl(DIOCGMEDIASIZE) failed, probably not a disk.", argv[i]);
200f5d62d03SXin LI exitval = 1;
201f5d62d03SXin LI goto out;
202f5d62d03SXin LI }
203a362eb63SPoul-Henning Kamp error = ioctl(fd, DIOCGSECTORSIZE, §orsize);
204f5d62d03SXin LI if (error) {
2056b381ff3SEdward Tomasz Napierala warnx("%s: ioctl(DIOCGSECTORSIZE) failed, probably not a disk.", argv[i]);
206f5d62d03SXin LI exitval = 1;
207f5d62d03SXin LI goto out;
208f5d62d03SXin LI }
209a362eb63SPoul-Henning Kamp error = ioctl(fd, DIOCGFWSECTORS, &fwsectors);
210a362eb63SPoul-Henning Kamp if (error)
211a362eb63SPoul-Henning Kamp fwsectors = 0;
212a362eb63SPoul-Henning Kamp error = ioctl(fd, DIOCGFWHEADS, &fwheads);
213a362eb63SPoul-Henning Kamp if (error)
214a362eb63SPoul-Henning Kamp fwheads = 0;
215851b967aSAlexander Motin error = ioctl(fd, DIOCGSTRIPESIZE, &stripesize);
216851b967aSAlexander Motin if (error)
217851b967aSAlexander Motin stripesize = 0;
218851b967aSAlexander Motin error = ioctl(fd, DIOCGSTRIPEOFFSET, &stripeoffset);
219851b967aSAlexander Motin if (error)
220851b967aSAlexander Motin stripeoffset = 0;
2219a6844d5SKenneth D. Merry error = zonecheck(fd, &zone_mode, zone_desc, sizeof(zone_desc));
2229a6844d5SKenneth D. Merry if (error == 0)
2239a6844d5SKenneth D. Merry zoned = 1;
2245ac5a2b2SEdward Tomasz Napierala }
225a362eb63SPoul-Henning Kamp if (!opt_v) {
226a362eb63SPoul-Henning Kamp printf("%s", argv[i]);
227a362eb63SPoul-Henning Kamp printf("\t%u", sectorsize);
228a362eb63SPoul-Henning Kamp printf("\t%jd", (intmax_t)mediasize);
229a362eb63SPoul-Henning Kamp printf("\t%jd", (intmax_t)mediasize/sectorsize);
230851b967aSAlexander Motin printf("\t%jd", (intmax_t)stripesize);
231851b967aSAlexander Motin printf("\t%jd", (intmax_t)stripeoffset);
232a362eb63SPoul-Henning Kamp if (fwsectors != 0 && fwheads != 0) {
233a362eb63SPoul-Henning Kamp printf("\t%jd", (intmax_t)mediasize /
234a362eb63SPoul-Henning Kamp (fwsectors * fwheads * sectorsize));
235a362eb63SPoul-Henning Kamp printf("\t%u", fwheads);
236a362eb63SPoul-Henning Kamp printf("\t%u", fwsectors);
237a362eb63SPoul-Henning Kamp }
238a362eb63SPoul-Henning Kamp } else {
239e975a1abSAlexander Motin humanize_number(tstr, 5, (int64_t)mediasize, "",
240991d64ecSPawel Jakub Dawidek HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
241a362eb63SPoul-Henning Kamp printf("%s\n", argv[i]);
242a362eb63SPoul-Henning Kamp printf("\t%-12u\t# sectorsize\n", sectorsize);
243991d64ecSPawel Jakub Dawidek printf("\t%-12jd\t# mediasize in bytes (%s)\n",
244e975a1abSAlexander Motin (intmax_t)mediasize, tstr);
245a362eb63SPoul-Henning Kamp printf("\t%-12jd\t# mediasize in sectors\n",
246a362eb63SPoul-Henning Kamp (intmax_t)mediasize/sectorsize);
247851b967aSAlexander Motin printf("\t%-12jd\t# stripesize\n", stripesize);
248851b967aSAlexander Motin printf("\t%-12jd\t# stripeoffset\n", stripeoffset);
249a362eb63SPoul-Henning Kamp if (fwsectors != 0 && fwheads != 0) {
250a362eb63SPoul-Henning Kamp printf("\t%-12jd\t# Cylinders according to firmware.\n", (intmax_t)mediasize /
251a362eb63SPoul-Henning Kamp (fwsectors * fwheads * sectorsize));
252a362eb63SPoul-Henning Kamp printf("\t%-12u\t# Heads according to firmware.\n", fwheads);
253a362eb63SPoul-Henning Kamp printf("\t%-12u\t# Sectors according to firmware.\n", fwsectors);
254a362eb63SPoul-Henning Kamp }
255321728ceSAlexander Motin strlcpy(arg.name, "GEOM::descr", sizeof(arg.name));
256321728ceSAlexander Motin arg.len = sizeof(arg.value.str);
257321728ceSAlexander Motin if (ioctl(fd, DIOCGATTR, &arg) == 0)
258321728ceSAlexander Motin printf("\t%-12s\t# Disk descr.\n", arg.value.str);
25918e5fe28SPawel Jakub Dawidek if (ioctl(fd, DIOCGIDENT, ident) == 0)
260c5791aaeSPawel Jakub Dawidek printf("\t%-12s\t# Disk ident.\n", ident);
261b5961be1SEdward Tomasz Napierala strlcpy(arg.name, "GEOM::attachment", sizeof(arg.name));
262b5961be1SEdward Tomasz Napierala arg.len = sizeof(arg.value.str);
263b5961be1SEdward Tomasz Napierala if (ioctl(fd, DIOCGATTR, &arg) == 0)
264b5961be1SEdward Tomasz Napierala printf("\t%-12s\t# Attachment\n", arg.value.str);
265416494d7SJustin T. Gibbs if (ioctl(fd, DIOCGPHYSPATH, physpath) == 0)
266416494d7SJustin T. Gibbs printf("\t%-12s\t# Physical path\n", physpath);
26727f0f2ecSAlan Somers printf("\t%-12s\t# TRIM/UNMAP support\n",
26827f0f2ecSAlan Somers candelete(fd) ? "Yes" : "No");
26927f0f2ecSAlan Somers rotationrate(fd, rrate, sizeof(rrate));
27027f0f2ecSAlan Somers printf("\t%-12s\t# Rotation rate in RPM\n", rrate);
2719a6844d5SKenneth D. Merry if (zoned != 0)
2729a6844d5SKenneth D. Merry printf("\t%-12s\t# Zone Mode\n", zone_desc);
273a362eb63SPoul-Henning Kamp }
274a362eb63SPoul-Henning Kamp printf("\n");
2756a33b3c6SSøren Schmidt if (opt_c)
2766a33b3c6SSøren Schmidt commandtime(fd, mediasize, sectorsize);
277a362eb63SPoul-Henning Kamp if (opt_t)
278cbf67506SPoul-Henning Kamp speeddisk(fd, mediasize, sectorsize);
279b76ce452SEdward Tomasz Napierala if (opt_i)
280b76ce452SEdward Tomasz Napierala iopsbench(fd, mediasize, sectorsize);
2811a01f934SAlexander Motin if (opt_S)
2821a01f934SAlexander Motin slogbench(fd, isreg, mediasize, sectorsize);
283f5d62d03SXin LI out:
284a362eb63SPoul-Henning Kamp close(fd);
285a362eb63SPoul-Henning Kamp }
286e975a1abSAlexander Motin free(buf);
287f5d62d03SXin LI exit (exitval);
288a362eb63SPoul-Henning Kamp }
289a362eb63SPoul-Henning Kamp
29027f0f2ecSAlan Somers static bool
candelete(int fd)29127f0f2ecSAlan Somers candelete(int fd)
29227f0f2ecSAlan Somers {
29327f0f2ecSAlan Somers struct diocgattr_arg arg;
29427f0f2ecSAlan Somers
29527f0f2ecSAlan Somers strlcpy(arg.name, "GEOM::candelete", sizeof(arg.name));
29627f0f2ecSAlan Somers arg.len = sizeof(arg.value.i);
29727f0f2ecSAlan Somers if (ioctl(fd, DIOCGATTR, &arg) == 0)
29827f0f2ecSAlan Somers return (arg.value.i != 0);
29927f0f2ecSAlan Somers else
30027f0f2ecSAlan Somers return (false);
30127f0f2ecSAlan Somers }
30227f0f2ecSAlan Somers
30327f0f2ecSAlan Somers static void
rotationrate(int fd,char * rate,size_t buflen)30427f0f2ecSAlan Somers rotationrate(int fd, char *rate, size_t buflen)
30527f0f2ecSAlan Somers {
30627f0f2ecSAlan Somers struct diocgattr_arg arg;
30727f0f2ecSAlan Somers int ret;
30827f0f2ecSAlan Somers
30927f0f2ecSAlan Somers strlcpy(arg.name, "GEOM::rotation_rate", sizeof(arg.name));
31027f0f2ecSAlan Somers arg.len = sizeof(arg.value.u16);
31127f0f2ecSAlan Somers
31227f0f2ecSAlan Somers ret = ioctl(fd, DIOCGATTR, &arg);
31327f0f2ecSAlan Somers if (ret < 0 || arg.value.u16 == DISK_RR_UNKNOWN)
31427f0f2ecSAlan Somers snprintf(rate, buflen, "Unknown");
31527f0f2ecSAlan Somers else if (arg.value.u16 == DISK_RR_NON_ROTATING)
31627f0f2ecSAlan Somers snprintf(rate, buflen, "%d", 0);
31727f0f2ecSAlan Somers else if (arg.value.u16 >= DISK_RR_MIN && arg.value.u16 <= DISK_RR_MAX)
31827f0f2ecSAlan Somers snprintf(rate, buflen, "%d", arg.value.u16);
31927f0f2ecSAlan Somers else
32027f0f2ecSAlan Somers snprintf(rate, buflen, "Invalid");
32127f0f2ecSAlan Somers }
32227f0f2ecSAlan Somers
323a362eb63SPoul-Henning Kamp static void
rdsect(int fd,off_t blockno,u_int sectorsize)32423454425SAlexander Motin rdsect(int fd, off_t blockno, u_int sectorsize)
325a362eb63SPoul-Henning Kamp {
326a362eb63SPoul-Henning Kamp int error;
327a362eb63SPoul-Henning Kamp
3284c9f98e2SAlan Somers if (lseek(fd, (off_t)blockno * sectorsize, SEEK_SET) == -1)
3294c9f98e2SAlan Somers err(1, "lseek");
3301a01f934SAlexander Motin error = read(fd, buf, sectorsize);
3316b381ff3SEdward Tomasz Napierala if (error == -1)
3326b381ff3SEdward Tomasz Napierala err(1, "read");
333cbf67506SPoul-Henning Kamp if (error != (int)sectorsize)
3346b381ff3SEdward Tomasz Napierala errx(1, "disk too small for test.");
335a362eb63SPoul-Henning Kamp }
336a362eb63SPoul-Henning Kamp
337a362eb63SPoul-Henning Kamp static void
rdmega(int fd)338a362eb63SPoul-Henning Kamp rdmega(int fd)
339a362eb63SPoul-Henning Kamp {
340a362eb63SPoul-Henning Kamp int error;
341a362eb63SPoul-Henning Kamp
3421a01f934SAlexander Motin error = read(fd, buf, MEGATX);
3436b381ff3SEdward Tomasz Napierala if (error == -1)
3446b381ff3SEdward Tomasz Napierala err(1, "read");
3451a01f934SAlexander Motin if (error != MEGATX)
3466b381ff3SEdward Tomasz Napierala errx(1, "disk too small for test.");
347a362eb63SPoul-Henning Kamp }
348a362eb63SPoul-Henning Kamp
349a362eb63SPoul-Henning Kamp static struct timeval tv1, tv2;
350a362eb63SPoul-Henning Kamp
351a362eb63SPoul-Henning Kamp static void
T0(void)352a362eb63SPoul-Henning Kamp T0(void)
353a362eb63SPoul-Henning Kamp {
354a362eb63SPoul-Henning Kamp
355a362eb63SPoul-Henning Kamp fflush(stdout);
356a362eb63SPoul-Henning Kamp sync();
357a362eb63SPoul-Henning Kamp sleep(1);
358a362eb63SPoul-Henning Kamp sync();
359a362eb63SPoul-Henning Kamp sync();
360a362eb63SPoul-Henning Kamp gettimeofday(&tv1, NULL);
361a362eb63SPoul-Henning Kamp }
362a362eb63SPoul-Henning Kamp
363f289d2a5SEdward Tomasz Napierala static double
delta_t(void)364f289d2a5SEdward Tomasz Napierala delta_t(void)
365a362eb63SPoul-Henning Kamp {
366a362eb63SPoul-Henning Kamp double dt;
367a362eb63SPoul-Henning Kamp
368a362eb63SPoul-Henning Kamp gettimeofday(&tv2, NULL);
369a362eb63SPoul-Henning Kamp dt = (tv2.tv_usec - tv1.tv_usec) / 1e6;
370a362eb63SPoul-Henning Kamp dt += (tv2.tv_sec - tv1.tv_sec);
371f289d2a5SEdward Tomasz Napierala
372f289d2a5SEdward Tomasz Napierala return (dt);
373f289d2a5SEdward Tomasz Napierala }
374f289d2a5SEdward Tomasz Napierala
375f289d2a5SEdward Tomasz Napierala static void
TN(int count)376f289d2a5SEdward Tomasz Napierala TN(int count)
377f289d2a5SEdward Tomasz Napierala {
378f289d2a5SEdward Tomasz Napierala double dt;
379f289d2a5SEdward Tomasz Napierala
380f289d2a5SEdward Tomasz Napierala dt = delta_t();
381a362eb63SPoul-Henning Kamp printf("%5d iter in %10.6f sec = %8.3f msec\n",
382a362eb63SPoul-Henning Kamp count, dt, dt * 1000.0 / count);
383a362eb63SPoul-Henning Kamp }
384a362eb63SPoul-Henning Kamp
385a362eb63SPoul-Henning Kamp static void
TR(double count)386a362eb63SPoul-Henning Kamp TR(double count)
387a362eb63SPoul-Henning Kamp {
388a362eb63SPoul-Henning Kamp double dt;
389a362eb63SPoul-Henning Kamp
390f289d2a5SEdward Tomasz Napierala dt = delta_t();
391a362eb63SPoul-Henning Kamp printf("%8.0f kbytes in %10.6f sec = %8.0f kbytes/sec\n",
392a362eb63SPoul-Henning Kamp count, dt, count / dt);
393a362eb63SPoul-Henning Kamp }
394a362eb63SPoul-Henning Kamp
395a362eb63SPoul-Henning Kamp static void
TI(double count)396b76ce452SEdward Tomasz Napierala TI(double count)
397b76ce452SEdward Tomasz Napierala {
398b76ce452SEdward Tomasz Napierala double dt;
399b76ce452SEdward Tomasz Napierala
400b76ce452SEdward Tomasz Napierala dt = delta_t();
401b76ce452SEdward Tomasz Napierala printf("%8.0f ops in %10.6f sec = %8.0f IOPS\n",
402b76ce452SEdward Tomasz Napierala count, dt, count / dt);
403b76ce452SEdward Tomasz Napierala }
404b76ce452SEdward Tomasz Napierala
405b76ce452SEdward Tomasz Napierala static void
TS(u_int size,int count)4061a01f934SAlexander Motin TS(u_int size, int count)
4071a01f934SAlexander Motin {
4081a01f934SAlexander Motin double dt;
4091a01f934SAlexander Motin
4101a01f934SAlexander Motin dt = delta_t();
4111a01f934SAlexander Motin printf("%8.1f usec/IO = %8.1f Mbytes/s\n",
41231c6d731SAlexander Motin dt * 1000000.0 / count, (double)size * count / dt / (1024 * 1024));
4131a01f934SAlexander Motin }
4141a01f934SAlexander Motin
4151a01f934SAlexander Motin static void
speeddisk(int fd,off_t mediasize,u_int sectorsize)416cbf67506SPoul-Henning Kamp speeddisk(int fd, off_t mediasize, u_int sectorsize)
417a362eb63SPoul-Henning Kamp {
41823454425SAlexander Motin int bulk, i;
41923454425SAlexander Motin off_t b0, b1, sectorcount, step;
420a362eb63SPoul-Henning Kamp
4211723a6e5SWarner Losh /*
4221723a6e5SWarner Losh * Drives smaller than 1MB produce negative sector numbers,
4231723a6e5SWarner Losh * as do 2048 or fewer sectors.
4241723a6e5SWarner Losh */
425a362eb63SPoul-Henning Kamp sectorcount = mediasize / sectorsize;
4261723a6e5SWarner Losh if (mediasize < 1024 * 1024 || sectorcount < 2048)
4271723a6e5SWarner Losh return;
4281723a6e5SWarner Losh
4294c9f98e2SAlan Somers
43023454425SAlexander Motin step = 1ULL << (flsll(sectorcount / (4 * 200)) - 1);
43123454425SAlexander Motin if (step > 16384)
43223454425SAlexander Motin step = 16384;
43323454425SAlexander Motin bulk = mediasize / (1024 * 1024);
43423454425SAlexander Motin if (bulk > 100)
43523454425SAlexander Motin bulk = 100;
436a362eb63SPoul-Henning Kamp
437a362eb63SPoul-Henning Kamp printf("Seek times:\n");
438a362eb63SPoul-Henning Kamp printf("\tFull stroke:\t");
439a362eb63SPoul-Henning Kamp b0 = 0;
44023454425SAlexander Motin b1 = sectorcount - step;
441a362eb63SPoul-Henning Kamp T0();
442a362eb63SPoul-Henning Kamp for (i = 0; i < 125; i++) {
443a362eb63SPoul-Henning Kamp rdsect(fd, b0, sectorsize);
44423454425SAlexander Motin b0 += step;
445a362eb63SPoul-Henning Kamp rdsect(fd, b1, sectorsize);
44623454425SAlexander Motin b1 -= step;
447a362eb63SPoul-Henning Kamp }
448a362eb63SPoul-Henning Kamp TN(250);
449a362eb63SPoul-Henning Kamp
450a362eb63SPoul-Henning Kamp printf("\tHalf stroke:\t");
451a362eb63SPoul-Henning Kamp b0 = sectorcount / 4;
452a362eb63SPoul-Henning Kamp b1 = b0 + sectorcount / 2;
453a362eb63SPoul-Henning Kamp T0();
454a362eb63SPoul-Henning Kamp for (i = 0; i < 125; i++) {
455a362eb63SPoul-Henning Kamp rdsect(fd, b0, sectorsize);
45623454425SAlexander Motin b0 += step;
457a362eb63SPoul-Henning Kamp rdsect(fd, b1, sectorsize);
45823454425SAlexander Motin b1 += step;
459a362eb63SPoul-Henning Kamp }
460a362eb63SPoul-Henning Kamp TN(250);
461a362eb63SPoul-Henning Kamp printf("\tQuarter stroke:\t");
462a362eb63SPoul-Henning Kamp b0 = sectorcount / 4;
463a362eb63SPoul-Henning Kamp b1 = b0 + sectorcount / 4;
464a362eb63SPoul-Henning Kamp T0();
465a362eb63SPoul-Henning Kamp for (i = 0; i < 250; i++) {
466a362eb63SPoul-Henning Kamp rdsect(fd, b0, sectorsize);
46723454425SAlexander Motin b0 += step;
468a362eb63SPoul-Henning Kamp rdsect(fd, b1, sectorsize);
46923454425SAlexander Motin b1 += step;
470a362eb63SPoul-Henning Kamp }
471a362eb63SPoul-Henning Kamp TN(500);
472a362eb63SPoul-Henning Kamp
473a362eb63SPoul-Henning Kamp printf("\tShort forward:\t");
474a362eb63SPoul-Henning Kamp b0 = sectorcount / 2;
475a362eb63SPoul-Henning Kamp T0();
476b8c2d40dSPoul-Henning Kamp for (i = 0; i < 400; i++) {
477a362eb63SPoul-Henning Kamp rdsect(fd, b0, sectorsize);
47823454425SAlexander Motin b0 += step;
479a362eb63SPoul-Henning Kamp }
480b8c2d40dSPoul-Henning Kamp TN(400);
481a362eb63SPoul-Henning Kamp
482a362eb63SPoul-Henning Kamp printf("\tShort backward:\t");
483a362eb63SPoul-Henning Kamp b0 = sectorcount / 2;
484a362eb63SPoul-Henning Kamp T0();
485b8c2d40dSPoul-Henning Kamp for (i = 0; i < 400; i++) {
486a362eb63SPoul-Henning Kamp rdsect(fd, b0, sectorsize);
48723454425SAlexander Motin b0 -= step;
488a362eb63SPoul-Henning Kamp }
489b8c2d40dSPoul-Henning Kamp TN(400);
490a362eb63SPoul-Henning Kamp
491a362eb63SPoul-Henning Kamp printf("\tSeq outer:\t");
492a362eb63SPoul-Henning Kamp b0 = 0;
493a362eb63SPoul-Henning Kamp T0();
494b8c2d40dSPoul-Henning Kamp for (i = 0; i < 2048; i++) {
495a362eb63SPoul-Henning Kamp rdsect(fd, b0, sectorsize);
496a362eb63SPoul-Henning Kamp b0++;
497a362eb63SPoul-Henning Kamp }
498b8c2d40dSPoul-Henning Kamp TN(2048);
499a362eb63SPoul-Henning Kamp
500a362eb63SPoul-Henning Kamp printf("\tSeq inner:\t");
50123454425SAlexander Motin b0 = sectorcount - 2048;
502a362eb63SPoul-Henning Kamp T0();
503b8c2d40dSPoul-Henning Kamp for (i = 0; i < 2048; i++) {
504a362eb63SPoul-Henning Kamp rdsect(fd, b0, sectorsize);
505a362eb63SPoul-Henning Kamp b0++;
506a362eb63SPoul-Henning Kamp }
507b8c2d40dSPoul-Henning Kamp TN(2048);
508a362eb63SPoul-Henning Kamp
5096307380aSEdward Tomasz Napierala printf("\nTransfer rates:\n");
510a362eb63SPoul-Henning Kamp printf("\toutside: ");
511a362eb63SPoul-Henning Kamp rdsect(fd, 0, sectorsize);
512a362eb63SPoul-Henning Kamp T0();
51323454425SAlexander Motin for (i = 0; i < bulk; i++) {
514a362eb63SPoul-Henning Kamp rdmega(fd);
515a362eb63SPoul-Henning Kamp }
51623454425SAlexander Motin TR(bulk * 1024);
517a362eb63SPoul-Henning Kamp
518a362eb63SPoul-Henning Kamp printf("\tmiddle: ");
51923454425SAlexander Motin b0 = sectorcount / 2 - bulk * (1024*1024 / sectorsize) / 2 - 1;
520a362eb63SPoul-Henning Kamp rdsect(fd, b0, sectorsize);
521a362eb63SPoul-Henning Kamp T0();
52223454425SAlexander Motin for (i = 0; i < bulk; i++) {
523a362eb63SPoul-Henning Kamp rdmega(fd);
524a362eb63SPoul-Henning Kamp }
52523454425SAlexander Motin TR(bulk * 1024);
526a362eb63SPoul-Henning Kamp
527a362eb63SPoul-Henning Kamp printf("\tinside: ");
528db702c59SEitan Adler b0 = sectorcount - bulk * (1024*1024 / sectorsize) - 1;
529a362eb63SPoul-Henning Kamp rdsect(fd, b0, sectorsize);
530a362eb63SPoul-Henning Kamp T0();
53123454425SAlexander Motin for (i = 0; i < bulk; i++) {
532a362eb63SPoul-Henning Kamp rdmega(fd);
533a362eb63SPoul-Henning Kamp }
53423454425SAlexander Motin TR(bulk * 1024);
535a362eb63SPoul-Henning Kamp
536a362eb63SPoul-Henning Kamp printf("\n");
5376a33b3c6SSøren Schmidt }
538a362eb63SPoul-Henning Kamp
5396a33b3c6SSøren Schmidt static void
commandtime(int fd,off_t mediasize,u_int sectorsize)5406a33b3c6SSøren Schmidt commandtime(int fd, off_t mediasize, u_int sectorsize)
5416a33b3c6SSøren Schmidt {
5426a33b3c6SSøren Schmidt double dtmega, dtsector;
5436a33b3c6SSøren Schmidt int i;
5446a33b3c6SSøren Schmidt
5456a33b3c6SSøren Schmidt printf("I/O command overhead:\n");
5466a33b3c6SSøren Schmidt i = mediasize;
5476a33b3c6SSøren Schmidt rdsect(fd, 0, sectorsize);
5486a33b3c6SSøren Schmidt T0();
5496a33b3c6SSøren Schmidt for (i = 0; i < 10; i++)
5506a33b3c6SSøren Schmidt rdmega(fd);
551f289d2a5SEdward Tomasz Napierala dtmega = delta_t();
5526a33b3c6SSøren Schmidt
5536a33b3c6SSøren Schmidt printf("\ttime to read 10MB block %10.6f sec\t= %8.3f msec/sector\n",
5546a33b3c6SSøren Schmidt dtmega, dtmega*100/2048);
5556a33b3c6SSøren Schmidt
5566a33b3c6SSøren Schmidt rdsect(fd, 0, sectorsize);
5576a33b3c6SSøren Schmidt T0();
5586a33b3c6SSøren Schmidt for (i = 0; i < 20480; i++)
5596a33b3c6SSøren Schmidt rdsect(fd, 0, sectorsize);
560f289d2a5SEdward Tomasz Napierala dtsector = delta_t();
5616a33b3c6SSøren Schmidt
5626a33b3c6SSøren Schmidt printf("\ttime to read 20480 sectors %10.6f sec\t= %8.3f msec/sector\n",
5636a33b3c6SSøren Schmidt dtsector, dtsector*100/2048);
5646a33b3c6SSøren Schmidt printf("\tcalculated command overhead\t\t\t= %8.3f msec/sector\n",
5656a33b3c6SSøren Schmidt (dtsector - dtmega)*100/2048);
5666a33b3c6SSøren Schmidt
5676a33b3c6SSøren Schmidt printf("\n");
568a362eb63SPoul-Henning Kamp }
5699a6844d5SKenneth D. Merry
570b76ce452SEdward Tomasz Napierala static void
iops(int fd,off_t mediasize,u_int sectorsize)571b76ce452SEdward Tomasz Napierala iops(int fd, off_t mediasize, u_int sectorsize)
572b76ce452SEdward Tomasz Napierala {
573b76ce452SEdward Tomasz Napierala struct aiocb aios[NAIO], *aiop;
574b76ce452SEdward Tomasz Napierala ssize_t ret;
575b76ce452SEdward Tomasz Napierala off_t sectorcount;
576b76ce452SEdward Tomasz Napierala int error, i, queued, completed;
577b76ce452SEdward Tomasz Napierala
578b76ce452SEdward Tomasz Napierala sectorcount = mediasize / sectorsize;
579b76ce452SEdward Tomasz Napierala
580b76ce452SEdward Tomasz Napierala for (i = 0; i < NAIO; i++) {
581b76ce452SEdward Tomasz Napierala aiop = &(aios[i]);
582b76ce452SEdward Tomasz Napierala bzero(aiop, sizeof(*aiop));
583b76ce452SEdward Tomasz Napierala aiop->aio_buf = malloc(sectorsize);
584b76ce452SEdward Tomasz Napierala if (aiop->aio_buf == NULL)
585b76ce452SEdward Tomasz Napierala err(1, "malloc");
586b76ce452SEdward Tomasz Napierala }
587b76ce452SEdward Tomasz Napierala
588b76ce452SEdward Tomasz Napierala T0();
589b76ce452SEdward Tomasz Napierala for (i = 0; i < NAIO; i++) {
590b76ce452SEdward Tomasz Napierala aiop = &(aios[i]);
591b76ce452SEdward Tomasz Napierala
592b76ce452SEdward Tomasz Napierala aiop->aio_fildes = fd;
593b76ce452SEdward Tomasz Napierala aiop->aio_offset = (random() % (sectorcount)) * sectorsize;
594b76ce452SEdward Tomasz Napierala aiop->aio_nbytes = sectorsize;
595b76ce452SEdward Tomasz Napierala
596b76ce452SEdward Tomasz Napierala error = aio_read(aiop);
597b76ce452SEdward Tomasz Napierala if (error != 0)
598b76ce452SEdward Tomasz Napierala err(1, "aio_read");
599b76ce452SEdward Tomasz Napierala }
600b76ce452SEdward Tomasz Napierala
601b76ce452SEdward Tomasz Napierala queued = i;
602b76ce452SEdward Tomasz Napierala completed = 0;
603b76ce452SEdward Tomasz Napierala
604b76ce452SEdward Tomasz Napierala for (;;) {
605b76ce452SEdward Tomasz Napierala ret = aio_waitcomplete(&aiop, NULL);
606b76ce452SEdward Tomasz Napierala if (ret < 0)
607b76ce452SEdward Tomasz Napierala err(1, "aio_waitcomplete");
608b76ce452SEdward Tomasz Napierala if (ret != (ssize_t)sectorsize)
609b76ce452SEdward Tomasz Napierala errx(1, "short read");
610b76ce452SEdward Tomasz Napierala
611b76ce452SEdward Tomasz Napierala completed++;
612b76ce452SEdward Tomasz Napierala
613b76ce452SEdward Tomasz Napierala if (delta_t() < 3.0) {
614b76ce452SEdward Tomasz Napierala aiop->aio_fildes = fd;
615b76ce452SEdward Tomasz Napierala aiop->aio_offset = (random() % (sectorcount)) * sectorsize;
616b76ce452SEdward Tomasz Napierala aiop->aio_nbytes = sectorsize;
617b76ce452SEdward Tomasz Napierala
618b76ce452SEdward Tomasz Napierala error = aio_read(aiop);
619b76ce452SEdward Tomasz Napierala if (error != 0)
620b76ce452SEdward Tomasz Napierala err(1, "aio_read");
621b76ce452SEdward Tomasz Napierala
622b76ce452SEdward Tomasz Napierala queued++;
623b76ce452SEdward Tomasz Napierala } else if (completed == queued) {
624b76ce452SEdward Tomasz Napierala break;
625b76ce452SEdward Tomasz Napierala }
626b76ce452SEdward Tomasz Napierala }
627b76ce452SEdward Tomasz Napierala
628b76ce452SEdward Tomasz Napierala TI(completed);
629b76ce452SEdward Tomasz Napierala }
630b76ce452SEdward Tomasz Napierala
631b76ce452SEdward Tomasz Napierala static void
iopsbench(int fd,off_t mediasize,u_int sectorsize)632b76ce452SEdward Tomasz Napierala iopsbench(int fd, off_t mediasize, u_int sectorsize)
633b76ce452SEdward Tomasz Napierala {
634b76ce452SEdward Tomasz Napierala printf("Asynchronous random reads:\n");
635b76ce452SEdward Tomasz Napierala
636b76ce452SEdward Tomasz Napierala printf("\tsectorsize: ");
637b76ce452SEdward Tomasz Napierala iops(fd, mediasize, sectorsize);
638b76ce452SEdward Tomasz Napierala
639b76ce452SEdward Tomasz Napierala if (sectorsize != 4096) {
640b76ce452SEdward Tomasz Napierala printf("\t4 kbytes: ");
641b76ce452SEdward Tomasz Napierala iops(fd, mediasize, 4096);
642b76ce452SEdward Tomasz Napierala }
643b76ce452SEdward Tomasz Napierala
644b76ce452SEdward Tomasz Napierala printf("\t32 kbytes: ");
645b76ce452SEdward Tomasz Napierala iops(fd, mediasize, 32 * 1024);
646b76ce452SEdward Tomasz Napierala
647b76ce452SEdward Tomasz Napierala printf("\t128 kbytes: ");
648b76ce452SEdward Tomasz Napierala iops(fd, mediasize, 128 * 1024);
649b76ce452SEdward Tomasz Napierala
650b7a4380dSEdward Tomasz Napierala printf("\t1024 kbytes: ");
651b7a4380dSEdward Tomasz Napierala iops(fd, mediasize, 1024 * 1024);
652b7a4380dSEdward Tomasz Napierala
653b76ce452SEdward Tomasz Napierala printf("\n");
654b76ce452SEdward Tomasz Napierala }
655b76ce452SEdward Tomasz Napierala
6561a01f934SAlexander Motin #define MAXIO (128*1024)
6571a01f934SAlexander Motin #define MAXIOS (MAXTX / MAXIO)
6581a01f934SAlexander Motin
6591a01f934SAlexander Motin static void
parwrite(int fd,size_t size,off_t off)6601a01f934SAlexander Motin parwrite(int fd, size_t size, off_t off)
6611a01f934SAlexander Motin {
6621a01f934SAlexander Motin struct aiocb aios[MAXIOS];
6631a01f934SAlexander Motin off_t o;
6641a01f934SAlexander Motin int n, error;
6651a01f934SAlexander Motin struct aiocb *aiop;
6661a01f934SAlexander Motin
66718e980c0SAlan Somers // if size > MAXIO, use AIO to write n - 1 pieces in parallel
66818e980c0SAlan Somers for (n = 0, o = 0; size > MAXIO; n++, size -= MAXIO, o += MAXIO) {
6691a01f934SAlexander Motin aiop = &aios[n];
6701a01f934SAlexander Motin bzero(aiop, sizeof(*aiop));
6711a01f934SAlexander Motin aiop->aio_buf = &buf[o];
6721a01f934SAlexander Motin aiop->aio_fildes = fd;
6731a01f934SAlexander Motin aiop->aio_offset = off + o;
67418e980c0SAlan Somers aiop->aio_nbytes = MAXIO;
6751a01f934SAlexander Motin error = aio_write(aiop);
6761a01f934SAlexander Motin if (error != 0)
6771a01f934SAlexander Motin err(EX_IOERR, "AIO write submit error");
6781a01f934SAlexander Motin }
67918e980c0SAlan Somers // Use synchronous writes for the runt of size <= MAXIO
6801a01f934SAlexander Motin error = pwrite(fd, &buf[o], size, off + o);
6811a01f934SAlexander Motin if (error < 0)
6821a01f934SAlexander Motin err(EX_IOERR, "Sync write error");
6831a01f934SAlexander Motin for (; n > 0; n--) {
6841a01f934SAlexander Motin error = aio_waitcomplete(&aiop, NULL);
6851a01f934SAlexander Motin if (error < 0)
6861a01f934SAlexander Motin err(EX_IOERR, "AIO write wait error");
6871a01f934SAlexander Motin }
6881a01f934SAlexander Motin }
6891a01f934SAlexander Motin
6901a01f934SAlexander Motin static void
slogbench(int fd,int isreg,off_t mediasize,u_int sectorsize)6911a01f934SAlexander Motin slogbench(int fd, int isreg, off_t mediasize, u_int sectorsize)
6921a01f934SAlexander Motin {
6931a01f934SAlexander Motin off_t off;
6941a01f934SAlexander Motin u_int size;
69575b2ed47SAlexander Motin int error, n, N, nowritecache = 0;
6961a01f934SAlexander Motin
6971a01f934SAlexander Motin printf("Synchronous random writes:\n");
6981a01f934SAlexander Motin for (size = sectorsize; size <= MAXTX; size *= 2) {
6991a01f934SAlexander Motin printf("\t%4.4g kbytes: ", (double)size / 1024);
7001a01f934SAlexander Motin N = 0;
7011a01f934SAlexander Motin T0();
7021a01f934SAlexander Motin do {
7031a01f934SAlexander Motin for (n = 0; n < 250; n++) {
7041a01f934SAlexander Motin off = random() % (mediasize / size);
7051a01f934SAlexander Motin parwrite(fd, size, off * size);
70675b2ed47SAlexander Motin if (nowritecache)
70775b2ed47SAlexander Motin continue;
7081a01f934SAlexander Motin if (isreg)
7091a01f934SAlexander Motin error = fsync(fd);
7101a01f934SAlexander Motin else
7111a01f934SAlexander Motin error = ioctl(fd, DIOCGFLUSH);
71275b2ed47SAlexander Motin if (error < 0) {
71375b2ed47SAlexander Motin if (errno == ENOTSUP)
71475b2ed47SAlexander Motin nowritecache = 1;
71575b2ed47SAlexander Motin else
7161a01f934SAlexander Motin err(EX_IOERR, "Flush error");
7171a01f934SAlexander Motin }
71875b2ed47SAlexander Motin }
7191a01f934SAlexander Motin N += 250;
7201a01f934SAlexander Motin } while (delta_t() < 1.0);
7211a01f934SAlexander Motin TS(size, N);
7221a01f934SAlexander Motin }
7231a01f934SAlexander Motin }
7241a01f934SAlexander Motin
7259a6844d5SKenneth D. Merry static int
zonecheck(int fd,uint32_t * zone_mode,char * zone_str,size_t zone_str_len)7269a6844d5SKenneth D. Merry zonecheck(int fd, uint32_t *zone_mode, char *zone_str, size_t zone_str_len)
7279a6844d5SKenneth D. Merry {
7289a6844d5SKenneth D. Merry struct disk_zone_args zone_args;
7299a6844d5SKenneth D. Merry int error;
7309a6844d5SKenneth D. Merry
7319a6844d5SKenneth D. Merry bzero(&zone_args, sizeof(zone_args));
7329a6844d5SKenneth D. Merry
7339a6844d5SKenneth D. Merry zone_args.zone_cmd = DISK_ZONE_GET_PARAMS;
7349a6844d5SKenneth D. Merry error = ioctl(fd, DIOCZONECMD, &zone_args);
7359a6844d5SKenneth D. Merry
7369a6844d5SKenneth D. Merry if (error == 0) {
7379a6844d5SKenneth D. Merry *zone_mode = zone_args.zone_params.disk_params.zone_mode;
7389a6844d5SKenneth D. Merry
7399a6844d5SKenneth D. Merry switch (*zone_mode) {
7409a6844d5SKenneth D. Merry case DISK_ZONE_MODE_NONE:
7419a6844d5SKenneth D. Merry snprintf(zone_str, zone_str_len, "Not_Zoned");
7429a6844d5SKenneth D. Merry break;
7439a6844d5SKenneth D. Merry case DISK_ZONE_MODE_HOST_AWARE:
7449a6844d5SKenneth D. Merry snprintf(zone_str, zone_str_len, "Host_Aware");
7459a6844d5SKenneth D. Merry break;
7469a6844d5SKenneth D. Merry case DISK_ZONE_MODE_DRIVE_MANAGED:
7479a6844d5SKenneth D. Merry snprintf(zone_str, zone_str_len, "Drive_Managed");
7489a6844d5SKenneth D. Merry break;
7499a6844d5SKenneth D. Merry case DISK_ZONE_MODE_HOST_MANAGED:
7509a6844d5SKenneth D. Merry snprintf(zone_str, zone_str_len, "Host_Managed");
7519a6844d5SKenneth D. Merry break;
7529a6844d5SKenneth D. Merry default:
7539a6844d5SKenneth D. Merry snprintf(zone_str, zone_str_len, "Unknown_zone_mode_%u",
7549a6844d5SKenneth D. Merry *zone_mode);
7559a6844d5SKenneth D. Merry break;
7569a6844d5SKenneth D. Merry }
7579a6844d5SKenneth D. Merry }
7589a6844d5SKenneth D. Merry return (error);
7599a6844d5SKenneth D. Merry }
760