xref: /freebsd/sbin/mdconfig/mdconfig.c (revision 7e06d7bcbc39518d9984a07ab19116a9f050a176)
170d586c0SPoul-Henning Kamp /*
270d586c0SPoul-Henning Kamp  * ----------------------------------------------------------------------------
370d586c0SPoul-Henning Kamp  * "THE BEER-WARE LICENSE" (Revision 42):
470d586c0SPoul-Henning Kamp  * <phk@FreeBSD.ORG> wrote this file.  As long as you retain this notice you
570d586c0SPoul-Henning Kamp  * can do whatever you want with this stuff. If we meet some day, and you think
670d586c0SPoul-Henning Kamp  * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
770d586c0SPoul-Henning Kamp  * ----------------------------------------------------------------------------
870d586c0SPoul-Henning Kamp  *
970d586c0SPoul-Henning Kamp  * $FreeBSD$
1070d586c0SPoul-Henning Kamp  *
1170d586c0SPoul-Henning Kamp  */
1270d586c0SPoul-Henning Kamp 
1370d586c0SPoul-Henning Kamp #include <stdio.h>
1470d586c0SPoul-Henning Kamp #include <stdlib.h>
15c313f09bSChristian S.J. Peron #include <errno.h>
1670d586c0SPoul-Henning Kamp #include <fcntl.h>
1770d586c0SPoul-Henning Kamp #include <unistd.h>
18b830359bSPawel Jakub Dawidek #include <inttypes.h>
19b830359bSPawel Jakub Dawidek #include <libutil.h>
2070d586c0SPoul-Henning Kamp #include <string.h>
2170d586c0SPoul-Henning Kamp #include <err.h>
227e06d7bcSDima Dorfman #include <assert.h>
23b830359bSPawel Jakub Dawidek 
2470d586c0SPoul-Henning Kamp #include <sys/ioctl.h>
2570d586c0SPoul-Henning Kamp #include <sys/param.h>
2657e9624eSPoul-Henning Kamp #include <sys/module.h>
2757e9624eSPoul-Henning Kamp #include <sys/linker.h>
2870d586c0SPoul-Henning Kamp #include <sys/mdioctl.h>
29b830359bSPawel Jakub Dawidek #include <sys/stat.h>
30174b5e9aSPoul-Henning Kamp 
31174b5e9aSPoul-Henning Kamp int	 list(const int);
323fa96e66SDima Dorfman void	 mdmaybeload(void);
33174b5e9aSPoul-Henning Kamp int	 query(const int, const int);
343fa96e66SDima Dorfman void	 usage(void);
3570d586c0SPoul-Henning Kamp 
3670d586c0SPoul-Henning Kamp struct md_ioctl mdio;
3770d586c0SPoul-Henning Kamp 
38174b5e9aSPoul-Henning Kamp enum {UNSET, ATTACH, DETACH, LIST} action = UNSET;
3970d586c0SPoul-Henning Kamp 
40f79c46d3SRobert Watson int nflag;
41f79c46d3SRobert Watson 
42c2ef0b73SPoul-Henning Kamp void
43c2ef0b73SPoul-Henning Kamp usage()
44c2ef0b73SPoul-Henning Kamp {
4578bb1162SRuslan Ermilov 	fprintf(stderr,
4678bb1162SRuslan Ermilov "usage: mdconfig -a -t type [-n] [-o [no]option] ... [-f file]\n"
4778bb1162SRuslan Ermilov "                [-s size] [-S sectorsize] [-u unit]\n"
4878bb1162SRuslan Ermilov "                [-x sectors/track] [-y heads/cyl]\n"
4978bb1162SRuslan Ermilov "       mdconfig -d -u unit\n"
5078bb1162SRuslan Ermilov "       mdconfig -l [-n] [-u unit]\n");
51c2ef0b73SPoul-Henning Kamp 	fprintf(stderr, "\t\ttype = {malloc, preload, vnode, swap}\n");
523f6f9216SPoul-Henning Kamp 	fprintf(stderr, "\t\toption = {cluster, compress, reserve}\n");
535d19b2f9SPawel Jakub Dawidek 	fprintf(stderr, "\t\tsize = %%d (512 byte blocks), %%db (B),\n");
545d19b2f9SPawel Jakub Dawidek 	fprintf(stderr, "\t\t       %%dk (kB), %%dm (MB), %%dg (GB) or\n");
555d19b2f9SPawel Jakub Dawidek 	fprintf(stderr, "\t\t       %%dt (TB)\n");
56c2ef0b73SPoul-Henning Kamp 	exit(1);
57c2ef0b73SPoul-Henning Kamp }
58c2ef0b73SPoul-Henning Kamp 
5970d586c0SPoul-Henning Kamp int
6070d586c0SPoul-Henning Kamp main(int argc, char **argv)
6170d586c0SPoul-Henning Kamp {
6270d586c0SPoul-Henning Kamp 	int ch, fd, i;
63c2ef0b73SPoul-Henning Kamp 	char *p;
64c2ef0b73SPoul-Henning Kamp 	int cmdline = 0;
6570d586c0SPoul-Henning Kamp 
66b830359bSPawel Jakub Dawidek 	bzero(&mdio, sizeof(mdio));
6788b5b78dSPawel Jakub Dawidek 	mdio.md_file = malloc(PATH_MAX);
6888b5b78dSPawel Jakub Dawidek 	if (mdio.md_file == NULL)
6988b5b78dSPawel Jakub Dawidek 		err(1, "could not allocate memory");
7088b5b78dSPawel Jakub Dawidek 	bzero(mdio.md_file, PATH_MAX);
7170d586c0SPoul-Henning Kamp 	for (;;) {
72f79c46d3SRobert Watson 		ch = getopt(argc, argv, "ab:df:lno:s:S:t:u:x:y:");
7370d586c0SPoul-Henning Kamp 		if (ch == -1)
7470d586c0SPoul-Henning Kamp 			break;
7570d586c0SPoul-Henning Kamp 		switch (ch) {
7670d586c0SPoul-Henning Kamp 		case 'a':
77c2ef0b73SPoul-Henning Kamp 			if (cmdline != 0)
78c2ef0b73SPoul-Henning Kamp 				usage();
7970d586c0SPoul-Henning Kamp 			action = ATTACH;
80c2ef0b73SPoul-Henning Kamp 			cmdline = 1;
8170d586c0SPoul-Henning Kamp 			break;
8270d586c0SPoul-Henning Kamp 		case 'd':
83c2ef0b73SPoul-Henning Kamp 			if (cmdline != 0)
84c2ef0b73SPoul-Henning Kamp 				usage();
8570d586c0SPoul-Henning Kamp 			action = DETACH;
868f8def9eSPoul-Henning Kamp 			mdio.md_options = MD_AUTOUNIT;
878f8def9eSPoul-Henning Kamp 			cmdline = 3;
88c2ef0b73SPoul-Henning Kamp 			break;
89174b5e9aSPoul-Henning Kamp 		case 'l':
90174b5e9aSPoul-Henning Kamp 			if (cmdline != 0)
91174b5e9aSPoul-Henning Kamp 				usage();
92174b5e9aSPoul-Henning Kamp 			action = LIST;
93174b5e9aSPoul-Henning Kamp 			mdio.md_options = MD_AUTOUNIT;
94174b5e9aSPoul-Henning Kamp 			cmdline = 3;
95174b5e9aSPoul-Henning Kamp 			break;
96f79c46d3SRobert Watson 		case 'n':
97f79c46d3SRobert Watson 			nflag = 1;
98f79c46d3SRobert Watson 			break;
99c2ef0b73SPoul-Henning Kamp 		case 't':
100c2ef0b73SPoul-Henning Kamp 			if (cmdline != 1)
101c2ef0b73SPoul-Henning Kamp 				usage();
102c2ef0b73SPoul-Henning Kamp 			if (!strcmp(optarg, "malloc")) {
103c2ef0b73SPoul-Henning Kamp 				mdio.md_type = MD_MALLOC;
104c2ef0b73SPoul-Henning Kamp 				mdio.md_options = MD_AUTOUNIT | MD_COMPRESS;
105c2ef0b73SPoul-Henning Kamp 			} else if (!strcmp(optarg, "preload")) {
106c2ef0b73SPoul-Henning Kamp 				mdio.md_type = MD_PRELOAD;
107c2ef0b73SPoul-Henning Kamp 				mdio.md_options = 0;
108c2ef0b73SPoul-Henning Kamp 			} else if (!strcmp(optarg, "vnode")) {
109c2ef0b73SPoul-Henning Kamp 				mdio.md_type = MD_VNODE;
110c2ef0b73SPoul-Henning Kamp 				mdio.md_options = MD_CLUSTER | MD_AUTOUNIT | MD_COMPRESS;
111c2ef0b73SPoul-Henning Kamp 			} else if (!strcmp(optarg, "swap")) {
112c2ef0b73SPoul-Henning Kamp 				mdio.md_type = MD_SWAP;
113c2ef0b73SPoul-Henning Kamp 				mdio.md_options = MD_CLUSTER | MD_AUTOUNIT | MD_COMPRESS;
114c2ef0b73SPoul-Henning Kamp 			} else {
115c2ef0b73SPoul-Henning Kamp 				usage();
116c2ef0b73SPoul-Henning Kamp 			}
117c2ef0b73SPoul-Henning Kamp 			cmdline=2;
11870d586c0SPoul-Henning Kamp 			break;
11970d586c0SPoul-Henning Kamp 		case 'f':
120ed23a390SMaxim Sobolev 			if (cmdline != 1 && cmdline != 2)
121c2ef0b73SPoul-Henning Kamp 				usage();
122ed23a390SMaxim Sobolev 			if (cmdline == 1) {
123ed23a390SMaxim Sobolev 				/* Imply ``-t vnode'' */
124ed23a390SMaxim Sobolev 				mdio.md_type = MD_VNODE;
125ed23a390SMaxim Sobolev 				mdio.md_options = MD_CLUSTER | MD_AUTOUNIT | MD_COMPRESS;
126252bcf45SYaroslav Tykhiy 				cmdline = 2;
127ed23a390SMaxim Sobolev 			}
12861a6eb62SPawel Jakub Dawidek 			if (realpath(optarg, mdio.md_file) == NULL) {
12961a6eb62SPawel Jakub Dawidek 				err(1, "could not find full path for %s",
13061a6eb62SPawel Jakub Dawidek 				    optarg);
13161a6eb62SPawel Jakub Dawidek 			}
13261a6eb62SPawel Jakub Dawidek 			fd = open(mdio.md_file, O_RDONLY);
133e869d377SPoul-Henning Kamp 			if (fd < 0)
134e869d377SPoul-Henning Kamp 				err(1, "could not open %s", optarg);
135b830359bSPawel Jakub Dawidek 			else if (mdio.md_mediasize == 0) {
136b830359bSPawel Jakub Dawidek 				struct stat sb;
137b830359bSPawel Jakub Dawidek 
138b830359bSPawel Jakub Dawidek 				if (fstat(fd, &sb) == -1)
139b830359bSPawel Jakub Dawidek 					err(1, "could not stat %s", optarg);
140b830359bSPawel Jakub Dawidek 				mdio.md_mediasize = sb.st_size;
141b830359bSPawel Jakub Dawidek 			}
142e869d377SPoul-Henning Kamp 			close(fd);
14370d586c0SPoul-Henning Kamp 			break;
14470d586c0SPoul-Henning Kamp 		case 'o':
145c2ef0b73SPoul-Henning Kamp 			if (cmdline != 2)
146c2ef0b73SPoul-Henning Kamp 				usage();
1477a6b2b64SPoul-Henning Kamp 			if (!strcmp(optarg, "async"))
1487a6b2b64SPoul-Henning Kamp 				mdio.md_options |= MD_ASYNC;
1497a6b2b64SPoul-Henning Kamp 			else if (!strcmp(optarg, "noasync"))
1507a6b2b64SPoul-Henning Kamp 				mdio.md_options &= ~MD_ASYNC;
1517a6b2b64SPoul-Henning Kamp 			else if (!strcmp(optarg, "cluster"))
15270d586c0SPoul-Henning Kamp 				mdio.md_options |= MD_CLUSTER;
15370d586c0SPoul-Henning Kamp 			else if (!strcmp(optarg, "nocluster"))
15470d586c0SPoul-Henning Kamp 				mdio.md_options &= ~MD_CLUSTER;
155c2ef0b73SPoul-Henning Kamp 			else if (!strcmp(optarg, "compress"))
156c2ef0b73SPoul-Henning Kamp 				mdio.md_options |= MD_COMPRESS;
157c2ef0b73SPoul-Henning Kamp 			else if (!strcmp(optarg, "nocompress"))
158c2ef0b73SPoul-Henning Kamp 				mdio.md_options &= ~MD_COMPRESS;
15926a0ee75SDima Dorfman 			else if (!strcmp(optarg, "force"))
16026a0ee75SDima Dorfman 				mdio.md_options |= MD_FORCE;
16126a0ee75SDima Dorfman 			else if (!strcmp(optarg, "noforce"))
16226a0ee75SDima Dorfman 				mdio.md_options &= ~MD_FORCE;
163d31ba625SJohn-Mark Gurney 			else if (!strcmp(optarg, "readonly"))
164d31ba625SJohn-Mark Gurney 				mdio.md_options |= MD_READONLY;
165d31ba625SJohn-Mark Gurney 			else if (!strcmp(optarg, "noreadonly"))
166d31ba625SJohn-Mark Gurney 				mdio.md_options &= ~MD_READONLY;
16770d586c0SPoul-Henning Kamp 			else if (!strcmp(optarg, "reserve"))
16870d586c0SPoul-Henning Kamp 				mdio.md_options |= MD_RESERVE;
16970d586c0SPoul-Henning Kamp 			else if (!strcmp(optarg, "noreserve"))
17070d586c0SPoul-Henning Kamp 				mdio.md_options &= ~MD_RESERVE;
17170d586c0SPoul-Henning Kamp 			else
172d31ba625SJohn-Mark Gurney 				errx(1, "Unknown option: %s.", optarg);
17370d586c0SPoul-Henning Kamp 			break;
174ebe789d6SPoul-Henning Kamp 		case 'S':
175ebe789d6SPoul-Henning Kamp 			if (cmdline != 2)
176ebe789d6SPoul-Henning Kamp 				usage();
177b830359bSPawel Jakub Dawidek 			mdio.md_sectorsize = strtoul(optarg, &p, 0);
178ebe789d6SPoul-Henning Kamp 			break;
17970d586c0SPoul-Henning Kamp 		case 's':
180c2ef0b73SPoul-Henning Kamp 			if (cmdline != 2)
181c2ef0b73SPoul-Henning Kamp 				usage();
182b830359bSPawel Jakub Dawidek 			mdio.md_mediasize = (off_t)strtoumax(optarg, &p, 0);
183c2ef0b73SPoul-Henning Kamp 			if (p == NULL || *p == '\0')
184b830359bSPawel Jakub Dawidek 				mdio.md_mediasize *= DEV_BSIZE;
1850d79319aSPawel Jakub Dawidek 			else if (*p == 'b' || *p == 'B')
1860d79319aSPawel Jakub Dawidek 				; /* do nothing */
187c2ef0b73SPoul-Henning Kamp 			else if (*p == 'k' || *p == 'K')
188b830359bSPawel Jakub Dawidek 				mdio.md_mediasize <<= 10;
189c2ef0b73SPoul-Henning Kamp 			else if (*p == 'm' || *p == 'M')
190b830359bSPawel Jakub Dawidek 				mdio.md_mediasize <<= 20;
191c2ef0b73SPoul-Henning Kamp 			else if (*p == 'g' || *p == 'G')
192b830359bSPawel Jakub Dawidek 				mdio.md_mediasize <<= 30;
193b830359bSPawel Jakub Dawidek 			else if (*p == 't' || *p == 'T') {
194b830359bSPawel Jakub Dawidek 				mdio.md_mediasize <<= 30;
195b830359bSPawel Jakub Dawidek 				mdio.md_mediasize <<= 10;
196b830359bSPawel Jakub Dawidek 			} else
197c2ef0b73SPoul-Henning Kamp 				errx(1, "Unknown suffix on -s argument");
19870d586c0SPoul-Henning Kamp 			break;
19970d586c0SPoul-Henning Kamp 		case 'u':
2008f8def9eSPoul-Henning Kamp 			if (cmdline != 2 && cmdline != 3)
201c2ef0b73SPoul-Henning Kamp 				usage();
202fb1023d6SPoul-Henning Kamp 			if (!strncmp(optarg, "/dev/", 5))
203fb1023d6SPoul-Henning Kamp 				optarg += 5;
204174b5e9aSPoul-Henning Kamp 			if (!strncmp(optarg, MD_NAME, sizeof(MD_NAME) - 1))
20578baea25SDima Dorfman 				optarg += sizeof(MD_NAME) - 1;
2062885b421SDima Dorfman 			mdio.md_unit = strtoul(optarg, &p, 0);
2078a50130bSAlexander Kabaev 			if (mdio.md_unit == (unsigned)ULONG_MAX || *p != '\0')
2082885b421SDima Dorfman 				errx(1, "bad unit: %s", optarg);
20970d586c0SPoul-Henning Kamp 			mdio.md_options &= ~MD_AUTOUNIT;
21070d586c0SPoul-Henning Kamp 			break;
2114e8bfe14SPoul-Henning Kamp 		case 'x':
2124e8bfe14SPoul-Henning Kamp 			if (cmdline != 2)
2134e8bfe14SPoul-Henning Kamp 				usage();
2144e8bfe14SPoul-Henning Kamp 			mdio.md_fwsectors = strtoul(optarg, &p, 0);
2154e8bfe14SPoul-Henning Kamp 			break;
2164e8bfe14SPoul-Henning Kamp 		case 'y':
2174e8bfe14SPoul-Henning Kamp 			if (cmdline != 2)
2184e8bfe14SPoul-Henning Kamp 				usage();
2194e8bfe14SPoul-Henning Kamp 			mdio.md_fwheads = strtoul(optarg, &p, 0);
2204e8bfe14SPoul-Henning Kamp 			break;
22170d586c0SPoul-Henning Kamp 		default:
222c2ef0b73SPoul-Henning Kamp 			usage();
22370d586c0SPoul-Henning Kamp 		}
22470d586c0SPoul-Henning Kamp 	}
22553d745bcSDima Dorfman 	mdio.md_version = MDIOVERSION;
22670d586c0SPoul-Henning Kamp 
22757e9624eSPoul-Henning Kamp 	mdmaybeload();
228174b5e9aSPoul-Henning Kamp 	fd = open("/dev/" MDCTL_NAME, O_RDWR, 0);
22970d586c0SPoul-Henning Kamp 	if (fd < 0)
230174b5e9aSPoul-Henning Kamp 		err(1, "open(/dev/%s)", MDCTL_NAME);
2312885b421SDima Dorfman 	if (cmdline == 2
2322885b421SDima Dorfman 	    && (mdio.md_type == MD_MALLOC || mdio.md_type == MD_SWAP))
233b830359bSPawel Jakub Dawidek 		if (mdio.md_mediasize == 0)
2342885b421SDima Dorfman 			errx(1, "must specify -s for -t malloc or -t swap");
235252bcf45SYaroslav Tykhiy 	if (cmdline == 2 && mdio.md_type == MD_VNODE)
23688b5b78dSPawel Jakub Dawidek 		if (mdio.md_file[0] == '\0')
237252bcf45SYaroslav Tykhiy 			errx(1, "must specify -f for -t vnode");
238c313f09bSChristian S.J. Peron 	if (mdio.md_type == MD_VNODE &&
239c313f09bSChristian S.J. Peron 	    (mdio.md_options & MD_READONLY) == 0) {
240c313f09bSChristian S.J. Peron 		if (access(mdio.md_file, W_OK) < 0 &&
241c313f09bSChristian S.J. Peron 		    (errno == EACCES || errno == EPERM || errno == EROFS)) {
242c313f09bSChristian S.J. Peron 			fprintf(stderr,
243c313f09bSChristian S.J. Peron 			    "WARNING: opening backing store: %s readonly\n",
244c313f09bSChristian S.J. Peron 			    mdio.md_file);
245c313f09bSChristian S.J. Peron 			mdio.md_options |= MD_READONLY;
246c313f09bSChristian S.J. Peron 		}
247c313f09bSChristian S.J. Peron 	}
248174b5e9aSPoul-Henning Kamp 	if (action == LIST) {
249174b5e9aSPoul-Henning Kamp 		if (mdio.md_options & MD_AUTOUNIT)
250174b5e9aSPoul-Henning Kamp 			list(fd);
251174b5e9aSPoul-Henning Kamp 		else
252174b5e9aSPoul-Henning Kamp 			query(fd, mdio.md_unit);
253174b5e9aSPoul-Henning Kamp 	} else if (action == ATTACH) {
254252bcf45SYaroslav Tykhiy 		if (cmdline < 2)
255252bcf45SYaroslav Tykhiy 			usage();
25670d586c0SPoul-Henning Kamp 		i = ioctl(fd, MDIOCATTACH, &mdio);
257174b5e9aSPoul-Henning Kamp 		if (i < 0)
258174b5e9aSPoul-Henning Kamp 			err(1, "ioctl(/dev/%s)", MDCTL_NAME);
25983da2a90SPoul-Henning Kamp 		if (mdio.md_options & MD_AUTOUNIT)
260f79c46d3SRobert Watson 			printf("%s%d\n", nflag ? "" : MD_NAME, mdio.md_unit);
26183da2a90SPoul-Henning Kamp 	} else if (action == DETACH) {
2628f8def9eSPoul-Henning Kamp 		if (mdio.md_options & MD_AUTOUNIT)
2638f8def9eSPoul-Henning Kamp 			usage();
264c2ef0b73SPoul-Henning Kamp 		i = ioctl(fd, MDIOCDETACH, &mdio);
26570d586c0SPoul-Henning Kamp 		if (i < 0)
266174b5e9aSPoul-Henning Kamp 			err(1, "ioctl(/dev/%s)", MDCTL_NAME);
26783da2a90SPoul-Henning Kamp 	} else
26883da2a90SPoul-Henning Kamp 		usage();
269174b5e9aSPoul-Henning Kamp 	close (fd);
270174b5e9aSPoul-Henning Kamp 	return (0);
271174b5e9aSPoul-Henning Kamp }
272174b5e9aSPoul-Henning Kamp 
2737e06d7bcSDima Dorfman static int
2747e06d7bcSDima Dorfman mdunitcmp(const void *a, const void *b)
2757e06d7bcSDima Dorfman {
2767e06d7bcSDima Dorfman 	return (*(int *)a - *(int *)b);
2777e06d7bcSDima Dorfman }
2787e06d7bcSDima Dorfman 
279174b5e9aSPoul-Henning Kamp int
280174b5e9aSPoul-Henning Kamp list(const int fd)
281174b5e9aSPoul-Henning Kamp {
282c894b25aSDima Dorfman 	int unit;
2837e06d7bcSDima Dorfman 	int mdcount;
284174b5e9aSPoul-Henning Kamp 
285e39eff98SPoul-Henning Kamp 	if (ioctl(fd, MDIOCLIST, &mdio) < 0)
286e39eff98SPoul-Henning Kamp 		err(1, "ioctl(/dev/%s)", MDCTL_NAME);
2877e06d7bcSDima Dorfman 	mdcount = mdio.md_pad[0];
2887e06d7bcSDima Dorfman 	assert(mdcount < MDNPAD - 1);
2897e06d7bcSDima Dorfman 	if (mdcount > 0)
2907e06d7bcSDima Dorfman 		qsort(&mdio.md_pad[1], mdcount, sizeof(mdio.md_pad[0]), mdunitcmp);
2917e06d7bcSDima Dorfman 	for (unit = 0; unit < mdcount; unit++) {
292f79c46d3SRobert Watson 		printf("%s%s%d", unit > 0 ? " " : "",
293f79c46d3SRobert Watson 		    nflag ? "" : MD_NAME, mdio.md_pad[unit + 1]);
294174b5e9aSPoul-Henning Kamp 	}
2959a777b93SDima Dorfman 	if (unit > 0)
296e39eff98SPoul-Henning Kamp 		printf("\n");
297174b5e9aSPoul-Henning Kamp 	return (0);
298174b5e9aSPoul-Henning Kamp }
299174b5e9aSPoul-Henning Kamp 
300b830359bSPawel Jakub Dawidek static void
301b830359bSPawel Jakub Dawidek prthumanval(int64_t bytes)
302b830359bSPawel Jakub Dawidek {
303b830359bSPawel Jakub Dawidek 	char buf[6];
304b830359bSPawel Jakub Dawidek 
305b830359bSPawel Jakub Dawidek 	humanize_number(buf, sizeof(buf) - (bytes < 0 ? 0 : 1),
306b830359bSPawel Jakub Dawidek 	    bytes, "", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
307b830359bSPawel Jakub Dawidek 	(void)printf("%6s", buf);
308b830359bSPawel Jakub Dawidek }
309b830359bSPawel Jakub Dawidek 
310174b5e9aSPoul-Henning Kamp int
311174b5e9aSPoul-Henning Kamp query(const int fd, const int unit)
312174b5e9aSPoul-Henning Kamp {
313174b5e9aSPoul-Henning Kamp 
31453d745bcSDima Dorfman 	mdio.md_version = MDIOVERSION;
315174b5e9aSPoul-Henning Kamp 	mdio.md_unit = unit;
316174b5e9aSPoul-Henning Kamp 
317174b5e9aSPoul-Henning Kamp 	if (ioctl(fd, MDIOCQUERY, &mdio) < 0)
318174b5e9aSPoul-Henning Kamp 		err(1, "ioctl(/dev/%s)", MDCTL_NAME);
319174b5e9aSPoul-Henning Kamp 
320b830359bSPawel Jakub Dawidek 	(void)printf("%s%d\t", MD_NAME, mdio.md_unit);
321174b5e9aSPoul-Henning Kamp 	switch (mdio.md_type) {
322174b5e9aSPoul-Henning Kamp 	case MD_MALLOC:
323b830359bSPawel Jakub Dawidek 		(void)printf("malloc");
324174b5e9aSPoul-Henning Kamp 		break;
325174b5e9aSPoul-Henning Kamp 	case MD_PRELOAD:
326b830359bSPawel Jakub Dawidek 		(void)printf("preload");
327174b5e9aSPoul-Henning Kamp 		break;
328174b5e9aSPoul-Henning Kamp 	case MD_SWAP:
329b830359bSPawel Jakub Dawidek 		(void)printf("swap");
330174b5e9aSPoul-Henning Kamp 		break;
331174b5e9aSPoul-Henning Kamp 	case MD_VNODE:
332b830359bSPawel Jakub Dawidek 		(void)printf("vnode");
333174b5e9aSPoul-Henning Kamp 		break;
334174b5e9aSPoul-Henning Kamp 	}
335b830359bSPawel Jakub Dawidek 	printf("\t");
336b830359bSPawel Jakub Dawidek 	prthumanval(mdio.md_mediasize);
33761a6eb62SPawel Jakub Dawidek 	if (mdio.md_type == MD_VNODE)
33861a6eb62SPawel Jakub Dawidek 		printf("\t%s", mdio.md_file);
339b830359bSPawel Jakub Dawidek 	printf("\n");
340174b5e9aSPoul-Henning Kamp 
34170d586c0SPoul-Henning Kamp 	return (0);
34270d586c0SPoul-Henning Kamp }
34370d586c0SPoul-Henning Kamp 
34457e9624eSPoul-Henning Kamp void
34557e9624eSPoul-Henning Kamp mdmaybeload(void)
34657e9624eSPoul-Henning Kamp {
347d9414258SPawel Jakub Dawidek 	char name1[64], name2[64];
34857e9624eSPoul-Henning Kamp 
349d9414258SPawel Jakub Dawidek 	snprintf(name1, sizeof(name1), "g_%s", MD_NAME);
350d9414258SPawel Jakub Dawidek 	snprintf(name2, sizeof(name2), "geom_%s", MD_NAME);
351d9414258SPawel Jakub Dawidek 	if (modfind(name1) == -1) {
352d9414258SPawel Jakub Dawidek 		/* Not present in kernel, try loading it. */
353d9414258SPawel Jakub Dawidek 		if (kldload(name2) == -1 || modfind(name1) == -1) {
354d9414258SPawel Jakub Dawidek 			if (errno != EEXIST) {
355d9414258SPawel Jakub Dawidek 				errx(EXIT_FAILURE,
356d9414258SPawel Jakub Dawidek 				    "%s module not available!", name2);
35757e9624eSPoul-Henning Kamp 			}
35857e9624eSPoul-Henning Kamp 		}
35957e9624eSPoul-Henning Kamp 	}
360d9414258SPawel Jakub Dawidek }
361