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> 1570d586c0SPoul-Henning Kamp #include <fcntl.h> 1670d586c0SPoul-Henning Kamp #include <unistd.h> 17b830359bSPawel Jakub Dawidek #include <inttypes.h> 18b830359bSPawel Jakub Dawidek #include <libutil.h> 1970d586c0SPoul-Henning Kamp #include <string.h> 2070d586c0SPoul-Henning Kamp #include <err.h> 21b830359bSPawel Jakub Dawidek 2270d586c0SPoul-Henning Kamp #include <sys/ioctl.h> 2370d586c0SPoul-Henning Kamp #include <sys/param.h> 2457e9624eSPoul-Henning Kamp #include <sys/module.h> 2557e9624eSPoul-Henning Kamp #include <sys/linker.h> 2670d586c0SPoul-Henning Kamp #include <sys/mdioctl.h> 27b830359bSPawel Jakub Dawidek #include <sys/stat.h> 28174b5e9aSPoul-Henning Kamp 29174b5e9aSPoul-Henning Kamp int list(const int); 303fa96e66SDima Dorfman void mdmaybeload(void); 31174b5e9aSPoul-Henning Kamp int query(const int, const int); 323fa96e66SDima Dorfman void usage(void); 3370d586c0SPoul-Henning Kamp 3470d586c0SPoul-Henning Kamp struct md_ioctl mdio; 3570d586c0SPoul-Henning Kamp 36174b5e9aSPoul-Henning Kamp enum {UNSET, ATTACH, DETACH, LIST} action = UNSET; 3770d586c0SPoul-Henning Kamp 38f79c46d3SRobert Watson int nflag; 39f79c46d3SRobert Watson 40c2ef0b73SPoul-Henning Kamp void 41c2ef0b73SPoul-Henning Kamp usage() 42c2ef0b73SPoul-Henning Kamp { 4378bb1162SRuslan Ermilov fprintf(stderr, 4478bb1162SRuslan Ermilov "usage: mdconfig -a -t type [-n] [-o [no]option] ... [-f file]\n" 4578bb1162SRuslan Ermilov " [-s size] [-S sectorsize] [-u unit]\n" 4678bb1162SRuslan Ermilov " [-x sectors/track] [-y heads/cyl]\n" 4778bb1162SRuslan Ermilov " mdconfig -d -u unit\n" 4878bb1162SRuslan Ermilov " mdconfig -l [-n] [-u unit]\n"); 49c2ef0b73SPoul-Henning Kamp fprintf(stderr, "\t\ttype = {malloc, preload, vnode, swap}\n"); 503f6f9216SPoul-Henning Kamp fprintf(stderr, "\t\toption = {cluster, compress, reserve}\n"); 515d19b2f9SPawel Jakub Dawidek fprintf(stderr, "\t\tsize = %%d (512 byte blocks), %%db (B),\n"); 525d19b2f9SPawel Jakub Dawidek fprintf(stderr, "\t\t %%dk (kB), %%dm (MB), %%dg (GB) or\n"); 535d19b2f9SPawel Jakub Dawidek fprintf(stderr, "\t\t %%dt (TB)\n"); 54c2ef0b73SPoul-Henning Kamp exit(1); 55c2ef0b73SPoul-Henning Kamp } 56c2ef0b73SPoul-Henning Kamp 5770d586c0SPoul-Henning Kamp int 5870d586c0SPoul-Henning Kamp main(int argc, char **argv) 5970d586c0SPoul-Henning Kamp { 6070d586c0SPoul-Henning Kamp int ch, fd, i; 61c2ef0b73SPoul-Henning Kamp char *p; 62c2ef0b73SPoul-Henning Kamp int cmdline = 0; 6370d586c0SPoul-Henning Kamp 64b830359bSPawel Jakub Dawidek bzero(&mdio, sizeof(mdio)); 6588b5b78dSPawel Jakub Dawidek mdio.md_file = malloc(PATH_MAX); 6688b5b78dSPawel Jakub Dawidek if (mdio.md_file == NULL) 6788b5b78dSPawel Jakub Dawidek err(1, "could not allocate memory"); 6888b5b78dSPawel Jakub Dawidek bzero(mdio.md_file, PATH_MAX); 6970d586c0SPoul-Henning Kamp for (;;) { 70f79c46d3SRobert Watson ch = getopt(argc, argv, "ab:df:lno:s:S:t:u:x:y:"); 7170d586c0SPoul-Henning Kamp if (ch == -1) 7270d586c0SPoul-Henning Kamp break; 7370d586c0SPoul-Henning Kamp switch (ch) { 7470d586c0SPoul-Henning Kamp case 'a': 75c2ef0b73SPoul-Henning Kamp if (cmdline != 0) 76c2ef0b73SPoul-Henning Kamp usage(); 7770d586c0SPoul-Henning Kamp action = ATTACH; 78c2ef0b73SPoul-Henning Kamp cmdline = 1; 7970d586c0SPoul-Henning Kamp break; 8070d586c0SPoul-Henning Kamp case 'd': 81c2ef0b73SPoul-Henning Kamp if (cmdline != 0) 82c2ef0b73SPoul-Henning Kamp usage(); 8370d586c0SPoul-Henning Kamp action = DETACH; 848f8def9eSPoul-Henning Kamp mdio.md_options = MD_AUTOUNIT; 858f8def9eSPoul-Henning Kamp cmdline = 3; 86c2ef0b73SPoul-Henning Kamp break; 87174b5e9aSPoul-Henning Kamp case 'l': 88174b5e9aSPoul-Henning Kamp if (cmdline != 0) 89174b5e9aSPoul-Henning Kamp usage(); 90174b5e9aSPoul-Henning Kamp action = LIST; 91174b5e9aSPoul-Henning Kamp mdio.md_options = MD_AUTOUNIT; 92174b5e9aSPoul-Henning Kamp cmdline = 3; 93174b5e9aSPoul-Henning Kamp break; 94f79c46d3SRobert Watson case 'n': 95f79c46d3SRobert Watson nflag = 1; 96f79c46d3SRobert Watson break; 97c2ef0b73SPoul-Henning Kamp case 't': 98c2ef0b73SPoul-Henning Kamp if (cmdline != 1) 99c2ef0b73SPoul-Henning Kamp usage(); 100c2ef0b73SPoul-Henning Kamp if (!strcmp(optarg, "malloc")) { 101c2ef0b73SPoul-Henning Kamp mdio.md_type = MD_MALLOC; 102c2ef0b73SPoul-Henning Kamp mdio.md_options = MD_AUTOUNIT | MD_COMPRESS; 103c2ef0b73SPoul-Henning Kamp } else if (!strcmp(optarg, "preload")) { 104c2ef0b73SPoul-Henning Kamp mdio.md_type = MD_PRELOAD; 105c2ef0b73SPoul-Henning Kamp mdio.md_options = 0; 106c2ef0b73SPoul-Henning Kamp } else if (!strcmp(optarg, "vnode")) { 107c2ef0b73SPoul-Henning Kamp mdio.md_type = MD_VNODE; 108c2ef0b73SPoul-Henning Kamp mdio.md_options = MD_CLUSTER | MD_AUTOUNIT | MD_COMPRESS; 109c2ef0b73SPoul-Henning Kamp } else if (!strcmp(optarg, "swap")) { 110c2ef0b73SPoul-Henning Kamp mdio.md_type = MD_SWAP; 111c2ef0b73SPoul-Henning Kamp mdio.md_options = MD_CLUSTER | MD_AUTOUNIT | MD_COMPRESS; 112c2ef0b73SPoul-Henning Kamp } else { 113c2ef0b73SPoul-Henning Kamp usage(); 114c2ef0b73SPoul-Henning Kamp } 115c2ef0b73SPoul-Henning Kamp cmdline=2; 11670d586c0SPoul-Henning Kamp break; 11770d586c0SPoul-Henning Kamp case 'f': 118ed23a390SMaxim Sobolev if (cmdline != 1 && cmdline != 2) 119c2ef0b73SPoul-Henning Kamp usage(); 120ed23a390SMaxim Sobolev if (cmdline == 1) { 121ed23a390SMaxim Sobolev /* Imply ``-t vnode'' */ 122ed23a390SMaxim Sobolev mdio.md_type = MD_VNODE; 123ed23a390SMaxim Sobolev mdio.md_options = MD_CLUSTER | MD_AUTOUNIT | MD_COMPRESS; 124252bcf45SYaroslav Tykhiy cmdline = 2; 125ed23a390SMaxim Sobolev } 12661a6eb62SPawel Jakub Dawidek if (realpath(optarg, mdio.md_file) == NULL) { 12761a6eb62SPawel Jakub Dawidek err(1, "could not find full path for %s", 12861a6eb62SPawel Jakub Dawidek optarg); 12961a6eb62SPawel Jakub Dawidek } 13061a6eb62SPawel Jakub Dawidek fd = open(mdio.md_file, O_RDONLY); 131e869d377SPoul-Henning Kamp if (fd < 0) 132e869d377SPoul-Henning Kamp err(1, "could not open %s", optarg); 133b830359bSPawel Jakub Dawidek else if (mdio.md_mediasize == 0) { 134b830359bSPawel Jakub Dawidek struct stat sb; 135b830359bSPawel Jakub Dawidek 136b830359bSPawel Jakub Dawidek if (fstat(fd, &sb) == -1) 137b830359bSPawel Jakub Dawidek err(1, "could not stat %s", optarg); 138b830359bSPawel Jakub Dawidek mdio.md_mediasize = sb.st_size; 139b830359bSPawel Jakub Dawidek } 140e869d377SPoul-Henning Kamp close(fd); 14170d586c0SPoul-Henning Kamp break; 14270d586c0SPoul-Henning Kamp case 'o': 143c2ef0b73SPoul-Henning Kamp if (cmdline != 2) 144c2ef0b73SPoul-Henning Kamp usage(); 1457a6b2b64SPoul-Henning Kamp if (!strcmp(optarg, "async")) 1467a6b2b64SPoul-Henning Kamp mdio.md_options |= MD_ASYNC; 1477a6b2b64SPoul-Henning Kamp else if (!strcmp(optarg, "noasync")) 1487a6b2b64SPoul-Henning Kamp mdio.md_options &= ~MD_ASYNC; 1497a6b2b64SPoul-Henning Kamp else if (!strcmp(optarg, "cluster")) 15070d586c0SPoul-Henning Kamp mdio.md_options |= MD_CLUSTER; 15170d586c0SPoul-Henning Kamp else if (!strcmp(optarg, "nocluster")) 15270d586c0SPoul-Henning Kamp mdio.md_options &= ~MD_CLUSTER; 153c2ef0b73SPoul-Henning Kamp else if (!strcmp(optarg, "compress")) 154c2ef0b73SPoul-Henning Kamp mdio.md_options |= MD_COMPRESS; 155c2ef0b73SPoul-Henning Kamp else if (!strcmp(optarg, "nocompress")) 156c2ef0b73SPoul-Henning Kamp mdio.md_options &= ~MD_COMPRESS; 15726a0ee75SDima Dorfman else if (!strcmp(optarg, "force")) 15826a0ee75SDima Dorfman mdio.md_options |= MD_FORCE; 15926a0ee75SDima Dorfman else if (!strcmp(optarg, "noforce")) 16026a0ee75SDima Dorfman mdio.md_options &= ~MD_FORCE; 161d31ba625SJohn-Mark Gurney else if (!strcmp(optarg, "readonly")) 162d31ba625SJohn-Mark Gurney mdio.md_options |= MD_READONLY; 163d31ba625SJohn-Mark Gurney else if (!strcmp(optarg, "noreadonly")) 164d31ba625SJohn-Mark Gurney mdio.md_options &= ~MD_READONLY; 16570d586c0SPoul-Henning Kamp else if (!strcmp(optarg, "reserve")) 16670d586c0SPoul-Henning Kamp mdio.md_options |= MD_RESERVE; 16770d586c0SPoul-Henning Kamp else if (!strcmp(optarg, "noreserve")) 16870d586c0SPoul-Henning Kamp mdio.md_options &= ~MD_RESERVE; 16970d586c0SPoul-Henning Kamp else 170d31ba625SJohn-Mark Gurney errx(1, "Unknown option: %s.", optarg); 17170d586c0SPoul-Henning Kamp break; 172ebe789d6SPoul-Henning Kamp case 'S': 173ebe789d6SPoul-Henning Kamp if (cmdline != 2) 174ebe789d6SPoul-Henning Kamp usage(); 175b830359bSPawel Jakub Dawidek mdio.md_sectorsize = strtoul(optarg, &p, 0); 176ebe789d6SPoul-Henning Kamp break; 17770d586c0SPoul-Henning Kamp case 's': 178c2ef0b73SPoul-Henning Kamp if (cmdline != 2) 179c2ef0b73SPoul-Henning Kamp usage(); 180b830359bSPawel Jakub Dawidek mdio.md_mediasize = (off_t)strtoumax(optarg, &p, 0); 181c2ef0b73SPoul-Henning Kamp if (p == NULL || *p == '\0') 182b830359bSPawel Jakub Dawidek mdio.md_mediasize *= DEV_BSIZE; 1830d79319aSPawel Jakub Dawidek else if (*p == 'b' || *p == 'B') 1840d79319aSPawel Jakub Dawidek ; /* do nothing */ 185c2ef0b73SPoul-Henning Kamp else if (*p == 'k' || *p == 'K') 186b830359bSPawel Jakub Dawidek mdio.md_mediasize <<= 10; 187c2ef0b73SPoul-Henning Kamp else if (*p == 'm' || *p == 'M') 188b830359bSPawel Jakub Dawidek mdio.md_mediasize <<= 20; 189c2ef0b73SPoul-Henning Kamp else if (*p == 'g' || *p == 'G') 190b830359bSPawel Jakub Dawidek mdio.md_mediasize <<= 30; 191b830359bSPawel Jakub Dawidek else if (*p == 't' || *p == 'T') { 192b830359bSPawel Jakub Dawidek mdio.md_mediasize <<= 30; 193b830359bSPawel Jakub Dawidek mdio.md_mediasize <<= 10; 194b830359bSPawel Jakub Dawidek } else 195c2ef0b73SPoul-Henning Kamp errx(1, "Unknown suffix on -s argument"); 19670d586c0SPoul-Henning Kamp break; 19770d586c0SPoul-Henning Kamp case 'u': 1988f8def9eSPoul-Henning Kamp if (cmdline != 2 && cmdline != 3) 199c2ef0b73SPoul-Henning Kamp usage(); 200fb1023d6SPoul-Henning Kamp if (!strncmp(optarg, "/dev/", 5)) 201fb1023d6SPoul-Henning Kamp optarg += 5; 202174b5e9aSPoul-Henning Kamp if (!strncmp(optarg, MD_NAME, sizeof(MD_NAME) - 1)) 20378baea25SDima Dorfman optarg += sizeof(MD_NAME) - 1; 2042885b421SDima Dorfman mdio.md_unit = strtoul(optarg, &p, 0); 2058a50130bSAlexander Kabaev if (mdio.md_unit == (unsigned)ULONG_MAX || *p != '\0') 2062885b421SDima Dorfman errx(1, "bad unit: %s", optarg); 20770d586c0SPoul-Henning Kamp mdio.md_options &= ~MD_AUTOUNIT; 20870d586c0SPoul-Henning Kamp break; 2094e8bfe14SPoul-Henning Kamp case 'x': 2104e8bfe14SPoul-Henning Kamp if (cmdline != 2) 2114e8bfe14SPoul-Henning Kamp usage(); 2124e8bfe14SPoul-Henning Kamp mdio.md_fwsectors = strtoul(optarg, &p, 0); 2134e8bfe14SPoul-Henning Kamp break; 2144e8bfe14SPoul-Henning Kamp case 'y': 2154e8bfe14SPoul-Henning Kamp if (cmdline != 2) 2164e8bfe14SPoul-Henning Kamp usage(); 2174e8bfe14SPoul-Henning Kamp mdio.md_fwheads = strtoul(optarg, &p, 0); 2184e8bfe14SPoul-Henning Kamp break; 21970d586c0SPoul-Henning Kamp default: 220c2ef0b73SPoul-Henning Kamp usage(); 22170d586c0SPoul-Henning Kamp } 22270d586c0SPoul-Henning Kamp } 22353d745bcSDima Dorfman mdio.md_version = MDIOVERSION; 22470d586c0SPoul-Henning Kamp 22557e9624eSPoul-Henning Kamp mdmaybeload(); 226174b5e9aSPoul-Henning Kamp fd = open("/dev/" MDCTL_NAME, O_RDWR, 0); 22770d586c0SPoul-Henning Kamp if (fd < 0) 228174b5e9aSPoul-Henning Kamp err(1, "open(/dev/%s)", MDCTL_NAME); 2292885b421SDima Dorfman if (cmdline == 2 2302885b421SDima Dorfman && (mdio.md_type == MD_MALLOC || mdio.md_type == MD_SWAP)) 231b830359bSPawel Jakub Dawidek if (mdio.md_mediasize == 0) 2322885b421SDima Dorfman errx(1, "must specify -s for -t malloc or -t swap"); 233252bcf45SYaroslav Tykhiy if (cmdline == 2 && mdio.md_type == MD_VNODE) 23488b5b78dSPawel Jakub Dawidek if (mdio.md_file[0] == '\0') 235252bcf45SYaroslav Tykhiy errx(1, "must specify -f for -t vnode"); 236174b5e9aSPoul-Henning Kamp if (action == LIST) { 237174b5e9aSPoul-Henning Kamp if (mdio.md_options & MD_AUTOUNIT) 238174b5e9aSPoul-Henning Kamp list(fd); 239174b5e9aSPoul-Henning Kamp else 240174b5e9aSPoul-Henning Kamp query(fd, mdio.md_unit); 241174b5e9aSPoul-Henning Kamp } else if (action == ATTACH) { 242252bcf45SYaroslav Tykhiy if (cmdline < 2) 243252bcf45SYaroslav Tykhiy usage(); 24470d586c0SPoul-Henning Kamp i = ioctl(fd, MDIOCATTACH, &mdio); 245174b5e9aSPoul-Henning Kamp if (i < 0) 246174b5e9aSPoul-Henning Kamp err(1, "ioctl(/dev/%s)", MDCTL_NAME); 24783da2a90SPoul-Henning Kamp if (mdio.md_options & MD_AUTOUNIT) 248f79c46d3SRobert Watson printf("%s%d\n", nflag ? "" : MD_NAME, mdio.md_unit); 24983da2a90SPoul-Henning Kamp } else if (action == DETACH) { 2508f8def9eSPoul-Henning Kamp if (mdio.md_options & MD_AUTOUNIT) 2518f8def9eSPoul-Henning Kamp usage(); 252c2ef0b73SPoul-Henning Kamp i = ioctl(fd, MDIOCDETACH, &mdio); 25370d586c0SPoul-Henning Kamp if (i < 0) 254174b5e9aSPoul-Henning Kamp err(1, "ioctl(/dev/%s)", MDCTL_NAME); 25583da2a90SPoul-Henning Kamp } else 25683da2a90SPoul-Henning Kamp usage(); 257174b5e9aSPoul-Henning Kamp close (fd); 258174b5e9aSPoul-Henning Kamp return (0); 259174b5e9aSPoul-Henning Kamp } 260174b5e9aSPoul-Henning Kamp 261174b5e9aSPoul-Henning Kamp int 262174b5e9aSPoul-Henning Kamp list(const int fd) 263174b5e9aSPoul-Henning Kamp { 264c894b25aSDima Dorfman int unit; 265174b5e9aSPoul-Henning Kamp 266e39eff98SPoul-Henning Kamp if (ioctl(fd, MDIOCLIST, &mdio) < 0) 267e39eff98SPoul-Henning Kamp err(1, "ioctl(/dev/%s)", MDCTL_NAME); 268e39eff98SPoul-Henning Kamp for (unit = 0; unit < mdio.md_pad[0] && unit < MDNPAD - 1; unit++) { 269f79c46d3SRobert Watson printf("%s%s%d", unit > 0 ? " " : "", 270f79c46d3SRobert Watson nflag ? "" : MD_NAME, mdio.md_pad[unit + 1]); 271174b5e9aSPoul-Henning Kamp } 272e39eff98SPoul-Henning Kamp if (mdio.md_pad[0] - unit > 0) 273e39eff98SPoul-Henning Kamp printf(" ... %d more", mdio.md_pad[0] - unit); 2749a777b93SDima Dorfman if (unit > 0) 275e39eff98SPoul-Henning Kamp printf("\n"); 276174b5e9aSPoul-Henning Kamp return (0); 277174b5e9aSPoul-Henning Kamp } 278174b5e9aSPoul-Henning Kamp 279b830359bSPawel Jakub Dawidek static void 280b830359bSPawel Jakub Dawidek prthumanval(int64_t bytes) 281b830359bSPawel Jakub Dawidek { 282b830359bSPawel Jakub Dawidek char buf[6]; 283b830359bSPawel Jakub Dawidek 284b830359bSPawel Jakub Dawidek humanize_number(buf, sizeof(buf) - (bytes < 0 ? 0 : 1), 285b830359bSPawel Jakub Dawidek bytes, "", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL); 286b830359bSPawel Jakub Dawidek (void)printf("%6s", buf); 287b830359bSPawel Jakub Dawidek } 288b830359bSPawel Jakub Dawidek 289174b5e9aSPoul-Henning Kamp int 290174b5e9aSPoul-Henning Kamp query(const int fd, const int unit) 291174b5e9aSPoul-Henning Kamp { 292174b5e9aSPoul-Henning Kamp 29353d745bcSDima Dorfman mdio.md_version = MDIOVERSION; 294174b5e9aSPoul-Henning Kamp mdio.md_unit = unit; 295174b5e9aSPoul-Henning Kamp 296174b5e9aSPoul-Henning Kamp if (ioctl(fd, MDIOCQUERY, &mdio) < 0) 297174b5e9aSPoul-Henning Kamp err(1, "ioctl(/dev/%s)", MDCTL_NAME); 298174b5e9aSPoul-Henning Kamp 299b830359bSPawel Jakub Dawidek (void)printf("%s%d\t", MD_NAME, mdio.md_unit); 300174b5e9aSPoul-Henning Kamp switch (mdio.md_type) { 301174b5e9aSPoul-Henning Kamp case MD_MALLOC: 302b830359bSPawel Jakub Dawidek (void)printf("malloc"); 303174b5e9aSPoul-Henning Kamp break; 304174b5e9aSPoul-Henning Kamp case MD_PRELOAD: 305b830359bSPawel Jakub Dawidek (void)printf("preload"); 306174b5e9aSPoul-Henning Kamp break; 307174b5e9aSPoul-Henning Kamp case MD_SWAP: 308b830359bSPawel Jakub Dawidek (void)printf("swap"); 309174b5e9aSPoul-Henning Kamp break; 310174b5e9aSPoul-Henning Kamp case MD_VNODE: 311b830359bSPawel Jakub Dawidek (void)printf("vnode"); 312174b5e9aSPoul-Henning Kamp break; 313174b5e9aSPoul-Henning Kamp } 314b830359bSPawel Jakub Dawidek printf("\t"); 315b830359bSPawel Jakub Dawidek prthumanval(mdio.md_mediasize); 31661a6eb62SPawel Jakub Dawidek if (mdio.md_type == MD_VNODE) 31761a6eb62SPawel Jakub Dawidek printf("\t%s", mdio.md_file); 318b830359bSPawel Jakub Dawidek printf("\n"); 319174b5e9aSPoul-Henning Kamp 32070d586c0SPoul-Henning Kamp return (0); 32170d586c0SPoul-Henning Kamp } 32270d586c0SPoul-Henning Kamp 32357e9624eSPoul-Henning Kamp void 32457e9624eSPoul-Henning Kamp mdmaybeload(void) 32557e9624eSPoul-Henning Kamp { 32657e9624eSPoul-Henning Kamp struct module_stat mstat; 32757e9624eSPoul-Henning Kamp int fileid, modid; 32810b0e058SDima Dorfman const char *name; 32957e9624eSPoul-Henning Kamp char *cp; 33057e9624eSPoul-Henning Kamp 331a246f097SJohn-Mark Gurney name = MD_MODNAME; 33257e9624eSPoul-Henning Kamp /* scan files in kernel */ 33357e9624eSPoul-Henning Kamp mstat.version = sizeof(struct module_stat); 33457e9624eSPoul-Henning Kamp for (fileid = kldnext(0); fileid > 0; fileid = kldnext(fileid)) { 33557e9624eSPoul-Henning Kamp /* scan modules in file */ 33657e9624eSPoul-Henning Kamp for (modid = kldfirstmod(fileid); modid > 0; 33757e9624eSPoul-Henning Kamp modid = modfnext(modid)) { 33857e9624eSPoul-Henning Kamp if (modstat(modid, &mstat) < 0) 33957e9624eSPoul-Henning Kamp continue; 34057e9624eSPoul-Henning Kamp /* strip bus name if present */ 34157e9624eSPoul-Henning Kamp if ((cp = strchr(mstat.name, '/')) != NULL) { 34257e9624eSPoul-Henning Kamp cp++; 34357e9624eSPoul-Henning Kamp } else { 34457e9624eSPoul-Henning Kamp cp = mstat.name; 34557e9624eSPoul-Henning Kamp } 34657e9624eSPoul-Henning Kamp /* already loaded? */ 34757e9624eSPoul-Henning Kamp if (!strcmp(name, cp)) 34857e9624eSPoul-Henning Kamp return; 34957e9624eSPoul-Henning Kamp } 35057e9624eSPoul-Henning Kamp } 35157e9624eSPoul-Henning Kamp /* not present, we should try to load it */ 35257e9624eSPoul-Henning Kamp kldload(name); 35357e9624eSPoul-Henning Kamp } 35457e9624eSPoul-Henning Kamp 355