xref: /freebsd/sbin/mdconfig/mdconfig.c (revision c2ef0b73df3574fc05bc144220b388c0546448ff)
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>
1770d586c0SPoul-Henning Kamp #include <string.h>
1870d586c0SPoul-Henning Kamp #include <err.h>
1970d586c0SPoul-Henning Kamp #include <sys/ioctl.h>
2070d586c0SPoul-Henning Kamp #include <sys/param.h>
2170d586c0SPoul-Henning Kamp #include <sys/mdioctl.h>
2270d586c0SPoul-Henning Kamp 
2370d586c0SPoul-Henning Kamp struct md_ioctl mdio;
2470d586c0SPoul-Henning Kamp 
2570d586c0SPoul-Henning Kamp enum {UNSET, ATTACH, DETACH} action = UNSET;
2670d586c0SPoul-Henning Kamp 
27c2ef0b73SPoul-Henning Kamp void
28c2ef0b73SPoul-Henning Kamp usage()
29c2ef0b73SPoul-Henning Kamp {
30c2ef0b73SPoul-Henning Kamp 	fprintf(stderr, "Usage:\n\t");
31c2ef0b73SPoul-Henning Kamp 	fprintf(stderr, "mdconfig {-a|-d} -t type [-o [no]option]... [ -f file] [-s size] [-u unit]\n");
32c2ef0b73SPoul-Henning Kamp 	fprintf(stderr, "\t\ttype = {malloc, preload, vnode, swap}\n");
33c2ef0b73SPoul-Henning Kamp 	fprintf(stderr, "\t\toption = {cluster, compress, reserve, autounit}\n");
34c2ef0b73SPoul-Henning Kamp 	fprintf(stderr, "\t\tsize = %%d (512 byte blocks), %%dk (kB), %%dm (MB) or %%dg (GB)\n");
35c2ef0b73SPoul-Henning Kamp 	exit(1);
36c2ef0b73SPoul-Henning Kamp }
37c2ef0b73SPoul-Henning Kamp 
3870d586c0SPoul-Henning Kamp int
3970d586c0SPoul-Henning Kamp main(int argc, char **argv)
4070d586c0SPoul-Henning Kamp {
4170d586c0SPoul-Henning Kamp 	int ch, fd, i;
42c2ef0b73SPoul-Henning Kamp 	char *p;
43c2ef0b73SPoul-Henning Kamp 	int cmdline = 0;
4470d586c0SPoul-Henning Kamp 
4570d586c0SPoul-Henning Kamp 	for (;;) {
4670d586c0SPoul-Henning Kamp 		ch = getopt(argc, argv, "adf:o:s:t:u:");
4770d586c0SPoul-Henning Kamp 		if (ch == -1)
4870d586c0SPoul-Henning Kamp 			break;
4970d586c0SPoul-Henning Kamp 		switch (ch) {
5070d586c0SPoul-Henning Kamp 		case 'a':
51c2ef0b73SPoul-Henning Kamp 			if (cmdline != 0)
52c2ef0b73SPoul-Henning Kamp 				usage();
5370d586c0SPoul-Henning Kamp 			action = ATTACH;
54c2ef0b73SPoul-Henning Kamp 			cmdline = 1;
5570d586c0SPoul-Henning Kamp 			break;
5670d586c0SPoul-Henning Kamp 		case 'd':
57c2ef0b73SPoul-Henning Kamp 			if (cmdline != 0)
58c2ef0b73SPoul-Henning Kamp 				usage();
5970d586c0SPoul-Henning Kamp 			action = DETACH;
60c2ef0b73SPoul-Henning Kamp 			cmdline = 1;
61c2ef0b73SPoul-Henning Kamp 			break;
62c2ef0b73SPoul-Henning Kamp 		case 't':
63c2ef0b73SPoul-Henning Kamp 			if (cmdline != 1)
64c2ef0b73SPoul-Henning Kamp 				usage();
65c2ef0b73SPoul-Henning Kamp 			if (!strcmp(optarg, "malloc")) {
66c2ef0b73SPoul-Henning Kamp 				mdio.md_type = MD_MALLOC;
67c2ef0b73SPoul-Henning Kamp 				mdio.md_options = MD_AUTOUNIT | MD_COMPRESS;
68c2ef0b73SPoul-Henning Kamp 			} else if (!strcmp(optarg, "preload")) {
69c2ef0b73SPoul-Henning Kamp 				mdio.md_type = MD_PRELOAD;
70c2ef0b73SPoul-Henning Kamp 				mdio.md_options = 0;
71c2ef0b73SPoul-Henning Kamp 			} else if (!strcmp(optarg, "vnode")) {
72c2ef0b73SPoul-Henning Kamp 				mdio.md_type = MD_VNODE;
73c2ef0b73SPoul-Henning Kamp 				mdio.md_options = MD_CLUSTER | MD_AUTOUNIT | MD_COMPRESS;
74c2ef0b73SPoul-Henning Kamp 			} else if (!strcmp(optarg, "swap")) {
75c2ef0b73SPoul-Henning Kamp 				mdio.md_type = MD_SWAP;
76c2ef0b73SPoul-Henning Kamp 				mdio.md_options = MD_CLUSTER | MD_AUTOUNIT | MD_COMPRESS;
77c2ef0b73SPoul-Henning Kamp 			} else {
78c2ef0b73SPoul-Henning Kamp 				usage();
79c2ef0b73SPoul-Henning Kamp 			}
80c2ef0b73SPoul-Henning Kamp 			cmdline=2;
8170d586c0SPoul-Henning Kamp 			break;
8270d586c0SPoul-Henning Kamp 		case 'f':
83c2ef0b73SPoul-Henning Kamp 			if (cmdline != 2)
84c2ef0b73SPoul-Henning Kamp 				usage();
8570d586c0SPoul-Henning Kamp 			strncpy(mdio.md_file, optarg, sizeof(mdio.md_file) - 1);
8670d586c0SPoul-Henning Kamp 			break;
8770d586c0SPoul-Henning Kamp 		case 'o':
88c2ef0b73SPoul-Henning Kamp 			if (cmdline != 2)
89c2ef0b73SPoul-Henning Kamp 				usage();
9070d586c0SPoul-Henning Kamp 			if (!strcmp(optarg, "cluster"))
9170d586c0SPoul-Henning Kamp 				mdio.md_options |= MD_CLUSTER;
9270d586c0SPoul-Henning Kamp 			else if (!strcmp(optarg, "nocluster"))
9370d586c0SPoul-Henning Kamp 				mdio.md_options &= ~MD_CLUSTER;
94c2ef0b73SPoul-Henning Kamp 			else if (!strcmp(optarg, "compress"))
95c2ef0b73SPoul-Henning Kamp 				mdio.md_options |= MD_COMPRESS;
96c2ef0b73SPoul-Henning Kamp 			else if (!strcmp(optarg, "nocompress"))
97c2ef0b73SPoul-Henning Kamp 				mdio.md_options &= ~MD_COMPRESS;
9870d586c0SPoul-Henning Kamp 			else if (!strcmp(optarg, "reserve"))
9970d586c0SPoul-Henning Kamp 				mdio.md_options |= MD_RESERVE;
10070d586c0SPoul-Henning Kamp 			else if (!strcmp(optarg, "noreserve"))
10170d586c0SPoul-Henning Kamp 				mdio.md_options &= ~MD_RESERVE;
10270d586c0SPoul-Henning Kamp 			else if (!strcmp(optarg, "autounit"))
10370d586c0SPoul-Henning Kamp 				mdio.md_options |= MD_AUTOUNIT;
10470d586c0SPoul-Henning Kamp 			else if (!strcmp(optarg, "noautounit"))
10570d586c0SPoul-Henning Kamp 				mdio.md_options &= ~MD_AUTOUNIT;
10670d586c0SPoul-Henning Kamp 			else
10770d586c0SPoul-Henning Kamp 				errx(1, "Unknown option.");
10870d586c0SPoul-Henning Kamp 			break;
10970d586c0SPoul-Henning Kamp 		case 's':
110c2ef0b73SPoul-Henning Kamp 			if (cmdline != 2)
111c2ef0b73SPoul-Henning Kamp 				usage();
112c2ef0b73SPoul-Henning Kamp 			mdio.md_size = strtoul(optarg, &p, 0);
113c2ef0b73SPoul-Henning Kamp 			if (p == NULL || *p == '\0')
114c2ef0b73SPoul-Henning Kamp 				;
115c2ef0b73SPoul-Henning Kamp 			else if (*p == 'k' || *p == 'K')
116c2ef0b73SPoul-Henning Kamp 				mdio.md_size *= (1024 / DEV_BSIZE);
117c2ef0b73SPoul-Henning Kamp 			else if (*p == 'm' || *p == 'M')
118c2ef0b73SPoul-Henning Kamp 				mdio.md_size *= (1024 * 1024 / DEV_BSIZE);
119c2ef0b73SPoul-Henning Kamp 			else if (*p == 'g' || *p == 'G')
120c2ef0b73SPoul-Henning Kamp 				mdio.md_size *= (1024 * 1024 * 1024 / DEV_BSIZE);
12170d586c0SPoul-Henning Kamp 			else
122c2ef0b73SPoul-Henning Kamp 				errx(1, "Unknown suffix on -s argument");
12370d586c0SPoul-Henning Kamp 			break;
12470d586c0SPoul-Henning Kamp 		case 'u':
125c2ef0b73SPoul-Henning Kamp 			if (cmdline != 2)
126c2ef0b73SPoul-Henning Kamp 				usage();
12770d586c0SPoul-Henning Kamp 			mdio.md_unit = strtoul(optarg, NULL, 0);
12870d586c0SPoul-Henning Kamp 			mdio.md_options &= ~MD_AUTOUNIT;
12970d586c0SPoul-Henning Kamp 			break;
13070d586c0SPoul-Henning Kamp 		default:
131c2ef0b73SPoul-Henning Kamp 			usage();
13270d586c0SPoul-Henning Kamp 		}
13370d586c0SPoul-Henning Kamp 	}
13470d586c0SPoul-Henning Kamp 
13570d586c0SPoul-Henning Kamp 	fd = open("/dev/mdctl", O_RDWR, 0);
13670d586c0SPoul-Henning Kamp 	if (fd < 0)
137c2ef0b73SPoul-Henning Kamp 		err(1, "open(/dev/mdctl)");
13870d586c0SPoul-Henning Kamp 	if (action == ATTACH)
13970d586c0SPoul-Henning Kamp 		i = ioctl(fd, MDIOCATTACH, &mdio);
14070d586c0SPoul-Henning Kamp 	else
141c2ef0b73SPoul-Henning Kamp 		i = ioctl(fd, MDIOCDETACH, &mdio);
14270d586c0SPoul-Henning Kamp 	if (i < 0)
14370d586c0SPoul-Henning Kamp 		err(1, "ioctl(/dev/mdctl)");
14470d586c0SPoul-Henning Kamp 	return (0);
14570d586c0SPoul-Henning Kamp }
14670d586c0SPoul-Henning Kamp 
147